FPGA编程易错点

1 编程、测试注意点

(1) 如果工程移植过去有问题,需要检查IP的设置是否和原来一模一样。
还需注意IP以及IP加载的coe文件路径是否在新工程的路径下。
(1)当程序仿真没有问题时,但是硬件测试有问题时,此时可以去综合文件。看看致命警告和警告,并修复警告。
(2)对一个信号的控制,只能在一个always语句内。在多个always语句内可能会导致时序错误;而且出现多驱动网络。
(3)编写一个模块时,要顺时进行两次数据。避免第二次相关指令下发时,没有数据或者标志信号输出。
(4)如果某模块的输出信号的标志信号是一个脉冲信号,那么一定要测试当输入信号的标志信号顺序来两个脉冲时,输出信号的标志信号是否也是两个脉冲。
(5)当vivado的工程实际测试的时候,如果波形不对。如何查找问题?
第一步:MATLAB的定点仿真和vivado的testbench的数据逐一对比。如果没有问题进入第二步。
第二步:MATLAB的定点仿真和vivado的ILA的数据逐一对比。
(6)程序里面的计数器count,在完成一次计数后,要清零,避免影响下一次的计数。
(7)在比较大小时,我们定义了一个temp值,最后比较完成后,temp值记得清零。
(8)使用累加器accumulator_ip时,一定要在声明信号时就给初值,例如 reg add_valid =0

(9)如果循环语句的使用出现问题,综合工具会给出提示,如Vivado的提示信息如下:

[Synth 8-3380] loop condition does not converge after 2000 iterations 

因为Vivado不支持动态调节的循环

(10)在 Xilinx FPGA 中,DSP Slice 能够用作累加器、加法器、减法器、除法器和乘法器。当需要这些功能时,最好使用 DSP slice 而不是 LUT/Fabric 来执行此操作。这将减少花在设计优化以及设计结束时的时序收敛上的时间。

有些设计需要非常高的时钟频率才能工作,在这种情况下,DSP Slice可以大大减少时序问题。

2 使用加法,注意数据位宽的变化

// 下面两行代码,求和后的位宽不对
//assign BB_stI=Freq1_stI+Freq2_stI+Freq3_stI+Freq4_stI+Freq5_stI
//             +Freq6_stI+Freq7_stI+Freq8_stI+Freq9_stI+Freq10_stI; 
 
// 为什么需要扩展4位
// 两2个信号相加需要扩展1位,4个信号相加需要扩展2位,8个信号相加需要扩展3位,16个信号相加需要扩展4位,
 wire [19:0] y;  //位宽:20
 assign  y =   {Freq1_stI[15],Freq1_stI[15],Freq1_stI[15],Freq1_stI[15],Freq1_stI}
              +{Freq2_stI[15],Freq2_stI[15],Freq2_stI[15],Freq2_stI[15],Freq2_stI} 
              +{Freq3_stI[15],Freq3_stI[15],Freq3_stI[15],Freq3_stI[15],Freq3_stI}
              +{Freq4_stI[15],Freq4_stI[15],Freq4_stI[15],Freq4_stI[15],Freq4_stI}
              +{Freq5_stI[15],Freq5_stI[15],Freq5_stI[15],Freq5_stI[15],Freq5_stI}
              +{Freq6_stI[15],Freq6_stI[15],Freq6_stI[15],Freq6_stI[15],Freq6_stI}
              +{Freq7_stI[15],Freq7_stI[15],Freq7_stI[15],Freq7_stI[15],Freq7_stI}
              +{Freq8_stI[15],Freq8_stI[15],Freq8_stI[15],Freq8_stI[15],Freq8_stI}
              +{Freq9_stI[15],Freq9_stI[15],Freq9_stI[15],Freq9_stI[15],Freq9_stI};

 assign y_end =y[19:4];  //截位

3 DDS IP易错点

  DDS的输入信号s_axis_config_tdata( Calib_Freq)是由其他模块产生的,因为最开始频率字Calib_Freq还没有得到,Calib_Freq是没有值的,是无效的。如果s_axis_config_tvalid(1’b1)这样写,那么最后得不到波形。应该这样s_axis_config_tvalid(Calib_Freq_vaild),频率字有效时,给一个频率字有效信号。

dds_sin dds_sin_inst (
  .aclk(clk),                                   // input wire aclk
  .s_axis_config_tvalid(Calib_Freq_vaild),      // input wire s_axis_config_tvalid
  //.s_axis_config_tvalid(1'b1), //这样写就不对,因为最开始频率字Calib_Freq还没有得到,是无效的
  .s_axis_config_tdata( Calib_Freq),             // input wire [31 : 0] s_axis_config_tdata
 
  .m_axis_data_tvalid(),                        // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_PINC),         // output wire [31 : 0] m_axis_data_tdata
  .m_axis_phase_tvalid(),                       // output wire m_axis_phase_tvalid
  .m_axis_phase_tdata()                         // output wire [31 : 0] m_axis_phase_tdata
);

4 并行语句与串行语句

在一个clk,只要满足条件,并行语句全部同时执行。串行语句顺序执行。

<=  并行语句
 =  串行语句

5 乘法IP如何截位

在这里插入图片描述
为什么要两级HILBERT
第一级实部是输入信号本身,所以没有去掉直流,虚部是去掉了的,所有把虚部给第二级,从而去掉直流分量。其目的在于避免直流偏置

6 两个信号相乘特别需要注意时序

两个信号相乘时,数据A对应的采样点序号必须和数据B对应的采样点序号一一对应。这一点特别容易出错。
(和MATLAB仿真数据对比,从而验证数据是否一一对齐)

7 error:add_1 must be in range [-1,DEPTH-1]

在这里插入图片描述
这是由于控制信号vaild没有初始化所造成的

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值