Verilog: Order of reg

2019-05-26 13:51发布

问题:

Simple question

If I need to use 4 8-bit numbers, I would declare the following reg.

reg [7:0] numbers [3:0]

I'm quite confused about the difference between the first and second declaration ([7:0] and [3:0]). In what order should they come? Does first one stay for the size of a number while the second is for the number of numbers or vice versa? And is [7:0] or [0:7] give the right order?

Thanks in advance.

EDIT:

Ordinary arrays of numbers look like this, for example

0000
0110
0001

There are three 4-bit numbers (0000, 0110, 0001). We can access them by using array indices. So, accessing the first digit of the second number is done by something like this

a[0][1]

assuming that this array is stored in a variable a.

Returning to Verilog, how would accessing elements change if I would swap values in reg or declare them in reverse order ([0:7]), for example?

回答1:

  1. reg[7:0] is an 8-bit "register", or variable
  2. reg[7:0] numbers[3:0] is a 1-D array with 4 elements, named numbers, each of which is an 8-bit register
  3. An element of numbers is accessed as numbers[index]
  4. numbers[i][j] is a bit-select of numbers[i]. It accesses bit j in the ith element of numbers
  5. As toolic says, it's more conventional for array indices to be numbered [lsb:msb], but there's no good reason for this.

When assigning two objects, bits are copied left-to-right, as for VHDL.

Verilog has (very) poor checking of bit and part selects and array indexes. See the code below.

module top;
   initial
     test;
   task test;
      reg[3:0] a[0:1];
      reg[0:3] b[0:1];
      reg[2:5] c[0:1];
      begin
       a[0] = 4'b1101;
       a[1] = 4'b0110;
       a[2] = 4'b0001;                      // error, but not caught by Verilog

       $display("a[2] is %d", a[2]);        // modelsim produces no warning, prints 'a[2] is x'
       $display("a[0][4] is %b", a[0][4]);  // modelsim warns, and prints 'a[0][4] is x'

       $display(                            // produces '1.1.0.1'
         "a[0][3:0] is %b.%b.%b.%b", a[0][3], a[0][2], a[0][1], a[0][0]);

       b[0] = a[0];                         
       $display("b[0] is %d", b[0]);        // produces '13'
       $display(                            // produces '1.1.0.1'
         "b[0][0:3] is %b.%b.%b.%b", b[0][0], b[0][1], b[0][2], b[0][3]);

       c[0] = a[0];                         
       $display("c[0] is %d", c[0]);        // produces '13'
       $display(                            // produces '1.1.0.1'
         "c[0][2:5] is %b.%b.%b.%b", c[0][2], c[0][3], c[0][4], c[0][5]);
     end
   endtask
endmodule


回答2:

Yes, that syntax can be used to declare 4 8-bit numbers, however it is more conventional for 0 to be left of the colon for the number of words:

reg [7:0] numbers [0:3]


回答3:

The dimensions to the right are called unpacked dimensions and those to the left are packed. I found this over the net as an easy way to remember for accessing elements. "Left to right, starting with right". So you start with unpacked dimensions first. For accessing 8th bit of 3rd number in your declaration I would use numbers numbers[2][7]. This post has proper explanation.

If you use same convention for declaring and assigning values, I think it should be fine. Actually it is far simpler to eliminate the [:] and declare it as reg [7:0] numbers [4]; giving four, 8 bit numbers.



标签: verilog