Sunday, June 21, 2009

multi-dimensional array ports and variable bit selects

As a software programmer who moved to VHDL and then to Verilog, I have always found Verilog's language limitations to be very frustrating. One of my biggest complaints is Verilog's inability to use multi-dimensional arrays in port declarations.

For example:
module test(
input reg [7:0] a [2:0]
);
is illegal in Verilog. The only way to do this is:
module test(
input reg [23:0] a
);
What I had previously found myself doing was declaring the port level array as flat, and then converting it inside a standard generate block to the originally intended multi-dimensional array.

This is much clunkier than necessary. Variable bit-selects in Verilog allow for a much easier design. You can easily access the bits you require with this:

always @(posedge clk) begin : indexing process
integer i, index, found;
found = 0;
for(i = 0; i < 3; i = i + 1) begin
if(!found) begin
if(get_this_index[i]) begin
index = i;
found = 1;
end
end
end
if(found) begin
my_data <= a[index * 8+:8];
// my_data <= a_non_flat[index];
end
end

*** Note the +: notation. The first value is the start bit in the array, and the second value is the number of bits going up the array ( -: would go down the array). This shouldn't be confused with normal x:y notation. This is what makes pulling the correct bits out so easy.

This easily allows for parameterized modules with both compile-time bit widths and compile-time number of elements. The lack of multi-dimensional ports is made up for by variable bit selects. Of course you do need to remember the size of each "index" of data otherwise you'll be accessing the wrong bits...

Be enlightened,

1 comment:

  1. One comment about +: notation: it's only valid in Verilog 2001. There are quite a few designs written and compiled in Verilog '95.

    ReplyDelete