`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/08/18 16:40:38 // Design Name: // Module Name: DAGC_v2 // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module DAGC_v2 ( input clk, input rst, input mgc1_rdy, input framesync_d0, input [1:0] vio_powertest_h, input [1:0] vio_powertest_l, input [9:0] matchfilterout_i, input [9:0] matchfilterout_q, output reg [9:0] DAGC_out_i = 10'd0, output reg [9:0] DAGC_out_q = 10'd0, //检测用 output reg flag_agch = 1'd0, output reg flag_agcl = 1'd0, output reg flag_agc_power = 1'd0, output reg [12:0] agc_ref = 13'd0, output reg [12:0] agc_check = 13'd0, output reg dagc_rdy, output reg mgc_rdy, output reg rst_dagc ); //近似求模值方法,做4096累积平均 //-------------------------------------数据缓存----------------------------// reg wea_1 = 1'd0; reg [11:0] addrin_1 = 12'd0; reg [ 9:0] din_1i = 10'd0; reg [11:0] addrout_1 = 12'd0; wire [ 9:0] dout_1i; //-------------------------------------------给数据、打缓存的状态机-------------------------------------// reg ND = 1'd0; reg [ 9:0] Din_I = 10'd0; reg [ 9:0] Din_Q = 10'd0; reg [ 5:0] cnt_50 = 6'd0; reg [ 2:0] state_storage = 3'd0; wire [ 9:0] mf_i; wire [ 9:0] mf_q; wire empty; wire full; reg rd_en = 1'b0; wire [13:0] data_count; fifo_dagc fifo_dagc ( .clk (clk), .srst (rst), .din ({matchfilterout_q, matchfilterout_i}), .wr_en (mgc1_rdy), .full (empty), .rd_en (rd_en), .empty (full), .dout ({mf_q, mf_i}), .data_count(data_count) ); //-------------------------------------求近似模值的模块----------------------------// wire [10:0] Dout; wire [ 0:0] Rdy_abs; ApproxAbs_v2 ApproxAbs_v2_djy ( .clk (clk), .ND (mgc1_rdy), .Din_I(matchfilterout_i), .Din_Q(matchfilterout_q), .Dout (Dout), .Rdy (Rdy_abs) ); reg framesync_d1; reg framesync_d2; reg framesync_d3; reg framesync_d4; reg framesync_d5; reg framesync; always @(posedge clk) begin //(MXQ)必须加 posedge clk ,否则仿真有问题,内存溢出 framesync_d1 <= framesync_d0; //与ApproxAbs_v2_djy同步 framesync_d2 <= framesync_d1; framesync_d3 <= framesync_d2; framesync_d4 <= framesync_d3; framesync_d5 <= framesync_d4; framesync <= framesync_d5; end //-------------------------------------LUT----------------------------// reg [10:0] addr_lut = 11'd0; wire [13:0] dout_lut; DAGC_LUT_rom DAGC_LUT_rom ( .clka (clk), // input clka .addra(addr_lut), // input [10 : 0] addra .douta(dout_lut) // output [13 : 0] douta ); reg dagc_rdy_d0; reg dagc_rdy_d1; reg dagc_rdy_d2; reg dagc_rdy_d3; reg dagc_rdy_d4; reg mgc_rdy_d0; reg mgc_rdy_d1; reg mgc_rdy_d2; reg mgc_rdy_d3; reg mgc_rdy_d4; always @(posedge clk) begin if (rst) begin dagc_rdy_d1 <= 1'b0; dagc_rdy_d2 <= 1'b0; dagc_rdy_d3 <= 1'b0; dagc_rdy_d4 <= 1'b0; dagc_rdy <= 1'b0; mgc_rdy_d1 <= 1'b0; mgc_rdy_d2 <= 1'b0; mgc_rdy_d3 <= 1'b0; mgc_rdy_d4 <= 1'b0; mgc_rdy <= 1'b0; end else begin dagc_rdy_d1 <= dagc_rdy_d0; dagc_rdy_d2 <= dagc_rdy_d1; dagc_rdy_d3 <= dagc_rdy_d2; dagc_rdy_d4 <= dagc_rdy_d3; dagc_rdy <= dagc_rdy_d4; mgc_rdy_d1 <= mgc_rdy_d0; mgc_rdy_d2 <= mgc_rdy_d1; mgc_rdy_d3 <= mgc_rdy_d2; mgc_rdy_d4 <= mgc_rdy_d3; mgc_rdy <= mgc_rdy_d4; end end //-------------------------------------求均值、查表、给补偿指令的状态机----------------------------// reg [ 3:0] state_agc = 4'd0; reg [11:0] cnt_4096_3 = 12'd0; reg [22:0] agc_ref_temp = 23'd0; reg [14:0] agc_ref_h = 15'd0; reg [12:0] agc_ref_l = 13'd0; reg flag_ram_1 = 1'd0; reg flag_ram_2 = 1'd0; reg [14:0] cnt_databag = 15'd0; always @(posedge clk) begin if (rst) begin state_agc <= 4'd0; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd0; flag_agch <= 1'd0; flag_agcl <= 1'd0; flag_agc_power <= 1'd0; agc_ref <= agc_ref; agc_ref_temp <= 23'd0; agc_check <= agc_check; agc_ref_h <= 15'd0; agc_ref_l <= 13'd0; addr_lut <= 11'd0; flag_ram_1 <= 1'd0; flag_ram_2 <= 1'd0; dagc_rdy_d0 <= 1'b0; rd_en <= 1'b0; mgc_rdy_d0 <= 1'b0; end else begin case (state_agc) 4'd0: begin if (Rdy_abs) begin //状态0进入第一次估计 state_agc <= 4'd1; agc_ref_temp <= {12'd0, Dout}; cnt_4096_3 <= 12'd1; cnt_databag <= 15'd1; end else begin state_agc <= state_agc; agc_ref_temp <= 23'd0; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd0; end flag_agch <= 1'd0; flag_agcl <= 1'd0; flag_agc_power <= 1'd0; agc_ref <= 13'd0; agc_check <= 13'd0; agc_ref_h <= 15'd0; agc_ref_l <= 13'd0; addr_lut <= 11'd0; flag_ram_1 <= 1'd0; flag_ram_2 <= 1'd0; end 4'd1: begin if (cnt_4096_3 == 12'd4095) begin state_agc <= 4'd2; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd1 + cnt_databag; end else begin state_agc <= state_agc; cnt_4096_3 <= 12'd01 + cnt_4096_3; cnt_databag <= 15'd1 + cnt_databag; end agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; flag_agc_power <= 1'd0; end 4'd2: begin if (framesync == 1'b1) begin //判断是否有帧同步如果有进入有效数据计算段 state_agc <= 4'd3; end else begin state_agc <= 4'd10; end cnt_databag <= 15'd1 + cnt_databag; cnt_4096_3 <= 12'd0; agc_ref_temp <= agc_ref_temp; agc_ref <= agc_ref_temp[22:10]; agc_check <= agc_ref_temp[22:10]; flag_agc_power <= 1'd1; end 4'd3: begin if (cnt_databag == 15'd13695) begin cnt_databag <= 15'd0; state_agc <= 4'd4; cnt_4096_3 <= 12'd1; agc_ref_temp <= {12'd0, Dout}; end else begin cnt_databag <= 15'd1 + cnt_databag; cnt_4096_3 <= 12'd0; state_agc <= state_agc; agc_ref_temp <= agc_ref_temp; end flag_agc_power <= 1'd0; case (vio_powertest_h) 2'd0: agc_ref_h <= {2'd0, agc_ref} + {4'd0, agc_ref[12:2]}; 2'd1: agc_ref_h <= {2'd0, agc_ref} + {3'd0, agc_ref[12:1]}; 2'd2: agc_ref_h <= {1'd0, agc_ref, 1'd0}; 2'd3: agc_ref_h <= {agc_ref, 2'd0}; endcase case (vio_powertest_l) 2'd0: agc_ref_l <= agc_ref - {3'd0, agc_ref[12:3]}; 2'd1: agc_ref_l <= agc_ref - {2'd0, agc_ref[12:2]}; 2'd2: agc_ref_l <= {1'd0, agc_ref[12:1]}; 2'd3: agc_ref_l <= {2'd0, agc_ref[12:2]}; endcase //查表地址 if (agc_check <= 13'd11) addr_lut <= 11'd0; else begin if (agc_check >= 13'd2037) addr_lut <= 11'd2026; else addr_lut <= agc_check[10:0] - 11'd11; end flag_ram_1 <= 1'd1; flag_ram_2 <= 1'd0; rd_en <= 1'b1; dagc_rdy_d0 <= 1'b1; end 4'd4: begin if (cnt_4096_3 == 12'd4095) begin state_agc <= 4'd5; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd1 + cnt_databag; end else begin state_agc <= state_agc; cnt_4096_3 <= 12'd01 + cnt_4096_3; cnt_databag <= 15'd1 + cnt_databag; end agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; flag_agch <= 1'd0; flag_agcl <= 1'd0; flag_agc_power <= 1'd0; flag_ram_1 <= 1'd0; flag_ram_2 <= 1'd0; end 4'd5: begin state_agc <= 4'd6; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd1 + cnt_databag; agc_ref_temp <= agc_ref_temp; agc_check <= agc_ref_temp[22:10]; flag_agc_power <= 1'd1; flag_agch <= 1'd0; flag_agcl <= 1'd0; end 4'd6: begin if (cnt_databag == 15'd13823) begin cnt_databag <= 15'd0; state_agc <= 4'd7; cnt_4096_3 <= 12'd1; agc_ref_temp <= {12'd0, Dout}; end else begin cnt_databag <= 15'd1 + cnt_databag; cnt_4096_3 <= 12'd0; state_agc <= state_agc; agc_ref_temp <= agc_ref_temp; end flag_agc_power <= 1'd0; if ({2'd0, agc_check} > agc_ref_h) begin flag_agch <= 1'd1; flag_agcl <= 1'd0; end else begin if (agc_check < agc_ref_l) begin flag_agch <= 1'd0; flag_agcl <= 1'd1; end else begin flag_agch <= 1'd0; flag_agcl <= 1'd0; end end //查表地址 if (agc_check <= 13'd11) addr_lut <= 11'd0; else begin if (agc_check >= 13'd2037) addr_lut <= 11'd2026; else addr_lut <= agc_check[10:0] - 11'd11; end flag_ram_1 <= 1'd0; flag_ram_2 <= 1'd1; end 4'd7: begin if (cnt_4096_3 == 12'd4095) begin state_agc <= 4'd8; cnt_4096_3 <= 12'd0; cnt_databag <= 15'd1 + cnt_databag; end else begin state_agc <= state_agc; cnt_4096_3 <= 12'd01 + cnt_4096_3; cnt_databag <= 15'd1 + cnt_databag; end agc_ref_temp <= agc_ref_temp + {12'd0, Dout}; flag_agch <= 1'd0; flag_agcl <= 1'd0; flag_agc_power <= 1'd0; flag_ram_1 <= 1'd0; flag_ram_2 <= 1'd0; end 4'd8: begin state_agc <= 4'd9; cnt_databag <= 15'd1 + cnt_databag; cnt_4096_3 <= 12'd0; agc_ref_temp <= {12'd0, Dout}; agc_check <= agc_ref_temp[22:10]; flag_agc_power <= 1'd1; flag_agch <= 1'd0; flag_agcl <= 1'd0; end 4'd9: begin if (cnt_databag == 15'd13823) begin cnt_databag <= 15'd0; state_agc <= 4'd4; cnt_4096_3 <= 12'd1; agc_ref_temp <= {12'd0, Dout}; end else begin cnt_databag <= 15'd1 + cnt_databag; cnt_4096_3 <= 12'd0; state_agc <= state_agc; agc_ref_temp <= agc_ref_temp; end flag_agc_power <= 1'd0; if ({2'd0, agc_check} > agc_ref_h) begin flag_agch <= 1'd1; flag_agcl <= 1'd0; end else begin if (agc_check < agc_ref_l) begin flag_agch <= 1'd0; flag_agcl <= 1'd1; end else begin flag_agch <= 1'd0; flag_agcl <= 1'd0; end end //查表地址 if (agc_check <= 13'd11) addr_lut <= 11'd0; else begin if (agc_check >= 13'd2037) addr_lut <= 11'd2026; else addr_lut <= agc_check[10:0] - 11'd11; end flag_ram_1 <= 1'd1; flag_ram_2 <= 1'd0; end 4'd10: begin if (framesync == 1'b1) begin state_agc <= 4'd1; agc_ref_temp <= {12'd0, Dout}; cnt_4096_3 <= 12'd1; cnt_databag <= 15'd1; end else begin state_agc <= state_agc; cnt_databag <= 15'd0; cnt_4096_3 <= 12'd0; flag_agc_power <= 1'd0; agc_ref_temp <= agc_ref_temp; case (vio_powertest_h) 2'd0: agc_ref_h <= {2'd0, agc_ref} + {4'd0, agc_ref[12:2]}; 2'd1: agc_ref_h <= {2'd0, agc_ref} + {3'd0, agc_ref[12:1]}; 2'd2: agc_ref_h <= {1'd0, agc_ref, 1'd0}; 2'd3: agc_ref_h <= {agc_ref, 2'd0}; endcase case (vio_powertest_l) 2'd0: agc_ref_l <= agc_ref - {3'd0, agc_ref[12:3]}; 2'd1: agc_ref_l <= agc_ref - {2'd0, agc_ref[12:2]}; 2'd2: agc_ref_l <= {1'd0, agc_ref[12:1]}; 2'd3: agc_ref_l <= {2'd0, agc_ref[12:2]}; endcase //查表地址 if (agc_check <= 13'd11) addr_lut <= 11'd0; else begin if (agc_check >= 13'd2037) addr_lut <= 11'd2026; else addr_lut <= agc_check[10:0] - 11'd11; end flag_ram_1 <= 1'd1; flag_ram_2 <= 1'd0; rd_en <= 1'b1; mgc_rdy_d0 <= 1'b1; end end endcase end end reg [13:0] agcdata0 = 14'd0; reg [13:0] agcdata1 = 14'd0; always @(posedge clk) begin agcdata0 <= dout_lut; agcdata1 <= agcdata0; end //-------------------------------------补偿用的乘法器----------------------------// wire [23:0] mulout_i; DAGC_mul_10bit12 DAGC_mul_10bit12_i ( .CLK(clk), // input clk .A (mf_i), // input [9 : 0] a .B (agcdata0), // input [13 : 0] b .P (mulout_i) // output [23 : 0] p ); wire [23:0] mulout_q; DAGC_mul_10bit12 DAGC_mul_10bit12_q ( .CLK(clk), // input clk .A (mf_q), // input [9 : 0] a .B (agcdata0), // input [13 : 0] b .P (mulout_q) // output [23 : 0] p ); always @(posedge clk) begin if (mulout_i[23:17] == 7'b111_1111 || mulout_i[23:17] == 7'b000_0000) DAGC_out_i <= mulout_i[17:8]; else DAGC_out_i <= (mulout_i[23]) ? 10'b1000_0000_01 : 10'b0111_1111_11; if (mulout_q[23:17] == 7'b111_1111 || mulout_q[23:17] == 7'b000_0000) DAGC_out_q <= mulout_q[17:8]; else DAGC_out_q <= (mulout_q[23]) ? 10'b1000_0000_01 : 10'b0111_1111_11; end /*ila_dagc ila_dagc( .clk(clk), .probe0(mgc1_rdy), .probe1(empty), .probe2(full), .probe3(rd_en), .probe4(DAGC_out_i), .probe5(DAGC_out_q), .probe6(state_agc), .probe7(dagc_rdy), .probe8(mgc_rdy), .probe9(data_count) );*/ reg [19:0] cnt_rst = 20'd0; always @(posedge clk) begin if (dagc_rdy_d0 && !dagc_rdy_d1) begin cnt_rst <= 20'd0; rst_dagc <= 1'b0; end else begin if (cnt_rst == 20'd580620) begin rst_dagc <= 1'b1; cnt_rst <= cnt_rst + 20'd1; end else if (cnt_rst == 20'd580621) begin rst_dagc <= 1'b0; cnt_rst <= cnt_rst; end else begin cnt_rst <= cnt_rst + 20'd1; rst_dagc <= 1'b0; end end end endmodule