Getting Z and X at output for a basic Full Adder - verilog

I have been designing a basic full adder with two half adder modules and trying to test it with a testbench. There are no compile errors, but at the output (Waveform), I get Z and X for Sum and Carry. I am stuck and not sure what next to look at to correct this error.
Any advice in what next steps (or some pointers) to be checked in order to rectify this would be helpful.
Here is the Verilog code for the Full Adder:
module half_adder(x,y,S,C);
input x,y;
output S,C;
xor G1(S,x,y);
and G2(C,x,y);
endmodule
module full_adder(x,y,z,S,C);
input x,y,z;
output S,C;
wire S1,C1,C2;
half_adder HA1(S1,C1,x,y);
half_adder HA2(S,C2,S1,z);
or G3(C,C1,C2);
endmodule
Testbench for the above:
module tb_fulladder;
wire S,C;
reg x,y,z;
full_adder DUT(x,y,z,S,C);
initial
begin
x=1'b0;y=1'b0;z=1'b0;
#50
x=1'b0;y=1'b0;z=1'b1;
#50
x=1'b0;y=1'b1;z=1'b0;
#50
x=1'b0;y=1'b1;z=1'b1;
#50
x=1'b1;y=1'b0;z=1'b0;
#50
x=1'b1;y=1'b0;z=1'b1;
#50
x=1'b1;y=1'b1;z=1'b0;
#50
x=1'b1;y=1'b1;z=1'b1;
end
initial
#500
$finish;
endmodule
Here is the waveform:

You made a mistake in your connections to half_adder. You need to change the order of the port signals. Change:
half_adder HA1(S1,C1,x,y);
half_adder HA2(S,C2,S1,z);
to:
half_adder HA1 (x,y,S1,C1);
half_adder HA2 (S1,z,S,C2);
I discovered this by looking at the waveforms for the internal full and half adder signals.
This is why it is better to use connection-by-name instead of connection-by-position. For example, use:
half_adder HA1 (.x(x), .y(y), .S(S1), .C(C1));
Using this syntax, the port order does not matter. Refer to the free IEEE Std 1800-2012, 23.3.2 Module instantiation syntax.

Related

Why is the SR latch output always X?

I am implementing SR latch without clock signal using Verilog. I am trying with the code given below, but I am getting the value of Qb as X. Please help me.
// design.v file
module sr_latch(q,qb,s,r);// module declaration
input s,r;
output q,qb;
assign qb=~q;
nand (q,s,qb);
nand (qb,r,q);
endmodule
// testbench.v file
module stimulus;
reg set,reset;
wire Q,Qb;
sr_latch mylatch(Q,Qb,set,rest);
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
$monitor($time,"set=%b,reset=%b,Q=%b,Qb=%b\n",set,reset,Q,Qb);
set=0; reset=0;
#5 set=0; reset=1;
#5 set=1; reset=0;
#5 set=1; reset=1;
end
endmodule
Result:
0set=0,reset=0,Q=1,Qb=x
5set=0,reset=1,Q=1,Qb=x
10set=1,reset=0,Q=x,Qb=x
15set=1,reset=1,Q=x,Qb=x
There are 2 errors in your code.
In your design file, you have 2 drivers for the qb signal, but you should only have 1. You should delete the following line:
assign qb=~q;
You have a typo in the testbench; I got a compile warning about this in one of the simulators on edaplayground. You misspelled reset as rest. Change:
sr_latch mylatch(Q,Qb,set,rest);
to:
sr_latch mylatch(Q,Qb,set,reset);
Result:
0set=0,reset=0,Q=1,Qb=1
5set=0,reset=1,Q=1,Qb=0
10set=1,reset=0,Q=0,Qb=1
15set=1,reset=1,Q=0,Qb=1

I am getting unknown value when doing a 4 bit shifter verilog (gate level)

I am trying to implement a 4 bit right shifter using gate level but i got unknown result for some reason, my mux work ok but when i try testbench for my shifter it give back something like this:
a=0010 b=01 c=0000
a=1111 b=01 c=00xx
Please help!!!! Thank you very much
module mux2(a,b,sel,c);
output c;
input a,b,sel;
wire net0,net1,net2;
not m1(net0,sel);
and m2(net1,a,net0);
and m3(net2,b,sel);
or m4(c,net1,net2);
endmodule
module mux4(a,sel,c);
output c;
input [1:0]sel;
input[3:0]a;
wire mux_1,mux_2;
mux2 m1(a[3],a[2],sel[0],mux_1);
mux2 m2(a[1],a[0],sel[0],mux_2);
mux2 m3(mux_1,mux_2,sel[1],c);
endmodule
module shift4bitright(c,a,b);
output [3:0]c;
input [3:0]a;
input [1:0]b;
wire [3:0]d=4'h0,d1=4'h0,d2=4'h0,d3=4'h0;
assign d[0]=a[3];
assign d1[0]=a[2]; assign d1[1]=a[3];
assign d2[0]=a[1]; assign d2[1]=a[2]; assign d2[2]=a[3];
assign d3[0]=a[0]; assign d3[1]=a[1];assign d3[2]=a[2];assign d3[3]=a[3];
mux4 m1(d,b,c[3]);
mux4 m2(d1,b,c[2]);
mux4 m3(d2,b,c[1]);
mux4 m4(d3,b,c[0]);
endmodule
`timescale 10ns/1ns
module shift4bitright_tb;
wire [3:0]c;
reg [3:0]a;
reg [1:0]b;
shift4bitright s1(.c(c),.a(a),.b(b));
initial begin
$monitor("a=%b b=%b c=%b",a,b,c);
a=4'h2;
b=2'd1;
#50
a=4'hf;
b=2'd1;
end
endmodule
This statement declared a wire type signal d as well as its driver cone (NOT initial value), which is a constant 0 in this case:
wire [3:0]d=4'h0;
Just below it, there's another a[3] driving d[0]:
assign d[0]=a[3];
This creates a multi-driven logic, hence x occurs.
To solve it, change it similar to:
wire [3:0] d;
assign d = {3'h0, a[3]};

Can input port be of type reg in verilog?

In my textbook there is a side note that input or inout ports can never be a reg, as this will result in perpetual 'x' in the port. However, when I wrote a code for AND gate with input ports set as reg types, it worked fine.
AND GATE:
//AND Gate
`timescale 1ns/100ps
module test(output C, input reg A,B);
assign C = A & B;
endmodule
Test Bench:
//AND GATE TEST BENCH
`timescale 1ns/100ps
module AND_tb;
//Declaring Variables
wire Cwatch;
reg [1:0] stim;
initial begin
#1 stim = 2'b00;
#1 stim = 2'b01;
#1 stim = 2'b10;
#1 stim = 2'b11;
#1 $stop;
end
test AND_1 (
.C(Cwatch),
.A(stim[0]),
.B(stim[1])
);
endmodule
And here is the paragraph from the textbook
You have not told which simulator you use.
But yes, I also noticed that some simulators have no problem with a input defined as 'reg'. I regard it as an idiosyncrasy of the simulator.
However as soon as you try to synthesize it is likely1 to fail.
1: I have yet to find a synthesis tool which accepts input reg it but I have not tried all existing ones.

output is not continuously changing in 2x4 decoder testbench

my 2x4 decoder code:
`timescale 1ns/100ps
module decoder(in,out);
input [1:0]in;
output [3:0]out;
reg [3:0]out;
always#(in)
begin
case(in)
2'b00:out = 4'b0001;
2'b01:out = 4'b0010;
2'b10:out = 4'b0100;
2'b11:out = 4'b1000;
default:out = 4'b1111;
endcase
end
endmodule
// **I have written behavior code for 2x4 decoder and test bench. What I am seeing in my output is only it is showing me the output at 11...which is 0011. I want to see output changing continuously whenever my input is changing.
can any body show my mistake ??**
piece of code//
`timescale 1ns / 100ps
module decoder_t;
reg [1:0]in;
wire [3:0] out;
decoder decoder1 ( .in(in),.out(out) );
initial
begin
#10 in=2'b00;
#10 in=2'b01;
#10 in=2'b10;
#10 in=2'b11;
#10 $stop;
end
endmodule
The Verilog runs as expected. Best guess is the user is observing the value of in and out at $stop and not before. My recommendation is to add a $monitor statement to report the value changes.
For example, add $monitor("%t: in:%b out:%b", $realtime, in, out); just before #10 in=2'b00; in the test bench. Then the log file will include the following:
0: in:xx out:xxxx
100: in:00 out:0001
200: in:01 out:0010
300: in:10 out:0100
400: in:11 out:1000
Update: waveform dumping
Assuming you are dumping to a standard value change dump (VCD) file as defined in all version of IEEE Std 1364 and IEEE Std 1800. Add $dumpfile("dump.vcd"); $dumpvars; before driving the stimulus (i.e. just before #10 in=2'b00;). Refer to IEEE Std 1364-1995 section 15 (section 18 for newer version of IEEE 1364), or IEEE Std 1800-2012 (available for free from IEEE) section 21.7, to see usage of all $dump* system tasks.
If you are using a different tool for waveform generation, then refer to the manual. 97% chance the placement of the system task(s) will need to be called before driving the stimulus, just like $dumpvars and $monitor.

Verilog 4 bit multiplier?

I'm having problems on how to create a test module for the following Verilog code:
module Multiplier_4bit(output [8:0] y, input [3:0] i1, input [3:0] i2);
assign y=i1*i2;
endmodule
I thought of the following test module:
module M4_Tester
reg [3:0] i1;
reg [3:0] i2;
wire [9:0] y;
initial begin
i1=5;
i2=3;
$finish();
Multiplier_4bit device1(
.out(y),
.in0(i1),
.in1(i2)
);
endmodule
Please correct me if I'm wrong and sorry for bad english, as I am not a native speaker.
Thanks in advance.
You cannot instantiate a module inside of a begin block (put the multiplier somewhere outside of your initial begin block.
You have no corresponding end which closes the initial begin block.
Your simulation will terminate instantly because there is no delay between setting the values and the $finish. Put some nominal time delay before the simulation finishes with #10 $finish().
Next time please clarify your question before asking, and post the actual error messages you are receiving.

Resources