From e33875ef8f6cd0c86bf1e8391b75ebaa7055fd81 Mon Sep 17 00:00:00 2001 From: ZoroGH Date: Fri, 19 Jul 2024 21:31:49 +0800 Subject: [PATCH] Add the recv hdl file --- hdl/ApproxAbs_18bit.v | 133 +++++ hdl/ApproxAbs_v2.v | 125 ++++ hdl/Chn_Estimate.v | 1192 +++++++++++++++++++++++++++++++++++++++ hdl/DAGC_v2.v | 552 ++++++++++++++++++ hdl/DDS_compensate.v | 211 +++++++ hdl/IQmerge.v | 149 +++++ hdl/Interp_half.v | 71 +++ hdl/Interp_quarter.v | 69 +++ hdl/Interpolation.v | 100 ++++ hdl/Noise_Estimate.v | 187 ++++++ hdl/RecvTop.v | 550 ++++++++++++++++++ hdl/SC_FDE_TOP.v | 684 ++++++++++++++++++++++ hdl/TSync_Abs_new16.v | 889 +++++++++++++++++++++++++++++ hdl/TSync_Abs_new4.v | 472 ++++++++++++++++ hdl/TimeSync_top.v | 196 +++++++ hdl/data_equalizer.v | 624 ++++++++++++++++++++ hdl/data_ow.v | 542 ++++++++++++++++++ hdl/freqestm.v | 643 +++++++++++++++++++++ hdl/phase_adjust.v | 261 +++++++++ hdl/trunc_25to12_2dly.v | 75 +++ 20 files changed, 7725 insertions(+) create mode 100644 hdl/ApproxAbs_18bit.v create mode 100644 hdl/ApproxAbs_v2.v create mode 100644 hdl/Chn_Estimate.v create mode 100644 hdl/DAGC_v2.v create mode 100644 hdl/DDS_compensate.v create mode 100644 hdl/IQmerge.v create mode 100644 hdl/Interp_half.v create mode 100644 hdl/Interp_quarter.v create mode 100644 hdl/Interpolation.v create mode 100644 hdl/Noise_Estimate.v create mode 100644 hdl/RecvTop.v create mode 100644 hdl/SC_FDE_TOP.v create mode 100644 hdl/TSync_Abs_new16.v create mode 100644 hdl/TSync_Abs_new4.v create mode 100644 hdl/TimeSync_top.v create mode 100644 hdl/data_equalizer.v create mode 100644 hdl/data_ow.v create mode 100644 hdl/freqestm.v create mode 100644 hdl/phase_adjust.v create mode 100644 hdl/trunc_25to12_2dly.v diff --git a/hdl/ApproxAbs_18bit.v b/hdl/ApproxAbs_18bit.v new file mode 100644 index 0000000..f0b975f --- /dev/null +++ b/hdl/ApproxAbs_18bit.v @@ -0,0 +1,133 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/14 18:02:13 +// Design Name: +// Module Name: ApproxAbs_12bit +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module ApproxAbs_18bit( + input clk, + input ND, + input [17:0] Din_I, + input [17:0] Din_Q, + + output reg [18:0] Dout, + output reg Rdy + ); + + + + // 第一级延迟:把输入变负值: + reg [17:0] Din_I_neg; + always @ (posedge clk) begin + if (Din_I[17:0]==18'b10_0000_0000_0000_0000) + Din_I_neg[17:0] <= 18'b01_1111_1111_1111_1111; + else + Din_I_neg[17:0] <= -Din_I[17:0]; + end + + reg [17:0] Din_Q_neg; + always @ (posedge clk) begin + if (Din_Q[17:0]==18'b10_0000_0000_0000_0000) + Din_Q_neg[17:0] <= 18'b01_1111_1111_1111_1111; + else + Din_Q_neg[17:0] <= -Din_Q[17:0]; + end + + + // 第二级延迟:求绝对值: + reg [17:0] Din_I_D1; + reg [17:0] Din_Q_D1; + always @ (posedge clk) begin + Din_I_D1[17:0] <= Din_I[17:0]; + Din_Q_D1[17:0] <= Din_Q[17:0]; + end + + reg [17:0] Abs_Din_I; + reg [17:0] Abs_Din_Q; + always @ (posedge clk) begin + if(Din_I_D1[17]==1'b1) + Abs_Din_I[17:0] <= Din_I_neg[17:0]; + else + Abs_Din_I[17:0] <= Din_I_D1[17:0]; + if(Din_Q_D1[17]==1'b1) + Abs_Din_Q[17:0] <= Din_Q_neg[17:0]; + else + Abs_Din_Q[17:0] <= Din_Q_D1[17:0]; + end + + + // 第三级延迟:确定I/Q两路绝对值的大小关系: + reg [17:0] AbsIQ_max; + reg [17:0] AbsIQ_min; + always @ (posedge clk) begin + if (Abs_Din_I[17:0]>=Abs_Din_Q[17:0]) begin + AbsIQ_max[17:0] <= Abs_Din_I[17:0]; + AbsIQ_min[17:0] <= Abs_Din_Q[17:0]; + end + else begin + AbsIQ_max[17:0] <= Abs_Din_Q[17:0]; + AbsIQ_min[17:0] <= Abs_Din_I[17:0]; + end + end + + // 第四级延迟:MXQ选择的系数:7/8和1/2: + reg [17:0] AbsIQ_max_7by8; + reg [17:0] AbsIQ_min_1by2; + always @ (posedge clk) begin + AbsIQ_max_7by8[17:0] <= AbsIQ_max[17:0]-{3'b000,AbsIQ_max[17:3]}; + AbsIQ_min_1by2[17:0] <= {AbsIQ_min[17],AbsIQ_min[17:1]}; + end + + // 第五级延迟:1bit位扩展求和: + // (MXQ)中间将最大延迟一个clk赋给 Dout_Temp2,使 Dout_Temp2与 Dout_Temp在同一个clk下进行比较。 + reg [18:0] Dout_Temp; + reg [18:0] Dout_Temp1; + reg [18:0] Dout_Temp2; + always @ (posedge clk) begin + Dout_Temp[18:0] <= {1'b0,AbsIQ_max_7by8[17:0]} + {1'b0,AbsIQ_min_1by2[17:0]}; + Dout_Temp1[18:0] <= {1'b0,AbsIQ_max[17:0]}; + Dout_Temp2[18:0] <= Dout_Temp1[18:0]; + end + + // (MXQ)第六级延迟:输出求和值与I/Q两路绝对值最大值比较之后的最大值: + + always @ (posedge clk) begin + if(Dout_Temp[18:0]>=Dout_Temp2[17:0]) + Dout[18:0] <= Dout_Temp[18:0]; + else + Dout[18:0] <= Dout_Temp2[18:0]; + end + + // 产生Rdy,与ND有六级延迟: + reg Rdy_b5 = 1'b0; + reg Rdy_b4 = 1'b0; + reg Rdy_b3 = 1'b0; + reg Rdy_b2 = 1'b0; + reg Rdy_b1 = 1'b0; + + always@(posedge clk) begin//(MXQ)必须加 posedge clk ,否则仿真有问题,内存溢出 + Rdy_b5 <= ND; + Rdy_b4 <= Rdy_b5; + Rdy_b3 <= Rdy_b4; + Rdy_b2 <= Rdy_b3; + Rdy_b1 <= Rdy_b2; + Rdy <= Rdy_b1; + end + +endmodule diff --git a/hdl/ApproxAbs_v2.v b/hdl/ApproxAbs_v2.v new file mode 100644 index 0000000..9a85724 --- /dev/null +++ b/hdl/ApproxAbs_v2.v @@ -0,0 +1,125 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 18:12 11/14/2019 +// Design Name: +// Module Name: ApproxAbs_v1 +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// 1. 在ApproxAbs基础上,由MXQ仿真、修改得到。 +// 2. 主要修改有两处:A.如果Max比(7/8*max+1/2*min)更大,就输出max。这样更准确。 +// B.原版在生成Dout_valid的逻辑中,犯了always后面没有“@ (posedge clk)”的错误。 +// Dependencies: +// +// Revision: +// v2(2015/11/07): +// 1. 更改输入为17bits,输出为18bits。 +// 2. 取消Din_valid和Dout_valid。改为ND和Rdy。 +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module ApproxAbs_v2 ( + input clk, + input ND, + input [9:0] Din_I, + input [9:0] Din_Q, + output reg [10:0] Dout = 11'd0, + output reg Rdy = 1'b0 +); + + + + // 第一级延迟:把输入变负值: + reg [9:0] Din_I_neg; + always @(posedge clk) begin + if (Din_I[9:0] == 10'b1000_0000_00) Din_I_neg[9:0] <= 10'b0111_1111_11; + else Din_I_neg[9:0] <= -Din_I[9:0]; + end + + reg [9:0] Din_Q_neg; + always @(posedge clk) begin + if (Din_Q[9:0] == 10'b1000_0000_00) Din_Q_neg[9:0] <= 10'b0111_1111_11; + else Din_Q_neg[9:0] <= -Din_Q[9:0]; + end + + + // 第二级延迟:求绝对值: + reg [9:0] Din_I_D1; + reg [9:0] Din_Q_D1; + always @(posedge clk) begin + Din_I_D1[9:0] <= Din_I[9:0]; + Din_Q_D1[9:0] <= Din_Q[9:0]; + end + + reg [9:0] Abs_Din_I; + reg [9:0] Abs_Din_Q; + always @(posedge clk) begin + if (Din_I_D1[9] == 1'b1) Abs_Din_I[9:0] <= Din_I_neg[9:0]; + else Abs_Din_I[9:0] <= Din_I_D1[9:0]; + if (Din_Q_D1[9] == 1'b1) Abs_Din_Q[9:0] <= Din_Q_neg[9:0]; + else Abs_Din_Q[9:0] <= Din_Q_D1[9:0]; + end + + + // 第三级延迟:确定I/Q两路绝对值的大小关系: + reg [9:0] AbsIQ_max; + reg [9:0] AbsIQ_min; + always @(posedge clk) begin + if (Abs_Din_I[9:0] >= Abs_Din_Q[9:0]) begin + AbsIQ_max[9:0] <= Abs_Din_I[9:0]; + AbsIQ_min[9:0] <= Abs_Din_Q[9:0]; + end + else begin + AbsIQ_max[9:0] <= Abs_Din_Q[9:0]; + AbsIQ_min[9:0] <= Abs_Din_I[9:0]; + end + end + + // 第四级延迟:MXQ选择的系数:7/8和1/2: + reg [9:0] AbsIQ_max_7by8; + reg [9:0] AbsIQ_min_1by2; + always @(posedge clk) begin + AbsIQ_max_7by8[9:0] <= AbsIQ_max[9:0] - {3'b000, AbsIQ_max[9:3]}; + AbsIQ_min_1by2[9:0] <= {AbsIQ_min[9], AbsIQ_min[9:1]}; + end + + // 第五级延迟:1bit位扩展求和: + // (MXQ)中间将最大延迟一个clk赋给 Dout_Temp2,使 Dout_Temp2与 Dout_Temp在同一个clk下进行比较。 + reg [10:0] Dout_Temp; + reg [10:0] Dout_Temp1; + reg [10:0] Dout_Temp2; + always @(posedge clk) begin + Dout_Temp[10:0] <= {1'b0, AbsIQ_max_7by8[9:0]} + {1'b0, AbsIQ_min_1by2[9:0]}; + Dout_Temp1[10:0] <= {1'b0, AbsIQ_max[9:0]}; + Dout_Temp2[10:0] <= Dout_Temp1[10:0]; + end + + // (MXQ)第六级延迟:输出求和值与I/Q两路绝对值最大值比较之后的最大值: + + always @(posedge clk) begin + if (Dout_Temp[10:0] >= Dout_Temp2[9:0]) Dout[10:0] <= Dout_Temp[10:0]; + else Dout[10:0] <= Dout_Temp2[10:0]; + end + + // 产生Rdy,与ND有六级延迟: + reg Rdy_b5 = 1'b0; + reg Rdy_b4 = 1'b0; + reg Rdy_b3 = 1'b0; + reg Rdy_b2 = 1'b0; + reg Rdy_b1 = 1'b0; + + always @(posedge clk) begin //(MXQ)必须加 posedge clk ,否则仿真有问题,内存溢出 + Rdy_b5 <= ND; + Rdy_b4 <= Rdy_b5; + Rdy_b3 <= Rdy_b4; + Rdy_b2 <= Rdy_b3; + Rdy_b1 <= Rdy_b2; + Rdy <= Rdy_b1; + end + +endmodule diff --git a/hdl/Chn_Estimate.v b/hdl/Chn_Estimate.v new file mode 100644 index 0000000..1565453 --- /dev/null +++ b/hdl/Chn_Estimate.v @@ -0,0 +1,1192 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/12/25 14:19:40 +// Design Name: +// Module Name: Chn_Estimate +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module Chn_Estimate( + input clk, + input rst, + + //零域估计,默认值为8'd29 + input [7:0] Zerozone_vio, + + //增强导频序列 + input nd_pilot2, + input [9:0] pilot_datai, + input [9:0] pilot_dataq, + + //噪声估计结果 + input nd_EstNoise, + input [27:0] EstNoise_i, + input [27:0] EstNoise_q, + + //fft核 + input [25:0] fft_out_i, + input [25:0] fft_out_q, + input fft_out_nd, + input [7:0] fft_index, + output reg [16:0] fft_in_i = 17'd0, + output reg [16:0] fft_in_q = 17'd0, + output reg fft_in_nd = 1'd0, + + //ifft核 + input [28:0] ifft_out_i, + input [28:0] ifft_out_q, + input ifft_out_nd, + input [7:0] ifft_index, + output reg [19:0] ifft_in_i = 20'd0, + output reg [19:0] ifft_in_q = 20'd0, + output reg ifft_in_nd = 1'd0, + + //信道估计两次fft输入完毕后拉高1clk + output reg flag_ChnEstFFT_done = 1'd0, + + //MMSE信道估计结果RAM + output reg write_MMSE_wea = 1'd0, + output reg [7:0] addrin_MMSE = 8'd0, + output reg [21:0] din_MMSE = 22'd0, + + //debug,溢出标志 + output reg flagoverflow_fftpilot_26to14 = 1'd0, //第1个fft结果截位,即导频fft结果的截位,26截到14 + output reg flagoverflow_ChnZF_26to18 = 1'd0, //第2个fft结果截位,即ZF信道估计结果的截位,26截到18 + output reg flagoverflow_comdiv_34to20i = 1'd0, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到20 + output reg flagoverflow_comdiv_34to20q = 1'd0, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到20 + output reg flagoverflow_ifftzero_29to17i = 1'd0, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output reg flagoverflow_ifftzero_29to17q = 1'd0, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output reg flagoverflow_MMSEdiv_divisor_31to28 = 1'd0, //第2个除法器,即MMSE除法的分母截位,31截到28 + output reg flagoverflow_divmmse_34to11 = 1'd0 //第2个除法器结果截位,即MMSE信道估计结果的截位,34截到11 + ); + + + + +//------------------------------------------------导频fft信息ROM--------------------------------------------// +reg [7:0] addr_fft_piloti = 8'd0; +wire[7:0] dout_fft_piloti; +fft_pilot_real fft_pilot_real ( + .clka(clk), // input wire clka + .addra(addr_fft_piloti), // input wire [7 : 0] addra + .douta(dout_fft_piloti) // output wire [7 : 0] douta + ); + +reg [7:0] addr_fft_pilotq = 8'd0; +wire[7:0] dout_fft_pilotq; +fft_pilot_imag fft_pilot_imag ( + .clka(clk), // input wire clka + .addra(addr_fft_pilotq), // input wire [7 : 0] addra + .douta(dout_fft_pilotq) // output wire [7 : 0] douta + ); + +reg [7:0] addr_abs_pilot2 = 8'd0; +wire[14:0] dout_abs_pilot2; +abs_pilot2 abs_pilot2 ( + .clka(clk), // input wire clka + .addra(addr_abs_pilot2), // input wire [7 : 0] addra + .douta(dout_abs_pilot2) // output wire [14 : 0] douta + ); + + + + +//------------------------------------------------复数除法器,分子计算,乘法部分延时1clk--------------------------------------------// +reg [13:0] comdiv_ac_a = 14'd0; +reg [7:0] comdiv_ac_c = 8'd0; +wire[21:0] comdiv_ac_out; +MUL_FDE ChnEst_comdiv_ac ( + .CLK(clk), // input wire CLK + .A(comdiv_ac_a), // input wire [13 : 0] A + .B(comdiv_ac_c), // input wire [7 : 0] B + .P(comdiv_ac_out) // output wire [21 : 0] P + ); + +reg [13:0] comdiv_bd_b = 14'd0; +reg [7:0] comdiv_bd_d = 8'd0; +wire[21:0] comdiv_bd_out; +MUL_FDE ChnEst_comdiv_bd ( + .CLK(clk), // input wire CLK + .A(comdiv_bd_b), // input wire [13 : 0] A + .B(comdiv_bd_d), // input wire [7 : 0] B + .P(comdiv_bd_out) // output wire [21 : 0] P + ); + +reg [13:0] comdiv_bc_b = 14'd0; +reg [7:0] comdiv_bc_c = 8'd0; +wire[21:0] comdiv_bc_out; +MUL_FDE ChnEst_comdiv_bc ( + .CLK(clk), // input wire CLK + .A(comdiv_bc_b), // input wire [13 : 0] A + .B(comdiv_bc_c), // input wire [7 : 0] B + .P(comdiv_bc_out) // output wire [21 : 0] P + ); + +reg [13:0] comdiv_ad_a = 14'd0; +reg [7:0] comdiv_ad_d = 8'd0; +wire[21:0] comdiv_ad_out; +MUL_FDE ChnEst_comdiv_ad ( + .CLK(clk), // input wire CLK + .A(comdiv_ad_a), // input wire [13 : 0] A + .B(comdiv_ad_d), // input wire [7 : 0] B + .P(comdiv_ad_out) // output wire [21 : 0] P + ); + + +reg [0:0] nd_comdiv_mulin = 1'd0; +reg [0:0] nd_comdiv_mulout = 1'd0; +always @(posedge clk) +begin + if(rst) + begin + nd_comdiv_mulout <= 1'd0; + end + else + begin + nd_comdiv_mulout <= nd_comdiv_mulin; + end +end + + + + +//---------------------------------------------复数除法器,分子计算,加法+量化*256*7,共延时2clk------------------------------------------// +reg [0:0] nd_comdiv_mulout_d1 = 1'd0; +reg [22:0] comdiv_temp_ac_bd = 23'd0; +reg [22:0] comdiv_temp_bc_ad = 23'd0; +always @(posedge clk) +begin + if(rst) + begin + nd_comdiv_mulout_d1 <= 1'd0; + comdiv_temp_ac_bd <= 23'd0; + comdiv_temp_bc_ad <= 23'd0; + end + else + begin + if(nd_comdiv_mulout) + begin + nd_comdiv_mulout_d1 <= 1'd1; + comdiv_temp_ac_bd <= {comdiv_ac_out[21],comdiv_ac_out} + {comdiv_bd_out[21],comdiv_bd_out}; + comdiv_temp_bc_ad <= {comdiv_bc_out[21],comdiv_bc_out} - {comdiv_ad_out[21],comdiv_ad_out}; + end + else + begin + nd_comdiv_mulout_d1 <= 1'd0; + comdiv_temp_ac_bd <= 23'd0; + comdiv_temp_bc_ad <= 23'd0; + end + end +end + +reg [0:0] nd_comdiv_mulout_d2 = 1'd0; +reg [25:0] comdiv_temp_ac_bd2 = 26'd0; +reg [25:0] comdiv_temp_bc_ad2 = 26'd0; +always @(posedge clk) +begin + if(rst) + begin + nd_comdiv_mulout_d2 <= 1'd0; + comdiv_temp_ac_bd2 <= 26'd0; + comdiv_temp_bc_ad2 <= 26'd0; + end + else + begin + if(nd_comdiv_mulout_d1) + begin + nd_comdiv_mulout_d2 <= 1'd1; + comdiv_temp_ac_bd2 <= {comdiv_temp_ac_bd,3'd0} - {{3{comdiv_temp_ac_bd[22]}},comdiv_temp_ac_bd}; + comdiv_temp_bc_ad2 <= {comdiv_temp_bc_ad,3'd0} - {{3{comdiv_temp_bc_ad[22]}},comdiv_temp_bc_ad}; + end + else + begin + nd_comdiv_mulout_d2 <= 1'd0; + comdiv_temp_ac_bd2 <= 26'd0; + comdiv_temp_bc_ad2 <= 26'd0; + end + end +end + + + + + +//------------------------------------------------除法器两个,复用(延时38clk)--------------------------------------------// +//------------------------------------------------①复数除法器,除法计算--------------------------------------------// +//------------------------------------------------②MMSE信道估计除法--------------------------------------------// +reg dividerin_valid = 1'd0; +reg [27:0] dividerin_divisor = 28'd0; +reg [33:0] dividerin_dividend_i = 34'd0; +wire dividerout_valid_i; +wire[71:0] div_axis_dout_tdata_i; +wire[33:0] dividerout_data_i; +assign dividerout_data_i = div_axis_dout_tdata_i[65:32]; +divider_ChnEst divider_ChnEst_i ( + .aclk (clk), // input wire aclk + .s_axis_divisor_tvalid (dividerin_valid), // input wire s_axis_divisor_tvalid + .s_axis_divisor_tdata ({4'd0,dividerin_divisor}), // input wire [31 : 0] s_axis_divisor_tdata + .s_axis_dividend_tvalid (dividerin_valid), // input wire s_axis_dividend_tvalid + .s_axis_dividend_tdata ({6'd0,dividerin_dividend_i}), // input wire [39 : 0] s_axis_dividend_tdata + .m_axis_dout_tvalid (dividerout_valid_i), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata (div_axis_dout_tdata_i) // output wire [71 : 0] m_axis_dout_tdata + ); + + +reg [33:0] dividerin_dividend_q = 34'd0; +wire dividerout_valid_q; +wire[71:0] div_axis_dout_tdata_q; +wire[33:0] dividerout_data_q; +assign dividerout_data_q = div_axis_dout_tdata_q[65:32]; +divider_ChnEst divider_ChnEst_q ( + .aclk (clk), // input wire aclk + .s_axis_divisor_tvalid (dividerin_valid), // input wire s_axis_divisor_tvalid + .s_axis_divisor_tdata ({4'd0,dividerin_divisor}), // input wire [31 : 0] s_axis_divisor_tdata + .s_axis_dividend_tvalid (dividerin_valid), // input wire s_axis_dividend_tvalid + .s_axis_dividend_tdata ({6'd0,dividerin_dividend_q}), // input wire [39 : 0] s_axis_dividend_tdata + .m_axis_dout_tvalid (dividerout_valid_q), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata (div_axis_dout_tdata_q) // output wire [71 : 0] m_axis_dout_tdata + ); + + + + + + +//------------------------------------------信道估计部分共做两次fft,对其进行延时,并监测溢出情况------------------------------------------// +reg [1:0] state_flag_overflow1 = 2'd0; +reg [25:0] fft_out_i_d1 = 26'd0; +reg [25:0] fft_out_q_d1 = 26'd0; +reg fft_out_nd_d1 = 1'd0; +always @(posedge clk) +begin + if(rst) + begin + state_flag_overflow1<= 2'd0; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + fft_out_nd_d1 <= 1'd0; + flagoverflow_fftpilot_26to14 <= 1'd0; + flagoverflow_ChnZF_26to18 <= 1'd0; + end + else + begin + case(state_flag_overflow1) + //帧间复位结束后,等待第一个数据段的pilot数据nd,开始做fft + 2'd0: + begin + flagoverflow_fftpilot_26to14 <= 1'd0; + flagoverflow_ChnZF_26to18 <= 1'd0; + if(nd_pilot2) + begin + state_flag_overflow1<= state_flag_overflow1 + 2'd1; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + fft_out_nd_d1 <= 1'd0; + end + else + begin + state_flag_overflow1<= state_flag_overflow1; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + fft_out_nd_d1 <= 1'd0; + end + end + //第1段fft,输出最大允许14bit + 2'd1: + begin + fft_out_i_d1 <= fft_out_i; + fft_out_q_d1 <= fft_out_q; + fft_out_nd_d1 <= fft_out_nd; + if(fft_index==8'd255) + state_flag_overflow1 <= state_flag_overflow1 + 2'd1; + else + state_flag_overflow1 <= state_flag_overflow1; + if(fft_out_i[25:13]!=13'd8191&&fft_out_i[25:13]!=13'd0) + flagoverflow_fftpilot_26to14 <= 1'd1; + else + begin + if(fft_out_q[25:13]!=13'd8191&&fft_out_q[25:13]!=13'd0) + flagoverflow_fftpilot_26to14 <= 1'd1; + else + flagoverflow_fftpilot_26to14 <= 1'd0; + end + flagoverflow_ChnZF_26to18 <= 1'd0; + end + //第2段fft,输出最大允许18bit + 2'd2: + begin + fft_out_i_d1 <= fft_out_i; + fft_out_q_d1 <= fft_out_q; + fft_out_nd_d1 <= fft_out_nd; + if(fft_index==8'd255) + state_flag_overflow1 <= 2'd0; + else + state_flag_overflow1 <= state_flag_overflow1; + if(fft_out_i[25:17]!=9'd511&&fft_out_i[25:17]!=9'd0) + flagoverflow_ChnZF_26to18 <= 1'd1; + else + begin + if(fft_out_q[25:17]!=9'd511&&fft_out_q[25:17]!=9'd0) + flagoverflow_ChnZF_26to18 <= 1'd1; + else + flagoverflow_ChnZF_26to18 <= 1'd0; + end + flagoverflow_fftpilot_26to14 <= 1'd0; + end + default: + state_flag_overflow1 <= 2'd0; + endcase + end +end + + + + + +//-------------------------------------------------------------fft输入控制状态机---------------------------------------------------------------// +//---------------------------------------顶层输入增强导频->①信道估计第一次fft的输入--------------------------------------// +//-------------------------------------①信道估计第一次fft的输出->②复数除法分子乘法输入--------------------------------------// +//-------------------------------------③信道估计第一次除法器的输出->④信道估计第一次ifft的输入--------------------------------------// +//-------------------------------------④信道估计第一次ifft的输出->⑤信道估计第二次fft的输入--------------------------------------// +//-------------------------------------⑤信道估计第二次fft的输出,截位--------------------------------------// +reg [4:0] state_pilot_fft = 5'd0; + +reg [0:0] ChnEst_ZF_nd = 1'd0; //ZF信道估计结果 +reg [17:0] ChnEst_ZF_i = 18'd0; +reg [17:0] ChnEst_ZF_q = 18'd0; + +always @(posedge clk) +begin + if(rst) + begin + state_pilot_fft <= 5'd0; + + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + + addr_fft_piloti <= 8'd0; + addr_fft_pilotq <= 8'd0; + + comdiv_ac_a <= 14'd0; + comdiv_ac_c <= 8'd0; + comdiv_bd_b <= 14'd0; + comdiv_bd_d <= 8'd0; + comdiv_bc_b <= 14'd0; + comdiv_bc_c <= 8'd0; + comdiv_ad_a <= 14'd0; + comdiv_ad_d <= 8'd0; + + nd_comdiv_mulin <= 1'd0; + + ChnEst_ZF_nd <= 1'd0; + ChnEst_ZF_i <= 18'd0; + ChnEst_ZF_q <= 18'd0; + + flagoverflow_ifftzero_29to17i <= 1'd0; + flagoverflow_ifftzero_29to17q <= 1'd0; + flag_ChnEstFFT_done <= 1'd0; + end + else + begin + case(state_pilot_fft) + //帧间复位结束后,等待第一个数据段的pilot数据nd,开始做fft + 5'd0: + begin + if(nd_pilot2) + begin + fft_in_i <= {{7{pilot_datai[9]}},pilot_datai}; + fft_in_q <= {{7{pilot_dataq[9]}},pilot_dataq}; + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft + 5'd1; + end + else + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + state_pilot_fft <= state_pilot_fft; + end + end + //等待256点的fft输入完毕 + 5'd1: + begin + if(nd_pilot2==1'd0) + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + state_pilot_fft <= state_pilot_fft + 5'd1; + end + else + begin + fft_in_i <= {{7{pilot_datai[9]}},pilot_datai}; + fft_in_q <= {{7{pilot_dataq[9]}},pilot_dataq}; + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft; + end + addr_fft_piloti <= 8'd0; + addr_fft_pilotq <= 8'd0; + end + //等待fft结果到达 + 5'd2: + begin + if(fft_out_nd) + begin + addr_fft_piloti <= addr_fft_piloti + 8'd1; + addr_fft_pilotq <= addr_fft_pilotq + 8'd1; + state_pilot_fft <= state_pilot_fft + 5'd1; + end + else + begin + addr_fft_piloti <= 8'd0; + addr_fft_pilotq <= 8'd0; + state_pilot_fft <= state_pilot_fft; + end + nd_comdiv_mulin <= 1'd0; + end + //等待fft结果到达后,送入复数除法的实数乘法部分 + 5'd3: + begin + nd_comdiv_mulin <= fft_out_nd_d1; + if(fft_out_nd_d1==1'd0) + begin + addr_fft_piloti <= 8'd0; + addr_fft_pilotq <= 8'd0; + comdiv_ac_a <= 14'd0; + comdiv_ac_c <= 8'd0; + comdiv_bd_b <= 14'd0; + comdiv_bd_d <= 8'd0; + comdiv_bc_b <= 14'd0; + comdiv_bc_c <= 8'd0; + comdiv_ad_a <= 14'd0; + comdiv_ad_d <= 8'd0; + state_pilot_fft <= state_pilot_fft + 5'd1; + end + else + begin + addr_fft_piloti <= addr_fft_piloti + 8'd1; + addr_fft_pilotq <= addr_fft_pilotq + 8'd1; + comdiv_ac_a <= fft_out_i_d1[13:0]; //根据仿真结果,fft结果最多14bit有符号数 + comdiv_ac_c <= dout_fft_piloti; + comdiv_bd_b <= fft_out_q_d1[13:0]; + comdiv_bd_d <= dout_fft_pilotq; + comdiv_bc_b <= fft_out_q_d1[13:0]; + comdiv_bc_c <= dout_fft_piloti; + comdiv_ad_a <= fft_out_i_d1[13:0]; + comdiv_ad_d <= dout_fft_pilotq; + state_pilot_fft <= state_pilot_fft; + end + end + //等待ifft结果到达,将结果直接给回fft模块的输入,做第二次fft(根据仿真,只保留低17bit) + 5'd4: + begin + nd_comdiv_mulin <= 1'd0; + if(ifft_out_nd) + begin + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft + 5'd1; + if(ifft_out_i[28:24]!=5'd31&&ifft_out_i[28:24]!=5'd0) + begin + flagoverflow_ifftzero_29to17i <= 1'd1; + fft_in_i <= (ifft_out_i[28])? 17'b1_0000_0000_0000_0000 : 17'b0_1111_1111_1111_1111; + end + else + begin + flagoverflow_ifftzero_29to17i <= 1'd0; + fft_in_i <= ifft_out_i[24:8]; + end + if(ifft_out_q[28:24]!=5'd31&&ifft_out_q[28:24]!=5'd0) + begin + flagoverflow_ifftzero_29to17q <= 1'd1; + fft_in_q <= (ifft_out_q[28])? 17'b1_0000_0000_0000_0000 : 17'b0_1111_1111_1111_1111; + end + else + begin + flagoverflow_ifftzero_29to17q <= 1'd0; + fft_in_q <= ifft_out_q[24:8]; + end + end + else + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + state_pilot_fft <= state_pilot_fft; + flagoverflow_ifftzero_29to17i <= 1'd0; + flagoverflow_ifftzero_29to17q <= 1'd0; + end + end + //零域估计,去噪 + 5'd5: + begin + if(ifft_index>=Zerozone_vio) + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft + 5'd1; + flagoverflow_ifftzero_29to17i <= 1'd0; + flagoverflow_ifftzero_29to17q <= 1'd0; + end + else + begin + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft; + if(ifft_out_i[28:24]!=5'd31&&ifft_out_i[28:24]!=5'd0) + begin + flagoverflow_ifftzero_29to17i <= 1'd1; + fft_in_i <= (ifft_out_i[28])? 17'b1_0000_0000_0000_0000 : 17'b0_1111_1111_1111_1111; + end + else + begin + flagoverflow_ifftzero_29to17i <= 1'd0; + fft_in_i <= ifft_out_i[24:8]; + end + if(ifft_out_q[28:24]!=5'd31&&ifft_out_q[28:24]!=5'd0) + begin + flagoverflow_ifftzero_29to17q <= 1'd1; + fft_in_q <= (ifft_out_q[28])? 17'b1_0000_0000_0000_0000 : 17'b0_1111_1111_1111_1111; + end + else + begin + flagoverflow_ifftzero_29to17q <= 1'd0; + fft_in_q <= ifft_out_q[24:8]; + end + end + flag_ChnEstFFT_done <= 1'd0; + end + //等待全部256个点第二次输入fft核 + 5'd6: + begin + if(ifft_out_nd==1'd0) + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + state_pilot_fft <= state_pilot_fft + 5'd1; + flag_ChnEstFFT_done <= 1'd1; + end + else + begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd1; + state_pilot_fft <= state_pilot_fft; + flag_ChnEstFFT_done <= 1'd0; + end + flagoverflow_ifftzero_29to17i <= 1'd0; + flagoverflow_ifftzero_29to17q <= 1'd0; + end + //等待第二次fft的结果,即ZF信道估计结果(只保留低18bit),将其单独缓存,用于计算MMSE信道估计 + 5'd7: + begin + if(fft_out_nd_d1) + begin + ChnEst_ZF_nd <= 1'd1; + ChnEst_ZF_i <= fft_out_i_d1[17:0]; + ChnEst_ZF_q <= -fft_out_q_d1[17:0]; + state_pilot_fft <= state_pilot_fft + 5'd1; + end + else + begin + ChnEst_ZF_nd <= 1'd0; + ChnEst_ZF_i <= 18'd0; + ChnEst_ZF_q <= 18'd0; + state_pilot_fft <= state_pilot_fft; + end + flag_ChnEstFFT_done <= 1'd0; + end + //等待第二次fft的结果全部输出,状态机转回状态0等待下一段导频 + 5'd8: + begin + if(fft_out_nd_d1==1'd0) + begin + ChnEst_ZF_nd <= 1'd0; + ChnEst_ZF_i <= 18'd0; + ChnEst_ZF_q <= 18'd0; + state_pilot_fft <= 5'd0; + end + else + begin + ChnEst_ZF_nd <= 1'd1; + ChnEst_ZF_i <= fft_out_i_d1[17:0]; + ChnEst_ZF_q <= -fft_out_q_d1[17:0]; + state_pilot_fft <= state_pilot_fft; + end + flag_ChnEstFFT_done <= 1'd0; + end + default: + state_pilot_fft <= 5'd0; + endcase + end +end + + + + + + + +//--------------------------------------------------------ifft输入控制状态机----------------------------------------------------------// +//-------------------------------------③信道估计第一次除法器的输出->④信道估计第一次ifft的输入--------------------------------------// +reg [1:0] state_pilot_ifft = 2'd0; +always @(posedge clk) +begin + if(rst) + begin + state_pilot_ifft <= 2'd0; + + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + + flagoverflow_comdiv_34to20i <= 1'd0; + flagoverflow_comdiv_34to20q <= 1'd0; + end + else + begin + case(state_pilot_ifft) + //帧间复位结束后,等待第一个数据段的pilot数据nd + 2'd0: + begin + if(nd_pilot2) + begin + state_pilot_ifft <= state_pilot_ifft + 2'd1; + end + else + begin + state_pilot_ifft <= state_pilot_ifft; + end + end + //等待③信道估计第一次除法器的输出 + 2'd1: + begin + if(dividerout_valid_i) + begin + ifft_in_nd <= 1'd1; + state_pilot_ifft <= state_pilot_ifft + 2'd1; + if(dividerout_data_i[33:19]!=15'd32767&÷rout_data_i[33:19]!=15'd0) + begin + flagoverflow_comdiv_34to20i <= 1'd1; + ifft_in_i <= (dividerout_data_i[33])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else + begin + flagoverflow_comdiv_34to20i <= 1'd0; + ifft_in_i <= dividerout_data_i[19:0]; + end + if(dividerout_data_q[33:19]!=15'd32767&÷rout_data_q[33:19]!=15'd0) + begin + flagoverflow_comdiv_34to20q <= 1'd1; + ifft_in_q <= (dividerout_data_q[33])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else + begin + flagoverflow_comdiv_34to20q <= 1'd0; + ifft_in_q <= dividerout_data_q[19:0]; + end + end + else + begin + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + state_pilot_ifft <= state_pilot_ifft; + flagoverflow_comdiv_34to20i <= 1'd0; + flagoverflow_comdiv_34to20q <= 1'd0; + end + end + //等待256点的ifft输入完毕 + 2'd2: + begin + if(dividerout_valid_i==1'd0) + begin + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + state_pilot_ifft <= 2'd0; + flagoverflow_comdiv_34to20i <= 1'd0; + flagoverflow_comdiv_34to20q <= 1'd0; + end + else + begin + ifft_in_nd <= 1'd1; + state_pilot_ifft <= state_pilot_ifft; + if(dividerout_data_i[33:19]!=15'd32767&÷rout_data_i[33:19]!=15'd0) + begin + flagoverflow_comdiv_34to20i <= 1'd1; + ifft_in_i <= (dividerout_data_i[33])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else + begin + flagoverflow_comdiv_34to20i <= 1'd0; + ifft_in_i <= dividerout_data_i[19:0]; + end + if(dividerout_data_q[33:19]!=15'd32767&÷rout_data_q[33:19]!=15'd0) + begin + flagoverflow_comdiv_34to20q <= 1'd1; + ifft_in_q <= (dividerout_data_q[33])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else + begin + flagoverflow_comdiv_34to20q <= 1'd0; + ifft_in_q <= dividerout_data_q[19:0]; + end + end + end + default: + state_pilot_ifft <= 2'd0; + endcase + end +end + + + + + + + + +//---------------------------------------ZF->MMSE信道估计的计算(除法分母部分);对齐分母分子时序----------------------------------------// +wire abs_ZF_nd; +wire [18:0] abs_ZF; +ApproxAbs_18bit ApproxAbs_18bit ( + .clk (clk), + .ND (ChnEst_ZF_nd), + .Din_I (ChnEst_ZF_i), + .Din_Q (ChnEst_ZF_q), + + .Rdy (abs_ZF_nd), + .Dout (abs_ZF) + ); + + +reg squ_abs_ZF_nd = 1'd0; +wire [29:0] squ_abs_ZF; +squ_abs_ZF squ_abs_ZF1 ( + .CLK (clk), // input wire CLK + .A (abs_ZF[18:4]), // input wire [14 : 0] A + .B (abs_ZF[18:4]), // input wire [14 : 0] B + .P (squ_abs_ZF) // output wire [29 : 0] P + ); +always @(posedge clk) +begin + if(rst) + squ_abs_ZF_nd <= 1'd0; + else + squ_abs_ZF_nd <= abs_ZF_nd; +end + + +reg div_MMSE_nd = 1'd0; +reg [30:0] div_MMSE = 31'd0; +always @(posedge clk) +begin + if(rst) + begin + div_MMSE_nd <= 1'd0; + div_MMSE <= 31'd0; + end + else + begin + if(squ_abs_ZF_nd) + begin + div_MMSE_nd <= 1'd1; + div_MMSE <= {{3{EstNoise_i[27]}},EstNoise_i} + {squ_abs_ZF[29],squ_abs_ZF}; + end + else + begin + div_MMSE_nd <= 1'd0; + div_MMSE <= 31'd0; + end + end +end + + +//除法器分母根据仿真结果截位到28bit位宽,同时设置溢出标志用于监测 +reg div2_MMSE_nd = 1'd0; +reg [27:0] div2_MMSE = 28'd0; +always @(posedge clk) +begin + if(rst) + begin + div2_MMSE_nd <= 1'd0; + div2_MMSE <= 28'd0; + flagoverflow_MMSEdiv_divisor_31to28 <= 1'd0; + end + else + begin + if(div_MMSE_nd) + begin + div2_MMSE_nd <= 1'd1; + if(div_MMSE[30:27]==4'd0||div_MMSE[30:27]==4'd15) + begin + flagoverflow_MMSEdiv_divisor_31to28 <= 1'd0; + div2_MMSE <= div_MMSE[27:0]; + end + else + begin + flagoverflow_MMSEdiv_divisor_31to28 <= 1'd1; + div2_MMSE <= (div_MMSE[30])? 28'b1000_0000_0000_0000_0000_0000_0000: 28'b0111_1111_1111_1111_1111_1111_1111; + end + end + else + begin + div2_MMSE_nd <= 1'd0; + div2_MMSE <= 28'd0; + flagoverflow_MMSEdiv_divisor_31to28 <= 1'd0; + end + end +end + + +//总共6+1+1+1=9clk延时,缓存ChnEst_ZF_i/q +reg [0:0] ChnEst_ZF_nd_d1 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d2 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d3 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d4 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d5 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d6 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d7 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d8 = 1'd0; +reg [0:0] ChnEst_ZF_nd_d9 = 1'd0; +reg [17:0] ChnEst_ZF_i_d1 = 18'd0; +reg [17:0] ChnEst_ZF_i_d2 = 18'd0; +reg [17:0] ChnEst_ZF_i_d3 = 18'd0; +reg [17:0] ChnEst_ZF_i_d4 = 18'd0; +reg [17:0] ChnEst_ZF_i_d5 = 18'd0; +reg [17:0] ChnEst_ZF_i_d6 = 18'd0; +reg [17:0] ChnEst_ZF_i_d7 = 18'd0; +reg [17:0] ChnEst_ZF_i_d8 = 18'd0; +reg [17:0] ChnEst_ZF_i_d9 = 18'd0; +reg [17:0] ChnEst_ZF_q_d1 = 18'd0; +reg [17:0] ChnEst_ZF_q_d2 = 18'd0; +reg [17:0] ChnEst_ZF_q_d3 = 18'd0; +reg [17:0] ChnEst_ZF_q_d4 = 18'd0; +reg [17:0] ChnEst_ZF_q_d5 = 18'd0; +reg [17:0] ChnEst_ZF_q_d6 = 18'd0; +reg [17:0] ChnEst_ZF_q_d7 = 18'd0; +reg [17:0] ChnEst_ZF_q_d8 = 18'd0; +reg [17:0] ChnEst_ZF_q_d9 = 18'd0; + +always @(posedge clk) +begin + if(rst) + begin + ChnEst_ZF_nd_d1 <= 1'd0; + ChnEst_ZF_nd_d2 <= 1'd0; + ChnEst_ZF_nd_d3 <= 1'd0; + ChnEst_ZF_nd_d4 <= 1'd0; + ChnEst_ZF_nd_d5 <= 1'd0; + ChnEst_ZF_nd_d6 <= 1'd0; + ChnEst_ZF_nd_d7 <= 1'd0; + ChnEst_ZF_nd_d8 <= 1'd0; + ChnEst_ZF_nd_d9 <= 1'd0; + ChnEst_ZF_i_d1 <= 18'd0; + ChnEst_ZF_i_d2 <= 18'd0; + ChnEst_ZF_i_d3 <= 18'd0; + ChnEst_ZF_i_d4 <= 18'd0; + ChnEst_ZF_i_d5 <= 18'd0; + ChnEst_ZF_i_d6 <= 18'd0; + ChnEst_ZF_i_d7 <= 18'd0; + ChnEst_ZF_i_d8 <= 18'd0; + ChnEst_ZF_i_d9 <= 18'd0; + ChnEst_ZF_q_d1 <= 18'd0; + ChnEst_ZF_q_d2 <= 18'd0; + ChnEst_ZF_q_d3 <= 18'd0; + ChnEst_ZF_q_d4 <= 18'd0; + ChnEst_ZF_q_d5 <= 18'd0; + ChnEst_ZF_q_d6 <= 18'd0; + ChnEst_ZF_q_d7 <= 18'd0; + ChnEst_ZF_q_d8 <= 18'd0; + ChnEst_ZF_q_d9 <= 18'd0; + end + else + begin + ChnEst_ZF_nd_d1 <= ChnEst_ZF_nd; + ChnEst_ZF_nd_d2 <= ChnEst_ZF_nd_d1; + ChnEst_ZF_nd_d3 <= ChnEst_ZF_nd_d2; + ChnEst_ZF_nd_d4 <= ChnEst_ZF_nd_d3; + ChnEst_ZF_nd_d5 <= ChnEst_ZF_nd_d4; + ChnEst_ZF_nd_d6 <= ChnEst_ZF_nd_d5; + ChnEst_ZF_nd_d7 <= ChnEst_ZF_nd_d6; + ChnEst_ZF_nd_d8 <= ChnEst_ZF_nd_d7; + ChnEst_ZF_nd_d9 <= ChnEst_ZF_nd_d8; + ChnEst_ZF_i_d1 <= ChnEst_ZF_i; + ChnEst_ZF_i_d2 <= ChnEst_ZF_i_d1; + ChnEst_ZF_i_d3 <= ChnEst_ZF_i_d2; + ChnEst_ZF_i_d4 <= ChnEst_ZF_i_d3; + ChnEst_ZF_i_d5 <= ChnEst_ZF_i_d4; + ChnEst_ZF_i_d6 <= ChnEst_ZF_i_d5; + ChnEst_ZF_i_d7 <= ChnEst_ZF_i_d6; + ChnEst_ZF_i_d8 <= ChnEst_ZF_i_d7; + ChnEst_ZF_i_d9 <= ChnEst_ZF_i_d8; + ChnEst_ZF_q_d1 <= ChnEst_ZF_q; + ChnEst_ZF_q_d2 <= ChnEst_ZF_q_d1; + ChnEst_ZF_q_d3 <= ChnEst_ZF_q_d2; + ChnEst_ZF_q_d4 <= ChnEst_ZF_q_d3; + ChnEst_ZF_q_d5 <= ChnEst_ZF_q_d4; + ChnEst_ZF_q_d6 <= ChnEst_ZF_q_d5; + ChnEst_ZF_q_d7 <= ChnEst_ZF_q_d6; + ChnEst_ZF_q_d8 <= ChnEst_ZF_q_d7; + ChnEst_ZF_q_d9 <= ChnEst_ZF_q_d8; + end +end + + + + + + + +//-------------------------------------------------------------控制状态机---------------------------------------------------------------// +//-------------------------------------②复数除法分子乘法输出->③信道估计第一次除法器的输入--------------------------------------// +//---------------------⑤信道估计第二次fft的输出->MMSE信道估计的计算(除法分母部分)->⑥信道估计第二次除法器的输入-----------------------// +reg [4:0] state_pilot_div = 5'd0; + + +always @(posedge clk) +begin + if(rst) + begin + state_pilot_div <= 5'd0; + + addr_abs_pilot2 <= 8'd0; + + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i<= 34'd0; + dividerin_dividend_q<= 34'd0; + end + else + begin + case(state_pilot_div) + //帧间复位结束后,等待数据段的pilot数据nd + 5'd0: + begin + if(nd_pilot2) + begin + state_pilot_div <= state_pilot_div + 5'd1; + end + else + begin + state_pilot_div <= state_pilot_div; + end + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i <= 34'd0; + dividerin_dividend_q <= 34'd0; + end + //等待第一次乘法器的输出有效信号,此时结果是复数除法的分子nd前一clk + 5'd1: + begin + if(nd_comdiv_mulout_d1) + begin + addr_abs_pilot2 <= addr_abs_pilot2 + 8'd1; + state_pilot_div <= state_pilot_div + 5'd1; + end + else + begin + addr_abs_pilot2 <= 8'd0; + state_pilot_div <= state_pilot_div; + end + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i <= 34'd0; + dividerin_dividend_q <= 34'd0; + end + //复数除法的分子nd结束后,转入下一状态,等待 + 5'd2: + begin + if(nd_comdiv_mulout_d2==1'd0) + begin + addr_abs_pilot2 <= 8'd0; + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i <= 34'd0; + dividerin_dividend_q <= 34'd0; + state_pilot_div <= state_pilot_div + 5'd1; + end + else + begin + addr_abs_pilot2 <= addr_abs_pilot2 + 8'd1; + dividerin_valid <= 1'd1; + dividerin_divisor <= {{13{dout_abs_pilot2[14]}},dout_abs_pilot2}; + dividerin_dividend_i <= {comdiv_temp_ac_bd2,8'd0}; + dividerin_dividend_q <= {comdiv_temp_bc_ad2,8'd0}; + state_pilot_div <= state_pilot_div; + end + end + //等待div2_MMSE_nd,即MMSE信道估计除法的分子分母准备好的nd,开始向除法器中第二次给输入 + 5'd3: + begin + if(div2_MMSE_nd) + begin + dividerin_valid <= 1'd1; + dividerin_divisor <= div2_MMSE; + dividerin_dividend_i <= {{4{ChnEst_ZF_i_d9[17]}},ChnEst_ZF_i_d9,12'd0}; + dividerin_dividend_q <= {{4{ChnEst_ZF_q_d9[17]}},ChnEst_ZF_q_d9,12'd0}; + state_pilot_div <= state_pilot_div + 5'd1; + end + else + begin + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i <= 34'd0; + dividerin_dividend_q <= 34'd0; + state_pilot_div <= state_pilot_div; + end + end + //等待除法器中第二次给输入结束 + 5'd4: + begin + if(div2_MMSE_nd==1'd0) + begin + dividerin_valid <= 1'd0; + dividerin_divisor <= 28'd0; + dividerin_dividend_i <= 34'd0; + dividerin_dividend_q <= 34'd0; + state_pilot_div <= 5'd0; + end + else + begin + dividerin_valid <= 1'd1; + dividerin_divisor <= div2_MMSE; + dividerin_dividend_i <= {{4{ChnEst_ZF_i_d9[17]}},ChnEst_ZF_i_d9,12'd0}; + dividerin_dividend_q <= {{4{ChnEst_ZF_q_d9[17]}},ChnEst_ZF_q_d9,12'd0}; + state_pilot_div <= state_pilot_div; + end + end + default: + state_pilot_div <= 5'd0; + endcase + end +end + + + + + + +//-------------------------------------------------------------控制状态机---------------------------------------------------------------// +//-------------------------------------⑥信道估计第二次除法器的输出,此时为MMSE的结果,截位后保存在rom中--------------------------------// +//--------------------------------------------------------截位设置溢出标志,保留低11bit--------------------------------// +reg div2_out_ce = 1'd0; +always @(posedge clk) +begin + if(rst) + begin + div2_out_ce <= 1'd0; + write_MMSE_wea <= 1'd0; + addrin_MMSE <= 8'd255; + din_MMSE <= 22'd0; + flagoverflow_divmmse_34to11 <= 1'd0; + end + else + begin + if(div2_out_ce==1'd0) + begin + if(div2_MMSE_nd) + begin + div2_out_ce <= 1'd1; + end + else + begin + div2_out_ce <= 1'd0; + end + write_MMSE_wea <= 1'd0; + addrin_MMSE <= 8'd255; + din_MMSE <= 22'd0; + flagoverflow_divmmse_34to11 <= 1'd0; + end + else + begin + if(dividerout_valid_i) + begin + if(addrin_MMSE==8'd254) + div2_out_ce <= 1'd0; + else + div2_out_ce <= 1'd1; + write_MMSE_wea <= 1'd1; + addrin_MMSE <= addrin_MMSE + 8'd1; + din_MMSE <= {dividerout_data_q[10:0],dividerout_data_i[10:0]}; + if(dividerout_data_i[33:10]!=24'd16777215&÷rout_data_i[33:10]!=24'd0) + flagoverflow_divmmse_34to11 <= 1'd1; + else + begin + if(dividerout_data_q[33:10]!=24'd16777215&÷rout_data_q[33:10]!=24'd0) + flagoverflow_divmmse_34to11 <= 1'd1; + else + flagoverflow_divmmse_34to11 <= 1'd0; + end + end + else + begin + div2_out_ce <= div2_out_ce; + write_MMSE_wea <= 1'd0; + addrin_MMSE <= 8'd255; + din_MMSE <= 22'd0; + flagoverflow_divmmse_34to11 <= 1'd0; + end + end + + end +end + + + + + + + + + +//------------------------------------------------------仿真文件保存---------------------------------------------------// +// integer handle01; +// integer handle02; +// integer handle03; +// integer handle04; + +// reg enable1 = 0; +// initial begin + +// handle01=$fopen("din_MMSEi.txt","w"); $fclose(handle01); +// handle02=$fopen("din_MMSEq.txt","w"); $fclose(handle02); +// handle03=$fopen("dividerout_data_i.txt","w"); $fclose(handle03); +// handle04=$fopen("dividerout_data_q.txt","w"); $fclose(handle04); + +// #10; +// enable1 = 1; +// end + +// always@(posedge clk)begin +// if(enable1)begin + +// if(write_MMSE_wea)begin +// handle01=$fopen("din_MMSEi.txt","a+");$fwrite(handle01,"%d\n",$signed(din_MMSE[10:0]));$fclose(handle01); +// handle02=$fopen("din_MMSEq.txt","a+");$fwrite(handle02,"%d\n",$signed(din_MMSE[21:11]));$fclose(handle02); +// end +// if(dividerout_valid_i)begin +// handle03=$fopen("dividerout_data_i.txt","a+");$fwrite(handle03,"%d\n",$signed(dividerout_data_i));$fclose(handle03); +// handle04=$fopen("dividerout_data_q.txt","a+");$fwrite(handle04,"%d\n",$signed(dividerout_data_q));$fclose(handle04); +// end +// end +// end + + +endmodule diff --git a/hdl/DAGC_v2.v b/hdl/DAGC_v2.v new file mode 100644 index 0000000..7f725b7 --- /dev/null +++ b/hdl/DAGC_v2.v @@ -0,0 +1,552 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2020/08/18 16:40:38 +// Design Name: +// Module Name: DAGC_v2 +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module DAGC_v2 ( + input clk, + input rst, + + input mgc1_rdy, + input framesync_d0, + + input [1:0] vio_powertest_h, + input [1:0] vio_powertest_l, + + input [9:0] matchfilterout_i, + input [9:0] matchfilterout_q, + + output reg [9:0] DAGC_out_i = 10'd0, + output reg [9:0] DAGC_out_q = 10'd0, + + //检测用 + output reg flag_agch = 1'd0, + output reg flag_agcl = 1'd0, + output reg flag_agc_power = 1'd0, + output reg [12:0] agc_ref = 13'd0, + output reg [12:0] agc_check = 13'd0, + output reg dagc_rdy, + output reg mgc_rdy, + output reg rst_dagc +); + + + //近似求模值方法,做4096累积平均 + + //-------------------------------------数据缓存----------------------------// + reg wea_1 = 1'd0; + reg [11:0] addrin_1 = 12'd0; + reg [ 9:0] din_1i = 10'd0; + reg [11:0] addrout_1 = 12'd0; + wire [ 9:0] dout_1i; + + + + //-------------------------------------------给数据、打缓存的状态机-------------------------------------// + reg ND = 1'd0; + reg [ 9:0] Din_I = 10'd0; + reg [ 9:0] Din_Q = 10'd0; + reg [ 5:0] cnt_50 = 6'd0; + reg [ 2:0] state_storage = 3'd0; + + + wire [ 9:0] mf_i; + wire [ 9:0] mf_q; + wire empty; + wire full; + reg rd_en = 1'b0; + wire [13:0] data_count; + fifo_dagc fifo_dagc ( + .clk (clk), + .srst (rst), + .din ({matchfilterout_q, matchfilterout_i}), + .wr_en (mgc1_rdy), + .full (empty), + .rd_en (rd_en), + .empty (full), + .dout ({mf_q, mf_i}), + .data_count(data_count) + ); + + + + + //-------------------------------------求近似模值的模块----------------------------// + wire [10:0] Dout; + wire [ 0:0] Rdy_abs; + ApproxAbs_v2 ApproxAbs_v2_djy ( + .clk (clk), + .ND (mgc1_rdy), + .Din_I(matchfilterout_i), + .Din_Q(matchfilterout_q), + .Dout (Dout), + .Rdy (Rdy_abs) + ); + + reg framesync_d1; + reg framesync_d2; + reg framesync_d3; + reg framesync_d4; + reg framesync_d5; + reg framesync; + + always @(posedge clk) begin //(MXQ)必须加 posedge clk ,否则仿真有问题,内存溢出 + framesync_d1 <= framesync_d0; //与ApproxAbs_v2_djy同步 + framesync_d2 <= framesync_d1; + framesync_d3 <= framesync_d2; + framesync_d4 <= framesync_d3; + framesync_d5 <= framesync_d4; + framesync <= framesync_d5; + end + + + //-------------------------------------LUT----------------------------// + reg [10:0] addr_lut = 11'd0; + wire [13:0] dout_lut; + DAGC_LUT_rom DAGC_LUT_rom ( + .clka (clk), // input clka + .addra(addr_lut), // input [10 : 0] addra + .douta(dout_lut) // output [13 : 0] douta + ); + + reg dagc_rdy_d0; + reg dagc_rdy_d1; + reg dagc_rdy_d2; + reg dagc_rdy_d3; + reg dagc_rdy_d4; + reg mgc_rdy_d0; + reg mgc_rdy_d1; + reg mgc_rdy_d2; + reg mgc_rdy_d3; + reg mgc_rdy_d4; + always @(posedge clk) begin + if (rst) begin + dagc_rdy_d1 <= 1'b0; + dagc_rdy_d2 <= 1'b0; + dagc_rdy_d3 <= 1'b0; + dagc_rdy_d4 <= 1'b0; + dagc_rdy <= 1'b0; + mgc_rdy_d1 <= 1'b0; + mgc_rdy_d2 <= 1'b0; + mgc_rdy_d3 <= 1'b0; + mgc_rdy_d4 <= 1'b0; + mgc_rdy <= 1'b0; + + end + else begin + dagc_rdy_d1 <= dagc_rdy_d0; + dagc_rdy_d2 <= dagc_rdy_d1; + dagc_rdy_d3 <= dagc_rdy_d2; + dagc_rdy_d4 <= dagc_rdy_d3; + dagc_rdy <= dagc_rdy_d4; + mgc_rdy_d1 <= mgc_rdy_d0; + mgc_rdy_d2 <= mgc_rdy_d1; + mgc_rdy_d3 <= mgc_rdy_d2; + mgc_rdy_d4 <= mgc_rdy_d3; + mgc_rdy <= mgc_rdy_d4; + end + + end + + //-------------------------------------求均值、查表、给补偿指令的状态机----------------------------// + reg [ 3:0] state_agc = 4'd0; + reg [11:0] cnt_4096_3 = 12'd0; + reg [22:0] agc_ref_temp = 23'd0; + reg [14:0] agc_ref_h = 15'd0; + reg [12:0] agc_ref_l = 13'd0; + + reg flag_ram_1 = 1'd0; + reg flag_ram_2 = 1'd0; + reg [14:0] cnt_databag = 15'd0; + always @(posedge clk) begin + if (rst) begin + state_agc <= 4'd0; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd0; + + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + flag_agc_power <= 1'd0; + + agc_ref <= agc_ref; + agc_ref_temp <= 23'd0; + agc_check <= agc_check; + agc_ref_h <= 15'd0; + agc_ref_l <= 13'd0; + + addr_lut <= 11'd0; + flag_ram_1 <= 1'd0; + flag_ram_2 <= 1'd0; + dagc_rdy_d0 <= 1'b0; + rd_en <= 1'b0; + mgc_rdy_d0 <= 1'b0; + end + else begin + case (state_agc) + 4'd0: begin + if (Rdy_abs) begin //状态0进入第一次估计 + state_agc <= 4'd1; + agc_ref_temp <= {12'd0, Dout}; + cnt_4096_3 <= 12'd1; + cnt_databag <= 15'd1; + end + else begin + state_agc <= state_agc; + agc_ref_temp <= 23'd0; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd0; + end + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + flag_agc_power <= 1'd0; + + agc_ref <= 13'd0; + agc_check <= 13'd0; + agc_ref_h <= 15'd0; + agc_ref_l <= 13'd0; + + addr_lut <= 11'd0; + flag_ram_1 <= 1'd0; + flag_ram_2 <= 1'd0; + + end + + 4'd1: begin + if (cnt_4096_3 == 12'd4095) begin + state_agc <= 4'd2; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd1 + cnt_databag; + end + else begin + state_agc <= state_agc; + cnt_4096_3 <= 12'd01 + cnt_4096_3; + cnt_databag <= 15'd1 + cnt_databag; + end + agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; + flag_agc_power <= 1'd0; + end + + 4'd2: begin + if (framesync == 1'b1) begin //判断是否有帧同步如果有进入有效数据计算段 + state_agc <= 4'd3; + end + else begin + state_agc <= 4'd10; + end + cnt_databag <= 15'd1 + cnt_databag; + cnt_4096_3 <= 12'd0; + agc_ref_temp <= agc_ref_temp; + agc_ref <= agc_ref_temp[22:10]; + agc_check <= agc_ref_temp[22:10]; + flag_agc_power <= 1'd1; + + end + + 4'd3: begin + if (cnt_databag == 15'd13695) begin + cnt_databag <= 15'd0; + state_agc <= 4'd4; + cnt_4096_3 <= 12'd1; + agc_ref_temp <= {12'd0, Dout}; + end + else begin + cnt_databag <= 15'd1 + cnt_databag; + cnt_4096_3 <= 12'd0; + state_agc <= state_agc; + agc_ref_temp <= agc_ref_temp; + end + flag_agc_power <= 1'd0; + case (vio_powertest_h) + 2'd0: agc_ref_h <= {2'd0, agc_ref} + {4'd0, agc_ref[12:2]}; + 2'd1: agc_ref_h <= {2'd0, agc_ref} + {3'd0, agc_ref[12:1]}; + 2'd2: agc_ref_h <= {1'd0, agc_ref, 1'd0}; + 2'd3: agc_ref_h <= {agc_ref, 2'd0}; + endcase + case (vio_powertest_l) + 2'd0: agc_ref_l <= agc_ref - {3'd0, agc_ref[12:3]}; + 2'd1: agc_ref_l <= agc_ref - {2'd0, agc_ref[12:2]}; + 2'd2: agc_ref_l <= {1'd0, agc_ref[12:1]}; + 2'd3: agc_ref_l <= {2'd0, agc_ref[12:2]}; + endcase + + //查表地址 + if (agc_check <= 13'd11) addr_lut <= 11'd0; + else begin + if (agc_check >= 13'd2037) addr_lut <= 11'd2026; + else addr_lut <= agc_check[10:0] - 11'd11; + end + flag_ram_1 <= 1'd1; + flag_ram_2 <= 1'd0; + rd_en <= 1'b1; + dagc_rdy_d0 <= 1'b1; + end + + 4'd4: begin + if (cnt_4096_3 == 12'd4095) begin + state_agc <= 4'd5; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd1 + cnt_databag; + end + else begin + state_agc <= state_agc; + cnt_4096_3 <= 12'd01 + cnt_4096_3; + cnt_databag <= 15'd1 + cnt_databag; + end + agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + flag_agc_power <= 1'd0; + + flag_ram_1 <= 1'd0; + flag_ram_2 <= 1'd0; + end + + 4'd5: begin + state_agc <= 4'd6; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd1 + cnt_databag; + agc_ref_temp <= agc_ref_temp; + agc_check <= agc_ref_temp[22:10]; + flag_agc_power <= 1'd1; + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + end + + 4'd6: begin + if (cnt_databag == 15'd13823) begin + cnt_databag <= 15'd0; + state_agc <= 4'd7; + cnt_4096_3 <= 12'd1; + agc_ref_temp <= {12'd0, Dout}; + end + else begin + cnt_databag <= 15'd1 + cnt_databag; + cnt_4096_3 <= 12'd0; + state_agc <= state_agc; + agc_ref_temp <= agc_ref_temp; + end + flag_agc_power <= 1'd0; + if ({2'd0, agc_check} > agc_ref_h) begin + flag_agch <= 1'd1; + flag_agcl <= 1'd0; + end + else begin + if (agc_check < agc_ref_l) begin + flag_agch <= 1'd0; + flag_agcl <= 1'd1; + end + else begin + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + end + end + //查表地址 + if (agc_check <= 13'd11) addr_lut <= 11'd0; + else begin + if (agc_check >= 13'd2037) addr_lut <= 11'd2026; + else addr_lut <= agc_check[10:0] - 11'd11; + end + flag_ram_1 <= 1'd0; + flag_ram_2 <= 1'd1; + end + + 4'd7: begin + if (cnt_4096_3 == 12'd4095) begin + state_agc <= 4'd8; + cnt_4096_3 <= 12'd0; + cnt_databag <= 15'd1 + cnt_databag; + end + else begin + state_agc <= state_agc; + cnt_4096_3 <= 12'd01 + cnt_4096_3; + cnt_databag <= 15'd1 + cnt_databag; + end + agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + flag_agc_power <= 1'd0; + + flag_ram_1 <= 1'd0; + flag_ram_2 <= 1'd0; + end + + 4'd8: begin + state_agc <= 4'd9; + cnt_databag <= 15'd1 + cnt_databag; + cnt_4096_3 <= 12'd0; + agc_ref_temp <= {12'd0, Dout}; + agc_check <= agc_ref_temp[22:10]; + flag_agc_power <= 1'd1; + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + end + + 4'd9: begin + if (cnt_databag == 15'd13823) begin + cnt_databag <= 15'd0; + state_agc <= 4'd4; + cnt_4096_3 <= 12'd1; + agc_ref_temp <= {12'd0, Dout}; + end + else begin + cnt_databag <= 15'd1 + cnt_databag; + cnt_4096_3 <= 12'd0; + state_agc <= state_agc; + agc_ref_temp <= agc_ref_temp; + end + flag_agc_power <= 1'd0; + if ({2'd0, agc_check} > agc_ref_h) begin + flag_agch <= 1'd1; + flag_agcl <= 1'd0; + end + else begin + if (agc_check < agc_ref_l) begin + flag_agch <= 1'd0; + flag_agcl <= 1'd1; + end + else begin + flag_agch <= 1'd0; + flag_agcl <= 1'd0; + end + end + + //查表地址 + if (agc_check <= 13'd11) addr_lut <= 11'd0; + else begin + if (agc_check >= 13'd2037) addr_lut <= 11'd2026; + else addr_lut <= agc_check[10:0] - 11'd11; + end + flag_ram_1 <= 1'd1; + flag_ram_2 <= 1'd0; + end + 4'd10: begin + if (framesync == 1'b1) begin + state_agc <= 4'd1; + agc_ref_temp <= {12'd0, Dout}; + cnt_4096_3 <= 12'd1; + cnt_databag <= 15'd1; + end + else begin + state_agc <= state_agc; + cnt_databag <= 15'd0; + cnt_4096_3 <= 12'd0; + flag_agc_power <= 1'd0; + agc_ref_temp <= agc_ref_temp; + case (vio_powertest_h) + 2'd0: agc_ref_h <= {2'd0, agc_ref} + {4'd0, agc_ref[12:2]}; + 2'd1: agc_ref_h <= {2'd0, agc_ref} + {3'd0, agc_ref[12:1]}; + 2'd2: agc_ref_h <= {1'd0, agc_ref, 1'd0}; + 2'd3: agc_ref_h <= {agc_ref, 2'd0}; + endcase + case (vio_powertest_l) + 2'd0: agc_ref_l <= agc_ref - {3'd0, agc_ref[12:3]}; + 2'd1: agc_ref_l <= agc_ref - {2'd0, agc_ref[12:2]}; + 2'd2: agc_ref_l <= {1'd0, agc_ref[12:1]}; + 2'd3: agc_ref_l <= {2'd0, agc_ref[12:2]}; + endcase + + //查表地址 + if (agc_check <= 13'd11) addr_lut <= 11'd0; + else begin + if (agc_check >= 13'd2037) addr_lut <= 11'd2026; + else addr_lut <= agc_check[10:0] - 11'd11; + end + flag_ram_1 <= 1'd1; + flag_ram_2 <= 1'd0; + rd_en <= 1'b1; + mgc_rdy_d0 <= 1'b1; + end + end + endcase + end + end + + reg [13:0] agcdata0 = 14'd0; + reg [13:0] agcdata1 = 14'd0; + always @(posedge clk) begin + agcdata0 <= dout_lut; + agcdata1 <= agcdata0; + end + //-------------------------------------补偿用的乘法器----------------------------// + wire [23:0] mulout_i; + DAGC_mul_10bit12 DAGC_mul_10bit12_i ( + .CLK(clk), // input clk + .A (mf_i), // input [9 : 0] a + .B (agcdata0), // input [13 : 0] b + .P (mulout_i) // output [23 : 0] p + ); + + wire [23:0] mulout_q; + DAGC_mul_10bit12 DAGC_mul_10bit12_q ( + .CLK(clk), // input clk + .A (mf_q), // input [9 : 0] a + .B (agcdata0), // input [13 : 0] b + .P (mulout_q) // output [23 : 0] p + ); + + + always @(posedge clk) begin + if (mulout_i[23:17] == 7'b111_1111 || mulout_i[23:17] == 7'b000_0000) DAGC_out_i <= mulout_i[17:8]; + else DAGC_out_i <= (mulout_i[23]) ? 10'b1000_0000_01 : 10'b0111_1111_11; + + if (mulout_q[23:17] == 7'b111_1111 || mulout_q[23:17] == 7'b000_0000) DAGC_out_q <= mulout_q[17:8]; + else DAGC_out_q <= (mulout_q[23]) ? 10'b1000_0000_01 : 10'b0111_1111_11; + end + + /*ila_dagc ila_dagc( + .clk(clk), + .probe0(mgc1_rdy), + .probe1(empty), + .probe2(full), + .probe3(rd_en), + .probe4(DAGC_out_i), + .probe5(DAGC_out_q), + .probe6(state_agc), + .probe7(dagc_rdy), + .probe8(mgc_rdy), + .probe9(data_count) + + );*/ + + reg [19:0] cnt_rst = 20'd0; + always @(posedge clk) begin + if (dagc_rdy_d0 && !dagc_rdy_d1) begin + cnt_rst <= 20'd0; + rst_dagc <= 1'b0; + end + else begin + if (cnt_rst == 20'd580620) begin + rst_dagc <= 1'b1; + cnt_rst <= cnt_rst + 20'd1; + end + else if (cnt_rst == 20'd580621) begin + rst_dagc <= 1'b0; + cnt_rst <= cnt_rst; + end + else begin + cnt_rst <= cnt_rst + 20'd1; + rst_dagc <= 1'b0; + end + end + end + + + +endmodule diff --git a/hdl/DDS_compensate.v b/hdl/DDS_compensate.v new file mode 100644 index 0000000..af305eb --- /dev/null +++ b/hdl/DDS_compensate.v @@ -0,0 +1,211 @@ +`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 diff --git a/hdl/IQmerge.v b/hdl/IQmerge.v new file mode 100644 index 0000000..c566492 --- /dev/null +++ b/hdl/IQmerge.v @@ -0,0 +1,149 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 16:01:14 07/21/2018 +// Design Name: +// Module Name: IQmerge +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module IQmerge( + input clk, + input clk2, + input rst, + input nd, + input framesync, + input [9:0] dini, + input [9:0] dinq, + + output reg rdy = 1'b0, + output reg ldpcsyncin = 1'b0, + output [7:0] dout + ); + + + + + + reg [9:0] addra = 10'd0; + reg [15:0] dina = 16'd0; + reg [10:0] addrb = 11'd0; + RAM_IQmerge RAM_IQmerge ( + .clka(clk), // input clka + .wea(1'b1), // input [0 : 0] wea + .addra(addra), // input [9 : 0] addra + .dina(dina), // input [15 : 0] dina + .clkb(clk2), // input clkb + .addrb(addrb), // input [10 : 0] addrb + .doutb(dout) // output [7 : 0] doutb + ); + + + + + reg [9:0] addradelay = 10'd0; + reg [8:0] bagcount = 9'd0; + reg [1:0] writevalid = 2'd0; + always @(posedge clk)begin + if(rst)begin + addra <= 10'd0; + addradelay <= 10'd0; + dina <= 16'd0; + writevalid <= 2'd0; + bagcount <= 9'd0; + end else begin + case(writevalid) + 2'd0:begin + if(framesync)begin + writevalid <= 2'd1; + end else begin + writevalid <= 2'd0; + end + bagcount <= 9'd0; + end + 2'd1:begin + if(nd)begin + addradelay <= addradelay + 10'd1; + dina <= {dinq[9:2],dini[9:2]}; + addra <= addradelay; + if(addradelay == 10'd1023)begin + writevalid <= 2'd2; + end else begin + writevalid <= 2'd1; + end + end else begin + addradelay <= addradelay; + addra <= addra; + dina <= dina; + writevalid <= 2'd1; + end + end + 2'd2:begin + bagcount <= bagcount + 9'd1; + if(bagcount == 9'd104)begin + writevalid <= 2'd0; + end else begin + writevalid <= 2'd1; + end + end + default:writevalid <= 2'd0; + endcase + end + end + + reg readvalid = 1'b0; + always @(posedge clk2)begin + if(rst)begin + addrb <= 11'd0; + readvalid <= 1'b0; + ldpcsyncin <= 1'b0; + end else begin + if(!readvalid)begin + addrb <= 11'd0; + if(addra == 10'd1000)begin + ldpcsyncin <= 1'b1; + readvalid <= 1'b1; + end else begin + ldpcsyncin <= 1'b0; + readvalid <= 1'b0; + end + end else begin + ldpcsyncin <= 1'b0; + addrb <= addrb + 11'd1; + if(addrb == 11'd2047)begin + readvalid <= 1'b0; + end else begin + readvalid <= 1'b1; + end + end + end + end + + + always @(posedge clk2)begin + rdy <= readvalid; + end + + /*ila_IQmerge ila_IQmerge( + .clk(clk2), + .probe0(clk), + .probe1(writevalid), + .probe2(dini[9:2]), + .probe3(dinq[9:2]), + .probe4(dout), + .probe5(framesync) + );*/ + + +endmodule diff --git a/hdl/Interp_half.v b/hdl/Interp_half.v new file mode 100644 index 0000000..59954d4 --- /dev/null +++ b/hdl/Interp_half.v @@ -0,0 +1,71 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/18 21:06:38 +// Design Name: +// Module Name: Interp_half +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module Interp_half( + input clk, + input [9:0] din_p1, + input [9:0] din_t0, + input [9:0] din_n1, + input [9:0] din_n2, + + output reg [9:0] dout + + ); + + wire [13:0] multquartert0; + wire [13:0] multquartern1; + CN1_half CT0_half (.CLK(clk), .A(din_t0), .P(multquartert0)); + CN1_half CN1_half (.CLK(clk), .A(din_n1), .P(multquartern1)); + + reg [9:0] multquarterp1 = 10'd0; + reg [9:0] multquartern2 = 10'd0; + always @(posedge clk)begin + multquarterp1 <= din_p1; + multquartern2 <= din_n2; + end + + reg [14:0] sumquarter1 = 15'd0; + reg [14:0] sumquarter2 = 15'd0; + always @(posedge clk)begin + sumquarter1 <= {multquartert0[13],multquartert0}-{{5{multquarterp1[9]}},multquarterp1}; + sumquarter2 <= {multquartern1[13],multquartern1}-{{5{multquartern2[9]}},multquartern2}; + end + + + reg [15:0] sumquarter3 = 16'd0; + always @(posedge clk)begin + sumquarter3 <= {sumquarter2[14],sumquarter2}+{sumquarter1[14],sumquarter1}; + end + + + always @(posedge clk)begin + if(sumquarter3[15:13]==3'b111||sumquarter3[15:13]==3'b000)begin + dout <= sumquarter3[13:4]; + end else begin + dout <= (sumquarter3[15]==1'b1) ? 10'b10_0000_0000 : 10'b01_1111_1111; + end + end + + + +endmodule + diff --git a/hdl/Interp_quarter.v b/hdl/Interp_quarter.v new file mode 100644 index 0000000..e8af439 --- /dev/null +++ b/hdl/Interp_quarter.v @@ -0,0 +1,69 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/18 21:06:38 +// Design Name: +// Module Name: Interp_quarter +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module Interp_quarter( + input clk, + input [9:0] din_p1, + input [9:0] din_t0, + input [9:0] din_n1, + input [9:0] din_n2, + + output reg [9:0] dout + + ); + + wire [13:0] multquartern2; + wire [15:0] multquartern1; + wire [16:0] multquartert0; + wire [13:0] multquarterp1; + CN2 CN2_quarter (.CLK(clk), .A(din_p1), .P(multquartern2)); + CN1 CN1_quarter (.CLK(clk), .A(din_t0), .P(multquartern1)); + CT0 CT0_quarter (.CLK(clk), .A(din_n1), .P(multquartert0)); + CP1 CP1_quarter (.CLK(clk), .A(din_n2), .P(multquarterp1)); + + + + reg [16:0] sumquarter1 = 17'd0; + reg [17:0] sumquarter2 = 18'd0; + always @(posedge clk)begin + sumquarter1 <= {{3{multquartern2[13]}},multquartern2}+{multquartern1[15],multquartern1}; + sumquarter2 <= {{4{multquarterp1[13]}},multquarterp1}+{multquartert0[16],multquartert0}; + end + + + reg [18:0] sumquarter3 = 19'd0; + always @(posedge clk)begin + sumquarter3 <= {{2{sumquarter1[16]}},sumquarter1}+{sumquarter2[17],sumquarter2}; + end + + + always @(posedge clk)begin + if(sumquarter3[18:16]==3'b111||sumquarter3[18:16]==3'b000)begin + dout <= sumquarter3[16:7]; + end else begin + dout <= (sumquarter3[18]==1'b1) ? 10'b10_0000_0000 : 10'b01_1111_1111; + end + end + + +endmodule + diff --git a/hdl/Interpolation.v b/hdl/Interpolation.v new file mode 100644 index 0000000..138ecd2 --- /dev/null +++ b/hdl/Interpolation.v @@ -0,0 +1,100 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/18 21:03:55 +// Design Name: +// Module Name: Interpolation +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +module Interpolation( + input clk, + input [9:0] dini, + input [9:0] dinq, + + input framesync, + output reg framesync_Interpolation = 1'd0, + + output reg [9:0] doutiA = 10'd0, + output reg [9:0] doutqA = 10'd0, + output [9:0] doutiB, + output [9:0] doutqB, + output [9:0] doutiC, + output [9:0] doutqC, + output [9:0] doutiD, + output [9:0] doutqD + ); + + reg [9:0] dini_p1 = 10'd0; + reg [9:0] dini_t0 = 10'd0; + reg [9:0] dini_n1 = 10'd0; + reg [9:0] dini_n2 = 10'd0; + reg [9:0] dini_n3 = 10'd0; + reg [9:0] dini_n4 = 10'd0; + + + reg [9:0] dinq_p1 = 10'd0; + reg [9:0] dinq_t0 = 10'd0; + reg [9:0] dinq_n1 = 10'd0; + reg [9:0] dinq_n2 = 10'd0; + reg [9:0] dinq_n3 = 10'd0; + reg [9:0] dinq_n4 = 10'd0; + + reg [0:0] framesync_p1 = 1'd0; + reg [0:0] framesync_t0 = 1'd0; + reg [0:0] framesync_n1 = 1'd0; + reg [0:0] framesync_n2 = 1'd0; + reg [0:0] framesync_n3 = 1'd0; + reg [0:0] framesync_n4 = 1'd0; + + always @(posedge clk)begin + dini_p1 <= dini; + dini_t0 <= dini_p1; + dini_n1 <= dini_t0; + dini_n2 <= dini_n1; + dini_n3 <= dini_n2; + dini_n4 <= dini_n3; + doutiA <= dini_n4; + + dinq_p1 <= dinq; + dinq_t0 <= dinq_p1; + dinq_n1 <= dinq_t0; + dinq_n2 <= dinq_n1; + dinq_n3 <= dinq_n2; + dinq_n4 <= dinq_n3; + doutqA <= dinq_n4; + + framesync_p1 <= framesync; + framesync_t0 <= framesync_p1; + framesync_n1 <= framesync_t0; + framesync_n2 <= framesync_n1; + framesync_n3 <= framesync_n2; + framesync_n4 <= framesync_n3; + framesync_Interpolation <= framesync_n4; + end + + + + Interp_quarter Interp_quarteri (.clk(clk), .din_p1(dini_p1), .din_t0(dini_t0), .din_n1(dini_n1), .din_n2(dini_n2), .dout(doutiB)); + Interp_quarter Interp_quarterq (.clk(clk), .din_p1(dinq_p1), .din_t0(dinq_t0), .din_n1(dinq_n1), .din_n2(dinq_n2), .dout(doutqB)); + + Interp_half Interp_halfi (.clk(clk), .din_p1(dini_p1), .din_t0(dini_t0), .din_n1(dini_n1), .din_n2(dini_n2), .dout(doutiC)); + Interp_half Interp_halfq (.clk(clk), .din_p1(dinq_p1), .din_t0(dinq_t0), .din_n1(dinq_n1), .din_n2(dinq_n2), .dout(doutqC)); + + Interp_quarter Interp_quarteri3 (.clk(clk), .din_p1(dini_n2), .din_t0(dini_n1), .din_n1(dini_t0), .din_n2(dini_p1), .dout(doutiD)); + Interp_quarter Interp_quarterq3 (.clk(clk), .din_p1(dinq_n2), .din_t0(dinq_n1), .din_n1(dinq_t0), .din_n2(dinq_p1), .dout(doutqD)); + +endmodule + diff --git a/hdl/Noise_Estimate.v b/hdl/Noise_Estimate.v new file mode 100644 index 0000000..8bcdcb0 --- /dev/null +++ b/hdl/Noise_Estimate.v @@ -0,0 +1,187 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/12/20 15:37:19 +// Design Name: +// Module Name: Noise_Estimate +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module Noise_Estimate( + input clk, + input rst, + + input nd_pilot2, + input [9:0] pilot_noisei, + input [9:0] pilot_noiseq, + + output reg nd_EstNoise = 1'd0, + output reg [27:0] EstNoise_i = 28'd0, + output reg [27:0] EstNoise_q = 28'd0 //应当为0 + + ); + + //----------------------------------------共轭相乘,延时为6clk-----------------------------------// + reg [9:0] noisei = 10'd0; + reg [9:0] noiseq = 10'd0; + reg [9:0] noiseqh = 10'd0; + reg nd_noise_d0 = 1'd0; + reg nd_noise_d1 = 1'd0; + reg nd_noise_d2 = 1'd0; + reg nd_noise_d3 = 1'd0; + reg nd_noise_d4 = 1'd0; + reg nd_noise_d5 = 1'd0; + reg nd_noise_d6 = 1'd0; + always @(posedge clk)begin + if(rst)begin + noisei <= 10'd0; + noiseq <= 10'd0; + noiseqh <= 10'd0; + nd_noise_d0 <= 1'd0; + nd_noise_d1 <= 1'd0; + nd_noise_d2 <= 1'd0; + nd_noise_d3 <= 1'd0; + nd_noise_d4 <= 1'd0; + nd_noise_d5 <= 1'd0; + nd_noise_d6 <= 1'd0; + end + else begin + noisei <= pilot_noisei; + noiseq <= pilot_noiseq; + if(pilot_noiseq==10'd512) noiseqh <= 10'd511; + else noiseqh <= -pilot_noiseq; + nd_noise_d0 <= nd_pilot2; + nd_noise_d1 <= nd_noise_d0; + nd_noise_d2 <= nd_noise_d1; + nd_noise_d3 <= nd_noise_d2; + nd_noise_d4 <= nd_noise_d3; + nd_noise_d5 <= nd_noise_d4; + nd_noise_d6 <= nd_noise_d5; + end + end + + + wire m_axis_dout_tvalid; + wire [47:0] m_axis_dout_tdata; + ComMul_EstNoise ComMul_EstNoise ( + .aclk (clk), // input wire aclk + .s_axis_a_tvalid (1'd1), // input wire s_axis_a_tvalid + .s_axis_a_tdata ({6'd0,noiseq,6'd0,noisei}), // input wire [31 : 0] s_axis_a_tdata + .s_axis_b_tvalid (1'd1), // input wire s_axis_b_tvalid + .s_axis_b_tdata ({6'd0,noiseqh,6'd0,noisei}), // input wire [31 : 0] s_axis_b_tdata + .m_axis_dout_tvalid (m_axis_dout_tvalid), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata (m_axis_dout_tdata) // output wire [47 : 0] m_axis_dout_tdata + ); + + wire [19:0] ComMul_Noisei; + wire [19:0] ComMul_Noiseq; + + assign ComMul_Noiseq = m_axis_dout_tdata[43:24]; + assign ComMul_Noisei = m_axis_dout_tdata[19:0]; + + + //--------------------------------------------累加求和,状态机控制----------------------------------------// + reg state_noise = 1'd0; + reg [27:0] add_Noisei = 28'd0; + reg [27:0] add_Noiseq = 28'd0; + + always @(posedge clk)begin + if(rst)begin + add_Noisei <= 28'd0; + add_Noiseq <= 28'd0; + nd_EstNoise <= 1'd0; + EstNoise_i <= 28'd0; + EstNoise_q <= 28'd0; + state_noise <= 1'd0; + end + else begin + case(state_noise) + //帧间复位结束后,等待nd_noise_d6拉高,拉高持续256clk,期间数据全部累加 + //nd_noise_d6拉低说明256clk的累加结束,给一次噪声估计结果,伴随nd + 1'd0:begin + if(nd_noise_d6) begin + add_Noisei <= {{8{ComMul_Noisei[19]}},ComMul_Noisei}; + add_Noiseq <= {{8{ComMul_Noiseq[19]}},ComMul_Noiseq}; + nd_EstNoise <= 1'd0; + EstNoise_i <= EstNoise_i; + EstNoise_q <= EstNoise_q; + state_noise <= state_noise + 1'd1; + end + else begin + add_Noisei <= 28'd0; + add_Noiseq <= 28'd0; + nd_EstNoise <= 1'd0; + EstNoise_i <= EstNoise_i; + EstNoise_q <= EstNoise_q; + state_noise <= state_noise; + end + end + 1'd1:begin + if(nd_noise_d6==1'd0) begin + add_Noisei <= add_Noisei; + add_Noiseq <= add_Noiseq; + nd_EstNoise <= 1'd1; + EstNoise_i <= add_Noisei; + EstNoise_q <= add_Noiseq; + state_noise <= 1'd0; + end + else begin + add_Noisei <= add_Noisei + {{8{ComMul_Noisei[19]}},ComMul_Noisei}; + add_Noiseq <= add_Noiseq + {{8{ComMul_Noiseq[19]}},ComMul_Noiseq}; + nd_EstNoise <= 1'd0; + EstNoise_i <= EstNoise_i; + EstNoise_q <= EstNoise_q; + state_noise <= state_noise; + end + + end + endcase + end + end + + + //----------------------------------------除data_length=256,再乘2-----------------------------------// + //----------------------------------------除49,再除2-----------------------------------// + //根据量化方案,此处不再做除法,相当于噪声估计结果放大了256*49倍 + //FullSystem_v5.m + + // integer handle01; + // integer handle02; + // integer handle03; + // integer handle04; + + // reg enable1 = 0; + // initial begin + // handle01=$fopen("ComMul_Noisei.txt","w"); $fclose(handle01); + // handle02=$fopen("ComMul_Noiseq.txt","w"); $fclose(handle02); + + + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + // if(nd_noise_d6)begin + // handle01=$fopen("ComMul_Noisei.txt","a+");$fwrite(handle01,"%d\n",$signed(ComMul_Noisei));$fclose(handle01); + // handle02=$fopen("ComMul_Noiseq.txt","a+");$fwrite(handle02,"%d\n",$signed(ComMul_Noiseq));$fclose(handle02); + // end + // end + // end + + +endmodule diff --git a/hdl/RecvTop.v b/hdl/RecvTop.v new file mode 100644 index 0000000..ac72c0b --- /dev/null +++ b/hdl/RecvTop.v @@ -0,0 +1,550 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 17:42 11/14/2019 +// Design Name: +// Module Name: RecvTop +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module RecvTop ( + input clk, + input clk2, + input clk_60M_mac, + input rst, + input rst2, + + input [11:0] dini, + input [11:0] dinq, + + //视频数据存储,shx + input [13:0] recv_addr_new_0, + input [13:0] recv_addr_new_1, + input [13:0] recv_addr_new_2, + input [13:0] recv_addr_new_3, + output [ 7:0] recv_data_new_0, + output [ 7:0] recv_data_new_1, + output [ 7:0] recv_data_new_2, + output [ 7:0] recv_data_new_3, + output [16:0] RAMaddra_write_0, + output [16:0] RAMaddra_write_1, + output [16:0] RAMaddra_write_2, + output [16:0] RAMaddra_write_3, + output [16:0] RAMaddra_new_0, + output [16:0] RAMaddra_new_1, + output [16:0] RAMaddra_new_2, + output [16:0] RAMaddra_new_3, + output flag_stop, //给shx,拉高8个clk表示当前时帧有效数据接收完毕 + output [16:0] addr_stop, //给shx,拉高8个clk,与flag_stop对齐,指示位置与最后1bit有效数据的位置对齐 + + //vio + // input DC_move_able, //为1的时候启用去直流,为0的时候不启用 + // input [1:0] vio_powertest_h, //DAGC + // input [1:0] vio_powertest_l, //DAGC + // input DAGC_enab, //为1的时候启用DAGC,为0的时候不启用DAGC + // input vio_tsync_inter16, //为1的时候启用内插,从16倍过采样中挑一路 + // input EQUenable_vio, //为1时启用均衡 + // input [7:0] Zerozone_vio, //零域估计,默认值为8'd29 + input [6:0] vio_stopbit, //寻找停止位,默认值为7'd60 + + //9361、射频增益控制 + output [7:0] data_9361, + output [9:0] addr_9361, + output enab_9361, + output D1_12dB, + output D2_6dB, + output D3_18dB, + output D4_12dB, + + //debug + //trigger + output rst_TimeSync, + output rst_freq, + output DAGC_rdy, + output framesync, //帧同步峰 + output framesync_delay, //帧同步峰,与频率补偿输出对应 + output framesync_tsync, //帧同步标志,与TSync输出对应 + output IntpARdy, //TSync输出nd + output nd_SC_FDE_dout, //SC_FDE输出nd + output framerdy, //一帧译码结果存储完毕标志 + output reg flag_bercount = 1'd0, + output reg flag_badframe = 1'd0, + output reg flag_ber = 1'd0, + //各模块输出,星座图 + output [11:0] dc_removal_dout_i, //MGC_adaptation、去直流输出 + output [11:0] dc_removal_dout_q, + output [ 9:0] matchfilterout_i, //MF输出 + output [ 9:0] matchfilterout_q, + output [ 9:0] DAGC_out_i, //DAGC输出 + output [ 9:0] DAGC_out_q, + output [ 9:0] freqdataout_i, //频率补偿输出 + output [ 9:0] freqdataout_q, + output [ 9:0] IntpOuti, //TSync输出 + output [ 9:0] IntpOutq, + output [ 9:0] SC_FDE_douti, //SC_FDE输出 + output [ 9:0] SC_FDE_doutq, + //MGC_adaptation + output [24:0] mean_temp, + output [12:0] acc_mean, + output [ 4:0] state_mgc, + output mgc1_rdy, + output flag_state_mgc, + output [ 2:0] state_rst, + output flag_overflow, + output flag_small, + //DC + output [11:0] dc_value_i, + output [11:0] dc_value_q, + output flag_dc, + //DAGC + output flag_agch, + output flag_agcl, + output flag_agc_power, + output [12:0] agc_ref, + output [12:0] agc_check, + //power test + output flag_powerabsh, + output flag_powerabsl, + output flag_abs_power, + output [10:0] abs_ref, + output [10:0] abs_check, + //TSync + output [ 3:0] flag_clk_4bit, //位同步选取通道结果 + //SC_FDE,溢出标志 + output flagoverflow_fftpilot_26to14, //第1个fft结果截位,即导频fft结果的截位,26截到14 + output flagoverflow_ChnZF_26to18, //第2个fft结果截位,即ZF信道估计结果的截位,26截到18 + output flagoverflow_comdiv_34to20i, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到18 + output flagoverflow_comdiv_34to20q, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到18 + output flagoverflow_ifftzero_29to17i, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output flagoverflow_ifftzero_29to17q, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output flagoverflow_MMSEdiv_divisor_31to28, //第2个除法器,即MMSE除法的分母截位,31截到28 + output flagoverflow_divmmse_34to11, //第2个除法器结果截位,即MMSE信道估计结果的截位,34截到11 + output flagoverflow_ifftindata_28to20i, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output flagoverflow_ifftindata_28to20q, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output flagoverflow_fftdata_26to16i, //数据段ow的fft输出截位,26截到16 + output flagoverflow_fftdata_26to16q, //数据段ow的fft输出截位,26截到16 + output flagoverflow_FDE_dataout_29to10i, //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + output flagoverflow_FDE_dataout_29to10q, //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + output reg flagoverflow = 1'd0, //总溢出标志 + output Pilot_rdy_hide1_d1, + + + + + + output [63:0] recvNetData, + output recvNetDataNd, + input debug_loss + // input [ 7:0] MAC_idNum + // input [ 7:0] video_id01, + // input [ 7:0] video_id02, + // input [ 7:0] video_id03 + +); + + + + MGC_adaptation MGC_adaptation ( + .clk (clk), + .rst (rst), + .dini(dini), + .dinq(dinq), + + .data_9361(data_9361), + .addr_9361(addr_9361), + .enab_9361(enab_9361), + .D1_12dB (D1_12dB), + .D2_6dB (D2_6dB), + .D3_18dB (D3_18dB), + .D4_12dB (D4_12dB), + + .mgc1_rdy(mgc1_rdy) + ); + + + wire MF_rdy; + wire MF_rst; + + + + MF_Top MF_Top ( + .clk(clk), + .rst(rst), + // .rst (rst), + + .dini (dini), + .dinq (dinq), + .start(mgc1_rdy), + + .matchfilterout_i(matchfilterout_i), + .matchfilterout_q(matchfilterout_q), + .MF_rdy (MF_rdy), + .MF_rst (MF_rst) + ); + + + + + + //帧同步模块 + + assign FrameSync_dini = (DAGC_enab) ? DAGC_out_i : matchfilterout_i; + assign FrameSync_dinq = (DAGC_enab) ? DAGC_out_q : matchfilterout_q; + // wire framesync; + wire Sync_rdy; + wire Pilot_rdy; + + wire [9:0] FrameSync_douti; + wire [9:0] FrameSync_doutq; + + + SCFDE_recv_FrameSync SCFDE_recv_FrameSync_inst ( + .clk (clk), + .rst (MF_rst), + .rst_ready (~MF_rdy), + .datain_i (matchfilterout_i), + .datain_q (matchfilterout_q), + .Sync_i (FrameSync_douti), + .Sync_q (FrameSync_doutq), + .Sync_rdy (Sync_rdy), // 帧同步找到了过门限峰值 + .Pilot_rdy (Pilot_rdy),// 开始取导频的标志位 not used + .flag_sync (framesync), // high level flag + .Pilot_rdy_hide1_d1(Pilot_rdy_hide1_d1) // not used + ); + + // + reg [20:0] cnt_lost; + reg framelost; + always @(posedge clk) begin + if (Pilot_rdy_hide1_d1) begin + cnt_lost <= 21'd0; + framelost <= 1'b0; + end else begin + if (cnt_lost >= 21'd750000) begin + ; + cnt_lost <= 21'd0; + framelost <= 1'b1; + end else begin + cnt_lost <= 21'd1 + cnt_lost; + framelost <= 1'b0; + end + end + end + // wire [9:0] DAGC_out_i; + // wire [9:0] DAGC_out_q; + // wire flag_agch; + // wire flag_agcl; + // wire flag_agc_power; + // wire [12:0] agc_ref; + // wire [12:0] agc_check; + wire dagc_rdy; + wire mgc_rdy; + wire rst_dagc; + DAGC_v2 DAGC_v2 ( + .clk (clk), + .rst (~mgc1_rdy), + .mgc1_rdy (MF_rdy), + .framesync_d0 (framesync), + .vio_powertest_h (2'b00), + .vio_powertest_l (2'b00), + .matchfilterout_i(FrameSync_douti), + .matchfilterout_q(FrameSync_doutq), + + .DAGC_out_i(DAGC_out_i), + .DAGC_out_q(DAGC_out_q), + + .flag_agch (flag_agch), + .flag_agcl (flag_agcl), + .flag_agc_power(flag_agc_power), + .agc_ref (agc_ref), + .agc_check (agc_check), + .dagc_rdy (dagc_rdy), + .mgc_rdy (mgc_rdy), + .rst_dagc (rst_dagc) + ); + + + //载波频偏补偿 + // wire [9:0] freqdataout_i; + // wire [9:0] freqdataout_q; + // wire framesync_delay; + wire data_save; //debug用,暂不需使用 + // wire rst_freq; + + freqestm freqestm ( + .clk (clk), + .rst (MF_rst), + .mgc_rdy (mgc_rdy), + .framesync (dagc_rdy), + .datain_i (DAGC_out_i), + .datain_q (DAGC_out_q), + .dataout_i (freqdataout_i), + .dataout_q (freqdataout_q), + .framesync_delay(framesync_delay), + .data_save (data_save), + .rst_freq (rst_freq) + + ); + + //位同步 + wire [1:0] cnt_tsync; + // wire framesync_tsync; //帧同步标志 + TimeSync_top TimeSync_top ( + .clk (clk), + .rst (Pilot_rdy_hide1_d1), + .dini (freqdataout_i), + .dinq (freqdataout_q), + .rdy (IntpARdy), + .douti (IntpOuti), + .doutq (IntpOutq), + .vio_tsync_inter16(vio_tsync_inter16), + .framesync (framesync_delay), //帧同步标志 + .framesync_tsync (framesync_tsync), //帧同步标志 + //debug + .cnt_tsync (cnt_tsync), + .flag_clk_4bit (flag_clk_4bit) + ); + + + + + + // SC-FDE + + SC_FDE_TOP SC_FDE_TOP_djy ( + .clk(clk), + .rst(Pilot_rdy_hide1_d1), + + .EQUenable_vio(EQUenable_vio), //为1时启用均衡 + .Zerozone_vio (Zerozone_vio), //零域估计,默认值为8'd29 + + .flag_ow_left (framesync_tsync), //在一帧内,与第一个数据段的pilot的ow第一个nd对齐 + .nd (IntpARdy), + .dini (IntpOuti), + .dinq (IntpOutq), + .nd_SC_FDE_dout (nd_SC_FDE_dout), + .SC_FDE_douti (SC_FDE_douti), + .SC_FDE_doutq (SC_FDE_doutq), + // debug,溢出标志 + .flagoverflow_fftpilot_26to14 (flagoverflow_fftpilot_26to14), + .flagoverflow_ChnZF_26to18 (flagoverflow_ChnZF_26to18), + .flagoverflow_comdiv_34to20i (flagoverflow_comdiv_34to20i), + .flagoverflow_comdiv_34to20q (flagoverflow_comdiv_34to20q), + .flagoverflow_ifftzero_29to17i (flagoverflow_ifftzero_29to17i), + .flagoverflow_ifftzero_29to17q (flagoverflow_ifftzero_29to17q), + .flagoverflow_MMSEdiv_divisor_31to28(flagoverflow_MMSEdiv_divisor_31to28), + .flagoverflow_divmmse_34to11 (flagoverflow_divmmse_34to11), + .flagoverflow_ifftindata_28to20i (flagoverflow_ifftindata_28to20i), + .flagoverflow_ifftindata_28to20q (flagoverflow_ifftindata_28to20q), + .flagoverflow_fftdata_26to16i (flagoverflow_fftdata_26to16i), + .flagoverflow_fftdata_26to16q (flagoverflow_fftdata_26to16q), + .flagoverflow_FDE_dataout_29to10i (flagoverflow_FDE_dataout_29to10i), + .flagoverflow_FDE_dataout_29to10q (flagoverflow_FDE_dataout_29to10q) + ); + + + wire phase_adjust_rdy; + wire [9:0] phase_adjust_douti; + wire [9:0] phase_adjust_doutq; + phase_adjust phase_adjust ( + .clk (clk), + .rst (Pilot_rdy_hide1_d1), + .din_i (SC_FDE_douti), + .din_q (SC_FDE_doutq), + .nd (nd_SC_FDE_dout), + .framesync(framesync_tsync), + .rdy (phase_adjust_rdy), + .dout_i (phase_adjust_douti), + .dout_q (phase_adjust_doutq) + ); + + wire IQmergerdy; + wire ldpcsyncin; + wire [7:0] IQmergedout; + + IQmerge IQmerge ( + .clk (clk), + .clk2 (clk2), + .rst (rst2 || Pilot_rdy_hide1_d1), + .nd (phase_adjust_rdy), + .framesync (framesync_tsync), + .dini (phase_adjust_douti), + .dinq (phase_adjust_doutq), + .rdy (IQmergerdy), + .ldpcsyncin(ldpcsyncin), + .dout (IQmergedout) + ); + + wire LDPC_SyncOut; + wire LDPC_Rdy; + wire LDPC_Dout; + wire [8:0] good_frames; + wire [8:0] bad_frames; + wire [8:0] total_frames; + CCSDS_LDPC_DEC_K1024_R12_TOPP LDPC_decode ( + .clk (clk2), + .Rst (rst2 || Pilot_rdy_hide1_d1), + .FrameSync (ldpcsyncin), + .Nd (IQmergerdy), + .Din (IQmergedout), + .LDPC_SyncOut(LDPC_SyncOut), + .Rdy (LDPC_Rdy), + .LDPC_Dout (LDPC_Dout), + .good_frames (good_frames), + .bad_frames (bad_frames), + .total_frames(total_frames) + ); + + + + + + wire flag_notbyte; //为1时说明得到的有效数据不以字节为单位 + wire [ 1:0] state_ram; + wire berstart_1d; + wire bercompare; + wire [16:0] bercount; + wire [16:0] bercount_max; + wire [16:0] ROMaddra_d2; + wire RAMdout_d1; + wire validnd_new_new; + wire [63:0] stop_temp_new; + wire flag_stop_0; //给shx,拉高1个clk表示当前时帧有效数据接收完毕 + wire [16:0] addr_stop_0; + wire [ 2:0] cnt_8; + wire state_8; + wire rdy_scramble; + wire dout_scramble; + wire [16:0] RAMaddra; //比较误码率 + wire [16:0] ROMaddra; //比较误码率 + wire nd_ber; + + FrameMerge FrameMerge ( + .clk (clk2), + .rst (Pilot_rdy_hide1_d1), + .rst2(rst2), + .sync(LDPC_SyncOut), + .nd (LDPC_Rdy), + .din (LDPC_Dout), + + .vio_stopbit(vio_stopbit), + + .frameIDnd(Pilot_rdy_hide1_d1), + .clk2 (clk_60M_mac), + .framerdy (framerdy), + + .recv_addr_new_0 (recv_addr_new_0), + .recv_addr_new_1 (recv_addr_new_1), + .recv_addr_new_2 (recv_addr_new_2), + .recv_addr_new_3 (recv_addr_new_3), + .recv_data_new_0 (recv_data_new_0), + .recv_data_new_1 (recv_data_new_1), + .recv_data_new_2 (recv_data_new_2), + .recv_data_new_3 (recv_data_new_3), + .RAMaddra_write_0(RAMaddra_write_0), + .RAMaddra_write_1(RAMaddra_write_1), + .RAMaddra_write_2(RAMaddra_write_2), + .RAMaddra_write_3(RAMaddra_write_3), + .RAMaddra_new_0 (RAMaddra_new_0), + .RAMaddra_new_1 (RAMaddra_new_1), + .RAMaddra_new_2 (RAMaddra_new_2), + .RAMaddra_new_3 (RAMaddra_new_3), + + .flag_notbyte(flag_notbyte), + .state_ram (state_ram), + .flag_stop (flag_stop), //给shx,拉高8个clk表示当前时帧有效数据接收完毕 + .addr_stop (addr_stop), //给shx,拉高8个clk,与flag_stop对齐,指示位置与最后1bit有效数据的位置对齐 + //debug + .berstart_1d (berstart_1d), + .bercompare (bercompare), + .bercount (bercount), + .bercount_max(bercount_max), + .ROMaddra_d2 (ROMaddra_d2), + .RAMdout_d1 (RAMdout_d1), + + .validnd_new_new(validnd_new_new), + + .stop_temp_new(stop_temp_new), + + .flag_stop_0(flag_stop_0), + .addr_stop_0(addr_stop_0), + .cnt_8 (cnt_8), + .state_8 (state_8), + + .rdy_scramble (rdy_scramble), + .dout_scramble(dout_scramble), + + .RAMaddra (RAMaddra), + .ROMaddra (ROMaddra), + .nd_ber (nd_ber), + .recvNetData (recvNetData), + .recvNetDataNd(recvNetDataNd) + // .MAC_idNum (MAC_idNum) + // .video_id01 (8'd0), + // .video_id02 (8'd0), + // .video_id03 (8'd0) + ); + + + + + /*ila_recvtop ila_recvtop( + .clk(clk), + .probe0(framesync), + .probe1(framesync_delay), + .probe2(phase_adjust_rdy), + .probe3(nd_SC_FDE_dout), + .probe4(IQmergerdy), + .probe5(IQmergedout), + .probe6(LDPC_Rdy), + .probe7(LDPC_Dout), + .probe8(SC_FDE_douti), + .probe9(SC_FDE_doutq), + .probe10(total_frames), + .probe11(good_frames), + .probe12(dini), + .probe13(dinq), + .probe14(phase_adjust_douti), + .probe15(phase_adjust_doutq), + .probe16(D1_12dB), + .probe17(D2_6dB), + .probe18(D3_18dB), + .probe19(D4_12dB) + +);*/ + ila_recvtest ila_recvtest ( + .clk (clk), + .probe0(framesync), + .probe1(framesync_delay), + .probe2(D1_12dB), + .probe3(D2_6dB), + .probe4(D3_18dB), + .probe5(D4_12dB), + .probe6(mgc1_rdy), + .probe7(rst), + .probe8(dini), + .probe9(dinq) + ); + /*ila_decode ila_decode( + .clk(clk2), + .probe0(IQmergerdy), + .probe1(IQmergedout), + .probe2(LDPC_Dout), + .probe3(LDPC_Rdy), + .probe4(framerdy), + .probe5(total_frames), + .probe6(good_frames) +);*/ + +endmodule diff --git a/hdl/SC_FDE_TOP.v b/hdl/SC_FDE_TOP.v new file mode 100644 index 0000000..dd453e9 --- /dev/null +++ b/hdl/SC_FDE_TOP.v @@ -0,0 +1,684 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/12/18 16:00:24 +// Design Name: +// Module Name: SC_FDE_TOP +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module SC_FDE_TOP( + input clk, + input rst, + + input EQUenable_vio, //为1时启用均衡 + + input [7:0] Zerozone_vio, //零域估计,默认值为8'd29 + + input flag_ow_left, //在一帧内,与第一个数据段的pilot的ow第一个nd对齐 + input nd, + input [9:0] dini, + input [9:0] dinq, + + output nd_SC_FDE_dout, + output [9:0] SC_FDE_douti, + output [9:0] SC_FDE_doutq, + + // debug,溢出标志 + output flagoverflow_fftpilot_26to14, //第1个fft结果截位,即导频fft结果的截位,26截到14 + output flagoverflow_ChnZF_26to18, //第2个fft结果截位,即ZF信道估计结果的截位,26截到18 + output flagoverflow_comdiv_34to20i, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到18 + output flagoverflow_comdiv_34to20q, //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到18 + output flagoverflow_ifftzero_29to17i, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output flagoverflow_ifftzero_29to17q, //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + output flagoverflow_MMSEdiv_divisor_31to28, //第2个除法器,即MMSE除法的分母截位,31截到28 + output flagoverflow_divmmse_34to11, //第2个除法器结果截位,即MMSE信道估计结果的截位,34截到11 + + output flagoverflow_ifftindata_28to20i, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output flagoverflow_ifftindata_28to20q, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output flagoverflow_fftdata_26to16i, //数据段ow的fft输出截位,26截到16 + output flagoverflow_fftdata_26to16q, //数据段ow的fft输出截位,26截到16 + output flagoverflow_FDE_dataout_29to10i, //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + output flagoverflow_FDE_dataout_29to10q //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + ); + + + + //-----------------------------------------导频和数据ow的缓存--------------------------------------------// + //----------------------还负责计算正负导频头的和与差。流水得到结果用于信道估计----------------------------// + //数据的fifo,4个 + wire [9:0] din_data1i; + wire [9:0] din_data1q; + wire wr_en_data1; + wire [9:0] din_data2i; + wire [9:0] din_data2q; + wire wr_en_data2; + wire flag_dataow; //拉高1clk,说明一段数据ow存储完毕,后端可开始连续读取 + wire flag_ChnEstFFT_done; //信道估计两次fft输入完毕后拉高1clk(Chn_Estimate给出) + //正负导频段的加减结果 + wire nd_pilot2; + wire [9:0] pilot_datai; + wire [9:0] pilot_dataq; + wire [9:0] pilot_noisei; + wire [9:0] pilot_noiseq; + + data_ow data_ow_djy ( + .clk (clk), + .rst (rst), + .flag_ow_left (flag_ow_left), + .nd (nd), + .dini (dini), + .dinq (dinq), + + .din_data1i (din_data1i), + .din_data1q (din_data1q), + .wr_en_data1 (wr_en_data1), + .din_data2i (din_data2i), + .din_data2q (din_data2q), + .wr_en_data2 (wr_en_data2), + .flag_dataow (flag_dataow), //拉高1clk,说明一段数据ow存储完毕,后端可开始连续读取 + + .nd_pilot2 (nd_pilot2), + .pilot_datai (pilot_datai), + .pilot_dataq (pilot_dataq), + .pilot_noisei (pilot_noisei), + .pilot_noiseq (pilot_noiseq) + ); + + + + + + + + //-------------------------------------------data数据ow的fifo,4个--------------------------------------------// + wire rd_en_data1; + wire [9:0] dout_data1i; + wire full_data1i; + wire empty_data1i; + fifo_ow256 fifo_data_ow1i ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_data1i), // input wire [9 : 0] din + .wr_en (wr_en_data1), // input wire wr_en + .rd_en (rd_en_data1), // input wire rd_en + .dout (dout_data1i), // output wire [9 : 0] dout + .full (full_data1i), // output wire full + .empty (empty_data1i) // output wire empty + ); + + wire [9:0] dout_data1q; + wire full_data1q; + wire empty_data1q; + fifo_ow256 fifo_data_ow1q ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_data1q), // input wire [9 : 0] din + .wr_en (wr_en_data1), // input wire wr_en + .rd_en (rd_en_data1), // input wire rd_en + .dout (dout_data1q), // output wire [9 : 0] dout + .full (full_data1q), // output wire full + .empty (empty_data1q) // output wire empty + ); + + wire rd_en_data2; + wire [9:0] dout_data2i; + wire full_data2i; + wire empty_data2i; + fifo_ow256 fifo_data_ow2i ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_data2i), // input wire [9 : 0] din + .wr_en (wr_en_data2), // input wire wr_en + .rd_en (rd_en_data2), // input wire rd_en + .dout (dout_data2i), // output wire [9 : 0] dout + .full (full_data2i), // output wire full + .empty (empty_data2i) // output wire empty + ); + + wire [9:0] dout_data2q; + wire full_data2q; + wire empty_data2q; + fifo_ow256 fifo_data_ow2q ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_data2q), // input wire [9 : 0] din + .wr_en (wr_en_data2), // input wire wr_en + .rd_en (rd_en_data2), // input wire rd_en + .dout (dout_data2q), // output wire [9 : 0] dout + .full (full_data2q), // output wire full + .empty (empty_data2q) // output wire empty + ); + + + + + + + + + //-----------------------------------------------------噪声估计--------------------------------------------------// + //--------------------------------------------噪声估计结果放大了256*49倍-----------------------------------------// + //噪声估计结果 + wire nd_EstNoise; + wire [27:0] EstNoise_i; + wire [27:0] EstNoise_q; + + Noise_Estimate Noise_Estimate_djy ( + .clk (clk), + .rst (rst), + + .nd_pilot2 (nd_pilot2), + .pilot_noisei (pilot_noisei), + .pilot_noiseq (pilot_noiseq), + + .nd_EstNoise (nd_EstNoise), + .EstNoise_i (EstNoise_i), + .EstNoise_q (EstNoise_q) + ); + + + + + + + + + //------------------------------------------fft核,及其输入输出控制器------------------------------------------// + reg fft_config_tvalid = 1'd0; + wire fft_config_tready; + reg [16:0] fft_in_i = 17'd0; + reg [16:0] fft_in_q = 17'd0; + reg fft_in_nd = 1'd0; + wire fft_in_tready; + wire[63:0] fft_out_tdata; + wire[25:0] fft_out_i; + wire[25:0] fft_out_q; + wire fft_out_nd; + wire[7:0] fft_index; + + assign fft_out_i = fft_out_tdata[25:0]; + assign fft_out_q = fft_out_tdata[57:32]; + + wire m_axis_data_tlast; + wire event_frame_started; + wire event_tlast_unexpected; + wire event_tlast_missing; + wire event_status_channel_halt; + wire event_data_in_channel_halt; + wire event_data_out_channel_halt; + + fft_256 fft_256 ( + .aclk (clk), // input wire aclk + .aresetn (~rst), // input wire aresetn低有效复位,每次帧结束后复位8clk,满足核要求 + .s_axis_config_tdata (8'd1), // input wire [7 : 0] s_axis_config_tdata + .s_axis_config_tvalid (fft_config_tvalid), // input wire s_axis_config_tvalid + .s_axis_config_tready (fft_config_tready), // output wire s_axis_config_tready + + .s_axis_data_tdata ({7'd0,fft_in_q,7'd0,fft_in_i}), // input wire [47 : 0] s_axis_data_tdata + .s_axis_data_tvalid (fft_in_nd), // input wire s_axis_data_tvalid + .s_axis_data_tready (fft_in_tready), // output wire s_axis_data_tready + .s_axis_data_tlast (1'd0), // input wire s_axis_data_tlastn不用给这个信号 + + .m_axis_data_tdata (fft_out_tdata), // output wire [63 : 0] m_axis_data_tdata + .m_axis_data_tuser (fft_index), // output wire [7 : 0] m_axis_data_tuser + .m_axis_data_tvalid (fft_out_nd), // output wire m_axis_data_tvalid + .m_axis_data_tready (1'd1), // input wire m_axis_data_tready + .m_axis_data_tlast (m_axis_data_tlast), // output wire m_axis_data_tlast + + .event_frame_started (event_frame_started), // output wire event_frame_started + .event_tlast_unexpected (event_tlast_unexpected), // output wire event_tlast_unexpected + .event_tlast_missing (event_tlast_missing), // output wire event_tlast_missing + .event_status_channel_halt (event_status_channel_halt), // output wire event_status_channel_halt + .event_data_in_channel_halt (event_data_in_channel_halt), // output wire event_data_in_channel_halt + .event_data_out_channel_halt (event_data_out_channel_halt) // output wire event_data_out_channel_halt + ); + + + reg [1:0] state_fft = 2'd0; + wire nd_pilotfft; + wire [16:0] fft_in_i_pilot; + wire [16:0] fft_in_q_pilot; + wire nd_datafft; + wire [16:0] fft_in_i_data; + wire [16:0] fft_in_q_data; + + always @(posedge clk)begin + if(rst)begin + fft_config_tvalid <= 1'd0; + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + state_fft <= 2'd0; + end + else begin + case(state_fft) + //帧间复位结束后,先等待fft_config_tvalid拉高,说明fft核允许配置,先写入一次fft配置 + 2'd0:begin + if(fft_config_tready) begin + fft_config_tvalid <= 1'd1; + fft_in_nd <= 1'd0; + state_fft <= state_fft + 2'd1; + end + else begin + fft_config_tvalid <= 1'd0; + fft_in_nd <= 1'd0; + state_fft <= state_fft; + end + end + //每帧一开始fft核输入交给信道估计模块,直到flag_ChnEstFFT_done到来,说明信道估计两次fft输入完毕(Chn_Estimate给出) + 2'd1:begin + fft_config_tvalid <= 1'd0; + if(flag_ChnEstFFT_done) begin + fft_in_i <= fft_in_i_data; + fft_in_q <= fft_in_q_data; + fft_in_nd <= nd_datafft; + state_fft <= state_fft + 2'd1; + end + else begin + fft_in_i <= fft_in_i_pilot; + fft_in_q <= fft_in_q_pilot; + fft_in_nd <= nd_pilotfft; + state_fft <= state_fft; + end + end + //nd_pilot2拉高,说明下一个征服导频头处理完毕,fft输入控制权交还信道估计模块 + 2'd2:begin + fft_config_tvalid <= 1'd0; + if(nd_pilot2) begin + fft_in_i <= fft_in_i_pilot; + fft_in_q <= fft_in_q_pilot; + fft_in_nd <= nd_pilotfft; + state_fft <= 2'd1; + end + else begin + fft_in_i <= fft_in_i_data; + fft_in_q <= fft_in_q_data; + fft_in_nd <= nd_datafft; + state_fft <= state_fft; + end + end + default:state_fft <= 2'd0; + endcase + end + end + + + + + + + + //------------------------------------------ifft核,及其输入输出控制器------------------------------------------// + reg ifft_config_tvalid = 1'd0; + wire ifft_config_tready; + reg [19:0] ifft_in_i = 20'd0; + reg [19:0] ifft_in_q = 20'd0; + reg ifft_in_nd = 1'd0; + wire ifft_in_tready; + wire[63:0] ifft_out_tdata; + wire[28:0] ifft_out_i; + wire[28:0] ifft_out_q; + wire ifft_out_nd; + wire[7:0] ifft_index; + + assign ifft_out_i = ifft_out_tdata[28:0]; + assign ifft_out_q = ifft_out_tdata[60:32]; + + wire m_axis_data_tlast_ifft; + wire event_frame_started_ifft; + wire event_tlast_unexpected_ifft; + wire event_tlast_missing_ifft; + wire event_status_channel_halt_ifft; + wire event_data_in_channel_halt_ifft; + wire event_data_out_channel_halt_ifft; + + ifft_256 ifft_256 ( + .aclk (clk), // input wire aclk + .aresetn (~rst), // input wire aresetn + + .s_axis_config_tdata (8'd0), // input wire [7 : 0] s_axis_config_tdata + .s_axis_config_tvalid (ifft_config_tvalid), // input wire s_axis_config_tvalid + .s_axis_config_tready (ifft_config_tready), // output wire s_axis_config_tready + + .s_axis_data_tdata ({4'd0,ifft_in_q,4'd0,ifft_in_i}), // input wire [47 : 0] s_axis_data_tdata + .s_axis_data_tvalid (ifft_in_nd), // input wire s_axis_data_tvalid + .s_axis_data_tready (ifft_in_tready), // output wire s_axis_data_tready + .s_axis_data_tlast (1'd0), // input wire s_axis_data_tlast + + .m_axis_data_tdata (ifft_out_tdata), // output wire [63 : 0] m_axis_data_tdata + .m_axis_data_tuser (ifft_index), // output wire [7 : 0] m_axis_data_tuser + .m_axis_data_tvalid (ifft_out_nd), // output wire m_axis_data_tvalid + .m_axis_data_tready (1'd1), // input wire m_axis_data_tready + .m_axis_data_tlast (m_axis_data_tlast_ifft), // output wire m_axis_data_tlast + + .event_frame_started (event_frame_started_ifft), // output wire event_frame_started + .event_tlast_unexpected (event_tlast_unexpected_ifft), // output wire event_tlast_unexpected + .event_tlast_missing (event_tlast_missing_ifft), // output wire event_tlast_missing + .event_status_channel_halt (event_status_channel_halt_ifft), // output wire event_status_channel_halt + .event_data_in_channel_halt (event_data_in_channel_halt_ifft), // output wire event_data_in_channel_halt + .event_data_out_channel_halt (event_data_out_channel_halt_ifft) // output wire event_data_out_channel_halt + ); + + + reg [1:0] state_ifft = 2'd0; + wire nd_pilotifft; + wire [19:0] ifft_in_i_pilot; + wire [19:0] ifft_in_q_pilot; + wire nd_dataifft; + wire [19:0] ifft_in_i_data; + wire [19:0] ifft_in_q_data; + + always @(posedge clk)begin + if(rst)begin + ifft_config_tvalid <= 1'd0; + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + state_ifft <= 2'd0; + end + else begin + case(state_ifft) + //帧间复位结束后,先等待ifft_config_tvalid拉高,说明ifft核允许配置,先写入一次ifft配置 + 2'd0:begin + if(ifft_config_tready) begin + ifft_config_tvalid <= 1'd1; + ifft_in_nd <= 1'd0; + state_ifft <= state_ifft + 2'd1; + end + else begin + ifft_config_tvalid <= 1'd0; + ifft_in_nd <= 1'd0; + state_ifft <= state_ifft; + end + end + //每帧一开始ifft核输入交给信道估计模块,直到flag_ChnEstFFT_done到来,说明信道估计两次fft输入完毕(Chn_Estimate给出) + 2'd1:begin + ifft_config_tvalid <= 1'd0; + if(flag_ChnEstFFT_done) begin + ifft_in_i <= ifft_in_i_data; + ifft_in_q <= ifft_in_q_data; + ifft_in_nd <= nd_dataifft; + state_ifft <= state_ifft + 2'd1; + end + else begin + ifft_in_i <= ifft_in_i_pilot; + ifft_in_q <= ifft_in_q_pilot; + ifft_in_nd <= nd_pilotifft; + state_ifft <= state_ifft; + end + end + //nd_pilot2拉高,说明下一个征服导频头处理完毕,ifft输入控制权交还信道估计模块 + 2'd2:begin + ifft_config_tvalid <= 1'd0; + if(nd_pilot2) begin + ifft_in_i <= ifft_in_i_pilot; + ifft_in_q <= ifft_in_q_pilot; + ifft_in_nd <= nd_pilotifft; + state_ifft <= 2'd1; + end + else begin + ifft_in_i <= ifft_in_i_data; + ifft_in_q <= ifft_in_q_data; + ifft_in_nd <= nd_dataifft; + state_ifft <= state_ifft; + end + end + default:state_ifft <= 2'd0; + endcase + end + end + + + + + + + //----------------------------------------------------MMSE信道估计结果RAM--------------------------------------------------// + wire write_MMSE_wea; + wire [7:0] addrin_MMSE; + wire [7:0] addrout_MMSE; + wire [21:0] din_MMSE; + wire [21:0] dout_MMSE; + + RAM_ChnEst_MMSE RAM_ChnEst_MMSE ( + .clka (clk), // input wire clka + .wea (write_MMSE_wea), // input wire [0 : 0] wea + .addra (addrin_MMSE), // input wire [7 : 0] addra + .dina (din_MMSE), // input wire [21 : 0] dina + .clkb (clk), // input wire clkb + .addrb (addrout_MMSE), // input wire [7 : 0] addrb + .doutb (dout_MMSE) // output wire [21 : 0] doutb + ); + + + + + + + + //----------------------------------------------------MMSE信道估计模块--------------------------------------------------// + Chn_Estimate Chn_Estimate_djy ( + .clk (clk), + .rst (rst), + //零域估计,默认值为8'd29 + .Zerozone_vio (Zerozone_vio), + //增强导频序列 + .nd_pilot2 (nd_pilot2), + .pilot_datai (pilot_datai), + .pilot_dataq (pilot_dataq), + //噪声估计结果 + .nd_EstNoise (nd_EstNoise), + .EstNoise_i (EstNoise_i), + .EstNoise_q (EstNoise_q), + //fft核 + .fft_out_i (fft_out_i), + .fft_out_q (fft_out_q), + .fft_out_nd (fft_out_nd), + .fft_index (fft_index), + .fft_in_i (fft_in_i_pilot), + .fft_in_q (fft_in_q_pilot), + .fft_in_nd (nd_pilotfft), + //ifft核 + .ifft_out_i (ifft_out_i), + .ifft_out_q (ifft_out_q), + .ifft_out_nd (ifft_out_nd), + .ifft_index (ifft_index), + .ifft_in_i (ifft_in_i_pilot), + .ifft_in_q (ifft_in_q_pilot), + .ifft_in_nd (nd_pilotifft), + //信道估计两次fft输入完毕后拉高1clk + .flag_ChnEstFFT_done (flag_ChnEstFFT_done), //信道估计两次fft输入完毕后拉高1clk + //MMSE信道估计结果RAM + .write_MMSE_wea (write_MMSE_wea), + .addrin_MMSE (addrin_MMSE), + .din_MMSE (din_MMSE), + //debug,溢出标志 + .flagoverflow_fftpilot_26to14 (flagoverflow_fftpilot_26to14), //第1个fft结果截位,即导频fft结果的截位,26截到14 + .flagoverflow_ChnZF_26to18 (flagoverflow_ChnZF_26to18), //第2个fft结果截位,即ZF信道估计结果的截位,26截到18 + .flagoverflow_comdiv_34to20i (flagoverflow_comdiv_34to20i), //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到20 + .flagoverflow_comdiv_34to20q (flagoverflow_comdiv_34to20q), //第1个除法器结果截位,即复数除法结果的截位,得到没有去噪的ZF估计,34截到20 + .flagoverflow_ifftzero_29to17i (flagoverflow_ifftzero_29to17i), //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + .flagoverflow_ifftzero_29to17q (flagoverflow_ifftzero_29to17q), //第1个ifft结果截位,即ZF零域估计处,结果先除掉低8位,29-8=21截到17 + .flagoverflow_MMSEdiv_divisor_31to28(flagoverflow_MMSEdiv_divisor_31to28), //第2个除法器,即MMSE除法的分母截位,31截到28 + .flagoverflow_divmmse_34to11 (flagoverflow_divmmse_34to11) //第2个除法器结果截位,即MMSE信道估计结果的截位,34截到11 + ); + + + + + + + + //------------------------------------------------------------均衡模块-------------------------------------------------------// + + data_equalizer data_equalizer_djy ( + .clk (clk), + .rst (rst), + .EQUenable_vio (EQUenable_vio), + //进程flag + .nd_pilot2 (nd_pilot2), + .flag_ChnEstFFT_done(flag_ChnEstFFT_done), //信道估计两次fft输入完毕后拉高1clk(Chn_Estimate给出) + //数据的fifo,4个 + .dout_data1i (dout_data1i), + .dout_data1q (dout_data1q), + .rd_en_data1 (rd_en_data1), + .dout_data2i (dout_data2i), + .dout_data2q (dout_data2q), + .rd_en_data2 (rd_en_data2), + .flag_dataow (flag_dataow), //拉高1clk,说明一段数据ow存储完毕,后端可开始连续读取 + //fft核 + .fft_out_i (fft_out_i), + .fft_out_q (fft_out_q), + .fft_out_nd (fft_out_nd), + .fft_index (fft_index), + .fft_in_i (fft_in_i_data), + .fft_in_q (fft_in_q_data), + .fft_in_nd (nd_datafft), + //ifft核 + .ifft_out_i (ifft_out_i), + .ifft_out_q (ifft_out_q), + .ifft_out_nd (ifft_out_nd), + .ifft_index (ifft_index), + .ifft_in_i (ifft_in_i_data), + .ifft_in_q (ifft_in_q_data), + .ifft_in_nd (nd_dataifft), + //MMSE信道估计结果RAM + .addrout_MMSE (addrout_MMSE), + .dout_MMSE (dout_MMSE), + //均衡结果输出 + .nd_SC_FDE_dout (nd_SC_FDE_dout), + .SC_FDE_douti (SC_FDE_douti), + .SC_FDE_doutq (SC_FDE_doutq), + //debug,溢出标志 + .flagoverflow_ifftindata_28to20i (flagoverflow_ifftindata_28to20i), //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + .flagoverflow_ifftindata_28to20q (flagoverflow_ifftindata_28to20q), //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + .flagoverflow_fftdata_26to16i (flagoverflow_fftdata_26to16i), //数据段ow的fft输出截位,26截到16 + .flagoverflow_fftdata_26to16q (flagoverflow_fftdata_26to16q), //数据段ow的fft输出截位,26截到16 + .flagoverflow_FDE_dataout_29to10i (flagoverflow_FDE_dataout_29to10i), //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + .flagoverflow_FDE_dataout_29to10q (flagoverflow_FDE_dataout_29to10q) //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + ); + + + + + + //-----------------------------------------------------------------------写测试文件---------------------------------------------------------------------// + //----------------------------------------验证data_ow----------------------------------// + // integer handle02; + // integer handle03; + // integer handle04; + // integer handle05; + // integer handle06; + // integer handle07; + // integer handle08; + // reg enable1 = 0; + // initial begin + // handle01=$fopen("pilot_datai.txt","w"); $fclose(handle01); + // handle02=$fopen("pilot_dataq.txt","w"); $fclose(handle02); + // handle03=$fopen("pilot_noisei.txt","w"); $fclose(handle03); + // handle04=$fopen("pilot_noiseq.txt","w"); $fclose(handle04); + + // handle05=$fopen("din_data1i.txt","w"); $fclose(handle05); + // handle06=$fopen("din_data1q.txt","w"); $fclose(handle06); + // handle07=$fopen("din_data2i.txt","w"); $fclose(handle07); + // handle08=$fopen("din_data2q.txt","w"); $fclose(handle08); + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + // if(nd_pilot2)begin + // handle01=$fopen("pilot_datai.txt","a+");$fwrite(handle01,"%d\n",$signed(pilot_datai));$fclose(handle01); + // handle02=$fopen("pilot_dataq.txt","a+");$fwrite(handle02,"%d\n",$signed(pilot_dataq));$fclose(handle02); + // handle03=$fopen("pilot_noisei.txt","a+");$fwrite(handle03,"%d\n",$signed(pilot_noisei));$fclose(handle03); + // handle04=$fopen("pilot_noiseq.txt","a+");$fwrite(handle04,"%d\n",$signed(pilot_noiseq));$fclose(handle04); + // end + // if(wr_en_data1)begin + // handle05=$fopen("din_data1i.txt","a+");$fwrite(handle05,"%d\n",$signed(din_data1i));$fclose(handle05); + // handle06=$fopen("din_data1q.txt","a+");$fwrite(handle06,"%d\n",$signed(din_data1q));$fclose(handle06); + // end + // if(wr_en_data2)begin + // handle07=$fopen("din_data2i.txt","a+");$fwrite(handle07,"%d\n",$signed(din_data2i));$fclose(handle07); + // handle08=$fopen("din_data2q.txt","a+");$fwrite(handle08,"%d\n",$signed(din_data2q));$fclose(handle08); + // end + // end + // end + + + + // ----------------------------------------验证data_ow----------------------------------// + // integer handle01; + // integer handle02; + // integer handle03; + // integer handle04; + // integer handle05; + // integer handle06; + // integer handle07; + // integer handle08; + // integer handle09; + // integer handle10; + + // reg enable1 = 0; + // initial begin + // handle01=$fopen("fft_out_i.txt","w"); $fclose(handle01); + // handle02=$fopen("fft_out_q.txt","w"); $fclose(handle02); + // handle03=$fopen("ifft_out_i.txt","w"); $fclose(handle03); + // handle04=$fopen("ifft_out_q.txt","w"); $fclose(handle04); + // handle05=$fopen("fft_in_i.txt","w"); $fclose(handle05); + // handle06=$fopen("fft_in_q.txt","w"); $fclose(handle06); + // handle07=$fopen("ifft_in_i.txt","w"); $fclose(handle07); + // handle08=$fopen("ifft_in_q.txt","w"); $fclose(handle08); + // handle09=$fopen("SC_FDE_douti.txt","w"); $fclose(handle09); + // handle10=$fopen("SC_FDE_doutq.txt","w"); $fclose(handle10); + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + // if(fft_out_nd)begin + // handle01=$fopen("fft_out_i.txt","a+");$fwrite(handle01,"%d\n",$signed(fft_out_i));$fclose(handle01); + // handle02=$fopen("fft_out_q.txt","a+");$fwrite(handle02,"%d\n",$signed(fft_out_q));$fclose(handle02); + // end + // if(ifft_out_nd)begin + // handle03=$fopen("ifft_out_i.txt","a+");$fwrite(handle03,"%d\n",$signed(ifft_out_i));$fclose(handle03); + // handle04=$fopen("ifft_out_q.txt","a+");$fwrite(handle04,"%d\n",$signed(ifft_out_q));$fclose(handle04); + // end + // if(fft_in_nd)begin + // handle05=$fopen("fft_in_i.txt","a+");$fwrite(handle05,"%d\n",$signed(fft_in_i));$fclose(handle05); + // handle06=$fopen("fft_in_q.txt","a+");$fwrite(handle06,"%d\n",$signed(fft_in_q));$fclose(handle06); + // end + // if(ifft_in_nd)begin + // handle07=$fopen("ifft_in_i.txt","a+");$fwrite(handle07,"%d\n",$signed(ifft_in_i));$fclose(handle07); + // handle08=$fopen("ifft_in_q.txt","a+");$fwrite(handle08,"%d\n",$signed(ifft_in_q));$fclose(handle08); + // end + // if(nd_SC_FDE_dout)begin + // handle09=$fopen("SC_FDE_douti.txt","a+");$fwrite(handle09,"%d\n",$signed(SC_FDE_douti));$fclose(handle09); + // handle10=$fopen("SC_FDE_doutq.txt","a+");$fwrite(handle10,"%d\n",$signed(SC_FDE_doutq));$fclose(handle10); + // end + // end + // end + + +endmodule diff --git a/hdl/TSync_Abs_new16.v b/hdl/TSync_Abs_new16.v new file mode 100644 index 0000000..7b1085b --- /dev/null +++ b/hdl/TSync_Abs_new16.v @@ -0,0 +1,889 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/18 21:03:55 +// Design Name: +// Module Name: TSync_Abs_new16 +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +//4倍过采样内插至16 +//帧内不更新 + +module TSync_Abs_new16( + input clk, + input rst, + + input framesync_Interpolation, + output reg framesync_out16 = 1'd0, + + input [9:0] datain1_i, + input [9:0] datain1_q, + input [9:0] datain2_i, + input [9:0] datain2_q, + input [9:0] datain3_i, + input [9:0] datain3_q, + input [9:0] datain4_i, + input [9:0] datain4_q, + + output reg TSyncout_nd = 1'd0, + output reg [9:0] TSyncout_i = 10'd0, + output reg [9:0] TSyncout_q = 10'd0, + + //debug + output reg [1:0] cnt = 2'd0, //12.5 + + output reg [1:0] flag_clk16 = 2'd0, //12.5 + output reg [1:0] flag_num16 = 2'd0 + + + ); + + //-------------------------------------状态机控制----------------------------------------------// + + + // reg [3:0] cnt = 4'd0; + reg nd_1 = 1'd0; + + reg flag_framesync = 1'd0; + // reg [3:0] flag_clk = 4'd0; + // reg [1:0] flag_num = 2'd0; + + + + always @(posedge clk)begin + if(rst)begin + cnt <= 2'd3; + nd_1 <= 1'd0; + + TSyncout_nd <= 1'd0; + TSyncout_i <= 10'd0; + TSyncout_q <= 10'd0; + + flag_framesync <= 1'd0; + framesync_out16 <= 1'd0; + end + else begin + cnt <= cnt + 2'd1; + + if(cnt == 2'd3) nd_1 <= 1'd1; + else nd_1 <= 1'd0; + + if(framesync_Interpolation) begin + if(cnt == flag_clk16) begin + framesync_out16 <= 1'd1; + TSyncout_nd <= 1'd1; + case(flag_num16) + 2'd0:begin + TSyncout_i <= datain1_i; + TSyncout_q <= datain1_q; + end + 2'd1:begin + TSyncout_i <= datain2_i; + TSyncout_q <= datain2_q; + end + 2'd2:begin + TSyncout_i <= datain3_i; + TSyncout_q <= datain3_q; + end + 2'd3:begin + TSyncout_i <= datain4_i; + TSyncout_q <= datain4_q; + end + endcase + flag_framesync <= 1'd0; + end + else begin + framesync_out16 <= 1'd0; + TSyncout_nd <= 1'd0; + flag_framesync <= 1'd1; + end + end + else begin + framesync_out16 <= 1'd0; + flag_framesync <= 1'd0; + TSyncout_nd <= 1'd0; + TSyncout_i <= 10'd0; + TSyncout_q <= 10'd0; + end + + end + end + + + //---------------------------------------求近似模值Abs,delay=6-------------------------------------// + wire [10:0] data_1; + ApproxAbs_v2 ApproxAbs_v2_tsync1 ( + .clk (clk), + .ND (1'd1), + .Din_I (datain1_i), + .Din_Q (datain1_q), + .Dout (data_1), + .Rdy () + ); + + wire [10:0] data_2; + ApproxAbs_v2 ApproxAbs_v2_tsync2 ( + .clk (clk), + .ND (1'd1), + .Din_I (datain2_i), + .Din_Q (datain2_q), + .Dout (data_2), + .Rdy () + ); + + wire [10:0] data_3; + ApproxAbs_v2 ApproxAbs_v2_tsync3 ( + .clk (clk), + .ND (1'd1), + .Din_I (datain3_i), + .Din_Q (datain3_q), + .Dout (data_3), + .Rdy () + ); + + wire [10:0] data_4; + ApproxAbs_v2 ApproxAbs_v2_tsync4 ( + .clk (clk), + .ND (1'd1), + .Din_I (datain4_i), + .Din_Q (datain4_q), + .Dout (data_4), + .Rdy () + ); + + + + reg nd_2 = 1'd0; + reg nd_3 = 1'd0; + reg nd_4 = 1'd0; + reg nd_5 = 1'd0; + reg nd_6 = 1'd0; + reg nd_7 = 1'd0; + + always @(posedge clk)begin + nd_2 <= nd_1; + nd_3 <= nd_2; + nd_4 <= nd_3; + nd_5 <= nd_4; + + nd_6 <= nd_5; + nd_7 <= nd_6; + end + + + + //-------------------------------------累加,delay=1-------------------------------------------------// + reg [19:0] acc_01 = 20'd0; + reg [19:0] acc_02 = 20'd0; + reg [19:0] acc_03 = 20'd0; + reg [19:0] acc_04 = 20'd0; + reg [19:0] acc_05 = 20'd0; + reg [19:0] acc_06 = 20'd0; + reg [19:0] acc_07 = 20'd0; + reg [19:0] acc_08 = 20'd0; + reg [19:0] acc_09 = 20'd0; + reg [19:0] acc_10 = 20'd0; + reg [19:0] acc_11 = 20'd0; + reg [19:0] acc_12 = 20'd0; + reg [19:0] acc_13 = 20'd0; + reg [19:0] acc_14 = 20'd0; + reg [19:0] acc_15 = 20'd0; + reg [19:0] acc_16 = 20'd0; + + reg [1:0] cnt_4 =2'd0; + reg nd_acc = 1'd0; + reg nd_flag = 1'd0; + + reg flag_cnt_0 = 1'd0; + + reg [5:0] cnt_64 = 6'd0; + reg [6:0] cnt_128 = 7'd0; + reg [7:0] cnt_256 = 8'd0; + reg [8:0] cnt_512 = 9'd0; + reg [9:0] cnt_1024 = 10'd0; + + reg [2:0] state_tsync4 = 3'd0; + + always @(posedge clk)begin + if(rst)begin + acc_01 <= 20'd0; + acc_02 <= 20'd0; + acc_03 <= 20'd0; + acc_04 <= 20'd0; + acc_05 <= 20'd0; + acc_06 <= 20'd0; + acc_07 <= 20'd0; + acc_08 <= 20'd0; + acc_09 <= 20'd0; + acc_10 <= 20'd0; + acc_11 <= 20'd0; + acc_12 <= 20'd0; + acc_13 <= 20'd0; + acc_14 <= 20'd0; + acc_15 <= 20'd0; + acc_16 <= 20'd0; + + cnt_4 <= 2'd3; + nd_acc <= 1'd0; + nd_flag<= 1'd0; + + cnt_64 <= 6'd0; + cnt_128 <= 7'd0; + cnt_256 <= 8'd0; + cnt_512 <= 9'd0; + cnt_1024 <= 10'd0; + + flag_cnt_0 <= 1'd0; + + state_tsync4 <= 3'd0; + end + else begin + if(nd_6) cnt_4 <= 4'd0; + else cnt_4 <= cnt_4 + 4'd1; + + if (nd_6) nd_flag <= 1'd1; + else nd_flag <= nd_flag; + + case(state_tsync4) + //等待第一次的数据幅值估计结果(与nd_7对齐) + 3'd0:begin + if(nd_6) state_tsync4 <= 3'd1; + else state_tsync4 <= state_tsync4; + end + //此clk内nd_7、第一次的数据幅值估计结果同时到来,cnt_4结果为4'd0。 + //累积,直到最后一个累积结束后转至下一状态 + 3'd1:begin + if(cnt_4==2'd3) begin + cnt_64 <=cnt_64 +6'd1; + cnt_128 <=cnt_128 +7'd1; + cnt_256 <=cnt_256 +8'd1; + cnt_512 <=cnt_512 +9'd1; + cnt_1024 <=cnt_1024 +10'd1; + + if(cnt_512==9'd511) flag_cnt_0 <= 1'd1; + else flag_cnt_0 <= 1'd0; + end + else begin + cnt_64 <= cnt_64; + cnt_128 <= cnt_128 ; + cnt_256 <= cnt_256 ; + cnt_512 <= cnt_512 ; + cnt_1024 <= cnt_1024; + flag_cnt_0 <= 1'd0; + end + + if(cnt_512==9'd0) begin + case(cnt_4) + 2'd0:begin + acc_01 <= {9'd0,data_1}; + acc_02 <= {9'd0,data_2}; + acc_03 <= {9'd0,data_3}; + acc_04 <= {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd1:begin + acc_05 <= {9'd0,data_1}; + acc_06 <= {9'd0,data_2}; + acc_07 <= {9'd0,data_3}; + acc_08 <= {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd2:begin + acc_09 <= {9'd0,data_1}; + acc_10 <= {9'd0,data_2}; + acc_11 <= {9'd0,data_3}; + acc_12 <= {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd3:begin + acc_13 <= {9'd0,data_1}; + acc_14 <= {9'd0,data_2}; + acc_15 <= {9'd0,data_3}; + acc_16 <= {9'd0,data_4}; + + nd_acc <= 1'd1; + end + endcase + end + else begin + case(cnt_4) + 2'd0:begin + acc_01 <= acc_01 + {9'd0,data_1}; + acc_02 <= acc_02 + {9'd0,data_2}; + acc_03 <= acc_03 + {9'd0,data_3}; + acc_04 <= acc_04 + {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd1:begin + acc_05 <= acc_05 + {9'd0,data_1}; + acc_06 <= acc_06 + {9'd0,data_2}; + acc_07 <= acc_07 + {9'd0,data_3}; + acc_08 <= acc_08 + {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd2:begin + acc_09 <= acc_09 + {9'd0,data_1}; + acc_10 <= acc_10 + {9'd0,data_2}; + acc_11 <= acc_11 + {9'd0,data_3}; + acc_12 <= acc_12 + {9'd0,data_4}; + + nd_acc <= 1'd0; + end + 2'd3:begin + acc_13 <= acc_13 + {9'd0,data_1}; + acc_14 <= acc_14 + {9'd0,data_2}; + acc_15 <= acc_15 + {9'd0,data_3}; + acc_16 <= acc_16 + {9'd0,data_4}; + + nd_acc <= 1'd1; + end + endcase + end + + if(cnt_512==9'd511&&cnt_4==2'd3) state_tsync4 <= 3'd2; + else state_tsync4 <= state_tsync4; + end + 3'd2:begin + state_tsync4 <= state_tsync4; + flag_cnt_0 <= 1'd0; + end + default:state_tsync4 <= 3'd0; + endcase + end + end + + + + //---------------------------------------排序找最大值,delay=3-------------------------------------------------// + + reg [19:0] temp_1_01 = 20'd0; + reg [19:0] temp_1_02 = 20'd0; + reg [19:0] temp_1_03 = 20'd0; + reg [19:0] temp_1_04 = 20'd0; + reg [19:0] temp_1_05 = 20'd0; + reg [19:0] temp_1_06 = 20'd0; + reg [19:0] temp_1_07 = 20'd0; + reg [19:0] temp_1_08 = 20'd0; + + reg [1:0] flag_clk_1_01 =2'd0; + reg [1:0] flag_clk_1_02 =2'd0; + reg [1:0] flag_clk_1_03 =2'd0; + reg [1:0] flag_clk_1_04 =2'd0; + reg [1:0] flag_clk_1_05 =2'd0; + reg [1:0] flag_clk_1_06 =2'd0; + reg [1:0] flag_clk_1_07 =2'd0; + reg [1:0] flag_clk_1_08 =2'd0; + + reg [1:0] flag_num_1_01 =2'd0; + reg [1:0] flag_num_1_02 =2'd0; + reg [1:0] flag_num_1_03 =2'd0; + reg [1:0] flag_num_1_04 =2'd0; + reg [1:0] flag_num_1_05 =2'd0; + reg [1:0] flag_num_1_06 =2'd0; + reg [1:0] flag_num_1_07 =2'd0; + reg [1:0] flag_num_1_08 =2'd0; + + reg nd_acc1 = 1'd0; + + //ila用 + reg [19:0] acc_01_reg = 20'd0; + reg [19:0] acc_02_reg = 20'd0; + reg [19:0] acc_03_reg = 20'd0; + reg [19:0] acc_04_reg = 20'd0; + reg [19:0] acc_05_reg = 20'd0; + reg [19:0] acc_06_reg = 20'd0; + reg [19:0] acc_07_reg = 20'd0; + reg [19:0] acc_08_reg = 20'd0; + reg [19:0] acc_09_reg = 20'd0; + reg [19:0] acc_10_reg = 20'd0; + reg [19:0] acc_11_reg = 20'd0; + reg [19:0] acc_12_reg = 20'd0; + reg [19:0] acc_13_reg = 20'd0; + reg [19:0] acc_14_reg = 20'd0; + reg [19:0] acc_15_reg = 20'd0; + reg [19:0] acc_16_reg = 20'd0; + + always @(posedge clk)begin + if(rst)begin + temp_1_01 <= 20'd0; + temp_1_02 <= 20'd0; + temp_1_03 <= 20'd0; + temp_1_04 <= 20'd0; + temp_1_05 <= 20'd0; + temp_1_06 <= 20'd0; + temp_1_07 <= 20'd0; + temp_1_08 <= 20'd0; + + flag_clk_1_01 <=2'd0; + flag_clk_1_02 <=2'd0; + flag_clk_1_03 <=2'd0; + flag_clk_1_04 <=2'd0; + flag_clk_1_05 <=2'd0; + flag_clk_1_06 <=2'd0; + flag_clk_1_07 <=2'd0; + flag_clk_1_08 <=2'd0; + + flag_num_1_01 <=2'd0; + flag_num_1_02 <=2'd0; + flag_num_1_03 <=2'd0; + flag_num_1_04 <=2'd0; + flag_num_1_05 <=2'd0; + flag_num_1_06 <=2'd0; + flag_num_1_07 <=2'd0; + flag_num_1_08 <=2'd0; + + nd_acc1 <= 1'd0; + + //ila用 + acc_01_reg <= 20'd0; + acc_02_reg <= 20'd0; + acc_03_reg <= 20'd0; + acc_04_reg <= 20'd0; + acc_05_reg <= 20'd0; + acc_06_reg <= 20'd0; + acc_07_reg <= 20'd0; + acc_08_reg <= 20'd0; + acc_09_reg <= 20'd0; + acc_10_reg <= 20'd0; + acc_11_reg <= 20'd0; + acc_12_reg <= 20'd0; + acc_13_reg <= 20'd0; + acc_14_reg <= 20'd0; + acc_15_reg <= 20'd0; + acc_16_reg <= 20'd0; + end + else begin + if(nd_acc&&flag_cnt_0) begin + nd_acc1 <= 1'd1; + + //ila用 + acc_01_reg <= acc_01; + acc_02_reg <= acc_02; + acc_03_reg <= acc_03; + acc_04_reg <= acc_04; + acc_05_reg <= acc_05; + acc_06_reg <= acc_06; + acc_07_reg <= acc_07; + acc_08_reg <= acc_08; + acc_09_reg <= acc_09; + acc_10_reg <= acc_10; + acc_11_reg <= acc_11; + acc_12_reg <= acc_12; + acc_13_reg <= acc_13; + acc_14_reg <= acc_14; + acc_15_reg <= acc_15; + acc_16_reg <= acc_16; + //ila用 + + if(acc_01>=acc_02) begin + temp_1_01 <= acc_01; + flag_clk_1_01 <= 2'd0; + flag_num_1_01 <= 2'd0; + end + else begin + temp_1_01 <= acc_02; + flag_clk_1_01 <= 2'd0; + flag_num_1_01 <= 2'd1; + end + + if(acc_03>=acc_04) begin + temp_1_02 <= acc_03; + flag_clk_1_02 <= 2'd0; + flag_num_1_02 <= 2'd2; + end + else begin + temp_1_02 <= acc_04; + flag_clk_1_02 <= 2'd0; + flag_num_1_02 <= 2'd3; + end + + if(acc_05>=acc_06) begin + temp_1_03 <= acc_05; + flag_clk_1_03 <= 2'd1; + flag_num_1_03 <= 2'd0; + end + else begin + temp_1_03 <= acc_06; + flag_clk_1_03 <= 2'd1; + flag_num_1_03 <= 2'd1; + end + + if(acc_07>=acc_08) begin + temp_1_04 <= acc_07; + flag_clk_1_04 <= 2'd1; + flag_num_1_04 <= 2'd2; + end + else begin + temp_1_04 <= acc_08; + flag_clk_1_04 <= 2'd1; + flag_num_1_04 <= 2'd3; + end + + if(acc_09>=acc_10) begin + temp_1_05 <= acc_09; + flag_clk_1_05 <= 2'd2; + flag_num_1_05 <= 2'd0; + end + else begin + temp_1_05 <= acc_10; + flag_clk_1_05 <= 2'd2; + flag_num_1_05 <= 2'd1; + end + + if(acc_11>=acc_12) begin + temp_1_06 <= acc_11; + flag_clk_1_06 <= 2'd2; + flag_num_1_06 <= 2'd2; + end + else begin + temp_1_06 <= acc_12; + flag_clk_1_06 <= 2'd2; + flag_num_1_06 <= 2'd3; + end + + if(acc_13>=acc_14) begin + temp_1_07 <= acc_13; + flag_clk_1_07 <= 2'd3; + flag_num_1_07 <= 2'd0; + end + else begin + temp_1_07 <= acc_14; + flag_clk_1_07 <= 2'd3; + flag_num_1_07 <= 2'd1; + end + + if(acc_15>=acc_16) begin + temp_1_08 <= acc_15; + flag_clk_1_08 <= 2'd3; + flag_num_1_08 <= 2'd2; + end + else begin + temp_1_08 <= acc_16; + flag_clk_1_08 <= 2'd3; + flag_num_1_08 <= 2'd3; + end + end + else nd_acc1 <= 1'd0; + end + end + + reg [19:0] temp_2_01 = 20'd0; + reg [19:0] temp_2_02 = 20'd0; + reg [19:0] temp_2_03 = 20'd0; + reg [19:0] temp_2_04 = 20'd0; + + reg [1:0] flag_clk_2_01 = 2'd0; + reg [1:0] flag_clk_2_02 = 2'd0; + reg [1:0] flag_clk_2_03 = 2'd0; + reg [1:0] flag_clk_2_04 = 2'd0; + + reg [1:0] flag_num_2_01 = 2'd0; + reg [1:0] flag_num_2_02 = 2'd0; + reg [1:0] flag_num_2_03 = 2'd0; + reg [1:0] flag_num_2_04 = 2'd0; + + reg nd_acc2 = 1'd0; + + always @(posedge clk)begin + if(rst)begin + temp_2_01 <= 20'd0; + temp_2_02 <= 20'd0; + temp_2_03 <= 20'd0; + temp_2_04 <= 20'd0; + + flag_clk_2_01 <= 2'd0; + flag_clk_2_02 <= 2'd0; + flag_clk_2_03 <= 2'd0; + flag_clk_2_04 <= 2'd0; + + flag_num_2_01 <= 2'd0; + flag_num_2_02 <= 2'd0; + flag_num_2_03 <= 2'd0; + flag_num_2_04 <= 2'd0; + + nd_acc2 <= 1'd0; + end + else begin + nd_acc2 <= nd_acc1; + if(nd_acc1) begin + if(temp_1_01>=temp_1_02) begin + temp_2_01 <= temp_1_01; + flag_clk_2_01 <= flag_clk_1_01; + flag_num_2_01 <= flag_num_1_01; + end + else begin + temp_2_01 <= temp_1_02; + flag_clk_2_01 <= flag_clk_1_02; + flag_num_2_01 <= flag_num_1_02; + end + + if(temp_1_03>=temp_1_04) begin + temp_2_02 <= temp_1_03; + flag_clk_2_02 <= flag_clk_1_03; + flag_num_2_02 <= flag_num_1_03; + end + else begin + temp_2_02 <= temp_1_04; + flag_clk_2_02 <= flag_clk_1_04; + flag_num_2_02 <= flag_num_1_04; + end + + if(temp_1_05>=temp_1_06) begin + temp_2_03 <= temp_1_05; + flag_clk_2_03 <= flag_clk_1_05; + flag_num_2_03 <= flag_num_1_05; + end + else begin + temp_2_03 <= temp_1_06; + flag_clk_2_03 <= flag_clk_1_06; + flag_num_2_03 <= flag_num_1_06; + end + + if(temp_1_07>=temp_1_08) begin + temp_2_04 <= temp_1_07; + flag_clk_2_04 <= flag_clk_1_07; + flag_num_2_04 <= flag_num_1_07; + end + else begin + temp_2_04 <= temp_1_08; + flag_clk_2_04 <= flag_clk_1_08; + flag_num_2_04 <= flag_num_1_08; + end + end + end + end + + + + reg [19:0] temp_3_1 = 20'd0; + reg [19:0] temp_3_2 = 20'd0; + + reg [1:0] flag_clk_3_1 = 2'd0; + reg [1:0] flag_clk_3_2 = 2'd0; + + reg [1:0] flag_num_3_1 = 2'd0; + reg [1:0] flag_num_3_2 = 2'd0; + + reg nd_acc3 = 1'd0; + + always @(posedge clk)begin + if(rst)begin + temp_3_1 <= 20'd0; + temp_3_2 <= 20'd0; + + flag_clk_3_1 <= 2'd0; + flag_clk_3_2 <= 2'd0; + + flag_num_3_1 <= 2'd0; + flag_num_3_2 <= 2'd0; + + nd_acc3 <= 1'd0; + end + else begin + nd_acc3 <= nd_acc2; + if(nd_acc2) begin + if(temp_2_01>=temp_2_02) begin + temp_3_1 <= temp_2_01; + flag_clk_3_1 <= flag_clk_2_01; + flag_num_3_1 <= flag_num_2_01; + end + else begin + temp_3_1 <= temp_2_02; + flag_clk_3_1 <= flag_clk_2_02; + flag_num_3_1 <= flag_num_2_02; + end + + if(temp_2_03>=temp_2_04) begin + temp_3_2 <= temp_2_03; + flag_clk_3_2 <= flag_clk_2_03; + flag_num_3_2 <= flag_num_2_03; + end + else begin + temp_3_2 <= temp_2_04; + flag_clk_3_2 <= flag_clk_2_04; + flag_num_3_2 <= flag_num_2_04; + end + end + end + end + + + //----------------------------------------------------给采样标志,delay=1--------------------------------------// + + reg nd_acc4 = 1'd0; + always @(posedge clk)begin + if(rst)begin + flag_clk16 <= 2'd0; + nd_acc4 <= 1'd0; + end + else begin + nd_acc4 <= nd_acc3; + if(nd_acc3) begin + if(temp_3_1>=temp_3_2) begin + flag_clk16 <= flag_clk_3_1; + flag_num16 <= flag_num_3_1; + end + else begin + flag_clk16 <= flag_clk_3_2; + flag_num16 <= flag_num_3_2; + end + end + end + end + + + + + //ila用 + // reg [6:0] state_check = 7'd0; + // always @(posedge clk)begin + // if(rst)begin + // state_check <= 7'd0; + // flag_TSync_check<= 1'd0; + // cnt_tsync_shixu <= 4'd0; + // flag_tongdao <= 1'd0; + // acc_tsync <= 20'd0; + // num_tsync <= num_tsync; + // end + // else begin + // case(state_check) + // 7'd0:begin + // if(nd_acc4) begin + // flag_TSync_check<= 1'd0; + // state_check <= 7'd1; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd0; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd1:begin + // if(flag_save) begin + // flag_TSync_check<= 1'd0; + // state_check <= 7'd2; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd1 + cnt_tsync_shixu; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd2:begin + // if(cnt==2'd3) begin + // flag_TSync_check<= 1'd1; + // state_check <= 7'd3; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd1 + cnt_tsync_shixu; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd03:begin acc_tsync <= acc_01_reg; num_tsync <= 6'd00; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd04; end + // 7'd04:begin acc_tsync <= acc_02_reg; num_tsync <= 6'd01; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd05; end + // 7'd05:begin acc_tsync <= acc_03_reg; num_tsync <= 6'd02; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd06; end + // 7'd06:begin acc_tsync <= acc_04_reg; num_tsync <= 6'd03; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd07; end + // 7'd07:begin acc_tsync <= acc_05_reg; num_tsync <= 6'd04; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd08; end + // 7'd08:begin acc_tsync <= acc_06_reg; num_tsync <= 6'd05; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd09; end + // 7'd09:begin acc_tsync <= acc_07_reg; num_tsync <= 6'd06; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd10; end + // 7'd10:begin acc_tsync <= acc_08_reg; num_tsync <= 6'd07; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd11; end + // 7'd11:begin acc_tsync <= acc_09_reg; num_tsync <= 6'd08; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd12; end + // 7'd12:begin acc_tsync <= acc_10_reg; num_tsync <= 6'd09; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd13; end + // 7'd13:begin acc_tsync <= acc_11_reg; num_tsync <= 6'd10; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd14; end + // 7'd14:begin acc_tsync <= acc_12_reg; num_tsync <= 6'd11; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd15; end + // 7'd15:begin acc_tsync <= acc_13_reg; num_tsync <= 6'd12; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd16; end + // 7'd16:begin acc_tsync <= acc_14_reg; num_tsync <= 6'd13; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd17; end + // 7'd17:begin acc_tsync <= acc_15_reg; num_tsync <= 6'd14; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd18; end + // 7'd18:begin acc_tsync <= acc_16_reg; num_tsync <= 6'd15; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd0; end + // endcase + // end + // end + + + + + + + + // integer handle01; + // integer handle02; + + // reg enable = 0; + // initial begin + // handle01=$fopen("TSyncout_i.txt","w"); $fclose(handle01); + // handle02=$fopen("TSyncout_q.txt","w"); $fclose(handle02); + + // #10; + // enable = 1; + // end + + // always@(posedge clk)begin + // if(enable)begin + // if(TSyncout_nd)begin + // handle01=$fopen("TSyncout_i.txt","a+");$fwrite(handle01,"%d\n",$signed(TSyncout_i));$fclose(handle01); + // handle02=$fopen("TSyncout_q.txt","a+");$fwrite(handle02,"%d\n",$signed(TSyncout_q));$fclose(handle02); + // end + // end + // end + + integer handle01; + integer handle02; + integer handle03; + integer handle04; + + + reg enable1 = 0; + reg flag_save = 0; + initial begin + handle01=$fopen("data_1.txt","w"); $fclose(handle01); + handle02=$fopen("data_2.txt","w"); $fclose(handle02); + handle03=$fopen("data_3.txt","w"); $fclose(handle03); + handle04=$fopen("data_4.txt","w"); $fclose(handle04); + + #10; + enable1 = 1; + end + + always@(posedge clk)begin + if(enable1)begin + if(nd_6) flag_save <= 1'd1; + else flag_save <= flag_save; + if(flag_save) begin + handle01=$fopen("data_1.txt","a+");$fwrite(handle01,"%d\n",$signed(data_1));$fclose(handle01); + handle02=$fopen("data_2.txt","a+");$fwrite(handle02,"%d\n",$signed(data_2));$fclose(handle02); + handle03=$fopen("data_3.txt","a+");$fwrite(handle03,"%d\n",$signed(data_3));$fclose(handle03); + handle04=$fopen("data_4.txt","a+");$fwrite(handle04,"%d\n",$signed(data_4));$fclose(handle04); + end + end + end + + + +endmodule diff --git a/hdl/TSync_Abs_new4.v b/hdl/TSync_Abs_new4.v new file mode 100644 index 0000000..f7edd6c --- /dev/null +++ b/hdl/TSync_Abs_new4.v @@ -0,0 +1,472 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/11/18 21:03:55 +// Design Name: +// Module Name: TSync_Abs_new4 +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +//4倍过采样不内插 +//帧内不更新 + +module TSync_Abs_new4( + input clk, + input rst, + input framesync_Interpolation, + output reg framesync_out4 = 1'd0, + + input [9:0] dataini, + input [9:0] datainq, + + output reg TSyncout_nd = 1'd0, + output reg [9:0] TSyncout_i = 10'd0, + output reg [9:0] TSyncout_q = 10'd0, + + //debug + output reg [1:0] cnt = 2'd0, //12.5 + + output reg [1:0] flag_clk4 = 2'd0 //12.5 + + + ); + + //-------------------------------------状态机控制----------------------------------------------// + + + // reg [3:0] cnt = 4'd0; + reg nd_1 = 1'd0; + + reg flag_framesync = 1'd0; + + // reg [3:0] flag_clk = 4'd0; + // reg [1:0] flag_num = 2'd0; + + + + always @(posedge clk)begin + if(rst)begin + cnt <= 2'd3; + nd_1 <= 1'd0; + + TSyncout_nd <= 1'd0; + TSyncout_i <= 10'd0; + TSyncout_q <= 10'd0; + + flag_framesync <= 1'd0; + framesync_out4 <= 1'd0; + end + else begin + cnt <= cnt + 2'd1; + + if(cnt == 2'd3) nd_1 <= 1'd1; + else nd_1 <= 1'd0; + if(framesync_Interpolation) begin + if(cnt == flag_clk4) begin + framesync_out4 <= 1'd1; + TSyncout_nd <= 1'd1; + TSyncout_i <= dataini; + TSyncout_q <= datainq; + flag_framesync <= 1'd0; + end + else begin + framesync_out4 <= 1'd0; + TSyncout_nd <= 1'd0; + TSyncout_i <= 10'd0; + TSyncout_q <= 10'd0; + flag_framesync <= 1'd1; + end + end + else begin + framesync_out4 <= 1'd0; + flag_framesync <= 1'd0; + TSyncout_nd <= 1'd0; + TSyncout_i <= 10'd0; + TSyncout_q <= 10'd0; + end + + // if(cnt == flag_clk4) begin + // TSyncout_nd <= 1'd1; + // TSyncout_i <= dataini; + // TSyncout_q <= datainq; + // end + // else begin + // TSyncout_nd <= 1'd0; + // end + + end + end + + + //---------------------------------------求近似模值Abs,delay=6-------------------------------------// + wire [10:0] data_Abs; + ApproxAbs_v2 ApproxAbs_v2_tsync ( + .clk (clk), + .ND (1'd1), + .Din_I (dataini), + .Din_Q (datainq), + .Dout (data_Abs), + .Rdy () + ); + + + + reg nd_2 = 1'd0; + reg nd_3 = 1'd0; + reg nd_4 = 1'd0; + reg nd_5 = 1'd0; + reg nd_6 = 1'd0; + reg nd_7 = 1'd0; + + always @(posedge clk)begin + nd_2 <= nd_1; + nd_3 <= nd_2; + nd_4 <= nd_3; + nd_5 <= nd_4; + + nd_6 <= nd_5; + nd_7 <= nd_6; + end + + + + //-------------------------------------累加,delay=1-------------------------------------------------// + reg [19:0] acc_01 = 20'd0; + reg [19:0] acc_02 = 20'd0; + reg [19:0] acc_03 = 20'd0; + reg [19:0] acc_04 = 20'd0; + + reg [1:0] cnt_4 =2'd0; + reg nd_acc = 1'd0; + reg nd_flag = 1'd0; + + reg flag_cnt_0 = 1'd0; + + reg [5:0] cnt_64 = 6'd0; + reg [6:0] cnt_128 = 7'd0; + reg [7:0] cnt_256 = 8'd0; + reg [8:0] cnt_512 = 9'd0; + reg [9:0] cnt_1024 = 10'd0; + + reg [2:0] state_tsync4 = 3'd0; + + always @(posedge clk)begin + if(rst)begin + acc_01 <= 20'd0; + acc_02 <= 20'd0; + acc_03 <= 20'd0; + acc_04 <= 20'd0; + + cnt_4 <= 2'd3; + nd_acc <= 1'd0; + nd_flag<= 1'd0; + + cnt_64 <= 6'd0; + cnt_128 <= 7'd0; + cnt_256 <= 8'd0; + cnt_512 <= 9'd0; + cnt_1024 <= 10'd0; + + flag_cnt_0 <= 1'd0; + + state_tsync4 <= 3'd0; + end + else begin + if(nd_6) cnt_4 <= 4'd0; + else cnt_4 <= cnt_4 + 4'd1; + + if (nd_6) nd_flag <= 1'd1; + else nd_flag <= nd_flag; + + case(state_tsync4) + //等待第一次的数据幅值估计结果(与nd_7对齐) + 3'd0:begin + if(nd_6) state_tsync4 <= 3'd1; + else state_tsync4 <= state_tsync4; + end + //此clk内nd_7、第一次的数据幅值估计结果同时到来,cnt_4结果为4'd0。 + //累积,直到最后一个累积结束后转至下一状态 + 3'd1:begin + if(cnt_4==2'd3) begin + cnt_64 <=cnt_64 +6'd1; + cnt_128 <=cnt_128 +7'd1; + cnt_256 <=cnt_256 +8'd1; + cnt_512 <=cnt_512 +9'd1; + cnt_1024 <=cnt_1024 +10'd1; + + if(cnt_512==9'd511) flag_cnt_0 <= 1'd1; + else flag_cnt_0 <= 1'd0; + end + else begin + cnt_64 <= cnt_64; + cnt_128 <= cnt_128 ; + cnt_256 <= cnt_256 ; + cnt_512 <= cnt_512 ; + cnt_1024 <= cnt_1024; + flag_cnt_0 <= 1'd0; + end + + if(cnt_512==9'd0) begin + case(cnt_4) + 2'd0:begin + acc_01 <= {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd1:begin + acc_02 <= {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd2:begin + acc_03 <= {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd3:begin + acc_04 <= {9'd0,data_Abs}; + nd_acc <= 1'd1; + end + endcase + end + else begin + case(cnt_4) + 2'd0:begin + acc_01 <= acc_01 + {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd1:begin + acc_02 <= acc_02 + {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd2:begin + acc_03 <= acc_03 + {9'd0,data_Abs}; + nd_acc <= 1'd0; + end + 2'd3:begin + acc_04 <= acc_04 + {9'd0,data_Abs}; + nd_acc <= 1'd1; + end + endcase + end + + if(cnt_512==9'd511&&cnt_4==2'd3) state_tsync4 <= 3'd2; + else state_tsync4 <= state_tsync4; + end + 3'd2:begin + state_tsync4 <= state_tsync4; + flag_cnt_0 <= 1'd0; + end + default:state_tsync4 <= 3'd0; + endcase + end + end + + + + //---------------------------------------排序找最大值,delay=3-------------------------------------------------// + + reg [19:0] temp_1_01 = 20'd0; + reg [19:0] temp_1_02 = 20'd0; + + reg [1:0] flag_clk_1_01 =2'd0; + reg [1:0] flag_clk_1_02 =2'd0; + + reg nd_acc1 = 1'd0; + + //ila用 + reg [19:0] acc_01_reg = 20'd0; + reg [19:0] acc_02_reg = 20'd0; + reg [19:0] acc_03_reg = 20'd0; + reg [19:0] acc_04_reg = 20'd0; + + always @(posedge clk)begin + if(rst)begin + temp_1_01 <= 20'd0; + temp_1_02 <= 20'd0; + + flag_clk_1_01 <=2'd0; + flag_clk_1_02 <=2'd0; + + nd_acc1 <= 1'd0; + + //ila用 + acc_01_reg <= 20'd0; + acc_02_reg <= 20'd0; + acc_03_reg <= 20'd0; + acc_04_reg <= 20'd0; + end + else begin + if(nd_acc&&flag_cnt_0) begin + nd_acc1 <= 1'd1; + + //ila用 + acc_01_reg <= acc_01; + acc_02_reg <= acc_02; + acc_03_reg <= acc_03; + acc_04_reg <= acc_04; + //ila用 + + if(acc_01>=acc_02) begin + temp_1_01 <= acc_01; + flag_clk_1_01 <= 2'd0; + end + else begin + temp_1_01 <= acc_02; + flag_clk_1_01 <= 2'd1; + end + + if(acc_03>=acc_04) begin + temp_1_02 <= acc_03; + flag_clk_1_02 <= 2'd2; + end + else begin + temp_1_02 <= acc_04; + flag_clk_1_02 <= 2'd3; + end + end + else nd_acc1 <= 1'd0; + end + end + + + + + //----------------------------------------------------给采样标志,delay=1--------------------------------------// + + reg nd_acc2 = 1'd0; + always @(posedge clk)begin + if(rst)begin + flag_clk4 <= 2'd0; + nd_acc2 <= 1'd0; + end + else begin + nd_acc2 <= nd_acc1; + if(nd_acc1) begin + if(temp_1_01>=temp_1_02) begin + flag_clk4 <= flag_clk_1_01; + end + else begin + flag_clk4 <= flag_clk_1_02; + end + end + end + end + + + + + //ila用 + // reg [6:0] state_check = 7'd0; + // always @(posedge clk)begin + // if(rst)begin + // state_check <= 7'd0; + // flag_TSync_check<= 1'd0; + // cnt_tsync_shixu <= 4'd0; + // flag_tongdao <= 1'd0; + // acc_tsync <= 20'd0; + // num_tsync <= num_tsync; + // end + // else begin + // case(state_check) + // 7'd0:begin + // if(nd_acc4) begin + // flag_TSync_check<= 1'd0; + // state_check <= 7'd1; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd0; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd1:begin + // if(flag_save) begin + // flag_TSync_check<= 1'd0; + // state_check <= 7'd2; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd1 + cnt_tsync_shixu; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd2:begin + // if(cnt==2'd3) begin + // flag_TSync_check<= 1'd1; + // state_check <= 7'd3; + // end + // else begin + // flag_TSync_check<= 1'd0; + // state_check <= state_check; + // end + // cnt_tsync_shixu <= 4'd1 + cnt_tsync_shixu; + // flag_tongdao <= 1'd0; + // acc_tsync <= acc_tsync; + // num_tsync <= num_tsync; + // end + // 7'd03:begin acc_tsync <= acc_01_reg; num_tsync <= 6'd00; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd04; end + // 7'd04:begin acc_tsync <= acc_02_reg; num_tsync <= 6'd01; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd05; end + // 7'd05:begin acc_tsync <= acc_03_reg; num_tsync <= 6'd02; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd06; end + // 7'd06:begin acc_tsync <= acc_04_reg; num_tsync <= 6'd03; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd07; end + // 7'd07:begin acc_tsync <= acc_05_reg; num_tsync <= 6'd04; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd08; end + // 7'd08:begin acc_tsync <= acc_06_reg; num_tsync <= 6'd05; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd09; end + // 7'd09:begin acc_tsync <= acc_07_reg; num_tsync <= 6'd06; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd10; end + // 7'd10:begin acc_tsync <= acc_08_reg; num_tsync <= 6'd07; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd11; end + // 7'd11:begin acc_tsync <= acc_09_reg; num_tsync <= 6'd08; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd12; end + // 7'd12:begin acc_tsync <= acc_10_reg; num_tsync <= 6'd09; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd13; end + // 7'd13:begin acc_tsync <= acc_11_reg; num_tsync <= 6'd10; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd14; end + // 7'd14:begin acc_tsync <= acc_12_reg; num_tsync <= 6'd11; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd15; end + // 7'd15:begin acc_tsync <= acc_13_reg; num_tsync <= 6'd12; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd16; end + // 7'd16:begin acc_tsync <= acc_14_reg; num_tsync <= 6'd13; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd17; end + // 7'd17:begin acc_tsync <= acc_15_reg; num_tsync <= 6'd14; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd18; end + // 7'd18:begin acc_tsync <= acc_16_reg; num_tsync <= 6'd15; flag_tongdao <= 1'd1; flag_TSync_check<= 1'd0; cnt_tsync_shixu <= 4'd0; state_check <=7'd0; end + // endcase + // end + // end + + + + + + + + // integer handle01; + // integer handle02; + + // reg enable = 0; + // initial begin + // handle01=$fopen("TSyncout_i.txt","w"); $fclose(handle01); + // handle02=$fopen("TSyncout_q.txt","w"); $fclose(handle02); + + // #10; + // enable = 1; + // end + + // always@(posedge clk)begin + // if(enable)begin + // if(TSyncout_nd)begin + // handle01=$fopen("TSyncout_i.txt","a+");$fwrite(handle01,"%d\n",$signed(TSyncout_i));$fclose(handle01); + // handle02=$fopen("TSyncout_q.txt","a+");$fwrite(handle02,"%d\n",$signed(TSyncout_q));$fclose(handle02); + // end + // end + // end + + + + +endmodule diff --git a/hdl/TimeSync_top.v b/hdl/TimeSync_top.v new file mode 100644 index 0000000..253f373 --- /dev/null +++ b/hdl/TimeSync_top.v @@ -0,0 +1,196 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 17:44 11/14/2019 +// Design Name: +// Module Name: TimeSync_top +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +module TimeSync_top( + input clk, + input rst, + + input [9:0] dini, + input [9:0] dinq, + + output reg rdy = 1'd0, + output reg [9:0] douti = 10'd0, + output reg [9:0] doutq = 10'd0, + + input vio_tsync_inter16,//12.5 + input framesync, //帧同步标志 + output reg framesync_tsync = 1'd0, //帧同步标志 + + //debug + output reg [1:0] cnt_tsync = 2'd0,//12.5 + output reg [3:0] flag_clk_4bit = 4'd0//12.5 + ); + + + wire [9:0] InterpdoutiA; + wire [9:0] InterpdoutqA; + wire [9:0] InterpdoutiB; + wire [9:0] InterpdoutqB; + wire [9:0] InterpdoutiC; + wire [9:0] InterpdoutqC; + wire [9:0] InterpdoutiD; + wire [9:0] InterpdoutqD; + + wire framesync_Interpolation; + Interpolation Interpolation ( + .clk(clk), + .framesync(framesync), + .framesync_Interpolation(framesync_Interpolation), + .dini(dini), + .dinq(dinq), + .doutiA(InterpdoutiA), + .doutqA(InterpdoutqA), + .doutiB(InterpdoutiB), + .doutqB(InterpdoutqB), + .doutiC(InterpdoutiC), + .doutqC(InterpdoutqC), + .doutiD(InterpdoutiD), + .doutqD(InterpdoutqD) + ); + + + wire rdy_4; + wire [9:0] douti_4; + wire [9:0] doutq_4; + wire [1:0] cnt_4; + wire [1:0] flag_clk4; + wire framesync_out4; + TSync_Abs_new4 TSync_Abs_new4 ( + .clk(clk), + .rst(rst), + .framesync_Interpolation(framesync), + .framesync_out4(framesync_out4), + .dataini(dini), + .datainq(dinq), + .TSyncout_nd(rdy_4), + .TSyncout_i(douti_4), + .TSyncout_q(doutq_4), + + .cnt(cnt_4), + .flag_clk4(flag_clk4) + ); + + + wire rdy_16; + wire [9:0] douti_16; + wire [9:0] doutq_16; + wire [1:0] cnt_16; + wire [1:0] flag_clk16; + wire [1:0] flag_num16; + wire framesync_out16; + TSync_Abs_new16 TSync_Abs_new16 ( + .clk(clk), + .rst(rst), + .framesync_Interpolation(framesync_Interpolation), + .framesync_out16(framesync_out16), + .datain1_i(InterpdoutiA), + .datain1_q(InterpdoutqA), + .datain2_i(InterpdoutiB), + .datain2_q(InterpdoutqB), + .datain3_i(InterpdoutiC), + .datain3_q(InterpdoutqC), + .datain4_i(InterpdoutiD), + .datain4_q(InterpdoutqD), + .TSyncout_nd(rdy_16), + .TSyncout_i(douti_16), + .TSyncout_q(doutq_16), + + .cnt(cnt_16), + .flag_clk16(flag_clk16), + .flag_num16(flag_num16) + ); + + + + always @(posedge clk)begin + if(rst)begin + rdy <= 1'd0; + douti <= 10'd0; + doutq <= 10'd0; + framesync_tsync <= 1'd0; + + cnt_tsync <= 2'd0; + flag_clk_4bit <= 4'd0; + end + else begin + if(vio_tsync_inter16) begin + rdy <= rdy_16; + douti <= douti_16; + doutq <= doutq_16; + framesync_tsync <= framesync_out16; + + cnt_tsync <= cnt_16; + flag_clk_4bit <= {flag_clk16,flag_num16}; + end + else begin + rdy <= rdy_4; + douti <= douti_4; + doutq <= doutq_4; + framesync_tsync <= framesync_out4; + + cnt_tsync <= cnt_4; + flag_clk_4bit <= {2'd0,flag_clk4}; + end + end + end + + + + // integer handle01; + // integer handle02; + // integer handle03; + // integer handle04; + // integer handle05; + // integer handle06; + // integer handle07; + // integer handle08; + + // reg enable1 = 0; + // initial begin + // handle01=$fopen("InterpdoutiA.txt","w"); $fclose(handle01); + // handle02=$fopen("InterpdoutqA.txt","w"); $fclose(handle02); + // handle03=$fopen("InterpdoutiB.txt","w"); $fclose(handle03); + // handle04=$fopen("InterpdoutqB.txt","w"); $fclose(handle04); + // handle05=$fopen("InterpdoutiC.txt","w"); $fclose(handle05); + // handle06=$fopen("InterpdoutqC.txt","w"); $fclose(handle06); + // handle07=$fopen("InterpdoutiD.txt","w"); $fclose(handle07); + // handle08=$fopen("InterpdoutqD.txt","w"); $fclose(handle08); + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + + // handle01=$fopen("InterpdoutiA.txt","a+");$fwrite(handle01,"%d\n",$signed(InterpdoutiA));$fclose(handle01); + // handle02=$fopen("InterpdoutqA.txt","a+");$fwrite(handle02,"%d\n",$signed(InterpdoutqA));$fclose(handle02); + // handle03=$fopen("InterpdoutiB.txt","a+");$fwrite(handle03,"%d\n",$signed(InterpdoutiB));$fclose(handle03); + // handle04=$fopen("InterpdoutqB.txt","a+");$fwrite(handle04,"%d\n",$signed(InterpdoutqB));$fclose(handle04); + // handle05=$fopen("InterpdoutiC.txt","a+");$fwrite(handle05,"%d\n",$signed(InterpdoutiC));$fclose(handle05); + // handle06=$fopen("InterpdoutqC.txt","a+");$fwrite(handle06,"%d\n",$signed(InterpdoutqC));$fclose(handle06); + // handle07=$fopen("InterpdoutiD.txt","a+");$fwrite(handle07,"%d\n",$signed(InterpdoutiD));$fclose(handle07); + // handle08=$fopen("InterpdoutqD.txt","a+");$fwrite(handle08,"%d\n",$signed(InterpdoutqD));$fclose(handle08); + + // end + // end + +endmodule diff --git a/hdl/data_equalizer.v b/hdl/data_equalizer.v new file mode 100644 index 0000000..d7b00ad --- /dev/null +++ b/hdl/data_equalizer.v @@ -0,0 +1,624 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2020/01/04 21:09:20 +// Design Name: +// Module Name: data_equalizer +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module data_equalizer( + input clk, + input rst, + input EQUenable_vio, + + input nd_pilot2, + input flag_ChnEstFFT_done, //信道估计两次fft输入完毕后拉高1clk(Chn_Estimate给出) + + //数据的fifo,4个 + input [9:0] dout_data1i, + input [9:0] dout_data1q, + output reg rd_en_data1 = 1'd0, + input [9:0] dout_data2i, + input [9:0] dout_data2q, + output reg rd_en_data2 = 1'd0, + input flag_dataow, //拉高1clk,说明一段数据ow存储完毕,后端可开始连续读取 + + //fft核 + input [25:0] fft_out_i, + input [25:0] fft_out_q, + input fft_out_nd, + input [7:0] fft_index, + output reg [16:0] fft_in_i = 17'd0, + output reg [16:0] fft_in_q = 17'd0, + output reg fft_in_nd = 1'd0, + + //ifft核 + input [28:0] ifft_out_i, + input [28:0] ifft_out_q, + input ifft_out_nd, + input [7:0] ifft_index, + output reg [19:0] ifft_in_i = 20'd0, + output reg [19:0] ifft_in_q = 20'd0, + output reg ifft_in_nd = 1'd0, + + //MMSE信道估计结果RAM + output reg [7:0] addrout_MMSE = 8'd0, + input [21:0] dout_MMSE, + + //均衡结果输出 + output reg nd_SC_FDE_dout = 1'd0, + output reg [9:0] SC_FDE_douti = 10'd0, + output reg [9:0] SC_FDE_doutq = 10'd0, + + //debug,溢出标志 + output reg flagoverflow_ifftindata_28to20i = 1'd0, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output reg flagoverflow_ifftindata_28to20q = 1'd0, //均衡完毕后(频域结果)的截位,即乘法器输出结果的截位,28截到20 + output reg flagoverflow_fftdata_26to16i = 1'd0, //数据段ow的fft输出截位,26截到16 + output reg flagoverflow_fftdata_26to16q = 1'd0, //数据段ow的fft输出截位,26截到16 + output reg flagoverflow_FDE_dataout_29to10i = 1'd0, //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + output reg flagoverflow_FDE_dataout_29to10q = 1'd0 //ifft结果截位,即均衡结果处,结果先除掉低8位,29-7=22截到10 + + ); + + + + //----------------------------------------------------fft的输入控制状态机---------------------------------------------------------// + reg [3:0] state_fftin = 4'd0; + reg [7:0] cnt_256 = 8'd0; + + always @(posedge clk)begin + if(rst)begin + state_fftin <= 4'd0; + cnt_256 <= 8'd0; + + rd_en_data1 <= 1'd0; + rd_en_data2 <= 1'd0; + + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + end + else begin + case(state_fftin) + //帧间复位结束后,等待nd_pilot2,即导频部分全部到达 + 4'd0:begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + if(nd_pilot2) state_fftin <= state_fftin + 4'd1; + else state_fftin <= state_fftin; + end + + //等待flag_ChnEstFFT_done,即信道估计的两次fft输入全部完成 + 4'd1:begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + if(flag_ChnEstFFT_done) state_fftin <= state_fftin + 4'd1; + else state_fftin <= state_fftin; + end + + //计数60clk,开始输入第一组data的ow给fft,保证其输出的时候MMSE信道估计结果已全部准备完毕 + 4'd2:begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + rd_en_data2 <= 1'd0; + if(cnt_256==8'd60) begin + rd_en_data1 <= 1'd1; + cnt_256 <= 8'd0; + state_fftin <= state_fftin + 4'd1; + end + else begin + rd_en_data1 <= 1'd0; + cnt_256 <= cnt_256 + 8'd1; + state_fftin <= state_fftin; + end + end + + //从rd_en_data1为1的第一个clk开始,输出第0组数据。rd_en_data1保持有效共需256clk,即最后一个clk的数据出到出口时仍需一个读nd(用于读空fifo) + 4'd3:begin + rd_en_data2 <= 1'd0; + if(cnt_256==8'd254) begin + rd_en_data1 <= 1'd1; + fft_in_i <= {{7{dout_data1i[9]}},dout_data1i}; + fft_in_q <= {{7{dout_data1q[9]}},dout_data1q}; + fft_in_nd <= 1'd1; + cnt_256 <= 6'd0; + state_fftin <= state_fftin + 4'd1; + end + else begin + rd_en_data1 <= 1'd1; + fft_in_i <= {{7{dout_data1i[9]}},dout_data1i}; + fft_in_q <= {{7{dout_data1q[9]}},dout_data1q}; + fft_in_nd <= 1'd1; + cnt_256 <= cnt_256 + 6'd1; + state_fftin <= state_fftin; + end + end + 4'd4:begin + rd_en_data2 <= 1'd0; + rd_en_data1 <= 1'd0; + fft_in_i <= {{7{dout_data1i[9]}},dout_data1i}; + fft_in_q <= {{7{dout_data1q[9]}},dout_data1q}; + fft_in_nd <= 1'd1; + cnt_256 <= 6'd0; + state_fftin <= state_fftin + 4'd1; + end + + //data1读空,等待flag_dataow,说明下一个256数据段缓存完毕,可以取用 + 4'd5:begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + rd_en_data1 <= 1'd0; + cnt_256 <= 8'd0; + if(flag_dataow) begin + rd_en_data2 <= 1'd1; + state_fftin <= state_fftin + 4'd1; + end + else begin + rd_en_data2 <= 1'd0; + state_fftin <= state_fftin; + end + end + + //从rd_en_data2为1的第一个clk开始,输出第0组数据。rd_en_data2保持有效共需256clk,即最后一个clk的数据出到出口时仍需一个读nd(用于读空fifo) + 4'd6:begin + rd_en_data1 <= 1'd0; + if(cnt_256==8'd254) begin + rd_en_data2 <= 1'd1; + fft_in_i <= {{7{dout_data2i[9]}},dout_data2i}; + fft_in_q <= {{7{dout_data2q[9]}},dout_data2q}; + fft_in_nd <= 1'd1; + cnt_256 <= 6'd0; + state_fftin <= state_fftin + 4'd1; + end + else begin + rd_en_data2 <= 1'd1; + fft_in_i <= {{7{dout_data2i[9]}},dout_data2i}; + fft_in_q <= {{7{dout_data2q[9]}},dout_data2q}; + fft_in_nd <= 1'd1; + cnt_256 <= cnt_256 + 6'd1; + state_fftin <= state_fftin; + end + end + 4'd7:begin + rd_en_data2 <= 1'd0; + rd_en_data1 <= 1'd0; + fft_in_i <= {{7{dout_data2i[9]}},dout_data2i}; + fft_in_q <= {{7{dout_data2q[9]}},dout_data2q}; + fft_in_nd <= 1'd1; + cnt_256 <= 6'd0; + state_fftin <= state_fftin + 4'd1; + end + + //data2读空,等待flag_dataow,说明下一个256数据段缓存完毕,可以取用;或等待nd_pilot2,说明本数据段结束,下一数据段的导频缓存完毕 + 4'd8:begin + fft_in_i <= 17'd0; + fft_in_q <= 17'd0; + fft_in_nd <= 1'd0; + rd_en_data2 <= 1'd0; + cnt_256 <= 8'd0; + if(flag_dataow) begin + rd_en_data1 <= 1'd1; + state_fftin <= 4'd3; + end + else begin + if(nd_pilot2) begin + rd_en_data1 <= 1'd0; + state_fftin <= 4'd1; + end + else begin + rd_en_data1 <= 1'd0; + state_fftin <= state_fftin; + end + end + end + default:state_fftin <= 4'd0; + endcase + end + end + + + + + + + //----------------------------------------------------fft的输出控制状态机---------------------------------------------------------// + reg [1:0] state_fftout = 2'd0; + reg fft_out_nd_d1 = 1'd0; + reg [25:0] fft_out_i_d1 = 26'd0; + reg [25:0] fft_out_q_d1 = 26'd0; + + always @(posedge clk)begin + if(rst)begin + state_fftout <= 2'd0; + + fft_out_nd_d1 <= 1'd0; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + end + else begin + case(state_fftout) + //帧间复位结束后,等待nd_pilot2,即导频部分全部到达 + 2'd0:begin + fft_out_nd_d1 <= 1'd0; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + if(nd_pilot2) state_fftout <= state_fftout + 2'd1; + else state_fftout <= state_fftout; + end + + //等待flag_ChnEstFFT_done,即信道估计的两次fft输入全部完成 + 2'd1:begin + fft_out_nd_d1 <= 1'd0; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + if(flag_ChnEstFFT_done) state_fftout <= state_fftout + 2'd1; + else state_fftout <= state_fftout; + end + + //等待第一组fft结果输出完毕。此组结果应为信道估计的第二次fft结果,本模块不取用 + 2'd2:begin + fft_out_nd_d1 <= 1'd0; + fft_out_i_d1 <= 26'd0; + fft_out_q_d1 <= 26'd0; + if(fft_index==8'd255) state_fftout <= state_fftout + 2'd1; + else state_fftout <= state_fftout; + + end + + //fft_out_nd指示fft结果有效。将fft输出延时1clk。nd_pilot2有效说明下一帧的导频部分输入完毕,转回状态1 + 2'd3:begin + fft_out_nd_d1 <= fft_out_nd; + fft_out_i_d1 <= fft_out_i; + fft_out_q_d1 <= fft_out_q; + if(nd_pilot2) state_fftout <= 2'd1; + else state_fftout <= state_fftout; + end + endcase + end + end + + + + + + //----------------------------------------------------复数乘法器+输出截位及溢出标志---------------------------------------------------------// + reg mulin_nd = 1'd0; + reg [15:0] mulin_ai = 16'd0; + reg [15:0] mulin_aq = 16'd0; + reg [10:0] mulin_bi = 11'd0; + reg [10:0] mulin_bq = 11'd0; + wire mulout_nd; + wire[63:0] mulout_data; + + SC_FDE_commul SC_FDE_commul ( + .aclk (clk), // input wire aclk + .s_axis_a_tvalid (mulin_nd), // input wire s_axis_a_tvalid + .s_axis_a_tdata ({mulin_aq,mulin_ai}), // input wire [31 : 0] s_axis_a_tdata + .s_axis_b_tvalid (mulin_nd), // input wire s_axis_b_tvalid + .s_axis_b_tdata ({5'd0,mulin_bq,5'd0,mulin_bi}), // input wire [31 : 0] s_axis_b_tdata + .m_axis_dout_tvalid (mulout_nd), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata (mulout_data) // output wire [63 : 0] m_axis_dout_tdata + ); + + wire [27:0] mulout_datai; + wire [27:0] mulout_dataq; + assign mulout_datai = mulout_data[27:0]; + assign mulout_dataq = mulout_data[59:32]; + + + + + reg mulifft_nd = 1'd0; + reg [19:0] mulifft_datai = 20'd0; + reg [19:0] mulifft_dataq = 20'd0; + + always @(posedge clk)begin + if(rst)begin + mulifft_nd <= 1'd0; + mulifft_datai <= 20'd0; + mulifft_dataq <= 20'd0; + flagoverflow_ifftindata_28to20i <= 1'd0; + flagoverflow_ifftindata_28to20q <= 1'd0; + end + else begin + if(mulout_nd) begin + mulifft_nd <= 1'd1; + if(mulout_datai[27:19]!=9'd511&&mulout_datai[27:19]!=9'd0) begin + flagoverflow_ifftindata_28to20i <= 1'd1; + mulifft_datai <= (mulout_datai[27])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else begin + flagoverflow_ifftindata_28to20i <= 1'd0; + mulifft_datai <= mulout_datai[19:0]; + end + if(mulout_dataq[27:19]!=9'd511&&mulout_dataq[27:19]!=9'd0) begin + flagoverflow_ifftindata_28to20q <= 1'd1; + mulifft_dataq <= (mulout_dataq[27])? 20'b1000_0000_0000_0000_0000 : 20'b0111_1111_1111_1111_1111; + end + else begin + flagoverflow_ifftindata_28to20q <= 1'd0; + mulifft_dataq <= mulout_dataq[19:0]; + end + end + else begin + mulifft_nd <= 1'd0; + mulifft_datai <= 20'd0; + mulifft_dataq <= 20'd0; + flagoverflow_ifftindata_28to20i <= 1'd0; + flagoverflow_ifftindata_28to20q <= 1'd0; + end + + end + end + + + //----------------------------------------------------复数乘法器输入控制状态机---------------------------------------------------------// + reg mulin_nd_d0 = 1'd0; + reg [15:0] mulin_i_d0 = 16'd0; + reg [15:0] mulin_q_d0 = 16'd0; + + always @(posedge clk)begin + if(rst)begin + addrout_MMSE <= 8'd0; + mulin_nd_d0 <= 1'd0; + mulin_i_d0 <= 16'd0; + mulin_q_d0 <= 16'd0; + flagoverflow_fftdata_26to16i <= 1'd0; + flagoverflow_fftdata_26to16q <= 1'd0; + + mulin_nd <= 1'd0; + mulin_ai <= 16'd0; + mulin_aq <= 16'd0; + mulin_bi <= 11'd0; + mulin_bq <= 11'd0; + end + else begin + //fft输出再延时1clk,利用这个延时取出mmse信道估计结果。截位到16bit,设置溢出标志 + if(fft_out_nd_d1) begin + addrout_MMSE <= addrout_MMSE + 8'd1; + mulin_nd_d0 <= 1'd1; + if(fft_out_i_d1[25:15]!=11'd2047&&fft_out_i_d1[25:15]!=11'd0) begin + flagoverflow_fftdata_26to16i <= 1'd1; + mulin_i_d0 <= (fft_out_i_d1[25])? 16'b1000_0000_0000_0000 : 16'b0111_1111_1111_1111; + end + else begin + flagoverflow_fftdata_26to16i <= 1'd0; + mulin_i_d0 <= fft_out_i_d1[15:0]; + end + if(fft_out_q_d1[25:15]!=11'd2047&&fft_out_q_d1[25:15]!=11'd0) begin + flagoverflow_fftdata_26to16q <= 1'd1; + mulin_q_d0 <= (fft_out_q_d1[25])? 16'b1000_0000_0000_0000 : 16'b0111_1111_1111_1111; + end + else begin + flagoverflow_fftdata_26to16q <= 1'd0; + mulin_q_d0 <= fft_out_q_d1[15:0]; + end + end + else begin + addrout_MMSE <= 8'd0; + mulin_nd_d0 <= 1'd0; + mulin_i_d0 <= 16'd0; + mulin_q_d0 <= 16'd0; + flagoverflow_fftdata_26to16i <= 1'd0; + flagoverflow_fftdata_26to16q <= 1'd0; + end + + if(mulin_nd_d0) begin + mulin_nd <= 1'd1; + mulin_ai <= mulin_i_d0; + mulin_aq <= mulin_q_d0; + if(EQUenable_vio) begin + mulin_bi <= dout_MMSE[10:0]; + mulin_bq <= dout_MMSE[21:11]; + end + else begin + mulin_bi <= 11'd1; + mulin_bq <= 11'd0; + end + end + else begin + mulin_nd <= 1'd0; + mulin_ai <= 16'd0; + mulin_aq <= 16'd0; + mulin_bi <= 11'd0; + mulin_bq <= 11'd0; + end + end + end + + + + + + + + //----------------------------------------------------乘法器输出->ifft的输入控制------------------------------------------------------// + always @(posedge clk)begin + if(rst)begin + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + end + else begin + if(mulifft_nd) begin + ifft_in_i <= mulifft_datai; + ifft_in_q <= mulifft_dataq; + ifft_in_nd <= 1'd1; + end + else begin + ifft_in_i <= 20'd0; + ifft_in_q <= 20'd0; + ifft_in_nd <= 1'd0; + end + end + end + + + + + + + + //-----------------------------------------------ifft的输出控制+截位+溢出标志设置--------------------------------------------------// + reg ifft_out_ce = 1'd0; + reg ifft_out_nd_d1 = 1'd0; + reg [28:0] ifft_out_i_d1 = 29'd0; + reg [28:0] ifft_out_q_d1 = 29'd0; + + always @(posedge clk)begin + if(rst)begin + ifft_out_ce <= 1'd0; + ifft_out_nd_d1 <= 1'd0; + ifft_out_i_d1 <= 29'd0; + ifft_out_q_d1 <= 29'd0; + end + else begin + if(ifft_out_ce==1'd0) begin + if(flag_ChnEstFFT_done) begin + ifft_out_ce <= 1'd1; + end + else begin + ifft_out_ce <= 1'd0; + end + ifft_out_nd_d1 <= 1'd0; + ifft_out_i_d1 <= 29'd0; + ifft_out_q_d1 <= 29'd0; + end + else begin + if(nd_pilot2) begin + ifft_out_ce <= 1'd0; + end + else begin + ifft_out_ce <= 1'd1; + end + ifft_out_nd_d1 <= ifft_out_nd; + ifft_out_i_d1 <= ifft_out_i; + ifft_out_q_d1 <= ifft_out_q; + end + end + end + + + always @(posedge clk)begin + if(rst)begin + nd_SC_FDE_dout <= 1'd0; + SC_FDE_douti <= 10'd0; + SC_FDE_doutq <= 10'd0; + flagoverflow_FDE_dataout_29to10i <= 1'd0; + flagoverflow_FDE_dataout_29to10q <= 1'd0; + end + else begin + if(ifft_out_nd_d1) begin + nd_SC_FDE_dout <= 1'd1; + if(EQUenable_vio) begin //均衡开启,结果保留10bit,低位截掉8+5=13bit + if(ifft_out_i_d1[28:22]!=7'd127&&ifft_out_i_d1[28:22]!=7'd0) begin + flagoverflow_FDE_dataout_29to10i <= 1'd1; + SC_FDE_douti <= (ifft_out_i_d1[28])? 10'b100000_0000 : 10'b01_1111_1111; + end + else begin + flagoverflow_FDE_dataout_29to10i <= 1'd0; + SC_FDE_douti <= ifft_out_i_d1[22:13]; + end + if(ifft_out_q_d1[28:22]!=7'd127&&ifft_out_q_d1[28:22]!=7'd0) begin + flagoverflow_FDE_dataout_29to10q <= 1'd1; + SC_FDE_doutq <= (ifft_out_q_d1[28])? 10'b100000_0000 : 10'b01_1111_1111; + end + else begin + flagoverflow_FDE_dataout_29to10q <= 1'd0; + SC_FDE_doutq <= ifft_out_q_d1[22:13]; + end + end + else begin //均衡关闭,结果保留10bit,低位截掉8bit(结果应与输入相同) + if(ifft_out_i_d1[28:17]!=12'd4095&&ifft_out_i_d1[28:17]!=12'd0) begin + flagoverflow_FDE_dataout_29to10i <= 1'd1; + SC_FDE_douti <= (ifft_out_i_d1[28])? 10'b100000_0000 : 10'b01_1111_1111; + end + else begin + flagoverflow_FDE_dataout_29to10i <= 1'd0; + SC_FDE_douti <= ifft_out_i_d1[17:8]; + end + if(ifft_out_q_d1[28:17]!=12'd4095&&ifft_out_q_d1[28:17]!=12'd0) begin + flagoverflow_FDE_dataout_29to10q <= 1'd1; + SC_FDE_doutq <= (ifft_out_q_d1[28])? 10'b100000_0000 : 10'b01_1111_1111; + end + else begin + flagoverflow_FDE_dataout_29to10q <= 1'd0; + SC_FDE_doutq <= ifft_out_q_d1[17:8]; + end + end + end + else begin + nd_SC_FDE_dout <= 1'd0; + SC_FDE_douti <= 10'd0; + SC_FDE_doutq <= 10'd0; + flagoverflow_FDE_dataout_29to10i <= 1'd0; + flagoverflow_FDE_dataout_29to10q <= 1'd0; + end + end + end + + + + + + + + //------------------------------------------------------仿真文件保存---------------------------------------------------// + // integer handle01; + // integer handle02; + // integer handle03; + // integer handle04; + // integer handle05; + // integer handle06; + + // reg enable1 = 0; + // initial begin + + // handle01=$fopen("mulin_ai.txt","w"); $fclose(handle01); + // handle02=$fopen("mulin_aq.txt","w"); $fclose(handle02); + // handle03=$fopen("mulin_bi.txt","w"); $fclose(handle03); + // handle04=$fopen("mulin_bq.txt","w"); $fclose(handle04); + // handle05=$fopen("mulout_datai.txt","w"); $fclose(handle05); + // handle06=$fopen("mulout_dataq.txt","w"); $fclose(handle06); + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + + // if(mulin_nd)begin + // handle01=$fopen("mulin_ai.txt","a+");$fwrite(handle01,"%d\n",$signed(mulin_ai));$fclose(handle01); + // handle02=$fopen("mulin_aq.txt","a+");$fwrite(handle02,"%d\n",$signed(mulin_aq));$fclose(handle02); + // handle03=$fopen("mulin_bi.txt","a+");$fwrite(handle03,"%d\n",$signed(mulin_bi));$fclose(handle03); + // handle04=$fopen("mulin_bq.txt","a+");$fwrite(handle04,"%d\n",$signed(mulin_bq));$fclose(handle04); + // end + // if(mulout_nd)begin + // handle05=$fopen("mulout_datai.txt","a+");$fwrite(handle05,"%d\n",$signed(mulout_datai));$fclose(handle05); + // handle06=$fopen("mulout_dataq.txt","a+");$fwrite(handle06,"%d\n",$signed(mulout_dataq));$fclose(handle06); + // end + // end + // end + + + +endmodule diff --git a/hdl/data_ow.v b/hdl/data_ow.v new file mode 100644 index 0000000..d500839 --- /dev/null +++ b/hdl/data_ow.v @@ -0,0 +1,542 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/12/19 16:14:42 +// Design Name: +// Module Name: data_ow +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module data_ow( + input clk, + input rst, + + input flag_ow_left, + input nd, + input [9:0] dini, + input [9:0] dinq, + + //数据的fifo,4个 + output reg [9:0] din_data1i = 10'd0, + output reg [9:0] din_data1q = 10'd0, + output reg wr_en_data1 = 1'd0, + output reg [9:0] din_data2i = 10'd0, + output reg [9:0] din_data2q = 10'd0, + output reg wr_en_data2 = 1'd0, + output reg flag_dataow = 1'd0, //拉高1clk,说明一段数据ow存储完毕,后端可开始连续读取 + + //正负导频段的加减结果 + output reg nd_pilot2 = 1'd0, + output reg [9:0] pilot_datai = 10'd0, + output reg [9:0] pilot_dataq = 10'd0, + output reg [9:0] pilot_noisei = 10'd0, + output reg [9:0] pilot_noiseq = 10'd0 + ); + + //导频的fifo,4个 + reg [9:0] din_pilot1i = 10'd0; + reg wr_en_pilot1 = 1'd0; + reg rd_en_pilot = 1'd0; + wire [9:0] dout_pilot1i; + wire full_pilot1i; + wire empty_pilot1i; + fifo_ow256 fifo_pilot_ow1i ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_pilot1i), // input wire [9 : 0] din + .wr_en (wr_en_pilot1), // input wire wr_en + .rd_en (rd_en_pilot), // input wire rd_en + .dout (dout_pilot1i), // output wire [9 : 0] dout + .full (full_pilot1i), // output wire full + .empty (empty_pilot1i) // output wire empty + ); + + reg [9:0] din_pilot1q = 10'd0; + // reg wr_en_pilot1q = 1'd0; + // reg rd_en_pilot1q = 1'd0; + wire [9:0] dout_pilot1q; + wire full_pilot1q; + wire empty_pilot1q; + fifo_ow256 fifo_pilot_ow1q ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_pilot1q), // input wire [9 : 0] din + .wr_en (wr_en_pilot1), // input wire wr_en + .rd_en (rd_en_pilot), // input wire rd_en + .dout (dout_pilot1q), // output wire [9 : 0] dout + .full (full_pilot1q), // output wire full + .empty (empty_pilot1q) // output wire empty + ); + + reg [9:0] din_pilot2i = 10'd0; + reg wr_en_pilot2 = 1'd0; + // reg rd_en_pilot2 = 1'd0; + wire [9:0] dout_pilot2i; + wire full_pilot2i; + wire empty_pilot2i; + fifo_ow256 fifo_pilot_ow2i ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_pilot2i), // input wire [9 : 0] din + .wr_en (wr_en_pilot2), // input wire wr_en + .rd_en (rd_en_pilot), // input wire rd_en + .dout (dout_pilot2i), // output wire [9 : 0] dout + .full (full_pilot2i), // output wire full + .empty (empty_pilot2i) // output wire empty + ); + + reg [9:0] din_pilot2q = 10'd0; + // reg wr_en_pilot2q = 1'd0; + // reg rd_en_pilot2q = 1'd0; + wire [9:0] dout_pilot2q; + wire full_pilot2q; + wire empty_pilot2q; + fifo_ow256 fifo_pilot_ow2q ( + .rst (rst), // input wire rst + .wr_clk (clk), // input wire wr_clk + .rd_clk (clk), // input wire rd_clk + .din (din_pilot2q), // input wire [9 : 0] din + .wr_en (wr_en_pilot2), // input wire wr_en + .rd_en (rd_en_pilot), // input wire rd_en + .dout (dout_pilot2q), // output wire [9 : 0] dout + .full (full_pilot2q), // output wire full + .empty (empty_pilot2q) // output wire empty + ); + + + reg [4:0] state_ow = 5'd0; + reg [7:0] cnt_256 = 8'd0; + reg [0:0] flag_pilot = 1'd0; + reg [3:0] cnt_10data = 1'd0; + reg [5:0] cnt_42block = 6'd0; + + always @(posedge clk)begin + if(rst)begin + state_ow <= 5'd0; + cnt_256 <= 8'd0; + flag_pilot <= 1'd0; + flag_dataow <= 1'd0; + cnt_10data <= 4'd0; + cnt_42block <= 6'd0; + + din_pilot1i <= 10'd0; + din_pilot1q <= 10'd0; + wr_en_pilot1 <= 1'd0; + din_pilot2i <= 10'd0; + din_pilot2q <= 10'd0; + wr_en_pilot2 <= 1'd0; + + din_data1i <= 10'd0; + din_data1q <= 10'd0; + wr_en_data1 <= 1'd0; + din_data2i <= 10'd0; + din_data2q <= 10'd0; + wr_en_data2 <= 1'd0; + end + else begin + case(state_ow) + //等待帧同步指示。flag_ow_left与正导频段OW的左边界对齐。(要求flag_ow_left为高时nd也需有效) + 5'd0:begin + if(flag_ow_left) begin + din_pilot1i <= dini; + din_pilot1q <= dinq; + wr_en_pilot1 <= 1'd1; + din_pilot2i <= din_pilot2i; + din_pilot2q <= din_pilot2q; + wr_en_pilot2 <= 1'd0; + + cnt_256 <= cnt_256 + 8'd1; + state_ow <= state_ow + 5'd1; + end + else begin + din_pilot1i <= din_pilot1i; + din_pilot1q <= din_pilot1q; + wr_en_pilot1 <= 1'd0; + din_pilot2i <= din_pilot2i; + din_pilot2q <= din_pilot2q; + wr_en_pilot2 <= 1'd0; + + cnt_256 <= 8'd0; + state_ow <= state_ow; + end + din_data1i <= din_data1i; + din_data1q <= din_data1q; + wr_en_data1 <= 1'd0; + din_data2i <= din_data2i; + din_data2q <= din_data2q; + wr_en_data2 <= 1'd0; + flag_pilot <= 1'd0; + cnt_10data <= 4'd0; + cnt_42block <= 6'd0; + end + + //等待正导频头全部存储完毕,256个nd + 5'd1:begin + if(nd) begin + if(cnt_256==8'd255) state_ow <= state_ow + 5'd1; + else state_ow <= state_ow; + din_pilot1i <= dini; + din_pilot1q <= dinq; + wr_en_pilot1 <= 1'd1; + din_pilot2i <= din_pilot2i; + din_pilot2q <= din_pilot2q; + wr_en_pilot2 <= 1'd0; + + cnt_256 <= cnt_256 + 8'd1; + end + else begin + din_pilot1i <= din_pilot1i; + din_pilot1q <= din_pilot1q; + wr_en_pilot1 <= 1'd0; + din_pilot2i <= din_pilot2i; + din_pilot2q <= din_pilot2q; + wr_en_pilot2 <= 1'd0; + + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + flag_pilot <= 1'd0; + cnt_10data <= 4'd0; + cnt_42block <= cnt_42block; + end + + //计数数过32cp间隔 + 5'd2:begin + if(nd) begin + if(cnt_256==8'd31) begin + cnt_256 <= 8'd0; + state_ow <= state_ow + 5'd1; + end + else begin + cnt_256 <= cnt_256 + 8'd1; + state_ow <= state_ow; + end + end + else begin + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + wr_en_pilot1 <= 1'd0; + wr_en_pilot2 <= 1'd0; + wr_en_data1 <= 1'd0; + wr_en_data2 <= 1'd0; + end + + //存储第二段导频头(负导频头),长度256。导频缓存全部结束,给出flag_pilot,指示另一状态机:信道估计可以开始 + 5'd3:begin + if(nd) begin + if(cnt_256==8'd255) begin + flag_pilot <= 1'd1; + state_ow <= state_ow + 5'd1; + end + else begin + flag_pilot <= 1'd0; + state_ow <= state_ow; + end + din_pilot1i <= din_pilot1i; + din_pilot1q <= din_pilot1q; + wr_en_pilot1 <= 1'd0; + din_pilot2i <= dini; + din_pilot2q <= dinq; + wr_en_pilot2 <= 1'd1; + + cnt_256 <= cnt_256 + 8'd1; + end + else begin + din_pilot1i <= din_pilot1i; + din_pilot1q <= din_pilot1q; + wr_en_pilot1 <= 1'd0; + din_pilot2i <= din_pilot2i; + din_pilot2q <= din_pilot2q; + wr_en_pilot2 <= 1'd0; + + flag_pilot <= 1'd0; + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + end + + //计数数过32cp间隔 + 5'd4:begin + if(nd) begin + if(cnt_256==8'd31) begin + cnt_10data <= cnt_10data + 4'd1; //cnt_10data代表接下来要存储的数据段为第几段(从1到10计数) + cnt_256 <= 8'd0; + state_ow <= state_ow + 5'd1; + end + else begin + cnt_10data <= cnt_10data; + cnt_256 <= cnt_256 + 8'd1; + state_ow <= state_ow; + end + end + else begin + cnt_10data <= cnt_10data; + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + wr_en_pilot1 <= 1'd0; + wr_en_pilot2 <= 1'd0; + wr_en_data1 <= 1'd0; + wr_en_data2 <= 1'd0; + flag_pilot <= 1'd0; + flag_dataow <= 1'd0; + end + + //存储数据段,长度256 + 5'd5:begin + if(nd) begin + if(cnt_256==8'd255) state_ow <= state_ow + 5'd1; + else state_ow <= state_ow; + if(cnt_10data[0]==1'd1) begin + din_data1i <= dini; + din_data1q <= dinq; + wr_en_data1 <= 1'd1; + din_data2i <= din_data2i; + din_data2q <= din_data2q; + wr_en_data2 <= 1'd0; + end + else begin + din_data1i <= din_data1i; + din_data1q <= din_data1q; + wr_en_data1 <= 1'd0; + din_data2i <= dini; + din_data2q <= dinq; + wr_en_data2 <= 1'd1; + end + cnt_256 <= cnt_256 + 8'd1; + end + else begin + din_data1i <= din_data1i; + din_data1q <= din_data1q; + wr_en_data1 <= 1'd0; + din_data2i <= din_data2i; + din_data2q <= din_data2q; + wr_en_data2 <= 1'd0; + + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + end + + //数据段最后一个nd的下一clk,此刻一定没有nd。利用这一时钟判断是否为数据段内最后一段256数据 + //同时利用这一时段给出flag_dataow,标志一段数据段ow存储完毕,后端可开始连续读取 + 5'd6:begin + if(cnt_10data==4'd10) begin //第10个256,当前数据段结束 + if(cnt_42block==6'd41) begin //42个数据段,当前帧结束,转至末尾状态31等待帧间复位即可 + cnt_42block <= 6'd0; + state_ow <= 5'd31; + end + else begin + cnt_42block <= cnt_42block + 6'd1; + state_ow <= state_ow + 5'd1; + end + cnt_10data <= 4'd0; + end + else begin + cnt_10data <= cnt_10data; + cnt_42block <= cnt_42block; + state_ow <= 5'd4; + end + wr_en_data1 <= 1'd0; + wr_en_data2 <= 1'd0; + flag_dataow <= 1'd1; + end + + //计数数过32cp间隔,之后来到正导频头缓存状态 + 5'd7:begin + if(nd) begin + if(cnt_256==8'd31) begin + cnt_10data <= cnt_10data; //cnt_10data代表接下来要存储的数据段为第几段(从1到10计数) + cnt_256 <= 8'd0; + state_ow <= 5'd1; + end + else begin + cnt_10data <= cnt_10data; + cnt_256 <= cnt_256 + 8'd1; + state_ow <= state_ow; + end + end + else begin + cnt_10data <= cnt_10data; + cnt_256 <= cnt_256; + state_ow <= state_ow; + end + wr_en_pilot1 <= 1'd0; + wr_en_pilot2 <= 1'd0; + wr_en_data1 <= 1'd0; + wr_en_data2 <= 1'd0; + flag_pilot <= 1'd0; + flag_dataow <= 1'd0; + end + + //一帧结束,等待复位 + 5'd31:begin + state_ow <= 5'd31; + flag_pilot <= 1'd0; + flag_dataow <= 1'd0; + end + + default:state_ow<= 5'd31; + endcase + end + end + + + + reg [2:0] state_pilot = 3'd0; + reg [7:0] cnt_256pilot = 8'd0; + reg [0:0] nd_pilot = 1'd0; + reg [10:0] pilot_sumi = 11'd0; + reg [10:0] pilot_sumq = 11'd0; + reg [10:0] pilot_diffi = 11'd0; + reg [10:0] pilot_diffq = 11'd0; + + always @(posedge clk)begin + if(rst)begin + state_pilot <= 3'd0; + cnt_256pilot <= 8'd0; + rd_en_pilot <= 1'd0; + nd_pilot <= 1'd0; + pilot_sumi <= 11'd0; + pilot_sumq <= 11'd0; + pilot_diffi <= 11'd0; + pilot_diffq <= 11'd0; + end + else begin + case(state_pilot) + //等待flag_pilot指示。说明两段导频缓存完毕 + 3'd0:begin + if(flag_pilot) begin + nd_pilot <= 1'd0; + rd_en_pilot <= 1'd1; + pilot_sumi <= pilot_sumi; + pilot_sumq <= pilot_sumq; + pilot_diffi <= pilot_diffi; + pilot_diffq <= pilot_diffq; + cnt_256pilot <= 8'd0; + state_pilot <= state_pilot + 3'd1; + end + else begin + nd_pilot <= 1'd0; + rd_en_pilot <= 1'd0; + pilot_sumi <= pilot_sumi; + pilot_sumq <= pilot_sumq; + pilot_diffi <= pilot_diffi; + pilot_diffq <= pilot_diffq; + cnt_256pilot <= 8'd0; + state_pilot <= state_pilot; + end + end + + //从rd_en_pilot为1的第一个clk开始,输出第0组数据。rd_en_pilot保持有效共需256clk,即最后一个clk的数据出到出口时仍需一个读nd(用读空fifo) + 3'd1:begin + if(cnt_256pilot==8'd254) begin + nd_pilot <= 1'd1; + rd_en_pilot <= 1'd1; + pilot_sumi <= {dout_pilot1i[9],dout_pilot1i} + {dout_pilot2i[9],dout_pilot2i}; + pilot_sumq <= {dout_pilot1q[9],dout_pilot1q} + {dout_pilot2q[9],dout_pilot2q}; + pilot_diffi <= {dout_pilot1i[9],dout_pilot1i} - {dout_pilot2i[9],dout_pilot2i}; + pilot_diffq <= {dout_pilot1q[9],dout_pilot1q} - {dout_pilot2q[9],dout_pilot2q}; + cnt_256pilot <= 8'd0; + state_pilot <= state_pilot + 3'd1; + end + else begin + nd_pilot <= 1'd1; + rd_en_pilot <= 1'd1; + pilot_sumi <= {dout_pilot1i[9],dout_pilot1i} + {dout_pilot2i[9],dout_pilot2i}; + pilot_sumq <= {dout_pilot1q[9],dout_pilot1q} + {dout_pilot2q[9],dout_pilot2q}; + pilot_diffi <= {dout_pilot1i[9],dout_pilot1i} - {dout_pilot2i[9],dout_pilot2i}; + pilot_diffq <= {dout_pilot1q[9],dout_pilot1q} - {dout_pilot2q[9],dout_pilot2q}; + cnt_256pilot <= cnt_256pilot + 8'd1; + state_pilot <= state_pilot; + end + end + + //最后一个数据:第255读完后转回0状态等待下一个数据段的导频。 + 3'd2:begin + nd_pilot <= 1'd1; + rd_en_pilot <= 1'd0; + pilot_sumi <= {dout_pilot1i[9],dout_pilot1i} + {dout_pilot2i[9],dout_pilot2i}; + pilot_sumq <= {dout_pilot1q[9],dout_pilot1q} + {dout_pilot2q[9],dout_pilot2q}; + pilot_diffi <= {dout_pilot1i[9],dout_pilot1i} - {dout_pilot2i[9],dout_pilot2i}; + pilot_diffq <= {dout_pilot1q[9],dout_pilot1q} - {dout_pilot2q[9],dout_pilot2q}; + cnt_256pilot <= 8'd0; + state_pilot <= 3'd0; + end + + default:state_pilot <= 3'd0; + endcase + end + end + + + //正负导频段的加减结果 + always @(posedge clk)begin + if(rst)begin + nd_pilot2 <= 1'd0; + pilot_datai <= 10'd0; + pilot_dataq <= 10'd0; + pilot_noisei <= 10'd0; + pilot_noiseq <= 10'd0; + end + else begin + nd_pilot2 <= nd_pilot; + pilot_noisei <= pilot_sumi[10:1]; + pilot_noiseq <= pilot_sumq[10:1]; + pilot_datai <= pilot_diffi[10:1]; + pilot_dataq <= pilot_diffq[10:1]; + end + end + + + //-----------------------------------------------------------------------写测试文件---------------------------------------------------------------------// + // integer handle01; + // integer handle02; + // integer handle03; + // integer handle04; + + // reg enable1 = 0; + // initial begin + // handle01=$fopen("din_pilot1i.txt","w"); $fclose(handle01); + // handle02=$fopen("din_pilot1q.txt","w"); $fclose(handle02); + // handle03=$fopen("din_pilot2i.txt","w"); $fclose(handle03); + // handle04=$fopen("din_pilot2q.txt","w"); $fclose(handle04); + + + // #10; + // enable1 = 1; + // end + + // always@(posedge clk)begin + // if(enable1)begin + // if(wr_en_pilot1)begin + // handle01=$fopen("din_pilot1i.txt","a+");$fwrite(handle01,"%d\n",$signed(din_pilot1i));$fclose(handle01); + // handle02=$fopen("din_pilot1q.txt","a+");$fwrite(handle02,"%d\n",$signed(din_pilot1q));$fclose(handle02); + // end + // if(wr_en_pilot2)begin + // handle03=$fopen("din_pilot2i.txt","a+");$fwrite(handle03,"%d\n",$signed(din_pilot2i));$fclose(handle03); + // handle04=$fopen("din_pilot2q.txt","a+");$fwrite(handle04,"%d\n",$signed(din_pilot2q));$fclose(handle04); + // end + // end + // end + + + +endmodule diff --git a/hdl/freqestm.v b/hdl/freqestm.v new file mode 100644 index 0000000..f94ba86 --- /dev/null +++ b/hdl/freqestm.v @@ -0,0 +1,643 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/12/23 17:06:52 +// Design Name: +// Module Name: freqestm +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module freqestm ( + input clk, + input rst, + input framesync, + input mgc_rdy, + input [9:0] datain_i, + input [9:0] datain_q, + output reg [9:0] dataout_i, + output reg [9:0] dataout_q, + output reg framesync_delay, + output reg data_save, + output reg rst_freq +); + + wire [19:0] datain_01; + wire [19:0] datain_02; + wire [19:0] datain_03; + wire framesync_d2; + wire framesync_d3; + + wire [19:0] dataout_16; + + assign datain_01 = {datain_q, datain_i}; + + shiftram_freq shiftram_freq_01 ( + .CLK(clk), + .D (datain_01), + .Q (datain_02) + ); + shiftram_freq shiftram_freq_02 ( + .CLK(clk), + .D (datain_02), + .Q (datain_03) + ); + wire empty; + wire full; + reg rd_en; + reg wr_en; + + fifo_freq fifo_freq ( + .clk (clk), + .srst (rst), + .din (datain_03), + .wr_en(wr_en), + .full (full), + .rd_en(rd_en), + .empty(empty), + .dout (dataout_16) + + ); + reg [15:0] cnt_fifo; + reg [ 2:0] state_fifo; + always @(posedge clk) begin + if (rst) begin + cnt_fifo <= 16'd0; + wr_en <= 1'b0; + rd_en <= 1'b0; + state_fifo <= 3'd0; + end + else begin + case (state_fifo) + 3'd0: begin + if (mgc_rdy) begin + state_fifo <= 3'd1; + end + else begin + state_fifo <= state_fifo; + end + end + 3'd1: begin + if (cnt_fifo == 16'd2175) begin + wr_en <= 1'b1; + cnt_fifo <= cnt_fifo + 16'd1; + end + else if (cnt_fifo == 16'd18065) begin + rd_en <= 1'b1; + cnt_fifo <= cnt_fifo; + end + else begin + cnt_fifo <= cnt_fifo + 16'd1; + wr_en <= wr_en; + rd_en <= rd_en; + end + state_fifo <= state_fifo; + end + endcase + end + end + + + reg [11:0] cnt_pilot; + reg [14:0] cnt_frame; + reg [ 7:0] cnt_bag; + reg [11:0] cnt_cp; + reg [11:0] cnt_process; + reg [11:0] addra_pilot01; + reg [11:0] addrb_pilot01; + reg [11:0] addra_pilot02; + reg [11:0] addrb_pilot02; + reg [ 4:0] state_freq; + + reg [19:0] din_pilot01; + reg [19:0] din_pilot02; + wire [19:0] dout_pilot01; + wire [19:0] dout_pilot02; + + reg framesync_delay_d1 = 1'b0; + reg framesync_delay_d2 = 1'b0; + reg framesync_delay_d3 = 1'b0; + reg framesync_delay_d4 = 1'b0; + reg framesync_delay_d5 = 1'b0; + reg framesync_delay_d6 = 1'b0; + reg framesync_delay_d7 = 1'b0; + reg framesync_delay_d8 = 1'b0; + reg framesync_delay_d9 = 1'b0; + + + reg wea_01; + reg wea_02; + + ram_pilot ram_pilota ( + .clka (clk), + .clkb (clk), + .addra(addra_pilot01), + .addrb(addrb_pilot01), + .dina (din_pilot01), + .doutb(dout_pilot01), + .wea (wea_01) + ); + + ram_pilot ram_pilotb ( + .clka (clk), + .clkb (clk), + .addra(addra_pilot02), + .addrb(addrb_pilot02), + .dina (din_pilot02), + .doutb(dout_pilot02), + .wea (wea_02) + ); + + wire [ 2:0] Multouti01_head; + wire [ 2:0] Multoutq01_head; + wire [20:0] Multouti01; + wire [20:0] Multoutq01; + reg acc_rdy; + + com_freq com_freq ( + .aclk (clk), + .s_axis_a_tvalid (1'd1), + .s_axis_a_tdata ({6'd0, dout_pilot01[19:10], 6'd0, dout_pilot01[9:0]}), + .s_axis_b_tvalid (1'd1), + .s_axis_b_tdata ({6'd0, dout_pilot02[19:10], 6'd0, dout_pilot02[9:0]}), + .m_axis_dout_tvalid(m_axis_dout_tvalid01), + .m_axis_dout_tdata ({Multoutq01_head, Multoutq01, Multouti01_head, Multouti01}) + ); + + + reg dfreq_word_nd_DDS; + reg [31:0] acc_com_i; + reg [31:0] acc_com_q; + reg [ 9:0] phase_reg; + reg [13:0] freq_out; + wire [ 9:0] phase_out; + wire [ 5:0] phase_out_head; + wire phaserdy; + reg [ 3:0] cnt_6; + always @(posedge clk) begin + if (rst) begin + //dataout_i <= 12'd0; + //dataout_q <= 12'd0; + framesync_delay_d2 <= 1'b0; + framesync_delay_d3 <= 1'b0; + framesync_delay_d4 <= 1'b0; + framesync_delay_d5 <= 1'b0; + framesync_delay_d6 <= 1'b0; + framesync_delay_d7 <= 1'b0; + framesync_delay_d8 <= 1'b0; + framesync_delay <= 1'b0; + state_freq <= 5'd0; + framesync_delay_d1 <= 1'b0; + cnt_bag <= 8'd0; + acc_com_i <= 32'd0; + acc_com_q <= 32'd0; + phase_reg <= 10'd0; + freq_out <= 14'd0; + cnt_pilot <= 12'd0; + cnt_frame <= 15'd0; + cnt_process <= 12'd0; + addra_pilot01 <= 12'd0; + addra_pilot02 <= 12'd0; + addrb_pilot01 <= 12'd0; + addrb_pilot02 <= 12'd0; + din_pilot01 <= 20'd0; + din_pilot02 <= 20'd0; + cnt_cp <= 12'd0; + wea_01 <= 1'b0; + wea_02 <= 1'b0; + acc_rdy <= 1'b0; + data_save <= 1'b0; + dfreq_word_nd_DDS <= 1'b0; + cnt_6 <= 4'd0; + end + else begin + framesync_delay_d2 <= data_save; + framesync_delay_d3 <= framesync_delay_d2; + framesync_delay_d4 <= framesync_delay_d3; + framesync_delay_d5 <= framesync_delay_d4; + framesync_delay_d6 <= framesync_delay_d5; + framesync_delay_d7 <= framesync_delay_d6; + framesync_delay_d8 <= framesync_delay_d7; + framesync_delay <= framesync_delay_d8; + case (state_freq) + 5'd0: begin + if (framesync) begin + state_freq <= 5'd1; + wea_01 <= 1'b1; + if (datain_q == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -datain_q; + + din_pilot01[9:0] <= datain_i[9:0]; + end + else begin + state_freq <= 5'd0; + end + //dataout_i <= 12'd0; + //dataout_q <= 12'd0; + framesync_delay_d1 <= 1'b0; + cnt_bag <= 8'd0; + acc_com_i <= 32'd0; + acc_com_q <= 32'd0; + phase_reg <= 10'd0; + freq_out <= 14'd0; + cnt_pilot <= 12'd0; + cnt_frame <= 15'd0; + cnt_process <= 12'd0; + addra_pilot01 <= 12'd0; + addra_pilot02 <= 12'd0; + addrb_pilot01 <= 12'd0; + addrb_pilot02 <= 12'd0; + din_pilot01 <= 20'd0; + din_pilot02 <= 20'd0; + cnt_cp <= 12'd0; + wea_01 <= 1'b0; + wea_02 <= 1'b0; + acc_rdy <= 1'b0; + dfreq_word_nd_DDS <= 1'b0; + end + + 5'd1: begin + if (cnt_pilot == 12'd1023) begin + addra_pilot01 <= addra_pilot01; + cnt_pilot <= 12'd0; + state_freq <= 5'd11; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + + wea_01 <= 1'b0; + end + else begin + if (datain_q == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -datain_q; + + din_pilot01[9:0] <= datain_i[9:0]; + addra_pilot01 <= addra_pilot01 + 12'd1; + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_01 <= 1'b1; + end + end + + 5'd2: begin + if (cnt_frame == 15'd13823) begin + state_freq <= 5'd3; + cnt_frame <= 15'd0; + wea_02 <= 1'b1; + din_pilot02 <= {datain_q, datain_i}; + end + else begin + cnt_frame <= cnt_frame + 15'd1; + end + end + + 5'd3: begin + if (cnt_pilot == 12'd1023) begin + addra_pilot02 <= addra_pilot02; + cnt_pilot <= 12'd0; + state_freq <= 5'd13; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag + 8'd1; + wea_02 <= 1'b0; + end + else begin + din_pilot02 <= {datain_q, datain_i}; + addra_pilot02 <= addra_pilot02 + 12'd1; + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_02 <= 1'b1; + end + end + + 5'd4: begin + state_freq <= 5'd5; + cnt_frame <= cnt_frame + 15'd1; + acc_com_i <= 32'd0; + acc_com_q <= 32'd0; + end + + 5'd5: begin + if (cnt_6 == 4'd6) begin + if (Multouti01[20] == 1'b1) acc_com_i <= acc_com_i + {11'b11111111111, Multouti01}; + else acc_com_i <= acc_com_i + {11'b00000000000, Multouti01}; + if (Multoutq01[20] == 1'b1) acc_com_q <= acc_com_q + {11'b11111111111, Multoutq01}; + else acc_com_q <= acc_com_q + {11'b00000000000, Multoutq01}; + cnt_6 <= cnt_6; + end + else begin + acc_com_q <= acc_com_q; + acc_com_i <= acc_com_i; + cnt_6 <= cnt_6 + 4'd1; + end + if (cnt_pilot >= 12'd2047) begin + addrb_pilot01 <= 12'd0; + addrb_pilot02 <= 12'd0; + cnt_frame <= cnt_frame + 15'd1; + if (cnt_pilot == 12'd2053) begin + acc_rdy <= 1'b1; + cnt_pilot <= 12'd0; + state_freq <= 5'd6; + cnt_6 <= 4'd0; + end + else begin + cnt_pilot <= cnt_pilot + 12'd1; + end + end + else begin + cnt_pilot <= cnt_pilot + 12'd1; + addrb_pilot01 <= addrb_pilot01 + 12'd1; + addrb_pilot02 <= addrb_pilot02 + 12'd1; + acc_rdy <= 1'b0; + cnt_frame <= cnt_frame + 15'd1; + end + end + + 5'd6: begin + acc_rdy <= 1'b0; + if (phaserdy) begin + phase_reg <= phase_out; + state_freq <= 5'd7; + cnt_frame <= cnt_frame + 15'd1; + wea_01 <= 1'b1; + + if (dout_pilot02[19:10] == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -dout_pilot02[19:10]; + din_pilot01[9:0] <= dout_pilot02[9:0]; + + addrb_pilot02 <= addrb_pilot02 + 12'd1; + end + else begin + phase_reg <= phase_reg; + cnt_frame <= cnt_frame + 15'd1; + end + end + + 5'd7: begin + state_freq <= 5'd8; + data_save <= 1'b1; + + if (phase_reg[9] == 1'b1) freq_out <= {3'b111, phase_reg, 1'b0} + {4'b1111, phase_reg}; + else freq_out <= {3'b000, phase_reg, 1'b0} + {4'b0000, phase_reg}; + cnt_frame <= cnt_frame + 15'd1; + dfreq_word_nd_DDS <= 1'b1; + if (cnt_bag == 8'd1) framesync_delay_d1 <= 1'b1; + else framesync_delay_d1 <= 1'b0; + + wea_01 <= 1'b1; + + if (dout_pilot02[19:10] == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -dout_pilot02[19:10]; + din_pilot01[9:0] <= dout_pilot02[9:0]; + + addrb_pilot02 <= addrb_pilot02 + 12'd1; + end + + 5'd8: begin + dfreq_word_nd_DDS <= 1'b0; + framesync_delay_d1 <= 1'b0; + if (cnt_pilot >= 12'd2045) begin + + addrb_pilot02 <= 12'd0; + if (cnt_pilot == 12'd2047) begin + addra_pilot01 <= 12'd0; + addrb_pilot02 <= 12'd0; + cnt_pilot <= 12'd0; + state_freq <= 5'd9; + cnt_frame <= cnt_frame + 15'd1; + wea_01 <= 1'b0; + end + else begin + if (dout_pilot02[19:10] == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -dout_pilot02[19:10]; + din_pilot01[9:0] <= dout_pilot02[9:0]; + + addra_pilot01 <= addra_pilot01 + 12'd1; + + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + wea_01 <= 1'b1; + end + end + else begin + if (dout_pilot02[19:10] == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -dout_pilot02[19:10]; + din_pilot01[9:0] <= dout_pilot02[9:0]; + + addra_pilot01 <= addra_pilot01 + 12'd1; + addrb_pilot02 <= addrb_pilot02 + 12'd1; + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + wea_01 <= 1'b1; + end + end + 5'd9: begin + if (cnt_frame == 15'd13823) begin + + if (cnt_bag == 8'd40) begin + state_freq <= 5'd10; + cnt_bag <= cnt_bag + 8'd1; + end + else begin + state_freq <= 5'd3; + wea_02 <= 1'b1; + din_pilot02 <= {datain_q, datain_i}; + + end + + cnt_frame <= 15'd0; + end + else begin + cnt_frame <= cnt_frame + 15'd1; + end + end + + 5'd10: begin + if (cnt_frame == 15'd13695) begin + cnt_frame <= 15'd0; + state_freq <= 5'd0; + end + else begin + cnt_frame <= cnt_frame + 15'd1; + end + + end + + 5'd11: begin + if (cnt_cp == 12'd127) begin + state_freq <= 5'd12; + cnt_cp <= 12'd0; + wea_01 <= 1'b1; + addra_pilot01 <= addra_pilot01 + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + if (datain_q == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -datain_q; + + din_pilot01[9:0] <= datain_i[9:0]; + end + else begin + cnt_cp <= cnt_cp + 12'd1; + state_freq <= state_freq; + cnt_frame <= cnt_frame + 15'd1; + end + + end + + + 5'd12: begin + if (cnt_pilot == 12'd1023) begin + addra_pilot01 <= 12'd0; + cnt_pilot <= 12'd0; + state_freq <= 12'd2; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_01 <= 1'b0; + end + else begin + if (datain_q == 10'd512) din_pilot01[19:10] <= 10'd511; + else din_pilot01[19:10] <= -datain_q; + + din_pilot01[9:0] <= datain_i[9:0]; + addra_pilot01 <= addra_pilot01 + 12'd1; + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_01 <= 1'b1; + end + end + + 5'd13: begin + if (cnt_cp == 12'd127) begin + state_freq <= 5'd14; + cnt_cp <= 12'd0; + cnt_frame <= cnt_frame + 15'd1; + din_pilot02 <= {datain_q, datain_i}; + addra_pilot02 <= addra_pilot02 + 12'd1; + wea_02 <= 1'b1; + end + else begin + cnt_cp <= cnt_cp + 12'd1; + state_freq <= state_freq; + cnt_frame <= cnt_frame + 15'd1; + end + + end + + + 5'd14: begin + if (cnt_pilot == 12'd1023) begin + addra_pilot02 <= 12'd0; + cnt_pilot <= 12'd0; + state_freq <= 5'd4; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_02 <= 1'b0; + end + else begin + din_pilot02 <= {datain_q, datain_i}; + addra_pilot02 <= addra_pilot02 + 12'd1; + cnt_pilot <= cnt_pilot + 12'd1; + cnt_frame <= cnt_frame + 15'd1; + cnt_bag <= cnt_bag; + wea_02 <= 1'b1; + end + end + + endcase + end + + end + + + atan2_freq atan2_freq ( + .aclk (clk), // input wire aclk + .s_axis_cartesian_tvalid(acc_rdy), // input wire s_axis_cartesian_tvalid + .s_axis_cartesian_tdata ({acc_com_q, acc_com_i}), // input wire [47 : 0] s_axis_cartesian_tdata + .m_axis_dout_tvalid (phaserdy), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata ({phase_out_head, phase_out}) // output wire [15 : 0] m_axis_dout_tdata + ); + + wire [11:0] DDS_trunc_i; + wire [11:0] DDS_trunc_q; + wire DDS_trunc_nd; + wire Demod_ovrflw; + + + + reg [11:0] DDSin_i; + reg [11:0] DDSin_q; + + always @(posedge clk) begin + if (dataout_16[19] == 1'b1) DDSin_q <= {2'b11, dataout_16[19:10]}; + else DDSin_q <= {2'b00, dataout_16[19:10]}; + if (dataout_16[9] == 1'b1) DDSin_i <= {2'b11, dataout_16[9:0]}; + else DDSin_i <= {2'b00, dataout_16[9:0]}; + end + + + DDS_compensate DDS_compensate_mx ( + .clk (clk), + .rst (rst), //捕获模块复位受到发端影响,测试捕获情冿 + .din_nd (1'd1), + .din_i (DDSin_i), + .din_q (DDSin_q), + .acq_nd (1'b0), // 捕获信息 //捕获到了复位丿欿 + .dfreq_word_nd (dfreq_word_nd_DDS), // 频偏NCO信息 + .dfreq_word (freq_out), + .framesync_success(framesync), // 帧同步标志,用于切码 + .demod_trunc_i (DDS_trunc_i), + .demod_trunc_q (DDS_trunc_q), + .demod_trunc_nd (DDS_trunc_nd), + .Demod_ovrflw (Demod_ovrflw) + ); + + always @(posedge clk) begin + if (DDS_trunc_i[11:9] == 3'b000 || DDS_trunc_i[11:9] == 3'b111) begin + dataout_i <= DDS_trunc_i[9:0]; + end + else begin + dataout_i <= (DDS_trunc_i[11] == 1'b1) ? 10'b10_0000_0000 : 10'b01_1111_1111; + end + if (DDS_trunc_q[11:9] == 3'b000 || DDS_trunc_q[11:9] == 3'b111) begin + dataout_q <= DDS_trunc_q[9:0]; + end + else begin + dataout_q <= (DDS_trunc_q[11] == 1'b1) ? 10'b10_0000_0000 : 10'b01_1111_1111; + end + end + + reg [19:0] cnt_rst = 20'd0; + always @(posedge clk) begin + if (framesync_delay_d8 && !framesync_delay) begin + cnt_rst <= 20'd0; + rst_freq <= 1'b0; + end + else begin + if (cnt_rst == 20'd580620) begin + rst_freq <= 1'b1; + cnt_rst <= cnt_rst + 20'd1; + end + else if (cnt_rst == 20'd580621) begin + rst_freq <= 1'b0; + cnt_rst <= cnt_rst; + end + else begin + cnt_rst <= cnt_rst + 20'd1; + rst_freq <= 1'b0; + end + end + end + +endmodule diff --git a/hdl/phase_adjust.v b/hdl/phase_adjust.v new file mode 100644 index 0000000..3162e39 --- /dev/null +++ b/hdl/phase_adjust.v @@ -0,0 +1,261 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2020/12/14 14:44:05 +// Design Name: +// Module Name: phase_adjust +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module phase_adjust( + input clk, + input rst, + input [9:0] din_i, + input [9:0] din_q, + input nd, + input framesync, + output reg rdy, + output [9:0] dout_i, + output [9:0] dout_q + ); + + + reg [7:0] addra = 8'd0; + reg [19:0] dina = 20'd0; + reg [7:0] addrb = 8'd0; + wire [19:0] doutb; + RAM_phase RAM_phase ( + .clka(clk), // input clka + .wea(1'b1), // input [0 : 0] wea + .addra(addra), // input [9 : 0] addra + .dina(dina), // input [15 : 0] dina + .clkb(clk), // input clkb + .addrb(addrb), // input [10 : 0] addrb + .doutb(doutb) // output [7 : 0] doutb + ); + + + wire [10:0] squarei; + wire [10:0] squareq; + wire [47:0] m_axis_dout_tdata; + wire m_axis_dout_tvalid; + CompMultIP CompMultIP1 ( + .aclk(clk), // input wire aclk + .s_axis_a_tvalid(nd), // input wire s_axis_a_tvalid + .s_axis_a_tdata({6'd0,din_q,6'd0,din_i}), // input wire [31 : 0] s_axis_a_tdata + .s_axis_b_tvalid(nd), // input wire s_axis_b_tvalid + .s_axis_b_tdata({6'd0,din_q,6'd0,din_i}), // input wire [31 : 0] s_axis_b_tdata + .m_axis_dout_tvalid(m_axis_dout_tvalid), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata(m_axis_dout_tdata) // output wire [47 : 0] m_axis_dout_tdata + ); + assign squareq = m_axis_dout_tdata[40:30]; + assign squarei = m_axis_dout_tdata[16:6]; + + wire [11:0] square2i; + wire [11:0] square2q; + wire [47:0] m_axis_dout_tdata2; + wire m_axis_dout_tvalid2; + CompMultIP2 CompMultIP2 ( + .aclk(clk), // input wire aclk + .s_axis_a_tvalid(m_axis_dout_tvalid), // input wire s_axis_a_tvalid + .s_axis_a_tdata({5'd0,squareq,5'd0,squarei}), // input wire [31 : 0] s_axis_a_tdata + .s_axis_b_tvalid(m_axis_dout_tvalid), // input wire s_axis_b_tvalid + .s_axis_b_tdata({5'd0,squareq,5'd0,squarei}), // input wire [31 : 0] s_axis_b_tdata + .m_axis_dout_tvalid(m_axis_dout_tvalid2), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata(m_axis_dout_tdata2) // output wire [47 : 0] m_axis_dout_tdata + ); + assign square2q = m_axis_dout_tdata2[41:30]; + assign square2i = m_axis_dout_tdata2[17:6]; + + + reg [19:0] sum256i = 20'd0; + reg [19:0] sum256q = 20'd0; + reg [9:0] addradelay = 10'd0; + reg [3:0] state_phase; + reg [9:0] cnt_phase; + reg sum_rdy; + reg rotate_nd; + reg [9:0] phase_estm; + reg [9:0] phase_shengyu; + reg [9:0] phase_final; + reg [9:0] phase_pi = 10'b0110010010; + + + wire [9:0] phase_out; + wire [5:0] phase_out_head; + wire phaserdy; + atan2_phase atan2_phase ( + .aclk(clk), // input wire aclk + .s_axis_cartesian_tvalid(sum_rdy), // input wire s_axis_cartesian_tvalid + .s_axis_cartesian_tdata({4'd0,sum256q,4'd0,sum256i}), // input wire [47 : 0] s_axis_cartesian_tdata + .m_axis_dout_tvalid(phaserdy), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata({phase_out_head,phase_out}) // output wire [15 : 0] m_axis_dout_tdata + ); + + wire [5:0] rotate_headq; + wire [5:0] rotate_headi; + wire rotate_rdy; + + + atan2_rotate atan2_rotate ( + .aclk(clk), // input wire aclk + .s_axis_cartesian_tvalid(rotate_nd), // input wire s_axis_cartesian_tvalid + .s_axis_cartesian_tdata({6'd0,doutb[19:10],6'd0,doutb[9:0]}), // input wire [47 : 0] s_axis_cartesian_tdata + .s_axis_phase_tvalid(rotate_nd), // input wire s_axis_cartesian_tvalid + .s_axis_phase_tdata({6'd0,phase_final[9],phase_final[9],phase_final[9:2]}), // input wire [47 : 0] s_axis_cartesian_tdata + .m_axis_dout_tvalid(rotate_rdy), // output wire m_axis_dout_tvalid + .m_axis_dout_tdata({rotate_headq,dout_q,rotate_headi,dout_i}) // output wire [15 : 0] m_axis_dout_tdata + ); + + always @ (posedge clk) begin + if(rst) begin + state_phase <= 4'd0; + addradelay <= 10'd0; + sum256i <= 20'd0; + sum256q <= 20'd0; + cnt_phase <= 10'd0; + sum_rdy <= 1'b0; + phase_estm <= 10'd0; + phase_shengyu <= 10'd0; + phase_final <= 10'd0; + rotate_nd <= 1'b0; + rdy <= 1'b0; + end + else begin + rdy <= rotate_rdy; + case(state_phase) + 4'd0:begin + if(framesync) begin + state_phase <= 4'd1; + end + else begin + state_phase <= 4'd0; + end + end + 4'd1:begin + if(nd)begin + addradelay <= addradelay + 10'd1; + dina <= {din_q,din_i}; + addra <= addradelay[7:0]; + if(addradelay==10'd255) begin + state_phase <= 4'd2; + addradelay <= 10'd0; + end + else begin + state_phase <= 4'd1; + end + end + else begin + state_phase <= 4'd1; + addradelay <= addradelay; + addra <= addra; + dina <= dina; + state_phase <= 2'd1; + end + + + if(m_axis_dout_tvalid2)begin + cnt_phase <= cnt_phase + 10'd1; + sum256i <= sum256i + {square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i}; + sum256q <= sum256q + {square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q}; + end + else begin + cnt_phase <= cnt_phase; + sum256i <= sum256i; + sum256q <= sum256q; + end + end + 4'd2:begin + if(m_axis_dout_tvalid2)begin + if(cnt_phase==10'd255)begin + cnt_phase <= 10'd0; + state_phase <= 4'd3; + sum_rdy <= 1'b1; + end + else begin + cnt_phase <= cnt_phase + 10'd1; + sum_rdy <= 1'b0; + state_phase <= 4'd2; + end + sum256i <= sum256i + {square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i[11],square2i}; + sum256q <= sum256q + {square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q[11],square2q}; + end + else begin + cnt_phase <= cnt_phase; + state_phase <= 4'd2; + sum256i <= sum256i; + sum256q <= sum256q; + end + end + 4'd3:begin + sum_rdy <= 1'b0; + if(phaserdy) begin + sum256i <= 20'd0; + sum256q <= 20'd0; + phase_estm <= phase_out; + if(phase_out[9]) begin + phase_shengyu <= phase_pi + phase_out; + end + else begin + phase_shengyu <= phase_pi - phase_out; + end + state_phase <= 4'd4; + end + else begin + phase_estm <= phase_estm; + state_phase <= 4'd3; + end + end + 4'd4:begin + if(phase_estm[9]) begin + phase_final <= -phase_shengyu; + end + else begin + phase_final <= phase_shengyu; + end + if(cnt_phase == 10'd0) begin + cnt_phase <= cnt_phase + 10'd1; + addrb <= 10'd0; + rotate_nd <= 1'b1; + end + else if(cnt_phase == 10'd256) begin + cnt_phase <= 10'd0; + rotate_nd <= 1'b0; + state_phase <= 4'd1; + addrb <= 8'd0; + end + else begin + cnt_phase <= cnt_phase + 10'd1; + addrb <= addrb + 8'd1; + rotate_nd <= 1'b1; + end + end + default:begin + if(framesync) begin + state_phase <= 4'd1; + end + else begin + state_phase <= 4'd0; + end + end + endcase + end + end + + + + +endmodule diff --git a/hdl/trunc_25to12_2dly.v b/hdl/trunc_25to12_2dly.v new file mode 100644 index 0000000..c77076e --- /dev/null +++ b/hdl/trunc_25to12_2dly.v @@ -0,0 +1,75 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2019/08/03 14:53:56 +// Design Name: +// Module Name: trunc_25to12_2dly +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module trunc_25to12_2dly( + clk, + din_nd, + din, + ctrl, + dout_nd, + dout, + ovrflw + ); + //--------------------- IN/OUT ------------------------ + input clk; + input din_nd; + input [24:0] din; + input ctrl; + output reg dout_nd = 0; + output reg [11:0] dout = 0; + output reg ovrflw = 0; + + //---------------------- delay ----------------------- + reg [24:0] din_dly = 0; + always @(posedge clk) + din_dly <= din; + + reg sign_bit = 0; + always @(posedge clk) + sign_bit <= din[24]; + + //---------------------- flag ------------------------- + reg signbit3 = 0; + always @(posedge clk) + if(din[24:22] == 3'b000 || din[24:22] == 3'b111) + signbit3 <= 1'b1; + else + signbit3 <= 1'b0; + + //------------------------------------------------------ + always @(posedge clk) + if(signbit3 == 1'b1) + begin + dout <= din_dly[22:11]; + ovrflw <= 0; + end + else + begin + dout <= {sign_bit,{10{!sign_bit}}}; + ovrflw <= 1; + end + reg din_nd_d1 = 0; + always @(posedge clk) begin + din_nd_d1 <= din_nd; + dout_nd <= din_nd_d1; + end +endmodule