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.
Related
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;
I have to make a 64 Bit ALU that takes in A and B 64-bit inputs, a carry_in input and outputs a 64bit result along with a 1-bit carry_out. There is also a 5 bit function-select FS. Where FS[0] controls whether B is inverted or not (using a 2to1 mux.) F[1] does the same for the A. And FS[4:2] determines which operation (Adding, subtracting, logical operations, etc) using an 8to1 Mux. Below is the code for the ALU and Testbench.
I'm pretty sure my testbench is good and so is all the separate components for the ALU. I'm not too confident about my top-level where I instantiate and connect all the inputs/outputs. What is causing the high impedance in the waveform?
module ALU(A, B, FS, cin, cout, result);
input [63:0] A, B;
input [4:0] FS;
input cin;
output cout;
output [63:0] result;
eight_one_mux u7 (firstoutA & secoutB, firstoutA | secoutB, sum, firstoutA ^ secoutB,
left, right, 1'b0, 1'b0, FS[4:2], result);
adder u6 (firstoutA, secoutB, cin, sum, cout);
firstmux u1 (A, !A, FS[1], firstoutA);
secmux u2 (B, !B, FS[0], secoutB);
Alu_shifter u5 (A, left, right);
endmodule
//--------------------------------------------------------------------------------//
//These are the two muxes to split into input and inverted input A,B
module firstmux(a, nota, firstS, firstoutA);
input [63:0] a, nota;
input firstS;
output reg [63:0] firstoutA;
always #(a or nota or firstS)
begin
case(firstS)
0 : firstoutA = a;
1 : firstoutA = nota;
default : firstoutA = 1'bx;
endcase
end
endmodule
//<><><><><><><>//
module secmux(b, notb, secS, secoutB);
input [63:0] b, notb;
input secS;
output reg [63:0] secoutB;
always #(b or notb or secS)
begin
case(secS)
0 : secoutB = b;
1 : secoutB = notb;
default : secoutB = 1'bx;
endcase
end
endmodule
//--------------------------------------------------------------------------------//
//This is the Shifter Blocks
module Alu_shifter (shiftA, right, left); //This shifter block shifts the A input once right or left
input [63:0] shiftA;
output [63:0] right;
output [63:0] left;
shift_right w1 ( //instantiate right shifter block
.a_R(shiftA),
.R(right)
);
shift_left w2 ( //instantiate left shifter block
.a_L(shiftA),
.L(left)
);
endmodule
////////><><><><><><><><><><><><><><><///////
module shift_right (a_R, R); // right shifter block
input [63:0] a_R;
output [63:0] R;
assign R = a_R >> 1; //shift A right once (shift in a 0)
endmodule
module shift_left (a_L, L); //left shifter block
input [63:0] a_L;
output [63:0] L;
assign L = a_L << 1; //shift A left once (shift in a 0)
endmodule
//End shifter blocks (3 total modules)
//----------------------------------------------------//////////////////////
//This is the Adder that Adds A, B and cin
module adder(addA, addB, nic, sum, cout);
input [63:0] addA, addB;
input nic;
output [63:0] sum;
output cout;
assign {cout, sum} = addA + addB + nic;
endmodule
//----------------------------------------------------//////////////////////
//This is the 8to1 Mux that decides which operation is put forward
module eight_one_mux(D0, D1, D2, D3, D4, D5, D6, D7, S, out);
input [63:0] D0, D1, D2, D3, D4, D5, D6, D7;
input [2:0] S;
output reg [63:0] out;
always #(D0 or D1 or D2 or D3 or D4 or D5 or D6 or D7 or S)
begin
case(S)
0 : out = D0; //And
1 : out = D1; //Or
2 : out = D2; //Adder
3 : out = D3; //xor
4 : out = D4; //lefter
5 : out = D5; //righter
6 : out = D6; //GND
7 : out = D7; //GND
default : out = 1'bx;
endcase
end
endmodule
////////////-------------------------------////////////////////////////////
module ALU_tb();
reg [63:0] A, B;
reg [4:0] FS;
reg cin;
wire cout;
wire [63:0] result;
ALU dut (
.A(A),
.B(B),
.FS(FS),
.cin(cin),
.cout(cout),
.result(result)
);
initial begin
A = 8'b11001100;
B = 8'b11001101;
FS = 5'b01101;
cin = 1;
end
always
#5 cin <= ~cin;
always begin
#5
A <= A + 1;
B <= B + 2;
#5;
end
initial begin
#100 $finish;
end
endmodule
```
Unexpected high impedance (z) values are typically the result of undriven signals, and that is the problem with your code.
adder u6 (firstoutA, secoutB, cin, sum, cout);
In the line above, you connect the 1-bit signal firstoutA to the 64-bit addA input port. This connects firstoutA to addA[0], leaving the other 63 bits undriven. Thus, addA[63:1] are all z.
firstoutA is a 1-bit signal because you did not explicitly declare it. Also, undeclared signals are assumed to be of type wire, which default to z.
It is good practice to declare all signals.
To find all undeclared signals, add this to the top of your code:
`default_nettype none
You should get compile errors like:
Error-[IND] Identifier not declared
Identifier 'firstoutA' has not been declared yet. If this error is not
expected, please check if you have set `default_nettype to none.
Error-[IND] Identifier not declared
Identifier 'secoutB' has not been declared yet. If this error is not
expected, please check if you have set `default_nettype to none.
First you need to define signals (wire) for connections between modules. For example, you have left and right as outputs of Alu_shifter module and they are connected to firstmux and secmux modules; however, they are not defined in your top module. You should add following signal definitions to your topmodule:
wire [63:0] left,right;
wire [63:0] firstoutA;
wire [63:0] secoutB;
wire [63:0] sum;
Also, eight_one_mux module takes eight 64-bit inputs. However, you set the last two of them as 1'b0. You should change them to 64'b0 as below.
eight_one_mux u7 (firstoutA & secoutB, firstoutA | secoutB, sum, firstoutA ^ secoutB,
left, right, 64'b0, 64'b0, FS[4:2], result);
Finally, !A does not invert all bits of A (same for B). It applies a reduction operation and generates a 1-bit signal (and firstmux module expects a 64-bit signal in its second input port).
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
This is my gate level code for A 4 bit full adder.
//Define stimulus
module stimulus;
//setup variables
reg[3:0] A,B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
//Instantiate 4 bi full adder
fulladd4 FA1_4(SUM,C_OUT,A,B,C_IN);
//Setup for monitoring the values
initial
begin
$monitor($time," A= %b,B= %b,C_IN= %b, --- C_OUT= %b, SUM= %b \n",A,B,C_IN,C_OUT,SUM);
end
//Stimulate Inputs
initial
begin
A = 4'd0; B = 4'd0; C_IN = 1'b0;
#5 A = 4'd1; B = 4'd2;
#5 A = 4'd3; B = 4'd4;
end
endmodule
//Define full 1 bit adder
module fulladd(sum, c_out,a,b,c_in);
//I/O Ports Declaration
output sum,c_out;
input a,b,c_in;
//Internal nets
wire s1, c1, s2;
//Instantating the gates
xor (s1,a,b);
and (c1,a,b);
xor (sum,s1,c_in);
and (s2,s1,c_in);
xor (c_out,s2,c1);
endmodule
//Define a 4 bit full adder
module fulladd4(sum,c_out,a,b,c_in);
//I/O Ports declaration
output [3:0] sum;
output c_out;
input [3:0] a,b;
input c_in;
//internal nets
wire c1,c2,c3;
//Instantiate 4 full 1 bit adders
fulladd fa0(sum[0],c1,a[0],b[0],c_in);
fulladd fa1(sum[1],c2,a[1],b[1],c1);
fulladd fa2(sum[2],c3,,a[2],b[2],c2);
fulladd fa3(sum[3],c_out,a[3],b[3],c3);
endmodule
It show a fatal error while simulating.
** Fatal: (vsim-3365)
C:/altera/12.1/modelsim_ase/Full_Bit_Adder.v(67): Too many port
connections. Expected 5, found 6.
Time: 0 ps Iteration: 0 Instance: /fulladd4/fa2 File: C:/altera/12.1/modelsim_ase/Full_Bit_Adder.v
This is the error that it shows
Can someone please explain me my mistake
In the 67th line there are two commas after c3. If you remove one of them, it should be working.
fulladd fa2(sum[2],c3,,a[2],b[2],c2);
you have used 2 commas consecutively. This is resulting in error because simulation tool takes it as 6 ports but we require only 5.
Half Adder:
`timescale = 1ns/100ps //timescale ratio //actual HDL
module half_add(a,b,sum, carry);
input a,b;
output sum, carry;
wire sum, carry;
and(sum,a,b);
xor(carry,a,b);
endmodule
Test bench:
module half_addTB;
reg a,b;
wire carry, sum;
//instantiation
half_add half_add1(
.a(a),.b(b),.carry(carry),.sum(sum));
//port assignments with 10ns delays
initial begin
#10 a = 0; b= 0;
#10 b = 1;
#10 a = 1;
#10 b = 0;
end
endmodule
Code compiles fine...but when I try to simulate it, all my values are in a z state....I don't understand why..
You cannot drive inputs to the module from within the module.
Just instantiate your "half_add" module in another module/program (e.g. "half_add_tb") which doesn't have any inputs. then add two local regs "a" and "b", and drive those from an initial block like the one you wrote - but in the "half_add_tb" module instead.
Then just wire up the inputs "a" and "b" of the "half_add" instance to the local "a" and "b" regs.
You need to instantiate your design in a testharness then drive the inputs.
//Half Adder
module half_add(a, b, sum, carry);
input a,b;
output sum, carry;
wire sum, carry; //Outputs are wires by default this is not required
and(sum, a, b);
xor(carry,a, b);
endmodule
module testharness();
//create test signals
reg a; //1 bit reg (regs driven from always and initial blocks)
reg b;
wire sum; // 1 bit wires for outputs to drive
wire carry;
//instantiate DUT (Device under test)
half_add half_add_1(
.a ( a ),
.b ( b ),
.sum ( sum ),
.carry ( carry)
);
//begin testbench
initial begin
#100 $finish;
end
initial begin
#10 a = 0; b= 0;
#10 b = 1;
#10 a = 1;
#10 b = 0;
end
endmodule
NB: if your simulator supports verilog-2001 your port lists can be easier to read and more compact:
//Half Adder
module half_add(
input a,
input b,
output wire sum,
output wire carry
//for regs :
// output reg [WIDTH-1:0] out_reg
//multi-bit wires :
// output [WIDTH-1:0] out_wire
);
and(sum, a, b);
xor(carry,a, b);
endmodule