Related
Below is my code. It was supposed to output the addition of B+C when 'Odds' is true, and the subtraction of B-C when 'Evens' is true and 'Odds' is false. And then 0 when neither are true. I am getting ZZZ for the output of my full adder below - although all of the logic should be correct. I have checked multiple times...If you can help identify why my code is working that would be greatly appreciated.
module ECE228_2(
input [7:0] A,
input [3:0] B,
input [3:0] C,
output [4:0] Out
);
wire Odds, XEvens, Evens;
wire [3:0]Bit4AddOut, Bit4AddCarry, Bit4SubOut, Bit4SubCarry, NotC;
wire [4:0]EvenMuxOut;
//C inversion for 2's Complement Subtraction
not xC0(NotC[0],C[0]);
not xC1(NotC[1],C[1]);
not xC2(NotC[2],C[2]);
not xC3(NotC[3],C[3]);
//Generate The Xor of the Odd Positions to check for odd # of 1's
xor xo0(Odds,A[1],A[3],A[5],A[7]);
//Generate the Xor of the Even Positions and reverse it to check for even # of 1's
xor xo1(XEvens,A[0],A[2],A[4],A[6]);
not evenflip(Evens,XEvens);
//4 Bit Add of B and C in case it is desired output
FullAdd FA0(B[0],C[0],1'b0,Bit4AddOut[0],Bit4AddCarry[0]);
FullAdd FA1(B[1],C[1],Bit4AddCarry[0],Bit4AddOut[1],Bit4AddCarry[1]);
FullAdd FA2(B[2],C[2],Bit4AddCarry[1],Bit4AddOut[2],Bit4AddCarry[2]);
FullAdd FA3(B[3],C[3],Bit4AddCarry[2],Bit4AddOut[3],Bit4AddCarry[3]);
//4 Bit Subtract of B and C in case it is desired output
FullAdd FAS0(B[0],NotC[0],1'b1,Bit4SubOut[0],Bit4SubCarry[0]);
FullAdd FAS1(B[1],NotC[1],Bit4SubCarry[0],Bit4SubOut[1],Bit4SubCarry[1]);
FullAdd FAS2(B[2],NotC[2],Bit4SubCarry[1],Bit4SubOut[2],Bit4SubCarry[2]);
FullAdd FAS3(B[3],NotC[3],Bit4SubCarry[2],Bit4SubOut[3],Bit4SubCarry[3]);
//2:1 Mux with even positions check as sel and (A-B) as true cases and 00000 as false case (5 Bits)
MUX2_1 EvenMux0(Bit4SubOut[0],1'b0,Evens,EvenMuxOut[0]);
MUX2_1 EvenMux1(Bit4SubOut[1],1'b0,Evens,EvenMuxOut[1]);
MUX2_1 EvenMux2(Bit4SubOut[2],1'b0,Evens,EvenMuxOut[2]);
MUX2_1 EvenMux3(Bit4SubOut[3],1'b0,Evens,EvenMuxOut[3]);
MUX2_1 EvenMux4(Bit4SubCarry[3],1'b0,Evens,EvenMuxOut[4]);
//2:1 Mux with odd positions check as sel and (A+B) as true case and even check as false case
MUX2_1 OddMux0(Bit4AddOut[0],EvenMuxOut[0],Odds,Out[0]);
MUX2_1 OddMux1(Bit4AddOut[1],EvenMuxOut[1],Odds,Out[1]);
MUX2_1 OddMux2(Bit4AddOut[2],EvenMuxOut[2],Odds,Out[2]);
MUX2_1 OddMux3(Bit4AddOut[3],EvenMuxOut[3],Odds,Out[3]);
MUX2_1 OddMux4(Bit4AddCarry[3],EvenMuxOut[4],Odds,Out[4]);
endmodule
//Need a 2:1 MUX Module
module MUX2_1(
input MuxTrue,
input MuxFalse,
input MuxSel,
output MuxOut
);
wire MuxA1, MuxA2, XMuxSel;
//Selector Not
not XSel(XMuxSel,MuxSel);
//When Sel is 1
and MATrue(MuxA1,MuxTrue,MuxSel);
//When Sel is 0
and MAFalse(MuxA2,MuxFalse,XMuxSel);
//Or of the cases
or MuxOr(MuxOut,MuxA1,MuxA2);
endmodule
//Need a Full Adder Module
module FullAdd(
input FAin1,
input FAin2,
input FACin,
output FAOut,
output FACout
);
wire FAWHA1Out,FAWHA1Cout,FAWHA2Cout;
//Both calls to Half Adder
HalfAdd FA_HA1(FAin1,FAin2,FAWHA1Cout,FAWHA1Out);
HalfAdd FA_HA2(FAWHA1Out,FACin,FAWHA2Cout,FAout);
or FAOr(FACout,FAWHA1Cout,FAWHA2Cout);
endmodule
//Need a Half Adder Module
module HalfAdd(
input HAin1,
input HAin2,
output HACout,
output HAOut
);
//Gate design of a half adder
//Add but output 0 for carryover condition
xor HAXOR(HAOut,HAin1,HAin2);
//check for carryover condition
and HAAND(HACout,HAin1,HAin2);
endmodule
Here is the test bench:
module ECE228_2_test;
reg [7:0]A;
reg [3:0]B;
reg [3:0]C;
wire [4:0]Out;
ECE228_2 uut (
.A(A),
.B(B),
.C(C),
.Out(Out)
);
initial
begin
B = 4'b0111; //B = 7
C = 4'b0011; //C = 3
//Start counting
A = 8'b00000000;
#10 A = 8'b00000001;
#10 A = 8'b00000010;
#10 A = 8'b00000011;
#10 A = 8'b00000100;
#10 A = 8'b00000101;
#10 A = 8'b00000111;
#10 A = 8'b00001000;
//Too many to count - Lets do some random instead
#10 A = 8'b11011000;
#10 A = 8'b00011110;
#10 A = 8'b10100101;
#10 A = 8'b00110101;
#10 A = 8'b11001010;
#10 A = 8'b11100001;
#10 A = 8'b11111111;
#10 A = 8'b01011010;
#10 A = 8'b01110010;
end
endmodule
Here is the output of the objects:
Verilog is a case-sensitive language. This means that the signal named FAout is different from the one named FAOut.
The FullAdd module output port, FAOut, is undriven, which means it will have the high-impedance value (z). You likely meant to connect the output of the FA_HA2 instance to the FAOut port instead of the signal named FAout.
Here is the fixed version of the module:
module FullAdd(
input FAin1,
input FAin2,
input FACin,
output FAOut,
output FACout
);
wire FAWHA1Out,FAWHA1Cout,FAWHA2Cout;
//Both calls to Half Adder
HalfAdd FA_HA1(FAin1,FAin2,FAWHA1Cout,FAWHA1Out);
HalfAdd FA_HA2(FAWHA1Out,FACin,FAWHA2Cout,FAOut);
or FAOr(FACout,FAWHA1Cout,FAWHA2Cout);
endmodule
The full adder no longer has z output.
By default, Verilog does not require you to declare all signals. You could also change the default behavior and require explicitly declared signals using this compiler directive:
`default_nettype none
This helps you find common coding mistakes like this.
Error-[IND] Identifier not declared
Identifier 'FAout' has not been declared yet. If this error is not expected,
please check if you have set `default_nettype to none.
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;
`timescale 100ns/1ps
module CarryLAS_tb;
reg [7:0] a;
reg [7:0] b;
reg ci;
wire [7:0] sum;
wire of; //overflow
wire co;
integer i;
CarryLAS_8 CLA(a,b,ci,sum,co,of);
initial begin
a=0;
b=0;
ci=0;
end
initial begin // all possible cases
for(i=0; i<262144; i=i+1) // 2^18
#10 {a, b, ci} = i;
end
endmodule
module CarryLAS_8(a,b,ci,sum,co,of);
input [7:0] a,b;
input ci; // 0; Add 1: Subtract
output [7:0] sum;
output co;
output of;
wire[7:0] c;
wire[7:0] xb;
xor(xb[0],b[0],ci);
xor(xb[1],b[1],ci);
xor(xb[2],b[2],ci);
xor(xb[3],b[3],ci);
xor(xb[4],b[4],ci);
xor(xb[5],b[5],ci);
xor(xb[6],b[6],ci);
xor(xb[7],b[7],ci);
xor(of,c[7],c[6]);
xor(co,c[7],ci);
CarryLA_8 CLAS(a,xb,ci,sum,co);
endmodule
module CarryLA_8(a,b,ci,sum,co);
input [7:0] a,b;
input ci;
output [7:0] sum;
output co;
wire [7:0] sum;
wire cm,co;
CarryLA_4 CLA0(a[3:0],b[3:0],ci,sum[3:0],cm);
CarryLA_4 CLA1(a[7:4],b[7:4],cm,sum[7:4],cm);
endmodule
module CarryLA_4(a,b,ci,sum,co);
input [3:0] a,b;
input ci; // 0; Add 1: Subtract
output [3:0] sum;
output co;
wire[3:0] g,p,cout;
wire G0,P0;
wire[9:0] w;
and a0(g[0],a[0],b[0]);
and a1(g[1],a[1],b[1]);
and a2(g[2],a[2],b[2]);
and a3(g[3],a[3],b[3]);
xor x0(p[0],a[0],b[0]);
xor x1(p[1],a[1],b[1]);
xor x2(p[2],a[2],b[2]);
xor x3(p[3],a[3],b[3]);
and and0(w[0],p[0],ci);
or or0(cout[0],g[0],w[0]);
and and1(w[1],p[1],p[0],ci);
and and2(w[2],p[1],g[0]);
or or1(cout[1],g[1],w[2],w[1]);
and and3(w[3],p[2],p[1],p[0],ci);
and and4(w[4],p[2],p[1],g[0]);
and and5(w[5],p[2],g[1]);
or or2(cout[2],g[2],w[5],w[4],w[3]);
and and6(w[6],p[3],p[2],p[1],g[0]);
and and7(w[7],p[3],p[2],g[1]);
and and8(g[2],a[2],b[2]);
or or3(G0,g[3],w[8],w[7],w[6]);
and and9(P0,p[3],p[2],p[1],p[0]);
and and10(w[9],P0,ci);
or or4(cout[3],G0,w[9]);
and and11(co,cout[3],1);
xor xor0(sum[0],p[0],ci);
xor xor1(sum[1],p[1],cout[0]);
xor xor2(sum[2],p[2],cout[1]);
xor xor3(sum[3],p[3],cout[2]);
endmodule
This is my Verilog code. simulated well, but the result kinda sucks.
'sum' produces values with some Xs, and 'co', 'of'(overflow detection) are also Xs. I couldn't find out what the problem is. It might be about carry I think.
Could anyone help me with this?
Any help would be really appreciated.
Thanks in advance.
Captured waveform is attached
enter image description here
enter image description here
You have multiple drivers on wire [8:0] c. In your generate you have:
or o1 (c[i+1],g[i],q[i]);
and then you have the FullAdder instances that drive c:
FullAdder a0(a[0],b[0],ci,sum[0],c[0]);
I can't be certain that this is the reason that it won't simulate, but it certainly will make it not function correctly.
you should change "initial" part of your testbench like this:
initial
begin
assign ci =0;
assign a=8'b00000001;
assign b=8'b00000001;
#20
assign a=8'b00010010;
assign b=8'b00110111;
#20
assign a=8'b01011100;
assign b=8'b10010001;
#20
$finish;
and little wrong in module CarryLA_4 :
module CarryLA_4(a,b,ci,sum,co);
input [3:0] a,b;
input ci;
output [3:0] sum;
output co;
wire[3:0] g,p,cout;
wire G0,P0;
wire[9:0] w;
and a0(g[0],a[0],b[0]);
and a1(g[1],a[1],b[1]);
and a2(g[2],a[2],b[2]);
and a3(g[3],a[3],b[3]);
xor x0(p[0],a[0],b[0]);
xor x1(p[1],a[1],b[1]);
xor x2(p[2],a[2],b[2]);
xor x3(p[3],a[3],b[3]);
and and0(w[0],p[0],ci);
or or0(cout[0],g[0],w[0]);
and and1(w[1],p[1],p[0],ci);
and and2(w[2],p[1],g[0]);
or or1(cout[1],g[1],w[2],w[1]);
and and3(w[3],p[2],p[1],p[0],ci);
and and4(w[4],p[2],p[1],g[0]);
and and5(w[5],p[2],g[1]);
or or2(cout[2],g[2],w[5],w[4],w[3]);
and and6(w[6],p[3],p[2],p[1],g[0]);
and and7(w[7],p[3],p[2],g[1]);
and and8(w[8],p[3],p[2],p[1],p[0],ci);
and and9(w[9],p[3],g[2]);
or or3(cout[3],g[3],w[9],w[8],w[7],w[6]);
and and10(co,cout[3],1);
xor xor0(sum[0],p[0],ci);
xor xor1(sum[1],p[1],cout[0]);
xor xor2(sum[2],p[2],cout[1]);
xor xor3(sum[3],p[3],cout[2]);
endmodule
I'm trying to design a 4-bit counter with T-flipflop, here's what i did:
1- From a D-flipflop to T-flipflop:
module T_FlipFlop( clk,T, Q);
input wire clk;
input wire T;
output reg Q;
wire D;
initial
begin
Q<=1'b0;
end
assign D= T ^ Q;
always #(negedge clk)
begin
Q<=D;
end
endmodule
with RTL shematic :
following this "D_ff to T_ff" conversion:
2- Then, i instantiated 4 T-flipflops in the top module and connected the output of each flipflop to the clk of the next one:
module Counters_FreqDividers( sysclk,Q1,Q2,Q3,Q4);
input sysclk;
output wire Q1;
output wire Q2;
output wire Q3;
output wire Q4;
T_FlipFlop num_1(.clk(sysclk),.T(1'b1),.Q(Q1));
T_FlipFlop num_2(.clk(Q1),.T(1'b1),.Q(Q2));
T_FlipFlop num_3(.clk(Q2),.T(1'b1),.Q(Q3));
T_FlipFlop num_4(.clk(Q3),.T(1'b1),.Q(Q4));
endmodule
with RTL schematic :
to follow this diagram:
We know that T-flipflop is just a JK-flipflop with J and K connected to each other and that's what we have here, so consider them as T-flipflops.
3-The simulation:
4- Finally, my questions:
1) why Q1 is the ONLY output that operates properly?
2) Why Q2, Q3, Q4 starts with 1 although i have initialized them as 0?
I can't figure out what's missing, i tried to play around but nothing worked and i'm stuck here!
Edit: my testbench:
module test;
// Inputs
reg sysclk;
// Outputs
wire Q1;
wire Q2;
wire Q3;
wire Q4;
// Instantiate the Unit Under Test (UUT)
Counters_FreqDividers uut (
.sysclk(sysclk),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
initial begin
// Initialize Inputs
sysclk <= 1'b1;
#200 $finish();
end
always #5 sysclk=~sysclk;
endmodule
I am trying to add two 32 bits numbers using verilog.But I am getting many dont-care in the resut.
The 32 bit adder uses 4 8-bit adders.One 8 -bit adder uses one bit Full-Adder.FAdder makes use of 3 to 8 decoder.
Here is my code-
module Decoder(D,x,y,z);
input x,y,z;
output [0:7] D;
wire xn,yn,zn;
not n1(xn,x);
not n2(yn,y);
not n3(zn,z);
and a1(D[0],xn,yn,zn);
and a2(D[1],xn,yn,z);
and a3(D[2],xn,y,zn);
and a4(D[3],xn,y,z);
and a5(D[4],x,yn,zn);
and a6(D[5],x,yn,z);
and a7(D[6],x,y,zn);
and a8(D[7],x,y,z);
endmodule
module FAdder(S,C,x,y,z);
input x,y,z;
output S,C;
wire [0:7] D;
Decoder dec(D,x,y,z);
assign S= D[1] | D[2] | D[4] | D[7];
assign C= D[3] | D[5] | D[6] | D[7];
endmodule
module eightbitAdder(S,Carry,in1,in2,z);
input [7:0] in1;
input [7:0] in2;
input z;
output [7:0] S;
output Carry;
wire C[7:0];
assign z=0;
FAdder F1(S[0],C[0],in1[0],in2[0],z);
FAdder F2(S[1],C[1],in1[1],in2[1],C[0]);
FAdder F3(S[2],C[2],in1[2],in2[2],C[1]);
FAdder F4(S[3],C[3],in1[3],in2[3],C[2]);
FAdder F5(S[4],C[4],in1[4],in2[4],C[3]);
FAdder F6(S[5],C[5],in1[5],in2[5],C[4]);
FAdder F7(S[6],C[6],in1[6],in2[6],C[5]);
FAdder F8(S[7],C[7],in1[7],in2[7],C[6]);
assign Carry=C[7];
endmodule
module t32bitadder(S,Carry1,in1,in2);
input [31:0] in1,in2;
output [31:0] S;
output Carry1;
wire [3:0] C1;
wire initCarry;
assign initCarry=0;
eightbitAdder e1(S[7:0],C1[0],in1[7:0],in2[7:0],initCarry);
eightbitAdder e2(S[15:8],C1[1],in1[15:8],in2[15:8],C1[0]);
eightbitAdder e3(S[23:16],C1[2],in1[23:16],in2[23:16],C1[1]);
eightbitAdder e4(S[31:24],C1[3],in1[31:24],in2[31:24],C1[2]);
assign Carry1=C1[3];
endmodule
module testbench32bitAdder;
reg [31:0] in1,in2;
reg z;
wire [31:0] S;
wire C;
t32bitadder Al(S,C,in1,in2);
initial
$monitor(,$time,"in1=%b,in2=%b,S=%b,C=%b",in1,in2,S,C);
initial
begin
#0 in1=32'b00000001000000010000000110000001;in2=32'b00000001000000010000000110000001;
#4 in1=32'b11000001100000011000000100000001;in2=32'b11000001100000010000000100000001;
#4 in1=32'b00000001000000010000000100000001;in2=32'b10000001000000010000000100000001;
end
This is the result I am getting-
# 0in1=00000001000000010000000110000001,in2=00000001000000010000000110000001,S=0000001000000010000000xx00000010,C=0
# 4in1=11000001100000011000000100000001,in2=11000001100000010000000100000001,S=100000xx000000101000001000000010,C=1
# 8in1=00000001000000010000000100000001,in2=10000001000000010000000100000001,S=10000010000000100000001000000010,C=0
Notice the dont-care in the second output. This is because of the C1[2] which becomes X . Can anyone point out my mistake?
vipin is correct, the assign z=0; line in the eightbitAdder module is leading to the dont cares. In your test, the carry out of the first 8-bit adder is 1, it attempts to set the z input to the next 8-bit adder to 1, but this conflicts with the continuous assignment of z to 0, thus resulting in z = 1'bx. This dont care is propagated through the first FA and impacts the second as well, which results in the 2 dont cares in the 8th and 9th places of the result (where the first bit is the 0th place). The same thing is happening between your third and your final 8-bit adders in the second test. Your third test doesnt propagate a carry between 8-bit adders so no dont cares are generated.