技术标签: fpga如何约束走线
原标题:FPGA时序约束实战篇之多周期路径约束
多周期路径约束
多周期路径,我们一般按照以下4个步骤来约束:
带有使能的数据
首先来看带有使能的数据,在本工程中的Tming Report中,也提示了同一个时钟域之间的几个路径建立时间不满足要求
其实这几个路径都是带有使能的路径,使能的周期为2倍的时钟周期,本来就应该在2个时钟周期内去判断时序收敛。因此,我们添加时序约束:
set_multicycle_path2 -setup-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}]
set_multicycle_path1 -hold-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}]
也可以写为:
set_multicycle_path-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}] 2
set_multicycle_path-hold-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}] 1
这两种写法是等价的。
我们也可以直接点击右键通过GUI的方式进行约束,效果都是一样的。
在工程的 uart_tx_ctl.v 和 uart_rx_ctl.v 文件中,也存在带有使能的数据,但这些路径在未加多路径约束时并未报出时序错误或者警告。
因此,时序约束如下:
# 串口接收端
set_multicycle_path - from[get_cells uart_rx_i0 /uart_rx_ctl_i0/* -filter IS_SEQUENTIAL] -to [get_cells uart_rx_i0 /uart_rx_ctl_i0/* -filter IS_SEQUENTIAL] 108
set_multicycle_path -hold - from[get_cells uart_rx_i0 /uart_rx_ctl_i0/* -filter IS_SEQUENTIAL] -to [get_cells uart_rx_i0 /uart_rx_ctl_i0/* -filter IS_SEQUENTIAL] 107
# 串口发送端
set_multicycle_path - from[get_cells uart_tx_i0 /uart_tx_ctl_i0/* -filter IS_SEQUENTIAL] -to [get_cells uart_tx_i0 /uart_tx_ctl_i0/* -filter IS_SEQUENTIAL] 90
set_multicycle_path -hold - from[get_cells uart_tx_i0 /uart_tx_ctl_i0/* -filter IS_SEQUENTIAL] -to [get_cells uart_tx_i0 /uart_tx_ctl_i0/* -filter IS_SEQUENTIAL] 89
约束中的 filter 参数也将在下一章节具体讲解。
两个有数据交互的时钟之间存在相位差
在本工程中,没有这种应用场景,因此不需要添加此类约束。
存在快时钟到慢时钟的路径
在本工程中,没有这种应用场景,因此不需要添加此类约束。
存在慢时钟到快时钟的路径
在本工程中,没有这种应用场景,因此不需要添加此类约束。
综上,我们所有的时序约束如下:
# 主时钟约束
create_clock-period25 .000-nameclk2[get_ports clk_in2]
# 衍生时钟约束
create_generated_clock-nameclk_samp-source[get_pins clk_gen_i0/clk_core_i0/clk_tx]-divide_by32 [get_pins clk_gen_i0/BUFHCE_clk_samp_i0/O]
create_generated_clock-namespi_clk-source[get_pins dac_spi_i0/out_ddr_flop_spi_clk_i0/ODDR_inst/C]-divide_by1 -invert[get_ports spi_clk_pin]
create_generated_clock-nameclk_tx-source[get_pins clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKIN1][get_pins clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT1]
create_generated_clock-nameclk_rx-source[get_pins clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKIN1][get_pins clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT0]
# 设置异步时钟
set_clock_groups-asynchronous-group[get_clocks clk_samp]-group[get_clocks clk2]
# 延迟约束
create_clock-period6 .000-namevirtual_clock
set_input_delay-clock[get_clocks -of_objects [get_ports clk_pin_p]] 0 .000[get_ports rxd_pin]
set_input_delay-clock[get_clocks -of_objects [get_ports clk_pin_p]] -min-0.500[get_ports rxd_pin]
set_input_delay-clockvirtual_clock-max0 .000[get_ports lb_sel_pin]
set_input_delay-clockvirtual_clock-min-0.500[get_ports lb_sel_pin]
set_output_delay-clockvirtual_clock-max0 .000[get_ports {txd_pin {led_pins[*]}}]
set_output_delay-clockvirtual_clock-min-0.500[get_ports {txd_pin {led_pins[*]}}]
set_output_delay-clockspi_clk-max1 .000[get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]
set_output_delay-clockspi_clk-min-1.000[get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]
# 伪路径约束
set_false_path-from[get_clocks clk_rx]-to[get_clocks clk_tx]
set_false_path-from[get_ports rst_pin]
# 多周期约束
set_multicycle_path2 -setup-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}]
set_multicycle_path1 -hold-from[get_cells {cmd_parse_i0/send_resp_data_reg[*]} -include_replicated_objects] -to[get_cells {resp_gen_i0/to_bcd_i0/bcd_out_reg[*]}]
# 串口接收端
set_multicycle_path108 -setup-from[get_cells uart_rx_i0/uart_rx_ctl_i0/* -filter IS_SEQUENTIAL]-to[get_cells uart_rx_i0/uart_rx_ctl_i0/* -filter IS_SEQUENTIAL]
set_multicycle_path107 -hold-from[get_cells uart_rx_i0/uart_rx_ctl_i0/* -filter IS_SEQUENTIAL]-to[get_cells uart_rx_i0/uart_rx_ctl_i0/* -filter IS_SEQUENTIAL]
# 串口发送端
set_multicycle_path90 -setup-from[get_cells uart_tx_i0/uart_tx_ctl_i0/* -filter IS_SEQUENTIAL]-to[get_cells uart_tx_i0/uart_tx_ctl_i0/* -filter IS_SEQUENTIAL]
set_multicycle_path89 -hold-from[get_cells uart_tx_i0/uart_tx_ctl_i0/* -filter IS_SEQUENTIAL]-to[get_cells uart_tx_i0/uart_tx_ctl_i0/* -filter IS_SEQUENTIAL]
重新Synthesis并Implementation后,可以看到,已经没有了时序错误
仅有的两个warning也只是说rst没有设置input_delay,spi_clk_pin没有设置output_delay,但我们已经对rst设置了伪路径,而spi_clk_pin是我们约束的输出时钟,无需设置output_delay。
到这里,教科书版的时序约束教程就基本讲完了。但我们平时的工程中,跟上面这种约束还是有差异的:
首先是虚拟时钟,这个约束在平时的工程中基本不会用到,像需要设置虚拟时钟的场景,我们也都是通过设计来保证时序收敛,设置虚拟时钟的意义不大。
第二就是output delay,在FPGA的最后一级寄存器到输出的路径上,往往都使用了IOB,也就是IO block,因此最后一级寄存器的位置是固定的,从buffer到pad的走线延时是确定的。在这种情况下,是否满足时序要求完全取决于设计,做约束只是验证一下看看时序是否收敛。所以也基本不做。但是input delay是需要的,因为这是上一级器件输出的时序关系。
第三个就是多周期路径,我们讲了那么多多周期路径的应用场景,但实际我们是根据Timing report来进行约束的,即便那几种场景都存在,但如果Timing report中没有提示任何的时序 warning,我们往往也不会去添加约束。
第四个就是在设置了多周期后,如果还是提示Intra-Clocks Paths的setup time不过,那就要看下程序,是否写的不规范。比如
如果设置了多周期路径后,还是提示 Intra-Clocks Paths 的 setup time 不过,那就要看下程序,是否写的不规范。比如
always @ (posedge clk)
begin
regA <= regB;
if(regA != regB)
regC <= 4'hf;
else
regC <= {regC[2:0], 1' b 0};
if((&flag[ 3:0]) && regA != regB)
regD <= regB;
end
这么写的话,如果时钟频率稍微高一点,比如250MHz,就很容易导致从regB到regD的setup time不满足要求。因为begin end里面的代码都是按顺序执行的,要在4ns内完成这些赋值与判断的逻辑,挑战还是挺大的。因此,我们可以改写为:
always @ (posedge clk)
begin
regA <= regB;
end
always@ (posedge clk)
begin
if(regA != regB)
regC <= 4'hf;
else
regC <= {regC[2:0], 1' b0};
end
always@ (posedge phy_clk)
begin
if((&flag[ 3: 0]) && regA != regB)
regD <= regB;
end
把寄存器的赋值分开,功能还是一样的,只是分到了几个always中,这样就不会导致时序问题了。 返回搜狐,查看更多
责任编辑:
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法