Archived
finish coding and testing of online acq; add sample data
串行在线捕获程序已经完成编写,并进行了仿真和测试(对飞和814均可用);增加了在电子所使用转台测试的幅相采集数据
This commit is contained in:
@@ -0,0 +1,772 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 05/06/2023 02:33:07 PM
|
||||
// Design Name:
|
||||
// Module Name: freq_comp
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module freq_comp
|
||||
#(
|
||||
parameter DATA_I_WIDTH = 12,
|
||||
parameter DATA_O_WIDTH = 18,
|
||||
|
||||
parameter FREQ_WORD_WIDTH = 32,
|
||||
parameter FREQ_WORD_LOWER = -4194304,
|
||||
parameter FREQ_WORD_UPPER = 4194303,
|
||||
parameter FREQ_WORD_STEP = 1024,
|
||||
|
||||
parameter MAX_DMF_NUM = 64,
|
||||
|
||||
// length of pseudorandom bit sequence, need to be a power of 2
|
||||
parameter PRBS_LEN = 128,
|
||||
// interpolation of input signal, need to be a power of 2
|
||||
parameter INTERP_RATE = 8,
|
||||
// signal processing interpolation, need to be a power of 2
|
||||
parameter PROCESS_INTERP = 4,
|
||||
// possible position of pn code
|
||||
parameter PRBS_POS = 2*PRBS_LEN*PROCESS_INTERP
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input clk ,
|
||||
input rst ,
|
||||
|
||||
// module enable switch
|
||||
input freq_comp_start ,
|
||||
output freq_comp_busy ,
|
||||
|
||||
// input data
|
||||
input rx_data_valid ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch1_i ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch1_q ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch2_i ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch2_q ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch3_i ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch3_q ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch4_i ,
|
||||
input [DATA_I_WIDTH-1 : 0] rx_ch4_q ,
|
||||
|
||||
// configuration
|
||||
input [$clog2(MAX_DMF_NUM)-1 : 0] dmf_num_per_ch ,
|
||||
|
||||
input [FREQ_WORD_WIDTH-1 : 0] freq_manual ,
|
||||
input freq_manual_en ,
|
||||
|
||||
// output frequency result
|
||||
output [FREQ_WORD_WIDTH-1 : 0] freq_target ,
|
||||
output freq_target_valid ,
|
||||
|
||||
// output dmf result
|
||||
output ch_peak_valid ,
|
||||
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_abs ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_i ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_q ,
|
||||
output reg [$clog2(PRBS_POS-1) : 0] ch1_peak_index ,
|
||||
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_abs ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_i ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_q ,
|
||||
output reg [$clog2(PRBS_POS-1) : 0] ch2_peak_index ,
|
||||
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_abs ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_i ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_q ,
|
||||
output reg [$clog2(PRBS_POS-1) : 0] ch3_peak_index ,
|
||||
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_abs ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_i ,
|
||||
output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_q ,
|
||||
output reg [$clog2(PRBS_POS-1) : 0] ch4_peak_index
|
||||
);
|
||||
|
||||
localparam STATE_NUM = 8;
|
||||
localparam [$clog2(STATE_NUM)-1:0]
|
||||
STATE_IDLE = 0,
|
||||
STATE_FREQ_SW = 1,
|
||||
STATE_FREQ_DMF = 2,
|
||||
STATE_CH_SW = 3,
|
||||
STATE_CH1 = 4,
|
||||
STATE_CH2 = 5,
|
||||
STATE_CH3 = 6,
|
||||
STATE_CH4 = 7;
|
||||
|
||||
localparam FREQ_WORD_LOWER_WIDTH = $clog2(FREQ_WORD_LOWER);
|
||||
localparam FREQ_WORD_UPPER_WIDTH = $clog2(FREQ_WORD_UPPER);
|
||||
localparam FREQ_WORD_STEP_WIDTH = $clog2(FREQ_WORD_STEP );
|
||||
|
||||
localparam DDS_DATA_WIDTH = 8;
|
||||
localparam STABLE_COUNT_MOD = 16;
|
||||
|
||||
localparam CMPY_A_WIDTH = DATA_I_WIDTH;
|
||||
localparam CMPY_B_WIDTH = DDS_DATA_WIDTH;
|
||||
localparam CMPY_P_WIDTH = CMPY_A_WIDTH+CMPY_B_WIDTH;
|
||||
localparam CMPY_P_FULL_WIDTH = CMPY_P_WIDTH+1;
|
||||
localparam CMPY_OUTPUT_WIDTH = DATA_I_WIDTH;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// Center State Control /////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// current and next state
|
||||
reg [$clog2(STATE_NUM)-1 : 0] state_curr = STATE_IDLE;
|
||||
reg [$clog2(STATE_NUM)-1 : 0] state_next = STATE_IDLE;
|
||||
|
||||
// edge detection
|
||||
reg freq_comp_start_d1 = 'b0;
|
||||
reg freq_comp_start_d2 = 'b0;
|
||||
|
||||
// stable counter, for dds frequency and complex multiplier to be ready
|
||||
reg [$clog2(STABLE_COUNT_MOD)-1 : 0] cnt_stable = 'b0;
|
||||
|
||||
// count the number of times dmf has been executed on each channel
|
||||
reg [$clog2(MAX_DMF_NUM)-1 : 0] cnt_dmf_ch = 'b0;
|
||||
|
||||
// cmpy output data valid indicator
|
||||
wire din_cxr_valid;
|
||||
|
||||
// dmf finish indicator
|
||||
wire dmf_peak_valid;
|
||||
|
||||
// current frequency word
|
||||
reg signed [FREQ_WORD_WIDTH-1 : 0] freq_word = 'b0;
|
||||
|
||||
// frequency scan finish indicator
|
||||
reg freq_end = 'b0;
|
||||
|
||||
// dmf finish indicator for each channel
|
||||
reg ch1_peak_valid = 'b0;
|
||||
reg ch2_peak_valid = 'b0;
|
||||
reg ch3_peak_valid = 'b0;
|
||||
reg ch4_peak_valid = 'b0;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// 1st always block, sequential state transition
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
state_curr <= STATE_IDLE;
|
||||
end
|
||||
else begin
|
||||
state_curr <= state_next;
|
||||
end
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// 2nd always block, combinational condition judgment
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(*) begin
|
||||
case (state_curr)
|
||||
STATE_IDLE: begin
|
||||
if (rx_data_valid && (freq_comp_start_d2 != freq_comp_start_d1)) begin
|
||||
// when input data valid & either edge of start signal is detected
|
||||
state_next = STATE_FREQ_SW;
|
||||
end
|
||||
else begin
|
||||
state_next = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
STATE_FREQ_SW: begin
|
||||
if (cnt_stable == STABLE_COUNT_MOD-1) begin
|
||||
// wait util dds frequency and complex multiplier is ready
|
||||
state_next = STATE_FREQ_DMF;
|
||||
end
|
||||
else begin
|
||||
state_next = STATE_FREQ_SW;
|
||||
end
|
||||
end
|
||||
STATE_FREQ_DMF: begin
|
||||
if (dmf_peak_valid) begin
|
||||
// when dmf is done, check if frequency compensation is over
|
||||
state_next = freq_end ? STATE_CH_SW : STATE_FREQ_SW;
|
||||
end
|
||||
else begin
|
||||
state_next = STATE_FREQ_DMF;
|
||||
end
|
||||
end
|
||||
STATE_CH_SW : begin
|
||||
if (cnt_stable == STABLE_COUNT_MOD-1) begin
|
||||
// wait util dds frequency and complex multiplier is ready
|
||||
// go through each channel
|
||||
if (!ch1_peak_valid) begin
|
||||
state_next <= STATE_CH1;
|
||||
end
|
||||
else if (!ch2_peak_valid) begin
|
||||
state_next <= STATE_CH2;
|
||||
end
|
||||
else if (!ch3_peak_valid) begin
|
||||
state_next <= STATE_CH3;
|
||||
end
|
||||
else if (!ch4_peak_valid) begin
|
||||
state_next <= STATE_CH4;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
state_next <= STATE_CH_SW;
|
||||
end
|
||||
end
|
||||
STATE_CH1 : begin
|
||||
if (ch1_peak_valid) begin
|
||||
// wait until dmf is done
|
||||
state_next <= STATE_CH_SW;
|
||||
end
|
||||
else begin
|
||||
state_next <= STATE_CH1;
|
||||
end
|
||||
end
|
||||
STATE_CH2 : begin
|
||||
if (ch2_peak_valid) begin
|
||||
// wait until dmf is done
|
||||
state_next <= STATE_CH_SW;
|
||||
end
|
||||
else begin
|
||||
state_next <= STATE_CH2;
|
||||
end
|
||||
end
|
||||
STATE_CH3 : begin
|
||||
if (ch3_peak_valid) begin
|
||||
state_next <= STATE_CH_SW;
|
||||
// wait until dmf is done
|
||||
end
|
||||
else begin
|
||||
state_next <= STATE_CH3;
|
||||
end
|
||||
end
|
||||
STATE_CH4 : begin
|
||||
if (ch4_peak_valid) begin
|
||||
// wait until dmf is done, check if the number of dmf is enough
|
||||
state_next <= (cnt_dmf_ch == dmf_num_per_ch-1) ? STATE_IDLE : STATE_CH_SW;
|
||||
end
|
||||
else begin
|
||||
state_next <= STATE_CH4;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
// hold
|
||||
state_next = state_next;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// 3rd always block, the sequential FSM output
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// edge detection
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
freq_comp_start_d1 <= freq_comp_start;
|
||||
freq_comp_start_d2 <= freq_comp_start_d1;
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// busy indicator
|
||||
// -----------------------------------------------------------------------------
|
||||
reg freq_comp_busy_buf = 'b0;
|
||||
|
||||
assign freq_comp_busy = freq_comp_busy_buf;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
freq_comp_busy_buf <= 'b0;
|
||||
end
|
||||
else begin
|
||||
case (state_next)
|
||||
// change between states
|
||||
STATE_IDLE : freq_comp_busy_buf <= 1'b0;
|
||||
STATE_FREQ_SW : freq_comp_busy_buf <= 1'b1;
|
||||
STATE_FREQ_DMF: freq_comp_busy_buf <= 1'b1;
|
||||
STATE_CH_SW : freq_comp_busy_buf <= 1'b1;
|
||||
STATE_CH1 : freq_comp_busy_buf <= 1'b1;
|
||||
STATE_CH2 : freq_comp_busy_buf <= 1'b1;
|
||||
STATE_CH3 : freq_comp_busy_buf <= 1'b1;
|
||||
STATE_CH4 : freq_comp_busy_buf <= 1'b1;
|
||||
default : freq_comp_busy_buf <= freq_comp_busy_buf;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// stable counter, for dds frequency and complex multiplier to be ready
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cnt_stable <= 'b0;
|
||||
end
|
||||
else case (state_curr)
|
||||
// change within one state
|
||||
STATE_FREQ_SW: cnt_stable <= cnt_stable + 1'b1;
|
||||
STATE_CH_SW : cnt_stable <= cnt_stable + 1'b1;
|
||||
default : cnt_stable <= 'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// count the number of times dmf has been executed on each channel
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cnt_dmf_ch <= 'b0;
|
||||
end
|
||||
else if (state_next == STATE_IDLE) begin
|
||||
cnt_dmf_ch <= 'b0;
|
||||
end
|
||||
else begin
|
||||
cnt_dmf_ch <= (ch_peak_valid) ? cnt_dmf_ch + 1'b1 : cnt_dmf_ch;
|
||||
end
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// frequency word control
|
||||
// -----------------------------------------------------------------------------
|
||||
// record the frequency word generating the maximum peak
|
||||
reg [FREQ_WORD_WIDTH-1 : 0] max_peak_freq = 'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
freq_word <= FREQ_WORD_LOWER;
|
||||
end
|
||||
else case (state_next)
|
||||
// change between states
|
||||
STATE_FREQ_SW: begin
|
||||
if (state_curr == STATE_IDLE) begin
|
||||
// initialization
|
||||
freq_word <= FREQ_WORD_LOWER;
|
||||
end
|
||||
else if (state_curr == STATE_FREQ_DMF) begin
|
||||
// switch frequency
|
||||
freq_word <= freq_word + FREQ_WORD_STEP;
|
||||
end
|
||||
end
|
||||
STATE_CH_SW: begin
|
||||
freq_word <= (freq_manual_en) ? freq_manual : max_peak_freq;
|
||||
end
|
||||
default: begin
|
||||
freq_word <= freq_word;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// frequency scan finish indicator
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
freq_end <= 'b0;
|
||||
end
|
||||
else if (freq_word > FREQ_WORD_UPPER) begin
|
||||
freq_end <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
freq_end <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// complex multiplier input data control
|
||||
// -----------------------------------------------------------------------------
|
||||
reg [DATA_I_WIDTH-1 : 0] din_real = 'b0;
|
||||
reg [DATA_I_WIDTH-1 : 0] din_imag = 'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
din_real <= 'b0;
|
||||
din_imag <= 'b0;
|
||||
end
|
||||
else case (state_next)
|
||||
// reset when idle; using ch2 data for frequency scan
|
||||
STATE_IDLE : begin din_real <= 'b0 ; din_imag <= 'b0 ; end
|
||||
STATE_FREQ_SW : begin din_real <= rx_ch2_i; din_imag <= rx_ch2_q; end
|
||||
STATE_FREQ_DMF : begin din_real <= rx_ch2_i; din_imag <= rx_ch2_q; end
|
||||
STATE_CH_SW : case (state_curr)
|
||||
STATE_FREQ_DMF: begin din_real <= rx_ch1_i; din_imag <= rx_ch1_q; end
|
||||
STATE_CH1 : begin din_real <= rx_ch2_i; din_imag <= rx_ch2_q; end
|
||||
STATE_CH2 : begin din_real <= rx_ch3_i; din_imag <= rx_ch3_q; end
|
||||
STATE_CH3 : begin din_real <= rx_ch4_i; din_imag <= rx_ch4_q; end
|
||||
STATE_CH4 : begin din_real <= rx_ch1_i; din_imag <= rx_ch1_q; end
|
||||
default : begin din_real <= rx_ch1_i; din_imag <= rx_ch1_q; end
|
||||
endcase
|
||||
STATE_CH1 : begin din_real <= rx_ch1_i; din_imag <= rx_ch1_q; end
|
||||
STATE_CH2 : begin din_real <= rx_ch2_i; din_imag <= rx_ch2_q; end
|
||||
STATE_CH3 : begin din_real <= rx_ch3_i; din_imag <= rx_ch3_q; end
|
||||
STATE_CH4 : begin din_real <= rx_ch4_i; din_imag <= rx_ch4_q; end
|
||||
default : begin din_real <= rx_ch2_i; din_imag <= rx_ch2_q; end
|
||||
endcase
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// DDS //////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
localparam AXIS_FREQ_WORD_WIDTH = 8*((FREQ_WORD_WIDTH-1)/8+1);
|
||||
localparam AXIS_DDS_DATA_WIDTH = 8*((DDS_DATA_WIDTH-1)/8+1);
|
||||
|
||||
wire [DDS_DATA_WIDTH-1:0] sin_dds, cos_dds;
|
||||
wire dds_valid;
|
||||
|
||||
wire dds_s_axis_config_tvalid;
|
||||
wire [AXIS_FREQ_WORD_WIDTH-1 : 0] dds_s_axis_config_ttdata;
|
||||
wire dds_m_axis_data_tvalid ;
|
||||
wire [2*AXIS_DDS_DATA_WIDTH-1 : 0] dds_m_axis_data_ttdata ;
|
||||
|
||||
assign dds_s_axis_config_tvalid = freq_comp_busy;
|
||||
assign dds_s_axis_config_ttdata = freq_word;
|
||||
assign dds_valid = dds_m_axis_data_tvalid;
|
||||
assign {sin_dds,cos_dds} = dds_m_axis_data_ttdata;
|
||||
|
||||
dds_32b_8b u_dds_bb_shift
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_config_tvalid (dds_s_axis_config_tvalid ), // input wire s_axis_config_tvalid
|
||||
.s_axis_config_tdata (dds_s_axis_config_ttdata ), // input wire [31 : 0] s_axis_config_tdata
|
||||
.m_axis_data_tvalid (dds_m_axis_data_tvalid ), // output wire m_axis_data_tvalid
|
||||
.m_axis_data_tdata (dds_m_axis_data_ttdata ) // output wire [15 : 0] m_axis_data_tdata
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////// Complex Multiplier //////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
localparam AXIS_CMPY_A_WIDTH = 8*((CMPY_A_WIDTH-1)/8+1);
|
||||
localparam AXIS_CMPY_B_WIDTH = 8*((CMPY_B_WIDTH-1)/8+1);
|
||||
localparam AXIS_CMPY_P_WIDTH = 8*((CMPY_P_FULL_WIDTH-1)/8+1);
|
||||
|
||||
// cmpy
|
||||
wire [CMPY_OUTPUT_WIDTH-1 : 0] din_cxr_real;
|
||||
wire [CMPY_OUTPUT_WIDTH-1 : 0] din_cxr_imag;
|
||||
// wire din_cxr_valid; // declared ahead
|
||||
|
||||
wire cmpy_a_valid;
|
||||
wire [2*AXIS_CMPY_A_WIDTH-1 : 0] cmpy_a ;
|
||||
wire cmpy_b_valid;
|
||||
wire [2*AXIS_CMPY_B_WIDTH-1 : 0] cmpy_b ;
|
||||
wire cmpy_p_valid;
|
||||
wire [2*AXIS_CMPY_P_WIDTH-1 : 0] cmpy_p ;
|
||||
|
||||
assign cmpy_a_valid = freq_comp_busy;
|
||||
assign cmpy_b_valid = dds_valid;
|
||||
assign din_cxr_valid = cmpy_p_valid;
|
||||
|
||||
// sign bit extension to fit axis 8-bit data format
|
||||
assign cmpy_a = {{(AXIS_CMPY_A_WIDTH-CMPY_A_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag,
|
||||
{(AXIS_CMPY_A_WIDTH-CMPY_A_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real};
|
||||
assign cmpy_b = {{(AXIS_CMPY_B_WIDTH-CMPY_B_WIDTH){sin_dds[DDS_DATA_WIDTH-1]}},sin_dds,
|
||||
{(AXIS_CMPY_B_WIDTH-CMPY_B_WIDTH){cos_dds[DDS_DATA_WIDTH-1]}},cos_dds};
|
||||
|
||||
if (CMPY_OUTPUT_WIDTH > CMPY_P_WIDTH) begin
|
||||
// append zeros
|
||||
assign din_cxr_real = {cmpy_p[0 +: CMPY_P_WIDTH],{(CMPY_OUTPUT_WIDTH-CMPY_P_WIDTH){1'b0}}};
|
||||
assign din_cxr_imag = {cmpy_p[AXIS_CMPY_P_WIDTH +: CMPY_P_WIDTH],{(CMPY_OUTPUT_WIDTH-CMPY_P_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate valid msb
|
||||
assign din_cxr_real = cmpy_p[CMPY_P_WIDTH-1 -: CMPY_OUTPUT_WIDTH];
|
||||
assign din_cxr_imag = cmpy_p[AXIS_CMPY_P_WIDTH+CMPY_P_WIDTH-1 -: CMPY_OUTPUT_WIDTH];
|
||||
end
|
||||
|
||||
cmpy_12x8 u_cmpy_12x8
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_a_tvalid (cmpy_a_valid ), // input wire s_axis_a_tvalid
|
||||
.s_axis_a_tdata (cmpy_a ), // input wire [31 : 0] s_axis_a_tdata
|
||||
.s_axis_b_tvalid (cmpy_b_valid ), // input wire s_axis_b_tvalid
|
||||
.s_axis_b_tdata (cmpy_b ), // input wire [15 : 0] s_axis_b_tdata
|
||||
.m_axis_dout_tvalid (cmpy_p_valid ), // output wire m_axis_dout_tvalid
|
||||
.m_axis_dout_tdata (cmpy_p ) // output wire [47 : 0] m_axis_dout_tdata
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Digital Matched Filter ////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
reg dmf_start = 'b0;
|
||||
wire dmf_busy;
|
||||
|
||||
wire dmf_din_valid;
|
||||
wire [DATA_I_WIDTH-1 : 0] dmf_din_real;
|
||||
wire [DATA_I_WIDTH-1 : 0] dmf_din_imag;
|
||||
|
||||
wire [DATA_O_WIDTH-1 : 0] dmf_peak_value_abs;
|
||||
wire [DATA_O_WIDTH-1 : 0] dmf_peak_value_i;
|
||||
wire [DATA_O_WIDTH-1 : 0] dmf_peak_value_q;
|
||||
wire [$clog2(PRBS_POS-1) : 0] dmf_peak_index;
|
||||
|
||||
assign dmf_din_valid = din_cxr_valid;
|
||||
|
||||
if (DATA_I_WIDTH > CMPY_OUTPUT_WIDTH) begin
|
||||
// append zerod
|
||||
assign dmf_din_real = {din_cxr_real,{(DATA_I_WIDTH-CMPY_OUTPUT_WIDTH){1'b0}}};
|
||||
assign dmf_din_imag = {din_cxr_imag,{(DATA_I_WIDTH-CMPY_OUTPUT_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign dmf_din_real = din_cxr_real[CMPY_OUTPUT_WIDTH-1 -: DATA_I_WIDTH];
|
||||
assign dmf_din_imag = din_cxr_imag[CMPY_OUTPUT_WIDTH-1 -: DATA_I_WIDTH];
|
||||
end
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// dmf start control
|
||||
// -----------------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
dmf_start <= 'b0;
|
||||
end
|
||||
else case (state_next)
|
||||
STATE_FREQ_DMF: dmf_start <= (state_curr == STATE_FREQ_SW) ? ~dmf_start : dmf_start;
|
||||
STATE_CH1 : dmf_start <= (state_curr == STATE_CH_SW ) ? ~dmf_start : dmf_start;
|
||||
STATE_CH2 : dmf_start <= (state_curr == STATE_CH_SW ) ? ~dmf_start : dmf_start;
|
||||
STATE_CH3 : dmf_start <= (state_curr == STATE_CH_SW ) ? ~dmf_start : dmf_start;
|
||||
STATE_CH4 : dmf_start <= (state_curr == STATE_CH_SW ) ? ~dmf_start : dmf_start;
|
||||
default: dmf_start <= dmf_start;
|
||||
endcase
|
||||
end
|
||||
|
||||
// dmf instantiation
|
||||
rx_dmf #(
|
||||
.PRBS_LEN (PRBS_LEN ),
|
||||
.INTERP_RATE (INTERP_RATE ),
|
||||
.PROCESS_INTERP (PROCESS_INTERP ),
|
||||
.DATA_I_WIDTH (DATA_I_WIDTH ),
|
||||
.DATA_O_WIDTH (DATA_O_WIDTH )
|
||||
) u_rx_dmf
|
||||
(
|
||||
.clk (clk ),
|
||||
.rst (rst ),
|
||||
|
||||
.dmf_start (dmf_start ),
|
||||
.dmf_busy (dmf_busy ),
|
||||
|
||||
.din_valid (dmf_din_valid ),
|
||||
.din_real (dmf_din_real ),
|
||||
.din_imag (dmf_din_imag ),
|
||||
|
||||
.peak_valid (dmf_peak_valid ),
|
||||
.peak_value_abs (dmf_peak_value_abs ),
|
||||
.peak_value_i (dmf_peak_value_i ),
|
||||
.peak_value_q (dmf_peak_value_q ),
|
||||
.peak_index (dmf_peak_index )
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// peak finding at different frequencies
|
||||
// -----------------------------------------------------------------------------
|
||||
reg max_peak_valid = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] max_peak_value_abs = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] max_peak_value_i = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] max_peak_value_q = 'b0;
|
||||
reg [$clog2(PRBS_POS-1) : 0] max_peak_index = 'b0;
|
||||
|
||||
// output result to port
|
||||
assign freq_target_valid = max_peak_valid;
|
||||
assign freq_target = max_peak_freq;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
max_peak_valid <= 'b0;
|
||||
max_peak_value_abs <= 'b0;
|
||||
max_peak_value_i <= 'b0;
|
||||
max_peak_value_q <= 'b0;
|
||||
max_peak_index <= 'b0;
|
||||
max_peak_freq <= 'b0;
|
||||
end
|
||||
else case (state_next)
|
||||
STATE_IDLE: begin
|
||||
max_peak_valid <= 'b0;
|
||||
max_peak_value_abs <= 'b0;
|
||||
max_peak_value_i <= 'b0;
|
||||
max_peak_value_q <= 'b0;
|
||||
max_peak_index <= 'b0;
|
||||
max_peak_freq <= 'b0;
|
||||
end
|
||||
STATE_FREQ_SW: begin
|
||||
if ((state_curr == STATE_FREQ_DMF) && (dmf_peak_value_abs > max_peak_value_abs)) begin
|
||||
// at the end of [STATE_FREQ_DMF] state, check if peak is valid
|
||||
max_peak_value_abs <= dmf_peak_value_abs;
|
||||
max_peak_value_i <= dmf_peak_value_i ;
|
||||
max_peak_value_q <= dmf_peak_value_q ;
|
||||
max_peak_index <= dmf_peak_index ;
|
||||
max_peak_freq <= freq_word ;
|
||||
end
|
||||
else begin
|
||||
// hold otherwise
|
||||
max_peak_value_abs <= max_peak_value_abs;
|
||||
max_peak_value_i <= max_peak_value_i ;
|
||||
max_peak_value_q <= max_peak_value_q ;
|
||||
max_peak_index <= max_peak_index ;
|
||||
max_peak_freq <= max_peak_freq ;
|
||||
end
|
||||
end
|
||||
STATE_CH_SW: begin
|
||||
if (state_curr == STATE_FREQ_DMF) begin
|
||||
// indicate the target frequency word is found
|
||||
max_peak_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
max_peak_valid <= 'b0;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
max_peak_valid <= 'b0;
|
||||
max_peak_value_abs <= max_peak_value_abs;
|
||||
max_peak_value_i <= max_peak_value_i ;
|
||||
max_peak_value_q <= max_peak_value_q ;
|
||||
max_peak_index <= max_peak_index ;
|
||||
max_peak_freq <= max_peak_freq ;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// peak record for each channel
|
||||
// -----------------------------------------------------------------------------
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_abs = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_i = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_q = 'b0;
|
||||
// reg [$clog2(PRBS_POS-1) : 0] ch1_peak_index = 'b0;
|
||||
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_abs = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_i = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_q = 'b0;
|
||||
// reg [$clog2(PRBS_POS-1) : 0] ch2_peak_index = 'b0;
|
||||
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_abs = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_i = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_q = 'b0;
|
||||
// reg [$clog2(PRBS_POS-1) : 0] ch3_peak_index = 'b0;
|
||||
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_abs = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_i = 'b0;
|
||||
// reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_q = 'b0;
|
||||
// reg [$clog2(PRBS_POS-1) : 0] ch4_peak_index = 'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
ch1_peak_valid <= 'b0;
|
||||
ch1_peak_value_abs <= 'b0;
|
||||
ch1_peak_value_i <= 'b0;
|
||||
ch1_peak_value_q <= 'b0;
|
||||
ch1_peak_index <= 'b0;
|
||||
|
||||
ch2_peak_valid <= 'b0;
|
||||
ch2_peak_value_abs <= 'b0;
|
||||
ch2_peak_value_i <= 'b0;
|
||||
ch2_peak_value_q <= 'b0;
|
||||
ch2_peak_index <= 'b0;
|
||||
|
||||
ch3_peak_valid <= 'b0;
|
||||
ch3_peak_value_abs <= 'b0;
|
||||
ch3_peak_value_i <= 'b0;
|
||||
ch3_peak_value_q <= 'b0;
|
||||
ch3_peak_index <= 'b0;
|
||||
|
||||
ch4_peak_valid <= 'b0;
|
||||
ch4_peak_value_abs <= 'b0;
|
||||
ch4_peak_value_i <= 'b0;
|
||||
ch4_peak_value_q <= 'b0;
|
||||
ch4_peak_index <= 'b0;
|
||||
end
|
||||
else case (state_curr)
|
||||
STATE_CH_SW : begin
|
||||
ch1_peak_valid <= ch1_peak_valid;
|
||||
ch2_peak_valid <= ch2_peak_valid;
|
||||
ch3_peak_valid <= ch3_peak_valid;
|
||||
ch4_peak_valid <= ch4_peak_valid;
|
||||
end
|
||||
STATE_CH1 : begin
|
||||
ch1_peak_valid <= (dmf_peak_valid) ? 1'b1 : ch1_peak_valid;
|
||||
ch1_peak_value_abs <= (dmf_peak_valid) ? dmf_peak_value_abs : ch1_peak_value_abs;
|
||||
ch1_peak_value_i <= (dmf_peak_valid) ? dmf_peak_value_i : ch1_peak_value_i ;
|
||||
ch1_peak_value_q <= (dmf_peak_valid) ? dmf_peak_value_q : ch1_peak_value_q ;
|
||||
ch1_peak_index <= (dmf_peak_valid) ? dmf_peak_index : ch1_peak_index ;
|
||||
end
|
||||
STATE_CH2 : begin
|
||||
ch2_peak_valid <= (dmf_peak_valid) ? 1'b1 : ch2_peak_valid;
|
||||
ch2_peak_value_abs <= (dmf_peak_valid) ? dmf_peak_value_abs : ch2_peak_value_abs;
|
||||
ch2_peak_value_i <= (dmf_peak_valid) ? dmf_peak_value_i : ch2_peak_value_i ;
|
||||
ch2_peak_value_q <= (dmf_peak_valid) ? dmf_peak_value_q : ch2_peak_value_q ;
|
||||
ch2_peak_index <= (dmf_peak_valid) ? dmf_peak_index : ch2_peak_index ;
|
||||
end
|
||||
STATE_CH3 : begin
|
||||
ch3_peak_valid <= (dmf_peak_valid) ? 1'b1 : ch3_peak_valid;
|
||||
ch3_peak_value_abs <= (dmf_peak_valid) ? dmf_peak_value_abs : ch3_peak_value_abs;
|
||||
ch3_peak_value_i <= (dmf_peak_valid) ? dmf_peak_value_i : ch3_peak_value_i ;
|
||||
ch3_peak_value_q <= (dmf_peak_valid) ? dmf_peak_value_q : ch3_peak_value_q ;
|
||||
ch3_peak_index <= (dmf_peak_valid) ? dmf_peak_index : ch3_peak_index ;
|
||||
end
|
||||
STATE_CH4 : begin
|
||||
if ((state_next == STATE_CH_SW) || (state_next == STATE_IDLE)) begin
|
||||
// when another dmf is needed, clear valid indicator
|
||||
ch1_peak_valid <= 'b0;
|
||||
ch2_peak_valid <= 'b0;
|
||||
ch3_peak_valid <= 'b0;
|
||||
ch4_peak_valid <= 'b0;
|
||||
end
|
||||
else begin
|
||||
ch4_peak_valid <= (dmf_peak_valid) ? 1'b1 : ch4_peak_valid;
|
||||
ch4_peak_value_abs <= (dmf_peak_valid) ? dmf_peak_value_abs : ch4_peak_value_abs;
|
||||
ch4_peak_value_i <= (dmf_peak_valid) ? dmf_peak_value_i : ch4_peak_value_i ;
|
||||
ch4_peak_value_q <= (dmf_peak_valid) ? dmf_peak_value_q : ch4_peak_value_q ;
|
||||
ch4_peak_index <= (dmf_peak_valid) ? dmf_peak_index : ch4_peak_index ;
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
ch1_peak_valid <= 'b0 ;
|
||||
ch1_peak_value_abs <= ch1_peak_value_abs;
|
||||
ch1_peak_value_i <= ch1_peak_value_i ;
|
||||
ch1_peak_value_q <= ch1_peak_value_q ;
|
||||
ch1_peak_index <= ch1_peak_index ;
|
||||
|
||||
ch2_peak_valid <= 'b0 ;
|
||||
ch2_peak_value_abs <= ch2_peak_value_abs;
|
||||
ch2_peak_value_i <= ch2_peak_value_i ;
|
||||
ch2_peak_value_q <= ch2_peak_value_q ;
|
||||
ch2_peak_index <= ch2_peak_index ;
|
||||
|
||||
ch3_peak_valid <= 'b0 ;
|
||||
ch3_peak_value_abs <= ch3_peak_value_abs;
|
||||
ch3_peak_value_i <= ch3_peak_value_i ;
|
||||
ch3_peak_value_q <= ch3_peak_value_q ;
|
||||
ch3_peak_index <= ch3_peak_index ;
|
||||
|
||||
ch4_peak_valid <= 'b0 ;
|
||||
ch4_peak_value_abs <= ch4_peak_value_abs;
|
||||
ch4_peak_value_i <= ch4_peak_value_i ;
|
||||
ch4_peak_value_q <= ch4_peak_value_q ;
|
||||
ch4_peak_index <= ch4_peak_index ;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// indicate dmf on all 4 channels are finished
|
||||
// -----------------------------------------------------------------------------
|
||||
reg ch_peak_valid_buf = 'b0;
|
||||
|
||||
assign ch_peak_valid = ch_peak_valid_buf;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
ch_peak_valid_buf <= 'b0;
|
||||
end
|
||||
else if ((state_curr == STATE_CH4) && dmf_peak_valid) begin
|
||||
ch_peak_valid_buf <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
ch_peak_valid_buf <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,167 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2023/05/06 15:37:29
|
||||
// Design Name:
|
||||
// Module Name: rf_auto_switch_freq
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module rf_auto_switch_freq(
|
||||
input clk ,
|
||||
input rst ,
|
||||
// vio control
|
||||
input start , // rise-edge active, if start, change freq word to the first
|
||||
input rf_ctrl_mode , // 1 : auto switch, 0 : manual switch
|
||||
input switch_next_freq , // rise-edge active
|
||||
input switch_last_freq , // rise-edge active
|
||||
input [15:0] cnt_valid_to_switch , // clock number from valid to switch
|
||||
// input
|
||||
input [15:0] freq_hop_words_vio ,
|
||||
input hop_words_valid_vio ,
|
||||
input freq_hop_switch_vio ,
|
||||
// output
|
||||
output reg [15:0] freq_hop_words_auto = 11'd0 ,
|
||||
output reg hop_words_valid_auto = 1'd0 ,
|
||||
output reg freq_hop_switch_auto = 1'd0
|
||||
);
|
||||
|
||||
//************************* rise-edge detect ***********************************
|
||||
reg start_d1 = 1'b0;
|
||||
reg start_d2 = 1'b0;
|
||||
reg start_pulse = 1'b0;
|
||||
reg switch_next_freq_d1 = 1'b0;
|
||||
reg switch_next_freq_d2 = 1'b0;
|
||||
reg [9:0] switch_next_freq_pulse = 10'd0;
|
||||
reg switch_last_freq_d1 = 1'b0;
|
||||
reg switch_last_freq_d2 = 1'b0;
|
||||
reg [9:0] switch_last_freq_pulse = 10'd0;
|
||||
always @ (posedge clk)
|
||||
if(rst) begin
|
||||
start_d1 <= 1'b0;
|
||||
start_d2 <= 1'b0;
|
||||
start_pulse <= 1'b0;
|
||||
switch_next_freq_d1 <= 1'b0;
|
||||
switch_next_freq_d2 <= 1'b0;
|
||||
switch_next_freq_pulse <= 10'd0;
|
||||
switch_last_freq_d1 <= 1'b0;
|
||||
switch_last_freq_d2 <= 1'b0;
|
||||
switch_last_freq_pulse <= 10'd0;
|
||||
end else begin
|
||||
start_d1 <= start;
|
||||
start_d2 <= start_d1;
|
||||
start_pulse <= start_d1 & ~start_d2;
|
||||
switch_next_freq_d1 <= switch_next_freq;
|
||||
switch_next_freq_d2 <= switch_next_freq_d1;
|
||||
switch_next_freq_pulse[0] <= switch_next_freq_d1 & ~switch_next_freq_d2;
|
||||
switch_next_freq_pulse[9:1] <= switch_next_freq_pulse[8:0];
|
||||
switch_last_freq_d1 <= switch_last_freq;
|
||||
switch_last_freq_d2 <= switch_last_freq_d1;
|
||||
switch_last_freq_pulse[0] <= switch_last_freq_d1 & ~switch_last_freq_d2;
|
||||
switch_last_freq_pulse[9:1] <= switch_last_freq_pulse[8:0];
|
||||
end
|
||||
|
||||
//******************** local freq word control *********************************
|
||||
reg [15:0] local_freq_word = 16'd0;
|
||||
reg local_freq_word_valid = 1'b0;
|
||||
reg local_freq_word_switch = 1'b0;
|
||||
reg [7:0] freq_word_cnt = 8'd0; // range 0 -> 80
|
||||
wire [15:0] rom_freq_word_dout;
|
||||
// 2 clock latency
|
||||
rom_freq_word rom_freq_word_inst(
|
||||
.clka (clk ),
|
||||
.addra (freq_word_cnt[6:0] ),
|
||||
.douta (rom_freq_word_dout )
|
||||
);
|
||||
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
freq_word_cnt <= 8'd0;
|
||||
else if(freq_word_cnt == 8'd80 && switch_next_freq_pulse[0])
|
||||
freq_word_cnt <= 8'd0;
|
||||
else if(freq_word_cnt == 8'd0 && switch_last_freq_pulse[0])
|
||||
freq_word_cnt <= 8'd80;
|
||||
else if(switch_next_freq_pulse[0])
|
||||
freq_word_cnt <= freq_word_cnt + 1'b1;
|
||||
else if(switch_last_freq_pulse[0])
|
||||
freq_word_cnt <= freq_word_cnt - 1'b1;
|
||||
else
|
||||
freq_word_cnt <= freq_word_cnt;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
local_freq_word_valid <= 1'b0;
|
||||
else if(switch_next_freq_pulse[4] | switch_last_freq_pulse[4])
|
||||
local_freq_word_valid <= 1'b1;
|
||||
else
|
||||
local_freq_word_valid <= 1'b0;
|
||||
|
||||
reg [15:0] freq_word_valid_cnt = 16'd0;
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
freq_word_valid_cnt <= 16'd0;
|
||||
else if(freq_word_valid_cnt == cnt_valid_to_switch)
|
||||
freq_word_valid_cnt <= 16'd0;
|
||||
else if(local_freq_word_valid)
|
||||
freq_word_valid_cnt <= freq_word_valid_cnt + 1'b1;
|
||||
else if(freq_word_valid_cnt != 16'd0)
|
||||
freq_word_valid_cnt <= freq_word_valid_cnt + 1'b1;
|
||||
else
|
||||
freq_word_valid_cnt <= freq_word_valid_cnt;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
local_freq_word_switch <= 1'b0;
|
||||
else if(freq_word_valid_cnt == cnt_valid_to_switch)
|
||||
local_freq_word_switch <= ~local_freq_word_switch;
|
||||
else
|
||||
local_freq_word_switch <= local_freq_word_switch;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
local_freq_word <= 16'd0;
|
||||
else
|
||||
local_freq_word <= rom_freq_word_dout;
|
||||
|
||||
//******************** output freq switch signal *******************************
|
||||
// freq_hop_words_auto
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
freq_hop_words_auto <= 11'd0;
|
||||
else if(rf_ctrl_mode)
|
||||
freq_hop_words_auto <= local_freq_word;
|
||||
else
|
||||
freq_hop_words_auto <= freq_hop_words_vio;
|
||||
|
||||
// hop_words_valid_auto
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
hop_words_valid_auto <= 1'b0;
|
||||
else if(rf_ctrl_mode)
|
||||
hop_words_valid_auto <= local_freq_word_valid;
|
||||
else
|
||||
hop_words_valid_auto <= hop_words_valid_vio;
|
||||
|
||||
// freq_hop_switch_auto
|
||||
always @ (posedge clk)
|
||||
if(rst | start_pulse)
|
||||
freq_hop_switch_auto <= 1'b0;
|
||||
else if(rf_ctrl_mode)
|
||||
freq_hop_switch_auto <= local_freq_word_switch;
|
||||
else
|
||||
freq_hop_switch_auto <= freq_hop_switch_vio;
|
||||
|
||||
endmodule
|
||||
@@ -2,6 +2,11 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 04/25/2023 05:53:44 PM
|
||||
// Design Name:
|
||||
@@ -22,140 +27,407 @@
|
||||
|
||||
module rx_dmf
|
||||
#(
|
||||
DATA_I_WIDTH = 12,
|
||||
DATA_O_WIDTH = 19,
|
||||
CHANNEL_NUM = 4,
|
||||
PEAK_WIDTH = DATA_O_WIDTH,
|
||||
PRBS_LEN = 128
|
||||
// length of pseudorandom bit sequence, need to be a power of 2
|
||||
parameter PRBS_LEN = 128,
|
||||
// interpolation of input signal, need to be a power of 2
|
||||
parameter INTERP_RATE = 8,
|
||||
// signal processing interpolation, need to be a power of 2
|
||||
parameter PROCESS_INTERP = 4,
|
||||
// possible position of pn code
|
||||
parameter PRBS_POS = 2*PRBS_LEN*PROCESS_INTERP,
|
||||
|
||||
parameter DATA_I_WIDTH = 12,
|
||||
parameter DATA_O_WIDTH = 18
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst ,
|
||||
input clk ,
|
||||
input rst ,
|
||||
|
||||
input din_valid ,
|
||||
input [DATA_I_WIDTH*CHANNEL_NUM-1 : 0] din_real ,
|
||||
input [DATA_I_WIDTH*CHANNEL_NUM-1 : 0] din_imag ,
|
||||
input dmf_start ,
|
||||
output dmf_busy ,
|
||||
|
||||
output dout_valid ,
|
||||
input [DATA_O_WIDTH*CHANNEL_NUM-1 : 0] dout_real,
|
||||
input [DATA_O_WIDTH*CHANNEL_NUM-1 : 0] dout_imag,
|
||||
input din_valid ,
|
||||
input [DATA_I_WIDTH-1 : 0] din_real ,
|
||||
input [DATA_I_WIDTH-1 : 0] din_imag ,
|
||||
|
||||
output [$clog2(PRBS_LEN)-1 : 0] peak_index ,
|
||||
output [PEAK_WIDTH-1 : 0] peak_value_i ,
|
||||
output [PEAK_WIDTH-1 : 0] peak_value_q ,
|
||||
output peak_valid
|
||||
output peak_valid ,
|
||||
output [DATA_O_WIDTH-1 : 0] peak_value_abs ,
|
||||
output [DATA_O_WIDTH-1 : 0] peak_value_i ,
|
||||
output [DATA_O_WIDTH-1 : 0] peak_value_q ,
|
||||
output [$clog2(PRBS_POS)-1 : 0] peak_index
|
||||
);
|
||||
|
||||
localparam FIR_I_WIDTH = 12;
|
||||
localparam FIR_O_WIDTH = 19;
|
||||
localparam CMPLX_DIM = 2;
|
||||
localparam APPROX_ABS_WIDTH = 29;
|
||||
localparam ABS_WIDTH = 18;
|
||||
|
||||
localparam AXIS_FIR_I_WIDTH = 8*((FIR_I_WIDTH-1)/8+1);
|
||||
localparam AXIS_FIR_O_WIDTH = 8*((FIR_O_WIDTH-1)/8+1);
|
||||
localparam DMF_I_WIDTH = 12;
|
||||
localparam DMF_O_WIDTH = DMF_I_WIDTH+$clog2(PRBS_POS/2);
|
||||
|
||||
localparam AXIS_DMF_I_WIDTH = 8*((DMF_I_WIDTH-1)/8+1);
|
||||
localparam AXIS_DMF_O_WIDTH = 8*((DMF_O_WIDTH-1)/8+1);
|
||||
|
||||
genvar m;
|
||||
integer i;
|
||||
|
||||
//
|
||||
wire [AXIS_FIR_I_WIDTH-1 : 0] din_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [AXIS_FIR_I_WIDTH-1 : 0] din_imag_array [0 : CHANNEL_NUM-1];
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// Center State Control /////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
reg dmf_busy_buf = 'b0;
|
||||
reg dmf_start_d1 = 'b0;
|
||||
reg dmf_start_d2 = 'b0;
|
||||
|
||||
generate
|
||||
for(m = 0; m < CHANNEL_NUM; m = m + 1) begin: array_convert_in
|
||||
assign dmf_busy = dmf_busy_buf;
|
||||
|
||||
if (AXIS_FIR_I_WIDTH > DATA_I_WIDTH) begin
|
||||
always @(posedge clk) begin
|
||||
dmf_start_d1 <= dmf_start;
|
||||
dmf_start_d2 <= dmf_start_d1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
dmf_busy_buf <= 'b0;
|
||||
end
|
||||
else if (peak_valid == 1'b1) begin
|
||||
// clear when output is valid
|
||||
dmf_busy_buf <= 'b0;
|
||||
end
|
||||
else if (din_valid && (dmf_start_d2 != dmf_start_d1)) begin
|
||||
// set when either edge is detected
|
||||
dmf_busy_buf <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
// otherwise keep
|
||||
dmf_busy_buf <= dmf_busy_buf;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////// Decimation Counter //////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
reg [$clog2(INTERP_RATE/PROCESS_INTERP)-1 : 0] cnt_deci = 'b0;
|
||||
reg din_deci_valid = 'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cnt_deci <= 'b0;
|
||||
end
|
||||
else if (dmf_busy && din_valid) begin
|
||||
cnt_deci <= cnt_deci + 1'b1;
|
||||
end
|
||||
else begin
|
||||
cnt_deci <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
din_deci_valid <= 'b0;
|
||||
end
|
||||
else begin
|
||||
din_deci_valid <= (cnt_deci == INTERP_RATE/PROCESS_INTERP-1) ? 1'b1 : 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Digital Matched Filter ////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input & output signals
|
||||
wire [AXIS_DMF_I_WIDTH-1 : 0] dmf_axis_i_real;
|
||||
wire [AXIS_DMF_I_WIDTH-1 : 0] dmf_axis_i_imag;
|
||||
wire signed [AXIS_DMF_O_WIDTH-1 : 0] dmf_axis_o_real;
|
||||
wire signed [AXIS_DMF_O_WIDTH-1 : 0] dmf_axis_o_imag;
|
||||
wire signed [DMF_O_WIDTH-1 : 0] dmf_o_real;
|
||||
wire signed [DMF_O_WIDTH-1 : 0] dmf_o_imag;
|
||||
wire dmf_o_valid;
|
||||
|
||||
// dmf input data formatting
|
||||
if (AXIS_DMF_I_WIDTH > DATA_I_WIDTH) begin
|
||||
// sign extension to fit 8-bit axis data format
|
||||
assign din_real_array[m] = {{(AXIS_FIR_I_WIDTH-DATA_I_WIDTH){din_real[(m+1)*DATA_I_WIDTH-1]}},din_real[m*DATA_I_WIDTH +: DATA_I_WIDTH]};
|
||||
assign din_imag_array[m] = {{(AXIS_FIR_I_WIDTH-DATA_I_WIDTH){din_imag[(m+1)*DATA_I_WIDTH-1]}},din_imag[m*DATA_I_WIDTH +: DATA_I_WIDTH]};
|
||||
assign dmf_axis_i_real = {{(AXIS_DMF_I_WIDTH-DATA_I_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real};
|
||||
assign dmf_axis_i_imag = {{(AXIS_DMF_I_WIDTH-DATA_I_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign din_real_array[m] = din_real[(m+1)*DATA_I_WIDTH-1 -: AXIS_FIR_I_WIDTH];
|
||||
assign din_imag_array[m] = din_imag[(m+1)*DATA_I_WIDTH-1 -: AXIS_FIR_I_WIDTH];
|
||||
assign dmf_axis_i_real = din_real[DATA_I_WIDTH-1 -: AXIS_DMF_I_WIDTH];
|
||||
assign dmf_axis_i_imag = din_imag[DATA_I_WIDTH-1 -: AXIS_DMF_I_WIDTH];
|
||||
end
|
||||
|
||||
// dmf output data formatting, truncate valid bits
|
||||
assign dmf_o_real = dmf_axis_o_real[DMF_O_WIDTH-1 -: DMF_O_WIDTH];
|
||||
assign dmf_o_imag = dmf_axis_o_imag[DMF_O_WIDTH-1 -: DMF_O_WIDTH];
|
||||
|
||||
// fir port definition
|
||||
wire s_axis_data_tvalid_real;
|
||||
wire s_axis_data_tready_real;
|
||||
wire [AXIS_DMF_I_WIDTH-1 : 0] s_axis_data_ttdata_real;
|
||||
wire m_axis_data_tvalid_real;
|
||||
wire [AXIS_DMF_O_WIDTH-1 : 0] m_axis_data_ttdata_real;
|
||||
|
||||
wire s_axis_data_tvalid_imag;
|
||||
wire s_axis_data_tready_imag;
|
||||
wire [AXIS_DMF_I_WIDTH-1 : 0] s_axis_data_ttdata_imag;
|
||||
wire m_axis_data_tvalid_imag;
|
||||
wire [AXIS_DMF_O_WIDTH-1 : 0] m_axis_data_ttdata_imag;
|
||||
|
||||
// fir port connection
|
||||
assign s_axis_data_tvalid_real = din_deci_valid;
|
||||
assign s_axis_data_ttdata_real = dmf_axis_i_real;
|
||||
assign dmf_axis_o_real = m_axis_data_ttdata_real;
|
||||
|
||||
assign s_axis_data_tvalid_imag = din_deci_valid;
|
||||
assign s_axis_data_ttdata_imag = dmf_axis_i_imag;
|
||||
assign dmf_axis_o_imag = m_axis_data_ttdata_imag;
|
||||
|
||||
assign dmf_o_valid = m_axis_data_tvalid_real;
|
||||
|
||||
// fir ip core instantiation
|
||||
fir_prbs7_invert_rep4 u_dmf_real
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.aresetn (dmf_busy ), // input aresetn
|
||||
.s_axis_data_tvalid (s_axis_data_tvalid_real), // input wire s_axis_data_tvalid
|
||||
.s_axis_data_tready (s_axis_data_tready_real), // output wire s_axis_data_tready
|
||||
.s_axis_data_tdata (s_axis_data_ttdata_real), // input wire [15 : 0] s_axis_data_tdata
|
||||
.m_axis_data_tvalid (m_axis_data_tvalid_real), // output wire m_axis_data_tvalid
|
||||
.m_axis_data_tdata (m_axis_data_ttdata_real) // output wire [23 : 0] m_axis_data_tdata
|
||||
);
|
||||
|
||||
fir_prbs7_invert_rep4 u_dmf_imag
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.aresetn (dmf_busy ), // input aresetn
|
||||
.s_axis_data_tvalid (s_axis_data_tvalid_imag), // input wire s_axis_data_tvalid
|
||||
.s_axis_data_tready (s_axis_data_tready_imag), // output wire s_axis_data_tready
|
||||
.s_axis_data_tdata (s_axis_data_ttdata_imag), // input wire [15 : 0] s_axis_data_tdata
|
||||
.m_axis_data_tvalid (m_axis_data_tvalid_imag), // output wire m_axis_data_tvalid
|
||||
.m_axis_data_tdata (m_axis_data_ttdata_imag) // output wire [23 : 0] m_axis_data_tdata
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// Chip Counter /////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
localparam PEAK_ABS_DELAY = 6; // 5 for multiplier, 1 for adder
|
||||
localparam CHIP_CNT_DELAY = PEAK_ABS_DELAY + 2; // 1 for peak record, 1 for register output
|
||||
|
||||
reg [$clog2(PRBS_POS)-1 : 0] cnt_chip = 'b0;
|
||||
reg [$clog2(PRBS_POS)-1 : 0] cnt_chip_delay [0 : CHIP_CNT_DELAY-1];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cnt_chip <= 'b0;
|
||||
end
|
||||
else if (dmf_busy) begin
|
||||
cnt_chip <= (dmf_o_valid) ? cnt_chip + 1'b1 : cnt_chip;
|
||||
end
|
||||
else begin
|
||||
cnt_chip <= 'b0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
// fir
|
||||
wire [AXIS_FIR_O_WIDTH-1 : 0] dmf_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [AXIS_FIR_O_WIDTH-1 : 0] dmf_imag_array [0 : CHANNEL_NUM-1];
|
||||
|
||||
generate
|
||||
for(m = 0; m < CHANNEL_NUM; m = m + 1) begin: dmf
|
||||
|
||||
// port definition
|
||||
wire s_axis_data_tvalid_i;
|
||||
wire s_axis_data_tready_i;
|
||||
wire [AXIS_FIR_I_WIDTH-1 : 0] s_axis_data_tdata_i ;
|
||||
wire m_axis_data_tvalid_i;
|
||||
wire [AXIS_FIR_O_WIDTH-1 : 0] m_axis_data_tdata_i ;
|
||||
|
||||
wire s_axis_data_tvalid_q;
|
||||
wire s_axis_data_tready_q;
|
||||
wire [AXIS_FIR_I_WIDTH-1 : 0] s_axis_data_tdata_q ;
|
||||
wire m_axis_data_tvalid_q;
|
||||
wire [AXIS_FIR_O_WIDTH-1 : 0] m_axis_data_tdata_q ;
|
||||
|
||||
// port connection
|
||||
assign s_axis_data_tvalid_i = din_valid;
|
||||
assign s_axis_data_tdata_i = din_real_array[m];
|
||||
assign dmf_real_array[m] = m_axis_data_tdata_i;
|
||||
|
||||
assign s_axis_data_tvalid_q = din_valid;
|
||||
assign s_axis_data_tdata_q = din_imag_array[m];
|
||||
assign dmf_imag_array[m] = m_axis_data_tdata_q;
|
||||
|
||||
// ip core instantiation
|
||||
fir_dmf_invert_prbs7_deci8 u_dmf_i
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_data_tvalid (s_axis_data_tvalid_i ), // input wire s_axis_data_tvalid
|
||||
.s_axis_data_tready (s_axis_data_tready_i ), // output wire s_axis_data_tready
|
||||
.s_axis_data_tdata (s_axis_data_tdata_i ), // input wire [15 : 0] s_axis_data_tdata
|
||||
.m_axis_data_tvalid (m_axis_data_tvalid_i ), // output wire m_axis_data_tvalid
|
||||
.m_axis_data_tdata (m_axis_data_tdata_i ) // output wire [23 : 0] m_axis_data_tdata
|
||||
);
|
||||
|
||||
fir_dmf_invert_prbs7_deci8 u_dmf_q
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_data_tvalid (s_axis_data_tvalid_q ), // input wire s_axis_data_tvalid
|
||||
.s_axis_data_tready (s_axis_data_tready_q ), // output wire s_axis_data_tready
|
||||
.s_axis_data_tdata (s_axis_data_tdata_q ), // input wire [15 : 0] s_axis_data_tdata
|
||||
.m_axis_data_tvalid (m_axis_data_tvalid_q ), // output wire m_axis_data_tvalid
|
||||
.m_axis_data_tdata (m_axis_data_tdata_q ) // output wire [23 : 0] m_axis_data_tdata
|
||||
);
|
||||
for (i = 1; i < CHIP_CNT_DELAY; i = i + 1) begin
|
||||
cnt_chip_delay[i] <= cnt_chip_delay[i-1];
|
||||
end
|
||||
|
||||
cnt_chip_delay[0] <= cnt_chip;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// output data
|
||||
wire [DATA_O_WIDTH-1 : 0] dout_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [DATA_O_WIDTH-1 : 0] dout_imag_array [0 : CHANNEL_NUM-1];
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////// Accumulation & Peak Search //////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// moduli
|
||||
wire moduli_valid;
|
||||
reg moduli_valid_delay [0 : PEAK_ABS_DELAY-1];
|
||||
wire [ABS_WIDTH-1 : 0] moduli_real;
|
||||
wire [ABS_WIDTH-1 : 0] moduli_imag;
|
||||
reg [ABS_WIDTH-1 : 0] moduli_real_delay [0 : PEAK_ABS_DELAY-1];
|
||||
reg [ABS_WIDTH-1 : 0] moduli_imag_delay [0 : PEAK_ABS_DELAY-1];
|
||||
|
||||
generate
|
||||
for(m = 0; m < CHANNEL_NUM; m = m + 1) begin: array_convert_out
|
||||
assign moduli_valid = dmf_o_valid;
|
||||
|
||||
if (DATA_O_WIDTH > FIR_O_WIDTH) begin
|
||||
if (ABS_WIDTH > DMF_O_WIDTH) begin
|
||||
// append zeros
|
||||
assign dout_real_array[m] = {dmf_real_array[m],{(FIR_O_WIDTH-DATA_O_WIDTH){1'b0}}};
|
||||
assign dout_imag_array[m] = {dmf_imag_array[m],{(FIR_O_WIDTH-DATA_O_WIDTH){1'b0}}};
|
||||
assign moduli_real = {dmf_o_real,{(ABS_WIDTH-DMF_O_WIDTH){1'b0}}};
|
||||
assign moduli_imag = {dmf_o_imag,{(ABS_WIDTH-DMF_O_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign dout_real_array[m] = dmf_real_array[m][(m+1)*FIR_O_WIDTH-1 -: DATA_O_WIDTH];
|
||||
assign dout_imag_array[m] = dmf_imag_array[m][(m+1)*FIR_O_WIDTH-1 -: DATA_O_WIDTH];
|
||||
assign moduli_real = dmf_o_real[DMF_O_WIDTH-1 -: ABS_WIDTH];
|
||||
assign moduli_imag = dmf_o_imag[DMF_O_WIDTH-1 -: ABS_WIDTH];
|
||||
end
|
||||
|
||||
assign dout_real[m*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_real_array[m];
|
||||
assign dout_imag[m*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_imag_array[m];
|
||||
always @(posedge clk) begin
|
||||
|
||||
for (i = 1; i < PEAK_ABS_DELAY; i = i + 1) begin
|
||||
moduli_valid_delay[i] <= moduli_valid_delay[i-1];
|
||||
moduli_real_delay[i] <= moduli_real_delay[i-1];
|
||||
moduli_imag_delay[i] <= moduli_imag_delay[i-1];
|
||||
end
|
||||
|
||||
moduli_valid_delay[0] <= moduli_valid;
|
||||
moduli_real_delay[0] <= moduli_real;
|
||||
moduli_imag_delay[0] <= moduli_imag;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign dout_valid = dmf[0].m_axis_data_tvalid_i;
|
||||
wire [2*ABS_WIDTH-1 : 0] moduli_real_square;
|
||||
wire [2*ABS_WIDTH-1 : 0] moduli_imag_square;
|
||||
reg [ABS_WIDTH-1 : 0] moduli_abs_square = 'b0;
|
||||
wire [DATA_O_WIDTH-1 : 0] moduli_abs;
|
||||
wire moduli_abs_valid;
|
||||
|
||||
assign moduli_abs_valid = moduli_valid_delay[PEAK_ABS_DELAY-1];
|
||||
|
||||
if (DATA_O_WIDTH > ABS_WIDTH) begin
|
||||
// append zeros
|
||||
assign moduli_abs = {moduli_abs_square,{(DATA_O_WIDTH-ABS_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign moduli_abs = moduli_abs_square[ABS_WIDTH-1 -: DATA_O_WIDTH];
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
moduli_abs_square <= 'b0;
|
||||
end
|
||||
else begin
|
||||
moduli_abs_square <= moduli_real_square[(2*ABS_WIDTH-1) -: (ABS_WIDTH-1)] + moduli_imag_square[(2*ABS_WIDTH-1) -: (ABS_WIDTH-1)];
|
||||
end
|
||||
end
|
||||
|
||||
mult_18x18 u_mult_real
|
||||
(
|
||||
.CLK(clk ), // input wire CLK
|
||||
.A (moduli_real ), // input wire [17 : 0] A
|
||||
.B (moduli_real ), // input wire [17 : 0] B
|
||||
.P (moduli_real_square ) // output wire [17 : 0] P
|
||||
);
|
||||
|
||||
mult_18x18 u_mult_imag
|
||||
(
|
||||
.CLK(clk ), // input wire CLK
|
||||
.A (moduli_imag ), // input wire [17 : 0] A
|
||||
.B (moduli_imag ), // input wire [17 : 0] B
|
||||
.P (moduli_imag_square ) // output wire [17 : 0] P
|
||||
);
|
||||
|
||||
// wire accum_current_valid;
|
||||
|
||||
// assign accum_current_valid = dmf_o_valid;
|
||||
|
||||
// wire [APPROX_ABS_WIDTH-2 : 0] accum_moduli_real;
|
||||
// wire [APPROX_ABS_WIDTH-2 : 0] accum_moduli_imag;
|
||||
// wire [APPROX_ABS_WIDTH-1 : 0] accum_moduli_abs ;
|
||||
// wire accum_current_abs_valid;
|
||||
// wire [DATA_O_WIDTH-1 : 0] accum_current_abs;
|
||||
|
||||
// if (APPROX_ABS_WIDTH-1 > DMF_O_WIDTH) begin
|
||||
// // append zeros
|
||||
// assign accum_moduli_real = {dmf_o_real,{(APPROX_ABS_WIDTH-1-DMF_O_WIDTH){1'b0}}};
|
||||
// assign accum_moduli_imag = {dmf_o_imag,{(APPROX_ABS_WIDTH-1-DMF_O_WIDTH){1'b0}}};
|
||||
// end
|
||||
// else begin
|
||||
// // truncate msb
|
||||
// assign accum_moduli_real = dmf_o_real[DMF_O_WIDTH-1 -: (APPROX_ABS_WIDTH-1)];
|
||||
// assign accum_moduli_imag = dmf_o_imag[DMF_O_WIDTH-1 -: (APPROX_ABS_WIDTH-1)];
|
||||
// end
|
||||
|
||||
// if (DATA_O_WIDTH > APPROX_ABS_WIDTH) begin
|
||||
// // append zeros
|
||||
// assign accum_current_abs = {accum_moduli_abs,{(DATA_O_WIDTH-APPROX_ABS_WIDTH){1'b0}}};
|
||||
// end
|
||||
// else begin
|
||||
// // truncate msb
|
||||
// assign accum_current_abs = accum_moduli_abs[APPROX_ABS_WIDTH-1 -: DATA_O_WIDTH];
|
||||
// end
|
||||
|
||||
// ApproxAbs u_accum_abs
|
||||
// (
|
||||
// .clk (clk ),
|
||||
// .Nd (accum_current_valid ),
|
||||
// .Dini (accum_moduli_real ),
|
||||
// .Dinq (accum_moduli_imag ),
|
||||
// .Abs_Rdy (accum_current_abs_valid),
|
||||
// .Abs_Dout (accum_moduli_abs )
|
||||
// );
|
||||
|
||||
// peak record
|
||||
reg moduli_max_valid = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] moduli_max_abs = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] moduli_max_real = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] moduli_max_imag = 'b0;
|
||||
reg [$clog2(PRBS_POS)-1 : 0] moduli_max_index = 'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
moduli_max_valid <= 'b0;
|
||||
moduli_max_abs <= 'b0;
|
||||
moduli_max_real <= 'b0;
|
||||
moduli_max_imag <= 'b0;
|
||||
moduli_max_index <= 'b0;
|
||||
end
|
||||
else if (dmf_busy) begin
|
||||
if (moduli_abs_valid && (cnt_chip_delay[PEAK_ABS_DELAY-1][$clog2(PRBS_POS)-1] == 1)) begin
|
||||
moduli_max_valid <= 1'b1;
|
||||
moduli_max_abs <= (moduli_abs > moduli_max_abs) ? moduli_abs : moduli_max_abs ;
|
||||
moduli_max_real <= (moduli_abs > moduli_max_abs) ? moduli_real_delay[PEAK_ABS_DELAY-1] : moduli_max_real ;
|
||||
moduli_max_imag <= (moduli_abs > moduli_max_abs) ? moduli_imag_delay[PEAK_ABS_DELAY-1] : moduli_max_imag ;
|
||||
moduli_max_index <= (moduli_abs > moduli_max_abs) ? cnt_chip_delay[CHIP_CNT_DELAY-2] : moduli_max_index;
|
||||
end
|
||||
else begin
|
||||
moduli_max_valid <= 1'b0;
|
||||
moduli_max_abs <= moduli_max_abs;
|
||||
moduli_max_real <= moduli_max_real;
|
||||
moduli_max_imag <= moduli_max_imag;
|
||||
moduli_max_index <= moduli_max_index;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
moduli_max_valid <= 'b0;
|
||||
moduli_max_abs <= 'b0;
|
||||
moduli_max_real <= 'b0;
|
||||
moduli_max_imag <= 'b0;
|
||||
moduli_max_index <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// register output
|
||||
reg peak_valid_buf = 1'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] peak_value_abs_buf = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] peak_value_i_buf = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] peak_value_q_buf = 'b0;
|
||||
reg [$clog2(PRBS_POS)-1 : 0] peak_index_buf = 'b0;
|
||||
|
||||
assign peak_valid = peak_valid_buf ;
|
||||
assign peak_value_abs = peak_value_abs_buf;
|
||||
assign peak_value_i = peak_value_i_buf ;
|
||||
assign peak_value_q = peak_value_q_buf ;
|
||||
assign peak_index = peak_index_buf ;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
peak_valid_buf <= 'b0;
|
||||
peak_value_abs_buf <= 'b0;
|
||||
peak_value_i_buf <= 'b0;
|
||||
peak_value_q_buf <= 'b0;
|
||||
peak_index_buf <= 'b0;
|
||||
end
|
||||
else if (moduli_max_valid && (cnt_chip_delay[CHIP_CNT_DELAY-1] == PRBS_POS-1)) begin
|
||||
peak_valid_buf <= 1'b1;
|
||||
peak_value_abs_buf <= moduli_max_abs ;
|
||||
peak_value_i_buf <= moduli_max_real ;
|
||||
peak_value_q_buf <= moduli_max_imag ;
|
||||
peak_index_buf <= moduli_max_index;
|
||||
end
|
||||
else begin
|
||||
peak_valid_buf <= 1'b0;
|
||||
peak_value_abs_buf <= peak_value_abs_buf;
|
||||
peak_value_i_buf <= peak_value_i_buf ;
|
||||
peak_value_q_buf <= peak_value_q_buf ;
|
||||
peak_index_buf <= peak_index_buf ;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -1,426 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/11/06 15:24:48
|
||||
// Design Name:
|
||||
// Module Name: accor_mat_formatting
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Formmat the input complex matrix to 1-bit stream.
|
||||
// Parameter:
|
||||
// ROW_NUM: Row number of input matrix.
|
||||
// COL_NUM: Column number of input matrix.
|
||||
// DATA_I_WIDTH: Bit width of input matrix element.
|
||||
// FRAME_HEAD: Frame head indicate autocorrelation matrix frame.
|
||||
// Data format:
|
||||
// din_valid: Indicate [din_real/imag] data are valid.
|
||||
// din_real/imag: Suppose the input matrix x = [x11 x12; x21 x22], then
|
||||
// din_real = {Re{x22}, Re{x21}, Re{x12}, Re{x11}}
|
||||
// din_imag = {Im{x22}, Im{x21}, Im{x12}, Im{x11}}
|
||||
// dout_valid: Indicate [dout_data] is valid. The latency is set to 2 clock
|
||||
// cycles by default.
|
||||
// dout_data:
|
||||
// dout_data = {FRAME_HEAD[msb], ..., FRAME_HEAD[lsb], FRAME_LEN[msb],
|
||||
// ..., FRAME_LEN[lsb], Re{x11}[msb], ..., Re{x11}[lsb], Im{x11}[msb], ...,
|
||||
// Im{x11}[lsb], ..., Re{x12}[msb], ......, Im{x22}[lsb]}
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module accor_mat_formatting
|
||||
#(
|
||||
parameter ROW_NUM = 4,
|
||||
parameter COL_NUM = 4,
|
||||
parameter DATA_I_WIDTH = 32,
|
||||
parameter FRAME_HEAD = 32'h7E7E7E7E
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input sys_clk,
|
||||
input sys_rst,
|
||||
input clk_96m,
|
||||
input ant_rst,
|
||||
|
||||
// input data
|
||||
input din_valid,
|
||||
input [ROW_NUM*COL_NUM*DATA_I_WIDTH-1 : 0] din_real,
|
||||
input [ROW_NUM*COL_NUM*DATA_I_WIDTH-1 : 0] din_imag,
|
||||
input fifo_cdc_rst,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output dout_data
|
||||
);
|
||||
|
||||
localparam CMPLX_DIM = 2;
|
||||
localparam FRAME_LEN = ROW_NUM*COL_NUM*CMPLX_DIM; // 32-bit data number per frame
|
||||
localparam BYTE_LEN = 4 * (ROW_NUM*COL_NUM*CMPLX_DIM + 2); // byte number per frame, plus frame head and frame length
|
||||
|
||||
// available state
|
||||
localparam STATE_NUM = 4;
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_HEAD = 1;
|
||||
localparam STATE_LEN = 2;
|
||||
localparam STATE_DATA = 3;
|
||||
|
||||
genvar i;
|
||||
integer m;
|
||||
|
||||
// format input data to array
|
||||
wire [DATA_I_WIDTH-1 : 0] din_array [0 : ROW_NUM*COL_NUM*CMPLX_DIM-1];
|
||||
reg [DATA_I_WIDTH-1 : 0] din_array_cdc [0 : ROW_NUM*COL_NUM*CMPLX_DIM-1];
|
||||
|
||||
generate
|
||||
for (i = 0; i < ROW_NUM*COL_NUM; i = i + 1) begin: input_mat_reshape
|
||||
assign din_array[i*2] = din_real[i*DATA_I_WIDTH +: DATA_I_WIDTH];
|
||||
assign din_array[i*2+1] = din_imag[i*DATA_I_WIDTH +: DATA_I_WIDTH];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// clock domain crossing fifo, write channel
|
||||
reg fifo_wr_start = 'b0;
|
||||
reg fifo_wr_en = 'b0;
|
||||
reg [$clog2(ROW_NUM*COL_NUM*CMPLX_DIM)-1 : 0] fifo_wr_cnt = 'b0;
|
||||
reg [DATA_I_WIDTH-1 : 0] fifo_din = 'b0;
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_wr_start <= 'b0;
|
||||
end
|
||||
else if (din_valid) begin
|
||||
fifo_wr_start <= 1'b1;
|
||||
end
|
||||
else if (fifo_wr_cnt == ROW_NUM*COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_wr_start <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_wr_start <= fifo_wr_start;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_wr_en <= 'b0;
|
||||
fifo_wr_cnt <= 'b0;
|
||||
fifo_din <= 'b0;
|
||||
end
|
||||
else if (fifo_wr_start) begin
|
||||
fifo_wr_en <= 1'b1;
|
||||
fifo_wr_cnt <= fifo_wr_cnt + 1'b1;
|
||||
fifo_din <= din_array[fifo_wr_cnt];
|
||||
end
|
||||
else begin
|
||||
fifo_wr_en <= 'b0;
|
||||
fifo_wr_cnt <= 'b0;
|
||||
fifo_din <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// clock domain crossing fifo, read channel
|
||||
reg fifo_rd_en = 'b0;
|
||||
reg fifo_rd_en_d1 = 'b0;
|
||||
reg [$clog2(ROW_NUM*COL_NUM*CMPLX_DIM)-1 : 0] fifo_rd_cnt = 'b0;
|
||||
reg [$clog2(ROW_NUM*COL_NUM*CMPLX_DIM)-1 : 0] fifo_rd_cnt_d1 = 'b0; // read data latency
|
||||
reg fifo_rd_valid = 'b0;
|
||||
wire [DATA_I_WIDTH-1 : 0] fifo_dout;
|
||||
wire [$clog2(ROW_NUM*COL_NUM*CMPLX_DIM*2)-1 : 0] fifo_rd_num;
|
||||
wire fifo_full;
|
||||
wire fifo_empty;
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_rd_en <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_num == ROW_NUM*COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_rd_en <= 1'b1;
|
||||
end
|
||||
else if (fifo_rd_cnt == ROW_NUM*COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_rd_en <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_en <= fifo_rd_en;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_rd_en_d1 <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_en_d1 <= fifo_rd_en;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_rd_cnt <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_en) begin
|
||||
fifo_rd_cnt <= fifo_rd_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_cnt <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_rd_cnt_d1 <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_cnt_d1 <= fifo_rd_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_rd_valid <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_cnt_d1 == ROW_NUM*COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_rd_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_valid <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
for (m = 0; m < ROW_NUM*COL_NUM*CMPLX_DIM; m = m + 1) begin
|
||||
din_array_cdc[m] <= 'b0;
|
||||
end
|
||||
end
|
||||
else if (fifo_rd_en_d1) begin
|
||||
din_array_cdc[fifo_rd_cnt_d1] <= fifo_dout;
|
||||
end
|
||||
else begin
|
||||
for (m = 0; m < ROW_NUM*COL_NUM*CMPLX_DIM; m = m + 1) begin
|
||||
din_array_cdc[m] <= din_array_cdc[m];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// clock domain crossing fifo, interface
|
||||
fifo_accor_cdc u_fifo_accor_cdc
|
||||
(
|
||||
.rst (fifo_cdc_rst ), // input wire wr_rst
|
||||
.wr_clk (sys_clk ), // input wire wr_clk
|
||||
.rd_clk (clk_96m ), // input wire rd_clk
|
||||
.din (fifo_din ), // input wire [31 : 0] din
|
||||
.wr_en (fifo_wr_en ), // input wire wr_en
|
||||
.rd_en (fifo_rd_en ), // input wire rd_en
|
||||
.dout (fifo_dout ), // output wire [31 : 0] dout
|
||||
.full (fifo_full ), // output wire full
|
||||
.empty (fifo_empty ), // output wire empty
|
||||
.rd_data_count (fifo_rd_num ) // output wire [5 : 0] rd_data_count
|
||||
);
|
||||
|
||||
// center state machine & counter
|
||||
reg [$clog2(STATE_NUM)-1 : 0] state = STATE_IDLE;
|
||||
reg [$clog2(DATA_I_WIDTH)-1 : 0] bit_cnt = 'b0; // bit counter within one frame
|
||||
reg [$clog2(FRAME_LEN)-1 : 0] frame_cnt = 'b0; // frame counter
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
STATE_IDLE: state <= fifo_rd_valid ? STATE_HEAD : STATE_IDLE;
|
||||
STATE_HEAD: state <= (bit_cnt == DATA_I_WIDTH-1) ? STATE_LEN : STATE_HEAD;
|
||||
STATE_LEN : state <= (bit_cnt == DATA_I_WIDTH-1) ? STATE_DATA : STATE_LEN;
|
||||
STATE_DATA: state <= (frame_cnt == FRAME_LEN-1 && bit_cnt == DATA_I_WIDTH-1) ? STATE_IDLE : STATE_DATA;
|
||||
default: state <= STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
bit_cnt <= 'b0;
|
||||
end
|
||||
else if (state == STATE_IDLE) begin
|
||||
bit_cnt <= 'b0;
|
||||
end
|
||||
else begin
|
||||
bit_cnt <= (bit_cnt == DATA_I_WIDTH-1) ? 'b0 : bit_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
frame_cnt <= 'b0;
|
||||
end
|
||||
else if (state == STATE_IDLE) begin
|
||||
frame_cnt <= 'b0;
|
||||
end
|
||||
else if (state == STATE_DATA && bit_cnt == DATA_I_WIDTH-1) begin
|
||||
frame_cnt <= frame_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
frame_cnt <= frame_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// output data
|
||||
reg dout_valid_buf = 'b0;
|
||||
reg dout_data_buf = 'b0;
|
||||
|
||||
assign dout_valid = dout_valid_buf;
|
||||
assign dout_data = dout_data_buf;
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
dout_valid_buf <= 'b0;
|
||||
dout_data_buf <= 'b0;
|
||||
end
|
||||
else case (state)
|
||||
STATE_IDLE: begin dout_valid_buf <= 'b0 ; dout_data_buf <= 'b0; end
|
||||
STATE_HEAD: begin dout_valid_buf <= 1'b1; dout_data_buf <= FRAME_HEAD[DATA_I_WIDTH-1 - bit_cnt]; end
|
||||
STATE_LEN : begin dout_valid_buf <= 1'b1; dout_data_buf <= BYTE_LEN[DATA_I_WIDTH-1 - bit_cnt]; end
|
||||
STATE_DATA: begin dout_valid_buf <= 1'b1; dout_data_buf <= din_array_cdc[frame_cnt][DATA_I_WIDTH-1 - bit_cnt]; end
|
||||
default: begin dout_valid_buf <= 'b0 ; dout_data_buf <= 'b0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 20:46:26
|
||||
// Design Name:
|
||||
// Module Name: tb_accum
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Testbench for [accor_mat_formatting]
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// MATLAB Code for data generation
|
||||
// -------------------------------
|
||||
// COLUMN_NUM = 4;
|
||||
// DATA_I_WIDTH = 12;
|
||||
// ACC_NUM = 10;
|
||||
|
||||
// rng(0);
|
||||
// data = rand(4,2)*2-1;
|
||||
// d_12b = round(data.*(2^(DATA_I_WIDTH-1)-1));
|
||||
// d_12b_cmplx = d_12b(:,1) + 1i*d_12b(:,2);
|
||||
// d_12b_cmplx = d_12b_cmplx(end:-1:1,:);
|
||||
// d_12b_acorr = d_12b_cmplx*d_12b_cmplx';
|
||||
// d_12b_acorr_real_sim = reshape(flip(reshape(real(d_12b_acorr)',1,16)),4,4);
|
||||
// d_12b_acorr_imag_sim = reshape(flip(reshape(imag(d_12b_acorr)',1,16)),4,4);
|
||||
// d_12b_acorr_real_sim_sum = ACC_NUM*d_12b_acorr_real_sim;
|
||||
// d_12b_acorr_imag_sim_sum = ACC_NUM*d_12b_acorr_imag_sim;
|
||||
|
||||
|
||||
// module tb_accor_format;
|
||||
|
||||
// localparam DATA_I_WIDTH = 32;
|
||||
// localparam ROW_NUM = 4;
|
||||
// localparam COL_NUM = 4;
|
||||
|
||||
// reg sys_clk = 1'b1;
|
||||
// reg sys_rst = 1'b1;
|
||||
// reg clk_96m = 1'b1;
|
||||
// reg ant_rst = 1'b1;
|
||||
// reg din_valid = 'b0;
|
||||
// reg [ROW_NUM*COL_NUM*DATA_I_WIDTH-1:0] din_real = 'b0, din_imag = 'b0;
|
||||
|
||||
// wire dout_valid;
|
||||
// wire dout_data;
|
||||
|
||||
// accor_mat_formatting #(
|
||||
// .ROW_NUM (ROW_NUM),
|
||||
// .COL_NUM (COL_NUM),
|
||||
// .DATA_I_WIDTH (DATA_I_WIDTH)
|
||||
// ) u_accor_mat_formatting
|
||||
// (
|
||||
// // clock & reset
|
||||
// .sys_clk (sys_clk ), // input sys_clk
|
||||
// .sys_rst (sys_rst ), // input sys_rst
|
||||
// .clk_96m (clk_96m ), // input clk_96m
|
||||
// .ant_rst (ant_rst ), // input ant_rst
|
||||
|
||||
// // input data
|
||||
// .din_valid (din_valid ),
|
||||
// .din_real (din_real ),
|
||||
// .din_imag (din_imag ),
|
||||
|
||||
// // output data
|
||||
// .dout_valid (dout_valid ),
|
||||
// .dout_data (dout_data )
|
||||
// );
|
||||
|
||||
|
||||
// initial begin
|
||||
// #102
|
||||
// sys_rst = 1'b0;
|
||||
// ant_rst = 1'b0;
|
||||
|
||||
// #222;
|
||||
// @(posedge sys_clk)
|
||||
// din_valid = 1'b1;
|
||||
// din_real = {
|
||||
// 32'd1952708, 32'd1246152, -32'd2458370, 32'd2283360,
|
||||
// 32'd1246152, 32'd5474825, -32'd1041611, 32'd2493996,
|
||||
// -32'd2458370, -32'd1041611, 32'd3154378, -32'd2757828,
|
||||
// 32'd2283360, 32'd2493996, -32'd2757828, 32'd2899728
|
||||
// };
|
||||
|
||||
// din_imag = {
|
||||
// 32'd1, -32'd3022886, -32'd340582, -32'd669768,
|
||||
// 32'd3022886, 32'd2, -32'd4023023, 32'd3107328,
|
||||
// 32'd340582, 32'd4023023, 32'd3, 32'd1241460,
|
||||
// 32'd669768, -32'd3107328, -32'd1241460, 32'd4
|
||||
// };
|
||||
|
||||
// @(posedge sys_clk)
|
||||
// din_valid = 1'b0;
|
||||
|
||||
// end
|
||||
|
||||
// always begin
|
||||
// #20 sys_clk = ~sys_clk;
|
||||
// end
|
||||
|
||||
// always begin
|
||||
// #7;
|
||||
// clk_96m = ~clk_96m;
|
||||
// #3;
|
||||
// end
|
||||
|
||||
|
||||
// endmodule
|
||||
@@ -1,332 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/11/02 11:06:43
|
||||
// Design Name:
|
||||
// Module Name: accum_cmplx_mat
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions: 2019.1.3
|
||||
// Description: Compute the accumulation of complex matrices. The row number
|
||||
// [ROW_NUM] and column number [ROW_NUM] are flexible parameters. The
|
||||
// accumulation number [ACC_NUM], input data width [DATA_I_WIDTH] and output
|
||||
// data width [DATA_ACC_WIDTH] are related to each other and should match the
|
||||
// Adder/Subtracter LogiCORE IP configuration.
|
||||
// Parameter:
|
||||
// ROW_NUM: Row number of input matrix.
|
||||
// COL_NUM: Column number of input matrix.
|
||||
// ACC_NUM: Accumulation number of input matrix.
|
||||
// DATA_I_WIDTH: Bit width of input matrix element.
|
||||
// DATA_ACC_WIDTH: !!!Caution!!! Accumulation adder output data width. It is
|
||||
// determined by [DATA_I_WIDTH] and [ACC_NUM], and is calculated as
|
||||
// log2(ACC_NUM*(2^DATA_I_WIDTH-1)), and should match the Adder/Subtracter
|
||||
// LogiCORE IP configuration.
|
||||
// DATA_O_WIDTH: Bit width of output matrix element. If [DATA_O_WIDTH] <
|
||||
// [DATA_ACC_WIDTH], MSB of accumulation result will be truncated. If
|
||||
// [DATA_O_WIDTH] > [DATA_ACC_WIDTH], the sign bit of accumulation result
|
||||
// will be extended.
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module accum_cmplx_mat
|
||||
#(
|
||||
parameter ROW_NUM = 4,
|
||||
parameter COL_NUM = 4,
|
||||
parameter ACC_NUM = 256,
|
||||
parameter DATA_I_WIDTH = 24,
|
||||
parameter DATA_ACC_WIDTH = $clog2(ACC_NUM*(2^DATA_I_WIDTH-1)),
|
||||
parameter DATA_O_WIDTH = 32
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input clk,
|
||||
input rst,
|
||||
input acc_rst, // [acc_rst] should assert before accumulation starts
|
||||
|
||||
// input data
|
||||
input din_valid,
|
||||
input [ROW_NUM*COL_NUM*DATA_I_WIDTH-1:0] din_real,
|
||||
input [ROW_NUM*COL_NUM*DATA_I_WIDTH-1:0] din_imag,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output [ROW_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_real,
|
||||
output [ROW_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_imag
|
||||
);
|
||||
|
||||
genvar i;
|
||||
|
||||
// prepare adder input & output data
|
||||
wire [DATA_I_WIDTH-1:0] add_real_a_array [0:ROW_NUM*COL_NUM-1];
|
||||
wire [DATA_I_WIDTH-1:0] add_imag_a_array [0:ROW_NUM*COL_NUM-1];
|
||||
wire [DATA_ACC_WIDTH-1:0] add_real_b_array [0:ROW_NUM*COL_NUM-1];
|
||||
wire [DATA_ACC_WIDTH-1:0] add_imag_b_array [0:ROW_NUM*COL_NUM-1];
|
||||
wire [DATA_ACC_WIDTH-1:0] add_real_s_array [0:ROW_NUM*COL_NUM-1];
|
||||
wire [DATA_ACC_WIDTH-1:0] add_imag_s_array [0:ROW_NUM*COL_NUM-1];
|
||||
|
||||
generate
|
||||
for (i = 0; i < ROW_NUM*COL_NUM; i = i + 1) begin: cmplx_mat_accum
|
||||
assign add_real_a_array[i] = din_real[i*DATA_I_WIDTH +: DATA_I_WIDTH];
|
||||
assign add_imag_a_array[i] = din_imag[i*DATA_I_WIDTH +: DATA_I_WIDTH];
|
||||
|
||||
assign add_real_b_array[i] = add_real_s_array[i];
|
||||
assign add_imag_b_array[i] = add_imag_s_array[i];
|
||||
|
||||
if (ACC_NUM > 1) begin
|
||||
add_s24_s32_s32 u_accum_real
|
||||
(
|
||||
.A (add_real_a_array[i]), // input wire [23 : 0] A
|
||||
.B (add_real_b_array[i]), // input wire [31 : 0] B
|
||||
.CLK (clk ), // input wire CLK
|
||||
.CE (din_valid ), // input wire CE
|
||||
.SCLR (rst || acc_rst ), // input wire SCLR
|
||||
.S (add_real_s_array[i]) // output wire [31 : 0] S
|
||||
);
|
||||
|
||||
add_s24_s32_s32 u_accum_imag
|
||||
(
|
||||
.A (add_imag_a_array[i]), // input wire [23 : 0] A
|
||||
.B (add_imag_b_array[i]), // input wire [31 : 0] B
|
||||
.CLK (clk ), // input wire CLK
|
||||
.CE (din_valid ), // input wire CE
|
||||
.SCLR (rst || acc_rst ), // input wire SCLR
|
||||
.S (add_imag_s_array[i]) // output wire [31 : 0] S
|
||||
);
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// input data counter & full flag
|
||||
reg [$clog2(ACC_NUM)-1:0] accum_cnt = 'b0;
|
||||
reg accum_full_flag = 'b0;
|
||||
reg accum_full_flag_d = 'b0; // delay of [accum_full_flag]
|
||||
|
||||
if (ACC_NUM > 1) begin
|
||||
always @(posedge clk) begin
|
||||
if (rst || acc_rst) begin
|
||||
accum_cnt <= 'b0;
|
||||
end
|
||||
else if (din_valid) begin
|
||||
accum_cnt <= accum_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
accum_cnt <= accum_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst || acc_rst) begin
|
||||
accum_full_flag <= 'b0;
|
||||
end
|
||||
else begin
|
||||
accum_full_flag <= (accum_cnt == ACC_NUM - 1) ? 1'b1 : accum_full_flag;
|
||||
end
|
||||
|
||||
accum_full_flag_d <= accum_full_flag;
|
||||
end
|
||||
end
|
||||
|
||||
// output control
|
||||
reg dout_valid_buf;
|
||||
reg [DATA_O_WIDTH-1:0] dout_real_array [0:ROW_NUM*COL_NUM-1];
|
||||
reg [DATA_O_WIDTH-1:0] dout_imag_array [0:ROW_NUM*COL_NUM-1];
|
||||
|
||||
assign dout_valid = dout_valid_buf;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst || acc_rst) begin
|
||||
dout_valid_buf <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if (ACC_NUM > 1) begin
|
||||
dout_valid_buf <= ~accum_full_flag_d & accum_full_flag;
|
||||
end
|
||||
else begin
|
||||
dout_valid_buf <= din_valid;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
generate
|
||||
for (i = 0; i < ROW_NUM*COL_NUM; i = i + 1) begin: output_buf
|
||||
assign dout_real[i*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_real_array[i];
|
||||
assign dout_imag[i*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_imag_array[i];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst || acc_rst) begin
|
||||
dout_real_array[i] <= 'b0;
|
||||
dout_imag_array[i] <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if (ACC_NUM > 1) begin
|
||||
if (~accum_full_flag_d & accum_full_flag) begin
|
||||
if (DATA_O_WIDTH <= DATA_ACC_WIDTH) begin
|
||||
// truncate msb
|
||||
dout_real_array[i] <= add_real_s_array[i][DATA_ACC_WIDTH-1 -: DATA_O_WIDTH];
|
||||
dout_imag_array[i] <= add_imag_s_array[i][DATA_ACC_WIDTH-1 -: DATA_O_WIDTH];
|
||||
end
|
||||
else begin // if (ACC_NUM <= 1)
|
||||
// Sign extension to fit output data width
|
||||
dout_real_array[i] <= {{(DATA_O_WIDTH-DATA_ACC_WIDTH){add_real_s_array[i][DATA_ACC_WIDTH-1]}},add_real_s_array[i]};
|
||||
dout_imag_array[i] <= {{(DATA_O_WIDTH-DATA_ACC_WIDTH){add_imag_s_array[i][DATA_ACC_WIDTH-1]}},add_real_s_array[i]};
|
||||
end
|
||||
end
|
||||
else begin
|
||||
dout_real_array[i] <= dout_real_array[i];
|
||||
dout_imag_array[i] <= dout_imag_array[i];
|
||||
end
|
||||
end // if (ACC_NUM > 1)
|
||||
else begin // if (ACC_NUM <= 1)
|
||||
if (DATA_O_WIDTH <= DATA_I_WIDTH) begin
|
||||
// truncate msb
|
||||
dout_real_array[i] <= add_real_a_array[i][DATA_I_WIDTH-1 -: DATA_O_WIDTH];
|
||||
dout_imag_array[i] <= add_imag_a_array[i][DATA_I_WIDTH-1 -: DATA_O_WIDTH];
|
||||
end
|
||||
else begin // if (DATA_O_WIDTH > DATA_I_WIDTH)
|
||||
// Sign extension to fit output data width
|
||||
dout_real_array[i] <= {{(DATA_O_WIDTH-DATA_I_WIDTH){add_real_a_array[i][DATA_I_WIDTH-1]}},add_real_a_array[i]};
|
||||
dout_imag_array[i] <= {{(DATA_O_WIDTH-DATA_I_WIDTH){add_imag_a_array[i][DATA_I_WIDTH-1]}},add_imag_a_array[i]};
|
||||
end
|
||||
end // if (ACC_NUM <= 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 20:46:26
|
||||
// Design Name:
|
||||
// Module Name: tb_accum
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Testbench for [accum_cmplx_mat]
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// MATLAB Code for data generation
|
||||
// -------------------------------
|
||||
// COLUMN_NUM = 4;
|
||||
// DATA_I_WIDTH = 12;
|
||||
// ACC_NUM = 10;
|
||||
|
||||
// rng(0);
|
||||
// data = rand(4,2)*2-1;
|
||||
// d_12b = round(data.*(2^(DATA_I_WIDTH-1)-1));
|
||||
// d_12b_cmplx = d_12b(:,1) + 1i*d_12b(:,2);
|
||||
// d_12b_cmplx = d_12b_cmplx(end:-1:1,:);
|
||||
// d_12b_acorr = d_12b_cmplx*d_12b_cmplx';
|
||||
// d_12b_acorr_real_sim = reshape(flip(reshape(real(d_12b_acorr)',1,16)),4,4);
|
||||
// d_12b_acorr_imag_sim = reshape(flip(reshape(imag(d_12b_acorr)',1,16)),4,4);
|
||||
// d_12b_acorr_real_sim_sum = ACC_NUM*d_12b_acorr_real_sim;
|
||||
// d_12b_acorr_imag_sim_sum = ACC_NUM*d_12b_acorr_imag_sim;
|
||||
|
||||
|
||||
// module tb_accum;
|
||||
|
||||
// localparam DATA_I_WIDTH = 24;
|
||||
// localparam DATA_ACC_WIDTH = 32;
|
||||
// localparam DATA_O_WIDTH = 35;
|
||||
// localparam ROW_NUM = 4;
|
||||
// localparam COL_NUM = 4;
|
||||
|
||||
// reg acc_rst = 1'b0;
|
||||
|
||||
// reg clk = 1'b1;
|
||||
// reg rst = 1'b1;
|
||||
// reg din_valid = 'b0;
|
||||
// reg [ROW_NUM*COL_NUM*DATA_I_WIDTH-1:0] din_real = 'b0, din_imag = 'b0;
|
||||
|
||||
// wire dout_valid;
|
||||
// wire [ROW_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_real, dout_imag;
|
||||
|
||||
// accum_cmplx_mat #(
|
||||
// .ROW_NUM (ROW_NUM),
|
||||
// .COL_NUM (COL_NUM),
|
||||
// .DATA_I_WIDTH (DATA_I_WIDTH),
|
||||
// .DATA_ACC_WIDTH (DATA_ACC_WIDTH),
|
||||
// .DATA_O_WIDTH (DATA_O_WIDTH),
|
||||
// .ACC_NUM (1)
|
||||
// ) u_accum_cmplx_mat
|
||||
// (
|
||||
// // clock & reset
|
||||
// .clk (clk ),
|
||||
// .rst (rst ),
|
||||
// .acc_rst (acc_rst ), // [acc_rst] should assert before accumulation starts
|
||||
|
||||
// // input data
|
||||
// .din_valid (din_valid ),
|
||||
// .din_real (din_real ),
|
||||
// .din_imag (din_imag ),
|
||||
|
||||
// // output data
|
||||
// .dout_valid (dout_valid ),
|
||||
// .dout_real (dout_real ),
|
||||
// .dout_imag (dout_imag )
|
||||
// );
|
||||
|
||||
|
||||
// initial begin
|
||||
// #102 rst = 1'b0;
|
||||
// #222;
|
||||
// @(posedge clk)
|
||||
// din_valid = 1'b1;
|
||||
// din_real = {
|
||||
// 24'd1952708, 24'd1246152, -24'd2458370, 24'd2283360,
|
||||
// 24'd1246152, 24'd5474825, -24'd1041611, 24'd2493996,
|
||||
// -24'd2458370, -24'd1041611, 24'd3154378, -24'd2757828,
|
||||
// 24'd2283360, 24'd2493996, -24'd2757828, 24'd2899728
|
||||
// };
|
||||
|
||||
// din_imag = {
|
||||
// 24'd0, -24'd3022886, -24'd340582, -24'd669768,
|
||||
// 24'd3022886, 24'd0, -24'd4023023, 24'd3107328,
|
||||
// 24'd340582, 24'd4023023, 24'd0, 24'd1241460,
|
||||
// 24'd669768, -24'd3107328, -24'd1241460, 24'd0
|
||||
// };
|
||||
|
||||
// #1002
|
||||
// acc_rst = 1'b1;
|
||||
// #20
|
||||
// acc_rst = 1'b0;
|
||||
|
||||
// end
|
||||
|
||||
// always #10 clk = ~clk;
|
||||
|
||||
|
||||
// endmodule
|
||||
@@ -1,266 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 19:27:01
|
||||
// Design Name:
|
||||
// Module Name: acorr_cmplx_col_vec
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Compute the autocorrelation of a complex column vector. The
|
||||
// computation is conducted in fully parallel style.
|
||||
// Parameter:
|
||||
// DATA_I_WIDTH: Bit width of input vector element, the same as of complex
|
||||
// multiplication input data.
|
||||
// DATA_MULT_FULL_WIDTH (local): Bit width of unsigned complex multiplication
|
||||
// output data (The cmpy LogiCore IP does not care whether the input data
|
||||
// are signed or unsigned). It equals to (2*[DATA_MULT_WIDTH]+1).
|
||||
// DATA_MULT_VALID_WIDTH (local): Bit width of signed complex multiplication.acc_rst
|
||||
// It equals to 2*[DATA_MULT_WIDTH].
|
||||
// DATA_O_WIDTH: Bit width of output matrix element. If [DATA_O_WIDTH] <
|
||||
// [DATA_MULT_WIDTH], MSB of valid complex mutiplication output will be
|
||||
// truncated. If [DATA_O_WIDTH] > [DATA_MULT_WIDTH], the sign bit of valid
|
||||
// complex mutiplication output will be extended.
|
||||
// Data format:
|
||||
// din_valid: Indicate [din_real/imag] data are valid.
|
||||
// din_real/imag: Suppose the input column vector x = [x1 x2 x3 x4]^T, then
|
||||
// din_real = {Re{x4}, Re{x3}, Re{x2}, Re{x1}}
|
||||
// din_imag = {Im{x4}, Im{x3}, Im{x2}, Im{x1}}
|
||||
// dout_valid: Indicate [dout_real/imag] data are valid. The latency is
|
||||
// determined by the configuration of the cmpy ip core, which is set to 6
|
||||
// clock cycles by default.
|
||||
// dout_real/imag:
|
||||
// dout_real = {Re{x4*x4^H}, Re{x4*x3^H}, ..., Re{x1*x2^H}, Re{x1*x1^H}}
|
||||
// dout_imag = {Im{x4*x4^H}, Im{x4*x3^H}, ..., Im{x1*x2^H}, Im{x1*x1^H}}
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module acorr_cmplx_col_vec
|
||||
#(
|
||||
parameter DATA_I_WIDTH = 12,
|
||||
parameter DATA_O_WIDTH = 24,
|
||||
parameter COL_NUM = 4
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
// input data
|
||||
input din_valid,
|
||||
input [COL_NUM*DATA_I_WIDTH-1:0] din_real,
|
||||
input [COL_NUM*DATA_I_WIDTH-1:0] din_imag,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output [COL_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_real,
|
||||
output [COL_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_imag
|
||||
);
|
||||
|
||||
localparam DATA_MULT_FULL_WIDTH = 2*DATA_I_WIDTH+1;
|
||||
localparam DATA_MULT_VALID_WIDTH = 2*DATA_I_WIDTH;
|
||||
localparam AXIS_DATA_I_WIDTH = 8*((DATA_I_WIDTH-1)/8+1) ; // axis data width of input real/image data
|
||||
localparam AXIS_DATA_P_WIDTH = 8*((DATA_MULT_FULL_WIDTH-1)/8+1) ; // axis data width of cmpy output real/image data
|
||||
|
||||
genvar i,j;
|
||||
|
||||
|
||||
// prepare cmpy input data
|
||||
wire [AXIS_DATA_I_WIDTH-1:0] din_real_array [0:COL_NUM-1];
|
||||
wire [AXIS_DATA_I_WIDTH-1:0] din_imag_array [0:COL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < COL_NUM; i = i + 1) begin: array_convert
|
||||
// Sign extension to fit 8-bit axis data format
|
||||
assign din_real_array[i] = {{(AXIS_DATA_I_WIDTH-DATA_I_WIDTH){din_real[(i+1)*DATA_I_WIDTH-1]}},din_real[i*DATA_I_WIDTH +: DATA_I_WIDTH]};
|
||||
assign din_imag_array[i] = {{(AXIS_DATA_I_WIDTH-DATA_I_WIDTH){din_imag[(i+1)*DATA_I_WIDTH-1]}},din_imag[i*DATA_I_WIDTH +: DATA_I_WIDTH]};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// complex multiplication
|
||||
wire [AXIS_DATA_P_WIDTH-1:0] cmpy_real_array [0:COL_NUM*COL_NUM-1];
|
||||
wire [AXIS_DATA_P_WIDTH-1:0] cmpy_imag_array [0:COL_NUM*COL_NUM-1];
|
||||
|
||||
wire [DATA_O_WIDTH-1:0] dout_real_array [0:COL_NUM*COL_NUM-1];
|
||||
wire [DATA_O_WIDTH-1:0] dout_imag_array [0:COL_NUM*COL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < COL_NUM; i = i + 1) begin: acorr_cmpy_col
|
||||
for(j = 0; j < COL_NUM; j = j + 1) begin: acorr_cmpy_row
|
||||
wire [2*AXIS_DATA_I_WIDTH-1:0] cmpy_a;
|
||||
wire [2*AXIS_DATA_I_WIDTH-1:0] cmpy_b;
|
||||
wire [2*AXIS_DATA_P_WIDTH-1:0] cmpy_p;
|
||||
wire cmpy_p_vld;
|
||||
|
||||
assign cmpy_a = {din_imag_array[i],din_real_array[i]};
|
||||
assign cmpy_b = {-din_imag_array[j],din_real_array[j]};
|
||||
assign {cmpy_imag_array[i*COL_NUM+j],cmpy_real_array[i*COL_NUM+j]} = cmpy_p;
|
||||
|
||||
if (DATA_O_WIDTH <= DATA_MULT_VALID_WIDTH) begin
|
||||
// truncate msb of the valid part
|
||||
assign dout_real_array[i*COL_NUM+j] = cmpy_real_array[i*COL_NUM+j][DATA_MULT_VALID_WIDTH-1 -: DATA_O_WIDTH];
|
||||
assign dout_imag_array[i*COL_NUM+j] = cmpy_imag_array[i*COL_NUM+j][DATA_MULT_VALID_WIDTH-1 -: DATA_O_WIDTH];
|
||||
end
|
||||
else begin
|
||||
// sign extension to fit output data width
|
||||
assign dout_real_array[i*COL_NUM+j] = {{(DATA_O_WIDTH-DATA_MULT_VALID_WIDTH){cmpy_real_array[i*COL_NUM+j][DATA_MULT_VALID_WIDTH-1]}},cmpy_real_array[i*COL_NUM+j][0 +: DATA_MULT_VALID_WIDTH]};
|
||||
assign dout_imag_array[i*COL_NUM+j] = {{(DATA_O_WIDTH-DATA_MULT_VALID_WIDTH){cmpy_imag_array[i*COL_NUM+j][DATA_MULT_VALID_WIDTH-1]}},cmpy_imag_array[i*COL_NUM+j][0 +: DATA_MULT_VALID_WIDTH]};
|
||||
end
|
||||
|
||||
assign dout_real[(i*COL_NUM+j)*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_real_array[i*COL_NUM+j];
|
||||
assign dout_imag[(i*COL_NUM+j)*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_imag_array[i*COL_NUM+j];
|
||||
|
||||
cmpy_12x12 u_cmpy_12x12
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_a_tvalid (din_valid ), // input wire s_axis_a_tvalid
|
||||
.s_axis_a_tdata (cmpy_a ), // input wire [31 : 0] s_axis_a_tdata
|
||||
.s_axis_b_tvalid (din_valid ), // input wire s_axis_b_tvalid
|
||||
.s_axis_b_tdata (cmpy_b ), // input wire [31 : 0] s_axis_b_tdata
|
||||
.m_axis_dout_tvalid (cmpy_p_vld ), // output wire m_axis_dout_tvalid
|
||||
.m_axis_dout_tdata (cmpy_p ) // output wire [63 : 0] m_axis_dout_tdata
|
||||
);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// output mapping
|
||||
assign dout_valid = acorr_cmpy_col[0].acorr_cmpy_row[0].cmpy_p_vld;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 20:46:26
|
||||
// Design Name:
|
||||
// Module Name: acorr_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Testbench for [acorr_cmplx_col_vec]
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// MATLAB Code for data generation
|
||||
// -------------------------------
|
||||
// COLUMN_NUM = 4;
|
||||
// DATA_I_WIDTH = 12;
|
||||
|
||||
// rng(0);
|
||||
// data = (rand(4,2)*2-1) + 1i*(rand(4,2)*2-1);
|
||||
// d_12b = round(data/max(max(abs(data)))*(2^11-1));
|
||||
// d_12b_real = real(d_12b(end:-1:1,:));
|
||||
// d_12b_imag = imag(d_12b(end:-1:1,:));
|
||||
// d_12b_acorr(:,:,1) = d_12b(:,1)*d_12b(:,1)';
|
||||
// d_12b_acorr(:,:,2) = d_12b(:,2)*d_12b(:,2)';
|
||||
|
||||
|
||||
// module tb_acorr;
|
||||
|
||||
// localparam ROW_NUM = 1;
|
||||
// localparam COL_NUM = 4;
|
||||
// localparam DATA_I_WIDTH = 12;
|
||||
// localparam DATA_O_WIDTH = 23;
|
||||
|
||||
// reg acc_rst = 1'b0;
|
||||
|
||||
// reg clk = 1'b1;
|
||||
// reg rst = 1'b1;
|
||||
// reg din_valid = 'b0;
|
||||
// reg [COL_NUM*DATA_I_WIDTH-1:0] din_real = 'b0, din_imag = 'b0;
|
||||
|
||||
// wire dout_valid;
|
||||
// wire [COL_NUM*COL_NUM*DATA_O_WIDTH-1:0] dout_real, dout_imag;
|
||||
|
||||
// acorr_cmplx_col_vec #(
|
||||
// .COL_NUM (COL_NUM),
|
||||
// .DATA_I_WIDTH (DATA_I_WIDTH),
|
||||
// .DATA_O_WIDTH (DATA_O_WIDTH)
|
||||
// ) u_acorr_cmplx_col_vec
|
||||
// (
|
||||
// // clock & reset
|
||||
// .clk (clk ),
|
||||
// .rst (rst ),
|
||||
|
||||
// // input data
|
||||
// .din_valid (din_valid ),
|
||||
// .din_real (din_real ),
|
||||
// .din_imag (din_imag ),
|
||||
|
||||
// // output data
|
||||
// .dout_valid (dout_valid ),
|
||||
// .dout_real (dout_real ),
|
||||
// .dout_imag (dout_imag )
|
||||
// );
|
||||
|
||||
|
||||
// initial begin
|
||||
// #102 rst = 1'b0;
|
||||
// #222;
|
||||
// @(posedge clk)
|
||||
// din_valid = 1'b1;
|
||||
// din_real = {
|
||||
// 12'd1351,
|
||||
// -12'd1219,
|
||||
// 12'd1326,
|
||||
// 12'd1029};
|
||||
|
||||
// din_imag = {
|
||||
// 12'd1538,
|
||||
// -12'd1119,
|
||||
// 12'd1519,
|
||||
// 12'd1495};
|
||||
|
||||
// @(posedge clk)
|
||||
// din_valid = 1'b0;
|
||||
|
||||
// @(posedge clk)
|
||||
// din_valid = 1'b1;
|
||||
// din_real = {
|
||||
// 12'd153 ,
|
||||
// -12'd724 ,
|
||||
// -12'd1315,
|
||||
// 12'd433 };
|
||||
|
||||
// din_imag = {
|
||||
// -12'd1170,
|
||||
// 12'd981 ,
|
||||
// -12'd48 ,
|
||||
// 12'd1494};
|
||||
// end
|
||||
|
||||
// always #10 clk = ~clk;
|
||||
|
||||
|
||||
// endmodule
|
||||
@@ -1,162 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 04/25/2023 03:22:25 PM
|
||||
// Design Name:
|
||||
// Module Name: phase_compensation
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Rotate input data using Cordic LogiCORE IP.
|
||||
// Parameter:
|
||||
// DATA_WIDTH: Bit width of input and output data.
|
||||
// PHASE_WIDTH: Bit width of input phase.
|
||||
// CHANNEL_NUM: Channel number of input data.
|
||||
// ROTATE_WIDTH (local): Cordic LogiCORE IP input and output actual data width.
|
||||
// AXIS_ROTATE_WIDTH (local): Cordic LogiCORE IP input and output axis data
|
||||
// width.
|
||||
// Data format:
|
||||
// din_valid: Indicate [din_data_real/imag] and [din_phase] are valid.
|
||||
// din_data_real/imag: Suppose the channel number is 4, then
|
||||
// din_data_real = {Re{ch4}, Re{ch3}, Re{ch2}, Re{ch1}}
|
||||
// din_data_imag = {Im{ch4}, Im{ch3}, Im{ch2}, Im{ch1}}
|
||||
// din_phase = {phase_ch4, phase_ch3, phase_ch2, phase_ch1}
|
||||
// dout_valid: Indicate [dout_real/imag] data are valid. The latency is
|
||||
// determined by the cordic ip core, which is 20 clock cycles.
|
||||
// dout_real/imag:
|
||||
// dout_data_real = {Re{rotate_ch4}, Re{rotate_ch3}, ..., Re{rotate_ch1}}
|
||||
// dout_data_imag = {Im{rotate_ch4}, Im{rotate_ch3}, ..., Im{rotate_ch1}}
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module phase_compensation
|
||||
#(
|
||||
parameter DATA_WIDTH = 12,
|
||||
parameter PHASE_WIDTH = 16,
|
||||
parameter CHANNEL_NUM = 4
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
// input data
|
||||
input din_valid,
|
||||
input [CHANNEL_NUM*DATA_WIDTH-1 : 0] din_data_real,
|
||||
input [CHANNEL_NUM*DATA_WIDTH-1 : 0] din_data_imag,
|
||||
input [CHANNEL_NUM*PHASE_WIDTH-1 : 0] din_phase,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output [CHANNEL_NUM*DATA_WIDTH-1:0] dout_data_real,
|
||||
output [CHANNEL_NUM*DATA_WIDTH-1:0] dout_data_imag
|
||||
);
|
||||
|
||||
// local parameter & variables
|
||||
localparam ROTATE_WIDTH = 16;
|
||||
localparam AXIS_ROTATE_WIDTH = 8*((ROTATE_WIDTH-1)/8+1); // axis data width of input real/image data
|
||||
|
||||
genvar i,j;
|
||||
|
||||
// prepare rotate input data
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] din_data_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] din_data_imag_array [0 : CHANNEL_NUM-1];
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] din_phase_array [0 : CHANNEL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < CHANNEL_NUM; i = i + 1) begin: array_convert_in
|
||||
|
||||
if (AXIS_ROTATE_WIDTH > DATA_WIDTH) begin
|
||||
// append zeros
|
||||
assign din_data_real_array[i] = {din_data_real[i*DATA_WIDTH +: DATA_WIDTH],{(AXIS_ROTATE_WIDTH-DATA_WIDTH){1'b0}}};
|
||||
assign din_data_imag_array[i] = {din_data_imag[i*DATA_WIDTH +: DATA_WIDTH],{(AXIS_ROTATE_WIDTH-DATA_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign din_data_real_array[i] = din_data_real[(i+1)*DATA_WIDTH-1 -: AXIS_ROTATE_WIDTH];
|
||||
assign din_data_imag_array[i] = din_data_imag[(i+1)*DATA_WIDTH-1 -: AXIS_ROTATE_WIDTH];
|
||||
end
|
||||
|
||||
if (AXIS_ROTATE_WIDTH > PHASE_WIDTH) begin
|
||||
// append zeros
|
||||
assign din_phase_array[i] = {din_phase[i*PHASE_WIDTH +: PHASE_WIDTH],{(AXIS_ROTATE_WIDTH-PHASE_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign din_phase_array[i] = din_phase[(i+1)*PHASE_WIDTH-1 -: PHASE_WIDTH];
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// rotate
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] rotate_out_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] rotate_out_imag_array [0 : CHANNEL_NUM-1];
|
||||
|
||||
generate
|
||||
for (i = 0; i < CHANNEL_NUM; i = i + 1) begin: input_data_rotate
|
||||
wire rotate_phase_valid;
|
||||
wire [AXIS_ROTATE_WIDTH-1 : 0] rotate_phase_data;
|
||||
wire rotate_cart_valid;
|
||||
wire [2*AXIS_ROTATE_WIDTH-1 : 0] rotate_cart_data;
|
||||
wire rotate_dout_valid;
|
||||
wire [2*AXIS_ROTATE_WIDTH-1 : 0] rotate_dout_data;
|
||||
|
||||
assign rotate_phase_valid = din_valid;
|
||||
assign rotate_phase_data = din_phase_array[i];
|
||||
assign rotate_cart_valid = din_valid;
|
||||
assign rotate_cart_data = {din_data_imag_array[i],din_data_real_array[i]};
|
||||
assign {rotate_out_imag_array[i],rotate_out_real_array[i]} = rotate_dout_data;
|
||||
|
||||
rotate_16b u_rotate_16b
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_phase_tvalid (rotate_phase_valid ), // input wire s_axis_phase_tvalid
|
||||
.s_axis_phase_tdata (rotate_phase_data ), // input wire [15 : 0] s_axis_phase_tdata
|
||||
.s_axis_cartesian_tvalid(rotate_cart_valid ), // input wire s_axis_cartesian_tvalid
|
||||
.s_axis_cartesian_tdata (rotate_cart_data ), // input wire [31 : 0] s_axis_cartesian_tdata
|
||||
.m_axis_dout_tvalid (rotate_dout_valid ), // output wire m_axis_dout_tvalid
|
||||
.m_axis_dout_tdata (rotate_dout_data ) // output wire [31 : 0] m_axis_dout_tdata
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// output data
|
||||
wire [DATA_WIDTH-1 : 0] dout_data_real_array [0 : CHANNEL_NUM-1];
|
||||
wire [DATA_WIDTH-1 : 0] dout_data_imag_array [0 : CHANNEL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < CHANNEL_NUM; i = i + 1) begin: array_convert_out
|
||||
|
||||
if (DATA_WIDTH > AXIS_ROTATE_WIDTH) begin
|
||||
// append zeros
|
||||
assign dout_data_real_array[i] = {rotate_out_real_array[i],{(DATA_WIDTH-AXIS_ROTATE_WIDTH){1'b0}}};
|
||||
assign dout_data_imag_array[i] = {rotate_out_imag_array[i],{(DATA_WIDTH-AXIS_ROTATE_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign dout_data_real_array[i] = rotate_out_real_array[i][AXIS_ROTATE_WIDTH-1 -: DATA_WIDTH];
|
||||
assign dout_data_imag_array[i] = rotate_out_imag_array[i][AXIS_ROTATE_WIDTH-1 -: DATA_WIDTH];
|
||||
end
|
||||
|
||||
assign dout_data_real[i*DATA_WIDTH +: DATA_WIDTH] = dout_data_real_array[i];
|
||||
assign dout_data_imag[i*DATA_WIDTH +: DATA_WIDTH] = dout_data_imag_array[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign dout_valid = input_data_rotate[0].rotate_dout_valid;
|
||||
|
||||
endmodule
|
||||
@@ -1,531 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 18:09:20
|
||||
// Design Name:
|
||||
// Module Name: rx_pre_process
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Pre-process rx data, including ad9361 mcs & implementing nulling
|
||||
// algorithm on rx data. The latency of autocorrelation is consisted of 2
|
||||
// parts: 1. [STABLE_CNT_MOD] + [SNAPSHOT_NUM] + several intermediate delay
|
||||
// of [sys_clk] clock cycles; 2. ([CHANNEL_NUM]*[CHANNEL_NUM]*[CMPLX_DIM] +
|
||||
// 1 frame head + 1 frame length)*[ACCUM_WIDTH] of [clk_96m] clock cycles.
|
||||
// The simulation result shows delay of about 30us when [sys_clk] is 48m.
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*******************************************************************************
|
||||
* Contents
|
||||
* 01. AD9361 Rx Multi-Channel Calibration
|
||||
* 02. Autocorrelation of Snapshot Vector
|
||||
* 03. Accumulation of Snapshot Autocorrelation Matrices
|
||||
* 04. 32-bit Matrix Element to 1-bit Stream Conversion
|
||||
* 05. 1-bit Stream to 32-bit Vector Element Conversion
|
||||
* 06. RF Synthesizer Control
|
||||
* 07. Debug IO
|
||||
* 08. DDR and Fixed-io (Do NOT Modify)
|
||||
*******************************************************************************/
|
||||
|
||||
module rx_pre_process
|
||||
#(
|
||||
parameter CAL_CNT_MOD = 48 ,
|
||||
parameter CAL_PEAK_POS = 12 ,
|
||||
parameter PHASE_WIDTH = 16 ,
|
||||
parameter STABLE_CNT_MOD = 48 ,
|
||||
parameter ADC_DATA_WIDTH = 12 ,
|
||||
parameter CHANNEL_NUM = 4 ,
|
||||
parameter SNAPSHOT_NUM = 256,
|
||||
parameter PS_PL_WIDTH = 32 ,
|
||||
parameter WEIGHT_TRUNC_WIDTH = 16 ,
|
||||
parameter CMPLX_DIM = 2 ,
|
||||
parameter OUTPUT_DATA_WIDTH = ADC_DATA_WIDTH,
|
||||
parameter ACCOR_FRAME_HEAD = 32'h7E7E7E7E,
|
||||
parameter WEIGHT_FRAME_HEAD = ACCOR_FRAME_HEAD // Same head is required by [c2c_bridge] module
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input sys_clk , // sync to adc data
|
||||
input sys_clk_4x , // sync to adc data
|
||||
input sys_rst , // sync to [sys_clk]
|
||||
input clk_96m , // sync to c2c data
|
||||
input ant_rst , // sync to [clk_96m]
|
||||
|
||||
// input un-calibrated data
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch1_i ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch1_q ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch2_i ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch2_q ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch3_i ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch3_q ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch4_i ,
|
||||
input [ADC_DATA_WIDTH-1:0] rx_ch4_q ,
|
||||
|
||||
// input phase
|
||||
input [PHASE_WIDTH-1:0] phase_ch1 ,
|
||||
input [PHASE_WIDTH-1:0] phase_ch2 ,
|
||||
input [PHASE_WIDTH-1:0] phase_ch3 ,
|
||||
input [PHASE_WIDTH-1:0] phase_ch4 ,
|
||||
|
||||
// ad9361 calibration interface
|
||||
input ad9361_1_cal_start ,
|
||||
output ad9361_1_cal_done ,
|
||||
input ad9361_2_cal_start ,
|
||||
output ad9361_2_cal_done ,
|
||||
output ad9361_cal_result ,
|
||||
output ad9361_cal_valid ,
|
||||
input ad9361_recal ,
|
||||
|
||||
// nulling algotithm interface
|
||||
input hop_start_flag , // sync to [sys_clk_4x]
|
||||
output accor_stream_valid , // sync to [clk_96m]
|
||||
output accor_stream_data , // sync to [clk_96m]
|
||||
input weight_stream_data , // sync to [clk_96m]
|
||||
output rx_data_valid , // sync to [sys_clk]
|
||||
output [OUTPUT_DATA_WIDTH-1:0] rx_data_i, // sync to [sys_clk]
|
||||
output [OUTPUT_DATA_WIDTH-1:0] rx_data_q // sync to [sys_clk]
|
||||
);
|
||||
|
||||
localparam ACORR_WIDTH = 2*ADC_DATA_WIDTH;
|
||||
localparam ACCUM_WIDTH = $clog2(SNAPSHOT_NUM)+ACORR_WIDTH; // = 32
|
||||
// autocorrelation state machine
|
||||
localparam ACORR_STATE_NUM = 3;
|
||||
localparam ACORR_STATE_IDLE = 0;
|
||||
localparam ACORR_STATE_STABLE = 1; // wait until rf is stable
|
||||
localparam ACORR_STATE_CALC = 2; // autocorrelation calculation and formatting
|
||||
|
||||
genvar i;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////// AD9361 Rx Multi-Channel Calibration //////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
wire [11:0] rx_cal_ch1_i, rx_cal_ch1_q;
|
||||
wire [11:0] rx_cal_ch2_i, rx_cal_ch2_q;
|
||||
wire [11:0] rx_cal_ch3_i, rx_cal_ch3_q;
|
||||
wire [11:0] rx_cal_ch4_i, rx_cal_ch4_q;
|
||||
|
||||
ad9361_phase_cal_coarse u_ad9361_phase_cal
|
||||
(
|
||||
// clock & reset
|
||||
.clk (sys_clk ), // input clk
|
||||
.rst (sys_rst ), // input rst
|
||||
// control interface
|
||||
.ad9361_1_cal_start (ad9361_1_cal_start ), // input ad9361_1_cal_start
|
||||
.ad9361_1_cal_done (ad9361_1_cal_done ), // output ad9361_1_cal_done
|
||||
.ad9361_2_cal_start (ad9361_2_cal_start ), // input ad9361_2_cal_start
|
||||
.ad9361_2_cal_done (ad9361_2_cal_done ), // output ad9361_2_cal_done
|
||||
.ad9361_cal_result (ad9361_cal_result ), // output ad9361_cal_result
|
||||
.ad9361_cal_valid (ad9361_cal_valid ), // output ad9361_cal_valid
|
||||
.ad9361_recal (ad9361_recal ), // input ad9361_recal
|
||||
// input data interface
|
||||
.rx_ch1_i (rx_ch1_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch1_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch2_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch2_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch2_q
|
||||
.rx_ch3_i (rx_ch3_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch3_i
|
||||
.rx_ch3_q (rx_ch3_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch3_q
|
||||
.rx_ch4_i (rx_ch4_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch4_i
|
||||
.rx_ch4_q (rx_ch4_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch4_q
|
||||
// output data interface
|
||||
.rx_cal_ch1_i (rx_cal_ch1_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch1_i
|
||||
.rx_cal_ch1_q (rx_cal_ch1_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch1_q
|
||||
.rx_cal_ch2_i (rx_cal_ch2_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch2_i
|
||||
.rx_cal_ch2_q (rx_cal_ch2_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch2_q
|
||||
.rx_cal_ch3_i (rx_cal_ch3_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch3_i
|
||||
.rx_cal_ch3_q (rx_cal_ch3_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch3_q
|
||||
.rx_cal_ch4_i (rx_cal_ch4_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch4_i
|
||||
.rx_cal_ch4_q (rx_cal_ch4_q ) // output [ADC_DATA_WIDTH-1:0] rx_cal_ch4_q
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////// Channel Phase Diff Compensation ////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input
|
||||
wire phase_comp_din_valid;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH - 1 : 0] phase_comp_din_data_real;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH - 1 : 0] phase_comp_din_data_imag;
|
||||
wire [CHANNEL_NUM*PHASE_WIDTH-1 : 0] phase_comp_din_phase;
|
||||
|
||||
assign phase_comp_din_valid = ad9361_cal_valid;
|
||||
assign phase_comp_din_data_real = {rx_cal_ch4_i, rx_cal_ch3_i, rx_cal_ch2_i, rx_cal_ch1_i};
|
||||
assign phase_comp_din_data_imag = {rx_cal_ch4_q, rx_cal_ch3_q, rx_cal_ch2_q, rx_cal_ch1_q};
|
||||
assign phase_comp_din_phase = {phase_ch4, phase_ch3, phase_ch2, phase_ch1};
|
||||
|
||||
// output
|
||||
wire phase_comp_dout_valid;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH - 1 : 0] phase_comp_dout_data_real;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH - 1 : 0] phase_comp_dout_data_imag;
|
||||
|
||||
phase_compensation #(
|
||||
.DATA_WIDTH (ADC_DATA_WIDTH ),
|
||||
.PHASE_WIDTH (PHASE_WIDTH ),
|
||||
.CHANNEL_NUM (CHANNEL_NUM )
|
||||
) u_phase_compensation
|
||||
(
|
||||
// clock & reset
|
||||
.clk (sys_clk ),
|
||||
.rst (sys_rst ),
|
||||
|
||||
// input data
|
||||
.din_valid (phase_comp_din_valid ),
|
||||
.din_data_real (phase_comp_din_data_real ),
|
||||
.din_data_imag (phase_comp_din_data_imag ),
|
||||
.din_phase (phase_comp_din_phase ),
|
||||
|
||||
// output data
|
||||
.dout_valid (phase_comp_dout_valid ),
|
||||
.dout_data_real (phase_comp_dout_data_real ),
|
||||
.dout_data_imag (phase_comp_dout_data_imag )
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////// Autocorrelation State Machine /////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
reg [$clog2(ACORR_STATE_NUM)-1 : 0] acorr_state = ACORR_STATE_IDLE;
|
||||
reg [$clog2(STABLE_CNT_MOD)-1 : 0] stable_cnt = 'b0;
|
||||
reg [$clog2(SNAPSHOT_NUM)-1 : 0] snapshot_cnt = 'b0;
|
||||
reg snapshot_valid = 'b0;
|
||||
|
||||
reg fifo_cdc_rst = 1'b0; // reset [fifo_accor_cdc] & [fifo_weight_cdc] at each hop
|
||||
|
||||
wire hop_start_flag_cdc;
|
||||
|
||||
xpm_cdc_pulse #(
|
||||
.DEST_SYNC_FF (4), // DECIMAL; range: 2-10
|
||||
.INIT_SYNC_FF (1), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
|
||||
.REG_OUTPUT (1), // DECIMAL; 0=disable registered output, 1=enable registered output
|
||||
.RST_USED (0), // DECIMAL; 0=no reset, 1=implement reset
|
||||
.SIM_ASSERT_CHK (1) // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
|
||||
) u_hop_start_flag_cdc
|
||||
(
|
||||
.dest_pulse (hop_start_flag_cdc ), // 1-bit output: Outputs a pulse the size of one dest_clk period when a pulse
|
||||
// transfer is correctly initiated on src_pulse input. This output is
|
||||
// combinatorial unless REG_OUTPUT is set to 1.
|
||||
.dest_clk (sys_clk ), // 1-bit input: Destination clock.
|
||||
.dest_rst (1'b1 ), // 1-bit input: optional; required when RST_USED = 1
|
||||
.src_clk (sys_clk_4x ), // 1-bit input: Source clock.
|
||||
.src_pulse (hop_start_flag ), // 1-bit input: Rising edge of this signal initiates a pulse transfer to the
|
||||
// destination clock domain. The minimum gap between each pulse transfer must be
|
||||
// at the minimum 2*(larger(src_clk period, dest_clk period)). This is measured
|
||||
// between the falling edge of a src_pulse to the rising edge of the next
|
||||
// src_pulse. This minimum gap will guarantee that each rising edge of src_pulse
|
||||
// will generate a pulse the size of one dest_clk period in the destination
|
||||
// clock domain. When RST_USED = 1, pulse transfers will not be guaranteed while
|
||||
// src_rst and/or dest_rst are asserted.
|
||||
.src_rst (1'b1 ) // 1-bit input: optional; required when RST_USED = 1
|
||||
);
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
acorr_state <= ACORR_STATE_IDLE;
|
||||
end
|
||||
else begin
|
||||
case (acorr_state)
|
||||
ACORR_STATE_IDLE : acorr_state <= (hop_start_flag_cdc & phase_comp_dout_valid) ? ACORR_STATE_STABLE : ACORR_STATE_IDLE;
|
||||
ACORR_STATE_STABLE: acorr_state <= (stable_cnt == STABLE_CNT_MOD-1) ? ACORR_STATE_CALC : ACORR_STATE_STABLE;
|
||||
ACORR_STATE_CALC : acorr_state <= (snapshot_cnt == SNAPSHOT_NUM-1) ? ACORR_STATE_IDLE : ACORR_STATE_CALC;
|
||||
default: acorr_state <= ACORR_STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
stable_cnt <= 'b0;
|
||||
end
|
||||
else begin
|
||||
case (acorr_state)
|
||||
ACORR_STATE_IDLE : stable_cnt <= 'b0;
|
||||
ACORR_STATE_STABLE: stable_cnt <= (stable_cnt == STABLE_CNT_MOD-1) ? 'b0 : stable_cnt + 1'b1;
|
||||
ACORR_STATE_CALC : stable_cnt <= 'b0;
|
||||
default: stable_cnt <= 'b0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
snapshot_cnt <= 'b0;
|
||||
end
|
||||
else begin
|
||||
case (acorr_state)
|
||||
ACORR_STATE_IDLE : snapshot_cnt <= 'b0;
|
||||
ACORR_STATE_STABLE: snapshot_cnt <= 'b0;
|
||||
ACORR_STATE_CALC : snapshot_cnt <= (snapshot_cnt == SNAPSHOT_NUM-1) ? 'b0 : snapshot_cnt + 1'b1;
|
||||
default: snapshot_cnt <= 'b0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
snapshot_valid <= 'b0;
|
||||
end
|
||||
else begin
|
||||
case (acorr_state)
|
||||
ACORR_STATE_IDLE : snapshot_valid <= 'b0;
|
||||
ACORR_STATE_STABLE: snapshot_valid <= 'b0;
|
||||
ACORR_STATE_CALC : snapshot_valid <= 1'b1;
|
||||
default: snapshot_valid <= 'b0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_cdc_rst <= 'b0;
|
||||
end
|
||||
else if (acorr_state == ACORR_STATE_STABLE) begin
|
||||
fifo_cdc_rst <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_cdc_rst <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// Autocorrelation of Snapshot Vector //////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input data
|
||||
wire acorr_din_valid;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH-1 : 0] acorr_din_real;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH-1 : 0] acorr_din_imag;
|
||||
|
||||
assign acorr_din_valid = snapshot_valid;
|
||||
assign acorr_din_real = phase_comp_dout_data_real;
|
||||
assign acorr_din_imag = phase_comp_dout_data_imag;
|
||||
|
||||
// output data
|
||||
wire acorr_dout_valid;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*ACORR_WIDTH-1:0] acorr_dout_real;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*ACORR_WIDTH-1:0] acorr_dout_imag;
|
||||
|
||||
acorr_cmplx_col_vec #(
|
||||
.DATA_I_WIDTH (ADC_DATA_WIDTH ),
|
||||
.DATA_O_WIDTH (ACORR_WIDTH ),
|
||||
.COL_NUM (CHANNEL_NUM )
|
||||
) u_acorr (
|
||||
// clock & reset
|
||||
.clk (sys_clk ),
|
||||
.rst (sys_rst ),
|
||||
|
||||
// input data
|
||||
.din_valid (acorr_din_valid ),
|
||||
.din_real (acorr_din_real ),
|
||||
.din_imag (acorr_din_imag ),
|
||||
|
||||
// output data
|
||||
.dout_valid (acorr_dout_valid ),
|
||||
.dout_real (acorr_dout_real ),
|
||||
.dout_imag (acorr_dout_imag )
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////// Accumulation of Snapshot Autocorrelation Matrices ///////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// accumulation reset
|
||||
wire acc_rst; // [acc_rst] should assert before accumulation starts
|
||||
|
||||
assign acc_rst = hop_start_flag_cdc;
|
||||
|
||||
// input data
|
||||
wire accum_din_valid;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*ACORR_WIDTH-1:0] accum_din_real;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*ACORR_WIDTH-1:0] accum_din_imag;
|
||||
|
||||
assign accum_din_valid = acorr_dout_valid;
|
||||
assign accum_din_real = acorr_dout_real;
|
||||
assign accum_din_imag = acorr_dout_imag;
|
||||
|
||||
// output data
|
||||
wire accum_dout_valid;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*PS_PL_WIDTH-1:0] accum_dout_real;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*PS_PL_WIDTH-1:0] accum_dout_imag;
|
||||
|
||||
accum_cmplx_mat #(
|
||||
.ROW_NUM (CHANNEL_NUM ),
|
||||
.COL_NUM (CHANNEL_NUM ),
|
||||
.DATA_I_WIDTH (ACORR_WIDTH ),
|
||||
.DATA_ACC_WIDTH (ACCUM_WIDTH ),
|
||||
.DATA_O_WIDTH (PS_PL_WIDTH ),
|
||||
.ACC_NUM (SNAPSHOT_NUM )
|
||||
) u_accum_cmplx_mat
|
||||
(
|
||||
// clock & reset
|
||||
.clk (sys_clk ),
|
||||
.rst (sys_rst ),
|
||||
.acc_rst (acc_rst ), // [acc_rst] should assert before accumulation starts
|
||||
|
||||
// input data
|
||||
.din_valid (accum_din_valid ),
|
||||
.din_real (accum_din_real ),
|
||||
.din_imag (accum_din_imag ),
|
||||
|
||||
// output data
|
||||
.dout_valid (accum_dout_valid ),
|
||||
.dout_real (accum_dout_real ),
|
||||
.dout_imag (accum_dout_imag )
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////// 32-bit Matrix Element to 1-bit Stream Conversion ///////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input data
|
||||
wire stream_din_valid;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*PS_PL_WIDTH-1 : 0] stream_din_real;
|
||||
wire [CHANNEL_NUM*CHANNEL_NUM*PS_PL_WIDTH-1 : 0] stream_din_imag;
|
||||
|
||||
assign stream_din_valid = accum_dout_valid;
|
||||
assign stream_din_real = accum_dout_real;
|
||||
assign stream_din_imag = accum_dout_imag;
|
||||
|
||||
// output data
|
||||
wire stream_dout_valid;
|
||||
wire stream_dout_data;
|
||||
|
||||
assign accor_stream_valid = stream_dout_valid; // to module port
|
||||
assign accor_stream_data = stream_dout_data; // to module port
|
||||
|
||||
accor_mat_formatting #(
|
||||
.ROW_NUM (CHANNEL_NUM ),
|
||||
.COL_NUM (CHANNEL_NUM ),
|
||||
.DATA_I_WIDTH (PS_PL_WIDTH ),
|
||||
.FRAME_HEAD (ACCOR_FRAME_HEAD )
|
||||
) u_accor_mat_stream
|
||||
(
|
||||
// clock & reset
|
||||
.sys_clk (sys_clk ),
|
||||
.sys_rst (sys_rst ),
|
||||
.clk_96m (clk_96m ),
|
||||
.ant_rst (ant_rst ),
|
||||
|
||||
// input data, sync to [sys_clk]
|
||||
.din_valid (stream_din_valid ),
|
||||
.din_real (stream_din_real ),
|
||||
.din_imag (stream_din_imag ),
|
||||
.fifo_cdc_rst (fifo_cdc_rst ),
|
||||
|
||||
// output data, sync to [clk_96m]
|
||||
.dout_valid (stream_dout_valid ),
|
||||
.dout_data (stream_dout_data )
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////// 1-bit Stream to 32-bit Vector Element Conversion ///////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input data
|
||||
wire weight_din_data;
|
||||
|
||||
assign weight_din_data = weight_stream_data;
|
||||
assign stream_din_real = accum_dout_real;
|
||||
assign stream_din_imag = accum_dout_imag;
|
||||
|
||||
// output data
|
||||
wire weight_dout_valid;
|
||||
wire [CHANNEL_NUM*WEIGHT_TRUNC_WIDTH-1 : 0] weight_dout_real;
|
||||
wire [CHANNEL_NUM*WEIGHT_TRUNC_WIDTH-1 : 0] weight_dout_imag;
|
||||
|
||||
weight_vec_formatting #(
|
||||
.COL_NUM (CHANNEL_NUM ),
|
||||
.WEIGHT_WIDTH (PS_PL_WIDTH ),
|
||||
.DATA_O_WIDTH (WEIGHT_TRUNC_WIDTH ),
|
||||
.FRAME_HEAD (WEIGHT_FRAME_HEAD )
|
||||
) u_weight_vec_formatting
|
||||
(
|
||||
// clock & reset
|
||||
.sys_clk (sys_clk ),
|
||||
.sys_rst (sys_rst ),
|
||||
.clk_96m (clk_96m ),
|
||||
.ant_rst (ant_rst ),
|
||||
|
||||
// input data, sync to [clk_96m]
|
||||
.din_data (weight_din_data ),
|
||||
|
||||
// sync to [sys_clk]
|
||||
.fifo_cdc_rst (fifo_cdc_rst ),
|
||||
|
||||
// output data, sync to [sys_clk]
|
||||
.dout_valid (weight_dout_valid ),
|
||||
.dout_real (weight_dout_real ),
|
||||
.dout_imag (weight_dout_imag )
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// Spatial Filter ////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// input weight vector
|
||||
wire filter_weight_valid;
|
||||
wire [CHANNEL_NUM*WEIGHT_TRUNC_WIDTH-1 : 0] filter_weight_real;
|
||||
wire [CHANNEL_NUM*WEIGHT_TRUNC_WIDTH-1 : 0] filter_weight_imag;
|
||||
|
||||
assign filter_weight_valid = weight_dout_valid;
|
||||
assign filter_weight_real = weight_dout_real;
|
||||
assign filter_weight_imag = weight_dout_imag;
|
||||
|
||||
// input adc data
|
||||
wire filter_adc_valid;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH-1 : 0] filter_adc_real;
|
||||
wire [CHANNEL_NUM*ADC_DATA_WIDTH-1 : 0] filter_adc_imag;
|
||||
|
||||
assign filter_adc_valid = phase_comp_dout_valid;
|
||||
assign filter_adc_real = phase_comp_dout_data_real;
|
||||
assign filter_adc_imag = phase_comp_dout_data_imag;
|
||||
|
||||
// output data
|
||||
wire filter_dout_valid;
|
||||
wire [OUTPUT_DATA_WIDTH-1 : 0] filter_dout_real;
|
||||
wire [OUTPUT_DATA_WIDTH-1 : 0] filter_dout_imag;
|
||||
|
||||
assign rx_data_valid = filter_dout_valid;
|
||||
assign rx_data_i = filter_dout_real;
|
||||
assign rx_data_q = filter_dout_imag;
|
||||
|
||||
spatial_filter #(
|
||||
.CHANNEL_NUM (CHANNEL_NUM ),
|
||||
.WEIGHT_WIDTH (WEIGHT_TRUNC_WIDTH ),
|
||||
.ADC_WIDTH (ADC_DATA_WIDTH ),
|
||||
.FILTER_O_WIDTH (OUTPUT_DATA_WIDTH )
|
||||
) u_spatial_filter
|
||||
(
|
||||
// clock & reset
|
||||
.clk (sys_clk ),
|
||||
.rst (sys_rst ),
|
||||
|
||||
// input weight vector
|
||||
.din_weight_valid (filter_weight_valid),
|
||||
.din_weight_real (filter_weight_real ),
|
||||
.din_weight_imag (filter_weight_imag ),
|
||||
|
||||
// input adc data
|
||||
.hop_start_flag (hop_start_flag_cdc ),
|
||||
.din_adc_valid (filter_adc_valid ),
|
||||
.din_adc_real (filter_adc_real ),
|
||||
.din_adc_imag (filter_adc_imag ),
|
||||
|
||||
// output data
|
||||
.dout_valid (filter_dout_valid ),
|
||||
.dout_real (filter_dout_real ),
|
||||
.dout_imag (filter_dout_imag )
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -1,250 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/11/16 11:18:28
|
||||
// Design Name:
|
||||
// Module Name: rx_pre_test
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module rx_pre_test
|
||||
#(
|
||||
parameter ADC_DATA_WIDTH = 12,
|
||||
parameter BYPASS_CAL = 0
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input sys_clk ,
|
||||
input sys_clk_4x ,
|
||||
input sys_rst ,
|
||||
// calc result
|
||||
input ad9361_cal_result ,
|
||||
input ad9361_cal_valid ,
|
||||
//
|
||||
input hop_trigger ,
|
||||
input hop_trigger_en ,
|
||||
// output test data
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch1_i ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch1_q ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch2_i ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch2_q ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch3_i ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch3_q ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch4_i ,
|
||||
output [ADC_DATA_WIDTH-1:0] rx_ch4_q ,
|
||||
output hop_start_flag
|
||||
);
|
||||
|
||||
localparam HOP_CNT_MOD_192M = 192*200;
|
||||
localparam HOP_CNT_MOD_48M = 48*200;
|
||||
|
||||
// data valid cdc
|
||||
wire ad9361_cal_valid_cdc;
|
||||
|
||||
xpm_cdc_single #(
|
||||
.DEST_SYNC_FF (4), // DECIMAL; range: 2-10
|
||||
.INIT_SYNC_FF (0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
|
||||
.SIM_ASSERT_CHK (0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
|
||||
.SRC_INPUT_REG (1) // DECIMAL; 0=do not register input, 1=register input
|
||||
) u_ad9361_cal_valid_cdc
|
||||
(
|
||||
.dest_out (ad9361_cal_valid_cdc ), // 1-bit output: src_in synchronized to the destination clock domain. This output is
|
||||
// registered.
|
||||
.dest_clk (sys_clk_4x ), // 1-bit input: Clock signal for the destination clock domain.
|
||||
.src_clk (sys_clk ), // 1-bit input: optional; required when SRC_INPUT_REG = 1
|
||||
.src_in (ad9361_cal_valid ) // 1-bit input: Input signal to be synchronized to dest_clk domain.
|
||||
);
|
||||
|
||||
// auto hop flag generation
|
||||
reg [$clog2(HOP_CNT_MOD_192M)-1 : 0] hop_cnt_192m = 'b0;
|
||||
reg hop_flag_auto = 'b0;
|
||||
|
||||
always @(posedge sys_clk_4x) begin
|
||||
if (sys_rst) begin
|
||||
hop_cnt_192m = 'b0;
|
||||
hop_flag_auto = 'b0;
|
||||
end
|
||||
else if (ad9361_cal_valid_cdc) begin
|
||||
hop_cnt_192m <= (hop_cnt_192m == HOP_CNT_MOD_192M-1) ? 'b0 : hop_cnt_192m + 1'b1;
|
||||
hop_flag_auto <= (hop_cnt_192m == 20) ? 1'b1 : 1'b0;
|
||||
end
|
||||
else begin
|
||||
hop_cnt_192m <= 'b0;
|
||||
hop_flag_auto = 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// manual hop flag generation
|
||||
reg hop_flag_manual = 'b0;
|
||||
reg hop_trigger_d1 = 'b0;
|
||||
|
||||
always @(posedge sys_clk_4x) begin
|
||||
hop_trigger_d1 <= hop_trigger;
|
||||
end
|
||||
|
||||
always @(posedge sys_clk_4x) begin
|
||||
if (sys_rst) begin
|
||||
hop_flag_manual <= 'b0;
|
||||
end
|
||||
else if (ad9361_cal_valid_cdc) begin
|
||||
if (~hop_trigger_d1 && hop_trigger) begin
|
||||
hop_flag_manual <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
hop_flag_manual <= 1'b0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
hop_flag_manual <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// output hop flag
|
||||
reg hop_start_flag_buf = 'b0;
|
||||
|
||||
assign hop_start_flag = hop_start_flag_buf;
|
||||
|
||||
always @(posedge sys_clk_4x) begin
|
||||
if (sys_rst) begin
|
||||
hop_start_flag_buf <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if (hop_trigger_en) begin
|
||||
hop_start_flag_buf <= hop_flag_manual;
|
||||
end
|
||||
else begin
|
||||
hop_start_flag_buf <= hop_flag_auto;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// hop flag cdc
|
||||
wire hop_flag_cdc;
|
||||
|
||||
xpm_cdc_pulse #(
|
||||
.DEST_SYNC_FF (4), // DECIMAL; range: 2-10
|
||||
.INIT_SYNC_FF (0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
|
||||
.REG_OUTPUT (0), // DECIMAL; 0=disable registered output, 1=enable registered output
|
||||
.RST_USED (1), // DECIMAL; 0=no reset, 1=implement reset
|
||||
.SIM_ASSERT_CHK (0) // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
|
||||
) u_hop_flag_cdc
|
||||
(
|
||||
.dest_pulse (hop_flag_cdc ), // 1-bit output: Outputs a pulse the size of one dest_clk period when a pulse
|
||||
// transfer is correctly initiated on src_pulse input. This output is
|
||||
// combinatorial unless REG_OUTPUT is set to 1.
|
||||
.dest_clk (sys_clk ), // 1-bit input: Destination clock.
|
||||
.dest_rst (sys_rst ), // 1-bit input: optional; required when RST_USED = 1
|
||||
.src_clk (sys_clk_4x ), // 1-bit input: Source clock.
|
||||
.src_pulse (hop_start_flag_buf ), // 1-bit input: Rising edge of this signal initiates a pulse transfer to the
|
||||
// destination clock domain. The minimum gap between each pulse transfer must be
|
||||
// at the minimum 2*(larger(src_clk period, dest_clk period)). This is measured
|
||||
// between the falling edge of a src_pulse to the rising edge of the next
|
||||
// src_pulse. This minimum gap will guarantee that each rising edge of src_pulse
|
||||
// will generate a pulse the size of one dest_clk period in the destination
|
||||
// clock domain. When RST_USED = 1, pulse transfers will not be guaranteed while
|
||||
// src_rst and/or dest_rst are asserted.
|
||||
.src_rst (sys_rst ) // 1-bit input: optional; required when RST_USED = 1
|
||||
);
|
||||
|
||||
// data rom address counter
|
||||
reg [$clog2(HOP_CNT_MOD_48M)-1 : 0] hop_cnt_48m = 'b0;
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
hop_cnt_48m <= 2'd2;
|
||||
end
|
||||
else if (ad9361_cal_valid) begin
|
||||
if (hop_flag_cdc) begin
|
||||
hop_cnt_48m = 2'd2;
|
||||
end
|
||||
else begin
|
||||
hop_cnt_48m <= (hop_cnt_48m == HOP_CNT_MOD_48M-1 || hop_flag_cdc) ? 'b0 : hop_cnt_48m + 1'b1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
hop_cnt_48m <= 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
// rom interface
|
||||
wire [95:0] hop_data;
|
||||
|
||||
wire [11:0] rom_ch1_i,rom_ch2_i,rom_ch3_i,rom_ch4_i;
|
||||
wire [11:0] rom_ch1_q,rom_ch2_q,rom_ch3_q,rom_ch4_q;
|
||||
|
||||
assign {rom_ch1_i,rom_ch2_i,rom_ch3_i,rom_ch4_i,
|
||||
rom_ch1_q,rom_ch2_q,rom_ch3_q,rom_ch4_q} = hop_data;
|
||||
|
||||
rom_hop_data u_rom_hop_data
|
||||
(
|
||||
.clka (sys_clk ), // input wire clka
|
||||
.addra (hop_cnt_48m), // input wire [13 : 0] addra
|
||||
.douta (hop_data ) // output wire [95 : 0] douta
|
||||
);
|
||||
|
||||
reg [11:0] rom_ch1_i_buf,rom_ch2_i_buf,rom_ch3_i_buf,rom_ch4_i_buf;
|
||||
reg [11:0] rom_ch1_q_buf,rom_ch2_q_buf,rom_ch3_q_buf,rom_ch4_q_buf;
|
||||
|
||||
assign rx_ch1_i = rom_ch1_i_buf;
|
||||
assign rx_ch1_q = rom_ch1_q_buf;
|
||||
assign rx_ch2_i = rom_ch2_i_buf;
|
||||
assign rx_ch2_q = rom_ch2_q_buf;
|
||||
assign rx_ch3_i = rom_ch3_i_buf;
|
||||
assign rx_ch3_q = rom_ch3_q_buf;
|
||||
assign rx_ch4_i = rom_ch4_i_buf;
|
||||
assign rx_ch4_q = rom_ch4_q_buf;
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (BYPASS_CAL) begin
|
||||
rom_ch1_i_buf <= rom_ch1_i;
|
||||
rom_ch1_q_buf <= rom_ch1_q;
|
||||
rom_ch2_i_buf <= rom_ch2_i;
|
||||
rom_ch2_q_buf <= rom_ch2_q;
|
||||
rom_ch3_i_buf <= rom_ch3_i;
|
||||
rom_ch3_q_buf <= rom_ch3_q;
|
||||
rom_ch4_i_buf <= rom_ch4_i;
|
||||
rom_ch4_q_buf <= rom_ch4_q;
|
||||
end
|
||||
else begin
|
||||
if (ad9361_cal_result) begin
|
||||
rom_ch1_i_buf <= rom_ch1_i;
|
||||
rom_ch1_q_buf <= rom_ch1_q;
|
||||
rom_ch2_i_buf <= -rom_ch2_i;
|
||||
rom_ch2_q_buf <= -rom_ch2_q;
|
||||
rom_ch3_i_buf <= -rom_ch3_i;
|
||||
rom_ch3_q_buf <= -rom_ch3_q;
|
||||
rom_ch4_i_buf <= rom_ch4_i;
|
||||
rom_ch4_q_buf <= rom_ch4_q;
|
||||
end
|
||||
else begin
|
||||
rom_ch1_i_buf <= rom_ch1_i;
|
||||
rom_ch1_q_buf <= rom_ch1_q;
|
||||
rom_ch2_i_buf <= -rom_ch2_i;
|
||||
rom_ch2_q_buf <= -rom_ch2_q;
|
||||
rom_ch3_i_buf <= rom_ch3_i;
|
||||
rom_ch3_q_buf <= rom_ch3_q;
|
||||
rom_ch4_i_buf <= -rom_ch4_i;
|
||||
rom_ch4_q_buf <= -rom_ch4_q;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,270 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/11/11 17:05:31
|
||||
// Design Name:
|
||||
// Module Name: spatial_filter
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// 20230404-1037 - 将权矢量和数据对齐,增加 [last_hop_weight_d1] 补偿 RAM 读数
|
||||
// 的延迟。
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module spatial_filter
|
||||
#(
|
||||
parameter CHANNEL_NUM = 4,
|
||||
parameter WEIGHT_WIDTH = 16,
|
||||
parameter ADC_WIDTH = 12,
|
||||
parameter FILTER_O_WIDTH = ADC_WIDTH
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
// input weight vector
|
||||
input din_weight_valid,
|
||||
input [CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] din_weight_real,
|
||||
input [CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] din_weight_imag,
|
||||
|
||||
// input adc data
|
||||
input hop_start_flag,
|
||||
input din_adc_valid,
|
||||
input [CHANNEL_NUM*ADC_WIDTH-1 : 0] din_adc_real,
|
||||
input [CHANNEL_NUM*ADC_WIDTH-1 : 0] din_adc_imag,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output [FILTER_O_WIDTH-1 : 0] dout_real,
|
||||
output [FILTER_O_WIDTH-1 : 0] dout_imag
|
||||
);
|
||||
|
||||
localparam RAM_HOP_DEPTH = 9728;
|
||||
localparam CMPLX_DIM = 2;
|
||||
|
||||
localparam FILTER_MULT_FULL_WIDTH = WEIGHT_WIDTH+ADC_WIDTH+1;
|
||||
localparam FILTER_MULT_VALID_WIDTH = WEIGHT_WIDTH+ADC_WIDTH;
|
||||
localparam FILTER_SUM_WIDTH = FILTER_MULT_VALID_WIDTH+$clog2(CHANNEL_NUM);
|
||||
localparam AXIS_WEIGHT_WIDTH = 8*((WEIGHT_WIDTH-1)/8+1); // axis data width of input weight vector real/image data
|
||||
localparam AXIS_ADC_I_WIDTH = 8*((ADC_WIDTH-1)/8+1) ; // axis data width of input adc real/image data
|
||||
localparam AXIS_FILTER_WIDTH = 8*((FILTER_MULT_FULL_WIDTH-1)/8+1) ; // axis data width of cmpy output real/image data
|
||||
|
||||
genvar i;
|
||||
|
||||
|
||||
// store current hop & restore last hop weight
|
||||
reg [CMPLX_DIM*CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] current_hop_weight = 'b0;
|
||||
reg [CMPLX_DIM*CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] last_hop_weight = 'b0;
|
||||
reg [CMPLX_DIM*CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] last_hop_weight_d1 = 'b0; // wait for ram data
|
||||
|
||||
wire [CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] last_weight_real;
|
||||
wire [CHANNEL_NUM*WEIGHT_WIDTH-1 : 0] last_weight_imag;
|
||||
|
||||
assign {last_weight_imag,last_weight_real} = last_hop_weight_d1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
current_hop_weight <= 'b0;
|
||||
end
|
||||
else begin
|
||||
current_hop_weight <= (din_weight_valid) ? {din_weight_imag,din_weight_real} : current_hop_weight;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
last_hop_weight <= 'b0;
|
||||
end
|
||||
else begin
|
||||
last_hop_weight <= (hop_start_flag) ? current_hop_weight : last_hop_weight;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
last_hop_weight_d1 <= 'b0;
|
||||
end
|
||||
else begin
|
||||
last_hop_weight_d1 <= last_hop_weight;
|
||||
end
|
||||
end
|
||||
|
||||
// store current hop & restore last hop data
|
||||
wire [CMPLX_DIM*CHANNEL_NUM*ADC_WIDTH-1 : 0] current_hop_data;
|
||||
reg last_hop_valid = 'b0;
|
||||
wire [CMPLX_DIM*CHANNEL_NUM*ADC_WIDTH-1 : 0] last_hop_data;
|
||||
|
||||
wire [CHANNEL_NUM*ADC_WIDTH-1 : 0] last_data_real;
|
||||
wire [CHANNEL_NUM*ADC_WIDTH-1 : 0] last_data_imag;
|
||||
|
||||
reg [$clog2(RAM_HOP_DEPTH)-1 : 0] hop_data_cnt = 'b0;
|
||||
|
||||
assign current_hop_data = {din_adc_imag,din_adc_real};
|
||||
assign {last_data_imag,last_data_real} = last_hop_data;
|
||||
|
||||
always @(posedge clk) begin
|
||||
last_hop_valid <= din_adc_valid;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
hop_data_cnt <= 'b0;
|
||||
end
|
||||
else if(din_adc_valid) begin
|
||||
if (hop_start_flag) begin
|
||||
hop_data_cnt <= 'b0;
|
||||
end
|
||||
else if (hop_data_cnt == RAM_HOP_DEPTH-1) begin
|
||||
hop_data_cnt <= 'b0;
|
||||
end
|
||||
else begin
|
||||
hop_data_cnt <= hop_data_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
hop_data_cnt <= hop_data_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
ram_hop_data u_ram_hop_data
|
||||
(
|
||||
.clka (clk ), // input wire clka
|
||||
.wea (din_adc_valid ), // input wire [0 : 0] wea
|
||||
.addra(hop_data_cnt ), // input wire [13 : 0] addra
|
||||
.dina (current_hop_data ), // input wire [95 : 0] dina
|
||||
.douta(last_hop_data ) // output wire [95 : 0] douta
|
||||
);
|
||||
|
||||
// prepare cmpy input data
|
||||
wire [AXIS_WEIGHT_WIDTH-1:0] din_weight_real_array [0:CHANNEL_NUM-1];
|
||||
wire [AXIS_WEIGHT_WIDTH-1:0] din_weight_imag_array [0:CHANNEL_NUM-1];
|
||||
|
||||
wire [AXIS_ADC_I_WIDTH-1:0] din_adc_real_array [0:CHANNEL_NUM-1];
|
||||
wire [AXIS_ADC_I_WIDTH-1:0] din_adc_imag_array [0:CHANNEL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < CHANNEL_NUM; i = i + 1) begin: weight_array_convert
|
||||
// Sign extension to fit 8-bit axis data format
|
||||
assign din_weight_real_array[i] = {{(AXIS_WEIGHT_WIDTH-WEIGHT_WIDTH){last_weight_real[(i+1)*WEIGHT_WIDTH-1]}},last_weight_real[i*WEIGHT_WIDTH +: WEIGHT_WIDTH]};
|
||||
assign din_weight_imag_array[i] = {{(AXIS_WEIGHT_WIDTH-WEIGHT_WIDTH){last_weight_imag[(i+1)*WEIGHT_WIDTH-1]}},last_weight_imag[i*WEIGHT_WIDTH +: WEIGHT_WIDTH]};
|
||||
|
||||
assign din_adc_real_array[i] = {{(AXIS_ADC_I_WIDTH-ADC_WIDTH){last_data_real[(i+1)*ADC_WIDTH-1]}},last_data_real[i*ADC_WIDTH +: ADC_WIDTH]};
|
||||
assign din_adc_imag_array[i] = {{(AXIS_ADC_I_WIDTH-ADC_WIDTH){last_data_imag[(i+1)*ADC_WIDTH-1]}},last_data_imag[i*ADC_WIDTH +: ADC_WIDTH]};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// complex multiplication, spatial filtering
|
||||
wire [AXIS_FILTER_WIDTH-1:0] cmpy_real_array [0:CHANNEL_NUM-1];
|
||||
wire [AXIS_FILTER_WIDTH-1:0] cmpy_imag_array [0:CHANNEL_NUM-1];
|
||||
|
||||
wire [FILTER_MULT_VALID_WIDTH-1:0] weight_adc_real_array [0:CHANNEL_NUM-1];
|
||||
wire [FILTER_MULT_VALID_WIDTH-1:0] weight_adc_imag_array [0:CHANNEL_NUM-1];
|
||||
|
||||
wire weight_adc_valid;
|
||||
wire [CHANNEL_NUM*FILTER_MULT_VALID_WIDTH-1:0] weight_adc_real;
|
||||
wire [CHANNEL_NUM*FILTER_MULT_VALID_WIDTH-1:0] weight_adc_imag;
|
||||
|
||||
generate
|
||||
for(i = 0; i < CHANNEL_NUM; i = i + 1) begin: spatial_filter_cmpy
|
||||
wire [2*AXIS_WEIGHT_WIDTH-1:0] cmpy_a;
|
||||
wire [2*AXIS_ADC_I_WIDTH-1:0] cmpy_b;
|
||||
wire [2*AXIS_FILTER_WIDTH-1:0] cmpy_p;
|
||||
wire cmpy_p_vld;
|
||||
|
||||
assign cmpy_a = {-din_weight_imag_array[i],din_weight_real_array[i]};
|
||||
assign cmpy_b = {din_adc_imag_array[i],din_adc_real_array[i]};
|
||||
assign {cmpy_imag_array[i],cmpy_real_array[i]} = cmpy_p;
|
||||
|
||||
assign weight_adc_real_array[i] = cmpy_real_array[i][0 +: FILTER_MULT_VALID_WIDTH];
|
||||
assign weight_adc_imag_array[i] = cmpy_imag_array[i][0 +: FILTER_MULT_VALID_WIDTH];
|
||||
|
||||
assign weight_adc_real[i*FILTER_MULT_VALID_WIDTH +: FILTER_MULT_VALID_WIDTH] = weight_adc_real_array[i];
|
||||
assign weight_adc_imag[i*FILTER_MULT_VALID_WIDTH +: FILTER_MULT_VALID_WIDTH] = weight_adc_imag_array[i];
|
||||
|
||||
cmpy_16x12 u_cmpy_16x12
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_a_tvalid (last_hop_valid ), // input wire s_axis_a_tvalid
|
||||
.s_axis_a_tdata (cmpy_a ), // input wire [31 : 0] s_axis_a_tdata
|
||||
.s_axis_b_tvalid (last_hop_valid ), // input wire s_axis_b_tvalid
|
||||
.s_axis_b_tdata (cmpy_b ), // input wire [31 : 0] s_axis_b_tdata
|
||||
.m_axis_dout_tvalid (cmpy_p_vld ), // output wire m_axis_dout_tvalid
|
||||
.m_axis_dout_tdata (cmpy_p ) // output wire [63 : 0] m_axis_dout_tdata
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign weight_adc_valid = spatial_filter_cmpy[0].cmpy_p_vld;
|
||||
|
||||
// multi-channel sum
|
||||
wire weight_adc_sum_valid;
|
||||
wire [FILTER_SUM_WIDTH-1 : 0] weight_adc_sum_real;
|
||||
wire [FILTER_SUM_WIDTH-1 : 0] weight_adc_sum_imag;
|
||||
|
||||
adder_tree_ppl #(
|
||||
.DATA_I_WIDTH (FILTER_MULT_VALID_WIDTH),
|
||||
.DATA_NUM (CHANNEL_NUM )
|
||||
) u_multi_ch_add_ppl_i (
|
||||
// clock & reset
|
||||
.clk (clk ),
|
||||
.rst (rst ),
|
||||
|
||||
// input data
|
||||
.din_valid (weight_adc_valid ),
|
||||
.din_data (weight_adc_real ),
|
||||
|
||||
// output data
|
||||
.dout_valid (weight_adc_sum_valid ),
|
||||
.dout_data (weight_adc_sum_real )
|
||||
);
|
||||
|
||||
adder_tree_ppl #(
|
||||
.DATA_I_WIDTH (FILTER_MULT_VALID_WIDTH),
|
||||
.DATA_NUM (CHANNEL_NUM )
|
||||
) u_multi_ch_add_ppl_q (
|
||||
// clock & reset
|
||||
.clk (clk ),
|
||||
.rst (rst ),
|
||||
|
||||
// input data
|
||||
.din_valid (weight_adc_valid ),
|
||||
.din_data (weight_adc_imag ),
|
||||
|
||||
// output data
|
||||
.dout_valid ( ),
|
||||
.dout_data (weight_adc_sum_imag )
|
||||
);
|
||||
|
||||
// output filtered signal
|
||||
assign dout_valid = weight_adc_sum_valid;
|
||||
|
||||
if (FILTER_O_WIDTH <= FILTER_SUM_WIDTH) begin
|
||||
assign dout_real = weight_adc_sum_real[FILTER_SUM_WIDTH-1 -: FILTER_O_WIDTH];
|
||||
assign dout_imag = weight_adc_sum_imag[FILTER_SUM_WIDTH-1 -: FILTER_O_WIDTH];
|
||||
end
|
||||
else begin
|
||||
assign dout_real = {{(FILTER_O_WIDTH-FILTER_SUM_WIDTH){weight_adc_sum_real[FILTER_SUM_WIDTH-1]}},weight_adc_sum_real};
|
||||
assign dout_imag = {{(FILTER_O_WIDTH-FILTER_SUM_WIDTH){weight_adc_sum_imag[FILTER_SUM_WIDTH-1]}},weight_adc_sum_imag};
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// This module has been tested during the simulation of [rx_pre_process]
|
||||
@@ -1,410 +0,0 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/11/10 11:48:23
|
||||
// Design Name:
|
||||
// Module Name: weight_vec_formatting
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Format the input 1-bit stream to weight vector.
|
||||
// Parameter:
|
||||
// COL_NUM: Column number of output vector.
|
||||
// WEIGHT_WIDTH: Bit width of input weight vector element (retrieve from
|
||||
// stream data).
|
||||
// DATA_O_WIDTH: Bit width of output vector element, and bit width of
|
||||
// FRAME_HEAD: Frame head indicate weight vector frame.
|
||||
// FIFO_CDC_DEPTH: Depth of [clk_96m] to [sys_clk] cdc fifo.
|
||||
// Data format:
|
||||
// din_data: Suppose the output vector x = [x11 x21 x31 x41]^T, then
|
||||
// din_data = {FRAME_HEAD[msb], ..., FRAME_HEAD[lsb], FRAME_LEN[msb],
|
||||
// ..., FRAME_LEN[lsb], Re{x11}[msb], ..., Re{x11}[lsb], Im{x11}[msb], ...,
|
||||
// Im{x11}[lsb], ..., Re{x41}[msb], ......, Im{x41}[lsb]}
|
||||
// dout_valid: Indicate [dout_data] is valid.
|
||||
// dout_real/imag:
|
||||
// dout_real = {Re{x41}, Re{x31}, Re{x21}, Re{x11}}
|
||||
// dout_imag = {Im{x41}, Im{x31}, Im{x21}, Im{x11}}
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module weight_vec_formatting
|
||||
#(
|
||||
parameter COL_NUM = 4,
|
||||
parameter WEIGHT_WIDTH = 32,
|
||||
parameter DATA_O_WIDTH = 16,
|
||||
parameter FRAME_HEAD = 32'h7E7E7E7E,
|
||||
parameter FIFO_CDC_DEPTH = 32
|
||||
)
|
||||
(
|
||||
// clock & reset
|
||||
input sys_clk,
|
||||
input sys_rst,
|
||||
input clk_96m,
|
||||
input ant_rst,
|
||||
|
||||
// input data
|
||||
input din_data,
|
||||
|
||||
input fifo_cdc_rst,
|
||||
|
||||
// output data
|
||||
output dout_valid,
|
||||
output [COL_NUM*DATA_O_WIDTH-1 : 0] dout_real,
|
||||
output [COL_NUM*DATA_O_WIDTH-1 : 0] dout_imag
|
||||
);
|
||||
|
||||
localparam CMPLX_DIM = 2;
|
||||
localparam FRAME_LEN = COL_NUM*CMPLX_DIM;
|
||||
localparam BYTE_LEN = 4 * (COL_NUM*CMPLX_DIM + 2);
|
||||
|
||||
// available state
|
||||
localparam STATE_NUM_DIN = 3;
|
||||
localparam STATE_IDLE_DIN = 0;
|
||||
localparam STATE_LEN_DIN = 1;
|
||||
localparam STATE_DATA_DIN = 2;
|
||||
|
||||
localparam STATE_NUM_DOUT = 2;
|
||||
localparam STATE_IDLE_DOUT = 0;
|
||||
localparam STATE_READ_DOUT = 1;
|
||||
|
||||
genvar i;
|
||||
integer m;
|
||||
|
||||
// input data shift register
|
||||
reg [WEIGHT_WIDTH-1 : 0] din_shift = 'b0;
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
din_shift <= 'b0;
|
||||
end
|
||||
else begin
|
||||
din_shift <= {din_shift[WEIGHT_WIDTH-2 : 0],din_data};
|
||||
end
|
||||
end
|
||||
|
||||
// input data center state machine & counter
|
||||
reg [$clog2(STATE_NUM_DIN)-1 : 0] state_din = STATE_IDLE_DIN;
|
||||
reg [$clog2(WEIGHT_WIDTH)-1 : 0] bit_cnt = 'b0; // bit counter within one frame
|
||||
reg [$clog2(FRAME_LEN)-1 : 0] frame_cnt = 'b0; // frame counter
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
state_din <= STATE_IDLE_DIN;
|
||||
end
|
||||
else begin
|
||||
case (state_din)
|
||||
STATE_IDLE_DIN: state_din <= (din_shift == FRAME_HEAD) ? STATE_LEN_DIN : STATE_IDLE_DIN;
|
||||
STATE_LEN_DIN : begin
|
||||
if (bit_cnt == WEIGHT_WIDTH-1) begin
|
||||
state_din <= (din_shift == BYTE_LEN) ? STATE_DATA_DIN : STATE_IDLE_DIN;
|
||||
end
|
||||
else begin
|
||||
state_din <= STATE_LEN_DIN;
|
||||
end
|
||||
end
|
||||
STATE_DATA_DIN: state_din <= (frame_cnt == FRAME_LEN-1 && bit_cnt == WEIGHT_WIDTH-1) ? STATE_IDLE_DIN : STATE_DATA_DIN;
|
||||
default: state_din <= STATE_IDLE_DIN;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
bit_cnt <= 'b0;
|
||||
end
|
||||
else if (state_din == STATE_IDLE_DIN) begin
|
||||
bit_cnt <= 'b0;
|
||||
end
|
||||
else begin
|
||||
bit_cnt <= (bit_cnt == WEIGHT_WIDTH-1) ? 'b0 : bit_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
frame_cnt <= 'b0;
|
||||
end
|
||||
else if (state_din == STATE_IDLE_DIN) begin
|
||||
frame_cnt <= 'b0;
|
||||
end
|
||||
else if (state_din == STATE_DATA_DIN && bit_cnt == WEIGHT_WIDTH-1) begin
|
||||
frame_cnt <= frame_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
frame_cnt <= frame_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
// clock domain crossing fifo, write channel
|
||||
reg [DATA_O_WIDTH-1 : 0] fifo_din = 'b0;
|
||||
reg fifo_wr_en = 'b0;
|
||||
|
||||
always @(posedge clk_96m) begin
|
||||
if (ant_rst) begin
|
||||
fifo_din <= 'b0;
|
||||
fifo_wr_en <= 'b0;
|
||||
end
|
||||
else if (state_din == STATE_DATA_DIN && bit_cnt == DATA_O_WIDTH-1) begin
|
||||
fifo_din <= din_shift[DATA_O_WIDTH-1 -: DATA_O_WIDTH];
|
||||
fifo_wr_en <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_din <= fifo_din;
|
||||
fifo_wr_en <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// clock domain crossing fifo, read channel
|
||||
reg fifo_rd_en = 'b0;
|
||||
reg fifo_rd_en_d1 = 'b0;
|
||||
reg [$clog2(COL_NUM*CMPLX_DIM)-1 : 0] fifo_rd_cnt = 'b0;
|
||||
reg [$clog2(COL_NUM*CMPLX_DIM)-1 : 0] fifo_rd_cnt_d1 = 'b0; // read data latency
|
||||
reg fifo_rd_valid = 'b0;
|
||||
wire [DATA_O_WIDTH-1 : 0] fifo_dout;
|
||||
wire [$clog2(COL_NUM*CMPLX_DIM*2)-1 : 0] fifo_rd_num;
|
||||
wire fifo_full;
|
||||
wire fifo_empty;
|
||||
reg [DATA_O_WIDTH-1 : 0] dout_array_cdc [0 : COL_NUM*CMPLX_DIM-1];
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_rd_en <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_num == COL_NUM*CMPLX_DIM) begin
|
||||
fifo_rd_en <= 1'b1;
|
||||
end
|
||||
else if (fifo_rd_cnt == COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_rd_en <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_en <= fifo_rd_en;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_rd_en_d1 <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_en_d1 <= fifo_rd_en;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_rd_cnt <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_en) begin
|
||||
fifo_rd_cnt <= fifo_rd_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_cnt <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_rd_cnt_d1 <= 'b0;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_cnt_d1 <= fifo_rd_cnt;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
fifo_rd_valid <= 'b0;
|
||||
end
|
||||
else if (fifo_rd_cnt_d1 == COL_NUM*CMPLX_DIM-1) begin
|
||||
fifo_rd_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_valid <= 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
for (m = 0; m < COL_NUM*CMPLX_DIM; m = m + 1) begin
|
||||
dout_array_cdc[m] <= 'b0;
|
||||
end
|
||||
end
|
||||
else if (fifo_rd_en_d1) begin
|
||||
dout_array_cdc[fifo_rd_cnt_d1] <= fifo_dout;
|
||||
end
|
||||
else begin
|
||||
for (m = 0; m < COL_NUM*CMPLX_DIM; m = m + 1) begin
|
||||
dout_array_cdc[m] <= dout_array_cdc[m];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fifo_weight_cdc u_fifo_weight_cdc
|
||||
(
|
||||
.rst (fifo_cdc_rst ), // input wire rd_rst
|
||||
.wr_clk (clk_96m ), // input wire wr_clk
|
||||
.rd_clk (sys_clk ), // input wire rd_clk
|
||||
.din (fifo_din ), // input wire [15 : 0] din
|
||||
.wr_en (fifo_wr_en ), // input wire wr_en
|
||||
.rd_en (fifo_rd_en ), // input wire rd_en
|
||||
.dout (fifo_dout ), // output wire [15 : 0] dout
|
||||
.full (fifo_full ), // output wire full
|
||||
.empty (fifo_empty ), // output wire empty
|
||||
.rd_data_count (fifo_rd_num ) // output wire [3 : 0] rd_data_count
|
||||
);
|
||||
|
||||
// format output data array
|
||||
wire [DATA_O_WIDTH-1 : 0] dout_real_array [0 : COL_NUM-1];
|
||||
wire [DATA_O_WIDTH-1 : 0] dout_imag_array [0 : COL_NUM-1];
|
||||
|
||||
generate
|
||||
for(i = 0; i < COL_NUM; i = i + 1) begin: array_convert_stg1
|
||||
assign dout_real_array[i] = dout_array_cdc[2*i];
|
||||
assign dout_imag_array[i] = dout_array_cdc[2*i+1];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i = 0; i < COL_NUM; i = i + 1) begin: array_convert_stg2
|
||||
assign dout_real[i*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_real_array[i];
|
||||
assign dout_imag[i*DATA_O_WIDTH +: DATA_O_WIDTH] = dout_imag_array[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign dout_valid = fifo_rd_valid;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 2022/10/30 20:46:26
|
||||
// Design Name:
|
||||
// Module Name: tb_wvec_format
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description: Testbench for [weight_vec_formatting]
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// MATLAB Code for data generation
|
||||
// -------------------------------
|
||||
// COLUMN_NUM = 4;
|
||||
// DATA_O_WIDTH = 32;
|
||||
|
||||
// rng(0);
|
||||
// data = rand(4,2)*2-1;
|
||||
// d_32b = round(data.*(2^(DATA_O_WIDTH-1)-1));
|
||||
// d_32b_cmplx = d_32b(:,1) + 1i*d_32b(:,2);
|
||||
|
||||
|
||||
// module tb_wvec_format;
|
||||
|
||||
// localparam ROW_NUM = 1;
|
||||
// localparam COL_NUM = 4;
|
||||
// localparam WEIGHT_WIDTH = 32;
|
||||
// localparam DATA_O_WIDTH = 16;
|
||||
// localparam FRAME_HEAD = 32'b10110011100011110000111000110010;
|
||||
// localparam FRAME_BITS = (2+COL_NUM*2)*WEIGHT_WIDTH + 1024;
|
||||
|
||||
// reg sys_clk = 1'b1;
|
||||
// reg sys_rst = 1'b1;
|
||||
// reg clk_96m = 1'b1;
|
||||
// reg ant_rst = 1'b1;
|
||||
// wire din_data;
|
||||
// reg [FRAME_BITS-1 : 0] din_buf =
|
||||
// {
|
||||
// FRAME_HEAD, 32'd40,
|
||||
// 32'd1351727940, 32'd568478634,
|
||||
// 32'd1742863098, -32'd1728550798,
|
||||
// -32'd1602079424, -32'd951342906,
|
||||
// 32'd1775435782, 32'd201354592,
|
||||
// 1024'd0
|
||||
// };
|
||||
|
||||
|
||||
// wire dout_valid;
|
||||
// wire [COL_NUM*DATA_O_WIDTH-1:0] dout_real, dout_imag;
|
||||
|
||||
// weight_vec_formatting #(
|
||||
// .COL_NUM (COL_NUM),
|
||||
// .DATA_O_WIDTH (DATA_O_WIDTH),
|
||||
// .WEIGHT_WIDTH (WEIGHT_WIDTH),
|
||||
// .FRAME_HEAD (FRAME_HEAD )
|
||||
// ) u_weight_vec_formatting
|
||||
// (
|
||||
// // clock & reset
|
||||
// .sys_clk (sys_clk ), // input sys_clk
|
||||
// .sys_rst (sys_rst ), // input sys_rst
|
||||
// .clk_96m (clk_96m ), // input clk_96m
|
||||
// .ant_rst (ant_rst ), // input ant_rst
|
||||
|
||||
// // input data
|
||||
// .din_data (din_data ),
|
||||
|
||||
// // output data
|
||||
// .dout_valid (dout_valid ),
|
||||
// .dout_real (dout_real ),
|
||||
// .dout_imag (dout_imag )
|
||||
// );
|
||||
|
||||
// always begin
|
||||
// #20 sys_clk = ~sys_clk;
|
||||
// end
|
||||
|
||||
// always begin
|
||||
// #7;
|
||||
// clk_96m = ~clk_96m;
|
||||
// #3;
|
||||
// end
|
||||
|
||||
// initial begin
|
||||
// #102
|
||||
// sys_rst = 1'b0;
|
||||
// ant_rst = 1'b0;
|
||||
// end
|
||||
|
||||
// reg [$clog2(FRAME_BITS)-1 : 0] din_cnt;
|
||||
|
||||
// always @(posedge clk_96m) begin
|
||||
// if (sys_rst) begin
|
||||
// din_cnt <= 'b0;
|
||||
// end
|
||||
// else begin
|
||||
// din_cnt <= (din_cnt == FRAME_BITS-1) ? 'b0 : din_cnt + 1'b1;
|
||||
// end
|
||||
// end
|
||||
|
||||
// assign din_data = din_buf[FRAME_BITS-1-din_cnt];
|
||||
|
||||
// endmodule
|
||||
@@ -444,6 +444,38 @@ always @(posedge clk_96m) begin
|
||||
end
|
||||
end
|
||||
|
||||
// rf auto switch frequency function
|
||||
wire rf_auto_start_vio ;
|
||||
wire rf_ctrl_mode_vio ;
|
||||
wire switch_next_freq_vio;
|
||||
wire switch_last_freq_vio;
|
||||
wire [15:0] cnt_valid_to_switch_vio;
|
||||
|
||||
wire vio_switch;
|
||||
wire vio_switch_auto;
|
||||
wire [15:0] vio_frequency;
|
||||
wire [15:0] vio_frequency_auto;
|
||||
wire hop_words_valid_auto;
|
||||
|
||||
rf_auto_switch_freq u_rf_auto_switch_freq(
|
||||
.clk (clk_48m ),
|
||||
.rst (sys_rst ),
|
||||
// vio control
|
||||
.start (rf_auto_start_vio ), // rise-edge active, if start, change freq word to the first
|
||||
.rf_ctrl_mode (rf_ctrl_mode_vio ), // 1 : auto switch, 0 : manual switch
|
||||
.switch_next_freq (switch_next_freq_vio ), // rise-edge active
|
||||
.switch_last_freq (switch_last_freq_vio ), // rise-edge active
|
||||
.cnt_valid_to_switch (cnt_valid_to_switch_vio ),
|
||||
// input
|
||||
.freq_hop_words_vio (vio_frequency[15:0] ),
|
||||
.hop_words_valid_vio (1'b0 ),
|
||||
.freq_hop_switch_vio (vio_switch ),
|
||||
// output
|
||||
.freq_hop_words_auto (vio_frequency_auto[15:0] ),
|
||||
.hop_words_valid_auto (hop_words_valid_auto ),
|
||||
.freq_hop_switch_auto (vio_switch_auto )
|
||||
);
|
||||
|
||||
ant_rf_ctrl u_ant_rf_ctrl
|
||||
(
|
||||
.clk_48m (clk_48m ), // input clk_48m
|
||||
@@ -495,6 +527,8 @@ ant_rf_ctrl u_ant_rf_ctrl
|
||||
.rf_sw_rx (rf_sw_rx ) // output rf_sw_rx
|
||||
);
|
||||
|
||||
assign u_ant_rf_ctrl.vio_switch = vio_switch_auto ;
|
||||
assign u_ant_rf_ctrl.vio_frequency = vio_frequency_auto;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////// LVDS for Time Synchronization /////////////////////////
|
||||
@@ -542,10 +576,10 @@ tx_pre_process #(
|
||||
.clk (sys_clk ),
|
||||
.rst (sys_rst ),
|
||||
// input data
|
||||
.tx_data_ch1_i (tx_data_i ),
|
||||
.tx_data_ch1_q (tx_data_q ),
|
||||
.tx_data_ch2_i (tx_data_i ),
|
||||
.tx_data_ch2_q (tx_data_q ),
|
||||
.tx_data_ch1_i (tx_ch1_i ),
|
||||
.tx_data_ch1_q (tx_ch1_q ),
|
||||
.tx_data_ch2_i (tx_ch2_i ),
|
||||
.tx_data_ch2_q (tx_ch2_q ),
|
||||
// ad9361 calibration interface
|
||||
.ad9361_tx_switch (ad9361_tx_switch ),
|
||||
//
|
||||
@@ -583,68 +617,21 @@ tx_qpsk u_tx_qpsk
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////// Rx Signals //////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
reg [11:0] rx_ch1_i, rx_ch1_q;
|
||||
reg [11:0] rx_ch2_i, rx_ch2_q;
|
||||
reg [11:0] rx_ch3_i, rx_ch3_q;
|
||||
reg [11:0] rx_ch4_i, rx_ch4_q;
|
||||
wire [11:0] rx_ch1_i, rx_ch1_q;
|
||||
wire [11:0] rx_ch2_i, rx_ch2_q;
|
||||
wire [11:0] rx_ch3_i, rx_ch3_q;
|
||||
wire [11:0] rx_ch4_i, rx_ch4_q;
|
||||
|
||||
wire [11:0] rx_ch1_i_9361, rx_ch1_q_9361;
|
||||
wire [11:0] rx_ch2_i_9361, rx_ch2_q_9361;
|
||||
wire [11:0] rx_ch3_i_9361, rx_ch3_q_9361;
|
||||
wire [11:0] rx_ch4_i_9361, rx_ch4_q_9361;
|
||||
|
||||
wire [11:0] rx_ch1_i_test, rx_ch1_q_test;
|
||||
wire [11:0] rx_ch2_i_test, rx_ch2_q_test;
|
||||
wire [11:0] rx_ch3_i_test, rx_ch3_q_test;
|
||||
wire [11:0] rx_ch4_i_test, rx_ch4_q_test;
|
||||
wire [11:0] rx_cal_ch1_i, rx_cal_ch1_q;
|
||||
wire [11:0] rx_cal_ch2_i, rx_cal_ch2_q;
|
||||
wire [11:0] rx_cal_ch3_i, rx_cal_ch3_q;
|
||||
wire [11:0] rx_cal_ch4_i, rx_cal_ch4_q;
|
||||
|
||||
wire [15:0] phase_ch1, phase_ch2, phase_ch3, phase_ch4;
|
||||
|
||||
wire rx_data_valid;
|
||||
wire [29:0] rx_data_i, rx_data_q;
|
||||
|
||||
wire hop_trigger;
|
||||
wire hop_trigger_en;
|
||||
wire rx_test_en;
|
||||
|
||||
wire hop_start_flag ;
|
||||
// wire accor_stream_valid ;
|
||||
// wire accor_stream_data ;
|
||||
// wire weight_stream_data ;
|
||||
|
||||
always @(posedge sys_clk) begin
|
||||
if (sys_rst) begin
|
||||
rx_ch1_i <= 'b0;
|
||||
rx_ch2_i <= 'b0;
|
||||
rx_ch3_i <= 'b0;
|
||||
rx_ch4_i <= 'b0;
|
||||
rx_ch1_q <= 'b0;
|
||||
rx_ch2_q <= 'b0;
|
||||
rx_ch3_q <= 'b0;
|
||||
rx_ch4_q <= 'b0;
|
||||
end
|
||||
else if (rx_test_en && ad9361_cal_valid) begin
|
||||
rx_ch1_i <= rx_ch1_i_test;
|
||||
rx_ch2_i <= rx_ch2_i_test;
|
||||
rx_ch3_i <= rx_ch3_i_test;
|
||||
rx_ch4_i <= rx_ch4_i_test;
|
||||
rx_ch1_q <= rx_ch1_q_test;
|
||||
rx_ch2_q <= rx_ch2_q_test;
|
||||
rx_ch3_q <= rx_ch3_q_test;
|
||||
rx_ch4_q <= rx_ch4_q_test;
|
||||
end
|
||||
else begin
|
||||
rx_ch1_i <= rx_ch1_i_9361;
|
||||
rx_ch2_i <= rx_ch2_i_9361;
|
||||
rx_ch3_i <= rx_ch3_i_9361;
|
||||
rx_ch4_i <= rx_ch4_i_9361;
|
||||
rx_ch1_q <= rx_ch1_q_9361;
|
||||
rx_ch2_q <= rx_ch2_q_9361;
|
||||
rx_ch3_q <= rx_ch3_q_9361;
|
||||
rx_ch4_q <= rx_ch4_q_9361;
|
||||
end
|
||||
end
|
||||
|
||||
ad9361_rx_map_cmos_dual u_ad9361_1_rx_map
|
||||
(
|
||||
.clk_2x_in (ad9361_1_clk_2x ), // input clk_2x_in
|
||||
@@ -657,10 +644,10 @@ ad9361_rx_map_cmos_dual u_ad9361_1_rx_map
|
||||
|
||||
.rx_frame (ad9361_1_rx_frame ), // input rx_frame
|
||||
.rx_data (ad9361_1_rx_data ), // input [11:0] rx_data
|
||||
.rx_ch1_i (rx_ch1_i_9361 ), // output [11:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch1_q_9361 ), // output [11:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch2_i_9361 ), // output [11:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch2_q_9361 ) // output [11:0] rx_ch2_q
|
||||
.rx_ch1_i (rx_ch1_i ), // output [11:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch1_q ), // output [11:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch2_i ), // output [11:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch2_q ) // output [11:0] rx_ch2_q
|
||||
);
|
||||
|
||||
ad9361_rx_map_cmos_dual u_ad9361_2_rx_map
|
||||
@@ -675,82 +662,131 @@ ad9361_rx_map_cmos_dual u_ad9361_2_rx_map
|
||||
|
||||
.rx_frame (ad9361_2_rx_frame ), // input rx_frame
|
||||
.rx_data (ad9361_2_rx_data ), // input [11:0] rx_data
|
||||
.rx_ch1_i (rx_ch3_i_9361 ), // output [11:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch3_q_9361 ), // output [11:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch4_i_9361 ), // output [11:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch4_q_9361 ) // output [11:0] rx_ch2_q
|
||||
.rx_ch1_i (rx_ch3_i ), // output [11:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch3_q ), // output [11:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch4_i ), // output [11:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch4_q ) // output [11:0] rx_ch2_q
|
||||
);
|
||||
|
||||
rx_pre_process #(
|
||||
.OUTPUT_DATA_WIDTH (30 )
|
||||
) u_rx_pre_process
|
||||
ad9361_phase_cal_coarse u_ad9361_phase_cal
|
||||
(
|
||||
// clock & reset
|
||||
.sys_clk (sys_clk ), // sync to adc data
|
||||
.sys_clk_4x (sys_clk_4x ), // sync to physical layer
|
||||
.sys_rst (sys_rst ), // sync to [sys_clk]
|
||||
.clk_96m (clk_96m ), // sync to c2c data
|
||||
.ant_rst (ant_rst ), // sync to [clk_96m]
|
||||
.clk (sys_clk ), // input clk
|
||||
.rst (sys_rst ), // input rst
|
||||
// control interface
|
||||
.ad9361_1_cal_start (ad9361_1_cal_start ), // input ad9361_1_cal_start
|
||||
.ad9361_1_cal_done (ad9361_1_cal_done ), // output ad9361_1_cal_done
|
||||
.ad9361_2_cal_start (ad9361_2_cal_start ), // input ad9361_2_cal_start
|
||||
.ad9361_2_cal_done (ad9361_2_cal_done ), // output ad9361_2_cal_done
|
||||
.ad9361_cal_result (ad9361_cal_result ), // output ad9361_cal_result
|
||||
.ad9361_cal_valid (ad9361_cal_valid ), // output ad9361_cal_valid
|
||||
.ad9361_recal (ad9361_recal ), // input ad9361_recal
|
||||
// input data interface
|
||||
.rx_ch1_i (rx_ch1_i ),
|
||||
.rx_ch1_q (rx_ch1_q ),
|
||||
.rx_ch2_i (rx_ch2_i ),
|
||||
.rx_ch2_q (rx_ch2_q ),
|
||||
.rx_ch3_i (rx_ch3_i ),
|
||||
.rx_ch3_q (rx_ch3_q ),
|
||||
.rx_ch4_i (rx_ch4_i ),
|
||||
.rx_ch4_q (rx_ch4_q ),
|
||||
// input phase
|
||||
.phase_ch1 (phase_ch1 ),
|
||||
.phase_ch2 (phase_ch2 ),
|
||||
.phase_ch3 (phase_ch3 ),
|
||||
.phase_ch4 (phase_ch4 ),
|
||||
// ad9361 calibration interface
|
||||
.ad9361_1_cal_start (ad9361_1_cal_start ),
|
||||
.ad9361_1_cal_done (ad9361_1_cal_done ),
|
||||
.ad9361_2_cal_start (ad9361_2_cal_start ),
|
||||
.ad9361_2_cal_done (ad9361_2_cal_done ),
|
||||
.ad9361_cal_result (ad9361_cal_result ),
|
||||
.ad9361_cal_valid (ad9361_cal_valid ),
|
||||
.ad9361_recal (ad9361_recal ),
|
||||
// nulling algorithm interface
|
||||
.hop_start_flag (hop_start_flag ), // sync to [sys_clk_4x]
|
||||
.accor_stream_valid (accor_stream_valid ), // sync to [clk_96m]
|
||||
.accor_stream_data (accor_stream_data ), // sync to [clk_96m]
|
||||
.weight_stream_data (weight_stream_data ), // sync to [clk_96m]
|
||||
.rx_data_valid (rx_data_valid ), // sync to [sys_clk]
|
||||
.rx_data_i (rx_data_i ), // sync to [sys_clk]
|
||||
.rx_data_q (rx_data_q ) // sync to [sys_clk]
|
||||
);
|
||||
|
||||
// temporary test cases
|
||||
rx_pre_test u_rx_pre_test
|
||||
(
|
||||
// clock & reset
|
||||
.sys_clk (sys_clk ),
|
||||
.sys_clk_4x (sys_clk_4x ),
|
||||
.sys_rst (sys_rst ),
|
||||
.hop_trigger (hop_trigger ),
|
||||
.hop_trigger_en (hop_trigger_en ),
|
||||
// calc result
|
||||
.ad9361_cal_result (ad9361_cal_result ),
|
||||
.ad9361_cal_valid (ad9361_cal_valid ),
|
||||
// output test data
|
||||
.rx_ch1_i (rx_ch1_i_test ),
|
||||
.rx_ch1_q (rx_ch1_q_test ),
|
||||
.rx_ch2_i (rx_ch2_i_test ),
|
||||
.rx_ch2_q (rx_ch2_q_test ),
|
||||
.rx_ch3_i (rx_ch3_i_test ),
|
||||
.rx_ch3_q (rx_ch3_q_test ),
|
||||
.rx_ch4_i (rx_ch4_i_test ),
|
||||
.rx_ch4_q (rx_ch4_q_test ),
|
||||
.hop_start_flag (hop_start_flag )
|
||||
.rx_ch1_i (rx_ch1_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch1_i
|
||||
.rx_ch1_q (rx_ch1_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch1_q
|
||||
.rx_ch2_i (rx_ch2_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch2_i
|
||||
.rx_ch2_q (rx_ch2_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch2_q
|
||||
.rx_ch3_i (rx_ch3_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch3_i
|
||||
.rx_ch3_q (rx_ch3_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch3_q
|
||||
.rx_ch4_i (rx_ch4_i ), // input [ADC_DATA_WIDTH-1:0] rx_ch4_i
|
||||
.rx_ch4_q (rx_ch4_q ), // input [ADC_DATA_WIDTH-1:0] rx_ch4_q
|
||||
// output data interface
|
||||
.rx_cal_ch1_i (rx_cal_ch1_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch1_i
|
||||
.rx_cal_ch1_q (rx_cal_ch1_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch1_q
|
||||
.rx_cal_ch2_i (rx_cal_ch2_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch2_i
|
||||
.rx_cal_ch2_q (rx_cal_ch2_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch2_q
|
||||
.rx_cal_ch3_i (rx_cal_ch3_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch3_i
|
||||
.rx_cal_ch3_q (rx_cal_ch3_q ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch3_q
|
||||
.rx_cal_ch4_i (rx_cal_ch4_i ), // output [ADC_DATA_WIDTH-1:0] rx_cal_ch4_i
|
||||
.rx_cal_ch4_q (rx_cal_ch4_q ) // output [ADC_DATA_WIDTH-1:0] rx_cal_ch4_q
|
||||
);
|
||||
|
||||
// <--------------------------------------------------------------------------->
|
||||
// <----------------------- insert receiver logic below ----------------------->
|
||||
// <--------------------------------------------------------------------------->
|
||||
wire freq_comp_start ;
|
||||
wire freq_comp_busy ;
|
||||
wire [7:0] dmf_num_per_ch ;
|
||||
wire [31:0] freq_manual ;
|
||||
wire freq_manual_en ;
|
||||
wire [31:0] freq_target ;
|
||||
wire freq_target_valid;
|
||||
|
||||
wire ch_peak_valid ;
|
||||
wire [17:0] ch1_peak_value_abs ;
|
||||
wire [17:0] ch1_peak_value_i ;
|
||||
wire [17:0] ch1_peak_value_q ;
|
||||
wire [ 9:0] ch1_peak_index ;
|
||||
wire [17:0] ch2_peak_value_abs ;
|
||||
wire [17:0] ch2_peak_value_i ;
|
||||
wire [17:0] ch2_peak_value_q ;
|
||||
wire [ 9:0] ch2_peak_index ;
|
||||
wire [17:0] ch3_peak_value_abs ;
|
||||
wire [17:0] ch3_peak_value_i ;
|
||||
wire [17:0] ch3_peak_value_q ;
|
||||
wire [ 9:0] ch3_peak_index ;
|
||||
wire [17:0] ch4_peak_value_abs ;
|
||||
wire [17:0] ch4_peak_value_i ;
|
||||
wire [17:0] ch4_peak_value_q ;
|
||||
wire [ 9:0] ch4_peak_index ;
|
||||
|
||||
freq_comp #(
|
||||
.FREQ_WORD_LOWER (-4194304 ),
|
||||
.FREQ_WORD_UPPER (4194303 ),
|
||||
.FREQ_WORD_STEP (1024 )
|
||||
) u_freq_comp
|
||||
(
|
||||
// clock & reset
|
||||
.clk (sys_clk ), // input clk
|
||||
.rst (sys_rst ), // input rst
|
||||
|
||||
// input data
|
||||
.freq_comp_start (freq_comp_start ), // input freq_comp_start
|
||||
.freq_comp_busy (freq_comp_busy ), // output freq_comp_busy
|
||||
|
||||
.rx_data_valid (ad9361_cal_valid ), // input rx_data_valid
|
||||
.rx_ch1_i (rx_cal_ch1_i ), // input [DATA_I_WIDTH-1 : 0] rx_ch1_i
|
||||
.rx_ch1_q (rx_cal_ch1_q ), // input [DATA_I_WIDTH-1 : 0] rx_ch1_q
|
||||
.rx_ch2_i (rx_cal_ch2_i ), // input [DATA_I_WIDTH-1 : 0] rx_ch2_i
|
||||
.rx_ch2_q (rx_cal_ch2_q ), // input [DATA_I_WIDTH-1 : 0] rx_ch2_q
|
||||
.rx_ch3_i (rx_cal_ch3_i ), // input [DATA_I_WIDTH-1 : 0] rx_ch3_i
|
||||
.rx_ch3_q (rx_cal_ch3_q ), // input [DATA_I_WIDTH-1 : 0] rx_ch3_q
|
||||
.rx_ch4_i (rx_cal_ch4_i ), // input [DATA_I_WIDTH-1 : 0] rx_ch4_i
|
||||
.rx_ch4_q (rx_cal_ch4_q ), // input [DATA_I_WIDTH-1 : 0] rx_ch4_q
|
||||
|
||||
// configuration
|
||||
.dmf_num_per_ch (dmf_num_per_ch ), // input [$clog2(MAX_DMF_NUM)-1 : 0] dmf_num_per_ch
|
||||
|
||||
.freq_manual (freq_manual ), // input [FREQ_WORD_WIDTH-1 : 0] freq_manual
|
||||
.freq_manual_en (freq_manual_en ), // input freq_manual_en
|
||||
|
||||
// output frequency result
|
||||
.freq_target (freq_target ), // output [FREQ_WORD_WIDTH-1 : 0] freq_target
|
||||
.freq_target_valid (freq_target_valid ), // output freq_target_valid
|
||||
|
||||
// output dmf result
|
||||
.ch_peak_valid (ch_peak_valid ), // output ch_peak_valid
|
||||
|
||||
.ch1_peak_value_abs (ch1_peak_value_abs ), // output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_abs
|
||||
.ch1_peak_value_i (ch1_peak_value_i ), // output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_i
|
||||
.ch1_peak_value_q (ch1_peak_value_q ), // output reg [DATA_O_WIDTH-1 : 0] ch1_peak_value_q
|
||||
.ch1_peak_index (ch1_peak_index ), // output reg [$clog2(PRBS_POS-1) : 0] ch1_peak_index
|
||||
|
||||
.ch2_peak_value_abs (ch2_peak_value_abs ), // output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_abs
|
||||
.ch2_peak_value_i (ch2_peak_value_i ), // output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_i
|
||||
.ch2_peak_value_q (ch2_peak_value_q ), // output reg [DATA_O_WIDTH-1 : 0] ch2_peak_value_q
|
||||
.ch2_peak_index (ch2_peak_index ), // output reg [$clog2(PRBS_POS-1) : 0] ch2_peak_index
|
||||
|
||||
.ch3_peak_value_abs (ch3_peak_value_abs ), // output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_abs
|
||||
.ch3_peak_value_i (ch3_peak_value_i ), // output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_i
|
||||
.ch3_peak_value_q (ch3_peak_value_q ), // output reg [DATA_O_WIDTH-1 : 0] ch3_peak_value_q
|
||||
.ch3_peak_index (ch3_peak_index ), // output reg [$clog2(PRBS_POS-1) : 0] ch3_peak_index
|
||||
|
||||
.ch4_peak_value_abs (ch4_peak_value_abs ), // output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_abs
|
||||
.ch4_peak_value_i (ch4_peak_value_i ), // output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_i
|
||||
.ch4_peak_value_q (ch4_peak_value_q ), // output reg [DATA_O_WIDTH-1 : 0] ch4_peak_value_q
|
||||
.ch4_peak_index (ch4_peak_index ) // output reg [$clog2(PRBS_POS-1) : 0] ch4_peak_index
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// ILAs and VIOs /////////////////////////////////
|
||||
@@ -765,9 +801,9 @@ rx_pre_test u_rx_pre_test
|
||||
vio_rfcontrl u_vio_rfcontrl
|
||||
(
|
||||
.clk (clk_48m ), // input wire clk
|
||||
.probe_out0 (u_ant_rf_ctrl.vio_switch ), // output wire [0 : 0] probe_out0
|
||||
.probe_out0 (vio_switch ), // output wire [0 : 0] probe_out0
|
||||
.probe_out1 (u_ant_rf_ctrl.vio_trdirection ), // output wire [0 : 0] probe_out1
|
||||
.probe_out2 (u_ant_rf_ctrl.vio_frequency[15:0] ), // output wire [15 : 0] probe_out2
|
||||
.probe_out2 (vio_frequency[15:0] ), // output wire [15 : 0] probe_out2
|
||||
.probe_out3 (u_ant_rf_ctrl.vio_emitMGC[7:0] ), // output wire [7 : 0] probe_out3
|
||||
.probe_out4 (u_ant_rf_ctrl.vio_ch01MGC[3:0] ), // output wire [3 : 0] probe_out4
|
||||
.probe_out5 (u_ant_rf_ctrl.vio_ch02MGC[3:0] ), // output wire [3 : 0] probe_out5
|
||||
@@ -777,7 +813,13 @@ vio_rfcontrl u_vio_rfcontrl
|
||||
.probe_out9 (u_ant_rf_ctrl.vio_AntMod[7:0] ), // output wire [7 : 0] probe_out9
|
||||
.probe_out10(u_ant_rf_ctrl.vio_AntOffAxis[15:0] ), // output wire [15 : 0] probe_out10
|
||||
.probe_out11(u_ant_rf_ctrl.vio_AntYaw[15:0] ), // output wire [15 : 0] probe_out11
|
||||
.probe_out12(u_ant_rf_ctrl.vio_PrecessTime[15:0] ) // output wire [15 : 0] probe_out12
|
||||
.probe_out12(u_ant_rf_ctrl.vio_PrecessTime[15:0] ), // output wire [15 : 0] probe_out12
|
||||
.probe_out13(rf_auto_start_vio ), // output wire [0 : 0] probe_out13
|
||||
.probe_out14(rf_ctrl_mode_vio ), // output wire [0 : 0] probe_out14
|
||||
.probe_out15(switch_next_freq_vio ), // output wire [0 : 0] probe_out15
|
||||
.probe_out16(switch_last_freq_vio ), // output wire [0 : 0] probe_out16
|
||||
.probe_out17(cnt_valid_to_switch_vio[15:0] ), // output wire [15: 0] probe_out17
|
||||
.probe_in0 (vio_frequency_auto[15:0] ) // input wire [10: 0] probe_in0
|
||||
);
|
||||
|
||||
vio_ant_test u_vio_ant_test
|
||||
@@ -893,70 +935,37 @@ ila_2x12x1024 u_ila_tx
|
||||
.probe1 (tx_ch1_q ) // input wire [11:0] probe1
|
||||
);
|
||||
|
||||
ila_8x12_2x30_8192 u_ila_rx
|
||||
ila_8x12_8192 u_ila_rx
|
||||
(
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (u_rx_pre_process.rx_cal_ch1_i ), // input wire [11:0] probe0
|
||||
.probe1 (u_rx_pre_process.rx_cal_ch1_q ), // input wire [11:0] probe1
|
||||
.probe2 (u_rx_pre_process.rx_cal_ch2_i ), // input wire [11:0] probe2
|
||||
.probe3 (u_rx_pre_process.rx_cal_ch2_q ), // input wire [11:0] probe3
|
||||
.probe4 (u_rx_pre_process.rx_cal_ch3_i ), // input wire [11:0] probe4
|
||||
.probe5 (u_rx_pre_process.rx_cal_ch3_q ), // input wire [11:0] probe5
|
||||
.probe6 (u_rx_pre_process.rx_cal_ch4_i ), // input wire [11:0] probe6
|
||||
.probe7 (u_rx_pre_process.rx_cal_ch4_q ), // input wire [11:0] probe7
|
||||
.probe8 (rx_data_i ), // input wire [29:0] probe8
|
||||
.probe9 (rx_data_q ) // input wire [29:0] probe9
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (rx_cal_ch1_i ), // input wire [11:0] probe0
|
||||
.probe1 (rx_cal_ch1_q ), // input wire [11:0] probe1
|
||||
.probe2 (rx_cal_ch2_i ), // input wire [11:0] probe2
|
||||
.probe3 (rx_cal_ch2_q ), // input wire [11:0] probe3
|
||||
.probe4 (rx_cal_ch3_i ), // input wire [11:0] probe4
|
||||
.probe5 (rx_cal_ch3_q ), // input wire [11:0] probe5
|
||||
.probe6 (rx_cal_ch4_i ), // input wire [11:0] probe6
|
||||
.probe7 (rx_cal_ch4_q ) // input wire [11:0] probe7
|
||||
);
|
||||
|
||||
ila_cal u_ila_cal
|
||||
(
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_1_cal_start_d2 ), // input wire [0:0] probe0
|
||||
.probe1 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_1_cal_done ), // input wire [0:0] probe1
|
||||
.probe2 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_2_cal_start_d2 ), // input wire [0:0] probe2
|
||||
.probe3 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_2_cal_done ), // input wire [0:0] probe3
|
||||
.probe4 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_cal_result ), // input wire [0:0] probe4
|
||||
.probe5 (u_rx_pre_process.u_ad9361_phase_cal.ad9361_recal_d2 ), // input wire [0:0] probe5
|
||||
.probe6 (u_rx_pre_process.u_ad9361_phase_cal.curr_state ), // input wire [1:0] probe6
|
||||
.probe7 (rx_ch2_i ), // input wire [11:0] probe7
|
||||
.probe8 (rx_ch2_q ), // input wire [11:0] probe8
|
||||
.probe9 (rx_ch4_i ), // input wire [11:0] probe9
|
||||
.probe10(rx_ch4_q ), // input wire [11:0] probe10
|
||||
.probe11(u_rx_pre_process.rx_cal_ch2_i ), // input wire [11:0] probe11
|
||||
.probe12(u_rx_pre_process.rx_cal_ch2_q ), // input wire [11:0] probe12
|
||||
.probe13(u_rx_pre_process.rx_cal_ch4_i ), // input wire [11:0] probe13
|
||||
.probe14(u_rx_pre_process.rx_cal_ch4_q ) // input wire [11:0] probe14
|
||||
);
|
||||
|
||||
ila_rx_pre_sys u_ila_rx_pre_sys
|
||||
(
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (u_rx_pre_process.hop_start_flag_cdc ), // input wire [0:0] probe0
|
||||
.probe1 (u_rx_pre_process.fifo_cdc_rst ), // input wire [0:0] probe1
|
||||
.probe2 (u_rx_pre_process.u_accor_mat_stream.fifo_wr_en ), // input wire [0:0] probe2
|
||||
.probe3 (u_rx_pre_process.u_accor_mat_stream.fifo_din ), // input wire [31:0] probe3
|
||||
.probe4 (u_rx_pre_process.u_accor_mat_stream.fifo_full ), // input wire [0:0] probe4
|
||||
.probe5 (u_rx_pre_process.u_weight_vec_formatting.fifo_rd_en ), // input wire [0:0] probe5
|
||||
.probe6 (u_rx_pre_process.u_weight_vec_formatting.fifo_dout ), // input wire [15:0] probe6
|
||||
.probe7 (u_rx_pre_process.u_weight_vec_formatting.fifo_empty ), // input wire [0:0] probe7
|
||||
.probe8 (u_rx_pre_process.u_weight_vec_formatting.fifo_rd_num ) // input wire [3:0] probe8
|
||||
);
|
||||
|
||||
ila_rx_pre_ant u_ila_rx_pre_ant
|
||||
(
|
||||
.clk (clk_96m ), // input wire clk
|
||||
.probe0 (u_rx_pre_process.hop_start_flag_cdc ), // input wire [0:0] probe0
|
||||
.probe1 (accor_stream_valid ), // input wire [0:0] probe1
|
||||
.probe2 (accor_stream_data ), // input wire [0:0] probe2
|
||||
.probe3 (weight_stream_data ), // input wire [0:0] probe3
|
||||
.probe4 (u_rx_pre_process.fifo_cdc_rst ), // input wire [0:0] probe4
|
||||
.probe5 (u_rx_pre_process.u_accor_mat_stream.fifo_rd_en ), // input wire [0:0] probe5
|
||||
.probe6 (u_rx_pre_process.u_accor_mat_stream.fifo_dout ), // input wire [31:0] probe6
|
||||
.probe7 (u_rx_pre_process.u_accor_mat_stream.fifo_empty ), // input wire [0:0] probe7
|
||||
.probe8 (u_rx_pre_process.u_accor_mat_stream.fifo_rd_num ), // input wire [4:0] probe8
|
||||
.probe9 (u_rx_pre_process.u_weight_vec_formatting.fifo_wr_en), // input wire [0:0] probe9
|
||||
.probe10(u_rx_pre_process.u_weight_vec_formatting.fifo_din ), // input wire [15:0] probe10
|
||||
.probe11(u_rx_pre_process.u_weight_vec_formatting.fifo_full ) // input wire [0:0] probe11
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (u_ad9361_phase_cal.ad9361_1_cal_start_d2 ), // input wire [0:0] probe0
|
||||
.probe1 (u_ad9361_phase_cal.ad9361_1_cal_done ), // input wire [0:0] probe1
|
||||
.probe2 (u_ad9361_phase_cal.ad9361_2_cal_start_d2 ), // input wire [0:0] probe2
|
||||
.probe3 (u_ad9361_phase_cal.ad9361_2_cal_done ), // input wire [0:0] probe3
|
||||
.probe4 (u_ad9361_phase_cal.ad9361_cal_result ), // input wire [0:0] probe4
|
||||
.probe5 (u_ad9361_phase_cal.ad9361_recal_d2 ), // input wire [0:0] probe5
|
||||
.probe6 (u_ad9361_phase_cal.curr_state ), // input wire [1:0] probe6
|
||||
.probe7 (rx_ch2_i ), // input wire [11:0] probe7
|
||||
.probe8 (rx_ch2_q ), // input wire [11:0] probe8
|
||||
.probe9 (rx_ch4_i ), // input wire [11:0] probe9
|
||||
.probe10(rx_ch4_q ), // input wire [11:0] probe10
|
||||
.probe11(rx_cal_ch2_i ), // input wire [11:0] probe11
|
||||
.probe12(rx_cal_ch2_q ), // input wire [11:0] probe12
|
||||
.probe13(rx_cal_ch4_i ), // input wire [11:0] probe13
|
||||
.probe14(rx_cal_ch4_q ) // input wire [11:0] probe14
|
||||
);
|
||||
|
||||
vio_manual_ctrl u_vio_manual_ctrl
|
||||
@@ -966,24 +975,44 @@ vio_manual_ctrl u_vio_manual_ctrl
|
||||
.probe_out1 (sweep_on ), // output wire [0 : 0] probe_out1
|
||||
.probe_out2 (freq_set[31:0] ), // output wire [31 : 0] probe_out2
|
||||
.probe_out3 (iq_sel[1:0] ), // output wire [1 : 0] probe_out3
|
||||
.probe_out4 (bb_rshift[3:0] ), // output wire [3 : 0] probe_out4
|
||||
.probe_out5 (rx_test_en ) // output wire [0 : 0] probe_out5
|
||||
.probe_out4 (bb_rshift[3:0] ) // output wire [3 : 0] probe_out4
|
||||
);
|
||||
|
||||
vio_hop u_vio_hop
|
||||
vio_freq_comp u_vio_freq_comp
|
||||
(
|
||||
.clk (sys_clk_4x ), // input wire clk
|
||||
.probe_out0 (hop_trigger ), // output wire [0 : 0] probe_out1
|
||||
.probe_out1 (hop_trigger_en ) // output wire [0 : 0] probe_out2
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe_in0 (freq_comp_busy ), // input wire [0 : 0] probe_in0
|
||||
.probe_out0 (freq_comp_start ), // output wire [0 : 0] probe_out0
|
||||
.probe_out1 (dmf_num_per_ch ), // output wire [7 : 0] probe_out1
|
||||
.probe_out2 (freq_manual_en ), // output wire [0 : 0] probe_out2
|
||||
.probe_out3 (freq_manual ) // output wire [31 : 0] probe_out3
|
||||
);
|
||||
|
||||
vio_null_phase u_vio_null_phase
|
||||
ila_freq_comp u_ila_freq_comp
|
||||
(
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe_out0 (phase_ch1 ), // output wire [15 : 0] probe_out0
|
||||
.probe_out1 (phase_ch2 ), // output wire [15 : 0] probe_out1
|
||||
.probe_out2 (phase_ch3 ), // output wire [15 : 0] probe_out2
|
||||
.probe_out3 (phase_ch4 ) // output wire [15 : 0] probe_out3
|
||||
.clk (sys_clk ), // input wire clk
|
||||
.probe0 (ch1_peak_value_i ), // input wire [17:0] probe0
|
||||
.probe1 (ch1_peak_value_q ), // input wire [17:0] probe1
|
||||
.probe2 (ch2_peak_value_i ), // input wire [17:0] probe2
|
||||
.probe3 (ch2_peak_value_q ), // input wire [17:0] probe3
|
||||
.probe4 (ch3_peak_value_i ), // input wire [17:0] probe4
|
||||
.probe5 (ch3_peak_value_q ), // input wire [17:0] probe5
|
||||
.probe6 (ch4_peak_value_i ), // input wire [17:0] probe6
|
||||
.probe7 (ch4_peak_value_q ), // input wire [17:0] probe7
|
||||
.probe8 (u_freq_comp.u_rx_dmf.moduli_abs), // input wire [17:0] probe8
|
||||
.probe9 (u_freq_comp.state_curr ), // input wire [2:0] probe9
|
||||
.probe10(freq_comp_start ), // input wire [0:0] probe10
|
||||
.probe11(u_freq_comp.dmf_peak_valid ), // input wire [0:0] probe11
|
||||
.probe12(ch_peak_valid ), // input wire [0:0] probe12
|
||||
.probe13(u_freq_comp.freq_word ), // input wire [31:0] probe13
|
||||
.probe14(freq_target_valid ), // input wire [0:0] probe14
|
||||
.probe15(freq_target ), // input wire [31:0] probe15
|
||||
.probe16(u_freq_comp.din_cxr_real ), // input wire [11:0] probe16
|
||||
.probe17(u_freq_comp.din_cxr_imag ), // input wire [11:0] probe17
|
||||
.probe18(ch1_peak_index ), // input wire [9:0] probe18
|
||||
.probe19(ch2_peak_index ), // input wire [9:0] probe19
|
||||
.probe20(ch3_peak_index ), // input wire [9:0] probe20
|
||||
.probe21(ch4_peak_index ) // input wire [9:0] probe21
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user