Verilog - 加法器主模块的问题

Verilog - Issue with Main Module for Adder

我正在尝试编写代码来模拟一个 8 位输入寄存器,输出输入数据的总和。该模型还包含时钟、启用和复位引脚。

我首先制作一个 1 位和 8 位加法器来开始这个问题,如下所示。 (请注意,我不关心 MSB 的执行引脚)。

module adder_1bit(A,B,Cin,S,Cout);

input A,B,Cin;
output  Cout,S;
wire   W1, W2, W3;
assign W1 = A ^ B;
assign W2 = Cin & W1;
assign W3 = A & B;
assign S = Cin ^ W1;
assign Cout = W2 | W3;

endmodule

module adder_8bit(Din,Sum);
input [7:0] Din;
output [7:0] Sum;
wire [7:0] C;

adder_1bit M1(Din[0],Din[0],1'b0,Sum[0],C[0]);
adder_1bit M2(Din[1],Din[1],C[0],Sum[1],C[1]);
adder_1bit M3(Din[2],Din[2],C[1],Sum[2],C[2]);
adder_1bit M4(Din[3],Din[3],C[2],Sum[3],C[3]);
adder_1bit M5(Din[4],Din[4],C[3],Sum[4],C[4]);
adder_1bit M6(Din[5],Din[5],C[4],Sum[5],C[5]);
adder_1bit M7(Din[6],Din[6],C[5],Sum[6],C[6]);
adder_1bit M8(Din[7],Din[7],C[6],Sum[7],C[7]);

endmodule

然后我做了一个测试台,一切正常。我的主要问题是将这些模块与我的 clk、enable 和 rst 代码结合起来。这是我目前拥有的。当我的复位引脚为高时,我的输出为 0。我还必须检查 MSB 是否为负,以确保我将其转换为正值(我的问题的一部分)。

module Main(Data_in,Start,rst,clk,Sum_Abs);

input rst, clk, Start;
input [7:0] Data_in;
output  [7:0] Sum_Abs;
reg [7:0] Sum_Abs;
reg [7:0] Data_in_buffer;

adder_8bit M9(Data_in_buffer,Sum_abs);

always @(posedge clk)
begin
    if(rst == 1'b1)
        begin
            Sum_Abs = 8'b00000000;      
        end 
    else if(Start == 1'b1)
        begin
            case(Data_in)
            8'b1xxxxxxx: Data_in_buffer = ~Data_in + 1'b1;
            8'b0xxxxxxx: Data_in_buffer = Data_in;
            endcase     
        end 
end
endmodule

这就是我的问题所在。当我创建如下所示的测试台时,我的总和输出始终为 'x'。我的问题必须来自主模块,因为我之前的测试没有遇到这个问题。我对verilog比较陌生,如果有任何提示或帮助将不胜感激,谢谢!

module Main_tb;

integer k;
reg signed [7:0] Din_tb;
reg str, rst_tb, clk_tb;
wire signed [7:0] Sum_tb; 

Main DUT(Din_tb,str,rst_tb,clk_tb,Sum_tb);

initial begin
$display("\tData,\tOutput");
$monitor("\t%d,\t%d",Din_tb,Sum_tb); 
Din_tb = 8'b00000001;
clk_tb = 0;
str = 1'b1;
rst_tb = 1'b0;

#5 clk_tb = 1;
#5 Din_tb = 8'b00000010;
#5 clk_tb = 0;
#5 Din_tb = 8'b00000100;
#5 clk_tb = 1;
#5 Din_tb = 8'b00001000;
#5 clk_tb = 0;
#5 Din_tb = 8'b00100000;
#5 clk_tb = 1;

end

endmodule 

你有几个地方有错误:

在模块 Main Sum_Abs 中,从两个地方驱动。通过重置,它从 M9 模块中出来。你不能那样做。将 HDL 视为硬件:您刚刚将两个输出端口连接在一起,都驱动相同的电线。
做到这一点:

if(rst == 1'b1)
   Data_in_buffer <= 8'b00000000;      

然后你在 Main 中出现拼写错误:

output  [7:0] Sum_Abs;
//                ^Upper case!
adder_8bit M9(Data_in_buffer,Sum_abs);
//                               ^ Lower case

下一个错误是可以理解的,它在这里:

case(Data_in)
8'b1xxxxxxx: Data_in_buffer = ~Data_in + 1'b1;
8'b0xxxxxxx: Data_in_buffer = Data_in;
endcase     

您假设忽略了 LS 7 位。但是 case 语句实际上是在寻找文字值 8'b1xxxxxxx 因此 with x-es.
您可以使用:

casez(Data_in)
8'b1zzzzzzz: Data_in_buffer <= ~Data_in + 1'b1;
8'b0zzzzzzz: Data_in_buffer <= Data_in;
endcase     

但更简单的是看MS位:

if (Data_in[7]=1'b1)
  ....

第四个错误是您在时钟部分使用阻塞分配。如果你注意了,你会发现我在新代码中用 <= 替换了你所有的 =。

第五个错误在您的测试台中:您没有足够快地更改时钟。该代码仅查看上升沿,您可以更改上升沿和下降沿的输入。这不是制作时钟的最佳方法。如果你需要模拟一百万个时钟怎么办?

这就是你制作时钟的方式:

initial
begin
   clk_tb= 1'b0;
   forever
      #50 clk_tb= ~clk_tb; // clock period of 100 time units
end

毕竟有些东西出来了,但我还没有检查是否出现了正确的值。我把它留给你。