【问题标题】:ALU using modules in VerilogALU 在 Verilog 中使用模块
【发布时间】:2021-08-11 11:39:39
【问题描述】:

我正在使用 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 中产生未知('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

【问题讨论】:

    标签: verilog hdl digital-logic


    【解决方案1】:

    您的敏感度列表不完整。变化:

        always@(A, B, CTRL)
    

    到:

        always @*
    

    这将删除模拟开始时的x。您的代码会忽略 subadd 上的更改,因为这些信号不在敏感度列表中。请参阅 IEEE Std,第 9.4.2.2 节 隐式 event_expression 列表


    我单独测试了波纹加法器,没有问题。

    这个说法是不正确的,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
    

    您需要进一步调试您的设计。也许你有一个连接错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多