在tcl脚本处输入如下命令:
设置多线程的命令为: set_param general.maxThreads 8
读取当前线程数的命令: get_param general.maxThreads
(1)满幅输入,看IP 核的输出应该从哪里开始截位。
比如16位的乘法IP,输入为全1。此时根据输出数据 m_axis_tdata 进行截位(连续相同的即为符号位)。
(2) 如何从m_axis_data_tdata得到m_axis_data_tdata[15:0]
选中需要截取出来的bit位---->单击右键----->选择new virtual bus—>命名
tool------language templates-------输入关键词
1、crtl+Alt,再滚动鼠标。即可进行批量操作。
2、crtl+F。快速查找某一个参数的上一次/下一次出现的地方。
3、crtl+R。批量替换
点击±—单击add or create design source------add file—找到现有工程的.srcs文件-----点击source----点击 ip----找到所需的IP,点击进去,选择.xci文件----添加所需的.xci文件–点击完成
(1)法一:
1.生成IP核的状态报告 Tools -> Report -> Report IP Status-> upgrade
(2)法二:
下面介绍另一种方法,对应上述方法不能使用的情况(Upgrade Selected 按钮是灰色的)。在 Tcl console中 执行如下一条命令即可:
upgrade_ip [get_ips]
如果信号直接对应外部芯片的管脚,那就用10’dz.
如果只是芯片内部的信号,那就不要用高阻态。
复位时,state=0;
case(state)
0:
begin
state<=1;
...程序功能
end
1:
begin
state<=2;
...程序功能
end
default :
state<= 0;
endcase
//改进:PINC_flag=1后,还需要间隔一定的时间,LMS算法才校正完成,所以需要对上式改进
reg [7:0] PINC_flag_delayCount;
reg [3:0] ST_PINC_flag;//状态机
reg PINC_flag_delay50;
always @(posedge clk)
begin
if(reset)
begin
PINC_flag_delayCount<=8'd0;
ST_PINC_flag<=4'd0;//状态0
PINC_flag_delay50<=1'b0;
end
else
begin
case(ST_PINC_flag)
0://进入状态0
if(PINC_flag==1)//完成整个频段的频率字的输出的标志信号
begin
PINC_flag_delayCount<=PINC_flag_delayCount+1'b1;
ST_PINC_flag<=4'd1;
end
1:
if(PINC_flag_delayCount==8'd50)
begin
ST_PINC_flag<=4'd2;
PINC_flag_delayCount<=PINC_flag_delayCount;
end
else
begin
ST_PINC_flag<=4'd0;
end
2:
PINC_flag_delay50=1'b1;
default :
ST_PINC_flag<=4'd0;
endcase
end
end
assign Calib_State=!( (PINC_flag_delay50) && (!Calib_flag) );
通过截位的方法
//缩小两倍: 0000_1000_0000_0000 0_0000_1000_0000_000
assign RtI={RtI_temp[15],RtI_temp[15:1]}; //将参考信号缩小一半
assign RtQ={RtQ_temp[15],RtQ_temp[15:1]}; //将参考信号缩小一半
//assign RtI={RtI_temp[15],RtI_temp[15], RtI_temp[15:2]}; //将参考信号缩小为1/4
//assign RtQ={RtQ_temp[15],RtQ_temp[15], RtQ_temp[15:2]}; //将参考信号缩小为1/4
数据格式为补码。
对于位宽为16位的数据而言,例如 x = 0111_1111_1111_1111,x的相反数-x = 1111_1111_1111_1111(原码表示方式)。
根据负数的补码与原码的转换规则:符号位不变,数据位按位取反,再+1。
所以 -x 的补码为:1000_0000_0000_0000+1= 1000_0000_0000_0001。
因此,+x到-x的快速转换方法为:所有位按位取反,再+1。
assign W_GE = {((~W[31:16]) + 1), W[15:0]}; //W的共轭; 高16位是虚部,低16位是实部。
//---2、抓取phase_vec_vaild的下降沿
reg phase_vec_vaild_delay;
reg phase_vec_vaild_syn;
always@(posedge clk)
begin
phase_vec_vaild_delay<=phase_vec_vaild;
//if(phase_vec_vaild_delay==1'b0 && phase_vec_vaild==1'b1)//抓取信号的上升沿
if(phase_vec_vaild_delay==1'b1 && phase_vec_vaild==1'b0)//抓取信号的下降沿
begin
phase_vec_vaild_syn<=1'b1;
end
else
begin
phase_vec_vaild_syn<=1'b0;
end
end
/*
step 1: 抓取 beam1_tvalid 的上升沿
*/
reg beam1_tvalid_delay;
reg beam1_tvalid_syn;//是一个高电平信号
always@(posedge clk_250M)
begin
beam1_tvalid_delay<=beam1_tvalid;
if(reset)
begin
beam1_tvalid_syn<=1'b0;
end
else if(beam1_tvalid_delay==1'b0 && beam1_tvalid==1'b1)//抓取信号的上升沿
begin
beam1_tvalid_syn<=1'b1;
end
else
begin
beam1_tvalid_syn<=beam1_tvalid_syn;
end
end
[ 31 : 0 ]表示一个数据的信号位宽,而 [0:7][0:7] 表示有8x8个位宽为32的数据。;
wire [31:0] A_matrix [0:7][0:7];
reg [31:0] B_matrix [0:7][0:7];
好处:
(1)直观;
(2)可以用这种数据表示方法+序号m、n来处理matlab的for语句(大量,重复的语句)。
(1)第一种方法
将矩阵放在变量A里面作为输出。
wire [8*8*31 : 0] A。
(2)第二种方法
二维数组直接作为输出,对于VHDL语言是可行的,但是对于Verlog是不可行的。但是,我们可以用串行输出的方式来将一个二维数组输出出来,此时需要一个计数器。最后,外部模块根据计数器count和矢量,来拼成一个矩阵。
always@(posedge clk)
begin
if(y_Vaild) //是一个脉冲信号(上升沿有效)
begin
Men_y[count_scan]<=y;
Men_y_Vaild[count_scan]<=1'b1; //是一个脉冲信号
end
else
begin
Men_y[count_scan]<=Men_y[count_scan];
Men_y_Vaild[count_scan]<=1'b0; //是一个脉冲信号(上升沿有效)
end
end
--debug 类似于ila
attribute MARK_DEBUG : string;
attribute MARK_DEBUG of A: signal is "TRUE";----****
attribute MARK_DEBUG of B: signal is "TRUE";
attribute MARK_DEBUG of C: signal is "TRUE";
attribute MARK_DEBUG of D: signal is "TRUE";
通过上述语句生成bit文件时,应该按照下面步骤进行操作。否则,debug加不上。
点击综合(run synthesis)—>展开open synthesisized Design—点击set up debug----设置完成后,最后点击生成比特流文件。
为了通过直接点击生成bit流文件生成bit文件,且保证ILA一定加上了,则采用添加ila IP核这种方法。
(1)处理板连接好线,但是此时没有输入信号,将ADC采集的数据偏置到平均值为0。
(2)**两级希尔伯特变换。**具体而言,首先经过第一级希尔伯特变换,其实部是有直流的,虚部信号没有直流,所以我们保留虚部信号;第二级希尔伯特变换,其输入为第一级希尔伯特变换的虚部。
--temp_alpha单位是度,temp_mult_a单位是弧度
-- 182是怎么来的:根据弧度=度/180*pi=度*pi/180
-- pi/180= (2*pi/2)/180= =(65536/2)/180=182
-------第1种理解方式:
-- 为了提高角度精度,上位机如果要发360度,实际上发的是ffff,即65536
-- 那么对于FPGA而言,为了对应真实的角度(360度),需要除以182(65536/182=360)
---为了转换为弧度,根据公式:弧度=度/180*pi=度*pi/180=度*182(2*PI对应65536),
-- 即需要再乘以182,所以最终为:/182*182= *1 。如下所示
-------第2种理解方式:
-- 上位机如果发送的角度为360度,真实发的是ffff,即65536
-- 对于FPGA而言,360度的弧度为2*pi,即65536。。
-- 所以上位机的角度值转化为FPGA的弧度值,直接*1即可
temp_mult_a := temp_alpha*1;--将度转化成弧度, 182是量化因子
temp_mult_b := temp_beta*1;--没有<,所以是串行执行,先执行这两行语句
generate
genvar j;
for (j=0;j<10;j=j+1)
begin : Loop_j
assign b[j] = a[j];
end
endgenerate
原因:
(1)在每一个clk,都会对该信号进行判断,所以不用担心采集不到该信号的上升沿;
(2)如果生成的是一个高电平信号,那么对于算法下一次执行时,是不利的。
synthesis—report Utilization—>Hierarchy
`timescale 1ns / 1ps
module Get_RxBeam_WPower_vaild(
input clk_250M ,
input reset ,
input receive_beam_weight_valid , //权值有效---是一个脉冲信号
input select_beam_power_valid , //---是一个脉冲信号
output receive_beam_WPower_vaild_pulse
);
wire a,b;
assign a=receive_beam_weight_valid;
assign b=select_beam_power_valid;
/*
step 1:保证a,b 是一个脉冲(仅持续一个clk)
*/
reg a_delay;
reg a_pulse; // 是一个脉冲信号
always@(posedge clk_250M)
begin
a_delay<=a;
if(a_delay==1'b0 && a==1'b1)//抓取信号的上升沿
begin
a_pulse<=1'b1;
end
else
begin
a_pulse<=1'b0;
end
end
reg b_delay;
reg b_pulse; // 是一个脉冲信号
always@(posedge clk_250M)
begin
b_delay<=b;
if(b_delay==1'b0 && b==1'b1)//抓取信号的上升沿
begin
b_pulse<=1'b1;
end
else
begin
b_pulse<=1'b0;
end
end
/*
step 2 :得到 a ,b 脉冲都有效后的标志信号,是一个脉冲信号
*/
reg c;
reg delay_a_pulse;
reg dd_a_pulse;
reg delay_b_pulse;
reg [3:0] ST;
always @(posedge clk_250M)
begin
delay_a_pulse<=a_pulse;
dd_a_pulse<=delay_a_pulse;
delay_b_pulse<=b_pulse;
if(reset)
begin
c<=1'b0;
ST<=4'd0;
end
case(ST)
0:
begin
if(a_pulse==1'b1 && b_pulse==1'b0) //a这个脉冲先来,b这个脉冲后来
begin
ST<=4'd1;
end
else if(b_pulse==1'b1 && a_pulse==1'b0) //b这个脉冲先来,a这个脉冲后来
begin
ST<=4'd2;
end
else if(a_pulse==1'b1 && b_pulse==1'b1) //a、b 脉冲同时来
begin
ST<=4'd3;
end
else
begin
ST<=4'd0;
end
end
1:
begin
if(delay_a_pulse) //a这个脉冲先来,b这个脉冲后来
c<=1'b1;
else if(delay_b_pulse)
begin
c<=1'b0;
ST<=4'd4;
end
else
c<=c;
end
2:
begin
if(delay_b_pulse) //b这个脉冲先来,a这个脉冲后来
c<=1'b1;
else if(delay_a_pulse)
begin
c<=1'b0;
ST<=4'd4;
end
else
c<=c;
end
3: //a、b 脉冲同时来
begin
ST<=4'd4;
if(delay_a_pulse)
c<=1'b1;
else
c<=1'b0;
end
4:
begin
ST<=4'd0;
c<=1'b0;
end
endcase
end
reg c_delay;
reg c_pulse; // 是一个脉冲信号
assign receive_beam_WPower_vaild_pulse=c_pulse;
always@(posedge clk_250M)
begin
c_delay<=c;
if(c_delay==1'b1 && c==1'b0)//抓取信号的下降沿
begin
c_pulse<=1'b1;
end
else
begin
c_pulse<=1'b0;
end
end
endmodule
对于滤波器而言,滤波器的增益为0dB,所以待滤波信号(位宽16)过了滤波器之后,应该仍然是16bit。但是,现在利用MATLAB生成滤波器系数的coe文件时,我们将滤波器的系数扩大 2^15-1倍,
所以在FPGA里面,要截去滤波器输出信号的低15位,即assign y = m_axis_data_tdata[30 : 15];