212 lines
5.6 KiB
Verilog
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
|