fpga如何约束走线_FPGA时序约束实战篇之多周期路径约束

多周期路径约束

多周期路径,我们一般按照以下4个步骤来约束:

1. 带有使能的数据

首先来看带有使能的数据,在本工程中的Tming Report中,也提示了同一个时钟域之间的几个路径建立时间不满足要求

其实这几个路径都是带有使能的路径,使能的周期为2倍的时钟周期,本来就应该在2个时钟周期内去判断时序收敛。因此,我们添加时序约束:

set_multicycle_path 2 -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_path 1 -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文件中,也存在带有使能的数据,但这些路径在未加多路径约束时并未报出时序错误或者警告。

在接收端,捕获时钟频率是200MHz,串口速率是115200,采用16倍的Oversampling,因此使能信号周期是时钟周期的200e6/115200/16=108.5倍。

在接收端,捕获时钟频率是166667MHz,串口速率是115200,采用16倍的Oversampling,因此使能信号周期是时钟周期的166.667e6/115200/16=90.4倍。

因此,时序约束如下:

# 串口接收端

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参数也将在下一章节具体讲解。

2. 两个有数据交互的时钟之间存在相位差

在本工程中,没有这种应用场景,因此不需要添加此类约束。

3. 存在快时钟到慢时钟的路径

在本工程中,没有这种应用场景,因此不需要添加此类约束。

4. 存在慢时钟到快时钟的路径

在本工程中,没有这种应用场景,因此不需要添加此类约束。

综上,我们所有的时序约束如下:

# 主时钟约束

create_clock -period 25.000 -name clk2 [get_ports clk_in2]

# 衍生时钟约束

create_generated_clock -name clk_samp -source [get_pins clk_gen_i0/clk_core_i0/clk_tx] -divide_by 32 [get_pins clk_gen_i0/BUFHCE_clk_samp_i0/O]

create_generated_clock -name spi_clk -source [get_pins dac_spi_i0/out_ddr_flop_spi_clk_i0/ODDR_inst/C] -divide_by 1 -invert [get_ports spi_clk_pin]

create_generated_clock -name clk_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 -name clk_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 -period 6.000 -name virtual_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 -clock virtual_clock -max 0.000 [get_ports lb_sel_pin]

set_input_delay -clock virtual_clock -min -0.500 [get_ports lb_sel_pin]

set_output_delay -clock virtual_clock -max 0.000 [get_ports {txd_pin {led_pins[*]}}]

set_output_delay -clock virtual_clock -min -0.500 [get_ports {txd_pin {led_pins[*]}}]

set_output_delay -clock spi_clk -max 1.000 [get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]

set_output_delay -clock spi_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_path 2 -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_path 1 -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 108 -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_path 107 -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_path 90 -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_path 89 -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'b0};

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中,这样就不会导致时序问题了。

本文转自:科学计算technomania,作者:猫叔,转载此文目的在于传递更多信息,版权归原作者所有。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uml 类图_UML-类图

概念Class diagram is UML structure diagram which shows structure of the designed system at the level of classes and interfaces, shows their features, constraints and relationships - associations, generalizations, dependencies, etc.类图是用于描述类、接口这一…

牙齿间隙变大怎么办_牙齿之间的间隙越来越大怎么办?

无论我们是否发现牙齿与牙齿之间有很大的裂缝问题&#xff0c;这不仅影响到面部的美观&#xff0c;而且对正常的饮食、咀嚼疲劳也有一定的影响。随着我国生活条件的改善&#xff0c;人们对生活质量的要求也越来越高&#xff0c;同时也开始关注自己的口腔状况&#xff0c;牙齿问…

python读取文件中的内容_python 读取文件夹中的文件内容

看thinking in java的时候发现有个题的答案不确定结果&#xff0c; 于是下载答案看下&#xff0c;结果是这个样子的,这样要怎么才能找到相对应的答案&#xff1f;于是我就着手写了一个快速遍历的脚本&#xff08;我这里只是单纯的找了出来&#xff0c; 没有把找到的文件单独拿出…

C语言编程日志,用C语言打印日志(Log)

用C语言打印日志(Log)直接上源代码。log.h 文件&#xff1a;/** log.h **/#ifndef __LOG_H__#define __LOG_H__#include "stdio.h"#include "string.h"#include "stdlib.h"#include "time.h"#include "stdarg.h"#include &q…

binlog数据库不写入binlog_京东智联云MySQL数据库如何保障数据的可靠性?

MySQL作为当前最流行的关系型数据库&#xff0c;在各个行业的系统中扮演着最重要的角色。随着大家对数据价值认可的逐步加深&#xff0c;数据的可靠性是最常被问到的一个问题。MySQL是如何保证数据可靠性的&#xff1f;京东智联云RDS-MySQL又做了哪些优化和新特性来保证用户数据…

在职高学C语言程序设计,中职学校C语言程序设计教学方法.doc

中职学校C语言程序设计教学方法中职学校C语言程序设计的教学方法摘 要&#xff1a;计算机专业中&#xff0c;C语言是一门基础的程序设计课&#xff0c;但学习《C语言程序设计》相对职高学生来说难度较大&#xff0c;但它却是很实用的一门课程&#xff0c;同时又是我省计算机对口…

js和python哪个好_Python与Node.JS:哪一个比较适合您的项目?

在进行新项目时选择正确的编程语言可能是程序员经常做出的比较艰巨的决定之一。这个挑战背后的原因是&#xff0c;每个新项目都会遇到一个独特的问题&#xff0c;并且在编程世界中&#xff0c;没有任何行业的大师。 不同的编程语言都有其长处和短处&#xff0c;这使其适用于某些…

typescript的类型描述_一文学懂TypeScript的类型

你将学到什么阅读本文后&#xff0c;你应该能够理解以下代码的含义&#xff1a;interface Array{concat(...items: Array): T[];reduce(callback: (state: U, element: T, index: number, array: T[]) >U,firstState?: U): U;}如果你认为这段代码非常神秘 —— 那么我同意你…

equation在c语言中是什么意思,MathType出现此对象创建于Equation中的问题怎么办

使用MathType出错的窗口&#xff1a;MathType程序停止工作提醒窗口&#xff1a;解决方法如下&#xff1a;1.打开Word文件&#xff0c;在Word菜单中选择“工具”——“模板和加载项”&#xff0c;将会跳出一个模板和加载项的对话框。在Word菜单中选择“工具”——“模板和加载项…

python messagebox弹窗退出_python 弹窗提示警告框MessageBox的实例

需要安装pywin32模块&#xff0c;pip install pywin32 ##pip install pywin32 import win32api,win32con ##提醒OK消息框 win32api.MessageBox(0, "这是一个测试提醒OK消息框", "提醒",win32con.MB_OK) ##是否信息框 win32api.MessageBox(0, "这是一个…

gradle是否可以编译c语言,build.gradle按条件编译与cmake配置

在build.gradle里面通过productFlavors就可以方便的实现不同的编译方案。flavorDimensions定义维度flavorDimensions 从单词字面理解知道是 “风味维度”&#xff0c;是需要结合 “产品风味(即productFlavors)” 来一起使用的。flavorDimensions 的使用会定义出维度&#xff0c…

post请求改成body_post请求body格式

在PostMan中用Post方式&#xff0c;Body有form-data,x-www-form-urlencoded,raw,binary四种。其中raw又分以下7种。现在来区分一下&#xff1a;form-data是http请求中的multipart/form-data,它会将表单的数据处理为一条消息&#xff0c;以标签为单元&#xff0c;用分隔符分开。…

windows多用户 文件夹不共享_手把手教你如何使用Tekla多用户

Tekla有多用户模式&#xff0c;对于大模型需要多人合作很有用&#xff0c;可以多人同时建模互不干扰&#xff0c;下面简单说下多用户建立过程。 首先需要参与模型的计算机处于同一局域网内&#xff0c;一般来说公司都有局域网&#xff0c;或者办公室内就是一个小局域网&#xf…

roads 用户体验标准_世界智能大会与ROAD用户体验报告

近期由国家发展和改革委员会、科学技术部、工业和信息化部、国家互联网信息办公室等共同举办的2020年第四届世界智能大会在天津云上展开&#xff0c;超过百余位智能科技领域的知名专家和企业家参与了大会过程&#xff0c;其中车联网领域专家关于5G车联网”推进中国特色的车路协…

android 组件路由框架,XRouter:组件化路由框架

添加jitpack仓库allprojects {repositories {...maven { url https://jitpack.io }}}添加依赖&#xff1a;dependencies {//kotlin 使用kapt编译时依赖注解&#xff0c;Java使用annotationProcessorkapt com.github.roger1245.XRouter:xrouter-compiler:1.0.2api com.github.ro…

hystrix原理_面试必问的SpringCloud实现原理图

引言面试中面试官喜欢问组件的实现原理&#xff0c;尤其是常用技术&#xff0c;我们平时使用了SpringCloud还需要了解它的实现原理&#xff0c;这样不仅起到举一反三的作用&#xff0c;还能帮助轻松应对各种问题及有针对的进行扩展。以下是《Java深入微服务原理改造房产销售平台…

android 图片跑马灯动画,ImageView 图片循环跑马灯的效果

不解释了 直接上代码了main.xml布局文件&#xff0c;记住必须用RelativeLayout将ImageView重叠android:orientation"vertical" android:layout_width"fill_parent"android:layout_height"fill_parent" android:id"id/rl">android:…

Rust Trait

Rust 第16节 Trait Trait 告诉编译器 某种类型具有那些并且可以与其他类型共享的功能 它的本质就是 不同类型具有的相同行为 声明一个trait 关键字 trait;只有方法签名&#xff0c;没有方法实现 pub trait Animal {// trait 的声明,一个trait中可以有多个方法fn say(&s…

c++ string类的常用方法_【常用类方法】Object

Object类的知识点总结概述&#xff1a;1. Object类是所有其他类的父类2. Object类只有一个构造方法&#xff0c;这也是为什么所有子类在调用构造方法时都会默认先调用父类的无参构造方法3. Object类没有成员变量方法&#xff1a;1. public int hashCode()2. public final Class…

android 收获地址管理,android UiAutomator添加收货地址的用例

本人在学习UiAutomator的时候&#xff0c;遇到添加收获地址的测试用例&#xff0c;这里的地址的地区是一级一级选择的。所以写了一个随机选择的方法。分享出来&#xff0c;供大家参考。public void addAdress() throws UiObjectNotFoundException {login();waitForResourceIdAn…