`timescale 1ns / 1ns ////////////////////////////////////////////////////////////////////////////////// // 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 data .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 data .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 //flag .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 ); endmodule