Form orthongonal group of busses from existing bus

2019-08-08 20:21发布

问题:

I have inputs like this coming into a module:

   input  wire [31:0]     row0_Q,
   input  wire [31:0]     row1_Q,
    ...
   input  wire [31:0]     row30_Q,
   input  wire [31:0]     row31_Q

and want to form busses of the "columns" for lack of better terms. I can do it the long way:

   assign col31 = {row31[31], row30[31], ... row1[31], row0[31]} ;

but it's a lot of typing. Is there an easier way?

回答1:

There is no easy way within Verilog. Try creating a script to generate the code for you. You can have the code generated by your preferred programming language, then use an `include statement in your verilog file. Or you can go with an embedded route:

  • Perl had EP3 : http://metacpan.org/pod/Text::EP3::Verilog
  • Ruby has eRuby : http://www.tutorialspoint.com/ruby/eruby.htm
  • Python has prepro : http://corner-case.com/indproj/prepro.html
  • I'm sure something like it exists for other languages to. Such as Tcl, JavaScript, C, etc.

Concept is the same, just a difference in embedded language and tool used for conversion.

In this case, a double for-loop like the following will be needed:

foreach my $i (0..31) {
  foreach my $j (0..31) {
    printf("assign col%0d[%0d] = row%0d[%0d];\n", $i,$j, $j, $i);
  }
}

With SystemVerilog you could redefine your module with arrayed input/output ports. It may add difficulty when instantiating, and a synthesizer my attempt flatten the array. But it could work. Verilog does not support this, SystemVerilog does.

module row2col #(parameter WIDTH=32) (
    input wire [WIDTH-1:0] row [WIDTH],
    output logic [WIDTH-1:0] col [WIDTH]
  );
  always_comb begin
    foreach(row[i,j]) begin
      col[j][i] = row[i][j];
    end
  end
endmodule : row2col


标签: verilog