Files

543 lines
15 KiB
Verilog
Raw Permalink 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/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