我遇到了Verilog乘法器模块的问题

我遇到了Verilog乘法器模块的问题,verilog,Verilog,给出的图片是我想表达的模块。 出于某种原因,我不得不使用wire从数字数组中调出乘法器。ex)导线[3:0]abc=4'b1111 但是很奇怪!当我将导线abc的特定值指定给“乘数”时,它工作得很好。然而,如果我将其分配给“被乘数”,我会看到与图中一样的红线 知道出了什么问题吗?谢谢 多小区编码 module MulCell(Multiplicand,Multiplier,Sin,Cin,Sout,Cout); input Multiplicand,Multiplier,Sin,Cin; ou

给出的图片是我想表达的模块。

出于某种原因,我不得不使用wire从数字数组中调出乘法器。ex)导线[3:0]abc=4'b1111

但是很奇怪!当我将导线abc的特定值指定给“乘数”时,它工作得很好。然而,如果我将其分配给“被乘数”,我会看到与图中一样的红线

知道出了什么问题吗?谢谢

多小区编码

module MulCell(Multiplicand,Multiplier,Sin,Cin,Sout,Cout);
input Multiplicand,Multiplier,Sin,Cin;
output Sout,Cout;
reg Sout,Cout;
wire tmp;

assign tmp=Multiplicand&Multiplier;
always@(tmp) begin
    {Cout,Sout} <= tmp+Sin+Cin;
end
endmodule 
`timescale 1ns/1ns

module testbench_MulCell();
reg Multiplicand,Multiplier,Sin,Cin;
wire Sout,Cout;

MulCell MC(Multiplicand,Multiplier,Sin,Cin,Sout,Cout);
wire [3:0]abc;
assign abc=4'b1111;

initial begin
    Multiplicand=abc[2];
    Multiplier=1'b1;
    Sin=1'b1;
    Cin=1'b1;
    #10 //expecting 11

    Multiplicand=1'b0;
    Multiplier=abc[1];
    Sin=1'b1;
    Cin=1'b1;
    #10 $stop;//expecting 10
end
endmodule

我可能错了,但似乎在为
abc
赋值和运行
initial
块之间存在竞争条件。当初始块开始运行时,
assignabc=..
尚未执行。这就是为什么在波形视图中会出现
x
/red\u行。

Verilog是一个事件驱动的模拟器。这意味着每个“始终…”、“分配”块都有输入和输出。always块中的输入由其灵敏度列表表示。在您的情况下,这将是
tmp
信号。当且仅当检测到输入的变化时,整个块将开始计算

此外,在模块中,
initial
在模拟过程中被安排执行一次,并且总是在任何always块之前首先执行(系统verilog中的特殊情况除外)。因此,在您的例子中,初始块的前几个语句(在first#10之前)在assign语句之前执行。因此,对于前10个周期,
abc
的值将为'4bxxxx,这解释了您的红线。出于同样的原因,这些值。因此,被乘数的值以及MC/tmp、Sout、Cout的值也将是“x”

在#10更改变量的值,导致MC中的always block使用新值重新计算。到那时,abc已经设置为1111,所有的“x”都消失了

因此,有效地只模拟了第二组值,而模拟了第一组值。 建议是:在初始块前面添加一个小延迟:

initial begin
    #1
    Multiplicand=abc[2];
    Multiplier=1'b1;
    Sin=1'b1;
这将延迟语句的执行,此时将设置“abc”的值。您将有一个短时间(1)的红线,但您将看到您设置的值的结果

另一种可能是首先在初始块中设置abc值,但需要一个reg变量:

reg[3:0] abcSet;
assign abc = abcSet;

initial begin
     abcSet = 4'b1111;
     ...

另一件事,在你的“总是阻塞”中,你使用了非阻塞分配(你是正确的。有一场比赛。非常感谢你的精彩解释。我应该把它打印出来。
{Cout,Sout} = tmp+Sin+Cin;
always @(tmp, Sin, Cin)
always @(posedge clk)
    {Cout,Sout} <= tmp+Sin+Cin;