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?
reg[7:0]
is an 8-bit "register", or variable
reg[7:0] numbers[3:0]
is a 1-D array with 4 elements, named
numbers
, each of which is an 8-bit register
- An element of
numbers
is accessed as numbers[index]
numbers[i][j]
is a bit-select of numbers[i]
. It accesses bit
j
in the i
th element of numbers
- 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
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]
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.