Reputation: 11
I am implementing a 4-bit ALU using Verilog. I am getting some weird results in testbecnh.
Here is code for the ALU:
`include "ripple_carry_adder_4.v"
module alu_4(A, B, CTRL, Y);
input [3:0] A, B;
input [3:0] CTRL;
output reg [4:0] Y;
wire [4:0] add;
wire [4:0] sub;
assign add_ctrl = 1'b0;
assign sub_ctrl = 1'b1;
ripple_carry_adder_4 rca0(A, B, add_ctrl, add[4:0]);
ripple_carry_adder_4 rca1(A, B, sub_ctrl, sub[4:0]);
always@(A, B, CTRL)
begin
Y = 5'b00000;
case(CTRL)
4'b0000 : Y = sub;
4'b0001 : Y = add;
default : Y = 5'b0;
endcase
end
endmodule
Code for above's testbench:
`timescale 1ns / 1ns
`include "alu_4.v"
module alu_4_tb;
reg [3:0] A, B;
reg [3:0] CTRL;
wire [4:0] OUT;
alu_4 a(A, B, CTRL, OUT);
initial
begin
$dumpfile("alu_4_tb.vcd");
$dumpvars(0, alu_4_tb);
CTRL=4'b0000;
A=$random;
B=$random;
#40;
CTRL=4'b0001;
A=$random;
B=$random;
#40;
$display("Test completed");
end
endmodule
Code for ripple adder
module ripple_carry_adder_4(A, B, CTRL, S);
input [3:0] A, B;
input CTRL;
output [4:0] S;
wire w[2:0];
wire o[3:0];
xor_2 x0(B[0], CTRL, o[0]);
xor_2 x1(B[1], CTRL, o[1]);
xor_2 x2(B[2], CTRL, o[2]);
xor_2 x3(B[3], CTRL, o[3]);
assign Cin = CTRL | 0;
full_adder f0(A[0], o[0], Cin, S[0], w[0]);
full_adder f1(A[1], o[1], w[0], S[1], w[1]);
full_adder f2(A[2], o[2], w[1], S[2], w[2]);
full_adder f3(A[3], o[3], w[2], S[3], S[4]);
endmodule
I individually tested the ripple adder and there are no problems. Incase of ALU, I observe that the the answer during subtractions always has a '1' ahead of the correct answer. For example, 9-3 = 6. But the answer produced is 16. Another is a case of 4-1 which should be 3, but the answer stored is 13. I have attached the testbench sims below. Kindly help.
Also, no matter how I change the order of simulation, the first operation is always producing unknown('x') state in Y. The wire add & sub are storing the results correctly, but when I transfer those results to Y, it's all going wrong. It's a basic reg=wire statement.
Code for full adder
`include "xor_2.v"
module full_adder(A, B, Cin, S, Cout);
input A, B, Cin;
output S, Cout;
wire w1;
assign Cout = (A & Cin) | (B & Cin) | (A & B);
xor_2 x1(A, B, w1);
xor_2 x2(w1, Cin, S);
endmodule
Code for XOR
module xor_2(A, B, C);
input A, B;
output C;
assign C = A&(~B) | (~A)&B;
endmodule
Upvotes: 1
Views: 1443
Reputation: 62037
You have an incomplete sensitivity list. Change:
always@(A, B, CTRL)
to:
always @*
This removes the x
at the beginning of the simulation. Your code ignores changes on sub
and add
because those signals are not in the sensitivity list. Refer to IEEE Std, section 9.4.2.2 Implicit event_expression list.
I individually tested the ripple adder, and there are no problems.
This claim is incorrect, as this trivial testbench of the ripple_carry_adder_4
demonstrates:
module tb;
reg [3:0] A=9;
reg [3:0] B=3;
reg CTRL=1;
wire [4:0] S;
ripple_carry_adder_4 dut (
.A (A),
.B (B),
.CTRL (CTRL),
.S (S)
);
initial begin
$monitorh("S=", S);
#5 $finish;
end
endmodule
The output is:
S=16
You need to debug your design further. Perhaps you have a connection error.
Upvotes: 1