Archived
1. 调零算法部分增加调零控制模块,用于各模块互联和状态控制以及数据存储,增加LCMV和DAS选通; 2. Cordic 旋转输入改为保留两个符号位,避免溢出; 3. LCMV快拍数修改为2048; 4. 修改功率计算模块,适配较小数据位宽; 5. 修改在线捕获校准程序自动校准部分VIO初值; 6. 地检新射频发端增加自动频点切换
259 lines
7.6 KiB
Verilog
259 lines
7.6 KiB
Verilog
`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
|
|
// 20230730-1427 - 修改输入位宽小于乘法器位宽时的处理,由补零变为符号位扩展;
|
|
// 修改;修改累加和输出截位方式,依托原始数据位宽进行处理。
|
|
// Additional Comments:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
module var_cal
|
|
#(
|
|
parameter ACCUM_NUM = 16384,
|
|
parameter DATA_I_WIDTH = 30,
|
|
parameter DATA_O_WIDTH = 32,
|
|
parameter CMPY_I_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_P_WIDTH = 2*CMPY_I_WIDTH+1;
|
|
localparam AXIS_CMPY_I_WIDTH = 8*((CMPY_I_WIDTH-1)/8+1) ; // axis data width of input real/image data
|
|
localparam AXIS_CMPY_P_WIDTH = 8*((CMPY_P_WIDTH-1)/8+1); // axis data width of cmpy output real/image data
|
|
localparam CMPY_P_VALID_WIDTH = (DATA_I_WIDTH > CMPY_I_WIDTH) ? 2*CMPY_I_WIDTH : 2*DATA_I_WIDTH;
|
|
|
|
|
|
localparam ACCUM_WIDTH = CMPY_P_VALID_WIDTH + $clog2(ACCUM_NUM);
|
|
|
|
// 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 [6:0] last_data_d = 'b0; // 1 for register input, 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_auto_en) begin
|
|
if (~cal_busy_buf) begin
|
|
cal_start_auto <= ~cal_start_auto;
|
|
end
|
|
else begin
|
|
cal_start_auto <= cal_start_auto;
|
|
end
|
|
end
|
|
else begin
|
|
cal_start_auto <= 'b0;
|
|
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
|
|
if (rst) begin
|
|
last_data_d[6:0] <= 'b0;
|
|
end
|
|
else begin
|
|
last_data_d[6:0] <= {last_data_d[5:0],last_data};
|
|
end
|
|
end
|
|
|
|
|
|
// cmpy
|
|
reg [AXIS_CMPY_I_WIDTH-1 : 0] cmpy_a_real = 'b0;
|
|
reg [AXIS_CMPY_I_WIDTH-1 : 0] cmpy_a_imag = 'b0;
|
|
reg [AXIS_CMPY_I_WIDTH-1 : 0] cmpy_b_real = 'b0;
|
|
reg [AXIS_CMPY_I_WIDTH-1 : 0] cmpy_b_imag = 'b0;
|
|
wire [AXIS_CMPY_P_WIDTH-1 : 0] cmpy_p_raw_real;
|
|
wire [AXIS_CMPY_P_WIDTH-1 : 0] cmpy_p_raw_imag;
|
|
wire [CMPY_P_VALID_WIDTH-1 : 0] cmpy_p_real;
|
|
wire [CMPY_P_VALID_WIDTH-1 : 0] cmpy_p_imag;
|
|
|
|
if (CMPY_I_WIDTH > DATA_I_WIDTH) begin
|
|
// sign-bit extension to fit cmpy input data width
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
cmpy_a_real <= 'b0;
|
|
cmpy_a_imag <= 'b0;
|
|
cmpy_b_real <= 'b0;
|
|
cmpy_b_imag <= 'b0;
|
|
end
|
|
else begin
|
|
cmpy_a_real <= {{(AXIS_CMPY_I_WIDTH-DATA_I_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real};
|
|
cmpy_a_imag <= {{(AXIS_CMPY_I_WIDTH-DATA_I_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag};
|
|
cmpy_b_real <= {{(AXIS_CMPY_I_WIDTH-DATA_I_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real};
|
|
cmpy_b_imag <= (din_imag == {1'b1,{(DATA_I_WIDTH-1){1'b0}}}) ? {{(AXIS_CMPY_I_WIDTH-DATA_I_WIDTH+1){1'b0}},{(DATA_I_WIDTH-1){1'b1}}} : -{{(AXIS_CMPY_I_WIDTH-DATA_I_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag};
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
// truncate msb
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
cmpy_a_real <= 'b0;
|
|
cmpy_a_imag <= 'b0;
|
|
cmpy_b_real <= 'b0;
|
|
cmpy_b_imag <= 'b0;
|
|
end
|
|
else begin
|
|
cmpy_a_real <= {{(AXIS_CMPY_I_WIDTH-CMPY_I_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real[DATA_I_WIDTH-1 -: CMPY_I_WIDTH]};
|
|
cmpy_a_imag <= {{(AXIS_CMPY_I_WIDTH-CMPY_I_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag[DATA_I_WIDTH-1 -: CMPY_I_WIDTH]};
|
|
cmpy_b_real <= {{(AXIS_CMPY_I_WIDTH-CMPY_I_WIDTH){din_real[DATA_I_WIDTH-1]}},din_real[DATA_I_WIDTH-1 -: CMPY_I_WIDTH]};
|
|
cmpy_b_imag <= (din_imag[DATA_I_WIDTH-1 -: CMPY_I_WIDTH] == {1'b1,{(CMPY_I_WIDTH-1){1'b0}}}) ? {{(AXIS_CMPY_I_WIDTH-CMPY_I_WIDTH+1){1'b0}},{(CMPY_I_WIDTH-1){1'b1}}} : -{{(AXIS_CMPY_I_WIDTH-CMPY_I_WIDTH){din_imag[DATA_I_WIDTH-1]}},din_imag[DATA_I_WIDTH-1 -: CMPY_I_WIDTH]};
|
|
end
|
|
end
|
|
end
|
|
|
|
// truncate valid bits
|
|
assign cmpy_p_real = cmpy_p_raw_real[0 +: CMPY_P_VALID_WIDTH];
|
|
assign cmpy_p_imag = cmpy_p_raw_imag[0 +: CMPY_P_VALID_WIDTH];
|
|
|
|
|
|
wire [2*AXIS_CMPY_I_WIDTH-1:0] cmpy_a;
|
|
wire [2*AXIS_CMPY_I_WIDTH-1:0] cmpy_b;
|
|
wire [2*AXIS_CMPY_P_WIDTH-1:0] cmpy_p;
|
|
wire cmpy_p_vld;
|
|
|
|
assign cmpy_a = {cmpy_a_imag,cmpy_a_real};
|
|
assign cmpy_b = {cmpy_b_imag,cmpy_b_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 [ACCUM_WIDTH-1 : 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
|
|
|
|
if (DATA_O_WIDTH > ACCUM_WIDTH) begin
|
|
// sign-bit extension to fit output data width
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
var_buf <= 'b0;
|
|
end
|
|
else if (last_data_d[5]) begin
|
|
var_buf <= {{(DATA_O_WIDTH-ACCUM_WIDTH){accum[ACCUM_WIDTH-1]}},accum};
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
// truncate msb
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
var_buf <= 'b0;
|
|
end
|
|
else if (last_data_d[5]) begin
|
|
var_buf <= accum[ACCUM_WIDTH-1 -: DATA_O_WIDTH];
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|