Files
MM7020/hdl/SC_FDE_TOP.v
T

560 lines
26 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
`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