If statement 否则,请锁定SystemVerilog

If statement 否则,请锁定SystemVerilog,if-statement,verilog,If Statement,Verilog,我试图在SystemVerilog中制作一个浮点加法器。当我看到生成的示意图时,我注意到有一个闩锁。代码是: module ADDER ( input ieee_effloat In1_ADD, In2_ADD, input ieee_float A_ADD, output ieee_float Out_ADD ); logic [24:0] MantissaSum;

我试图在SystemVerilog中制作一个浮点加法器。当我看到生成的示意图时,我注意到有一个闩锁。代码是:

module ADDER (
    input   ieee_effloat  In1_ADD, In2_ADD,
    input   ieee_float    A_ADD,

    output  ieee_float    Out_ADD
    );

    logic [24:0] MantissaSum;                               //Can generate an overflow, expand at 25 bit

    always_comb
        begin
            MantissaSum = In1_ADD.Eff_Mantissa + In2_ADD.Eff_Mantissa;  //Sum the mantissas
            
            if(MantissaSum[24] == 1'b1)                        //If overflow
                begin
                    MantissaSum >>= 1;                      //Shift the mantissa of 1
                    Out_ADD.Exponent = A_ADD.Exponent + 1;  //<== Here is the latch (?)
                    Out_ADD.Mantissa = MantissaSum [22:0];  //Select the first 23 bit 
                end
            else
                begin
                    Out_ADD.Mantissa = MantissaSum [22:0];   //Select the first 23 bit
                end
        end

    assign Out_ADD = '{1'b0, Out_ADD.Exponent, Out_ADD.Mantissa};
    
endmodule

我不知道为什么会发生这种情况,我甚至用else关闭了if…

我相信问题在于行
Out\u ADD.Mantissa=MantissaSum[22:0]因为在执行此语句的true和false条件下,我认为代码的合成版本将使用enable=
推断闩锁!尾数[24]
(不是100%确定),我认为下面的更改将保持相同的逻辑并移除闩锁。。只需删除行
Out\u ADD.Mantissa=MantissaSum[22:0]根据真和假条件,而不是在
始终_comb
块之外,键入以下
分配_ADD.尾数=尾数[22:0]
,告诉我这是否解决了你的问题,我相信问题出在这行
Out\u ADD.Mantissa=MantissaSum[22:0]因为在执行此语句的true和false条件下,我认为代码的合成版本将使用enable=
推断闩锁!尾数[24]
(不是100%确定),我认为下面的更改将保持相同的逻辑并移除闩锁。。只需删除行
Out\u ADD.Mantissa=MantissaSum[22:0]根据真和假条件,而不是在
始终_comb
块之外,键入以下
分配_ADD.尾数=尾数[22:0],告诉我这是否解决了您的问题

在verilog中创建锁存器的方式是当您没有在always块的所有分支中分配所有输出时。在你的情况下:

    always_comb
        begin
尾数
创建默认值。这样,它总是被分配的

            MantissaSum = In1_ADD.Eff_Mantissa + In2_ADD.Eff_Mantissa;  
现在,当您在一个分支中移动它,而在另一个分支中不执行任何操作时,前面的语句将处理它

            if(MantissaSum[24] == 1'b1)                        //If overflow
                begin
                    MantissaSum >>= 1;                      //Shift the mantissa of 1
然而,这里是你的问题。您的
Out\u ADD.Exponent
仅在
if
语句的真分支中赋值。如果ManticcaSum[24]不是1,则其值应与之前相同。这是一种闩锁行为

                    Out_ADD.Exponent = A_ADD.Exponent + 1;  //<== Here is the latch (?)

如果这是您想要的,您应该将这个始终块分成两部分:一部分使用always_梳,另一部分使用always_闩锁,用于处理指数。或者,您应该检查您的算法。

在verilog中创建锁存器的方式是,您不在always块的所有分支中分配所有输出。在你的情况下:

    always_comb
        begin
尾数
创建默认值。这样,它总是被分配的

            MantissaSum = In1_ADD.Eff_Mantissa + In2_ADD.Eff_Mantissa;  
现在,当您在一个分支中移动它,而在另一个分支中不执行任何操作时,前面的语句将处理它

            if(MantissaSum[24] == 1'b1)                        //If overflow
                begin
                    MantissaSum >>= 1;                      //Shift the mantissa of 1
然而,这里是你的问题。您的
Out\u ADD.Exponent
仅在
if
语句的真分支中赋值。如果ManticcaSum[24]不是1,则其值应与之前相同。这是一种闩锁行为

                    Out_ADD.Exponent = A_ADD.Exponent + 1;  //<== Here is the latch (?)

如果这是您想要的,您应该将这个始终块分成两部分:一部分使用always_梳,另一部分使用always_闩锁,用于处理指数。或者您应该检查您的算法。

是!现在成功了,非常感谢。但我不明白什么时候我必须使用assign,什么时候我总是喋喋不休地欢迎你,我的朋友,从本质上说,它们是可以互换的,当我们需要建模一些复杂的组合逻辑时,我们通常使用
always\u comb
,但当它很简单时,我们使用
assign
语句,您可以更改我刚才用
always\u comb Out\u ADD.尾数=尾数[22:0]告诉您的
assign
语句这应该给你同样的行为!现在成功了,非常感谢。但我不明白什么时候我必须使用assign,什么时候我总是喋喋不休地欢迎你,我的朋友,从本质上说,它们是可以互换的,当我们需要建模一些复杂的组合逻辑时,我们通常使用
always\u comb
,但当它很简单时,我们使用
assign
语句,您可以更改我刚才用
always\u comb Out\u ADD.尾数=尾数[22:0]告诉您的
assign
语句这应该给你同样的行为