if-else 锁存器 SystemVerilog

if-else latch SystemVerilog

我试图在 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

定义的类型:

`ifndef FPU_MACROFLAG
    `define FPU_MACROFLAG

    package FPU_DEFINITION;

        typedef struct packed {
            logic               Sign;
            logic        [7:0]  Exponent;
            logic        [22:0] Mantissa;
        } ieee_float;               //IEEE-753 floating point number rapresentation

        typedef struct packed {
            logic               Eff_Sign;
            logic        [7:0]  Eff_Exponent;
            logic        [23:0] Eff_Mantissa;
        } ieee_effloat;             //IEEE-753 floating point number rapresentation effective mantissa

    endpackage
    
    import FPU_DEFINITION::*;

`endif

我不知道为什么会这样,我什至用 else 关闭了 if...

我认为问题出在 Out_ADD.Mantissa = MantissaSum [22:0]; 行,因为在执行此语句的真假条件下,我认为您的代码的综合版本将推断出一个带有 enable = [=11 的锁存器=](不是 100% 确定),我认为以下更改将保持相同的逻辑并删除闩锁.. 只需从 true 和 false 条件中删除行 Out_ADD.Mantissa = MantissaSum [22:0]; 而不是 always_comb 块输入以下内容 assign Out_ADD.Mantissa = MantissaSum [22:0];,告诉我这是否解决了您的问题

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

    always_comb
        begin

您为 MantissaSum 创建了一个默认值。这样它总是被分配。

            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_ADD.Exponent 仅在 if 语句的 true 分支中分配。如果 ManticcaSum[24] 不是 1,那么它的值应该和以前一样。这是闩锁行为。

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

其他的就ok了。 Out_ADD.Mantissa 在所有分支中分配。

                    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

如果这是你想要的,你应该将这个总是块分成两部分:一个用 always_comb,第二个用 always_latch,它负责处理指数。或者你应该检查你的算法。