文章目录

  • 前言
  • 时空变换之空域优化
    • 逻辑化简
    • 资源合并
    • 模块复用之分时复用
    • 静态重构
    • 动态重构
    • 思路转换

前言

这是三月的第二篇博客,不得不说的是,有点儿怀念在实验室学习写博客的感觉(当然,并不怀念项目缠身,整日被催进度的噩梦日子),两个大屏幕,一台换了固态硬盘,因此还算流畅的台式电脑,简直不要太爽。平日里最讨厌用笔记本电脑,是因为觉得笔记本的键盘和鼠标很不人性化,这下好了,关键时期,笔记本成为了最依赖的东西,用笔记本打字也顺畅了,都是惯得。哈。当然最重要的还是学习氛围,在家是容易懒惰的,我宁愿打打游戏度日,也不愿坐在桌子前去思考一些复杂的问题,这是大脑惰性的选择。
好啦,这些日子也只能想想啦,也许这样的日子,哪怕一天也不会再有啦,我总是顾虑的,考虑到最坏的情况,疫情结束恐怕还是遥遥无期,毕竟学校不是一个随便开玩笑的地方,人口大量聚集,一起上课,一起吃饭,集体宿舍,这都给传染病提供了最好的传染途径,因此,疫情不结束,恐怕难以开学,更何况开学之后还有很多事情要处理,要么关乎毕业,要么。。。
进入正题,上篇博客是关于时域优化的内容, 回忆一下吧。
时域优化也就是对时序上的问题进行优化,例如我想更快的时钟去处理事件,而更快的时钟要求更精进的设计以及硬件条件要跟得上,假设硬件条件(FPGA)能跟得上,那么剩下的问题就是设计的问题了。
设计的问题,包括冗余的问题,这就需要对逻辑表达式进行化简,简洁之道,但是鉴于FPGA内部结构的特殊性,例如使用LUT进行组合逻辑的实现,因此,过于化简也未必就是好事,也许出现反常现象,这个具体看上篇博客吧。
其次进行时域优化的方法是结构调整,通过结构调整,可以使得某些设计或者某部分设计的关键路径变得更加的优化(更短),这就有利于时序。
再者就是分布调整,这个就很好理解,例如过长的组合逻辑(过于复杂的组合逻辑),分开实现等等,可以解决组合逻辑耗时过长的问题,有利于时序的优化。
就这样吧,更多的可以参考上篇博客。
本篇博客讨论的依然是时空变换问题,着重于空域优化,摘自《FPGA之道》,作者对于这方便的描述可谓是独到,让我们一起站在巨人的肩膀上,学习下作者对于此部分内容的见解。

时空变换之空域优化

本小节我们主要关注空域内部的优化方法。注意,在做空域优化时,往往是不以牺牲时域余量为前提的,因为它的目的主要是去除空域内部的一些冗余。接下来,将为大家介绍几类比较常用的空域优化方法:

逻辑化简

正如我们在【时空变换之时域优化->逻辑化简】小节中所讨论的,采用逻辑化简的方法不仅对提高时域方面的性能有好处,对提高空域性能方面也具有很好的效果,不过受制于FPGA芯片所基于的LUT结构以及编译器的优化功能,我们并不需要在此花费过多精力,仅需在我们的HDL代码中稍作注意,剔除明显且过分的组合逻辑冗余即可。具体的逻辑化简方法,可以参考【共同语言篇->数字逻辑电路基础知识->数字逻辑的化简】章节。

资源合并

资源合并是提高空域余量的另一个好方法,它的原理有点类似于数据压缩,即当FPGA设计中需要同时用到两个以上功能一样的模块时,想办法让其功能变为单个模块的N倍,但是资源的膨胀却小于单个模块的N倍,这样一来,便给空域腾出了可观的余量。注意,资源合并的方法并不是对任何情况都适用的,而且它还必须以资源本身有余为前提,即在当前条件下,资源并没有被充分使用。下面,我们就以FPGA内部的BRAM资源为例,来介绍一下具体的资源合并情况。
BRAM是FPGA内部一个比较灵活的资源,假设,某一型号FPGA芯片内部每一块BRAM的容量为8kbits,可以被配置成为1bit x 8k、2bits x 4k、4bits x 2k、8bits x 1k、16bits x 512 以及32bits x 256这几种可供选用的RAM形式。
如果我们需要缓存1路连续的数据,数据位宽均为8bits,缓存深度要求为512个采样,那么此时,我们可以选取8bits x 1k或16bits x 512这两种BRAM配置模式,来得到可以满足当前缓存要求的RAM。注意,此时无论选用上述两种中哪一种配置模式,BRAM资源都没有被充分使用——对于8bits x 1k模式来说,有一半的存储空间被闲置了;而对于16bits x 512模式来说,有一半的数据位宽被浪费了。
现在假设我们需要同时缓存两路这样的连续数据,那么大脑中的第一反应估计就是为2路数据都创建一个独立的缓存,而这样一来,就需要2块BRAM资源。每块BRAM资源的存储容量为8kbits,可是每路路数据仅需要缓存容量为4kbits,这也就是说,如果仅仅看存储容量的话,那么其实1块BRAM就足够应付这2路数据的缓存了。不过虽然FPGA内部的BRAM一般都是双口RAM,有两套独立的读、写及控制总线,但是高吞吐的数据缓存一般都是采用A写B读的操作模式(详见【本篇->编程思路->数据的存储->双口RAM的HDL描述与用法】小节),因此两套端口都被占用,所以即便是缓存第1路数据的BRAM中有多余的空间,由于它已经没有多余的读、写及控制端口供第2路数据使用,因此也不能贸然合并,这便是资源合并方法所受到的限制。不过如果这2路数据在此仅仅是需要一个缓存操作,并且对于缓存的读、写并没有特别不同于彼此的要求,那么我们其实可以将它们看做1路位宽为16bits的连续数据,这样便可以将BRAM配置成为16bits x 512的模式,来同时对它们进行缓存。这样一来,整个缓存电路的功能变为原来的两倍,但BRAM资源却仍然只需要1个,因此,总的资源膨胀率将会远小于2倍,为空域争取了客观的余量。

模块复用之分时复用

模块复用可分为两类:第一类是分时复用,它也是针对处理当FPGA设计中需要用到两个以上功能一样的模块时的空域优化需求,但分时复用与资源合并的方法有着本质不同,那就是分时复用针对的是不同时使用的多个功能相同模块的空域优化,而资源合并针对的是需要同时使用的多个功能相同模块的空域优化,这点是需要明确清楚地。模块复用的第二个类别是提速复用,这是以牺牲时域余量为前提的,因此将在后续的【时空变换之时间换空间】小节中予以介绍,而本小节则主要关注模块分时复用的方法。
模块分时复用的思路很简单,当一个模块的功能需要在多处使用时,如果这些使用不会同时发生,那么就可以考虑按照时间来分配该模块的使用权,从而达到该模块只需要被例化一次,但却可以为多个逻辑块提供服务。这就好比在家里看电视一样,晚上67点,动画片时间,小孩子最爱看;晚上78点,新闻时间,一路随着新中国走来的老一辈最爱看;晚上8~10点,各类肥皂剧以及综艺节目,工作压力较大的中青年人士最爱看。这样一来,虽然电视只有一台,但是各个年龄段人的需求都得到了满足,而分时复用也就是如此而已。注意,分时复用的方法同样也无法对任何情况都适用,而且它也必须以资源本身有余为前提,即在当前条件下,资源并没有被充分使用。下面我们仍以BRAM为例,来介绍一下具体的时分复用情况。
假设FPGA系统中有两个不会同时执行的任务——任务1和任务2,它们分别需要缓存第1路、第2路的数据,数据的宽度为8bits,缓存深度要求仍为512。与【资源合并】小节中的例子类似,在最开始的时候,我们通常会为每一个任务分配一个BRAM作为缓存,可以看出,此时资源仍然没有被充分利用,因为任务1执行的时候任务2所使用的BRAM处于闲置状态,反之,任务2执行的时候任务1所使用的BRAM也处于闲置状态。但与【资源合并】小节的例子又不同,本例中,任务1和任务2是不会同时执行的,因此我们在缓存第1路数据的时候无法同时也去缓存第2路数据,故难以应用资源合并的方法来优化空域。不过,如果任务1及任务2每次的执行都完成了本次所有数据的写入和读取操作,那么我们就可以让任务1和任务2来分时复用1个BRAM,从而在仅使用1个BRAM的条件下就完成了任务1和任务2的数据缓存需求,大大提高了空域的余量。但是,若任务1及任务2并不是每次执行都完成了本次所有数据的写入和读取操作,那么分时复用的方法就难以派上用场,这便是分时复用方法的制约。例如,现在共有四个任务,任务1、任务2分别负责将接收到的第1路、第2路数据写入缓存中,而任务3、任务4分别负责将缓存中的第1路、第2路数据读出。此时,即使这四个任务中,没有哪两个会同时执行,我们仍然不能使用分时复用的方式来优化空域,因为如果仍然想仅使用1个BRAM作为缓存的话,会给系统带来操作错误。例如,如果任务1执行完成之后,下一个触发的任务不是任务3,那么就会带来错误——如果下一个任务是任务2,那么BRAM中保存的第1路数据将会被覆盖,这样下次任务3执行的时候将无法读出正确的数据;如果下一个任务是任务4,那么由于BRAM中保存的是第1路数据,所以任务4读出的数据也是错误的。
类似的例子还有累加器的使用,如果串行发生的每个任务都能在它的执行过程结束后得到需要的累加结果,那么累加器就可以被多个任务复用;如果某个任务需要被多次调用后才能得到最终的累加结果,那么就必须为它单独分配一个累加器。

静态重构

FPGA芯片为什么需要配置?因为一旦掉电,FPGA芯片便变成一张白纸,不再具有任何有意义的逻辑功能,所以我们需要在每次系统上电的时候,采用在【知己知彼篇->FPGA芯片的配置方法】章节中介绍的那些FPGA芯片的配置方法,来对FPGA芯片进行配置,从而使得FPGA芯片具有我们预期的逻辑功能。
恰恰是FPGA芯片这种使用前需要配置的特征,可以被利用来进行空域优化,要想弄明白其中原因,我们需要先搞清楚一个问题,那就是对于一个被配置好的FPGA芯片,它将保持这配置好的功能到什么时候呢?答案有两个:一、系统掉电时,二、另外一次配置。没错,正是这利用这第二个答案,使得更加宏大的空域优化成为可能,这便是FPGA芯片的静态重构技术。
静态重构其实是更加宏观一些的分时复用,只不过之前介绍的分时复用指的是FPGA设计内部某一个模块或者某一个资源的分时复用,而静态重构,指的是整个FPGA芯片的分时复用。
静态重构技术的具体操作方式,其实就是提前针对多种不同的需求编译出多个不同的FPGA配置文件,然后在系统运行时,根据每个时段的不同需求,利用了FPGA芯片的被动配置模式或者JTAG配置模式,选择性的将具有对应功能的配置文件下载到FPGA芯片当中并开始工作。由于静态重构技术其实就是分时复用的宏观扩展,因此它的应用也受到相同的限制,不过对于那些适合应用静态重构技术的情况,其对空域方面的优化那是非常非常可观的!下面,我们就通过一个例子来对静态重构技术进行更为形象的了解:
假设你现在需要在FPGA上实现一个通用的视频编码器,即能够根据需求将输入的原始图像序列压缩为当前主流的mpeg2、mpeg4或h264等视频流并发送出去。在视频压缩领域中,往往编码要远比解码复杂,因此,我们先假设实现一个基本的mpeg2编码器需要相当于400万门的等效逻辑资源、实现一个基本的mpeg4编码器需要相当于700万门的等效逻辑资源、实现一个基本的h264编码器需要相当于600万门的等效逻辑资源。如果你现在是在做一个产品,那么你需要考虑成本,因此你做了市场调研,查到了如下两个型号的FPGA芯片的价格:
FPGA_CHIP_A —— 1000万门、40美元;
FPGA_CHIP_B —— 2000万门、100美元;
请问你该选择哪款芯片来开发你的产品呢?
如果你的方案是在FPGA内部同时实现mpeg2、mpeg4及h264这三个编码器,然后根据实际情况每次使能其中一个作为当前工作的视频压缩引擎,那么你需要选择FPGA_CHIP_B,这样每一个产品上的FPGA相关成本为100美元。
如果你在设计方案的时候参考了静态重构技术,那么你的方案可能是这样的:针对mpeg2、mpeg4及h264各建立一个单独的FPGA工程,并分别编译出三个单独的配置文件分别对应mpeg2、mpeg4及h264编码功能,然后根据实际情况,每次载入一个配置文件到当前的FPGA芯片中以实现相应的视频压缩功能。此时,你就可以选择FPGA_CHIP_A,如果存储多个配置文件需要花费10美元购买相应的存储芯片或微处理器,那么现在每一个产品上的FPGA相关成本仅为50美元,比上一方案节省了50美元,由此可见静态重构技术对空域方面的贡献以及其伟大之处。

动态重构

还有什么技术比静态重构更激动人心的吗?有!那就是动态重构!
动态重构仍然是分时复用技术的延伸,不过相比于静态重构,它在某些方面有着不可比拟的优越性:
首先,静态重构是整个FPGA芯片的重构,哪怕两个设计之间仅仅有一点不同,也必须对FPGA芯片进行大换血;而动态重构则可以针对FPGA设计中的某一个小部分进行重新配置,同时保持其他部分的状态不变。
其次,静态重构的过程中,整个FPGA芯片处于配置状态,此时所有I/O端口均处于输出或者高阻状态,因此不能进行工作;而动态重构仅影响FPGA芯片中的一部分逻辑,因此其他逻辑部分在动态重构过程中仍可以进行正常工作。
第三,静态重构一般耗时较长,这一点,容量越大的FPGA芯片感觉就越明显,有时候配置一次恐怕要用到几秒或十几秒;而动态重构仅针对性的修改某一小部分逻辑,并且可以选择更加快捷的下载机制,因此配置过程耗时短。
最后,并不是所有的FPGA芯片都支持静态重构的,例如基于反熔丝的FPGA芯片,但是我们有办法让所有的FPGA芯片都支持动态重构。
列举了这么多的优点,那到底什么是动态重构技术呢?其实动态重构就是一种在FPGA运行的过程中,通过某种方法动态的改变其某一部分电路所对应逻辑功能的技术。如果你对本书开始的内容还有印象,可以发现这好像与【共同语言篇->硬件描述语言->软件编程思路与FPGA编程思路的区别->执行方式对比->资源占用与释放】小节中的介绍的内容相冲突,因为在那一小节中,我们明确的阐述了FPGA编程中不存在对资源动态的申请与释放,那么动态重构又是怎么在FPGA芯片中实现的呢?
其实在【本篇->编程思路->状态机,FPGA的灵魂->状态机的实现方式->基于RAM的实现方式浅析】小节中,我们已经引出了动态重构的一些概念和应用,大家可以回顾一下。还记得组合逻辑是如何在FPGA芯片中实现的吧?没错,这是查找表(LUT)的功劳。LUT就像是一张空白的真值表,你填成什么样子,它就具有什么样的功能。那么LUT是什么?LUT其实就是数据存储啊!这也是为什么我们在【本篇->编程思路->数据的存储】章节中将一个看似不起眼的数据存储功能说的如此神乎其神,好像离了它FPGA芯片就不运行一样,因为事实真的就是如此。FPGA的配置过程,其实就是将配置文件的内容写入FPGA芯片的过程,这实际上就是一个数据存储的过程。但是,显然在FPGA运行的时候,我们无法重复这一数据存储的过程,因为除了静态重构方法以外,我们几乎没有方法去修改FPGA芯片所基于的那个特殊的SRAM中的数据内容(不过随着技术的进步,相信FPGA的集成开发环境会逐渐支持对该SRAM的非配置修改的)。不过在FPGA运行的时候,倒是给我们提供了不少可供使用的数据存储资源,例如触发器、查找表、BRAM甚至片外存储芯片等。因此,与LUT可呈现出多种不同功能一样,任何数据存储都可以被看做一张真值表,只要能够动态的修改数据存储中的内容,就相当于动态的修改了它的逻辑功能。数据存储中的内容可以被动态修改么?当然,因为FPGA中的数据存储载体都可以以RAM的形式出现。综上所述,动态重构技术就是利用RAM作为逻辑功能的载体,通过运行时修改RAM中的内容,来到达逻辑功能的动态改变,因此对空域性能有着很好的提升。下面我们仍以BRAM为例,来介绍一下具体的动态重构技术的使用:
仍以一个8kbits的BRAM为例,若我们将其配置为8bits x 1k的模式,那么其地址总线addr应该为10bits,数据总线data应该为8bits。
如果我们需要实现一个乘法功能Y = AxB,若A、B均为4bits位宽,那么其结果用一个8bits的数便可以完全表示。此时,我们将该BRAM的地址总线连接到““00” + A + B”(此处+号为连接符),然后动态的修改BRAM中地址0~255的内容如下即可:
0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、
0、1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、
0、2、4、6、8、10、12、14、16、18、……
0、3、6、9、12、……
……
0、15、30、45、60、……225。
如果接下来又要实现一个除法的功能Y = A / B,若A为8bits、B为2bits,那么其结果用一个8bits的数便可以完全表示。此时,我们将该BRAM的地址总线连接到“A + B”(此处+号为连接符),然后动态的修改BRAM中地址0~1023的内容如下即可:
*、0、0、0、(*号表示不关心,因为被除数不应该为0)
*、1、0、0、(商的整数结果采用去尾法得到)
*、2、1、0、
*、3、1、1、
*、4、2、1、
*、5、2、1、
……
*、255、127、85。
如果接下来又想实现一个波形发生器,产生一个方波,那么则可以使用一个10bits计数器的计数值连接到BRAM的地址总线,然后动态的修改BRAM中地址0~1023的内容类似如下即可:
0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、
80、80、80、80、80、80、80、80、80、80、80、80、80、80、80、80、
0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、
80、80、80、80、80、80、80、80、80、80、80、80、80、80、80、80、
……
如此这般,只要修改一次BRAM中的存储内容,就完成了一次动态重构操作,只要不断的修改,就可以仅仅利用一块BRAM实现出成千上万种行为迥异的逻辑,这是一项多么令人激动的技术啊!

思路转换

思路转换同样也是提高空域性能的一个好方法,关于它的具体讨论,可以参照【时空变换之时域优化->思路转换】小节。

FPGA之道(60)时空变换之空域优化相关推荐

  1. FPGA之道(59)时空变换之时域优化

    文章目录 前言 时空变换之基本概念 时空概念简介 时空变换方案 时空变换之时域优化 逻辑化简 逻辑化简讨论 空域方面的颠倒现象 时域方面的颠倒现象 逻辑化简总结 结构调整 分布调整 思路转换 提前进位 ...

  2. FPGA之道(61)时空变换之时间换空间

    文章目录 前言 时空变换之时间换空间 逻辑合并 模块复用之提速复用原理 简单提速复用 复杂提速复用 一个简单的FIR滤波器 FIR滤波器的转置结构 多路FIR滤波需求初步分析 提速后的问题分析 FIR ...

  3. FPGA之道(69)提高设计的综合性能(一)提高设计的鲁棒性

    文章目录 前言 提高设计的鲁棒性 一些影响设计正常工作的原因 非法输入 环境干扰 应对方法之输入预处理 应对方法之RAM替换FIFO 应对方法之状态机超时跳转 应对方法之三模冗余 应对方法之全局复位 ...

  4. FPGA之道(81)静态时序分析(七)根据时序报告修改设计(基于ISE的UCF文件语法)

    文章目录 前言 根据时序报告修改设计 时序分析报告示例 待分析设计 时序约束文件 时序报告简介 报告综述 内部时钟报告 输入接口报告 输出接口报告 输出数据延迟报告 输出时钟延迟报告 同步输出综合报告 ...

  5. FPGA之道(62)时空变换之空间换时间

    文章目录 前言 时空变换之空间换时间 缓存提速使用 模块复制 同频模块复制 缓存降频复制 缓存降频使用 逻辑拆分 流水线 流水线的由来 如何在组合逻辑中使用流水线 如何在时序逻辑中使用流水线 顺序系统 ...

  6. FPGA之道(50)复位的设计

    文章目录 前言 复位的设计 为什么FPGA设计中要有复位 复位方式的分类 同步复位 异步复位 复位的设计方法 同步信号同步复位 同步信号异步复位 异步信号同步复位 异步信号异步复位 复位高扇出的解决方 ...

  7. FPGA之道(42)FPGA设计的分类

    文章目录 前言 设计的分类 按功能分 按面向分 按速度和规模分 按速度分 按规模分 按速度.规模分 前言 本文摘自<FPGA之道>,一看来学习下作者的看法. 设计的分类 抛开应用背景.科研 ...

  8. FPGA之道(84)功能仿真之Verilog Test Fixture

    文章目录 前言 Verilog Test Fixture "Hello world"之Verilog Test Fixture 待仿真设计 仿真示例 示例详解 仿真结果 继承描述语 ...

  9. FPGA之道(83)功能仿真之仿真语法(Graphic Waveform )

    文章目录 前言 仿真语法 Graphic Waveform 数字波形简介 从实际到仿真 实际系统检测 软件仿真模拟 "Hello world"之Graphic Waveform 待 ...

最新文章

  1. Win7开机密码破解
  2. python中哪里用到缩进_Python编程常见十大错误
  3. sqlite 实例教程 IOS下用sqlite打造词典
  4. 字节码中的两个方法init,clinit
  5. 编程之美-寻找数组中的最大值和最小值方法整理
  6. 永劫无间为啥显示连接服务器失败,永劫无间服务器故障怎么办?永劫无间服务器故障解决办法...
  7. Python | 使用matplotlib.pyplot创建条形图
  8. 卡巴斯基误杀奇虎360
  9. ★LeetCode(669)——修剪二叉搜索树(JavaScript)
  10. python求解LeetCode习题Compare Version Numbers
  11. 明日之后怎么在电脑上玩 明日之后电脑版图文攻略
  12. 一文读懂自然语言处理NLP
  13. MySQL 5.7.17.0 下载安装笔记
  14. 基于JAVA美发店预约系统设计与实现
  15. 二叉树——推荐一些神奇的网站
  16. NVIDIA GPU的浮点计算能力
  17. 从零开始搭建公司后台技术栈
  18. java正则包含特殊字符_java – 捕获由特殊字符嵌套/包含的正则表达式组
  19. “用户名不在 sudoers文件中,此事将被报告” 解决方法
  20. 利用python预测交通拥堵_Python可视化轻松展示交通拥堵情况

热门文章

  1. 解决XP系统下HTTP 错误 403.9 - 禁止访问:连接的用户过多的问题
  2. python答辩结束语_2018-08-17 结束答辩
  3. 4*4按键扫描程序c语言,【资料】单片机4*4矩阵键盘扫描程序(c语言+汇编语言2个版本)...
  4. 青铜峡高级中学2021高考成绩查询,2021年吴忠高考成绩排名及成绩公布时间什么时候出来...
  5. 计算机一级考模拟试题,计算机一级MSOffice考前模拟试题「附答案」
  6. 子对象是什么java_面向对象编程(什么是对象)——java
  7. python运维脚本部署jdk_Jenkins自动执行Python脚本,并输出测试报告
  8. mysql数据库导入到excel表格数据_[转载]将EXCEL表格中的数据导入mysql数据库表中(两种方法)...
  9. 基于RT-Thread开发智能视觉组智能车-乐山师范学院
  10. 在CDF可以插入特殊字符编码