Verilog carry look ahead adder propagation confusion - verilog

I have just learned about the CLA adder am a little confused about getting the sum. I see there are two versions of p, p = a or b and p = a xor b.
If I simulate this code it will give the correct result:
module CLA_4bit(
output [3:0] S,
output Cout,
input [3:0] A,B,
input Cin
);
wire [3:0] G,P,C;
assign G = A & B;
assign P = A ^ B;
assign C[0] = Cin;
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 Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
assign S = P ^ C;
endmodule
However, if I change P = A ^ B to P = A | B it would give an incorrect sum. What changes to the code would be needed to have it work with P = A | B ?

The formula for S (P^C) is valid for P computed with XOR operation. As you probably know, the only difference in the truth tables between OR and XOR operation is when both bits are 1. That's why the formula for Sshould be slightly different if you use OR operation:
S = (P & (~G)) ^ C

Related

Verilog Two bit Magnitude comparator

I was trying to write Verilog code of a two bit comparator, but I keep getting errors. Any help?
Error Codes:
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(5) near text: ";"; expecting ")"
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(7) near text: ";"; expecting ")"
10170 Verilog HDL syntax error at two_bitcomparatorVerilog.v(15) near text: "~"; expecting ")"
Design:
module twobit_comparator(
//assigning inputs
input wire [1:0] A, B;
// assigning outputs
output wire LT, GT, EQ;
// L=Less, G=Greater, E=Equal
);
wire [9:0] s;
//A = B output
assign s0 = (~A[1] & ~A[0] & ~B[1] ~B[0]);
assign s1 = (~A[1] & A[0] & ~B[1] & B[0]);
assign s2 = (A[1] & ~A[0] & B[1] & ~B[0]);
assign s3 = (A[1] & A[0] & b[1] & B[0]);
assign EQ = s0 | s1 | s2 | s3;
//A less than B output
assign s4 = (~A[0]) & (~A[1]) & B[0];
assign s5 = (~A[1]) & B[1];
assign s6 = (~A[0]) & B[1] & B[0];
assign LT = s4 | s5| s6;
// A greater than B output
assign s7 = (~B[0]) & (~B[1]) & A[0];
assign s8 = (~B[1]) & A[1];
assign s9 = (~B[0]) & A[1] & A[0];
assign GT = s7 | s8 | s9;
endmodule
Separate ports with commas, not semicolons, and do not end the port list with a semicolon:
module twobit_comparator(
//assigning inputs
input wire [1:0] A, B,
// assigning outputs
output wire LT, GT, EQ
// L=Less, G=Greater, E=Equal
);
You are missing the & operator; I added it here:
assign s0 = (~A[1] & ~A[0] & ~B[1] & ~B[0]);
// ^
I changed b to B here (Verilog is case-sensitive):
assign s3 = (A[1] & A[0] & B[1] & B[0]);
// ^
I don't get any more compile errors with the changes above. However, you declared signal s, but it is not used. And, you did not declare s0, s1, etc., but you are using them. This works because Verilog allows you to use undeclared wires when they are 1-bit wide. But, you should declare all signals. For example, you could use:
wire [9:0] s;
assign s[0] = (~A[1] & ~A[0] & ~B[1] & ~B[0]);
assign s[1] = (~A[1] & A[0] & ~B[1] & B[0]);

Verilog module in Xilinx "signal never used" error

I have a Verilog program where I have to model an ALU that can add, subtract, check for equality and divide by 2. My code:
module alu(
input wire [7:0] sw,
output reg [2:0] s,
output reg cout
);
reg co1, co2;
always #(*) begin
if(~sw[6] & ~sw[7]) begin
s[0] = sw[0] ^ sw[3] ^ 1'b0;
co1 = (sw[3] & 1'b0) | (sw[0] & 1'b0) | (sw[0] & sw[3]);
s[1] = sw[1] ^ sw[4] ^ co1;
co2 = (sw[4] & co1) | (sw[1] & co1) | (sw[1] & sw[4]);
s[2] = sw[2] ^ sw[5] ^ co2;
cout = (sw[5] & co2) | (sw[2] & co2) | (sw[2] & sw[5]);
end
else if(sw[6] & ~sw[7]) begin
s[0] = sw[0] ^ ~sw[3] ^ 1'b1;
co1 = (~sw[3] & 1'b1) | (sw[0] & 1'b1) | (sw[0] & ~sw[3]);
s[1] = sw[1] ^ ~sw[4] ^ co1;
co2 = (~sw[4] & co1) | (sw[1] & co1) | (sw[1] & ~sw[4]);
s[2] = sw[2] ^ ~sw[5] ^ co2;
cout = (~sw[5] & co2) | (sw[2] & co2) | (sw[2] & ~sw[5]);
end
\\more code
end
endmodule
I am getting this warning for 'co1' and 'co2'
signal is assigned but never used. This unconnected signal will be trimmed during the optimization process.
I am confused with the warning because from my understanding 'co1' and 'co2' are used to assign something. Overall when I run it on my board I get no outputs at all.
So this ended up being a non-issue. They were removed after synthesis.

16-bit adder from 4-bit Carry Look Ahead (CLA) - Cout from Block Generate and Propagate

I'm new to Verilog. Here's what I have done so far and the 4-bit CLA works. However, the 16-bit (using instances of 4-bit CLA) doesn't. The problem is definitely in setting the Cout_itermed (intermediate carries) values from block propagate (BP) and block generate (BG). I've created a module carries to deal with this.
In Xilinx ISE, the output waveform shows up as this (no wave shown):
module CLA_4bit(
output [3:0] S,
output Cout, PG, GG,
input [3:0] A, B,
input Cin
);
wire [3:0] G,P,C;
assign G = A & B; //Generate
assign P = A ^ B; //Propagate
assign C[0] = Cin;
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 Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
assign S = P ^ C;
assign PG = P[3] & P[2] & P[1] & P[0]; // block generate
assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]); // block propagate
endmodule
module CLA_16bit(
output reg [15:0] S,
output reg Cout,
input [15:0] A, B,
input Cin
);
reg [3:0] BP, BG;
reg [3:0] Cout_itermed;
carries my_carries(BP, GP, Cin, Cout_itermed, Cout);
CLA_4bit cla0(S[3:0], Cout_itermed[0], BP[0], BG[0], A[3:0], B[3:0], Cin);
CLA_4bit cla1(S[7:4], Cout_itermed[1], BP[1], BG[1], A[7:4], B[7:4], Cout_itermed[0]);
CLA_4bit cla2(S[11:8], Cout_itermed[2], BP[2], BG[2], A[11:8], B[11:8], Cout_itermed[1]);
CLA_4bit cla3(S[15:12], Cout_itermed[3], BP[3], BG[3], A[15:12], B[15:12], Cout_itermed[2]);
Cout = Cout_itermed[3];
endmodule
module carries (
input [3:0] BP,
input [3:0] BG,
input Cin,
output reg [3:0] Cout_itermed,
output reg Cout
);
assign Cout_itermed[0] = BG[0] | (BP[0] & Cin);
assign Cout_itermed[1] = BG[1] | (BP[1] & Cout_itermed[0]);
assign Cout_itermed[2] = BG[2] | (BP[2] & Cout_itermed[1]);
assign Cout = Cout_itermed[3];
endmodule
The waveform does show up (and correctly) when I run a test bench of the 4 bit CLA. Could anyone explain where the problem lies in the carries or the CLA_16bit module?
Cout_itermed has two drivers - the first being the Cout outputs of a CLA_4bit, and the second being the Cout_itermed output of the carries module.
The same applies to Cout in CLA_16bit (though it's two drivers end up being the same signal, Cout_itermed[3], in CLA_16bit and carries).
Remember that in Verilog you're describing physical circuitry, and you should never have two sources (drivers) connected to the same wire - that's how we get short circuits!
The following is based on https://en.wikipedia.org/wiki/Lookahead_carry_unit#16-bit_adder.
What you'll want to do is define remove the Cout_itermed[x] from the Cout port in the CLA_16bits (you can just leave the port hanging). You should move the logic to determine Cout_itermed[3] (i.e. BG[3] | (BP[3]&Cout_itermed[2])) to the carries module.

Why this verilog assignment is wrong?

I'm trying to solve this problem from altera Lab.
Here's my code :
module AlteraLAB2
(
input [17:0] SW,
output [17:0] LEDR,
output [7:0] LEDG
);
wire S;
wire [7:0] X,Y,M;
//Use switch SW17 on the DE2 board as the s input, switches SW7−0 as the X input and SW15−8 as the Y input
assign S = SW[17];
assign X = SW[7:0];
assign Y = SW[15:8];
//Connect the SW switches to the red lights LEDR and connect the output M to the green lights LEDG7−0
assign LEDR = SW[17:0];
assign LEDG = M;
//The multiplexer can be described by the following Verilog statement: assign m=(~s & x)|(s & y);
assign M[0] = (~S & X[0]) | (S & Y[0]);
assign M[1] = (~S & X[1]) | (S & Y[1]);
assign M[2] = (~S & X[2]) | (S & Y[2]);
assign M[3] = (~S & X[3]) | (S & Y[3]);
assign M[4] = (~S & X[4]) | (S & Y[4]);
assign M[5] = (~S & X[5]) | (S & Y[5]);
assign M[6] = (~S & X[6]) | (S & Y[6]);
assign M[7] = (~S & X[7]) | (S & Y[7]);
endmodule
I solved it assigning step by step the values in M, but I don't understand why this does not work:
M=(~S & X) | (S & Y);
Could someone explain why?
Note the bit widths of the signals in the expression
M=(~S & X) | (S & Y);
S is only one bit while X is 8 bits. The bitwise AND of the two will result in a one-bit result, which is not what you want.
It's common in Verilog to use a ternary expression in situations like this. For example,
assign M = S ? Y : X;
It does not work because S is a 1-bit signal and Y is an 8-bit signal. When you bitwise AND a 1-bit signal with an 8-bit signal, the 1-bit signal (S) is left extended with 0's.
For example, if S=1 and Y='hff, (S & Y) = (8'b0000_0001 & 8'b1111_1111) = 8'b0000_0001.
The same goes for (~S & X).
Using the replicated concatenation operator will work:
assign M = (~{8{S}} & X) | ({8{S}} & Y);
It is more conventional in Verilog to use the ternary operator to describe a mux:
assign M = (S) ? Y : X;

Verilog 4 bits sum

does anybody know what are for PG and GG variables here:
module sum(S, Cout,PG,GG,A,B,Cin);
wire [3:0] G,P,C;
output [3:0] S;
output Cout,PG,GG;
input [3:0] A,B;
input Cin;
assign G = A & B;
assign P = A ^ B;
assign C[0] = Cin;
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 Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
assign S[0] = P[0] ^ C[0];
assign S[1] = P[1] ^ C[1];
assign S[2] = P[2] ^ C[2];
assign S[3] = P[3] ^ C[3];
endmodule
Your code is a four-bit carry-lookahead adder unit. PG and GG can be Group Propagate and Group Generate. PG and GG can be given to another CLA adder unit to combine such units to form a higher bit adder. They are given as
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];
More details here. http://en.wikipedia.org/wiki/Lookahead_Carry_Unit#16-bit_adder
GG and PG are output ports which are not driven by the code that you have shown. I can not think of a use for them. Unless they are driven by a hierarchical specifier outside of this module (which is possible, but unusual), their value will always be unknown (x).
Perhaps the original designer had intended to use these outputs, and then forgot to remove them.

Resources