fpga混频后误差大

混频器仿真问题

img

写了一个正弦函数与余弦函数混频的模块,正余弦函数由同一个DDS模块产生。根据sinαcosα=1/2 sinα,应得到1/2 sinα的混频信号,但混频后仿真信号出现了如上图较大的误差,RTL图以及相关代码如下,麻烦大家帮忙看一下是哪里出了问题。

img

顶层模块代码

module DDS(
    input   wire                 clk,
        output  wire                 clk_1,                                
    input   wire                 rst_n,    
    output  wire   [13:0]        wave_sin,
        output  wire   [13:0]        wave_cos,
        output  wire  signed[19:0]   mult_out
);

    wire[9:0]  addr_out_sin;
    wire[9:0]  addr_out_cos;
    wire  signed[11:0]   signal_sin;
    wire  signed[11:0]   signal_cos;
 
 
//相位累加器模块例化 
 DDS1_addr   DDS1_addr(
    .clk(clk),//时钟
   .clk_1(clk_1),
    .rst_n(rst_n),
    .addr_out_sin(addr_out_sin),
    .addr_out_cos(addr_out_cos)
 );
 
 
    
 //正弦信号ROM IP核例化
rom     rom_sin_inst (
    .address ( addr_out_sin ),
    .clock (clk_1 ),
    .q ( wave_sin )
    );
   
 //余弦信号ROM IP核例化   
rom     rom_cos_inst (
    .address ( addr_out_cos ),
    .clock (clk_1 ),
    .q ( wave_cos )
    );  

 mixed   mixed_sin_cos(
    .clk       (clk)       ,
    .clk_1     (clk_1)     ,
    .rst_n     (rst_n)     ,
    .wave_sin  (wave_sin ) ,
    .wave_cos  (wave_cos)  ,
    .signal_sin( signal_sin),
    .signal_cos( signal_cos),
    .signal_1  (mult_out)
 
 );    

乘法器模块代码

module mult(

    input                                    clk_1,
    input                                    rst_n,
    input                    [13: 0]                             wave_sin, wave_cos,
     input            signed  [13: 0]                     data_in,   
    output        reg    signed     [19: 0]         signal_1,
    output        reg    signed     [19: 0]         signal_2

    );


    wire            signed     [13: 0]        signal_sin;
    wire            signed     [13: 0]        signal_cos;
    initial signal_1        =    0;
    initial signal_2        =    0;
    
    
    assign signal_sin = wave_sin-12'd511;
    assign signal_cos = wave_cos-12'd511 ;    
    always @(posedge clk_1 or negedge rst_n) 
        if (!rst_n) 
            begin
            signal_1        <=    20'd0;
             signal_2        <=    20'd0;
            end
        else 
            begin
            signal_1        <= data_in*signal_sin;
            signal_2        <= data_in*signal_cos;
            end
    
    
endmodule