数字IC入门之二(简单的算法架构)
Posted hit1719292537
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数字IC入门之二(简单的算法架构)相关的知识,希望对你有一定的参考价值。
这一节的核心内容要围绕“脑中有清晰的电路框架,再用Verilog简洁表达”来进行,虽然数字电路由于其稳定性使得可以用软件式的设计形式来进行电路设计,但是其与软件设计有着本质的区别,《Verilog HDL高级数字设计》中数字信号处理的算法与架构那一块有个例子,半色调像素图像处理器,强烈推荐这本书给大家,如果你看过了但是没看透彻,希望能反复看个3~5遍,这本书可以说是目前我见过的数字设计教材形式中最好的一本了,虽然我的看的也不是很多,但是真的这本书非常的重要,尤其是上面提到的数字信号处理算法架构方面,是通向更高层次(算法和架构)的桥梁,半色调图像处理器,不要被名字吓到,以为必须明白什么图像处理这些高深的概念,实际上你不要去管什么像素,而是去看他如何将for嵌套描述的算法转化为性能和面积权衡之后的电路。如果你没看过这本书,可能对我所说的半色调,什么算法架构感觉很困惑,不要着急,本段就是想表达《Verilog HDL高级数字设计》这本书的重要性。下面本人将用一些简单的例子抛砖引玉,说说要达到的目标和其中推荐的教材。
在写Verilog代码(设计代码并非验证代码)之前和之中,或者是之后的仿真甚至综合,数字设计者的脑中都应该一直存在电路清晰的框架,为了更确切的描述这个说法,我特意将上述半色调图像像素图像处理器的例子简化百分之七八十之后描述如下,我们来看看数字设计的关键在哪里?随着我们的分析,您可能逐渐认识到数字设计是性能、面积以及功耗的权衡,从而很清晰的认识到自己的前进目标是什么,这个时候我会推荐相关教程来告诉您哪些书可以帮助快速进阶:
首先算法设计师给了我们如下的代码(C写的),让我们去用数字系统实现:
以上算法的描述中全部型号名称为k,但是我们可以区分下输入和输入,并且分别以i和o来表示如下:
注意,下图以i命名的为模块的输入,而以o命名的为模块的输出,模块的输出或者在下一步直接作为下一模块的输入或者是被寄存,我们不关心,只是同时将符合上述算法的值同时输出即可,不得不提到行为综合,行为综合可以自动将以上行为描述综合为RTL代码,但是问题是目前还没有成熟的工具,我们拿到这一段代码后,将其for循环展开,画出如下的有向无环图:
以下进行叙述的时候,我尽可能使用白话,因为毕竟是抛砖引玉,说的太正式反而达不到目的,我们看上面的图,这个图就是由上面的嵌套的for循环得到的,其中黄色的为输入,橘黄色的为输出,按照for循环里面的索引,我们在图中也用行列来表示,其中i或者o后面的就是行数和列数的组合,比如o22就就表示这是一个输出节点,它处在第二行第二列,前面的是行后面的是列,那么线上面的123代表什么呢?for循环中的数乘项啊,如果你仔细对照for循环以及我们得出的图示,想要证明二者相等可能还需要我说明这个橘黄色的东西是个什么东西,好,那么下面我要展开这个橘黄色的东西让大家看看这个表示什么,我们以o12为例吧:
蓝色小圆圈表示的是乘法器,也就是说上面左图中的带箭头的线(术语叫有向边)上面的数字就是信号经过这条线的时候需要数乘的因子,举个例子,i01开始为3,那么i01沿着箭头方向流动的时候就从开始的3变为了6,上面左图中的三个箭头都指向了o12,也就是i01*2、i02*3和o11乘以1都流入了o12节点,o12节点会对这三个信号进行操作,具体操作就是用两个加法器将这流入节点的三个数字相加,得到输出o12,所以上面左图中的o12可以认为有两个意思,第一个就是把它看做节点的时候,它只的是一个操作,这个操作是将流入的三个信号两两相加,另一个意思就是它是一个信号o12,它本身作为一个变量又传到下一级运算了,作为下一级运算的输入,下文中所说的o12默认都是说它是一个信号,也就是取第二层意思。好了,到此为止,你已经明白了从嵌套的for循环如何得到有向无环图了,下面我把上面的有向无环图复制到下面,我们再从下面的图开始我们的讨论:
给出了如上所示的有向无环图,那么怎么设计电路呢?可以停在这里想一想,不去往下看,不要认为什么有向无环图多么深奥,就是个信号流程图而已。
好,或许你已经想到了,因为线的操作就是乘以1、2或者3,那么你在每个线的地方用乘法器替代,而每个橘黄色为将三个数相加,那么每个橘黄色部分用两个加法器替代,那么就把这个有向无环图用电路实现了不是吗,相应的硬件框图我画在了下面,跟你想的一样吗?
其中的黄色部分为原始输入,而每个浅蓝色部分就是输出,这个电路是纯组合逻辑,它的优点很容易看出,那就是它一定是速度最快的,给定输入,电路就开始运算,经过一定延迟之后,输出结果,没有时钟周期的划分,根据数据依赖关系,它会从左上角开始运算,逐渐从左上角向右下角进行运算(不要着急数据依赖关系,后面的分析会提到),好,现在你脑中已经有上面这个硬件框架图了,一旦这个硬件框架图在你脑中形成,Verilog代码就是把你头脑中这个图用Verilog语言“说”出来,说给谁听?“说”给验证人员听,“说”给综合人员听,好,根据上面的框架写出如下的代码:
然后在顶层例化9次,那么给定输入就可以得到9个输出了,这是一个小型的例子,无奈的是实际上的设计for循环描述的相当复杂,而且位宽往往很大,例如本例子中如果矩阵是100*100,确实这种设计速度是最快的,但是算算你需要多少硬件资源,假设输入为N比特位宽,每个点需要两个加法器(至少2N比特位宽)、三个乘法器(2N位宽),那么100*100你需要2万个2N位宽加法器,3万个2N位宽的乘法器,好吧,等你生产出来就等着赔本吧,所以这种性能很好,但是面积超出承受能力,甚至很夸张的设计根本不具有可行性。
这个时候你会想:既然面积不行,好,那么我就把面积减少到极致,于是你聪明的发现9*9阵列操作每个都是一样的,你想到了能否就用一个这种单元,然后用控制器在每个时钟周期进行一次运算呢?因为9*9阵列操作(图上的浅蓝色部分)都是一样的形式,只不过信号不同,如果你置身其中任何一个节点都会发现,你需要做的是把你左边的、左上边的和上边的分别数乘在加起来,这很容易看出,或许看到这里,你很难理解控制器怎么做到的,后续会有专门的控制器介绍,不要着急,我们假设控制器可以做到这一点,而且你也不要担心是否控制器本身会很大,或者很慢,答案是不会的,这个放心,控制器的逻辑一般会比数据通路小的多。
设想现在仅仅有一个上图所示的计算单元(2个加法器和3个乘法器)
比如:
第一个周期:根据i00、i01、i10计算出o11
第二个周期:根据o11、i01、i02计算出o12
... ...
最后一个周期:根据o32、o22、o23计算出o33
你会发现,这种写法的面积会很小,可以说达到了最小,不管你原始的for循环的指数为多少,也就是不管你的阵列达到多么庞大,只有控制器和存储器会随之增加,但是你要知道存储器增加一个存储单元它的面积不会有太大的增加,就算SRAM的六管逻辑也没有2个加法器和3个乘法器这种增加夸张,所以最后你得到了面积最小的设计,如果阵列为100*100,你设计好之后,当被询问到设计的性能之后,你回答说1万个周期,我想没有客户会满意,所以,最小的面积导致了夸张的性能劣势。所以下面我们要找到性能和面积的平衡点,也就是权衡面积和性能来找到一种折中的设计方法,数字电路的折中需要考虑的变量不是很多,不像模拟设计中需要考虑的八边形法则,线性度噪声等八个变量。
在进行折中考虑之前,我们要认清一个事实,就是上述有向无环图中的数据依赖关系,什么数据依赖关系,举个例子o21的计算需要i20和i10和o11,当后面三个计算出来结果之后,o21才能计算出结果,由于实际硬件都是有延迟的,不可能给定输入立即得到输出,所以o21结果的计算也不是立即,只能等i20和i10和o11计算出来之后才能被计算,这种现象就好比银行排队,以前我们去银行取钱的时候会排一个老长的队,你只能心烦意乱的在队里等着不能做什么事,时间被白白浪费了,所以现在银行取钱都是你取个号码,当到了你的时候广播系统会通知你过去办理业务,那么每次只有一个人在办理,长队也没有了,而广播系统就是一个控制器,它告诉你什么时候轮到你,好,让我们回到这个列子,我下面画一个图来表示数据依赖关系:
上图可以看到,当给定电路原始输入,也就是黄色正方形部分时,那么o11(也就是白色),9*9阵列中也就只有它可以被计算出来,你想计算o12,那是不可能的,因为o11结果还没有计算出来,上图中标记出了,首先计算白色,当白色计算完毕,计算红色,然后在计算灰色,之后是绿最后是蓝色,所以,一个权衡了面积与性能的设计思路出现了,我们仅仅使用3个运算单元(所谓的运算单元就是上面图中计算节点,也就是3个乘法器和2个加法器),为什么是三个而不是2个,因为如果是2个,那么当你计算灰色部分的时候就不能在一个周期完成,需要额外的两个周期,这样的计算周期不一致很可能导致控制器的复杂,所以这里用了3个操作单元,那么这种折中的设计方案是怎么操作的呢?
始终记得一点,我们的电路中存在四个独立的运算单元的,好,第一个周期,控制器把i00、i01、i10取来放到3个运算单元的随便一个计算出结果,你会问了,其他2个怎么办,其他2个不用管,它们的输入随意指定,控制器很明白它自己用了哪个有效的运算单元并且会去那个运算单元取出结果并且存在存储器里面,然后下一个周期,控制器把i01、i02、o11取出来放到一个运算单元的输入,同时取出i10、i20和o11放到第二个运算单元的输入,至于其他1个运算单元,不用去管,注意被选中的两个运算单元的计算是并行进行的。下面的操作类似,希望我把整个操作说清楚了,那么整个设计的面积如何呢?有3个运算单元(而不是9个),性能为4个时钟周期(而不是9个),这个差距在设计规模扩大之后会很明显,你可以自己验证一下,所以我们得到了面积和性能都可以接受的最终折中设计,下面我来画出整个结构框图,这个框图也是在你编写Verilog代码的时候脑中出现的。
上面就是整个最终的折中设计的结构框图,设计中的数据通路为三个运算单元,其Verilog描述非常简单,控制器为的接下来会有介绍,还有存储器如果没有双端口SRAM可以用寄存器来替代,存储控制器也很简单,其本质就是数据通路与SRAM的一个接口结构,所以整个Verilog描述不是特别困难,编写Verilog的难点在于协调各种状态和控制信号。
好了,数字电路简单的架构就说到这里,本文主要推荐的教材为《Verilog HDL高级数字设计》,这本书可以说是非常推荐的,里面的每个例子都有各种版本的结构,可以让你理解各种结构之间的权衡,当然这本书比较难,尤其是你还没有对状态机很熟练的情况下,比较难,不要紧,后面我会推荐如何学习状态机的教材,那些教材可以让你学会并且熟练,再次强调,本文的目的主要是推荐教材,而其余部分的书写没有太经过思考,其中可能存在重大错误,仅供参考,如果你觉得原书中半色调图像处理器很难看懂,信号繁杂,那么,可以适当看看我改编的这个简单例子和适当听听我的分析,或许会让你学习《Verilog HDL高级数字设计》更加容易。
以上是关于数字IC入门之二(简单的算法架构)的主要内容,如果未能解决你的问题,请参考以下文章