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,它负责处理指数。或者你应该检查你的算法。
我试图在 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,它负责处理指数。或者你应该检查你的算法。