Why code is showing z output instead of 1? - verilog

module dulladd (C,A,B);
input A,B;
output C;
wire w1,w2;
not notl (w1,B);
or orl (w1,B);
or or2 (A,w2);
endmodule
/*
* Do not change Module name
*/
module main;
reg A,B;
wire C;
dulladd dulll (C,A,B);
initial
begin
A=0;
B=1;
#5 // Wait 5 time units.
$display ("carry = ",C);
end
endmodule
i need someone to please explain to me in simple terms why my output is z and not 1.

Your simulations shows:
carry = z
because C in the dulladd module is not driven by any logic.
In module dulladd, you declared the C module port:
output C;
However, you did not connect it to anything else. The default type of the port is wire, and the wire type defaults to the z value (high impedance).
You need to connect C to something inside the dulladd module.
Your code is strange in other ways, too. For example, you use or gates, but you only connect 2 signals to them. While this is legal syntax, an or gate would typically have 3 or more connections: one output and 2 or more inputs.
Another oddity is that you connect the module input (A) to the output port of the or gate. From IEEE Std 1800-2017, section 28.4 and, nand, nor, or, xor, and xnor gates:
These six logic gates shall have one output and one or more inputs.
The first terminal in the terminal list shall connect to the output of
the gate and all other terminals connect to its inputs.

Related

What is best way to call another module?

I'm confused about connection, I want to use ALU to call RippleCarry module, and I need to do branch without always block and Procedure Assignment.
I don't know what method is best. I see others have written in TestBench.v or ALU.v.
Here's my code.
ALU.v
module ALU( Signal, a, b, Output );
input [31:0] a, b;
input [5:0] Signal;
output [31:0] Output;
// write here ? or write into test bench?
// if Signal is 6'd35, do RippleCarry.
/*RippleCarry RC( .a(a), .b(b), .Sum(Output) ); */
endmodule
RippleCarray.v
module RippleCarry(
input [31:0] a, b,
input Cin,
output Cout,
output [31:0] Sum
);
In verilog, modules are not called, but instantiated. Unlike traditional programming, verilog is a hardware descriptive language; meaning it is code describing hardware, not specifying instructions to be run by a cpu as you do in typically programming languages. Hardware doesn't materialize and dematerialize when signals take on different values; the control signals simply define which of many different data paths is connected between input and output.
In your case, you wouldnt write something like this:
module ALU(...)
if (Signal == 6'd35) begin
RippleCarry RC(...);
end
endmodule
Since Signal is a control line that changes value as the hardware runs, this would imply the ripple carry adder exists when the Signal is 35 and disappears when it's not.
Instead, the adder should be instantiated, it exists in the design and it always there. The problem now is to direct it's output to the output of the ALU only when Signal is 35.
module ALU(input [5:0] Signal,
input [31:0] a, b,
output reg [31:0] Output); // Note, I made Output a reg so I can use always, it doesn't mean it's actually a register
wire [31:0] rcOutput;
// Instantiate the RC adder so it exists in the hardware
RippleCarry RC(.a(a), .b(b), .Sum(rcOutput));
// Direct the output of the RippleCarry adder to the output only when signal is 35, otherwise just leave it at 0.
// Use switch here to make it easy to add more operations later
always #(*) begin
Output = 32'd0; // default
case (Signal)
6'd35: Output = rcOutput; // rc add
endcase
end
endmodule
Edit: I see now you want to do it without using always or assign, which doesn't change the fundamental design but makes it more obscure and less scalable, which is why I'm leaving the above as a reference. In the case we only have one op code for signal, we can simply implement the logic that compares signal to 35 and masks output if not equal in gates:
// Replace the always block with the below, though it's certainly not as nice, it's a possible implementation of that always block in gates
wire [5:0] SignalN;
wire SignalIs35;
not g1[5:0](SignalN, Signal);
// 35 is 100011 in binary, so see if Signal is that value
and g2(SignalIs35, Signal[5], SignalN[4], SignalN[3], SignalN[2], Signal[1], Signal[0]);
and g3[31:0](Output, rcOutput, {32{SignalIs35}});

How can I fix the error: can't mix packed and unpacked types?

I am trying to build a 4:1 multiplexer using 2:1 multiplexers that I've built. I am getting a few errors whenever I try typing the command vsim mux4_test.
Array connection type 'reg$[1:0]' is incompatible with 'wire[1:0]' for
port (sel): can't mix packed and unpacked types.
Port size (1) does not match connection size (32) for port 'Z'. The
port definition is at: NOT.sv(3).
Illegal output or inout port connection for port 'Z'.
And here's my attempt in doing it:
For 2:1 mux:
module mux2 (
input logic d0, // Data input 0
input logic d1, // Data input 1
input logic sel, // Select input
output logic z // Output
);
logic w1,w2,w3,w4,w5,w6,w7,w8;
NOT # (.Tpdlh(10), .Tpdhl(8)) g1(.Z(w1) , .A(d0));
OR2 # (.Tpdlh(2), .Tpdhl(6)) g4(.Z(w5), .A(w1), .B(w4));
NOT # (.Tpdlh(10), .Tpdhl(8)) g2(.Z(w2) , .A(d1));
OR2 # (.Tpdlh(2), .Tpdhl(6)) g5(.Z(w6), .A(w2), .B(w3));
NOT # (.Tpdlh(10), .Tpdhl(8)) g3(.Z(w3) , .A(w4));
NOT # (.Tpdlh(10), .Tpdhl(8)) g6(.Z(w7) , .A(w5));
NOT # (.Tpdlh(10), .Tpdhl(8)) g7(.Z(w8) , .A(w6));
OR2 # (.Tpdlh(2), .Tpdhl(6)) g8(.Z(z) , .A(w7), .B(w8));
endmodule
for 4:1 mux:
module mux4 (
input logic d0, // Data input 0
input logic d1, // Data input 1
input logic d2, // Data input 2
input logic d3, // Data input 3
input logic [1:0] sel, // Select input
output logic z // Output
);
logic w1,w2;
mux2 mux2a(
.d0(d0),
.d1(d1),
.sel(sel[0]),
.z(w1)
);
mux2 mux2b(
.d2(d0),
.d3(d1),
.sel(sel[0]),
.z(w2)
);
mux2 mux2c(
.d0(w1),
.d1(w2),
.sel(sel[1]),
.z(z)
);
endmodule
and finally my testbench
module mux4_test;
logic d0,d1,d2,d3,sel[1:0], z;
mux4 m4a(
.d0(d0),
.d1(d1),
.d2(d2),
.d3(d3),
.sel(sel),
.z(z)
);
initial begin
d0=1'b0;
d1=1'b0;
d2=1'b0;
d3=1'b0;
sel[0]=1'b0;
sel[1]=1'b0;
#20
d0=1'b1;
d1=1'b0;
d2=1'b0;
d3=1'b0;
sel[0]=1'b0;
sel[1]=1'b0;
end
endmodule
Array connection type 'reg$[1:0]' is incompatible with 'wire[1:0]' for port (sel): can't mix packed and unpacked types.
Here sel is defined as an unpacked array of 2 single bits:
logic d0,d1,d2,d3,sel[1:0], z;
Here is the definition of the port where sel is defined as packed array (vector) of 2 bits.
input logic [1:0] sel
System verilog does not allow assignments between them. so, the port .sel(sel), causes the issue. To fix, you need to declare both the same way. I suggest to change declaration of the variable to
logic [1:0] sel;
Port size (1) does not match connection size (32) for port 'Z'. The port definition is at: NOT.sv(3).
This points to the file NOT.sv, which seems to be a definition of the module NOT. you need to provide this module in your example.
Port size (1) does not match connection size (32) for port 'Z'. The port definition is at: NOT.sv(3).
Could you please share the definition of NOT.sv? It appears your problem is there (I note you are using your own implementation of those gates rather than the verilog primitives). Looks like you may have a port mismatch between NOT.sv and your 2mux.
This is a copy of the Answer I posted on electronics.stackexchange.com. I saw the Question there before I realized it was also posted here.
The 1st compile error I get is related to the sel port.
In module mux4_test, change:
logic d0,d1,d2,d3,sel[1:0], z;
to:
logic d0,d1,d2,d3, z;
logic [1:0] sel;
sel[1:0] (unpacked) is not the same as [1:0] sel (packed).
The 2nd compile error I get is related to the mux2b instance. Change:
mux2 mux2b(
.d2(d0),
.d3(d1),
.sel(sel[0]),
.z(w2)
);
to:
mux2 mux2b(
.d0(d2),
.d1(d3),
.sel(sel[0]),
.z(w2)
);
mux2 does not have d2 and d3 ports.
Your code compiles cleanly for me. I do not see errors related to the Z port; here is the code on edaplayground
We concluded that the Z error was a bug in the user's simulator. The OP updated to the latest version of ModelSim, and now all errors are gone.

How do I write this verilog testbench?

I am using Vivado to try to write a testbench for some Verilog code I wrote for an FSM. Here is the timing diagram which I derived from the state diagram:
.
Below is what I have so far:
module testbench();
reg X_tb, clk_tb, rstn_tb;
wire S_tb, V_tb;
statemachine statemachine_tb(X_tb, clk_tb, rstn_tb, S_tb, V_tb);
initial begin
#10 X_tb = 0;
end
endmodule
If X_tb and clk_tb are inputs and S_tb and V_tb are outputs, how do I include timing for S_tb and V_tb? I keep getting an error saying I can't use wire variables.
S_tb and V_tb are the expected outputs which are asserted by the design module which in this case is "statemachine".
The test bench encompasses the design, it acts as a stimulus for your design. In this case you will apply inputs like
initial
begin
rstn_tb = 0; //assuming an active low reset
clk_tb = 0;
#10 X_tb = 0;
end
always
#5 clk_tb = ~clk_tb; //generates a clock having a frequency of 100MHz
The above inputs are passed on-to the statemachine module and in response to that the statemachine module generates some result which is received at the ports S_tb & V_tb.
Also while instantiating the module its better to use the dot-name convention like
module half_add(a,b,sum,carry); //half adder, partially written
input a,b;
output sum,carry;
//logic
endmodule
module full_add(a,b,cin,sum,carry)
input a,b,cin;
output sum,carry;
//wires are not declared
//instantiating half_add
half_add h1(.a(w1),
.b(w2),
.sum(sum1),
.carry(carry1)
);
half_add h2(
//similar call as h1 instance
);
endmodule
The above type of instance avoids errors now if I instantiate the module like the one below
half_add h1(w1,
w2,
sum1,
carry1
);
Here the ports are connected based on the position and one may make mistakes while writing this like accidentally one may write
half_add h1(w1,
w2,
carry1,
sum1
);
This will cause carry1 to be connected to the sum port of the half adder module resulting in erroneous output. Hence I suggest you to avoid such type of instance calling. I guess that could be the reason for the error.
You don't need to provide timing delays for your state machine outputs. You are building a synchronous design; therefore the outputs should simply be sampled on the relevant clock edges (falling edge from your instructions). You can do this by embedding the following line in your testbench everytime you want to wait for a clock edge:
# (negedge clk_tb)
You can then capture the outputs or directly perform comparisons to expected values. Then change your input stimulus and wait for another clock edge and repeat for your next comparison.

Designing a 3-bit counter using T-flipflop

module tff(t,i,qbprev,q,qb);
input t,i,qbprev;
output q,qb;
wire q,qb,w1;
begin
assign w1=qbprev;
if(w1==1)begin
not n1(i,i);
end
assign q=i;
not n2(qb,i);
end
endmodule
module counter(a,b,c,cin,x0,x1,x2);
input a,b,c,cin;
output x0,x1,x2;
reg a,b,c,x0,x1,x2,temp,q,qb;
always#(posedge cin)
begin
tff t1(.t(1) ,.i(a),.qbprev(1),.q(),.qb());
x0=q;
temp=qb;
tff t2(.t(1) ,.i(b),.qbprev(temp),.q(),.qb());
x1=q;
temp=qb;
tff t3(.t(1) ,.i(c),.qbprev(temp),.q(),.qb());
x2=q;
a=x0;
b=x1;
c=x2;
end
endmodule
This is my code in verilog. My inputs are - the initial state - a,b,c and cin
I get many errors with the first of them being "w1 is not a constant" What doesn this mean?
I also get error "Non-net port a cannot be of mode input" But I want a to be an input!
Thank you.
Modules are instantiated as pieces of hardware. They are not software calls, and you can not create and destroy hardware on the fly therefore:
if(w1==1)begin
not n1(i,i);
end
With that in mind I hope that you can see that unless w1 is a constant parameter, and this is a 'generate if' What your describing does not make sense.
instance n1 is not called or created as required, it must always exist.
Also you have the input and output connected to i. i represent a physical wire it can not be i and not i. these need to be different names to represent different physical wires.
In your second module you have :
input a,b,c,cin;
// ...
reg a,b,c; //...
Inputs can not be regs as the warning says, just do not declare them as regs for this.
input a,b,c,cin;
output x0,x1,x2;
reg x0,x1,x2,temp,q,qb;

Tasktop.v(10): (vlog-2110) Illegal reference to net "b"

I am writing a program in verilog. Total 3 AND Gates, the output of first 2 AND Gates is input to the 3rd Gate, and i am required the output of 3rd Gate. Please let me know what is the problem with my program. I am attaching my Program
//enter Top Module
module TOP;
wire a,b;
reg out;
initial
begin
#3 a=1;
#3 b=1;
#3 b=0;
end
Two_AND s(a,b,out);
endmodule
//.....................
//Main Program
module Two_AND (a,b,out);
input a,b;
output out;
reg out;
and g1(out1,a,b);
and g2(out2,b,c);
and g3(out3,out1,out2);
endmodule
In module Two_AND (a,b,out); you have these lines:
and g2(out2,b,c);
c is not defined.
out1, out2 and out3 are also not defined but are outputs and will be created as 1 bit wires by default which is ok in this instance.
but your output out is not driven, where you have used out3 you need to use out.
module Two_AND (
input a,
input b,
input c,
output out
);
wire out1,out2;
and g1(out1,a,b);
and g2(out2,b,c);
and g3(out,out1,out2);
endmodule
#Morgan is right.
However, the error you get is because there is something wrong with your TOP module.
You should have defined a and b as reg and out as wire.
Only regs can be assigned within an initial or always block.
And outputs of modules should be connected to wires.
Also, since an input c is added to your module, you should consider it while you are instantiating your Two_AND in your TOP module.
I think the previous answers were very instructive and helpful. I only want to add a small tip. I recommend you that always add `default_nettype none to your verilog codes. for example you have used "out1" and "out2" wires but you haven't define them. if you don't want to be confused, you should add that to your codes.

Resources