一、IN_FIFO位置约束
LOC的使用
1、synthesisànetlistà找到目标cell并选中,右击àCell Properties,如下图:
2、复制“Name”后面的内容,这个是Cell的名字,等会LOC约束会用到;
3、依次点击“WindowàDevice”打开device窗口,在窗口里找到Cell理想的位置,如下图(左);选中理想的site后,在左侧的Site Properties窗口里面的“Name”选项后面就是该Site的代号,如下图(右)。
4、LOC约束语法:
set_property LOC “Site” [get_cells “Name of cell”]
5、本例中最终的LOC约束为:
set_property LOC IN_FIFO_X0Y7 [get_cells *******/*******/*******/in_fifo_inst_0]
end///
————————————————
二、其他约束
约束:
1,I/O引脚分配
set_property PACKAGE_PIN <pi_name> [get_ports <port>]
2,I/O引脚驱动能力设置
set_property DRIVE <2 4 6 8 12 16 24> [get_ports <ports>]
3,I/O引脚电器标准设置
set_property IOSTANDARD <io standard> [get_ports <ports>]
4,I/O引脚抖动设置
set_property SLEW <SLOW\FAST> [get_ports <ports>]
5,I/O引脚上拉设置
set_property PULLUP true [get_ports <ports>]
6,I/O引脚下拉设置
set_property PULLDOWN true [get_ports <ports>]
7,I/O引脚差分设置
set_property DIFF_TERM <true> [get_ports <ports>]
1,时钟生成
create_clock -name <clock_name> -period <period> [get_ports <clock port>]
2,输入延时
set_input_delay <max delay> -max -clock [get_clocks <clock>] [get_ports <ports>]
set_input_delay <min delay> -min -clock [get_clocks <clock>] [get_ports <ports>]
3,输出延时
set_output_delay <delay> -clock [get_clocks <clock>] [get_ports <ports>]
消除端口到寄存器之间的路径延时:
set_property IOB TRUE [get_ports ***] //将端口***前的寄存器放在I/O bank内的寄存器中.
设置不相关时钟即路径:
set_false_path -from <startpoints> -to <endpoints>
设置多周期约束:
set_multicycle_path -from [get_pins <startpoints> ] -to [get_pins <endpoints>] <2>
位置约束:
//PLL
set_property LOC PLLE2_ADV_X*Y* [get_cells PLL路径及例化名]
//MMCM
set_property LOC MMCME2_ADV_X*Y* [get_cells MMCM路径及例化名]
//BUFG
set_property LOC BUFGCTRL_X*Y* [get_cells BUFG路径及例化名]
//BUFH
set_property LOC BUFHCE_X*Y* [get_cells BUFH路径及例化名]
//FIFO
set_property LOC OUT_FIFO_X*Y* [get_cells out_fifo路径及例化名]
set_property LOC IN_FIFO_X*Y* [get_cells in_fifo路径及例化名]
防止综合后被优化:
(* DowngradeIPIdentifiedWarnings="yes" *) 加在module之前
BUFG BUFH BUFR BUFIO区别及使用:
BUFG:全局时钟网络,即可以到达整个芯片的任意位置;一般芯片都有16或32个;
BUFH:水平区域时钟网络,可以给水平方向的相邻的时钟网络使用;每个bank有12个;
BUFR:区域时钟网络,给本IObank时钟网络使用,每个IObank有4个;
BUFIO:IO时钟网络,一般都作用于MRCC,SRCC;专用时钟引脚;每个IObank有4个;
原语:
使用操作内部信号;
STARTUPE2 #(
.PROG_USR ("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ (0 ) // Set the Configuration Clock Frequency(ns) for simulation
) STARTUPE2_inst(
.CFGCLK (), // 1-bit output: Configuration main clock output
.CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output
.EOS (), // 1-bit output: Active high output signal indicating the End Of Startup.
.PREQ (), // 1-bit output: PROGRAM request to fabric output
.CLK (0), // 1-bit input: User start-up clock input
.GSR (0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
.GTS (0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
.KEYCLEARB (1), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
.PACK (1), // 1-bit input: PROGRAM acknowledge input
.USRCCLKO (flash_clk), // 1-bit input: User CCLK input
.USRCCLKTS (0), // 1-bit input: User CCLK 3-state enable input
.USRDONEO (1), // 1-bit input: User DONE pin output control
.USRDONETS (1) // 1-bit input: User DONE 3-state enable outpu
);
跨时钟域原语:
xpm_cdc_array_single #(
.DEST_SYNC_FF(4),
.INIT_SYNC_FF(0),
.SIM_ASSERT_CHK(0),
.SRC_INPUT_REG(1),
.WIDTH(16)
) xpm_cdc_array_single_inst (
.dest_out( ),
.dest_clk( ),
.src_clk ( ),
.src_in ( )
);
函数:
$fopen 打开文件;
$fclose 关闭文件;
$display 打印
$fdisplay, $fwrite, 写文件
$fgetc, $fgets, $fscanf, $fread 读文件
$fseek, $ftell 文件定位
$readmemh, $readmemb 存储器加载
(实例:fd文件描述符定义使用 integer )
: fd = $fopen("filename",mode) //fd为返回值为一个32位的文件描述符;(mode:w,a,rb,wb,ab,r+,w+,a+,rb+,wb+,ab+)
: $fclose(fd) //关闭fd描述的文件
: $display("hello this is file %d",fd); //打印文件名为filename的文件描述符号
: $fdisplay(fd,"xxxxxxxxxxx"); //往fd文件中写文件 自动换行
: $fwrite(fd,"xxxxxxxxxxx"); //往fd文件中写文件 不自动换行
: c = $fgetc(fd); //按字符格式将fd输出给c;
: code = $fgets(str,fd); //按字符连续读,放到str, 直到str满, 或一行读完;
: code = $fscanf(fd, format, args) //按格式format将文件fd中数据读到args
: code = $fread(store, fd, start, count) // 按二进制数据流格式将数据从文件读到store; start为文件起始文件,count读取长度.
: op = $ftell(fd) //返回当前文件指针位置;
: op = $fseek(fd, offset, type) //配置指针位置; offset 对应偏移; type偏移类型;(0: 设置到偏移位置; 1: 当前位置加偏移, 2: 文件尾加偏移)
: $readmemh("filename",mem,start_addr,finish_addr) //按mem变量读文件从start地址到finish地址;
问题记录:
1,约束问题
问题分析:
该项目中用了两片DDR,3个4X的SRIO和1个1X的SRIO;另外有8路X1的SATA;其中DDR分别在BANK13和BANK16,也就是如下图中的X0Y2和X0Y5;SRIO分别位于BANK111,BANK112,BANK113,BANK114,也就是如下图的X1Y0,X1Y1,X1Y2,X1Y3;
DDR控制器MIG需要一个MMCM和一个PLL做时钟管理;SRIO核需要一个MMCM做时钟管理;该芯片只有8个MMCM和32个BUFG;因为BUFG资源不够;因此SRIO核的部分局部时钟使用了BUFH资源。因此再布局的时候,MMCM就要使用就近MMCM资源。
因为X0Y2上的MMCM被DDR占用,因此X1Y2上的SRIO就只能使用远端X0Y4上的MMCM。而再使用BUFH资源时,就会出错。
解决方法:
(1)将DDR需要的MMCM和PLL放到XOY4上;
(2)此处发现MMCM和PLL中间有一个BUFH资源,也将它放到X0Y4附近;
(3)将SRIO需要的MMCM资源依次分布在X0Y0,X0Y1,X0Y2,X0Y3;
(4)将BUFH放在对应的X1Y0,X1Y1,X1Y2,X1Y3处。
具体修改约束如下:
DDR相关约束:
set_property LOC PLLE2_ADV_X0Y2 [get_cells -hier -filter {NAME =~ */u_ddr3_infrastructure/plle2_i}]
set_property LOC MMCME2_ADV_X0Y2 [get_cells -hier -filter {NAME =~ */u_ddr3_infrastructure/gen_mmcm.mmcm_i}]
set_property LOC BUFHCE_X0Y59 [get_cells -hier -filter {NAME =~ */u_ddr3_infrastructure//u_bufh_pll_clk3}]
SRIO相关约束:
set_property LOC MMCME2_ADV_X0Y0 [get_cells srio_ctrl_inst/u_srio_1x/SRIO_CORE_INST/srio_x1_clk_inst/srio_mmcm_inst]
set_property LOC MMCME2_ADV_X0Y1 [get_cells srio_ctrl_inst/u_srio_4x/u1_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/srio_mmcm_inst]
set_property LOC MMCME2_ADV_X0Y2 [get_cells srio_ctrl_inst/u_srio_4x/u2_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/srio_mmcm_inst]
set_property LOC MMCME2_ADV_X0Y3 [get_cells srio_ctrl_inst/u_srio_4x/u3_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/srio_mmcm_inst]
set_property LOC BUFHCE_X1Y0 [get_cells srio_ctrl_inst/u_srio_1x/SRIO_CORE_INST/srio_x1_clk_inst/gt_clk_bufh_inst]
set_property LOC BUFHCE_X1Y1 [get_cells srio_ctrl_inst/u_srio_1x/SRIO_CORE_INST/srio_x1_clk_inst/phy_clk_bufh_inst]
set_property LOC BUFHCE_X1Y2 [get_cells srio_ctrl_inst/u_srio_1x/SRIO_CORE_INST/srio_x1_clk_inst/drpclk_bufh_inst]
set_property LOC BUFHCE_X1Y3 [get_cells srio_ctrl_inst/u_srio_1x/SRIO_CORE_INST/srio_x1_clk_inst/gt_pcs_clk_bufh_inst]
set_property LOC BUFHCE_X1Y12 [get_cells srio_ctrl_inst/u_srio_4x/u1_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_clk_inst]
set_property LOC BUFHCE_X1Y13 [get_cells srio_ctrl_inst/u_srio_4x/u1_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/phy_clk_bufh_inst]
set_property LOC BUFHCE_X1Y14 [get_cells srio_ctrl_inst/u_srio_4x/u1_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_drpclk_inst]
set_property LOC BUFHCE_X1Y15 [get_cells srio_ctrl_inst/u_srio_4x/u1_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_pcs_clk_inst]
set_property LOC BUFHCE_X1Y24 [get_cells srio_ctrl_inst/u_srio_4x/u2_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_clk_inst]
set_property LOC BUFHCE_X1Y25 [get_cells srio_ctrl_inst/u_srio_4x/u2_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/phy_clk_bufh_inst]
set_property LOC BUFHCE_X1Y26 [get_cells srio_ctrl_inst/u_srio_4x/u2_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_drpclk_inst]
set_property LOC BUFHCE_X1Y27 [get_cells srio_ctrl_inst/u_srio_4x/u2_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_pcs_clk_inst]
set_property LOC BUFHCE_X1Y36 [get_cells srio_ctrl_inst/u_srio_4x/u3_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_clk_inst]
set_property LOC BUFHCE_X1Y37 [get_cells srio_ctrl_inst/u_srio_4x/u3_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/phy_clk_bufh_inst]
set_property LOC BUFHCE_X1Y38 [get_cells srio_ctrl_inst/u_srio_4x/u3_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_drpclk_inst]
set_property LOC BUFHCE_X1Y39 [get_cells srio_ctrl_inst/u_srio_4x/u3_srio_4x_ctrl_1/SRIO_INST_4x/srio_clk_inst/BUFH_gt_pcs_clk_inst]
2.ADV7931 SDI 芯片IIC配置时序
发现问题: IIC读寄存器数据时,一次对一次错?
排查问题:用ila抓IIC时序发现有时ACK不能正确响应;
解决问题:该芯片时序要求比较严谨;读最后一个数据之后到读停止中间必须为一个no ack;不然会导致下一次读数据出错;
3.AD ltc2141 接口逻辑问题
发现问题:图像采集到后噪点很多;
排查问题:用示波器在板上测试;发现波形挺好;再ila发现采集到的数据毛刺很多,又很明显的时钟数据不对齐现象;
解决问题:发现硬件上没有给LVDS信号的时钟和数据做终端匹配电阻,逻辑代码为其增加终端匹配电阻;代码如下:
————————————————