4-bit adder subtractor Verilog code errors - verilog

I am trying to do a 4-bit adder subtractor in Verilog code, but there is some kind of problem in my code that I couldn't figure out. I'm not sure if the testbench or the Verilog is wrong. Can someone please help me with it? Also, when I try to simulate it, it gives Loading Errors.
My Verilog code:
module addsubparameter (A, B, OP, C_out, Sum);
input A,B;
input OP;
output C_out;
output Sum;
wire C_out, Sum;
reg assigning;
always#(OP)
begin
if (OP == 0)
assigning = A + B + OP;
else
assigning = A + (~B + 1) + OP;
end
assign {C_out, Sum} = assigning;
endmodule
module adder (a, b, op, cout, sum);
parameter size = 4 ;
input [3:0] a, b;
output [3:0] sum;
input op;
output cout;
wire [2:0] c;
genvar i;
generate
for (i = 0; i < size; i = i + 1) begin: adder
if (i == 0)
addsubparameter (a[i], b[i], op, sum[i], c[i]);
else if (i == 3)
addsubparameter (a[i], b[i], c[i-1], cout, sum[i]);
else
addsubparameter (a[i], b[i], c[i-1], sum[i], c[i]);
end
endgenerate
endmodule
And this is my testbench:
module addsub_tb();
reg [3:0] a;
reg [3:0] b;
reg op;
wire [3:0] sum;
wire cout;
adder DUT (a,b,op,sum,cout);
initial begin
a = 4'b1010; b = 4'b1100; op = 1'b0; #100;
a = 4'b1111; b = 4'b1011; op = 1'b1; #100;
a = 4'b1010; b = 4'b1010; op = 1'b0; #100;
end
endmodule

Your simulator should generate error and/or warning messages because you have syntax errors. If it does not, sign up for a free account on edaplayground, where you will have access to multiple simulators which will produce helpful messages.
You need to add instance names. For example, I added i0 in the line below:
addsubparameter i0 (a[i], b[i], op, sum[i], c[i]);
You have port connection width mismatches, and these indicate connection errors. This is a common type of error when you use connections by position. You mistakenly connected the sum signal to the cout port, and vice versa. You should use connections by name instead. For example, change:
adder DUT (a,b,op,sum,cout);
to:
adder dut (
.a (a),
.b (b),
.op (op),
.cout (cout),
.sum (sum)
);
Use this coding style for all your instances.
You won't get a simulation warning, but you might get a synthesis warnings about an incomplete sensitivity list. Change:
always#(OP)
to:
always #*

Related

Verilog Adder/Subtractor [duplicate]

This question already has answers here:
How do I use flip flop output as input for reset signal
(1 answer)
Why is my counter out value producing StX?
(2 answers)
Closed 2 months ago.
Trying to make a Binary adder and Subtractor in Verilog Output keeps coming out as X I don't think it is the testbench I believe is something wrong with the wires for the output F. The Flip Flops and the Multiplexer should be correct but I have no way of knowing for sure I do not get any error messages when I run this
module Subtractor(A, B, Bin, Bout , Sub); //Variables for subtractor
// 1-bit full binary subtractor.
input A;//Input variable
input B;//Input variable
input Bin;//Input variable
output Bout;
output Sub;
assign Bout=((~A)&(B))|((~A)&(Bin))|((B)&(Bin));
assign Sub=(A^B^Bin);
endmodule
module Adder(A, B, Cin, Cout, Sum);
// 1- bit full binary adder
input A, B, Cin;
output Cout, Sum;
assign Cout = ((A)&(Cin))|((B)&(Cin))|((A)&(B));
assign Sum = (A^B^Cin);
endmodule
module CarryFLIPFLOP(CLK,RESET,D,Q);
//Flip flop for carry value
input CLK,RESET,D;
output reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module BorrowFLIPFLOP(CLK,RESET,D,Q);
// 1- bit full binary adder
input CLK,RESET,D;
output reg Q;
//reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module Fplexer(Sum, Sub, S, F, clk);
input Sum, Sub, S, clk;
output reg F;
always#(posedge clk) begin
if(S==1) begin
F <= Sum;
end else begin
F <= Sub;
end
end
endmodule
module z_flag(clk,F,R,Z);
input clk,F,R;
output reg Z=1;
always#(posedge clk)begin
Z=R|(Z&~F);
end
endmodule
module top(A,B,S,R,clk,F,Z,N,V);
input A, B, S, R, clk;
output F, Z, N, V;
wire w0,w1,w2,w3,w4,w5,w6,w7,w8;
assign w7 = A;
assign w8 = B;
Subtractor S0(.A(w7), .B(w8), .Bin(w3), .Bout(w4), .Sub(w5));
BorrowFLIPFLOP Borrow(.CLK(clk), .RESET(R), .D(w2), .Q(w3));
Adder A0(.A(w7), .B(w8), .Cin(w0), .Cout(w1), .Sum(w2));
CarryFLIPFLOP Carry(.CLK(clk), .RESET(R), .D(w2), .Q(w0));
Fplexer multi(.Sum(w2), .Sub(w5), .S(S), .F(w6), .clk(clk));
assign V=(w0 & w1);
assign F = w6;
assign N = w6;
z_flag Zflag(.clk(clk), .F(w6), .R(R), .Z(Z));
endmodule
module testbench;
reg clk;
reg R;
reg A;
reg B;
reg S = 0;
wire F;
//intitialize clock/top
top UUT(A,B,S,R,clk,F,Z,N,V);
always
#5 clk = ~clk;
initial begin
$display("Testing +- Machine");
$monitor("%d - %d Is %d",A, B, F);
A = 0; B = 1; S = 0; R=0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 1; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
end
endmodule
Your design has a reset signal and you never used it.
Your FLIPFLOP code does not have RESET in the sensitivity list.
You are making assignments to clk in an always block and in the initial block. Pick one place.
Learn how to save waveforms to see internal signals, not just the top level output.

assign not updating result value in testbench in EDA playground

I am using EDA Playground with Aldec Riviera simulator, and I have this module here:
module alu(input logic [31:0] a, b,
input logic [2:0] alucontrol,
output logic [31:0] result,
output logic zero);
logic [31:0] condinvb, sum;
assign condinvb = alucontrol[2] ? ~b : b;
assign sum = a + condinvb + alucontrol[2];
always_comb
case (alucontrol[1:0])
2'b00: result = a & b;
2'b01: result = a | b;
2'b10: result = sum;
2'b11: result = sum[31];
endcase
assign zero = (result == 32'b0);
endmodule
and my testbench is here:
module alu_testbench();
logic [31:0] a,b;
logic [2:0] alucontrol;
logic [31:0] result;
logic zero, clk;
alu test_alu(a,b,alucontrol);
initial begin
$dumpfile("dump.vcd"); $dumpvars(1);
clk = 0;
a = 'hdead0000; b = 'h0000beef; alucontrol = 'b010; #1;
a = 'hc0debabe; b = 'h0000ffff; alucontrol = 'b000; #1;
a = 'hc0de0000; b = 'h0000babe; alucontrol = 'b001; #1;
a = 'hc0debabe; b = 'h0000babe; alucontrol = 'b100; #1;
end
always begin
#1; clk = ~clk;
end
endmodule
When I run the testbench and look at the generated waveform, I do not see result being updated. Instead, it stays as XXXX_XXXX. What am I doing wrong in the testbench?
In the testbench, you declared the result signal, but it is not connected to anything. You probably intended it to be driven by the alu output of the same name. In that case, you should connect it to the instance:
Change:
alu test_alu(a,b,alucontrol);
to:
alu test_alu(a,b,alucontrol,result,zero);
Try your code on other simulators on edaplayground; you should get warnings about unconnected ports.
With your code, if you looked inside the alu instance, the result signal would not be X.
Another equivalent way to code the instance is to use connections by name:
alu test_alu (
.a (a),
.b (b),
.alucontrol (alucontrol),
.result (result),
.zero (zero)
);
This makes it easier to avoid common connection errors.

4-bit adder not adding correctly

I'm creating a 4-bit adder using 1-bit adder in Verilog and facing a problem that my 4-bit is not adding correctly.
This is my code for both:
1bit
module ab_fulladd (A,B,Cin,S,Cout);
output Cout,S;
input A,B,Cin;
wire w1,w2,w3;
xor G1(S,A,B,Cin);
and
G2(w1,A,B),
G3(w2,A,Cin),
G4(w3,B,Cin);
or
G5(Cout,w1,w2,w3);
endmodule
4-bit
module add4bit_parametric (a, b, cin, cout, sum);
parameter size = 4;
input [size-1:0] a, b;
input cin;
output cout;
output [size-1:0] sum;
wire [size-2:0] c;
genvar i;
generate
for (i = 0; i < size; i = i + 1) begin: adder
if (i == 0)
ab_fulladd fa (a[i], b[i], cin, c[i], sum[i]);
else if (i == size-1)
ab_fulladd fa(a[i],b[i],c[i-1],cout,sum[i]);
else
ab_fulladd fa (a[i],b[i],c[i-1],c[i],sum[i]);
end endgenerate
endmodule
My 4-bit is not adding up well in the waveform. Can you help me please?
You have a port connection bug. You mistakenly connected the sum and c signals because you use connection-by-order. To avoid this common type of mistake, use connection-by-name. Change:
ab_fulladd fa (a[i], b[i], cin, c[i], sum[i]);
to:
ab_fulladd fa (.A(a[i]), .B(b[i]), .Cin(cin), .Cout(c[i]), .S(sum[i]));
Repeat this for all instances. Here is the complete module code:
module add4bit_parametric (a, b, cin, cout, sum);
parameter size = 4;
input [size-1:0] a, b;
input cin;
output cout;
output [size-1:0] sum;
wire [size-2:0] c;
genvar i;
generate
for (i = 0; i < size; i = i + 1) begin: adder
if (i == 0)
ab_fulladd fa (.A(a[i]), .B(b[i]), .Cin(cin), .Cout(c[i]), .S(sum[i]));
else if (i == size-1)
ab_fulladd fa(.A(a[i]), .B(b[i]), .Cin(c[i-1]), .Cout(cout), .S(sum[i]));
else
ab_fulladd fa (.A(a[i]), .B(b[i]), .Cin(c[i-1]), .Cout(c[i]), .S(sum[i]));
end endgenerate
endmodule
It compiles on multiple simulators on edaplayground (sign up for a free account).

How do I resolve Verilog simulation error: "Too many port connections. Expected 8, found 9" in ModelSim

I'm trying to build an 8-bit multiplier in Verilog, but I keep running in to this weird error when I go to simulate my module's test bench. It says:
Too many port connections. Expected 8, found 9
This doesn't really make any sense seeing as how both the module AND the test bench have 9 variables listed. Any help will be much appreciated!
Multiplier Module
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
reg Done;
reg [1:0] state;
reg [7:0] A_reg, B_reg;
reg [15:0] A_temp, B_temp, O_temp, O_reg;
my16bitadder Adding(O_temp, Cout,A_temp,B_temp, Cin);
always#(posedge Clk)
begin
if(Reset) assign state = {2'b00};
case(state)
0:
if(Load)
begin
A_reg = A;
B_reg = B;
O_reg = A_reg;
state = 1;
end
1:
begin
A_temp = A_reg;
B_temp = O_reg;
B_reg = B_reg - 1;
state = 2;
end
2:
begin
O_reg = O_temp;
if(B_temp)
begin
state = 1;
end
else
begin
state = 3;
Done = 1'b1;
end
end
3:
begin
Done = 1'b0;
state = 0;
end
endcase
end
endmodule
Testbench
module my8bitmultiplier_tb;
reg Load, Clk, Reset, Cin;
reg [7:0] A, B;
wire [15:0] O;
wire Done, Cout;
my8bitmultiplier dut(O, Done, Cout, A, B, Load, Clk, Reset, Cin);
always #5 Clk = ~Clk;
initial
begin
A = 8'b10;
B = 8'b10;
Load = 1;
Cin = 0;
#10 Load = 0;
#3000 A = 8'd100;
#3000 B = 8'd100;
#3000 Load = 1;
#3010 Load = 0;
#6000 A = 8'd150;
#6000 B = 8'd150;
#6000 Load = 1;
#6000 Load = 0;
begin
$display ($time,"A= %d B= %d O=%d ", A, B, O);
end
#10000 $finish;
end
endmodule
When I run you code on another simulator, I get a more helpful warning message:
reg Done;
|
xmvlog: *W,ILLPDX : Multiple declarations for a port not allowed in module with ANSI list of port declarations (port 'Done') [12.3.4(IEEE-2001)].
The warning goes away when I delete this line:
reg Done;
and change:
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
to:
module my8bitmultiplier (output [15:0] O, output reg Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
Perhaps that solves your problem on modelsim. You can also try your code on different simulators on edaplayground. You will sometimes get more helpful messages.

I understand the fundamentals of verilog, but test bench just won't make sense

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

Resources