Archived
update phase comp with cmpy; add var cal module
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// _ _ ____
|
||||
// | | ___ ___| |__ / ___| __ _ ___
|
||||
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
||||
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
||||
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
||||
//
|
||||
// Create Date: 06/11/2023 02:41:47 PM
|
||||
// Design Name:
|
||||
// Module Name: var_cal
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module var_cal
|
||||
#(
|
||||
parameter ACCUM_NUM = 16384,
|
||||
parameter DATA_I_WIDTH = 30,
|
||||
parameter DATA_O_WIDTH = 32,
|
||||
parameter CMPY_WIDTH = 18
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input rst ,
|
||||
|
||||
input cal_start ,
|
||||
input cal_auto_en ,
|
||||
output cal_busy ,
|
||||
|
||||
input din_valid ,
|
||||
input [DATA_I_WIDTH-1 : 0] din_real ,
|
||||
input [DATA_I_WIDTH-1 : 0] din_imag ,
|
||||
|
||||
output var_valid ,
|
||||
output [DATA_O_WIDTH-1 : 0] var
|
||||
);
|
||||
|
||||
integer i;
|
||||
|
||||
localparam CMPY_VALID_WIDTH = CMPY_WIDTH-1; // 17-bit valid data to protect cmpy from overflow
|
||||
localparam DATA_MULT_FULL_WIDTH = 2*CMPY_VALID_WIDTH+1;
|
||||
localparam DATA_MULT_VALID_WIDTH = 2*CMPY_VALID_WIDTH;
|
||||
localparam AXIS_DATA_I_WIDTH = 8*((CMPY_VALID_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
|
||||
|
||||
// status control
|
||||
reg cal_start_auto = 'b0;
|
||||
reg cal_start_d1 = 'b0;
|
||||
reg cal_start_d2 = 'b0;
|
||||
reg cal_busy_buf = 'b0;
|
||||
reg [$clog2(ACCUM_NUM)-1 : 0] cnt_accum = 'b0;
|
||||
reg last_data = 'b0;
|
||||
reg last_data_d [0:6]; // 6 for cmpy, 1 for register output
|
||||
|
||||
assign cal_busy = cal_busy_buf;
|
||||
assign var_valid = last_data_d[6];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cal_start_auto <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if (~cal_busy_buf) begin
|
||||
cal_start_auto = ~cal_start_auto;
|
||||
end
|
||||
else begin
|
||||
cal_start_auto <= cal_start_auto;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cal_start_d1 <= cal_auto_en ? cal_start_auto : cal_start;
|
||||
cal_start_d2 <= cal_start_d1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cal_busy_buf <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if ((cal_start_d1 ^ cal_start_d2) && din_valid) begin
|
||||
cal_busy_buf <= 1'b1;
|
||||
end
|
||||
else if (cnt_accum == ACCUM_NUM-1) begin
|
||||
cal_busy_buf <= 'b0;
|
||||
end
|
||||
else begin
|
||||
cal_busy_buf <= cal_busy_buf;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
cnt_accum <= 'b0;
|
||||
end
|
||||
else begin
|
||||
cnt_accum <= cal_busy ? (cnt_accum + 1'b1) : 'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
last_data <= 'b0;
|
||||
end
|
||||
else begin
|
||||
last_data <= (cnt_accum == ACCUM_NUM-1) ? 1'b1 : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
last_data_d[0] <= last_data;
|
||||
|
||||
for (i = 0; i < 6; i = i + 1) begin
|
||||
last_data_d[i+1] <= last_data_d[i];
|
||||
end
|
||||
end
|
||||
|
||||
// cmpy
|
||||
wire [AXIS_DATA_I_WIDTH-1 : 0] cmpy_i_real;
|
||||
wire [AXIS_DATA_I_WIDTH-1 : 0] cmpy_i_imag;
|
||||
wire [AXIS_DATA_P_WIDTH-1 : 0] cmpy_p_raw_real;
|
||||
wire [AXIS_DATA_P_WIDTH-1 : 0] cmpy_p_raw_imag;
|
||||
wire [DATA_O_WIDTH-1 : 0] cmpy_p_real;
|
||||
wire [DATA_O_WIDTH-1 : 0] cmpy_p_imag;
|
||||
|
||||
if (CMPY_WIDTH > DATA_I_WIDTH) begin
|
||||
// append zeros
|
||||
assign cmpy_i_real = {{(AXIS_DATA_I_WIDTH-CMPY_VALID_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real,{(CMPY_VALID_WIDTH-DATA_I_WIDTH){1'b0}}};
|
||||
assign cmpy_i_imag = {{(AXIS_DATA_I_WIDTH-CMPY_VALID_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag,{(CMPY_VALID_WIDTH-DATA_I_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign cmpy_i_real = {{(AXIS_DATA_I_WIDTH-CMPY_VALID_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real[DATA_I_WIDTH-1 -: CMPY_VALID_WIDTH]};
|
||||
assign cmpy_i_imag = {{(AXIS_DATA_I_WIDTH-CMPY_VALID_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag[DATA_I_WIDTH-1 -: CMPY_VALID_WIDTH]};
|
||||
end
|
||||
|
||||
if (DATA_O_WIDTH > DATA_MULT_VALID_WIDTH) begin
|
||||
// append zeros
|
||||
assign cmpy_p_real = {cmpy_p_raw_real[0 +: DATA_MULT_VALID_WIDTH],{(DATA_O_WIDTH-DATA_MULT_VALID_WIDTH){1'b0}}};
|
||||
assign cmpy_p_imag = {cmpy_p_raw_imag[0 +: DATA_MULT_VALID_WIDTH],{(DATA_O_WIDTH-DATA_MULT_VALID_WIDTH){1'b0}}};
|
||||
end
|
||||
else begin
|
||||
// truncate msb
|
||||
assign cmpy_p_real = cmpy_p_raw_real[DATA_MULT_VALID_WIDTH-1 -: DATA_O_WIDTH];
|
||||
assign cmpy_p_imag = cmpy_p_raw_imag[DATA_MULT_VALID_WIDTH-1 -: DATA_O_WIDTH];
|
||||
end
|
||||
|
||||
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 = {cmpy_i_imag,cmpy_i_real};
|
||||
assign cmpy_b = {-cmpy_i_imag,cmpy_i_real};
|
||||
assign {cmpy_p_raw_imag,cmpy_p_raw_real} = cmpy_p;
|
||||
|
||||
cmpy_18x18_mult u_cmpy_18x18
|
||||
(
|
||||
.aclk (clk ), // input wire aclk
|
||||
.s_axis_a_tvalid (cal_busy ), // input wire s_axis_a_tvalid
|
||||
.s_axis_a_tdata (cmpy_a ), // input wire [31 : 0] s_axis_a_tdata
|
||||
.s_axis_b_tvalid (cal_busy ), // 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
|
||||
);
|
||||
|
||||
// accumulation
|
||||
reg [DATA_O_WIDTH+$clog2(ACCUM_NUM) : 0] accum = 'b0;
|
||||
reg [DATA_O_WIDTH-1 : 0] var_buf = 'b0;
|
||||
|
||||
assign var = var_buf;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
accum <= 'b0;
|
||||
end
|
||||
else begin
|
||||
if (cmpy_p_vld) begin
|
||||
accum <= accum + cmpy_p_real;
|
||||
end
|
||||
else begin
|
||||
accum <= 'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
var_buf <= 'b0;
|
||||
end
|
||||
else if (last_data_d[5]) begin
|
||||
var_buf <= accum[DATA_O_WIDTH+$clog2(ACCUM_NUM) -: DATA_O_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user