`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2019/08/03 14:12:18 // Design Name: // Module Name: DDS_compensate // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module DDS_compensate( clk, rst, din_nd, // 输入数据 din_i, din_q, acq_nd, // 捕获信息 dfreq_word_nd, // 频偏NCO信息 dfreq_word, framesync_success, // 帧同步标志,用于切码 // rs_idx_nd, //数据段信息速率,在帧同步标志后、勤务段最后一个数据前给出,!但并不表示从rs_idx_nd有效起输入就是数据段的数据了 // rs_idx, demod_trunc_i, demod_trunc_q, demod_trunc_nd, Demod_ovrflw ); input clk; input rst; input din_nd; input [11:0] din_i,din_q; input acq_nd; input dfreq_word_nd; input [13:0] dfreq_word; //-- 解调频偏 input framesync_success; //-- 8个可变数据速率,从0~7分别代表30k~3840k wire rs_idx_nd =1'b0; wire [2:0] rs_idx; assign rs_idx =3'b000; output [11:0] demod_trunc_i,demod_trunc_q; output demod_trunc_nd ; output Demod_ovrflw; wire [4:0] acq_freindex; //-- 捕获频偏 assign acq_freindex =5'd0; //----------------------------- DDS For FreqShift -------------------------------- //-- 注意这里DDS产生的是偏移频率,下面补偿的时候要与DDS输出的【共轭】相复乘 localparam DDS_width = 24; //25bits in fact reg dds_rst = 0; // DDS starts after acquisition reg [DDS_width:0] dds_start_freq = 0; reg dds_update = 0; // identifier of updated deltafrequency & its rate reg [DDS_width:0] dds_update_df = 0; reg [DDS_width:0] dds_phase = 0; reg [DDS_width:0] dds_freq = 0; // 相位累积量,残余频偏和变化率控制 /*wire [13:0] freq_abs; reg freq_plus; assign freq_abs=(dfreq_word[13]==1'd1)? -dfreq_word:dfreq_word; always @ (posedge clk) begin if(rst) begin freq_plus <= 1'b0; end else begin if(dfreq_word_nd) begin freq_plus <= dfreq_word[13]; end else begin freq_plus <= freq_plus; end end end */ always @(posedge clk) if (rst || acq_nd) dds_rst <= 1; else dds_rst <= 0; always @(posedge clk) if (!rst && acq_nd) dds_start_freq <= {{8{acq_freindex[4]}},acq_freindex[4:0],{(DDS_width-12){1'b0}}}; else dds_start_freq <= dds_start_freq; always @(posedge clk) if (!rst && dfreq_word_nd) begin dds_update <= 1; dds_update_df <= {{(DDS_width-13){dfreq_word[13]}},dfreq_word[13:0]}; end else dds_update <= 0; always @(posedge clk) if (rst || dds_rst) dds_phase <= 0; else if (din_nd) dds_phase <= dds_phase + dds_freq; else dds_phase <= dds_phase; wire [DDS_width:0] updata_s; AdderSigned_25_25_2dly DDS_DFreq_Update1 ( //.A(dds_freq), // input wire [24 : 0] A .A(25'd0), .B(dds_update_df), // input wire [24 : 0] B .CLK(clk), // input wire CLK .S(updata_s) // output wire [24 : 0] S ); //--- delay --- reg dds_update_d1 = 0,dds_update_d2 = 0; reg din_nd_d1 = 0,din_nd_d2 = 0; always @(posedge clk) if (rst) begin dds_update_d1 <= 0; dds_update_d2 <= 0; din_nd_d1 <= 0; din_nd_d2 <= 0; end else begin dds_update_d1 <= dds_update; dds_update_d2 <= dds_update_d1; din_nd_d1 <= din_nd; din_nd_d2 <= din_nd_d1; end always @(posedge clk) if (rst) dds_freq <= 0; else if (dds_rst) dds_freq <= dds_start_freq; else if (dds_update_d2) dds_freq <= updata_s; else dds_freq <= dds_freq; reg [12:0] cos_addr = 0,sin_addr = -13'd2048; wire [11:0] cos_dout,sin_dout; always @(posedge clk) if (rst) begin cos_addr <= 0; sin_addr <= -13'd2048; end else begin cos_addr <= dds_phase[DDS_width:DDS_width-12]; sin_addr <= dds_phase[DDS_width:DDS_width-12] - 13'd2048; end COSLUT_8192 DDS_12bit_8192 ( .clka(clk), // input wire clka .addra(cos_addr), // input wire [12 : 0] addra .douta(cos_dout), // output wire [11 : 0] douta .clkb(clk), // input wire clkb .addrb(sin_addr), // input wire [12 : 0] addrb .doutb(sin_dout) // output wire [11 : 0] doutb ); //------------------------------- Compensate ------------------------------ wire [24:0] demod_i,demod_q; wire [13:0] DemodMult_pad; //wire [11:0] demod_trunc_i,demod_trunc_q; wire demod_nd; //排除第一个,这两个信号和din_nd是同步的 //wire demod_trunc_nd; wire Demod_ovrflw_i,Demod_ovrflw_q; //wire Demod_ovrflw ; assign Demod_ovrflw = Demod_ovrflw_i || Demod_ovrflw_q; /*wire [11:0] sin_din; wire [11:0] cos_din; assign sin_din=(freq_plus==1'd1)? sin_dout:-sin_dout; assign cos_din = cos_dout;*/ ComplexMult12x12_4dly MultFreq ( .aclk(clk), // input wire aclk .s_axis_a_tvalid(din_nd), // input wire s_axis_a_tvalid .s_axis_a_tdata({4'd0,din_q,4'd0,din_i}), // input wire [31 : 0] s_axis_a_tdata .s_axis_b_tvalid(din_nd), // input wire s_axis_b_tvalid .s_axis_b_tdata({4'd0,-sin_dout,4'd0,cos_dout}), // input wire [15 : 0] s_axis_b_tdata .m_axis_dout_tvalid(demod_nd), // output wire m_axis_dout_tvalid .m_axis_dout_tdata({DemodMult_pad[13:7],demod_q,DemodMult_pad[6:0],demod_i}) // output wire [47 : 0] m_axis_dout_tdata ); trunc_25to12_2dly Trunc_demod_i ( .clk(clk), .din_nd(demod_nd), .din(demod_i), .ctrl(), .dout_nd(demod_trunc_nd), .dout(demod_trunc_i), .ovrflw(Demod_ovrflw_i) ); trunc_25to12_2dly Trunc_demod_q ( .clk(clk), .din_nd(demod_nd), .din(demod_q), .ctrl(), .dout_nd(), .dout(demod_trunc_q), .ovrflw(Demod_ovrflw_q) ); endmodule