4-Bit verilog adder not passing carry bit - module

I had my 2-bit adder working, except for some reason it is not passing the carry bit. For instance if I use A=1 and B=1 the result S=00, but if either A or B is 1 i get S=1
?i tried printing out the values and it seems my c1 wire in the 2nd module isn't being set, and for some reason Cout is.
So with a input of A=1, B=1, S=00 and Cout=1
when it should be. S=10 and Cout=0
I have only been using Verilog for one day so the syntax is very new to me.
module fulladder(Cin,A,B,S,Cout); // dont forget semi colon
input A,B, Cin; // defaults to 1 bit or [0,0] size
output S, Cout;
wire XOR1,AND1,AND2;
xor(XOR1,A,B);
and(AND1,A,B);
xor(S,Cin,XOR1);
and(AND2,Cin,XOR1);
or(Cout,AND2,AND1);
endmodule
module adder4(Cin,A,B,S,Cout);
input Cin;
input [0:1]A;
input [0:1]B;
output [0:1]S;
output Cout;
wire c1;
fulladder FA1(Cin,A[0:0],B[0:0],S[0:0],c1);
fulladder FA2(c1,A[1:1],B[1:1],S[1:1],Cout);
endmodule
module t_adder;
reg Cin;
reg [1:0]A;
reg [1:0]B;// to declare size, must be on own line, wires can be more than 1 bit
wire [1:0]S;
wire Cout;
adder4 add4bit(Cin,A,B,S,Cout);
initial
begin
A = 1; B = 1; Cin = 0;
#1$display("S=%b Cout = %b",S,Cout);
end
endmodule

You're reversing the bit order in the adder4 module, by declaring the inputs as [0:1], where elsewhere it is [1:0].
Since you reverse the bits, to adder4 it looks like you are adding A=2'b10, B=2'b10, which gives the output you see (3'b100).

Related

My testbench always shows X as the outputs

I'm not able to identify the bug, but all the code seems logically and syntactically right. The value of sum and carry in the testbench are always X.
There are two modules, one for an 8bit adder and another for a 16bit adder :
module adder_8(in1 , in2 , cin , sum , carry);
input [7:0] in1 , in2;
input cin;
output reg [7:0] sum;
output reg carry;
always #(in1 or in2) begin
{carry , sum} = in1 + in2 + cin;
end
endmodule
module adder_16(input_a , input_b , c , summation , cout);
input [15:0] input_a , input_b;
input c;
output [15:0] summation;
output cout;
wire t1;
adder_8 inst1 (input_a[7:0] , input_b[7:0] , c , summation[7:0] , t1);
adder_8 inst2 (input_a[15:8] , input_b[15:8] , t1 , summation[15:8] , cout);
endmodule
The test bench file is :
module testbench;
reg [15:0] a,b;
wire [15:0] sum;
wire carry;
parameter zero = 1'b0;
adder_16 ex(a , b , zero , sum , carry);
initial begin
$monitor($time," A = %d , B = %d sum = %d carry = %b", a , b , sum , carry);
#10 a = 16'd 100; b = 16'd 100;
#10 a = 16'd 50; b = 16'd 20;
#20 $finish;
end
endmodule
I would really appreciate some help.
cin is missing from the sensitivity list in always #(in1 or in2). It should be always #(in1 or in2 or cin) to be complement with the 1995 version of the standard. The 2001 version of the standard improved it to always #* (or the synonymous always #(*) for an automatic sensitivity list.
If you are targeting for SystemVerilog, use always_comb (no # or signal list). This will add an extra compile time check to make sure a the logic is not assigned in another always block which would make the code non-synthesizer.

Index out of range error in Verilog, although the register is declared correctly

I am trying to learn Verilog and I have this simple code
module division (
output reg [14:0] A,
input [14:0] D);
reg[4:0] i;
always #(*) begin
for (i = 14; i >= 0; i = i-1) begin
A[0] = D[i];
end
end
endmodule
This returns the error : Index out of range for D.. I have no idea why, since D is declared on that interval. Can you please help me?
I know the code might not make any sense, but I only included the relevant part to the issue.
You have declared i as unsigned, so the expression i >= 0 will always be true.
When i reaches 0, the next iteration is 5'b11111, which is out of range. You should declare i as an integer or add the signed keyword.

Verilog Instantiating module inside a always block. Using Adder for multiplication

I have a code written for multiplying two 53 bit numbers (written below). I am using shift-add strategy using two other 106 bit registers. This code is working fine. Now I have another 53 bit highly optimized hans carlson adder module written in form:
module hans_carlson_adder(input [52:0] a, b, input c_in, output [52:0] sum, output c_out);
I want to use this adder to do the summation line in for loop (mentioned in code). I am having problem instantiating the adder inside an always block. Plus I dont want to have 106 instances (due to for loop) of this adder. Can you please help with this code
module mul1(
output reg [105:0] c,
input [52:0] x,
input [52:0] y,
input clk,
input state
);
reg [105:0] p;
reg [105:0]a;
integer i;
always #(posedge clk) begin
if (state==1) begin
a={53'b0,x[52:0]};
p=106'b0; // needs to zeroed
for(i=0;i<106;i=i+1) begin
if(y[i]) begin
p=p+a; //THIS LINE NEEDS TO BE REPLACED WITH HANS CARLSONADDER
end
a=a<<1;
end
c<=p;
end else begin
c=0;
end
end
endmodule
First you need to instantiate your adder outside of the always block and connect it to signals:
wire [52:0] b;
reg [5:0] count;
assign b = c[count+7'd52:count];
wire [52:0] sum;
wire c_out;
// Add in x depending on the bits in y
// b has the running result bits that still apply at this point
hans_carlson_adder u0(x, b, 1'b0, sum, c_out);
Now because this is a pipelined adder you are going to need something to kick off the multiplication (I'll call that input start) and something that indicates that the result is available (I'll call that output reg done). You'll want to add them to your mul1 module definition. You can choose a slightly different protocol depending on your needs. It appears that you have something that you've been implementing with the input state. I'm also going to use start to initialize during each calculation so that I don't need a separate reset signal.
reg [52:0] shift;
always #(posedge clk) begin
if (start) begin
done <= 0;
count <= 0;
c <= 106'b0;
shift <= y;
end else if (count < 53) begin
if (shift[0]) begin
c[count+7'd52:count] <= sum;
c[count+7'd53] <= c_out;
end
count <= count + 1;
shift = shift >> 1;
end else begin
done <= 1;
end
end
If you want to make an optimization you could end once the shift signal is equal to 0. In this case the done signal would become high as soon as there were no more bits to add into the result, so multiplying by small values of y would take less cycles.

a simple increment register

I want to design an increment register that always increases input and put it in output. I write this code, but it has error:
# Error: VCP2858 test3.v : (51, 19): in is not a valid left-hand side of a procedural assignment.
module inc(in, out);
output reg [0:32] out ;
input [0:32] in ;
wire [0:32] in ;
always #(*)
begin
in <=( in + 1);//error
out<=in;
end
endmodule
In Verilog, you should not assign a value to a signal declared as an input inside a module. Your code can be simplified as:
module inc(in, out);
output [0:32] out ;
input [0:32] in ;
assign out = in + 1;
endmodule

Instantiate a module number of times based on a parameter value in Verilog

Assume we have the following arbitrary parameterized module
module module_x #(parameter WIDTH = 1) (in_a, in_b, out);
input [WIDTH - 1] in_a, in_b;
output out;
// Some module instantiation here
endmodule
How do I instantiate another based on the value of WIDTH ? like if it's 5 I instantiate it 5 times on each bit, is it possible to do this in Verilog ?
Generate statements are a common approach to this: Section 27 page 749 of IEEE 1800-1012.
A quick example :
logic [WIDTH-1:0] a;
logic [WIDTH-1:0] b;
genvar i;
generate
for(i=0; i<WIDTH; i++) begin
module_name instance_name(
.a(a[i]),
.b(a[i])
);
end
endgenerate
As #toolic has pointed out instance arrays are also possible, and simpler.
logic clk;
logic [WIDTH-1:0] a_i;
logic [WIDTH-1:0] b_i;
module_name instance_name[WIDTH-1:0] (
.clk ( clk ), //Single bit is replicated across instance array
.a ( a_i ), //connected wire a_i is wider than port so split across instances
.b ( b_i )
);