购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第五讲

语言设计两面全能
初学乍练一头雾水Verilog语言的可综合性

我们把世界看错,反说它欺骗了我们。

——《飞鸟集》

有诗赞曰:

“洪荒之力花千骨,生死无截天地哭。紫为仙子青霞姝,合二为一是佛祖。阅尽人间百般苦,皆因不得善门入。慧眼识得应用处,仿真不同于电路。”

“南无阿弥陀佛,老僧稽首了!”

前几周秋风乍起,红叶片片,对于有些人只是美景无限,可是劳碌了吾这一扫地的和尚。事态紧急,这个说书也不能耽误了,于是请穆道士帮忙代场讲了两回书。哪里想到这个牛鼻子生生把阳春白雪的电路设计思想,讲成了下里巴人的FPGA概要。要知道FPGA可是很多人自认为的“一亩三分地”,他这不是去占场子、踢馆子吗?此人诚心找打。(到时候大虾们一顿化骨绵掌和七伤拳上来,道士就可以头上仰四十五度吐血三月而亡了,可以参考《唐伯虎点秋香》里的姿势。到时候,老衲看热闹外加念《大悲咒》。呵呵……)这个事情和老朽无关啊,有关施主一定要分清老道和老衲,不要城门失火殃及池鱼才好。

善哉善哉,出家人“慈悲为怀、善念为本”,不说别人的坏话(穆道士:“啊呸,你坏话还说得少啊!”)。既然老道的上两回书有叫板的味道,老僧也不客气了。本来准备把以前《IP核芯志》有关可综合性的书文拿出来炒炒剩饭的。看来这是不够的了,列位听众,这一次某家就卖卖力气,重新说一说这个可综合性的话题。各位有福了,且洗了耳朵听我吹!

一、实现仿真两重天

基于最优假设的冒险主义,人们还是相信“一石二鸟”的奇迹的,殊不知很多时候是“偷鸡不成蚀把米”。

Verilog在设计之初就号称可以一次打两只鸟:设计和验证,殊不知这两个方向的思路却相差很大。数字逻辑的设计是基于数电的,受制于电路器件的特性;反观数字逻辑系统的验证,这是一个纯粹软件仿真的活计,工程师更加喜欢一般程序设计语言的思路。从老衲参与的很多技术讨论里发现,这“两只鸟”不仅没有打到,这把“米”反而是一定“蚀”了。大多数初学者完全分不清哪些可以综合,哪些不可以。

老僧也在总结这个现象的原因,称之为:“教不得法,学不得法。”

“教不得法”是指很多关于Verilog的书继承了程序语言教材的结构,把语句分为算术运算、条件判断和循环等部分,完全不区分可综合性,这样有误导的嫌疑;“学不得法”是一个历史原因,大多数学习者实际上具有很强的程序语言(如C语言)的基础,这反而是有害的。人的思维是有惯性的,Verilog的形式又与C语言很类似,因此多数人都把C语言设计里的习惯不自觉地带入了Verilog语言的电路实现中。于是,综合软件上报的错误“如滔滔江水,绵绵不绝”,实现与想象不一致也是“如黄河泛滥,一发不可收拾”。以上是一家之言啊,切勿对号入座,否则必有受伤者,老衲不负责医药费!

对于为什么很多语句不能综合,会有很多说法来说明“不是设计的问题,是条件限制”。现在就看一个(见有关Verilog语言可综合性的鼻祖材料:《谈VHDL/Verilog的可综合性以及对初学者的一些建议》):

“一、HDL不是硬件设计语言:过去笔者曾碰到过不少VHDL或Verilog HDL的初学者问一些相似的问题,诸如如何实现除法、开根号,如何写循环语句等。

在各个论坛上,也时常能看到一些网友提出这一类的问题。对于这些问题,首先要明确的是VHDL和Verilog最初并非是针对硬件设计而开发的语言,只不过目前被我们用来设计硬件。

HDL是Hardware Description Language的缩写,正式中文名称是“硬件描述语言”。也就是说,HDL并不是“硬件设计语言(Hardware Design Language)”。别看只差这一个单词,正是这一个单词才决定了绝大部分电路设计必须遵循RTL的模式来编写代码,而不能随心所欲地写仅仅符合语法的HDL代码。

二、HDL的来历:之所以是“硬件描述语言”,要从HDL的来历说起。

VHDL于1980年开始在美国国防部的指导下开发,完成于1983年,并于1987年成为IEEE的标准。当初开发这种语言,是出于美国国防部采购电子设备的需要。

美军的装备采购自私人企业,时常要面对这样一种风险:如果某种武器大量装备部队,而其中某个零件的供应商却在几年后倒闭了,则这种武器的再生产、维修和保养都会出现大问题。而电子设备、尤其是集成电路的内部结构较为复杂,若出现前面所说的情况要找其他公司生产代用品非常困难。于是美国国防部希望供应商能以某种形式留下其产品的信息,以保证一旦其破产后能由其他厂商迅速生产出代用品。当初的设计文档显然是不能交出来的,这在美国会涉及商业机密和知识产权问题。于是美国国防部就想出了一种折中的方法——描述硬件的语言,也就是VHDL。通过VHDL,供应商要把自己生产的集成电路芯片的行为描述出来:比如说,加了什么样的信号后过多少时间它能输出什么等。这样,如果有必要让其他厂商生产代用品,他们只需照着VHDL文档,设计出行为与其相同的芯片即可。这样的代用品相当于是新厂商在不了解原产品结构的情况下独立设计的,因此不太会涉及知识侵权。

Verilog HDL也形成于差不多的年代,是由Gateway Design Automation公司在1983年左右开发的。其架构与VHDL相似,但主要被用来进行硬件仿真。或许私人公司更注重实用,Verilog要比VHDL简洁得多。

由此可见,这两种最流行的用于电路设计的语言,没有一种是为了设计硬件而开发的(更何况80年代还没有现在的那些功能强大的EDA软件呢)。因此,当初制定HDL语言标准时,并没有考虑这些代码如何用硬件来实现。换句话说,有些代码写起来简单,实现起来却可能非常复杂,或者几乎不可能实现。”

看起来很有道理,但是老僧却认为都值得商榷。以下是一家之言,希望大家“再商榷”。

首先,硬件描述语言描述的也是硬件吧?按照该文作者的说法,“接口描述语言”的说法似乎更合适。而且系统的外部行为也似乎没有必要非要用语言描述,看看很多器件的手册(Datasheet,DS)不也很好?为什么要来画蛇添足?

其次,Verilog在出世之初,不就号称具备良好的支持设计和仿真两个方面吗?是“门路”公司市场部门吹牛呢?还是上文的作者臆测呢?老衲就不得而知了。不敢想啊,越想越有味道。但是,不敢说“病从口入,祸从口出”。

最后,穆老道已经告诉听众朋友们了一个事实:组合逻辑在FPGA里基本都是LUT实现的,则在可综合性这个问题上,加法与乘除法的难度差距就急剧缩小了。综合软件完全可以算出计算结果,然后填进LUT里,至于这个结果是两个数相加还是相乘,乃至于是开平方,都是软件的事情,对与FPGA的资源消耗根本无关嘛!因此,老衲这才意识到把ASIC与FPGA大而化之一起来讨论,对于很多问题而言是危险的,得到的结论是经不起推敲的。老道英明啊,我错了(“悔不该,错骂了穆达人……”)。所谓“知错能改,善莫大焉”,这就抱老穆的大腿去。

啰唆了这么多,纯属“论道”级别的东西,除了显摆自己有多大学识和让大家觉得郁闷之外,没什么干货。来点有营养的,那就是脱离电路实质来谈Verilog语言的可综合性是不靠谱的。抓住电路,主要关注数字电路的教材,思考语句对应电路里的哪个或哪几个器件,这个思路用四川话说就是:“要得!”

二、触发器信息分析

下面以D触发器为例子,听众朋友们和老僧一起看个热闹。图1.27是D触发器的电气符号,可以看到它的输入/输出管脚。D 是数据输入管脚,Q 是数据输出管脚,S是数据复位管脚,R是数据清零管脚,EC是芯片选择管脚,CLK是上升沿驱动的时钟输入。

图1.27 D触发器的电气符号

看到这个图,如果还想通过两个时钟来控制D触发器的设计者们可以死心了,没有两个管脚用来输入啊。当然也会有些“不见黄河不死心”的,在代码里非要玩双驱动的,综合器也能有办法,见图1.28。两个驱动时钟CLK1和CLK2会借助一个逻辑电路选择器通过时钟选择信号CLK_SEL选择,再输入D触发器的时钟输入管脚CLK。这个是典型的所谓“门控时钟”,结论是最好不要在电路中使用(至于为什么,可以参考老衲以前说的评书《IP核芯志》)。

图1.28 双时钟启动D触发器的电路实现

还有一种思想,是借鉴 DDR SDRAM(Double Data Rate Synchronous Dynamic Random Access Memory,双倍速率同步动态随机存储器)的,提出:“利用时钟的两个沿来驱动D触发器,这样工作效率不是可以翻番了吗?”这个思想就需要进去D触发器内部,看一看其门电路的实现方法了,如图1.29所示。忽略《数字电子技术》教材里的详细论述(希望了解详情的读者,可以在任何一本教材里找到答案),简单得出一个结论:双时钟沿驱动是不靠谱的。一个简单的说法是,只要看一看 D 触发器和 DDR SDRAM出现的时间差距,你应该就会有所顿悟了。

图1.29 D触发器的门电路结构

那能不能改造电路,使得D触发器能够通过双时钟沿启动呢?这个或许可以,但是至少没人这样做过。道理很简单:与其这样重新设计电路,还不如提高芯片外部的时钟频率来得直截了当。

再说两句题外话,大家觉得哪种“错误”更可怕?老衲觉得是第一种“双时钟”方案。理由嘛,因为这个真的能综合,但是电路性能奇差。第二种方案的“优点”是:综合软件直接报错,设计者知道这个代码有问题,不会到了后期性能不好又不晓得哪里有问题。工程里有句名言:“不怕语法错,就怕逻辑误。”这是老夫首创的说法,现在有很多人喜欢抢这句台词了。

三、作比较软硬不同

数字电路和程序语言的区别,别告诉我你不知道。下面姑且总结几条,好让大家以后面试时,可以说得头头是道。

(1)对应于仿真:C语言的代码是一行一行执行的,属于顺序结构;而Verilog是一种硬件描述语言,语句同时进行,属于并行结构。

这个特点说起来有点抽象,我们举一个例子吧(见表1.1)。对于某家上面举出的代码,惊奇到掉下巴了。

表1.1 两种语言的仿真方式差别

“不看不知道,世界真奇妙”,套用以前《正大综艺》的台词。见到黄河了?佛祖说:“回头是岸,南无阿弥陀佛”。

表中的Verilog代码里,如果采用“阻塞赋值”,则表面上C语言与Verilog仿真的结果是一致的。表1.1的例子里,采用了“非阻塞赋值”并非要强调论点的正确,而是故意地以偏概全。具体理由请参考上面的一讲中关于FPGA结构的论述,简单来说就是“阻塞赋值”不可综合。

(2)对应于实际系统:C 语言的代码,逻辑分支在代码中体现,但是执行时只执行满足逻辑的部分;而Verilog无论逻辑成立与否,都会在面积中体现,如果控制不好都会计算,然后被选择。

再举一个例子(见表1.2)来说明一下。任你再坚强,老衲也把你的头撞撞南墙,倒是看你回不回头。不准翻墙啊!?

表1.2 两种语言的执行方式差别

捎带说一句,C语言的优化,可以仅仅考虑优化各个分支;而Verilog的优化,则是更多考察整体的优化。

(3)C语言的计算结果与CPU的频率无关;而Verilog的结果与芯片的外部时钟有着强烈的关系。

CPU的频率高低只是影响C语言的运行时间。一个C语言做的程序,在386上可能要运行一天,在i5上可能仅需运行10分钟。但是它们的输出是没有差别的。

Verilog 综合的电路与时钟的关系则是一个很大的课题。这个话题说上三天三夜也说不完。下一讲里,会对这个问题进行一定的讨论。实际上,整本书都会和这个话题有关。在本书的后面部分,大家将会看到,针对不同频率的时钟,设计相同功能的电路,有天壤之别。

(4)综合分析两边站。

“借我借我一双慧眼吧,让我把这纷扰,看个清清楚楚明明白白真真切切”,谁啊?这里是说书的不是演唱会,严禁踢场子!

对于Verilog里面可综合性,网上有很多玄妙的描述:

“……

用一句简单的话概括:电脑永远没有你聪明。具体来说,通常EDA软件对HDL代码的综合能力总是比人差。对于一段代码,如果你不能想象出一个较直观的硬件实现方法,则EDA软件肯定也不行。

……

此外,硬件无法支持的行为描述,当然也不能被综合(如想在 FPGA 上实现 DDR内存那样的双延触发逻辑,代码很容易写,但却不能实现)。”

能看懂这些话的人,似乎也没有必要从网上查找“可综合性”的资料了。

自然我们可以根据Verilog语言里的各条语句,逐一分析其是否可以综合,或者其在什么条件下可以综合。这个工作量将会十分庞大,远非本书的页数可以涵盖的。

避繁就简,结合网上查出来的资料,老衲针对 Verilog 可综合性设计,分 FPGA 和ASIC的情况,给列位总结出了表1.3(内部资料,注意保密)。表里可能有一些超前的概念,如always、循环和阻塞/非阻塞赋值等,这些会在后文书里介绍。

表1.3 Verilog可综合性设计原则汇总表

(续表)

话说两头,老衲从来不提倡先写代码,然后去看能不能综合的设计步骤。老僧把那叫作“C Style”、“逻辑派”或“语法党”,某家提倡的是“电路门”。早在《IP核芯志》里,吾就说过了:“看图说话基本法,电路映射程序中。”这是不二法门。就是先画电路/时序/状态转移图,再去写代码的意思。

如果施主一定要坚持“逻辑派”/“语法党”,不肯皈依我“电路门”,老衲也不好强人所难。老僧年纪大啦,早就过了喜欢当头棒喝的时光。那么,至少听一句劝,现在开发环境里都有将代码恢复到电路图的功能,常去推敲一二是极好的。Xilinx的ISE环境,对应这一功能的截图见图1.30。其中圆圈部分是对应菜单选择项目,右边是一个小例子的电路原理图,详细内容请阅读Xilinx公司的有关文档。其他公司的对应操作界面,也请阅读对应的操作手册。

图1.30 ISE的代码转换电路图功能

这才符合 HDL 的深刻含义:用语言来描述电路。没有电路,写的代码不就成了无源之水了吗?那样描述的估计是“一枕黄粱”的大梦了。

(5)冷知识大话上电。

网上有言:“重要的话说三遍,”可综合性这个概念对于学习Verilog语言进行数字电路设计而言实在太重要了,因此写完之后,老衲又看了五遍,然后发现除了“不使用初始化赋值”这一条原则则在 FPGA 里以外,其他原则的原因都会在后文书里有所涉及。最终,老僧决定破个例,专门抽一点时间给大家讲解一下 FPGA 的话题:FPGA 的上电与配置。这是一个冷知识,只是用来显摆我博学的,不了解也无伤大雅。

看过电影《谍影重重》没有,一个FPGA在刚刚开机时刻的处境,比男主角马特·达蒙饰演的杰森·伯恩还要糟糕。伯恩至少还知道自己在船上,FPGA连自己在哪里都不清楚。在核磁共振机里?在马桶圈内部?一切均有可能。因此,FPGA需要一整套上电配置过程,来确定自身的目标与任务。图1.31是从Xilinx公司资料上复制下来的图,标记了FPGA的上电配置过程。这相当于无崖子对虚竹做的事情——去掉原来的武功,然后输入逍遥派的武艺。

图1.31 FPGA上电配置过程

对于图1.31里的各种名词和过程,要想详细论述本书就要改名叫《FPGA详细教程》了,其实这些对于学习语言不重要,张三丰说了:“去其形,会其意。”听众只要知道“FPGA 在系统上电之后,是有很多事情要做的;这些事情是要花费时间的;在做这些事情时,捎带就把初始赋值了”也就足够了。

这正是:

“语言内部擒双隼,设计验证二度春。预作高手敌曹孙,需住综合秘籍屯。条条原则先谨遵,理由存在电路群。两种器件分开炖,开锅美餐万世存。” z2dTHdlQsUwzhy1sFB1maURIrgHpEotjqINv3TVNhOQvkXcYbDFWJGVPAkYsaW9I

点击中间区域
呼出菜单
上一章
目录
下一章
×