I've been looking at some verilog code and came across something I've never seen before and have not been able to find information about online.
module FA_n_bit(c_out, Sum, A, B, c_in);
parameter word_size = 4; // the default size of this n bit adder
input [word_size-1:0] A, B;
input c_in;
output [word_size-1:0] Sum;
output c_out;
wire [word_size-1:0] c_inner;
// the c_out of the ith 1-bit full aderr is the c_in of the (i+1)th full adder
FA_one_bit fullAdder [word_size-1:0](
{c_out, c_inner[word_size-1:1]},
Sum,
A,
B,
{c_inner[word_size-1:1], c_in}
);
endmodule
I understand the parameter syntax, but I am having a hard time understanding what the FA_one_bit fullAdder [word_size-1:0] (...) syntax does.
any help would be greatly appreciated.
So far I think that its declaring 4 fullAdders but I get lost at the concatenation of the c_out and c_inner[word_size-1:1].
The FA_one_bit is another module instantiated inside FA_n_bit module. The instance name is fullAdder. Also, [word_size-1:0] indicates that word_size number of instances are created.
In Verilog, when you are instantiating a module, that means you are adding extra hardware to the board. Here, 4 fullAdders are added.
Concatenations are expressed using the brace characters { and }, with commas separating the expressions within. Referring to SystemVerilog LRM IEEE 1800-2012, section 11.4.12:
A concatenation is the result of the joining together of bits resulting from one or more expressions. The
concatenation shall be expressed using the brace characters { and }, with commas separating the expressions
within.
// if a, b and c are 8-bit numbers, the results has 24 bits
For Example: {a, b[3:0], c, 4'b1001}
Here, {c_out, c_inner[word_size-1:1]} means 1-bit of c_out and word_size-1 bits of c_inner from MSB are concatenated. This shall result in a signal of width word_size.
Yet another example from LRM:
{a, b[3:0], w, 3'b101}
// equivalent to the following
{a, b[3], b[2], b[1], b[0], w, 1'b1, 1'b0, 1'b1}
The MSB of concatenated signal is c_out and MSB-1 position is for c_inner[word_size-1] and LSB of signal is c_inner[1].
For more information on array of instances, refer to Array of modules link. Refer IEEE 1800-2012 section 11.4.12 for concatenation operator.
Related
I wanna create divisible by 6 module in verilog using divisible by 2 module and divisible by 3 module, I grasped the idea, but maybe my verilog grammar is wrong.
the module structure i want to implement is below,
module Divisible_6(input [3:0] a, output out);
using
module Divisible_2(
input [3:0] a,
output out
);
module Divisible_3(
input [3:0] a,
output out
);
and if input is 6(0110), then both divisible_2 and divisible_3 output 1,
and both 1 goes in to the AND gate, then came out with 1.
1 = true, 0 = false.
how can I implement the idea in verilog language?
and help is appreciated, thanks.
input: 1~15
Since I understand question a little bit different than #Morgan, I'd rather try this code:
module Divisible_6(
input [3:0] a,
output out
);
wire out_1, out_2;
assign out = out_1 & out_2;
Divisible_2(
.a (a),
.out(out_1)
);
Divisible_3(
.a (a),
.out(out_2)
);
endmodule
I assume that both Divisible_2 and Divisible_3 take 4-bit input and return boolean value (divisible (1) or not (0)).
You need divisible by 6 design, which can only be obtained, if your input is both divisible by 2 and divisible by 3.
Hence you can use both modules, like the following code.
// Defining the nets
logic out1, out2;
// Continuous Assignment
assign out = out1 & out2;
// Instantiation of 2 modules with instance name d1 & d2
divisible_2 d1 (a, out1);
divisible_3 d2 (a, out2);
I am trying to write down ALU for verilog.
And there are several error I experiences.
First of all, here is my code:
module yAlu(z, ex, a, b, op);
input [31:0] a, b;
input [2:0] op;
output [31:0] z, ztemp;
output ex;
wire[31:0]a0,a1,a2,a3,a4, atemp;
assign slt = 0;
assign ex = 0;
assign a0 = a & b;
assign a1 = a | b;
assign a2 = a + b;
assign a3 = a - b;
assign a4 = a[31] ^ b[31];
yMux #(32) lo(zLo, a0, a1, op[0]);
yMux #(32) hi(zHi, a2, a3, op[0]);
yMux #(32) temp(atemp, zLo, zHi, op[1]);
assign z = (op[2] == 1) ? a4 : atemp;
assign slt = z;
endmodule
And yAlu.v uses following:
module yMux(z, a, b, c);
parameter SIZE = 2;
output [SIZE-1:0] z;
input [SIZE-1:0] a, b;
input c;
yMux1 mine[SIZE-1:0](z, a, b, c); // 2-bit 2 -to-1 mux and it would be cumbersome to write 32 mux instantiation lines.
endmodule
Lastly above yMux uses following:
module yMux1(z, a, b, c);
output z;
input a, b, c;
wire notC, upper, lower;
// Gates and interconnections for MUX
// if c is 0, z=a.
// if c is 1, z=b
not my_not(notC, c);
and upperAnd(upper, a, notC);
and lowerAnd(lower, c, b);
or my_or(z, upper, lower);
endmodule
Here is is what it tests above yAlu:
module lab8;
reg [31:0] a, b;
reg [31:0] expect;
reg [2:0] op;
wire ex;
wire [31:0] z;
reg ok, flag;
yAlu mine(z, ex, a, b, op);
initial begin
repeat (10) begin
a = $random; b = $random;
if(op==0)
expect = a & b;
else if (op==1)
expect = a | b;
else if (op==2)
expect = a + b;
else if (op==3)
expect = a - b;
else if (op==4)
expect = (a < b) ? 1 : 0;
#1;
if(expect == z)
$display("PASS : expected=%d, a=%d, b=%d, z=%d, op=%d", expect,a,b,z,op);
#1;
$finish;
end
end
endmodule
My questions in order as follow:
Question 1.
Code above only works for 0 and 1. It doesn't work more than that.
For example, on the 2nd source code, there is
a = $random; b = $random;
it doesn't work for this. it only works when a=1 or 0 and b=1 or 0.
Question 2.
I am not sure "slt" function is working correctly. The instructor who teaches this never told me what slt does in lecture but have us design slt, by googling or something.
Question 3.
Whenever I compile, i get following Error. Why is this?
yAlu.v:38: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:38: : Padding 31 high bits of the port.
yAlu.v:39: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:39: : Padding 31 high bits of the port.
yAlu.v:40: warning: Port 2 (a) of yMux expects 32 bits, got 1.
yAlu.v:40: : Padding 31 high bits of the port.
yAlu.v:40: warning: Port 3 (b) of yMux expects 32 bits, got 1.
yAlu.v:40: : Padding 31 high bits of the port.
I can't fix this at all.
I don't even know I am doing it correctly. The manual that directs me to do what it says has no enough explanation as well as no sample output.
I couldn't finish in time anyway, so I guess it doesn't matter but I think I have to know solution for my problems.
Thank you very much if you can help me out.
As shown by the warnings, your port connection width are mismatched. Refer to single warning and other are the same to tackle.
yAlu.v:38: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:38: : Padding 31 high bits of the port.
The module declares ports a,b,c and z, each of width defined by SIZE parameter.
module yMux(z, a, b, c);
parameter SIZE = 2;
output [SIZE-1:0] z;
input [SIZE-1:0] a, b;
Moreover, the SIZE is overridden while instantiating. Now, the value of SIZE is 32. Hence the width of each of a,b,c and z is 32-bits.
yMux #(32) lo(zLo, a0, a1, op[0]);
yMux #(32) hi(zHi, a2, a3, op[0]);
yMux #(32) temp(atemp, zLo, zHi, op[1]);
Here, the ports zLo,zHi is not declared and used directly in port connection.
Referring to IEEE 1800-2012, section 6.10- Implicit declarations:
If an identifier is used in a port expression declaration, then an
implicit net of default net type shall be assumed, with the vector
width of the port expression declaration.
This, if an undeclared identifier is used as a connection to an instance then an implicit net is inferred.
Thus, zLo,zHi are implicitly declared as single bit nets and the rest 32-bits are padded with zeros. Just declare them as follows and all warnings shall be removed:
wire [31:0] zLo,zHi;
To get an error in such a situation, use default_nettype none compiler directive.
For more information, refer Sutherland SV Gotchas paper, section 2.2 and SystemVerilog IEEE 1800-2012 for implicit declarations.
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.
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]
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.