提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
FPGA经验谈系列文章——时序不过怎么办
跟FPGA打交道这么多年,多多少少总会碰到一些时序问题。时钟越来越高,资源利用率越来越多,到了一定时候,免不了时序报表会爆红。
总结下来大概有如下原因:
1、 时钟频率过高
2、 资源利用率过大
3、 逻辑级数过大
4、 扇出过大
5、 资源拥塞
等这些情况。
下面大概写一些我之前碰到过的一些场景,以及解决的办法
这个时候就不建议通过修改代码来进行优化了,首先在设计验证和测试几乎完成的情况下,证明你这套逻辑已经经过了层层考验,不会出什么问题。如果这个时候还通过改功能模块来优化时序有可能引入新的不确定因素,还得花很多时间来验证才行。
在这个时候一般的做法是多开几个策略来进行综合或者布局布线。举个简单的例子,因为只是偶尔会出现时序不过的情况,假设概率为0.3。那么如果有3个策略同时编译,则3个都不过的概率就变成0.027了。这样只要哪个策略时序通过了我们就用哪个策略生成的结果即可。
有时候几乎每把编译都是那几个路径爆红,很有可能就是那几条路径组合逻辑级数实在是太多了,有时候组合逻辑的逻辑级数甚至到了十几级,这个时候就最好优化一下了。在组合逻辑中间插入一下触发器来降低整体逻辑级数一般就能解决这个问题。
首先这个最有可能出现的就是复位信号了,因为大部分童鞋都喜欢用
Always @(posedge i_clk or negedge i_rst_n)
这种写法了。甭管什么逻辑,实现啥功能,都先来一个这样的帽子。
这样就引出了一个问题,i_rst_n是整个工程扇出最大的信号了。这个特别是资源用的比较多得时候就会暴雷了,每次时序违例都是一大堆跟i_rst_n有关的。但绝大多数时候我们的功能是不需要i_rst_n复位的。因此在这里还是强烈推荐大家不用在FPGA设计中使用复位,可以参考我之前的博文。在资源用的很多的时候这个问题会更加明显。
那这是复位信号可以删掉,如果是其他功能信号呢。
如果是无法忽略的信号,那要么就做
(1) 逻辑复制,以增加资源来减少扇出。
(2) 或者某些情况下我们了解其信号特性,并不需要下一个时钟周期就做出响应的话,可以使用multicycle约束。这样,触发器之间的时延就可以成倍增加了,大大缓解了其布线压力
某一块的逻辑功能特别大,组合逻辑也多,但又不太容易优化,只能说我们在设计的时候不要引入太多不必要的一些控制信号,这里有一个控制集的概念:
触发器中的Flip-flops和flip-flop/latches有着相同的控制信号,CLK,SR, CE等等。那么对用户来说最重要的事情就是尝试着减少用户设计中的控制信号的数量。用户需要加强对控制信号的行为的理解:所有Flip-flops和flip-flop/latches共享所有这些控制信号,这些控制信号主要是时钟,置位和复位。如果一个组中的一个flip-flop用了时钟使能信号,那么所有其他的Flip-Flop必须使用相同的时钟使能或者不用时钟使能。如果一个组中的一个flip-flop用了置位或者复位信号,那么所有其他的Flip-Flop必须使用相同的置位或者复位信号。
这也是经常会出现的资源使用过多得时候,编译不过时vivado会提示的一个错误,但实际上FF和LUT的资源利用率又没有这么高,因此在设计的心里就要有这个意识,尽量减少控制集,例如都不用复位,而不是有些用有些又不用之类的。
例如我之前看到一篇文章,里面有一个这样的题目:
1) 以下这些案例能不能把这两个寄存器放在同一个slice里面?
注:所有控制信号都是直接驱动触发器的控制信号。
– 案例 1
• FF1: Clock, CE, Set
• FF2: CLK, CE, Set
– 案例 2
• FF1: CLK, CE, Reset
• FF2: CLK, Reset
– 案例3
• FF1: CLK, CE, Reset
• FF2: CLK, CE, not Reset
– 案例 4
• FF1: CLK, CE, Reset
• FF2: CLK, CE, Reset
案例1:不能。触发器有不同的时钟,所以它们有不同的控制组的。
案例2:不能。FF2具有时钟使能,所以它们有不同的控制组的。
案例3:不能。FF2无法提供翻转逻辑,所以它们有不同的控制组的。
案例4:能。两个触发器具有完全相同的控制信号,所以它们是相同的控制组的成员。可以被放在同一个Slice里面。
赶紧把你的vivado升级到最新的,实际上还有一个最大的变量就是,你的时序还跟vivado软件的布局布线的内部算法有很大的关系。每次更新版本有可能在这方面做一些改进,有可能之前版本解决不了的时序问题,到了后面的版本就没有了,这点其实也是经常有的事。
碰到这种情况是比较头痛的了,这意味着你的设计有可能无法达到既定要求。当前的时钟和资源利用率已经超出了片子的承受范围。这种情况下无法通过小修小补就能让时序收敛,只能从整个方案设计来看是否有妥协的办法。
(1) 最直接的办法只能是降时钟频率了,头痛医头脚痛医脚嘛,时序不过,说明目前设计时钟频率过高。但大部分情况下是不能这么降系统时钟的,降系统时钟很有可能意味着整体性能的下降,很可能出现无法达成既定指标的情况。
(2) 审视所有功能模块,看看所有模块的数据吞吐量是否有不同的情况。例如我之前弄过FPGA暴力破解算法。A模块是接口模块和路由通路,B模块是解密核心算法。B模块的时钟快慢决定性能的好坏,因此B模块时钟越快越好。但B模块运算时间较长,因此不要A模块这么快的速度传递数据。因此A模块时钟可以用更慢的时钟。
这样比A/B模块都用一个时钟对于时序的压力会减轻。当然这只是一个例子,每个不同的功能都要进行具体的分析,有些是可以优化的,有些的实在没办法就只能从性能上进行取舍了。
时序和资源就是一个矛盾体。当资源利用率不高的时候,可能啥问题都没有。一旦资源利用率上来了,各种问题就暴露了。因此需要在设计的时候就注意上述提到的点,例如扇出、逻辑级数等,再后面就很可能能减少这类时序问题。
因为这类经验还是需要自己去经历,去感悟。只要实际经历过并且去解决了问题才会更深刻的理解。因为我也经历也不一定算多,可能写的也不全面,同时其他大佬可能也有其他更好的办法或者遇到过不同的案例也欢迎指导。
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
我在我的Rails3示例应用程序上使用CarrierWave。我想验证远程位置上传,因此当用户提交无效URL(空白或非图像)时,我不会收到标准错误异常:CarrierWave::DownloadErrorinImageController#createtryingtodownloadafilewhichisnotservedoverHTTP这是我的模型:classPaintingtrue,:length=>{:minimum=>5,:maximum=>100}validates:image,:presence=>trueend这是我的Controller:classPaintingsC
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于
我正在研究使用EventMachine支持的twitter-streamrubygem来跟踪和捕获推文。我对整个事件编程有点陌生。我如何判断我在事件循环中所做的任何处理是否导致我落后?有没有简单的检查方法? 最佳答案 您可以通过使用周期性计时器并打印出耗时来确定延迟。如果您使用的是1秒的计时器,您应该已经过了大约1秒,如果它更长,您就知道您正在减慢react器的速度。@last=Time.now.to_fEM.add_periodic_timer(1)doputs"LATENCY:#{Time.now.to_f-@last}"@
啊,正则表达式有点困惑。我正在尝试删除字符串末尾所有可能的标点符号:ifstr[str.length-1]=='?'||str[str.length-1]=='.'||str[str.length-1]=='!'orstr[str.length-1]==','||str[str.length-1]==';'str.chomp!end我相信有更好的方法来做到这一点。有什么指点吗? 最佳答案 str.sub!(/[?.!,;]?$/,'')[?.!,;]-字符类。匹配这5个字符中的任何一个(注意,。在字符类中并不特殊)?-前一个字符或组