Add the recv hdl file

This commit is contained in:
2024-07-19 21:31:49 +08:00
parent 9a1f168184
commit e33875ef8f
20 changed files with 7725 additions and 0 deletions
+624
View File
@@ -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