16 -bit CLA instantiation - verilog

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.

Related

8 bit carry lookahead adder error with SystemVerilog in Questasim using two 4 CLA's

I keep getting an error when I simulate the CLA4Top, CLA8Top and the test.
The testbench was given and the entire project compiles. For the CLA4Top I thought it looked like "cout" is coming out to be correct but "sum" is not matching the expected outputs. I changed that and this is the updated code:
Here is the CLA4Top.sv
//4 bit carry lookahead adder
module CLA4Top(ain, bin, cin, sum, cout);
//parameter nBITS = 4;
//logic [nBITS - 1 : 0] ain, bin, sum;
//logic cin, cout;
input [3:0] ain, bin;
input cin;
output logic [3:0] sum;
output logic cout;
CLA4Bit C1(.*);
test #(4) TB(.*);
endmodule
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;
wire p0,p1,p2,p3,g0,g1,g2,g3,c1,c2,c3,c4,c0;
assign p0=(ain[0]^bin[0]),
p1=(ain[1]^bin[1]),
p2=(ain[2]^bin[2]),
p3=(ain[3]^bin[3]);
assign g0=(ain[0]&bin[0]),
g1=(ain[1]&bin[1]),
g2=(ain[2]&bin[2]),
g3=(ain[3]&bin[3]);
assign c0=cin,
c1=g0|(p0&cin),
c2=g1|(p1&g0)|(p1&p0&cin),
c3=g2|(p2&g1)|(p2&p1&g0)|(p1&p1&p0&cin),
c4=g3|(p3&g2)|(p3&p2&g1)|(p3&p2&p1&g0)|(p3&p2&p1&p0&cin);
assign sum[0] = ain[0] ^ bin[0] ^ cin,
sum[1] = ain[1] ^ bin[1] ^ c1,
sum[2] = ain[2] ^ bin[2] ^ c2,
sum[3] = ain[3] ^ bin[3] ^ c3;
assign cout=c4;
endmodule
Here is the CLA8Top.sv
// module with 8 bit adder using 4 bit CLA instances
module CLA8Top(ain, bin, cin, sum, cout);
//parameter nBITS = 8;
input [7:0] ain, bin;
input cin;
output logic [7:0] sum;
output logic cout;
wire c1;
// CLA4Bit c11(ain[3:0],bin[3:0],1'b0,sum[3:0],c1);
CLA4Bit c11(ain[3:0],bin[3:0],cin,sum[3:0],c1);
CLA4Bit c22(ain[7:4],bin[7:4],c1,sum[7:4],cout);
test #(8) TB(.*);
endmodule
And this is the testbench.sv
// Test bench for Generic N-Bits Adder design module
module test(ain, bin, cin, sum, cout);
timeunit 1ns/1ns;
parameter nBITS = 4;
parameter DELAY = 100;
input [nBITS - 1 : 0] sum;
input cout;
output [nBITS - 1 : 0] ain, bin;
output cin;
logic [nBITS - 1 : 0] ain, bin, sum;
logic cin, cout;
// test variables
logic [nBITS : 0] exp_value;
int i, j, test_count;
bit error;
initial begin
error = 0;
test_count = 0;
cin = 0;
repeat(2) begin
for(i = 0; i < (1 << nBITS); i++) begin
ain = i;
for(j = 0; j < (1 << nBITS); j++) begin
test_count++;
bin = j;
exp_value = ain + bin + cin;
#DELAY;
if({cout, sum} !== exp_value) begin
$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, sum, exp_value[nBITS], exp_value[nBITS-1:0]);
error = 1;
end // end for if block
end // end for j for loop
end // end for i for loop
cin = ~cin;
end // end for repeat block
if(error === 0)
$display("***Congratulations, No errors found after %d tests***", test_count);
else
$display("***Sorry, errors found in your code ***");
end // end for initial block
endmodule
Is there any changes that I can make that would give me the $display("***Congratulations, No errors found after %d tests***", test_count); that you can see? What problems am I having and why? I will include the transcript from running the CLA4Top.sv.
The log file shows that sum[3] mismatches the expected value. There is a typo in the equation for c3. Change:
c3=g2|(p2&g1)|(p2&p1&g0)|(p1&p1&p0&cin),
//
to:
c3=g2|(p2&g1)|(p2&p1&g0)|(p2&p1&p0&cin),
//

Verilog not displaying the correct results for 8-bit adder

I am having some trouble displaying the result of my 8 bit adder verilog
module Adder(a,b,cin,s,co);
input [7:0]a;
input [7:0]b;
output [7:0]s;
output co;
wire [6:0] u;
input cin;
Carry c1(a[0],b[0],cin,s[0],u[0]);
Carry c2(a[1],b[1],u[0],s[1],u[1]);
Carry c3(a[2],b[2],u[1],s[2],u[2]);
Carry c4(a[3],b[3],u[2],s[3],u[3]);
Carry c5(a[4],b[4],u[3],s[4],u[4]);
Carry c6(a[5],b[5],u[4],s[5],u[5]);
Carry c7(a[6],b[6],u[5],s[6],u[6]);
Carry c8(a[7],b[7],u[6],s[7],co);
endmodule
module Carry(a,b,cin,s,co);
input wire a;
input wire b;
input wire cin;
output wire co;
output wire s;
assign co = (a & b) | (b & cin) | (a & cin);
assign s = (~a & ~b & cin) | (~a & b & ~cin) | (a & ~b & ~cin)| (a & b & cin);
endmodule
module testbench;
reg [7:0]a;
reg [7:0]b;
reg cin;
wire [7:0]s;
wire co;
Adder add(a, b, cin, s, co);
initial begin
$dumpfile("result.vcd");
$dumpvars;
a <= 00000010; b <= 00000010; cin <= 0;
#5
$monitor("time=%4d: %b + %b + %b: sum = %b, carry = %b\n",$time,a,b,cin,s,co);
end
endmodule
although it adds everything correctly, it's not adding the numbers I originally wanted.
time= 5: 00001010 + 00001010 + 0: sum = 00010100, carry = 0
How can i fix it so that instead of adding those numbers, it would add the numbers i'd want.
(a = 00000010; b = 00000010; cin = 0;)
I already tried changing the numbers around and it does not work except when they're 00000001.
By default, Verilog interprets a numerical literal value as decimal. The value 00000010 is decimal 10. The $monitor statement uses %b, and it correctly displays the decimal value 10 as 1010. The sum of 10 + 10 is 20 (decimal), which is correctly displayed as 10100 (binary).
For Verilog to interpret 00000010 as binary, you need to specify the base as 'b00000010:
a <= 'b00000010; b <= 'b00000010; cin <= 0;
Refer to IEEE Std 1800-2012, section 5.7.1 Integer literal constants.
The reason that 1 + 1 works is that 1 is the special case where 00000001 (decimal) is the same value as 'b00000001 (binary).

Trouble with 8-bit Carry Lookahead Adder in Verilog

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!

8 bit wide, 2-to-1 multiplexer verilog module

I'm having a lot of trouble making any sort of sense of this problem. I'm supposed to create a module for an 8 bit wide 2-to-1 multiplexer using Verilog.
The question:
Write a verilog module that uses 8 assignment statements to describe the circuit. Use SW[17] on the DE2 board as the s input, switches [7:0] as the X input, switches [15:8] as the Y input. Connect SW switches to the red lights LEDR and output M to the green light LEDG [7:0].
My code:
module example(M, X, Y, S)
input[15:0] SW;
input SW[17];
output [7:0] LEDR;
output [7:0] LEDG;
output [7:0] M;
wire [7:0] X = SW[7:0];
wire [7:0] Y = SW[15:8];
wire S = SW[17]
assign M[0] = X[0] & ~S | Y[8] & S;
assign M[1] = X[1] & ~S | Y[9] & S;
assign M[2] = X[2] & ~S | Y[10] & S;
assign M[3] = X[3] & ~S | Y[11] & S;
assign M[4] = X[4] & ~S | Y[12] & S;
assign M[5] = X[5] & ~S | Y[13] & S;
assign M[6] = X[6] & ~S | Y[14] & S;
assign M[7] = X[7] & ~S | Y[15] & S;
endmodule
I don't understand how I'm supposed to assign m to the green LEDG[7:0] since I've already assigned each M to those conditional statements. Anyone know how to get around this?
While there are multiple ways to do this, I suggest make a wrapper module containing the board i/o as inputs and outputs and instantiate your MUX inside of it:
module top(input [17:0] SW,
output [15:0] LEDR,
output [7:0] LEDG);
example ex(.M(LEDG), .s(SW[17]), .X(SW[7:0]), .Y(SW[15:8]));
assign LEDR[7:0] = X;
assign LEDR[15:8] = Y;
endmodule
[insert your mux module minus the board i/o here]
If you cannot use the above solution, you can look up how to use the Pin Planner in QuartusII (which I assume you are using from the DE2 reference in your prompt).

Using created ALU to make a bigger one

I have a 8-bit ALU unit in verilog that can do addition, invert, etc. This single unit is tested and performs correctly. When I combine 4 of these to make a bigger ALU every output is correct except when I choose the addition operation it comes out as
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010101, basically the first alu does the work right then the output from the second is xxxxxxxx as is the third and fourth. This is really frustrating!!
the 8 bit module( it would be nice to point if this model is behavioral or structural model i go for the former!)
module alu_8bit(
output reg [7:0] out,
output reg cout,g,e,
input [7:0] A,B,
input cin,
input [2:0] S
);
//used functions
parameter BUF_A = 3'b000;
parameter NOT_A = 3'b001;
parameter ADD = 3'b010;
parameter OR = 3'b011;
parameter AND = 3'b100;
parameter NOT_B = 3'b101;
parameter BUF_B = 3'b110;
parameter LOW = 3'b111;
always #(A or B or S) begin
//Comparator
g = A>B;
e = A==B;
//Other selective functions
case(S)
BUF_A: out = A;
NOT_A: out = ~A;
ADD: {cout,out} = A+B+cin;
OR: out = A | B;
AND: out = A & B;
NOT_B: out = ~B;
BUF_B: out = B;
LOW: out = {8{1'b0}};
endcase
end
endmodule
Here is the code of the bigger one:
module alu_32bit(
output [31:0] out,
output cout,g,e,
input [31:0] A,B,
input cin,
input [2:0] S
);
wire e1,e2,e3,e4;
wire g1,g2,g3,g4;
alu_8bit ALU1(out[7:0],cin2,g1,e1,A[7:0],B[7:0],cin,S);
alu_8bit ALU2(out[15:8],cin3,g2,e2,A[15:8],B[15:8],cin2,S);
alu_8bit ALU3(out[23:16],cin4,g3,e3,A[23:16],B[23:16],cin3,S);
alu_8bit ALU4(out[31:24],cout,g4,e4,A[31:24],B[31:24],cin4,S);
assign g = g4 | (e4 & g3) |(e4 & e3 & g2) | (e4& e3 & e2 & g1);
assign e = e4 & e3 & e2 & e1;
endmodule
Can any one give some help?! if you need more info just tell me.
Edited:
Waveform pic clearly input comes in correct but output not
The dataflow diagram shows that ALU1 output is just fine
Your sensitivity list for the main part of the ALU doesn't include cin.

Resources