赞
踩
在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语句(大量,重复的语句)。
第一种方法:
第二种方法:
integer i_clk,j_clk;
(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
对于滤波器而言,滤波器的增益为0dB,所以待滤波信号(位宽16)过了滤波器之后,应该仍然是16bit。但是,现在利用MATLAB生成滤波器系数的coe文件时,我们将滤波器的系数扩大 2^15-1倍,
所以在FPGA里面,要截去滤波器输出信号的低15位,即assign y = m_axis_data_tdata[30 : 15];
ila_Beam1_W Inst_ila_Beam1_W( .clk(clk),//第一行的实部 .probe0(debug_W_Beam1_I[0]), //(15 DOWNTO 0); .probe1(debug_W_Beam1_I[1]), //(15 DOWNTO 0); .probe2(debug_W_Beam1_I[2]), //(15 DOWNTO 0); .probe3(debug_W_Beam1_I[3]), //(15 DOWNTO 0); .probe4(debug_W_Beam1_I[4]), //(15 DOWNTO 0); .probe5(debug_W_Beam1_I[5]), //(15 DOWNTO 0); .probe6(debug_W_Beam1_I[6]), //(15 DOWNTO 0); .probe7(debug_W_Beam1_I[7]), //(15 DOWNTO 0); .probe8( debug_W_Beam1_Q[0]), //(15 DOWNTO 0); .probe9( debug_W_Beam1_Q[1]), //(15 DOWNTO 0); .probe10(debug_W_Beam1_Q[2]), //(15 DOWNTO 0); .probe11(debug_W_Beam1_Q[3]), //(15 DOWNTO 0); .probe12(debug_W_Beam1_Q[4]), //(15 DOWNTO 0); .probe13(debug_W_Beam1_Q[5]), //(15 DOWNTO 0); .probe14(debug_W_Beam1_Q[6]), //(15 DOWNTO 0); .probe15(debug_W_Beam1_Q[7]) //(15 DOWNTO 0); );
`timescale 1ns / 1ps module Get_AandB_vaild_module( input clk , input reset , input A_valid , //权值有效---是一个脉冲信号 input B_valid , //---是一个脉冲信号 output AB_vaild ); /* step 1:保证a,b 是一个脉冲(仅持续一个clk) */ reg A_valid_delay; reg a_pulse; // 是一个脉冲信号 always@(posedge clk) begin A_valid_delay<=A_valid; if(A_valid_delay==1'b0 && A_valid==1'b1)//抓取信号的上升沿 begin a_pulse<=1'b1; end else begin a_pulse<=1'b0; end end reg B_valid_delay; reg b_pulse; // 是一个脉冲信号 always@(posedge clk) begin B_valid_delay<=B_valid; if(B_valid_delay==1'b0 && B_valid==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) 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 AB_vaild=c_pulse; always@(posedge clk) 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。