first commit after restructuring

This commit is contained in:
2023-04-13 13:33:41 +08:00
commit 3c2cd0ba29
15090 changed files with 6794217 additions and 0 deletions
@@ -0,0 +1,135 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%
%本仿真基于以下环境,64元矩形方阵,每若干个阵元通过TR通道和合路器,合成一路子阵信号,然后AD采样进入阵列信号处理单元;
% - 子阵分割均匀,(16,16,16,16),共有4个子阵
% - 1个已知方向的期望来波,3个未知方向的干扰信号;
% - 信干比60dB;
%θ表示俯仰角(来波与Z轴正向夹角);φ表示方位角(来波在XOY平面投影与X轴正向夹角);X轴与阵列每列平行,Y轴与阵列每行平行
%通过空域滤波得到抑制干扰后的信号
%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear all;
Tt=256;%快拍数,用于阵列信号处理的采样点数
Tmax = 32768;
t=1:Tmax;
%%%%%%%%%此处假设来波均为单频信号,可按自身定义修改
f1=0.1*pi;
f2=0.2*pi;
f3=0.3*pi;
f4=0.4*pi;
%% 通信基带信号
%% 窄带白噪声干扰信号
filter_name = 'lpf_fs100_fpass5_fstop6.mat';
%%
snr=0;%信噪比可根据应用场景确定
sjr=(60+snr);%干信比
s1=sqrt(2*10^(snr/10))*exp(1i*f1*t);
s2=sqrt(2*10^(sjr/10))*exp(1i*f2*t);
s3=sqrt(2*10^(sjr/10))*exp(1i*f3*t);
s4=sqrt(2*10^(sjr/10))*exp(1i*f4*t);
%%%%%%%由信噪比和干信比计算出信号的幅度
lamuda=1;%当前载频的波长,可根据载频输入实际值d
d=0.5;%阵元间距,需小于最高工作频率半波长,可根据实际情况输入实际值
theta1=20;%期望来波俯仰角
phi1=30;%期望来波方位角
theta2=-20;%干扰1俯仰角
phi2=50;%干扰1方位角
theta3=-40;%干扰2俯仰角
phi3=80;%干扰2方位角
theta4=-60;%干扰3俯仰角
phi4=120;%干扰3方位角
%%%%%%%%
m=8;%列
n=8;%行
L=m*n;
a1=exp(1i*2*pi*d/lamuda*(-(m/2-1/2):1:(m/2-1/2)).'*sin(theta1/180*pi)*sin(phi1/180*pi));
b1=exp(1i*2*pi*d/lamuda*(-(n/2-1/2):1:(n/2-1/2)).'*sin(theta1/180*pi)*cos(phi1/180*pi));
A1=kron(b1,a1);
a2=exp(1i*2*pi*d/lamuda*(-(m/2-1/2):1:(m/2-1/2)).'*sin(theta2/180*pi)*sin(phi2/180*pi));
b2=exp(1i*2*pi*d/lamuda*(-(n/2-1/2):1:(n/2-1/2)).'*sin(theta2/180*pi)*cos(phi2/180*pi));
A2=kron(b2,a2);
a3=exp(1i*2*pi*d/lamuda*(-(m/2-1/2):1:(m/2-1/2)).'*sin(theta3/180*pi)*sin(phi3/180*pi));
b3=exp(1i*2*pi*d/lamuda*(-(n/2-1/2):1:(n/2-1/2)).'*sin(theta3/180*pi)*cos(phi3/180*pi));
A3=kron(b3,a3);
a4=exp(1i*2*pi*d/lamuda*(-(m/2-1/2):1:(m/2-1/2)).'*sin(theta4/180*pi)*sin(phi4/180*pi));
b4=exp(1i*2*pi*d/lamuda*(-(n/2-1/2):1:(n/2-1/2)).'*sin(theta4/180*pi)*cos(phi4/180*pi));
A4=kron(b4,a4);
As=[A1,A2,A3,A4];%阵列流型
rng(0);
x=As*[s1;s2;s3;s4]+randn(L,Tmax);
%%%%%%%%%%%%%%%4元子阵
%
N1=4;
C1=zeros(N1,64);
D1=zeros(N1,64);
for kk=0:3
C1(1,(kk*8+1):(kk*8+4))=ones(1,4);
C1(2,(kk*8+5):(kk*8+8))=ones(1,4);
C1(3,(kk*8+33):(kk*8+36))=ones(1,4);
C1(4,(kk*8+37):(kk*8+40))=ones(1,4);
end
%}
%%%%%%%%%%%%%%%%%%%%%%
D1=C1*diag(A1');%4元 阵元通道移相后,每16路合路为一个子阵
% D2=C2*diag(A1');%6元 阵元通道移相后,每(16,8)路合路为一个子阵
% D3=C3*diag(A1');%8元 阵元通道移相后,每8路合路为一个子阵
% %%%%%%%%%%%%%%%%%
xs1=D1*x(:,1:Tt);
Rx1=xs1*xs1';%4元子阵协方差矩阵
Ax1=D1*A1;%期望来波方向的子阵导向矢量
wx1=inv(Rx1)*Ax1/(Ax1'*inv(Rx1)*Ax1);%4子阵的LCMV权值
s_new1=wx1'*(D1*x);%4子阵情况下的空域滤波后的信号
% s_new1=[1,1,1,1]*xs1;
%% 方向图
[theta,phi] = meshgrid(-180:180);
wx = zeros(length(theta),length(phi));
for i = 1:length(theta)
for j = 1:length(phi)
a = exp(1i*2*pi*d/lamuda*(-(m/2-1/2):1:(m/2-1/2)).'*sin(theta(i,j)/180*pi)*sin(phi(i,j)/180*pi));
b = exp(1i*2*pi*d/lamuda*(-(n/2-1/2):1:(n/2-1/2)).'*sin(theta(i,j)/180*pi)*cos(phi(i,j)/180*pi));
A = kron(b,a);
Ax = D1*A;
wx(i,j) = wx1'*Ax;
end
end
wx_abs = abs(wx)/max(max(abs(wx)));
m = mesh(theta,phi,20*log(wx_abs));
xlabel('俯仰角');
ylabel('方位角');
datatip(m,'DataIndex',(theta1+180)*361+(phi1+180)+1);
datatip(m,'DataIndex',(theta2+180)*361+(phi2+180)+1);
datatip(m,'DataIndex',(theta3+180)*361+(phi3+180)+1);
datatip(m,'DataIndex',(theta4+180)*361+(phi4+180)+1);
zlim([-150 0]);
%% 数据导出
xs1_long = (D1*x).';
xs1_real = real(xs1_long);
xs1_imag = imag(xs1_long);
xs1_real_12b = round(xs1_real/max(max(abs(xs1_long)))*(2^11-1));
xs1_imag_12b = round(xs1_imag/max(max(abs(xs1_long)))*(2^11-1));
writematrix(xs1_real_12b,'./xs1_real.csv');
writematrix(xs1_imag_12b,'./xs1_imag.csv');
xs1_12b = xs1_real_12b' + 1i*xs1_imag_12b';
tb_snap = xs1_12b(:,(0:255)+54);
tb_acorr = tb_snap*tb_snap';
wx1_32b = round(wx1/max(abs(wx1))*(2^31-1));
wx1_16b = floor(wx1_32b/2^16);
s_new1_30b = (wx1_16b'*xs1_12b).';
s_new1_12b = floor(s_new1_30b/2^18);
@@ -0,0 +1,255 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
// _ _ ____
// | | ___ ___| |__ / ___| __ _ ___
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
// \___/ \___/|___/_| |_| \____|\__,_|\___/
//
// Create Date: 2022/09/15 11:12:45
// Last Modified Data: 2022/11/02
// Design Name:
// Module Name: tb_ad9361_cal
// Project Name:
// Target Devices:
// Tool Versions:
// Description: testbench for [rx_pre_process]
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tb_rx_pre;
localparam COL_NUM = 4;
localparam PS_PL_WIDTH = 32;
localparam OUTPUT_DATA_WIDTH = 30;
localparam FRAME_HEAD = 32'b10110011100011110000111000110010;
localparam FRAME_BITS = (2+COL_NUM*2)*PS_PL_WIDTH;
reg [FRAME_BITS-1 : 0] weight_stream_buf =
{
FRAME_HEAD, 32'd40,
-32'd1145474114, 32'd1816473250 ,
32'd2059208152, -32'd254581925 ,
32'd2062565030, 32'd244279278 ,
-32'd1154406364, -32'd1806170603
};
reg sys_clk = 1'b1;
reg sys_clk_4x = 1'b1;
reg sys_rst = 1'b1;
reg clk_96m = 1'b1;
reg ant_rst = 1'b1;
reg ad9361_1_cal_start = 'b0;
wire ad9361_1_cal_done ;
reg ad9361_2_cal_start = 'b0;
wire ad9361_2_cal_done ;
wire ad9361_cal_result ;
wire ad9361_cal_valid ;
reg ad9361_recal = 'b0;
// phase difference of 0 degree
wire [11:0] rx_ch1_i;
wire [11:0] rx_ch1_q;
wire [11:0] rx_ch2_i;
wire [11:0] rx_ch2_q;
wire [11:0] rx_ch3_q;
wire [11:0] rx_ch3_i;
wire [11:0] rx_ch4_i;
wire [11:0] rx_ch4_q;
reg hop_start_flag = 1'b0;
wire accor_stream_valid;
wire accor_stream_data;
wire weight_stream_data;
wire rx_data_valid;
wire [OUTPUT_DATA_WIDTH-1:0] rx_data_i, rx_data_q;
rx_pre_process #(
.OUTPUT_DATA_WIDTH (OUTPUT_DATA_WIDTH )
) u_rx_pre_process
(
// clock & reset
.sys_clk (sys_clk ), // input sys_clk
.sys_clk_4x (sys_clk_4x ), // input sys_clk_4x
.sys_rst (sys_rst ), // input sys_rst
.clk_96m (clk_96m ), // input clk_96m
.ant_rst (ant_rst ), // input ant_rst
// input data interface
.rx_ch1_i (rx_ch1_i ), // input [11:0] rx_ch1_i
.rx_ch1_q (rx_ch1_q ), // input [11:0] rx_ch1_q
.rx_ch2_i (-rx_ch2_i ), // input [11:0] rx_ch2_i
.rx_ch2_q (-rx_ch2_q ), // input [11:0] rx_ch2_q
.rx_ch3_i (rx_ch3_i ), // input [11:0] rx_ch3_i
.rx_ch3_q (rx_ch3_q ), // input [11:0] rx_ch3_q
.rx_ch4_i (-rx_ch4_i ), // input [11:0] rx_ch4_i
.rx_ch4_q (-rx_ch4_q ), // input [11:0] rx_ch4_q
// ad9361 calibration 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
// nulling algotithm interface
.hop_start_flag (hop_start_flag ), // input hop_start_flag
.accor_stream_valid (accor_stream_valid ), // output accor_stream_valid
.accor_stream_data (accor_stream_data ), // output accor_stream_data
.weight_stream_data (weight_stream_data ), // input weight_stream_data
.rx_data_valid (rx_data_valid ),
.rx_data_i (rx_data_i ),
.rx_data_q (rx_data_q )
);
// system clock generation
always begin
#6;
sys_clk = ~sys_clk;
#14;
end
always begin
#5 sys_clk_4x = ~sys_clk_4x;
end
always begin
#7;
clk_96m = ~clk_96m;
#3;
end
initial begin
#102
sys_rst = 1'b0;
ant_rst = 1'b0;
#100
ad9361_1_cal_start = 1'b1;
end
always @(posedge sys_clk) begin
if (ad9361_1_cal_done) begin
ad9361_2_cal_start <= 1'b1;
end
else begin
ad9361_2_cal_start <= 1'b0;
end
end
integer r_file_real;
integer r_file_imag;
reg signed [11:0] rx_ch1_i_data = 'b0, rx_ch1_q_data = 'b0;
reg signed [11:0] rx_ch2_i_data = 'b0, rx_ch2_q_data = 'b0;
reg signed [11:0] rx_ch3_i_data = 'b0, rx_ch3_q_data = 'b0;
reg signed [11:0] rx_ch4_i_data = 'b0, rx_ch4_q_data = 'b0;
reg [11:0] rx_ch1_i_cal = 12'd2047;
reg [11:0] rx_ch1_q_cal = 12'd2047;
reg [11:0] rx_ch2_i_cal = -12'd2047;
reg [11:0] rx_ch2_q_cal = -12'd2047;
reg [11:0] rx_ch3_q_cal = 12'd2047;
reg [11:0] rx_ch3_i_cal = 12'd2047;
reg [11:0] rx_ch4_i_cal = -12'd2047;
reg [11:0] rx_ch4_q_cal = -12'd2047;
assign rx_ch1_i = ad9361_cal_valid ? rx_ch1_i_data : rx_ch1_i_cal;
assign rx_ch1_q = ad9361_cal_valid ? rx_ch1_q_data : rx_ch1_q_cal;
assign rx_ch2_i = ad9361_cal_valid ? rx_ch2_i_data : rx_ch2_i_cal;
assign rx_ch2_q = ad9361_cal_valid ? rx_ch2_q_data : rx_ch2_q_cal;
assign rx_ch3_i = ad9361_cal_valid ? rx_ch3_i_data : rx_ch3_i_cal;
assign rx_ch3_q = ad9361_cal_valid ? rx_ch3_q_data : rx_ch3_q_cal;
assign rx_ch4_i = ad9361_cal_valid ? rx_ch4_i_data : rx_ch4_i_cal;
assign rx_ch4_q = ad9361_cal_valid ? rx_ch4_q_data : rx_ch4_q_cal;
initial begin
forever begin
@(posedge sys_clk)
// 校准数据
#720
rx_ch1_i_cal = ~rx_ch1_i_cal;
rx_ch2_i_cal = ~rx_ch2_i_cal;
rx_ch3_i_cal = ~rx_ch3_i_cal;
rx_ch4_i_cal = ~rx_ch4_i_cal;
#240
rx_ch1_q_cal = ~rx_ch1_q_cal;
rx_ch2_q_cal = ~rx_ch2_q_cal;
rx_ch3_q_cal = ~rx_ch3_q_cal;
rx_ch4_q_cal = ~rx_ch4_q_cal;
end
end
initial begin
r_file_real = $fopen("../../../../../testbenches/xs1_real.csv","r");
r_file_imag = $fopen("../../../../../testbenches/xs1_imag.csv","r");
@(posedge ad9361_cal_valid)
forever begin
@(posedge sys_clk)
$fscanf(r_file_real,"%d,%d,%d,%d",
rx_ch1_i_data,
rx_ch2_i_data,
rx_ch3_i_data,
rx_ch4_i_data);
$fscanf(r_file_imag,"%d,%d,%d,%d",
rx_ch1_q_data,
rx_ch2_q_data,
rx_ch3_q_data,
rx_ch4_q_data);
end
end
// hop flag counter
reg [$clog2(38400)-1 : 0] hop_cnt = 'b0;
always @(posedge sys_clk_4x) begin
if (sys_rst) begin
hop_cnt <= 'b0;
hop_start_flag <= 1'b0;
end
else if (ad9361_cal_valid) begin
hop_cnt <= (hop_cnt == 38399) ? 'b0 : hop_cnt + 1'b1;
hop_start_flag <= (hop_cnt == 1'b1) ? 1'b1 : 1'b0;
end
else begin
hop_cnt <= hop_cnt;
hop_start_flag <= hop_start_flag;
end
end
//
reg weight_stream_valid = 'b0;
always @(negedge accor_stream_valid) begin
#((48*50)*40+18); // 50us of 48M clock
weight_stream_valid = 'b1;
#(FRAME_BITS*20);
weight_stream_valid = 'b0;
end
reg [$clog2(FRAME_BITS)-1 : 0] weight_stream_cnt;
always @(posedge clk_96m) begin
if (sys_rst) begin
weight_stream_cnt <= 'b0;
end
else begin
weight_stream_cnt <= (weight_stream_valid & ~(weight_stream_cnt == FRAME_BITS - 1)) ? weight_stream_cnt + 1'b1 : 'b0;
end
end
assign weight_stream_data = weight_stream_buf[FRAME_BITS-1-weight_stream_cnt];
endmodule
@@ -0,0 +1,93 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
// _ _ ____
// | | ___ ___| |__ / ___| __ _ ___
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
// \___/ \___/|___/_| |_| \____|\__,_|\___/
//
// Create Date: 2023/02/25 15:50:45
// Design Name:
// Module Name: tb_tx_pre_process
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tb_tx_pre_process;
reg clk = 1'b1;
reg rst = 1'b1;
reg [11:0] tx_data_ch1_i = 'b0;
reg [11:0] tx_data_ch1_q = 'b0;
reg [11:0] tx_data_ch2_i = 'b0;
reg [11:0] tx_data_ch2_q = 'b0;
reg ad9361_tx_switch = 1'b0;
reg [3:0] bb_rshift = 4'd3;
wire [11:0] tx_ch1_i;
wire [11:0] tx_ch1_q;
wire [11:0] tx_ch2_i;
wire [11:0] tx_ch2_q;
tx_pre_process #(
.CAL_MOD_FINE (1 )
) u_tx_pre_process
(
// clock & reset
.clk (clk ),
.rst (rst ),
// input data
.tx_data_ch1_i (tx_data_ch1_i ),
.tx_data_ch1_q (tx_data_ch1_q ),
.tx_data_ch2_i (tx_data_ch2_i ),
.tx_data_ch2_q (tx_data_ch2_q ),
// ad9361 calibration interface
.ad9361_tx_switch (ad9361_tx_switch ),
//
.bb_rshift (bb_rshift ),
// output data
.tx_ch1_i (tx_ch1_i ),
.tx_ch1_q (tx_ch1_q ),
.tx_ch2_i (tx_ch2_i ),
.tx_ch2_q (tx_ch2_q )
);
initial begin
#102 rst = 1'b0;
#100 ad9361_tx_switch = 1'b1;
#10000 ad9361_tx_switch = 1'b0;
end
always #10 clk = ~clk;
always @(posedge clk) begin
if (rst) begin
tx_data_ch1_i <= 'b0;
tx_data_ch1_q <= 'b0;
tx_data_ch2_i <= 'b0;
tx_data_ch2_q <= 'b0;
end
else begin
tx_data_ch1_i <= tx_data_ch1_i + 12'd1;
tx_data_ch1_q <= tx_data_ch1_q + 12'd2;
tx_data_ch2_i <= tx_data_ch2_i + 12'd3;
tx_data_ch2_q <= tx_data_ch2_q + 12'd4;
end
end
endmodule
@@ -0,0 +1,86 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03/29/2023 09:02:30 PM
// Design Name:
// Module Name: tb_xpm_cdc_pulse
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tb_xpm_cdc_pulse;
reg sys_clk = 1'b1;
reg sys_clk_4x = 1'b1;
reg sys_rst = 1'b1;
reg src_pulse = 1'b0;
wire dest_pulse;
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 (1), // DECIMAL; 0=disable registered output, 1=enable registered output
.RST_USED (1), // DECIMAL; 0=no reset, 1=implement reset
.SIM_ASSERT_CHK (1) // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
) u_xpm_cdc_pulse
(
.dest_pulse (dest_pulse ), // 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 (src_pulse ), // 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
);
initial begin
#102;
sys_rst = 1'b0;
end
always begin
#3;
sys_clk = ~sys_clk;
#37;
end
always begin
#5;
sys_clk_4x = ~sys_clk_4x;
end
reg [3:0] pulse_cnt = 'b0;
always @(posedge sys_clk_4x) begin
if (sys_rst) begin
src_pulse <= 1'b0;
pulse_cnt <= 'b0;
end
else begin
pulse_cnt <= pulse_cnt + 1'b1;
src_pulse <= (pulse_cnt == 4'd15) ? 1'b1 : 1'b0;
end
end
endmodule
Binary file not shown.
1 version https://git-lfs.github.com/spec/v1
2 oid sha256:63874679d6cb1cc2738fd5816e9b17345bdf6a41772fadf6adc31005adb224ed
3 size 629981
Binary file not shown.
1 version https://git-lfs.github.com/spec/v1
2 oid sha256:155a65367f9e1e2e2e2799ab9426e2a9b8cc99da0a3571a179cc42b15219f929
3 size 631856