Make some basic block simpler and its delay more deterministic

This commit is contained in:
Xianjun Jiao 2023-01-09 14:47:34 +01:00
parent a1e1e0090b
commit e65ee43101
6 changed files with 494 additions and 107 deletions

View File

@ -10,69 +10,72 @@ module complex_mult
input [15:0] b_q,
input input_strobe,
output reg [31:0] p_i,
output reg [31:0] p_q,
output [31:0] p_i,
output [31:0] p_q,
output output_strobe
);
localparam DELAY = 4;
reg [DELAY-1:0] delay;
reg [15:0] ar;
reg [15:0] ai;
reg [15:0] br;
reg [15:0] bi;
wire [31:0] prod_i;
wire [31:0] prod_q;
// instantiation of complex multiplier
wire [31:0] s_axis_a_tdata;
assign s_axis_a_tdata = {ai,ar} ;
wire [31:0] s_axis_b_tdata;
assign s_axis_b_tdata = {bi, br} ;
wire [63:0] m_axis_dout_tdata;
assign prod_q = m_axis_dout_tdata[63:32];
assign prod_i = m_axis_dout_tdata[31:0];
wire m_axis_dout_tvalid ; // first try not use it
assign p_q = m_axis_dout_tdata[63:32];
assign p_i = m_axis_dout_tdata[31:0];
complex_multiplier mult_inst (
.aclk(clock), // input wire aclk
.s_axis_a_tvalid(input_strobe), // input wire s_axis_a_tvalid
.s_axis_a_tdata(s_axis_a_tdata), // input wire [31 : 0] s_axis_a_tdata
.s_axis_a_tdata({a_q, a_i}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(input_strobe), // input wire s_axis_b_tvalid
.s_axis_b_tdata(s_axis_b_tdata), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(m_axis_dout_tvalid), // output wire m_axis_dout_tvalid
.s_axis_b_tdata({b_q, b_i}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(output_strobe), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata(m_axis_dout_tdata) // output wire [63 : 0] m_axis_dout_tdata
);
delayT #(.DATA_WIDTH(1), .DELAY(5)) stb_delay_inst (
.clock(clock),
.reset(reset),
.data_in(input_strobe),
.data_out(output_strobe)
);
// reg [15:0] ar;
// reg [15:0] ai;
// reg [15:0] br;
// reg [15:0] bi;
always @(posedge clock) begin
if (reset) begin
ar <= 0;
ai <= 0;
br <= 0;
bi <= 0;
p_i <= 0;
p_q <= 0;
delay <= 0;
end else if (enable) begin
ar <= a_i;
ai <= a_q;
br <= b_i;
bi <= b_q;
// wire [31:0] prod_i;
// wire [31:0] prod_q;
p_i <= prod_i;
p_q <= prod_q;
end
end
// // instantiation of complex multiplier
// wire [31:0] s_axis_a_tdata;
// assign s_axis_a_tdata = {ai,ar} ;
// wire [31:0] s_axis_b_tdata;
// assign s_axis_b_tdata = {bi, br} ;
// wire [63:0] m_axis_dout_tdata;
// assign prod_q = m_axis_dout_tdata[63:32];
// assign prod_i = m_axis_dout_tdata[31:0];
// wire m_axis_dout_tvalid ;
// assign output_strobe = m_axis_dout_tvalid; //output strobe valid at the beginning of new data -- simulation confirmed
// complex_multiplier mult_inst (
// .aclk(clock), // input wire aclk
// .s_axis_a_tvalid(input_strobe), // input wire s_axis_a_tvalid
// .s_axis_a_tdata(s_axis_a_tdata), // input wire [31 : 0] s_axis_a_tdata
// .s_axis_b_tvalid(input_strobe), // input wire s_axis_b_tvalid
// .s_axis_b_tdata(s_axis_b_tdata), // input wire [31 : 0] s_axis_b_tdata
// .m_axis_dout_tvalid(m_axis_dout_tvalid), // output wire m_axis_dout_tvalid
// .m_axis_dout_tdata(m_axis_dout_tdata) // output wire [63 : 0] m_axis_dout_tdata
// );
// always @(posedge clock) begin
// if (reset) begin
// ar <= 0;
// ai <= 0;
// br <= 0;
// bi <= 0;
// p_i <= 0;
// p_q <= 0;
// end else if (enable) begin
// ar <= a_i;
// ai <= a_q;
// br <= b_i;
// bi <= b_q;
// p_i <= prod_i;
// p_q <= prod_q;
// end
// end
endmodule

View File

@ -12,7 +12,7 @@ module complex_to_mag
input input_strobe,
output reg [DATA_WIDTH-1:0] mag,
output mag_stb
output reg mag_stb
);
reg [DATA_WIDTH-1:0] abs_i;
@ -21,13 +21,16 @@ reg [DATA_WIDTH-1:0] abs_q;
reg [DATA_WIDTH-1:0] max;
reg[ DATA_WIDTH-1:0] min;
delayT #(.DATA_WIDTH(1), .DELAY(3)) stb_delay_inst (
.clock(clock),
.reset(reset),
reg input_strobe_reg0;
reg input_strobe_reg1;
.data_in(input_strobe),
.data_out(mag_stb)
);
// delayT #(.DATA_WIDTH(1), .DELAY(3)) stb_delay_inst (
// .clock(clock),
// .reset(reset),
// .data_in(input_strobe),
// .data_out(mag_stb)
// );
// http://dspguru.com/dsp/tricks/magnitude-estimator
@ -40,6 +43,8 @@ always @(posedge clock) begin
abs_q <= 0;
max <= 0;
min <= 0;
input_strobe_reg0 <= 0;
input_strobe_reg1 <= 0;
end else if (enable) begin
abs_i <= i[DATA_WIDTH-1]? (~i+1): i;
abs_q <= q[DATA_WIDTH-1]? (~q+1): q;
@ -48,6 +53,10 @@ always @(posedge clock) begin
min <= abs_i > abs_q? abs_q: abs_i;
mag <= max + (min>>2);
input_strobe_reg0 <= input_strobe;
input_strobe_reg1 <= input_strobe_reg0;
mag_stb <= input_strobe_reg1;
end
end

View File

@ -0,0 +1,91 @@
// Xianjun jiao. putaoshu@msn.com; xianjun.jiao@imec.be;
`timescale 1 ns / 1 ps
module fifo_sample_delay #
(
parameter integer DATA_WIDTH = 8,
parameter integer LOG2_FIFO_DEPTH = 7
)
(
input wire clk,
input wire rst,
input wire [(LOG2_FIFO_DEPTH-1):0] delay_ctl,
input wire [(DATA_WIDTH-1):0] data_in,
input wire data_in_valid,
output wire [(DATA_WIDTH-1):0] data_out,
output wire data_out_valid
);
wire [LOG2_FIFO_DEPTH:0] rd_data_count;
wire [LOG2_FIFO_DEPTH:0] wr_data_count;
wire full;
wire empty;
reg rd_en_start;
wire rd_en;
reg [LOG2_FIFO_DEPTH:0] wr_data_count_reg;
wire wr_complete_pulse;
assign wr_complete_pulse = (wr_data_count > wr_data_count_reg);
assign rd_en = (rd_en_start&wr_complete_pulse);
assign data_out_valid = (rd_en_start&data_in_valid);
xpm_fifo_sync #(
.DOUT_RESET_VALUE("0"), // String
.ECC_MODE("no_ecc"), // String
.FIFO_MEMORY_TYPE("auto"), // String
.FIFO_READ_LATENCY(0), // DECIMAL
.FIFO_WRITE_DEPTH(1<<LOG2_FIFO_DEPTH), // DECIMAL
.FULL_RESET_VALUE(0), // DECIMAL
.PROG_EMPTY_THRESH(10), // DECIMAL
.PROG_FULL_THRESH(10), // DECIMAL
.RD_DATA_COUNT_WIDTH(LOG2_FIFO_DEPTH+1), // DECIMAL
.READ_DATA_WIDTH(DATA_WIDTH), // DECIMAL
.READ_MODE("fwft"), // String
.USE_ADV_FEATURES("0404"), // only enable rd_data_count and wr_data_count
.WAKEUP_TIME(0), // DECIMAL
.WRITE_DATA_WIDTH(DATA_WIDTH), // DECIMAL
.WR_DATA_COUNT_WIDTH(LOG2_FIFO_DEPTH+1) // DECIMAL
) fifo_1clk_i (
.almost_empty(),
.almost_full(),
.data_valid(),
.dbiterr(),
.dout(data_out),
.empty(empty),
.full(full),
.overflow(),
.prog_empty(),
.prog_full(),
.rd_data_count(rd_data_count),
.rd_rst_busy(),
.sbiterr(),
.underflow(),
.wr_ack(),
.wr_data_count(wr_data_count),
.wr_rst_busy(),
.din(data_in),
.injectdbiterr(),
.injectsbiterr(),
.rd_en(rd_en),
.rst(rst),
.sleep(),
.wr_clk(clk),
.wr_en(data_in_valid)
);
always @(posedge clk) begin
if (rst) begin
wr_data_count_reg <= 0;
rd_en_start <= 0;
end else begin
wr_data_count_reg <= wr_data_count;
rd_en_start <= ((wr_data_count == delay_ctl)?1:rd_en_start);
end
end
endmodule

104
verilog/mv_avg.v Normal file
View File

@ -0,0 +1,104 @@
// Xianjun jiao. putaoshu@msn.com; xianjun.jiao@imec.be;
module mv_avg
#(
parameter DATA_WIDTH = 16,
parameter LOG2_AVG_LEN = 5
)
(
input clk,
input rstn,
input signed [DATA_WIDTH-1:0] data_in,
input data_in_valid,
output wire signed [DATA_WIDTH-1:0] data_out,
output wire data_out_valid
);
localparam FIFO_SIZE = 1<<LOG2_AVG_LEN;
localparam TOTAL_WIDTH = DATA_WIDTH + LOG2_AVG_LEN;
reg signed [(TOTAL_WIDTH-1):0] running_total;
reg signed [DATA_WIDTH-1:0] data_in_reg; // to lock data_in by data_in_valid in case it changes in between two valid strobes
wire signed [DATA_WIDTH-1:0] data_in_old;
wire signed [TOTAL_WIDTH-1:0] ext_data_in_old = {{LOG2_AVG_LEN{data_in_old[DATA_WIDTH-1]}}, data_in_old};
wire signed [TOTAL_WIDTH-1:0] ext_data_in = {{LOG2_AVG_LEN{data_in_reg[DATA_WIDTH-1]}}, data_in_reg};
reg rd_en, rd_en_start;
wire [LOG2_AVG_LEN:0] wr_data_count;
reg [LOG2_AVG_LEN:0] wr_data_count_reg;
wire wr_complete_pulse;
reg wr_complete_pulse_reg;
assign wr_complete_pulse = (wr_data_count > wr_data_count_reg);
assign data_out_valid = wr_complete_pulse_reg;
assign data_out = running_total[TOTAL_WIDTH-1:LOG2_AVG_LEN];
xpm_fifo_sync #(
.DOUT_RESET_VALUE("0"), // String
.ECC_MODE("no_ecc"), // String
.FIFO_MEMORY_TYPE("auto"), // String
.FIFO_READ_LATENCY(0), // DECIMAL
.FIFO_WRITE_DEPTH(FIFO_SIZE), // DECIMAL minimum 16!
.FULL_RESET_VALUE(0), // DECIMAL
.PROG_EMPTY_THRESH(10), // DECIMAL
.PROG_FULL_THRESH(10), // DECIMAL
.RD_DATA_COUNT_WIDTH(LOG2_AVG_LEN+1), // DECIMAL
.READ_DATA_WIDTH(DATA_WIDTH), // DECIMAL
.READ_MODE("fwft"), // String
.USE_ADV_FEATURES("0404"), // only enable rd_data_count and wr_data_count
.WAKEUP_TIME(0), // DECIMAL
.WRITE_DATA_WIDTH(DATA_WIDTH), // DECIMAL
.WR_DATA_COUNT_WIDTH(LOG2_AVG_LEN+1) // DECIMAL
) fifo_1clk_for_mv_avg_i (
.almost_empty(),
.almost_full(),
.data_valid(),
.dbiterr(),
.dout(data_in_old),
.empty(empty),
.full(full),
.overflow(),
.prog_empty(),
.prog_full(),
.rd_data_count(),
.rd_rst_busy(),
.sbiterr(),
.underflow(),
.wr_ack(),
.wr_data_count(wr_data_count),
.wr_rst_busy(),
.din(data_in),
.injectdbiterr(),
.injectsbiterr(),
.rd_en(rd_en),
.rst(~rstn),
.sleep(),
.wr_clk(clk),
.wr_en(data_in_valid)
);
always @(posedge clk) begin
if (~rstn) begin
data_in_reg <= 0;
wr_data_count_reg <= 0;
running_total <= 0;
rd_en <= 0;
rd_en_start <= 0;
wr_complete_pulse_reg <= 0;
end else begin
wr_complete_pulse_reg <= wr_complete_pulse;
data_in_reg <= (data_in_valid?data_in:data_in_reg);
wr_data_count_reg <= wr_data_count;
rd_en_start <= ((wr_data_count == (FIFO_SIZE))?1:rd_en_start);
rd_en <= (rd_en_start?wr_complete_pulse:rd_en);
if (wr_complete_pulse) begin
running_total <= running_total + ext_data_in - (rd_en_start?ext_data_in_old:0);
end
end
end
endmodule

118
verilog/mv_avg_dual_ch.v Normal file
View File

@ -0,0 +1,118 @@
// Xianjun jiao. putaoshu@msn.com; xianjun.jiao@imec.be;
module mv_avg_dual_ch
#(
parameter DATA_WIDTH0 = 16,
parameter DATA_WIDTH1 = 16,
parameter LOG2_AVG_LEN = 5
)
(
input clk,
input rstn,
input signed [DATA_WIDTH0-1:0] data_in0,
input signed [DATA_WIDTH1-1:0] data_in1,
input data_in_valid,
output signed [DATA_WIDTH0-1:0] data_out0,
output signed [DATA_WIDTH1-1:0] data_out1,
output data_out_valid
);
localparam FIFO_SIZE = 1<<LOG2_AVG_LEN;
localparam TOTAL_WIDTH0 = DATA_WIDTH0 + LOG2_AVG_LEN;
localparam TOTAL_WIDTH1 = DATA_WIDTH1 + LOG2_AVG_LEN;
reg signed [(TOTAL_WIDTH0-1):0] running_total0;
reg signed [(TOTAL_WIDTH1-1):0] running_total1;
reg signed [DATA_WIDTH0-1:0] data_in0_reg; // to lock data_in by data_in_valid in case it changes in between two valid strobes
reg signed [DATA_WIDTH0-1:0] data_in1_reg; // to lock data_in by data_in_valid in case it changes in between two valid strobes
wire signed [DATA_WIDTH0-1:0] data_in_old0;
wire signed [DATA_WIDTH1-1:0] data_in_old1;
wire signed [TOTAL_WIDTH0-1:0] ext_data_in_old0 = {{LOG2_AVG_LEN{data_in_old0[DATA_WIDTH0-1]}}, data_in_old0};
wire signed [TOTAL_WIDTH0-1:0] ext_data_in0 = {{LOG2_AVG_LEN{data_in0_reg[DATA_WIDTH0-1]}}, data_in0_reg};
wire signed [TOTAL_WIDTH1-1:0] ext_data_in_old1 = {{LOG2_AVG_LEN{data_in_old1[DATA_WIDTH1-1]}}, data_in_old1};
wire signed [TOTAL_WIDTH1-1:0] ext_data_in1 = {{LOG2_AVG_LEN{data_in1_reg[DATA_WIDTH1-1]}}, data_in1_reg};
reg rd_en, rd_en_start;
wire [LOG2_AVG_LEN:0] wr_data_count;
reg [LOG2_AVG_LEN:0] wr_data_count_reg;
wire wr_complete_pulse;
reg wr_complete_pulse_reg;
assign wr_complete_pulse = (wr_data_count > wr_data_count_reg);
assign data_out_valid = wr_complete_pulse_reg;
assign data_out0 = running_total0[TOTAL_WIDTH0-1:LOG2_AVG_LEN];
assign data_out1 = running_total1[TOTAL_WIDTH1-1:LOG2_AVG_LEN];
xpm_fifo_sync #(
.DOUT_RESET_VALUE("0"), // String
.ECC_MODE("no_ecc"), // String
.FIFO_MEMORY_TYPE("auto"), // String
.FIFO_READ_LATENCY(0), // DECIMAL
.FIFO_WRITE_DEPTH(FIFO_SIZE), // DECIMAL minimum 16!
.FULL_RESET_VALUE(0), // DECIMAL
.PROG_EMPTY_THRESH(10), // DECIMAL
.PROG_FULL_THRESH(10), // DECIMAL
.RD_DATA_COUNT_WIDTH(LOG2_AVG_LEN+1), // DECIMAL
.READ_DATA_WIDTH(DATA_WIDTH0+DATA_WIDTH1), // DECIMAL
.READ_MODE("fwft"), // String
.USE_ADV_FEATURES("0404"), // only enable rd_data_count and wr_data_count
.WAKEUP_TIME(0), // DECIMAL
.WRITE_DATA_WIDTH(DATA_WIDTH0+DATA_WIDTH1), // DECIMAL
.WR_DATA_COUNT_WIDTH(LOG2_AVG_LEN+1) // DECIMAL
) fifo_1clk_for_mv_avg_dual_ch_i (
.almost_empty(),
.almost_full(),
.data_valid(),
.dbiterr(),
.dout({data_in_old1, data_in_old0}),
.empty(empty),
.full(full),
.overflow(),
.prog_empty(),
.prog_full(),
.rd_data_count(),
.rd_rst_busy(),
.sbiterr(),
.underflow(),
.wr_ack(),
.wr_data_count(wr_data_count),
.wr_rst_busy(),
.din({data_in1, data_in0}),
.injectdbiterr(),
.injectsbiterr(),
.rd_en(rd_en),
.rst(~rstn),
.sleep(),
.wr_clk(clk),
.wr_en(data_in_valid)
);
always @(posedge clk) begin
if (~rstn) begin
data_in0_reg <= 0;
data_in1_reg <= 0;
wr_complete_pulse_reg <= 0;
wr_data_count_reg <= 0;
running_total0 <= 0;
running_total1 <= 0;
rd_en <= 0;
rd_en_start <= 0;
end else begin
data_in0_reg <= (data_in_valid?data_in0:data_in0_reg);
data_in1_reg <= (data_in_valid?data_in1:data_in1_reg);
wr_complete_pulse_reg <= wr_complete_pulse;
wr_data_count_reg <= wr_data_count;
rd_en_start <= ((wr_data_count == (FIFO_SIZE))?1:rd_en_start);
rd_en <= (rd_en_start?wr_complete_pulse:rd_en);
if (wr_complete_pulse) begin
running_total0 <= running_total0 + ext_data_in0 - (rd_en_start?ext_data_in_old0:0);
running_total1 <= running_total1 + ext_data_in1 - (rd_en_start?ext_data_in_old1:0);
end
end
end
endmodule

View File

@ -27,6 +27,11 @@ module sync_short (
localparam WINDOW_SHIFT = 4;
localparam DELAY_SHIFT = 4;
reg reset_delay1;
reg reset_delay2;
reg reset_delay3;
reg reset_delay4;
wire [31:0] mag_sq;
wire mag_sq_stb;
@ -92,26 +97,46 @@ complex_to_mag_sq mag_sq_inst (
.mag_sq_strobe(mag_sq_stb)
);
moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT)) mag_sq_avg_inst (
.clock(clock),
.enable(enable),
.reset(reset),
// moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT)) mag_sq_avg_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
.data_in(mag_sq),
.input_strobe(mag_sq_stb),
// .data_in(mag_sq),
// .input_strobe(mag_sq_stb),
// .data_out(mag_sq_avg),
// .output_strobe(mag_sq_avg_stb)
// );
mv_avg #(.DATA_WIDTH(33), .LOG2_AVG_LEN(WINDOW_SHIFT)) mag_sq_avg_inst (
.clk(clock),
.rstn(~(reset|reset_delay1|reset_delay2|reset_delay3|reset_delay4)),
// .rstn(~reset),
.data_in({1'd0, mag_sq}),
.data_in_valid(mag_sq_stb),
.data_out(mag_sq_avg),
.output_strobe(mag_sq_avg_stb)
.data_out_valid(mag_sq_avg_stb)
);
delay_sample #(.DATA_WIDTH(32), .DELAY_SHIFT(DELAY_SHIFT)) sample_delayed_inst (
.clock(clock),
.enable(enable),
.reset(reset),
// delay_sample #(.DATA_WIDTH(32), .DELAY_SHIFT(DELAY_SHIFT)) sample_delayed_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
// .data_in(sample_in),
// .input_strobe(sample_in_strobe),
// .data_out(sample_delayed),
// .output_strobe(sample_delayed_stb)
// );
fifo_sample_delay # (.DATA_WIDTH(32), .LOG2_FIFO_DEPTH(5)) sample_delayed_inst (
.clk(clock),
.rst(reset|reset_delay1|reset_delay2|reset_delay3|reset_delay4),
.delay_ctl(16),
.data_in(sample_in),
.input_strobe(sample_in_strobe),
.data_in_valid(sample_in_strobe),
.data_out(sample_delayed),
.output_strobe(sample_delayed_stb)
.data_out_valid(sample_delayed_stb)
);
complex_mult delay_prod_inst (
@ -130,48 +155,75 @@ complex_mult delay_prod_inst (
.output_strobe(prod_stb)
);
moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT))
delay_prod_avg_i_inst (
.clock(clock),
.enable(enable),
.reset(reset),
.data_in(prod[63:32]),
.input_strobe(prod_stb),
.data_out(prod_avg[63:32]),
.output_strobe(prod_avg_stb)
// moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT))
// delay_prod_avg_i_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
// .data_in(prod[63:32]),
// .input_strobe(prod_stb),
// .data_out(prod_avg[63:32]),
// .output_strobe(prod_avg_stb)
// );
// moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT))
// delay_prod_avg_q_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
// .data_in(prod[31:0]),
// .input_strobe(prod_stb),
// .data_out(prod_avg[31:0])
// );
mv_avg_dual_ch #(.DATA_WIDTH0(32), .DATA_WIDTH1(32), .LOG2_AVG_LEN(WINDOW_SHIFT)) delay_prod_avg_inst (
.clk(clock),
.rstn(~(reset|reset_delay1|reset_delay2|reset_delay3|reset_delay4)),
// .rstn(~reset),
.data_in0(prod[63:32]),
.data_in1(prod[31:0]),
.data_in_valid(prod_stb),
.data_out0(prod_avg[63:32]),
.data_out1(prod_avg[31:0]),
.data_out_valid(prod_avg_stb)
);
moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(WINDOW_SHIFT))
delay_prod_avg_q_inst (
.clock(clock),
.enable(enable),
.reset(reset),
.data_in(prod[31:0]),
.input_strobe(prod_stb),
.data_out(prod_avg[31:0])
);
// // for fixing freq offset
// moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(6))
// freq_offset_i_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
// .data_in(prod[63:32]),
// .input_strobe(prod_stb),
// .data_out(phase_in_i),
// .output_strobe(phase_in_stb)
// );
// moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(6))
// freq_offset_q_inst (
// .clock(clock),
// .enable(enable),
// .reset(reset),
// .data_in(prod[31:0]),
// .input_strobe(prod_stb),
// .data_out(phase_in_q)
// );
// for fixing freq offset
moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(6))
freq_offset_i_inst (
.clock(clock),
.enable(enable),
.reset(reset),
.data_in(prod[63:32]),
.input_strobe(prod_stb),
.data_out(phase_in_i),
.output_strobe(phase_in_stb)
);
mv_avg_dual_ch #(.DATA_WIDTH0(32), .DATA_WIDTH1(32), .LOG2_AVG_LEN(6)) freq_offset_inst (
.clk(clock),
.rstn(~(reset|reset_delay1|reset_delay2|reset_delay3|reset_delay4)),
// .rstn(~reset),
.data_in0(prod[63:32]),
.data_in1(prod[31:0]),
.data_in_valid(prod_stb),
moving_avg #(.DATA_WIDTH(32), .WINDOW_SHIFT(6))
freq_offset_q_inst (
.clock(clock),
.enable(enable),
.reset(reset),
.data_in(prod[31:0]),
.input_strobe(prod_stb),
.data_out(phase_in_q)
.data_out0(phase_in_i),
.data_out1(phase_in_q),
.data_out_valid(phase_in_stb)
);
complex_to_mag #(.DATA_WIDTH(32)) delay_prod_avg_mag_inst (
@ -188,6 +240,11 @@ complex_to_mag #(.DATA_WIDTH(32)) delay_prod_avg_mag_inst (
always @(posedge clock) begin
if (reset) begin
reset_delay1 <= reset;
reset_delay2 <= reset;
reset_delay3 <= reset;
reset_delay4 <= reset;
sample_delayed_conj <= 0;
sample_delayed_conj_stb <= 0;
@ -205,6 +262,11 @@ always @(posedge clock) begin
short_preamble_detected <= 0;
phase_offset <= 0;
end else if (enable) begin
reset_delay4 <= reset_delay3;
reset_delay3 <= reset_delay2;
reset_delay2 <= reset_delay1;
reset_delay1 <= reset;
sample_delayed_conj_stb <= sample_delayed_stb;
sample_delayed_conj[31:16] <= sample_delayed[31:16];
sample_delayed_conj[15:0] <= ~sample_delayed[15:0]+1;