Files

553 lines
19 KiB
Verilog

`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// 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