昨晚项目调试的时候遇到一个问题:
输入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