Quartus综合有符号数乘加运算的一个问题

昨晚项目调试的时候遇到一个问题:

 

输入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 [31:0] i_power_unsigned;),那么Quartus综合的时候会把前面的$signed(iq_data) * $signed(iq_data)中的iq_data数据当成无符号的来综合,

Synplify综合的结果跟Quartus一样,而用Xilinx-ISE综合就不会出现这样的问题。

i_power_unsigned定义成有符号(reg signed [31:0] 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              [15:0]      iq_data                         ,  

   

       /////////////信号输出////////////////////  

       output     reg   [31:0]      iq_power_out               ,

       output     reg   [31:0]      iq_power_out_error              //错误的计算输出 

       );

      

       /////////////参数定义////////////////////

      

       reg          signed     [31:0]      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          [31:0]      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    

永不止步步 发表于11-05 13:43 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67417个|学分:363741个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号