SynplifyPro综合结果异常,与Icarus Verilog/Verilator仿真不符求助
有符号位宽饱和转换模块的综合异常问题
我实现了一个名为saturate_signed的Verilog模块,用于完成有符号位宽转换并带有饱和功能:输入WIN位有符号数,截断高位得到WOUT位有符号输出;若输入超出输出范围则饱和到最值;若WOUT≥WIN则进行符号扩展。例如WOUT=16时,+37268会被饱和到+32767。
模块代码如下:
/// Given an WIN-bit signed input, truncates the most significant bits to produce a WOUT-bit signed output, /// saturating to the maximum or minimum representable value if the input is out of range. /// If WOUT >= WIN, the value is sign-extended. /// For example, given WOUT=16, +37268 => +32767. module saturate_signed#( parameter WIN = 16, parameter WOUT = 8 )( input wire signed [WIN-1:0] din, output reg signed [WOUT-1:0] dout ); initial if (WOUT < 2) $fatal("Output width is too small"); initial if (WIN < 2) $fatal("Input width is too small"); generate if (WOUT >= WIN) begin : g_extend always @(*) begin dout = {{(WOUT-WIN){din[WIN-1]}}, din}; end end else begin : g_saturate // Output-precision rails. localparam signed [WOUT-1:0] SAT_POS = {1'b0, {(WOUT-1){1'b1}}}; localparam signed [WOUT-1:0] SAT_NEG = {1'b1, {(WOUT-1){1'b0}}}; // Same but extended to input precision for comparison. localparam signed [WIN-1:0] LIM_POS = { {(WIN-(WOUT-1)){1'b0}}, {(WOUT-1){1'b1}} }; localparam signed [WIN-1:0] LIM_NEG = -$signed(LIM_POS) - 1; // Combinational saturation logic. always @(*) begin case ({din > LIM_POS, din < LIM_NEG}) 2'b10: dout = SAT_POS; 2'b01: dout = SAT_NEG; default: dout = din[WOUT-1:0]; endcase end end endgenerate endmodule
当以WIN=16、WOUT=15实例化该模块时:
- Icarus Verilog与Verilator的仿真结果完全正确;
- SynplifyPro综合时却忽略了符号位,导致电路行为明显错误,同时发出警告:
2019991 WARNING - CL247 :"../saturate_signed.v":18:33:18:35|Input port bit 15 of din[15:0] is unused
通过HDL-Analyst查看生成的电路,确认综合结果确实错误。我可以调整代码得到正确电路,但想明确:是否误用了Verilog语言结构?未来如何避免此类问题?我用verible和svlint都没检测出问题。
补充:Yosys的综合结果符合预期,电路包含符号位相关逻辑,能实现正确的饱和功能。
内容的提问来源于stack exchange,提问作者Pavel Kirienko
相关产品推荐
相关产品推荐

