Verilog: Order of reg - verilog

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 ith 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]

Related

In Verilog, counting and outputting the number of 1's in an 8bit input?

What I am trying to do in my mind is take 8 1-bit inputs and count the 1's. Then represent those 1's.
01010111 should output 0101 (There are five 1's from input)
module 8to4 (in,out,hold,clk,reset);
input [7:0] in; //1 bit inputs
reg [7:0] hold; //possible use for case statement
output [3:0] out; //Shows the count of bits
always #(clk)
begin
out = in[0] + in[1] + in[2] + in[3] + in[4] + in[5] + in[6] + in[7]; //Adds the inputs from testbench and outputs it
end
endmodule
Questions:
Is that the proper way to have 8 1-bit inputs? Or do I need to declare each variable as one bit ex: input A,B,C,D,E,F,G,H;
If my above code is close to being correct, is that the proper way to get out to display the count of 1's? Would I need a case statement?
I'm really new to verilog, so I don't even want to think about a test bench yet.
The way you wrote it is probably the better way of writing it because it makes it easier to parameterize the number of bits. But technically, you have one 8-bit input.
module 8to4 #(parameter WIDTH=8) (input [WIDTH-1:0] in,
output reg [3:0] out,hold,
input clk,reset);
reg [WIDTH-1:0] temp;
integer ii;
always #(clk)
begin
temp = 0;
for(ii=0; ii<WIDTH; i = i + 1)
temp = temp + in[ii];
out <= temp;
end
endmodule
Logically the code is proper.
However you can improve it like the following.
Make out as a reg, because you are using it in a procedural assignment.
Usage of reset. Ideally any code should have reset state, which is missing in your code.
Declare the direction (input/output) for hold, clk & reset port, which is currently not specified.
As dave mentioned, you can use parameters for your code.

Is this code structure going in the right direction?

I am trying to utilize a 7 segment display. I have written a module which I want to take 4 inputs and change the hex output. There seems to be an issue with unpacked/packed arrays and I really don't know what on earth I'm doing. Any help much appreciated.
module hexDisplay(hex, c0, c1, c2, c3);
input c0;
input c1;
input c2;
input c3;
output hex[6:0];
reg out[6:0];
always#(*)
begin
case({c3, c2, c1, c0})
4'b0000:out [5:0] = 1;
// 0001-1111 go here
//...
default:out [6:0] = 0;
endcase
assign hex = out;
end
endmodule
Errors:
Error (10773): Verilog HDL error at lab2pre.v(55): declaring module ports or function arguments with unpacked array types requires SystemVerilog extensions
Error (10133): Verilog HDL Expression error at lab2pre.v(61): illegal part select of unpacked array "out"
Error (10133): Verilog HDL Expression error at lab2pre.v(62): illegal part select of unpacked array "out"
Error (10048): Verilog HDL error at lab2pre.v(64): values cannot be assigned directly to all or part of array "hex" - assignments must be made to individual elements only
Error (10137): Verilog HDL Procedural Assignment error at lab2pre.v(64): object "hex" on left-hand side of assignment must have a variable data type
Error (10044): Verilog HDL error at lab2pre.v(64): expression cannot reference entire array "out"
Error: Quartus II 64-Bit Analysis & Synthesis was unsuccessful. 6 errors, 1 warning
Error: Peak virtual memory: 959 megabytes
Error: Processing ended: Tue Feb 2 17:33:35 2016
Error: Elapsed time: 00:00:15
Error: Total CPU time (on all processors): 00:00:46
Error (293001): Quartus II Full Compilation was unsuccessful. 8 errors, 1 warning
2 Errors :
You need to have "packed" array rather than an "unpacked" array for
"out" & "hex" nets.
SystemVerilog supports both packed arrays and unpacked arrays of data.
The term packed array is used to refer to the dimensions declared
before the data identifier name. The term unpacked array is used to
refer to the dimensions declared after the data identifier name.
bit [7:0] c1; // packed array of scalar bit types
real u [7:0]; // unpacked array of real types
A packed array is a mechanism for subdividing a vector into subfields,
which can be conveniently accessed as array elements. Consequently, a
packed array is guaranteed to be represented as a contiguous set of
bits.
An unpacked array may or may not be so represented. A packed array
differs from an unpacked array in that, when a packed array appears as
a primary, it is treated as a single vector.
So in the code, you require, out & hex to be used as a continuous
bit vector, then it should be packed array, instead of unpacked
array.
Refer to topic 7.4 of the Systemverilog LRM.
assign statement to hex, cannot be with in always block. Because an
assign statement is used for modeling only combinational logic and it
is executed continuously. So the assign statement is called
'continuous assignment statement' as there is no sensitive list.
So it can't be within always block, which is executed as per
sensitivity list.
So your final working code is as below:
module hexDisplay(hex, c0, c1, c2, c3);
input c0;
input c1;
input c2;
input c3;
output [6:0] hex;
reg [6:0] out;
always#(*)
begin
case({c3, c2, c1, c0})
4'b0000:out [5:0] = 1;
// 0001-1111 go here
//...
default:out [6:0] = 0;
endcase
end
assign hex = out;
endmodule
Try something like this. Move the range specifiers ([6:0]) to the left of the signal names, and move the assign outside of the always block.
module hexDisplay(hex, c0, c1, c2, c3);
input c0;
input c1;
input c2;
input c3;
output [6:0] hex;
reg [6:0] out;
always#(*)
begin
case({c3, c2, c1, c0})
4'b0000:out [5:0] = 1;
// 0001-1111 go here
//...
default:out [6:0] = 0;
endcase
end
assign hex = out;
endmodule
whatever variable in always block must be reg , here you assign hex in always which is by default wire so if you assign hex at out side of always u will get compile free code.

Use of << in given Verilog code?

In the following Verilog code snippet for implementing an input buffer for a router, in second line, what is the role of 1<<`BUF_WIDTH? I understand that << is the left shift operator, but what happens by left shifting 1 by `BUF_WIDTH? Or is there some other function of << operator?
`define BUF_WIDTH 3 // BUF_SIZE = 16 -> BUF_WIDTH = 4, no. of bits to be used in pointer
`define BUF_SIZE ( 1<<`BUF_WIDTH )
module fifo13( clk, rst, buf_in, buf_out, wr_en, rd_en, buf_empty, buf_full, fifo_counter );
input rst, clk, wr_en, rd_en;
input [7:0] buf_in; // data input to be pushed to buffer
output[7:0] buf_out;// port to output the data using pop.
output buf_empty, buf_full; // buffer empty and full indication
output[`BUF_WIDTH :0] fifo_counter; // number of data pushed in to buffer
reg[7:0] buf_out;
reg buf_empty, buf_full;
reg[`BUF_WIDTH :0] fifo_counter;
reg[`BUF_WIDTH -1:0] rd_ptr, wr_ptr; // pointer to read and write addresses
reg[7:0] buf_mem[`BUF_SIZE -1 : 0];
.
.
.
The entire code is available on http://electrosofts.com/verilog/fifo.html
You assume correctly that << is the left-shift operator, it has no other special meaning.
Shifting the binary representation of a number to the left is equivalent to multiplying the number by 2. So, by shifting 1 to the left N times, you get 2 to the power of N as a result.
The way this is used in the code sample ensures that the buffer has exactly as many entries (BUF_SIZE) as can be uniquely addressed by a pointer of size BUF_WIDTH.
It is the bit shift operator. Think what it does: it shifts bits left. You have a definition of BUF_WIDTH being 3. Then you take 1, shift it by that many places and you get 8 for BUF_SIZE. With three bits you can have 8 different values.
So this is a way to define these two constants so that you only have to change one value. If they would be two constants, someone might accidentally only change one and not the other and this would cause problems.

Converting a wire value in Verilog for further processing

I'm new to Verilog.
I have written code to convert a wire value to an integer:
wire [31:0] w1;
integer k;
always # (w1) k = w1;
Source: converting a wire value to an integer in verilog
Now, for the next part I get an ERROR!
wire [63:0] w2; // Suppose it contains some value
wire [63:0] w3;
assign w3[k-1:0] = w2[k-1:0]; // ERROR in this line
ERROR : k is not a constant.
How do I solve this issue?
Verilog requires that part selects (code like [msb:lsb] to select part of a vector) be constant. To access a variable-sized group of bits requires something more complicated. Here is one way to do it:
wire [63:0] src;
wire [6:0] k;
wire [127:0] mask = { { 64 { 1'b0 } }, { 64 { 1'b1 } } } << k;
wire [63:0] dest;
assign dest = mask[127:64] & src;
The technique here is to construct a vector of 64 zeros followed by 64 ones, shift that vector by a variable amount, and then use a portion of the vector as a qualifying mask to control which bits are transferred from src to dest.
A related concept which does not help in your example but which is worth being aware of: Verilog-2001 introduced the "indexed part-select". An indexed part select specifies a base index and a width. The width is required to be constant but the base index does not need to be constant. The syntax for an indexed part select is vec[base+:width] or vec[base-:width].
The part select operators in Verilog 2001 could be useful for what you want to achieve.
Basically verilog allows for the starting index to be variable but needs the width of the assignment to be constant. The "+:" operator indicates counting upwards from the index value and vice-versa for "-:".
You can do something like,
assign w3[k-1 -: 8 ] = w2[k-1 -: 8]; // Where 8 bits is copied downwards
Search for "+:" in the below document.
http://www.sutherland-hdl.com/papers/2001-Wescon-tutorial_using_Verilog-2001_part1.pdf
Word of caution, generally variable part selects is considered as bad verilog.

i can't understand the following verilog code

i can't understand the two lines at the end of this code
input [15:0] offset ;
output [31:0] pc;
output [31:0] pc_plus_4;
reg [31:0] pc;
wire [31:0] pcinc ;
assign pcinc = pc +4 ;
assign pc_plus_4 = {pc[31],pcinc};
assign branch_aadr = {0,pcinc + {{13{offset[15]}},offset[15:0],2'b00}};
If you are unfamiliar with curly braces {}, they are concatenation operators. You can read about them in the IEEE Std for Verilog (for example, 1800-2009, Section 11.4.12).
assign pc_plus_4 = {pc[31],pcinc};
This concatenates the MSB of pc with all bits of pcinc to assemble the pc_plus_4 signal. However, in this case, since pcinc and pc_plus_4 are both 32 bits wide, pc[31] is ignored. A good linting tool will notify you that the RHS is 33 bits and the LHS is 32 bits, and that the most significant bit will be lost. The line can be more simply coded as:
assign pc_plus_4 = pcinc;
The last line is a compile error for one simulator I'm using. You did not explicitly declare the width of the branch_aadr signal, and the width of the 0 constant is unspecified.
The last line also contains a replication operator, which uses two sets of curly braces.
{13{offset[15]}}
This replicates the bit offset[15] thirteen times. It looks like the author is doing a sign extension on offset before adding it to pcinc. A better way might be to declare offset as signed.
//Three ways to replicate bits
wire [3:0] repeated;
wire value;
//These two assignments have the same effect
assign repeated = {4{value}}; //Replication operator
assign repeated = {value,value,value,value}; //Concatenation operator
//These four taken together have the same effect as the above two
assign repeated[3] = value; //Bit selects
assign repeated[2] = value;
assign repeated[1] = value;
assign repeated[0] = value;

Resources