Files
MM7020/hdl/DDS_compensate.v

212 lines
5.6 KiB
Verilog

`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// 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