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

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]};

Related

why output of 2nd function call to 4 bit adder is X(don't care)?

I am new to verilog, I was building a 32-bit adder using structural modelling. So I made a 1-bit full adder, then used that to construct a 4-bit adder, and that was used to create an 8- bit adder.
Everything works fine until the 4-bit adder but when I use the 4-bit adder as a function this error pops up.
module adder_1bit(Sum,CarryOut,A,B,CarryIn);
output Sum,CarryOut;
input A,B,CarryIn;
assign Sum = A^B^CarryIn;
assign CarryOut = (A&B) | (B&CarryIn) | (A&CarryIn);
endmodule
module adder_4bit(Sum,CarryOut,A,B,CarryIn);
output [3:0] Sum;
output CarryOut;
input [3:0] A,B;
input CarryIn;
wire w[2:0];
assign CarryIn = 1'b0;
adder_1bit add0(Sum[0],w[0],A[0],B[0],CarryIn);
adder_1bit add1(Sum[1],w[1],A[1],B[1],w[0]);
adder_1bit add2(Sum[2],w[2],A[2],B[2],w[1]);
adder_1bit add3(Sum[3],CarryOut,A[3],B[3],w[2]);
endmodule
module adder_8bit(Sum,CarryOut,A,B,CarryIn);
output [7:0] Sum;
output CarryOut;
input [7:0] A,B;
input CarryIn;
wire w;
assign CarryIn = 1'b0;
adder_4bit add4(Sum[3:0],w,A[3:0],B[3:0],CarryIn);
adder_4bit add5(Sum[7:4],CarryOut,A[7:4],B[7:4],w);
endmodule
When I run with the following testbench code I get MSB 4-bit get as don't care
module adder_test;
reg [7:0] A,B;
reg CarryIn;
wire [7:0] Sum;
wire CarryOut;
adder_8bit UUT (Sum,CarryOut,A,B,CarryIn);
initial
begin
A = 8'b00101011;
B = 8'b01010110;
CarryIn = 1'b0;
#10;
end
endmodule
Simulation Result
Your problem is in this statement: assign CarryIn = 1'b0;
The following happens:
module adder_4bit(Sum,CarryOut,A,B,CarryIn);
...
assign CarryIn = 1'b0;
In this case you have carryIn driven by two drivers:
the input port
the assign statement
Unless the value of the port is the same as your driver (1'b0) the resulting value of carryIn will always be 'x'. This interferes with all your results.
To fix the issue just move this statement to your test bench:
module adder_test;
...
wire CarryOut = 0;

ERROR: 'Checker 'xor_module_b' not found. Instantiation 'x0_1' must be of a visible checker.'?

What is this error 'Checker 'xor_module_b' not found. Instantiation 'x0_1' must be of a visible checker.'? I am writing verilog code in behavioral model by using module instantiation. While compiling i am getting the error. Portion of code and error is attached.
module CSSA4_4bit_modified_b(s,cin,g,G,GP,a,b);
input cin,g,G,GP;
input [7:0] a,b;
output wire [7:0] s;
wire [6:0] c0;
wire [3:0] c1;
wire [2:0] pro;
wire [7:0] s0;
wire [3:0] s1;
always#(a,b,cin,g,G,GP)
begin
//Subblock 1
//Sum bit 0
xor_module_b x0_1(.a(a[0]), .b(b[0]),.s0(s0[0]));
xor_module_b x0_2(.a(s0[0]),.b(cin), .s0(s[0]));
and_logic_b a0 (.a(s0[0]), .b(cin), .out(pro[0]));
//end
//Sum bit 1
FA_b FA_b1(.a(a[1]), .b(b[1]), .c(g),.sum(s0[1]),.cout(c0[0]));
xor_module_b x1 (.a(s0[1]),.b(pro[0]),.s0(s[1]));
and_logic_b a1 (.a(s0[1]),.b(pro[0]), .out(pro[1]));
//end
//Sum bit 2
FA_b FA_b2(.a(a[2]), .b(b[2]), .c(c0[0]),.sum(s0[2]),.cout(c0[1]));
xor_module_b x2 (.a(s0[2]),.b(pro[1]),.s0(s[2]));
and_logic_b a2 (.a(s0[2]),.b(pro[1]),.out(pro[2]));
//end.......continued
//Sum bit 7
FA_b FA_b1_7_1(.a(a[7]),.b(b[7]),.c(c0[5]), .sum(s0[7]),.cout(c0[6]));
FA_b FA_b1_7_2(.a(a[7]),.b(b[7]),.c(c1[2]), .sum(s1[3]),.cout(c1[3]));
sum_select_mux_b M1_7(.Sum(s[7]),.Sum0(s0[7]),.Sum1(s1[3]),.C8k(cin));
//End of subblock 2
//End of CSSA 4-4 bit
end
endmodule
Error Snapshot
You can not instance a module inside an always.
Remove the always#(a,b,cin,g,G,GP)
You don't need the always here but in case you DO need it:
Listing your variable in the always is dangerous. If you forget one you are likely to get mismatches between simulation and reality (gates). Better to let the compiler work it out by using: always #( * )
You can use it in test benches but I can't remember ever needing it.

I have magnitude comparator 4-bit Verilog code and I have wrong output

I have Verilog code: magnitude comparator 4-bit.
I don't know what is wrong.
I have output without (a great than b) and (a less than b).
Where is my mistake?
`timescale 1ns/1ns
module magnitudecomparator(agtb,altb,aeqb,a,b);
input [3:0]a,b;
output agtb,altb,aeqb;
wire [3:0]x;
assign x=!(a^b);
assign agtb=(a[3]&(!b[3]))|(x[3]&a[2]&(!b[2]))|(x[3]&x[2]&a[1]&(!b[1]))|(x[3]&x[2]&x[1]&a[0]&(!b[0]));
assign altb=((!a[3])&b[3])|(x[3]&(!a[2])&b[2])|(x[3]&x[2]&(!a[1])&b[1])|(x[3]&x[2]&x[1]&(!a[0])&b[0]);
assign aeqb=x[3]&x[2]&x[1]&x[0];
endmodule
`timescale 1ns/1ns
module testmagnitudecomparator;
reg a,b;
wire agtb,aeqb,altb;
magnitudecomparator m0(agtb,altb,aeqb,a,b);
initial
begin
#10 a=4'b0110;b=4'b1110;
#20 a=4'b1101;b=4'b0111;
#30 a=4'b1011;b=4'b1011;
end
initial
$monitor($time, "THE VALUE OF INPUT IS a=%b ,b=%b AND OUTPUT IS agtb=%b ,aeqb=%b ,altb=%b",a,b,agtb,aeqb,altb);
endmodule
In your testbench, you connected 1-bit signals to 4-bit ports.
In the testmagnitudecomparator module, change:
reg a,b;
to:
reg [3:0]a,b;
Also, you could simplify your code:
assign agtb = (a > b);
assign altb = (a < b);
assign aeqb = (a == b);
Or you can also use a behavioral code by using if else statements..
always#(*)
begin
if(a>b)
agtb=1'b1;
else if(a<b)
altb=1'b1;
else
aeqb=q'b1;
end

Verilog hdl magnitude comparator error

I have written the simple code below for a magnitude comparator. The 6 bits of C give the values of A=B,A!=B,etc; However, i am getting the following error when i run the code. How can i fix the error?
c2q39.v:7: error: C['sd5] is not a valid l-value in testbench.m.
c2q39.v:3: : C['sd5] is declared here as wire.
My code is
module mag(A,B,C);
input [3:0] A,B;
output [5:0] C;
always # (A or B)
assign C[5]=(A==B);
assign C[4]=(A!=B);
assign C[3]=(A>B);
assign C[2]=(A<B);
assign C[1]=(A>=B);
assign C[0]=(A<=B);
endmodule
module testbench;
reg [3:0] A,B;
wire [5:0] C;
mag m(A,B,C);
initial
begin
A=4'b0000;B=4'b0000;
#10 A=4'b1000;
#10 B=4'b1001;
#10 A=4'b1000;
end
initial
$monitor("%0d %b %b %b",$time,A,B,C);
endmodule
It is not a good idea to use assign statement in always block ( for more details refer here ). So you can define your output C as reg and implement the following way:
module mag(A,B,C);
input [3:0] A,B;
output reg [5:0] C;
always # (A or B)
begin
C[5]=(A==B);
C[4]=(A!=B);
C[3]=(A>B);
C[2]=(A<B);
C[1]=(A>=B);
C[0]=(A<=B);
end
endmodule
The other way to implement is just use assign statements.
module mag(A,B,C);
input [3:0] A,B;
output [5:0] C;
//always # (A or B)
assign C[5]=(A==B);
assign C[4]=(A!=B);
assign C[3]=(A>B);
assign C[2]=(A<B);
assign C[1]=(A>=B);
assign C[0]=(A<=B);
endmodule

Connect 5-bit bus to 32-bit output bus

My design needs multiple multiplexers, all of them have two inputs and most are 32 bits wide. I started with designing the 32 bit, 2:1 multiplexer.
Now I need a 5 bit, 2:1 multiplexer and I want to reuse my 32 bit design. Connecting the inputs is easy (see code below), but I struggle to connect the output.
This is my code:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, result);
When I run the code through iverilog, I get a warning that says that the multiplexer expects a 32 bit output, but the connected bus is only 5 bit wide. The simulation shows the expected results, but I want to get rid of the warning.
Is there a way to tell iverilog to ignore the 27 unused bits of the multiplexer output or do I have to connect a 32 bit wide bus to the output of the multiplexer?
I don't know of a #pragma or something like that (similar to #pragma argsused from C) that can be used in Verilog.
Xilinx ISE, for example, has a feature called "message filtering", which allows the designer to silence specific warning messages. You find them once, select them, choose to ignore, and subsequent synthesis won't trigger those warnings.
Maybe you can design your multiplexer in a way you don't need to "waste" connections (not actually wasted though, as the synthesizer will prune unused connections from the netlist). A more elegant solution would be to use a parametrized module, and instantiate it with the required width. Something like this:
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
This module has been tested with this simple test bench, which shows you how to instantiate a module with params:
module tb;
reg [31:0] a1,b1;
reg sel;
wire [31:0] o1;
reg [4:0] a2,b2;
wire [4:0] o2;
mux #(32) mux32 (a1,b1,sel,o1);
mux #(5) mux5 (a2,b2,sel,o2);
// Best way to instantiate them:
// mux #(.WIDTH(32)) mux32 (.a(a1),.b(b1),.sel(sel),o(o1));
// mux #(.WIDTH(5)) mux5 (.a(a2),.b(b2),.sel(sel),.o(o2));
initial begin
$dumpfile ("dump.vcd");
$dumpvars (1, tb);
a1 = 32'h01234567;
b1 = 32'h89ABCDEF;
a2 = 5'b11111;
b2 = 5'b00000;
repeat (4) begin
sel = 1'b0;
#10;
sel = 1'b1;
#10;
end
end
endmodule
You can test it yourself using this Eda Playground link:
http://www.edaplayground.com/x/Pkz
I think the problem relates to the output of the multiplexer which is still 5 bits wide. You can solve it by doing something like this:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [31:0] temp;
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, temp);
assign result = temp[4:0];
This can be easily tested in http://www.edaplayground.com/ using the code below:
( I have re-used #mcleod_ideafix's code)
// Code your testbench here
// or browse Examples
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
module tb;
reg [31:0] a,b;
wire [31:0] o;
wire [4:0] r;
reg sel;
initial begin
$dumpfile("dump.vcd"); $dumpvars;
a = 10; b = 20; sel = 1;
end
mux MM(a,b,sel,o);
assign r = o[4:0];
endmodule
Let me know if you are still getting a warning.

Resources