543 lines
15 KiB
Verilog
543 lines
15 KiB
Verilog
`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
|