Does Verilog Module Instantiation Order Matter? - verilog

module parity (
a , // First input
b , // Second input
c , // Third Input
d , // Fourth Input
y // Parity output
);
// Input Declaration
input a ;
input b ;
input c ;
input d ;
// Ouput Declaration
output y ;
// port data types
wire a ;
wire b ;
wire c ;
wire d ;
wire y ;
// Internal variables
wire out_0 ;
wire out_1 ;
// Code starts Here
xor u0 (out_0,a,b);
xor u1 (out_1,c,d);
xor u2 (y,out_0,out_1);
endmodule // End Of Module parity
Suppose I have the module above. Does the order of the xor module declarations matter? If I reordered the declarations likes so:
xor u1 (out_1,c,d);
xor u2 (y,out_0,out_1);
xor u0 (out_0,a,b);
Would the synthesized circuit be the same?

The Verilog language is used to describe behavior of connected hardware-like elements and algorithms. The connections define how the elements are evaluated during simulation and how they are synthesized. The simulation scheduling (and hardware behavior) is based on the events which happen in the connection network.
Therefore, the order in which you instantiate those elements is irrelevant, if you connect them right. For example
module a(input i, output o);
endmodule
module b(input i, output o);
endmodule
module top(input i, output o);
a a1(i, t);
b b1(t, o);
endmodule
as soon as output of the module a a1 is connected to the input of module b b1, it will behave the same as in here:
module top(input i, output o);
b b1(t, o);
a a1(i, t);
endmodule
for readability reasons, you might prefer the first version though.

Related

wire output can be used as an inside variable?

i am learning verilog and i am doing practice questions on https://hdlbits.01xz.net/wiki.
one of the questions is:
so my answer was:
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire and_ab;
wire and_cd;
wire or_out;
and(and_ab,a,b);
and(and_cd, c, d);
or(or_out, and_ab, and_cd);
assign out= or_out;
not(out_n,or_out);
endmodule
which is correct without any doubt, but their answer is:
module top_module (
input a,
input b,
input c,
input d,
output out,
output out_n );
wire w1, w2; // Declare two wires (named w1 and w2)
assign w1 = a&b; // First AND gate
assign w2 = c&d; // Second AND gate
assign out = w1|w2; // OR gate: Feeds both 'out' and the NOT gate
assign out_n = ~out; // NOT gate
endmodule
my question is how can it be possible they use 'output' wire as an 'input' to an assign in the same module? its not reg to hold it value, not that i know if you can do it with reg as an 'output' type.
Verilog and SV allow the reading of outputs from within a module.
It is different than VHDL which does not allow the same.

Verilog: Instantiating arrays in modules

Let's say I have an adder module
module adder(
input [3:0] A,
input [3:0] B,
output [4:0] F
);
assign F = A + B;
endmodule;
and a toplevel module:
module toplevel(
input [3:0] X,
input [3:0] Y,
output [4:0] Z
);
adder adder_1(
.A(X),
.B(Y),
.F(Z)
);
endmodule;
Where I want to instantiate the adder. Would I be able to instantiate a module by assigning numbers to individual bits in its array?
For example can I write something like,
adder adder_1(
.A[0](X[0]),
.A[1](X[1},
and so on. Is there a way I can directly assign bit 0 of A from the adder module to a bit in the top level module?
You can use a temporary wire if your intention is to do some logic operations
on the toplevel port x bit by bit, the example below ands the 2nd bit only
of the port x with 0 and then connects it to the adder module
a quick example
wire [3 : 0] temp;
assign temp[0] = x[0];
assign temp[1] = x[1] & 1`b0;
assign temp[2] = x[2];
assign temp[3] = x[3];
adder adder_1(
.A(temp),
.B(Y),
.F(Z)
);
Yes, it is possible. in your case it would be like :
module toplevel(
input [3:0] X,
input [3:0] Y,
output [4:0] Z
);
adder adder_1(
.A({X[3],X[2],X[1],X[0]}),
.B(Y),
.F(Z)
);
endmodule;

What is the difference between input and reg in Verilog?

I have a circuit whose truth value looks like this A =BC+^C[(B and C) or (not C)]
Here I give,
output A;
input B, C;
wire w1, w2;
and (w1, B, C);
not (w2, C);
or (A, w1, w2);
My question is why do we write input B, C; Can we write it as reg B, C;?
What exactly is the difference?.
You are not showing a complete example, but inputs and outputs are part of a hierarchical module declaration. reg is a data type associated with a signal. Typically one encapsulates your circuit in a module, and then you instantiate that module in a top-level module to provide stimulus and observe the outputs.
module circuit( output wire A;
input wire B, C;
wire w1, w2; // internal wires
and (w1, B, C);
not (w2, C);
or (A, w1, w2);
endmodule
module top;
reg B,C; // these are different signals that get connected to the circuit wires
wire A;
circuit c(A,B,C);
initial begin
B = 0; C = 0;
...
endmodule
comparing input and reg is similar to comparing a keyboard to a verilog code. input defines a direction of a port. reg defines a data type.
However, every port has a data type associated with it. Default data type for an input/output port is wire. So input B is the same as input wire B.
Now, the right question is: what would be a differnce between wire and reg.
wire is a data type for describing connection between module instances. Its main characteristic is that it should always be connected and cannot keep is state otherwise. reg can keep the state if not connected. There are multiple differences in usage which you can find in corresponding verilog tutorials.

Verilog module for ALU but doesn't work properly

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.

How to handle the output and input bus trans by one input in verilog?

I'd like to make a simple module in verilog
The scheme is this.
If(en)
A=B;
else
B=A;
I want to implement to verilog without clock.
Could it be possible to implement the above logic?
update
I want to sum of 2 inout ports.
But I'm not sure how. Would you let me know how can I make sum of 2 inout ports?
Module test1(
en,
A,
B,
C
);
input en;
inout [1:0] A;
inout [1:0] B;
output [3:0] C;
...
What can I do ?
...
endmodule
If(en)
A=B;
else
B=A;
You can't sum the two inout ports A and B. en determines the direction.
Consider this code:
assign A = (en) ? B : 1'bz;
assign B = (~en) ? A : 1'bz;
When en is low, B will be your output and A will be your input.
When en is high, A will be your output and B will be your input.
Your output C will be undefined when you assign the sum of A and B since either of the input is 1'bz.
assign C = A + B; // will cause undefined behavior

Resources