Can anyone see any blatant errors as to why this does not compile. I think the logic is correct for most of these operations. Its most likely syntax errors.
the only thing i can think of is the switch statement isn't written correctly as well as the add module. Each of the foury bit statements are connected to one of the modules below it. (bitwise not binary)
module _4bitALU(C , O , A , B , Switch);
input[3:0] A ;
input [3:0] B;
input [3:0] Switch;
output [3:0] O;
output C;
case(Switch)
4'B0000: notop(O , A);
4'B0001: andop(O , A , B);
4'B0010: orop(O , A , B);
4'B0011: xorop(O , A , B);
4'B1000: addop(C , O , A , B);
endcase // case (Switch)
endmodule // _4bitALU
module notop(O , A);
input [3:0] A;
output [3:0] O;
assign O = ~A;
endmodule // notop
module andop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
assign O = (A & B);
endmodule // andop
module orop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
assign O = (A | B);
endmodule // orop
module xorop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O ;
assign O = (A ^ B);
endmodule // xorop
module addop(C , O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
output C;
assign C1 = (A[0] & B[0]);
assign C2 = ((A[1] & B[1]) | (A[1] & C1) | (B[1] & C1));
assign C3 = ((A[2] & B[2]) | (A[2] & C2) | (B[2] & C2));
assign C = ((A[3] & B[3]) | (A[3] & C3) | (B[3] & C3));
assign O[0] = (A[0] ^ B[0]);
assign O[1] = ((A[1] ^ B[1] ^ C1) | (A[1] & B[1] & C[1]));
assign O[2] = ((A[2] ^ B[2] ^ C2) | (A[2] & B[2] & C[2]));
assign O[3] = ((A[3] ^ B[3] ^ C3) | (A[3] & B[3] & C[3]));
assign O[4] = ((A[4] ^ B[4] ^ C4) | (A[4] & B[4] & C[4]));
endmodule // addop
There are quite a few problems in the _4bitALU module:
The case statement is not inside an always block.
You can't "call" other modules like you do in the case branches, instead you need to create instances of those modules and assign the wires which connect to those instances within the case branches to the desired output(s).
These issues are rather basic Verilog, therefore I suggest you read up on how it is used (maybe this tutorial might help). Remember that you are (in most cases anyway) trying to describe the structure of hardware, not a software program that just gets executed.
Related
This question already has answers here:
Can anyone help me to create a Verilog testbench?
(2 answers)
Closed 1 year ago.
I'm still honestly a bit unfamiliar with Verilog especially with test benches, considering I've only created a childishly simple project once. I'm not sure how to make a test bench for a Verilog file I've made and so I can't test if it works. Here's my code:
`timescale 1ns/1ps
module adder_4bit_cla(sum, Cout, A, B, S);
input [3:0] A, B;
input S;
output [3:0] sum;
output Cout;
wire P0, G0, P1, G1, P3, G3;
wire C4, C3, C2, C1;
assign
P0 = A[0] ^ B[0],
P1 = A[1] ^ B[1],
P2 = A[2] ^ B[2],
P3 = A[3] ^ B[3];
assign
G0 = A[0] & B[0],
G1 = A[1] & B[1],
G2 = A[2] & B[2],
G3 = A[3] & B[3];
assign
C1 = G0 | (P0 & S),
C2 = G1 | (P1 & G0) | (P1 & P0 & S),
C3 = G2 | (P2 & G1) | (P2 & P1 & G0) | (P2 & P1 & P0 & S),
C4 = G3 | (P3 & G2) | (P3 & P2 & G1) | (P3 & P2 & P1 & G0) | (P3 & P2 & P1 & P0 & S);
assign
sum[0] = P0 ^ S,
sum[1] = P1 ^ C1,
sum[2] = P2 ^ C2,
sum[3] = P3 ^ C3;
assign Cout = C4;
endmodule
Honestly, what I really need to do is a 4-bit adder-subtractor using carry lookahead, but I have no idea how to implement a carry lookahead to begin with so here I am. If anyone could help me that would be really great :<
Edit: I have calmed down and I can finally pinpoint the exact problem: the values of A and B for the test bench. While I could brute force it, how can I make use of loops to increment A and B so that it would be like this:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
While also updating M?
Use the following to improve your testbench.
`timescale 1ns / 1ps
module adder_4bit_cla_tb();
// inputs - keep them having reg as the data type
reg [3:0] A, B;
reg S;
// outputs - keep them having wire as the data type
wire [3:0] sum;
wire Cout;
adder_4bit_cla adder_4bit_cla_inst
(
.sum(sum), .Cout(Cout), .A(A), .B(B), .S(S)
);
initial begin
A = 4'd1; B = 4'd2; S = 1'd1;
#10 A = 4'd2; B = 4'd5; S = 1'd0;
#10 A = 4'd5; B = 4'd6; S = 1'd0;
#50 $stop;
end
endmodule
Waveform results
Inputs can be fed using for loops as follows.
`timescale 1ns / 1ps
module adder_4bit_cla_tb();
// inputs - keep them having reg as the data type
reg [3:0] A, B;
reg S;
// outputs - keep them having wire as the data type
wire [3:0] sum;
wire Cout;
reg [3:0] i;
adder_4bit_cla adder_4bit_cla_inst
(
.sum(sum), .Cout(Cout), .A(A), .B(B), .S(S)
);
initial begin
for(i = 4'd0; i < 4'd15; i = i + 4'd1) begin
A = i; B = i; S = 1'b0;
#10;
end
#200 $stop;
end
endmodule
Waveform Results
Using Verilog, I want to make 4by4 multiplier, but there is one error:
vlog-2110) Illegal reference to net array "w11".
about other variables w12, o1..... there is also error...
I cannot understand the meaning of the error. If you can solve this error, please tell me.
module half_adder (x,y,s,c);
input x,y;
output s,c;
assign s=x^y;
assign c=x&y;
endmodule
module full_adder (x,y,z,s,c);
input x,y,z;
output s,c;
wire w1,w2,w3;
half_adder h1(x,y,w1,w2);
half_adder h2(w1,z,s,w3);
assign c = w2|w3;
endmodule
module four_bit_adder (a, b, c0, s, c4);
input [3:0]a;
input [3:0]b;
input c0;
output [3:0]s;
output c4;
wire c1,c2,c3;
full_adder fu1(a[0],b[0],c0,s[0],c1);
full_adder fu2(a[1],b[1],c1,s[1],c2);
full_adder fu3(a[2],b[2],c2,s[2],c3);
full_adder fu4(a[3],b[3],c3,s[3],c4);
endmodule
maybe there is error next code
// 4by4_multiplier
module four_four_multi (A,B, zero, C);
input [3:0]A;
input [3:0]B;
input zero;
output [7:0]C;
wire w11[3:0];
wire w12[3:0];
wire o1[3:0];
wire w21[3:0];
wire w22[3:0];
wire o2[3:0];
wire w31[3:0];
wire w32[3:0];
wire o3[3:0];
wire o4;
assign C[0] = A[0] & B[0];
assign w11[0] = A[0] & B[1];
assign w11[1] = A[0] & B[2];
assign w11[2] = A[0] & B[3];
assign w11[3] = 0;
assign w12[0] = A[1] & B[0];
assign w12[1] = A[1] & B[1];
assign w12[2] = A[1] & B[2];
assign w12[3] = A[1] & B[3];
four_bit_adder four1(w11, w12, zero, o1 ,w21[3] );
assign C[1] = o1[0];
assign w21[0] = o1[1];
assign w21[1] = o1[2];
assign w21[2] = o1[3];
assign w22[0] = A[2] & B[0];
assign w22[1] = A[2] & B[1];
assign w22[2] = A[2] & B[2];
assign w22[3] = A[2] & B[3];
four_bit_adder four2(w21, w22, zero, o2 ,w31[3] );
assign C[2] = o2[0];
assign w31[0] = o2[1];
assign w31[1] = o2[2];
assign w31[2] = o2[3];
four_bit_adder four3(w31, w32, zero, o3 , o4 );
assign C[3] = o3[0];
assign C[4] = o3[1];
assign C[5] = o3[2];
assign C[6] = o3[3];
endmodule
The following declaration declares nets w11, w12, ... as arrays of nets.
wire w11[3:0];
wire w12[3:0];
...
The verilog standard allows you to declare them but does not allow using them as whole array in ports. To fix it in verilog you need to declare those nets as vectors:
wire [3:0] w11;
wire [3:0] w12;
...
System Verilog relaxed this rule and it should work in that language as is.
DO I need anything else to make a 16bit CLA ??????
so far I instantiated 4 (4 bit CLA to make a 16 bit CLA)
but I think I am missing about the carry I just don't understand how to add it to what I have since the 8 bit CLA was just instantiating 2 (4 bit CLA) I don't understand why can't just instantiate 4 (4 bit CLA together to get 16 bit CLA). Can someone help me figure out how to complete the 16bit CLA?
//CLA16Top.sv
module CLA4Bit(ain, bin, cin, sum, cout);
timeunit 1ns/1ns;
input [3:0] ain,bin;
input cin;
output logic [3:0] sum;
output logic cout;
logic [3:0] G,P,C;
// Carry propagate
assign P = ain ^ bin;
//Carry generate
assign G = ain & bin;
// Calculating each stage of the carry out
assign C[0] = cin;
assign #4 C[1] = (G[0] | (C[0] & P[0]));
assign #6 C[2] = (G[1] | (G[0] & P[1]) | (C[0] & P[1] & P[0]));
assign #8 C[3] = (G[2] | (G[1] & P[2]) | (G[0] & P[1] & P[2]) | (C[0] &
P[2] & P[1] & P[0]));
assign sum = P ^ C;
assign #13 cout= (G[3] | (G[2]&P[3]) | (G[1]&P[2]&P[3]) |
(G[0]&P[1]&P[2]&P[3]) | (C[0]&P[0]&P[1]&P[2]&P[3]));
endmodule
/*
module CLA16Top;
timeunit 1ns/1ns;
parameter nBITS = 16;
logic [nBITS - 1 : 0] ain, bin, sum;
logic in;
logic cout;
logic c4, c8, c12, c16;
assign cout = c16;
// instantiating the 16 bit CLA
CLA4Bit uut1(
.ain(ain[3:0]),
.bin(bin[3:0]),
.cin(cin),
.sum(sum[3:0]),
.cout(c4)
);
CLA4Bit uut2(
.ain(ain[7:4]),
.bin(bin[7:4]),
.cin(c4),
.sum(sum[7:4]),
.cout(c8)
);
CLA4Bit uut3(
.ain(ain[11:8]),
.bin(bin[11:8]),
.cin(c8),
.sum(sum[11:8]),
.cout(c12)
);
CLA4Bit uut4(
.ain(ain[15:12]),
.bin(bin[15:12]),
.cin(c12),
.sum(sum[15:12]),
.cout(c16)
);
// SIMULATE (CLA16Top)
//
test #(16) TB(.*);
endmodule: CLA16Top
I get compile errors in your test module. Change:
output in;
to:
output cin;
Also, the double-quoted string must be on one line:
$display("For inputs: ain = %b, bin = %b, cin = %b :: Actual outputs: cout = %1b, sum = %b :: Expected outputs: cout = %1b, sum = %b", ain, bin, cin, cout,
test_count could be too big to fit into an int variable. Use real and %g:
real test_count;
$display("***Congratulations, No errors found after %g tests***", test_count);
After those changes, the code compiles and runs for me. It took about 2 hours before the nested loops completed, and only the final message displays:
***Congratulations, No errors found after 8.58993e+09 tests***
This indicates that the adder works properly.
If you want to see more intermediate results, add more displays in the loops.
Note: The test module code was removed from the Question after I posted this Answer.
I'm got a error when running Implementation at vivado 2018.2
this is error detail Info:
[Place 30-494] The design is empty
Resolution: Check if opt_design has removed all the leaf cells of your design. Check whether you have instantiated and connected all of the top level ports.
[Common 17-69] Command failed: Placer could not place all instances
and my codes is following:
`timescale 1ns/1ns
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output reg sum, cout;
reg t1, t2, t3;
always
#(a or b or cin) begin
sum <= (a ^ b & cin);
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
endmodule
module fa_top;
reg pa, pb, pci;
wire pco, psum;
fa_seq uf1(pa, pb, pci, psum, pco);
initial
begin: blk_only_once
reg[3:0] pal;
for(pal = 0; pal < 8; pal = pal + 1)
begin
{pa,pb,pci} <= pal;
#5 $display("pa,pb,pci = %b%b%b",pa,pb,pci,":::pco,psum=%b%b",pco,psum);
end
end
endmodule
thanks for your answer.
Check whether you have instantiated and connected all of the top level ports.
It looks like you synthesized your actual design AND your test-bench.
The test-bench is the top level module and has no ports so all logic is optimised away.
You should split your design in files which hold the RTL and files which hold the test-bench/simulation code. In Vivado you have to specify what type it is if you 'add a file' here is a screen shot:
Your code has a latch inferred. Moreover you have used both blocking and non-blocking assignment in the same always block.
always
#(a or b or cin) begin //Not all dependencies are mentioned
sum <= (a ^ b & cin); //Non-blocking assignment
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
I suggest you to re-write the always block as shown below.
always
#(*) begin
sum = (a ^ b & cin);
t1 = a & cin;
t2 = b & cin;
t3 = a & b;
cout = (t1 | t2) | t3;
end
Actually you don't need an always block for the above combinational logic. Simply use assign statements.
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output sum, cout;
wire t1, t2, t3;
assign sum = (a ^ b & cin);
assign t1 = a & cin;
assign t2 = b & cin;
assign t3 = a & b;
assign cout = (t1 | t2) | t3;
endmodule
However an efficient way of writing a full adder code would be :-
module fa_seq(a, b, cin, sum, cout);
input a, b, cin;
output sum, cout;
assign {cout,sum} = (a + b + cin);
endmodule
I'm new to Verilog programming. I'm trying to put together an 8-bit Carry Lookahead Adder as a step toward building a 64-bit CLA. Basically, the way I implemented it is I use 2 4-bit CLA "blocks" to create the 8-bit CLA. I'll provide my code, then an explanation of the problem I'm having.
Code below:
// 4-BIT CLA CODE
module CLA4Bit(A, B, carryIn, carryOut, PG, GG, Sum);
input[3:0] A, B;
input carryIn;
output carryOut;
output PG;
output GG;
output[3:0] Sum;
wire[3:0] G, P, C;
assign G = A & B;
assign P = A ^ B;
assign Sum = P ^ C;
assign C[0] = carryIn;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);
assign PG = P[3] & P[2] & P[1] & P[0];
assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]);
endmodule
// 8-BIT CLA CODE BELOW
module CLA8Bit(A, B, carryIn, carryOut, Sum);
// 8-bit wire for the inputs A and B
input[7:0] A, B;
// Wire for the ORIGINAL carry-in
input carryIn;
// Wire for the carryOut
output carryOut;
// Wire that carries the Sum of this CLA
output[7:0] Sum;
// Wires for the propagate of the first 4-bit block (p3)
// and the second (p7)
wire p3, p7;
// Wires for the generate of the first 4-bit block (g3)
// and the second (g7)
wire g3, g7;
// Wires for the carry of the first block (c3) and the
// second (c7)
wire c3, c7;
// The two 4-bit CLA blocks that make up the 8-bit CLA
CLA4Bit block1(A[3:0], B[3:0], carryIn, c3, p3, g3, Sum[3:0]);
CLA4Bit block2(A[7:4], B[7:4], c3, c7, p7, g7, Sum[7:4]);
endmodule
I wrote a basic testbench to test my code:
module CLA_TB();
// TEST THE 8-BIT CLA
// Inputs
reg[7:0] A;
reg[7:0] B;
reg carryIn;
// Outputs
wire carryOut;
wire[7:0] Sum;
wire PG;
wire GG;
// Instantiate the 8-bit CLA
CLA8Bit CLA8BitDUT (
.A(A),
.B(B),
.carryIn(carryIn),
.carryOut(carryOut),
.Sum(Sum)
);
// Initialize the testbench signals
initial
begin
// Start with the carryIn set to 0
assign carryIn = 0;
// The standard first test. Set
// A = b0000 0001 and B = b0000 0001
// Answer should be Sum = b0000 0010
assign A = 8'b00000001;
assign B = 8'b00000001;
#20
// Next, set A = b0001 1011 and
// B = b1101 0111. Answer should
// be Sum = b1111 0010 = hF2.
assign A = 8'b00011011;
assign B = 8'b11010111;
#20
// Finally, try setting the carryIn
// to 1 and then test A = b0111 1011
// and B = b1101 0011. Answer should be
// Sum = 0100 1111 w/ overflow carry
assign carryIn = 1'b1;
assign A = 8'b01111011;
assign B = 8'b11010011;
#20
$finish;
end
endmodule
So the problem is, in my simulations of the testbench (I use ModelSim), the first 4 bits of the Sum (which correspond to the first 4-bit CLA instance in the 8-bit CLA module) are given as X in the Wave page. The second 4 bits add just fine, though.
After doing some research, I found out that X's are displayed in Verilog when a wire has more than one driver (source of the signal?). However, I don't see any place where I send more than one signal to my first 4-Bit CLA instance in the 8-Bit CLA module. Also, if something like that were the cause, then I don't know why it wouldn't happen to the second set of 4 bits as well, since both the 4-bit CLAs are set up very similarly.
Why is this happening?
X's are displayed in Verilog when a wire has more than one driver
That is true but it is only part of the story. There are other cases which produce X'es:
If a reg is not given a value it will be X.
If a Z is used in an expression it will produce an X .
Your waveform has some obvious 'Z' (blue) lines one it.
If you following the signals back to where they originate: your 4-bit adder never assigns a value to carryOut.
Then you make the same error in CLA8Bit.
If you see a 'Z' in a simulation: jump on it! 99.9% of the time you have an wire which has not been given a value!