0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何写出时序最优的HDL代码?如何写出时序裕量足够的代码?

FPGA攻城狮之家 来源:FPGA攻城狮之家 2024-03-12 09:59 次阅读

你想写出可以跑出700M以上的代码吗,直逼FPGA内部PLL的极限。

你想写出时序裕量足够的代码吗,让你的代码不会出现时序违例。

你想在时序违例时能轻松应对吗?让代码轻松越过时序这道门槛。

这篇文章就是一步步向你解释,如何理解代码中的时序,以及如何解决代码中的时序违例问题。

之前的文章中提到过,工程中ISP算法模块轻松跑到了762.5M的频率,整个ISP链路没有优化的情况下跑到400M的时钟频率(xilinx的us+系列)。

573357de-dfa1-11ee-a297-92fbcf53809c.png

这篇文章将逐步解开HDL代码中的时序之谜,并且让你轻松应对FPGA中的时序问题。我将从实际工程的ISP算法模块出发,从设计到时序违例的查找,一步步提高代码的时序性能。

在第一个ISP模块DPC中,我使用了一个在3x3的矩阵中查找中值的模块,也就是大家常用的中值滤波器。是不是很多人都设计过,先不着急觉得是否简单,而是看如何把算法移植和时序的思想灌入到这个模块之中。

首先假设你已经得到了一个3x3的矩阵,简单看看设计思想:

在3x3 窗口中获取9 个数据,对9 这个数据值进行排序,排序步骤如下

A)窗内的每行数据找到最大值、中间值和最小值;

B)把三列的最小值相比较,取其中的最大值;

C)把三列的最大值相比较,取其中的最小值;

D)把三列的中间值相比较,再取一次中间值;

E) 再把B,C,D 中得到的三个值再排序,获取中值。

5752fd00-dfa1-11ee-a297-92fbcf53809c.png

有了设计思想就有了灵魂,剩下的是如何构建一个有血有肉的躯体了。经过思考不难发现,9个数的中值滤波变成了3次在3个数中找最大值,最小值,中值。

第一次:执行步骤A。

第二次:执行步骤B,C,D .

第三次:执行E 。

第一次三行D1,D2,D3并行,第二次三列Dxmax,Dxmed,Dxmin并行,第三次在剩下的三个数里面找到中值,运算完毕。所以9个数据的中值查找的设计,变成了一个只需要解决三个数据里面找到max,med,min的设计。

是不是觉得这太简单了。别急,听我继续分析:

既然是在三个数据里面排序,那就需要两两比较,于是就是需要比较3次。A 与B ,B与C,A与C。现在假设A

好,此时另一个误区可能就要出现了。因为flag可能为0也可能为1,那么你得到了三个flag,一共有多少种情况呢?可能有人不假思索地回答8种,因为3bit数据,2^3= 8 ,所以就是8 种。其实不是,用概率与统计的知识,三个数据的排序应该是有C31* C21 * C11 = 6 种。真值表如下

A B A
0 0 0 max=A,min = C
0 0 1 不存在
0 1 0 max=A,min = B
0 1 1 max=C,min = B
1 0 0 max=B,min = C
1 0 1 max=B,min = A
1 1 0 不存在
1 1 1 max=C,min = A

算法分析完毕,剩下的就是代码设计了。首先你需要进行三次比较。

575de5ee-dfa1-11ee-a297-92fbcf53809c.png

5778e9f2-dfa1-11ee-a297-92fbcf53809c.png

针对上述代码,画出对应的数字电路示意图,(mux的三个输入端省略了datx_reg)

577fdba4-dfa1-11ee-a297-92fbcf53809c.png

我假设FPGA内部按照上图所示的方式进行布局布线,那么最长数据路径应该是dat2_reg→comp_12 → mux3. (或者说是dat2_reg→ comp_23 → mux1)这条路径也就被称之为最长路径或者关键路径。时序分析工具干的事情就是,分析这条最长路径(当然其他路径也分析)上的时序是否满足条件。

单独把这条路径抠出来,它就是这样子的。于是,STA静态时序分析的模型就出来了,计算reg到reg之间的延迟,两个reg之间,经历了一个比较器和一个多路选择器这两个组合逻辑。

578396e0-dfa1-11ee-a297-92fbcf53809c.png

如果上述的路径因为走线(linelatency)延迟,或者是因为逻辑延迟(logiclatency)过大导致了时序违例,那么我们就应该在两个组合逻辑之间插入reg。从电路上,应该如下图所示。

57900e84-dfa1-11ee-a297-92fbcf53809c.png

那么从代码的角度,应该这样修改,就可以达到上图的效果:

579b305c-dfa1-11ee-a297-92fbcf53809c.png

好了,有了这个参考模板,再去看其他的中值滤波代码,你就知道要从哪里去优化了。

为了让大家更好的理解时序,我在网上找了两个用相同的算法思路设计的开源的代码。看他们的设计方法

三方代码 1

57abe53c-dfa1-11ee-a297-92fbcf53809c.png

三方代码 2

57b1092c-dfa1-11ee-a297-92fbcf53809c.png

可以看到数据比较的时候,逻辑明显有冗余,EDA工具不一定能自动优化。

然后我将两个三方的代码,以及我自己的代码放入同一工程中进行编译,故意加大时钟频率,让它们出现时序违例,从而找出关键路径。

三方的两个模块我例化成 median_filter_3x3 ,和 medfilter3by3 ,用vivado2022.1进行编译。得到时序违例报告

57be6acc-dfa1-11ee-a297-92fbcf53809c.png

再进一步分析关联路径1,得到了如下图所示的路径示意图

57c8d76e-dfa1-11ee-a297-92fbcf53809c.png

可以看到在两个 reg之间有4个逻辑块,然后再去代码中找到相应的位置。然后再追究到代码内部。

57dbd22e-dfa1-11ee-a297-92fbcf53809c.png

57e00344-dfa1-11ee-a297-92fbcf53809c.png

可以看到,代码中多次出现重复性的数据比较,这都是数据优化的方向。具体的位置就是 33-37行,最后vivado推测出第37行,需要经过4级组合逻辑才能将dat3 赋值给 mid_dat 。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21326

    浏览量

    593216
  • 滤波器
    +关注

    关注

    158

    文章

    7332

    浏览量

    174784
  • 比较器
    +关注

    关注

    14

    文章

    1526

    浏览量

    106491
  • HDL
    HDL
    +关注

    关注

    8

    文章

    323

    浏览量

    47104
  • PLL电路
    +关注

    关注

    0

    文章

    91

    浏览量

    6281

原文标题:基于FPGA的 ISP代码精讲1 —— 如何写出时序最优的HDL代码

文章出处:【微信号:gh_99a29eb83412,微信公众号:FPGA攻城狮之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    进行RTL代码设计需要考虑时序收敛的问题

    更快,而一个坏的代码风格则给后续时序收敛造成很大负担。你可能要花费很长时间去优化时序,保证时序收敛。拆解你的代码,添加寄存器,修改走线,最后
    的头像 发表于 11-20 15:51 3437次阅读
    进行RTL<b class='flag-5'>代码</b>设计需要考虑<b class='flag-5'>时序</b>收敛的问题

    何为高质量的代码如何写出高质量代码

    懂得“数据结构与算法” 写出高效的代码,懂得“设计模式”写出高质量的代码
    发表于 08-02 09:44 455次阅读
    何为高质量的<b class='flag-5'>代码</b>?<b class='flag-5'>如何写出</b>高质量<b class='flag-5'>代码</b>?

    如何写出好的代码?高质量代码的三要素

    脍炙人口的诗"春有百花秋有月,夏有凉风冬有雪",意境唯美,简明易懂。好的代码也是让人陶醉的,那么如何写出好的代码
    的头像 发表于 01-05 11:29 657次阅读
    <b class='flag-5'>如何写出</b>好的<b class='flag-5'>代码</b>?高质量<b class='flag-5'>代码</b>的三要素

    如何写出可以让人理解的代码(以verilog语言为例)?

    如何写出可以让人理解的代码(以verilog语言为例)?1. 代码要比较好理解,最容易做到的就是把代码写短,因此在每个always语句块尽可能只处理一个信号,或者只处理一组相关度很高的
    发表于 02-01 11:39

    如何利用时钟芯片DS1302来分析时序图并写出代码

    以时钟芯片DS1302为例子来分析时序图并写出代码
    发表于 04-02 06:00

    如何写出高效并且简洁易于阅读的单片机C语言代码呢?

    单片机的运行除去需要硬件的支持之外,高效简洁的C语言也是非常重要的因素之一。那么如何写出高效并且简洁易于阅读的单片机C语言代码呢?本文将为大家介绍如何写出优美简洁 的单片机循环语句,感兴趣的朋友快来
    发表于 07-15 06:34

    如何写出多串口共用printf函数语句呢

    如何写出多串口共用printf函数语句呢?求大神解答
    发表于 11-17 06:37

    如何写DA转化代码

    如何写DA转化代码:s: 即startADDRESS: 即器件地址(0表示为写)A:表示等待回应CONTROL BYTE: 表示控制字(第二个发送的字节)A:表示等待回应DATE BYTE: 表示写入的电压值(注意如果写入255,其实结果是5v,以此来换算)A:表示等待
    发表于 02-16 07:48

    用C语言如何写出单片机延时程序,且延时时间如何计算的?

    用C语言,如何写出单片机延时程序,且延时时间如何计算的?
    发表于 10-18 08:19

    介绍了五个简单的总体概念 可轻松写出写出代码

    我认为应该建立起良好的心态,这样,不管你用什么语言或者库,都会自然而然的写出高质量的代码。这里我主要谈到 5 个相关的概念。记住它们,轻松写出写出
    的头像 发表于 01-10 14:00 5534次阅读
    介绍了五个简单的总体概念 可轻松<b class='flag-5'>写出</b><b class='flag-5'>写出</b>好<b class='flag-5'>代码</b>

    教你如何写出性能更高的SystemVerilog代码

    本文旨在帮助大家降低在编码过程中写出低性能和耗内存的概率,只要大家在写代码时稍注意下,积少成多。
    的头像 发表于 07-26 17:31 599次阅读
    教你<b class='flag-5'>如何写出</b>性能更高的SystemVerilog<b class='flag-5'>代码</b>

    如何写出高效的嵌入式C语言程序

    作为嵌入式工程师,怎么写出效率高、思路清晰的C语言程序呢?
    发表于 08-18 10:42 179次阅读

    如何写出易维护的嵌入式代码怎么写?

    面向对象的语言更接近人的思维方式,而且在很大程度上降低了代码的复杂性,同时提高了代码的可读性和可维护性,传统的 C 代码同样可以设计出比较易读,易维护,复杂度较低的优美代码,本文将通过
    发表于 08-23 09:42 147次阅读
    <b class='flag-5'>如何写出</b>易维护的嵌入式<b class='flag-5'>代码</b>怎么写?

    C语言如何写出高效代码呢?

    当涉及复杂的高效C代码案例时,这些代码示例展示了C语言中一些复杂且高效的应用案例,涵盖了排序算法、图算法、位操作、文件操作、多线程编程等领域。
    发表于 09-06 14:57 195次阅读
    C语言<b class='flag-5'>如何写出</b>高效<b class='flag-5'>代码</b>呢?

    如何写出高效优美的C语言代码

    电子发烧友网站提供《如何写出高效优美的C语言代码.pdf》资料免费下载
    发表于 11-18 10:55 0次下载
    <b class='flag-5'>如何写出</b>高效优美的C语言<b class='flag-5'>代码</b>