tag 标签: 有符号数相乘相加

相关博文
  • 热度 22
    2012-12-7 10:57
    5063 次阅读|
    1 个评论
      昨晚项目调试的时候遇到一个问题:   输入 IQ 交织、 有符号 的复信号,时序是: iq_data            : I Q I Q I Q I Q iq_data_fsync : 1 0 1 0 1 0 1 0 模块的功能是实现复信号的功率计算 Power =I*I + Q*Q ;   出现问题的语句是: iq_power_out_error = $signed(iq_data) * $signed(iq_data) + i_power_unsigned; 如果i_power_unsigned定义的是无符号的(reg i_power_unsigned;),那么Quartus综合的时候会把前面的$signed(iq_data) * $signed(iq_data)中的iq_data数据当成无符号的来综合, Synplify综合的结果跟Quartus一样,而用Xilinx-ISE综合就不会出现这样的问题。 i_power_unsigned定义成有符号(reg signed i_power;)的时候,都能得到正确的结果。   下面是验证程序(本文最后)Quartus综合的RTL和ISE综合的RTL对比:Quartus综合的RTL用了两个乘法器,一个是有符号相乘一个是无符号相乘,而ISE综合的RTL只有一个有符号乘法器。   Quartus-RTL   ISE-RTL   验证程序如下: module     iq_power_cal        (        ///////////// 时钟和复位 /////////////////        input                             clk_61_44m                   ,                      /////////////IQ 输入 //////////////////////             input                             iq_data_fsync                   ,              input                     iq_data                          ,               ///////////// 信号输出 ////////////////////           output      reg          iq_power_out                 ,        output      reg          iq_power_out_error               // 错误的计算输出          );               ///////////// 参数定义 ////////////////////               reg           signed            i_power    ;    //定义成有符号的能得到正确的结果          always @(posedge clk_61_44m)           begin               if(iq_data_fsync == 1'b0)                      i_power = $signed(iq_data) * $signed(iq_data);               else;        end               always @(posedge clk_61_44m)           begin               if(iq_data_fsync == 1'b1)                      iq_power_out = $signed(iq_data) * $signed(iq_data) + i_power;               else;        end                        reg                 i_power_unsigned   ;    //定义成无符号的,不能得到正确的结果,会导致计算        //$signed(iq_data) * $signed(iq_data) + i_power_unsigned;的时候把iq_data当成无符号的来计算               always @(posedge clk_61_44m)           begin               if(iq_data_fsync == 1'b0)                      i_power_unsigned = $signed(iq_data) * $signed(iq_data);               else;        end               always @(posedge clk_61_44m)           begin               if(iq_data_fsync == 1'b1)                      iq_power_out_error = $signed(iq_data) * $signed(iq_data) + i_power_unsigned;               else;        end            endmodule