Error in testbench as Inout port 'A' of 'DIGITADD' must be a net - verilog

module DIGITADD(
input [3:0] A,
input [3:0] B,
input CIN,
output COUT,
output [3:0] SUM
);
reg [4:0] s2;
assign SUM = s2[3:0];
assign COUT = s2[4];
//BCD ADDER PART
always # ( * )
begin
s2 = A + B + CIN;
if (s2 > 9)
begin
s2 = s2 + 6;
end
end
endmodule
TEST BENCH
module DIGITADD_tb(
reg [3:0] A,
reg [3:0] B,
reg CIN,
wire COUT,
wire [3:0] SUM);
DIGITADD uut(
.A(A),
.B(B),
.CIN(CIN),
.COUT(COUT),
.SUM(SUM));
initial begin
$dumpfile("dump.vcd");
$dumpvars(1,DIGITADD_tb);
#10;
#10 A=4'b0000;B=4'b0011;CIN=1'b0;
#10 A=4'b0111;B=4'b1000;CIN=1'b1;
$finish;
end
endmodule

You have added local variables in your testbench in the style of a port list:
module DIGITADD_tb(
reg [3:0] A,
reg [3:0] B,
reg CIN,
wire COUT,
wire [3:0] SUM);
Should be:
module DIGITADD_tb(); //<-- no ports
reg [3:0] A; //<-- semicolon
reg [3:0] B;
reg CIN;
wire COUT;
wire [3:0] SUM;

Related

Facing Some problem is FSM design and datapath [duplicate]

The output waveform shows no change in the sum, dif, burrow, and out. Even after increasing delay time, still the output shows no change. This should work like the mod adder like add 10 and 2 and with mod 3 give output zero.
CODE
module Mod_adder(a,b,p,out);
input [3:0] a;
input [3:0] b;
input [3:0] p;
output [3:0] out;
wire [3:0] sum;
wire cout;
wire burrow;
wire [3:0] dif;
ripple_carry_adder r1(a,b,sum,cout,1'b0);
ripple_carry_adder r2(sum,~p,dif,burrow,1'b1);
repeat_sum rs1(dif,burrow,sum);
outval o1(sum,burrow,out);
endmodule
module full_adder(in0, in1, cin, out, cout);
input in0, in1, cin;
output out, cout;
assign out = in0 ^ in1 ^ cin;
assign cout = ((in0 ^ in1) & cin) | (in0 & in1);
endmodule
module ripple_carry_adder(in0, in1, out, cout,cin);
input [3:0] in0;
input [3:0] in1;
output [3:0] out;
output cout;
input cin;
wire c1, c2, c3;
full_adder fa0(in0[0], in1[0], cin, out[0], c1);
full_adder fa1(in0[1], in1[1], c1, out[1], c2);
full_adder fa2(in0[2], in1[2], c2, out[2], c3);
full_adder fa3(in0[3], in1[3], c3, out[3], cout);
endmodule
module repeat_sum(dif,burrow,sum);
input [3:0] dif;
input burrow;
output [3:0] sum;
assign sum = (burrow == 1'b0) ? dif:sum;
endmodule
module outval(sum,burrow,out);
input [3:0] sum;
input burrow;
output [3:0] out;
assign out = (burrow == 1'b1) ? sum:out;
endmodule
TEST BENCH
` include "MOD_ADDER.V"
module Mod_adder_tb;
reg [3:0] a;
reg [3:0] b;
reg [3:0] p;
wire [3:0] out; // wires
// Instantiate the module to be tested
Mod_adder MA1(a,b,p,out);
initial begin // initial block
$dumpfile("Test_Full_Adder.vcd");
$dumpvars(1, MA1);
a=4'b1010;
b=4'b0100;
p=4'b0011;
#100;
end // end of initial block
endmodule
I see 2 major problems.
Your out testbench signal is unknown (X) because of driver contention. For example, the sum signal in Mod_adder has multiple drivers: from the r1 instance and from the rs1 instance. The out output of r1 and the sum output of rs1 are both driving the sum wire. You should not drive the same signal from 2 different module instances. You could rename one of the sum signals to something unique, like sum_rs1 and declare a new wire.
wire [3:0] sum, sum_rs1;
Also, you have combinational feed back loops. For example:
assign out = (burrow == 1'b1) ? sum:out;
The out signal should not be on both the LHS and RHS of a continuous assignment.

Modulo adder output shows no change

The output waveform shows no change in the sum, dif, burrow, and out. Even after increasing delay time, still the output shows no change. This should work like the mod adder like add 10 and 2 and with mod 3 give output zero.
CODE
module Mod_adder(a,b,p,out);
input [3:0] a;
input [3:0] b;
input [3:0] p;
output [3:0] out;
wire [3:0] sum;
wire cout;
wire burrow;
wire [3:0] dif;
ripple_carry_adder r1(a,b,sum,cout,1'b0);
ripple_carry_adder r2(sum,~p,dif,burrow,1'b1);
repeat_sum rs1(dif,burrow,sum);
outval o1(sum,burrow,out);
endmodule
module full_adder(in0, in1, cin, out, cout);
input in0, in1, cin;
output out, cout;
assign out = in0 ^ in1 ^ cin;
assign cout = ((in0 ^ in1) & cin) | (in0 & in1);
endmodule
module ripple_carry_adder(in0, in1, out, cout,cin);
input [3:0] in0;
input [3:0] in1;
output [3:0] out;
output cout;
input cin;
wire c1, c2, c3;
full_adder fa0(in0[0], in1[0], cin, out[0], c1);
full_adder fa1(in0[1], in1[1], c1, out[1], c2);
full_adder fa2(in0[2], in1[2], c2, out[2], c3);
full_adder fa3(in0[3], in1[3], c3, out[3], cout);
endmodule
module repeat_sum(dif,burrow,sum);
input [3:0] dif;
input burrow;
output [3:0] sum;
assign sum = (burrow == 1'b0) ? dif:sum;
endmodule
module outval(sum,burrow,out);
input [3:0] sum;
input burrow;
output [3:0] out;
assign out = (burrow == 1'b1) ? sum:out;
endmodule
TEST BENCH
` include "MOD_ADDER.V"
module Mod_adder_tb;
reg [3:0] a;
reg [3:0] b;
reg [3:0] p;
wire [3:0] out; // wires
// Instantiate the module to be tested
Mod_adder MA1(a,b,p,out);
initial begin // initial block
$dumpfile("Test_Full_Adder.vcd");
$dumpvars(1, MA1);
a=4'b1010;
b=4'b0100;
p=4'b0011;
#100;
end // end of initial block
endmodule
I see 2 major problems.
Your out testbench signal is unknown (X) because of driver contention. For example, the sum signal in Mod_adder has multiple drivers: from the r1 instance and from the rs1 instance. The out output of r1 and the sum output of rs1 are both driving the sum wire. You should not drive the same signal from 2 different module instances. You could rename one of the sum signals to something unique, like sum_rs1 and declare a new wire.
wire [3:0] sum, sum_rs1;
Also, you have combinational feed back loops. For example:
assign out = (burrow == 1'b1) ? sum:out;
The out signal should not be on both the LHS and RHS of a continuous assignment.

verilog AND gate when 32 not working correctly

The AND gate
module andgate
#(parameter Port_Num = 2,
parameter WIDTH=8)
(
input [(WIDTH-1):0] a,
input [(WIDTH-1):0] b,
input [(WIDTH-1):0] c,
input [(WIDTH-1):0] d,
input [(WIDTH-1):0] e,
input [(WIDTH-1):0] f,
input [(WIDTH-1):0] g,
input [(WIDTH-1):0] h,
output [(WIDTH-1):0] q
);
assign q = (a & b & c & d & e & f & g & h);
endmodule
The angate_sim
`timescale 1ns / 1ps
module andgate_sim();
// input
reg a=0;
reg b=0;
reg c=1;
reg d=1;
reg e=1;
reg f=1;
reg g=1;
reg h=1;
//outbut
wire q;
andgate #(8,1) u(.a(a),.b(b),.c(c),.d(d),.e(e),.f(f),.g(g),.h(h),.q(q));
always #100 a=~a;
initial begin
#100 a=1;
#100 begin a=0;b=1;end
#100 a=1;
#60000000 $finish;
end
initial
begin
$dumpfile("wave2.vcd");
$dumpvars(0, andgate_sim);
end
endmodule
When I test the testbench, it worked correctly like this
iverilog -o Ex2 andgate.v andgate_sim.v
vvp -n Ex2 -lxt2
gtkwave wave2.vcd
The successful wave in wave2.vcd
Then I tried to make a AND gate*32 just like this
`timescale 1ns / 1ps
module andgate32_sim( );
// input
reg [31:0] a=32'h00000000;
reg [31:0] b=32'h00000000;
reg [31:0] c=32'hffffffff;
reg [31:0] d=32'hffffffff;
reg [31:0] e=32'hffffffff;
reg [31:0] f=32'hffffffff;
reg [31:0] g=32'hffffffff;
reg [31:0] h=32'hffffffff;
//outbut
wire [31:0] q;
andgate #(8,32) u(.a(a),.b(b),.c(c),.d(d),.e(e),.f(f),.g(g),.h(h),.q(q));
always #100
begin
a <= 32'hffffffff;
end
always #200
begin
a <= 32'h00000000;
b <= 32'hffffffff;
end
always #300
begin
a <= 32'h007fa509;
end
always #400
begin
a <= 32'hffffffff;
end
initial begin
#100 a <= 32'hffffffff;
#100 begin a <= 32'h00000000;b <= 32'hffffffff;end
#100 a <= 32'h007fa509;
#100 a <= 32'hffffffff;
#60000000 $finish;
end
initial
begin
$dumpfile("wave2-2.vcd");
$dumpvars(0, andgate32_sim);
end
endmodule
But when I did the steps like before
iverilog -o Ex2 andgate.v andgate32_sim.v
vvp -n Ex22 -lxt2
gtkwave wave2-2.vcd
There was nothing in the wave like this
No waves in the wave2-2.vcd
Actaully, it should be something in the wave2-2.vcd.
Could you please help me ?
You are trying to run another compiled testbench "Ex22" instead of "Ex2".
Hint: You can use parameters and pass them to the instantiation, as:
localparam WIDTH = 32;
localparam Port_Num = 8;
// input
reg [WIDTH-1:0] a=32'h00000000;
reg [WIDTH-1:0] b=32'h00000000;
reg [WIDTH-1:0] c=32'hffffffff;
reg [WIDTH-1:0] d=32'hffffffff;
reg [WIDTH-1:0] e=32'hffffffff;
reg [WIDTH-1:0] f=32'hffffffff;
reg [WIDTH-1:0] g=32'hffffffff;
reg [WIDTH-1:0] h=32'hffffffff;
//outbut
wire [WIDTH-1:0] q;
andgate #(.Port_Num (Port_Num), .WIDTH (WIDTH)) u(.a(a),.b(b),.c(c),.d(d),.e(e),.f(f),.g(g),.h(h),.q(q));

Arithmetic right shift not working in Verilog HDL

I am building a shift-unit that is capable of arithmetic and logical right shift, and logical left shift depending on the control signals given to it. However, the arithmetic right shift operator output generates output similar to that logical right shift operator, i.e. sign extension does not occur.
Main code
`timescale 1ns / 1ps
module shift_unit(
input [15:0] a,
input [3:0] b,
input clk,
input isLSL,
input isLSR,
input isASR,
output reg [15:0] result
);
wire [15:0] LSL_result, LSR_result, ASR_result;
LSL lsl(a, b, clk, isLSL, LSL_result);
LSR lsr(a, b, clk, isLSR, LSR_result);
ASR asr(a, b, clk, isASR, ASR_result);
always#(posedge clk) begin
case({isLSL, isLSR, isASR})
3'b001: result <= ASR_result;
3'b010: result <= LSR_result;
3'b100: result <= LSL_result;
endcase
end
endmodule
LSL code:
`timescale 1ns / 1ps
module LSL(
input [15:0] a,
input [3:0] b,
input clk,
input isLSL,
output [15:0] out
);
reg [15:0] result;
always#(posedge clk) begin
if(isLSL) result = a << b;
end
assign out = result;
endmodule
LSR code:
`timescale 1ns / 1ps
module LSR(
input [15:0] a,
input [3:0] b,
input clk,
input isLSR,
output [15:0] out
);
reg [15:0] result;
always#(posedge clk) begin
if(isLSR) result = a >> b;
end
assign out = result;
endmodule
ASR code:
`timescale 1ns / 1ps
module ASR(
input [15:0] a,
input [3:0] b,
input clk,
input isASR,
output [15:0] out
);
reg [15:0] result;
always#(posedge clk) begin
if(isASR) result = a >>> b;
end
assign out = result;
endmodule
And finally, the testbench:
`timescale 1ns / 1ps
module shift_unit_test;
reg [15:0] a;
reg [3:0] b;
reg clk;
reg isLSL;
reg isLSR;
reg isASR;
wire [15:0] result;
shift_unit uut (
.a(a),
.b(b),
.clk(clk),
.isLSL(isLSL),
.isLSR(isLSR),
.isASR(isASR),
.result(result)
);
always #5 clk = ~clk;
initial begin
clk = 1'b0;
a = 16'b1100101011001010;
b = 4;
{isLSL, isLSR, isASR} = 3'b100; #100;
{isLSL, isLSR, isASR} = 3'b010; #100;
{isLSL, isLSR, isASR} = 3'b001; #100;
end
endmodule
The above code has been modelled using Xilinx ISE 14.7.
Any help would be greatly appreciated.
You need to be working with signed signals to get sign extension.
module ASR(
input wire signed [15:0] a,
input [3:0] b,
input clk,
input isASR,
output reg signed [15:0] out
);
always#(posedge clk) begin
if(isASR) out = a >>> b;
end
endmodule

Red outputs lines - Verilog simulation

I try to simulate in Modelsim my code on Verilog. When I'm simulating it, it shows me X(red) outputs lines. This is my code and testbench:
module alu64bit (
input wire [63:0] a, // Input bit a
input wire [63:0] b, // Input bit b
input wire cin, // Carry in
input wire [1:0] op, // Operation
output wire [63:0] s, // Output S
output wire cout // Carry out
);
wire [63:0] cin_out;
assign cout = cin_out[63];
assign cin = cin_out[0];
genvar i;
generate
for(i=0; i <= 63; i = i + 1) begin
alu1bit alu (.s(s[i]),.cout(cin_out[i+1]),.a(a[i]),.b(b[i]),.cin(cin_out[i]),.op(op));
end
endgenerate
// End of your code
endmodule
TB:
module alu64bit_test;
reg [63:0] a;
reg [63:0] b;
reg [1:0] op;
reg cin;
wire [63:0] s;
wire cout;
alu64bit uut (
.a(a),
.b(b),
.cin(cin),
.op(op),
.s(s),
.cout(cout)
);
initial begin
a = 64'hffffffffffffffff;
b = 64'h0000000000000000;
cin = 0;
op[1] = 1;
op[0] = 0;
#100;
end
endmodule
enter image description here
Can somebody help me with this problem? Thank You!

Resources