verilog - ALU 在 Verilog 中使用模块
问题描述
我正在使用 Verilog 实现一个 4 位 ALU。我在 testbecnh 中得到了一些奇怪的结果。
这是 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
上面的测试台代码:
`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
波纹加法器的代码
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
我单独测试了纹波加法器,没有问题。在 ALU 的情况下,我观察到减法期间的答案总是在正确答案之前有一个“1”。例如,9-3 = 6。但产生的答案是 16。另一个是 4-1 的情况,应该是 3,但存储的答案是 13。我附上了下面的测试台模拟程序。请帮忙。
此外,无论我如何更改模拟顺序,第一个操作总是在 Y 中产生 unknown('x') 状态。线add & sub正确存储结果,但是当我将这些结果传输到Y时,这一切出错了。这是一个基本的 reg=wire 语句。
全加器代码
`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
异或代码
module xor_2(A, B, C);
input A, B;
output C;
assign C = A&(~B) | (~A)&B;
endmodule
解决方案
您的敏感度列表不完整。改变:
always@(A, B, CTRL)
至:
always @*
这将删除x
模拟开始时的 。您的代码忽略了更改sub
,add
因为这些信号不在敏感度列表中。请参阅 IEEE 标准,第 9.4.2.2 节隐式事件表达式列表。
我单独测试了纹波加法器,没有问题。
这个说法是不正确的,因为这个简单的测试台ripple_carry_adder_4
证明了:
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
输出是:
S=16
您需要进一步调试您的设计。也许你有一个连接错误。
推荐阅读
- sql - 如何将选择上的最大/最小日期列与上一个日期的数据连接起来
- angular - 错误:期望验证器返回 Promise 或 Observable
- r - 治疗组和对照组之间 OR 语句的 R 代码
- windows - Windows 沙盒不运行 .NET 应用程序
- kubernetes - 阻止 Kubernetes Ingress 重写 URL
- javascript - 看来我无法通过 AJAX 将 JSON 对象传递给我的 php 服务器
- java - JVM CodeCache 区域中存储了哪些编译后的代码
- react-native - 如何在不使用图像的情况下更改 MapView.Marker “SIZE”?
- python - 有没有办法定期保存您当前正在使用的 Simulink 文件?
- android - 尝试将 Google 帐户与新电话号码关联时出现 FirebaseAuthUserCollisionException