`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