曾几何时,终于听不到街舞大妈震耳欲聋的《江南 Style》的音乐了。作为一种流行文化的,韩国胖子的骑马舞,可是曾经上到联合国秘书长下到餐厅小妹,都是趋之若鹜的。(幻想一下,如果这本书能这么流行,我就发达了,也不用潘基文了,奥本海默接见我一下就满足了……)按照意识流的要求,现在从《江南 Style》可以联想起我所谓的“C Style Verilog(C语言风格的Verilog代码)”。这个“Style”就令贫僧深恶痛绝了。在此高声疾呼一个乌鸦嘴式的偈语:“《江南Style》风靡,‘C Style’必死。”
1.C语言陷阱
凡是从程序设计语言,尤其是 C 语言,过来的工程师。都会有意无意地拿 Verilog语言与C语言做类比。然后,自然地把很多C代码的习惯带到HDL里面来。俗话说得好:“习惯成自然”、“积习难改”。贫僧做小沙弥的时候,也有这样的代码:
这个代码曾经叫在下在调试里面吃尽了苦头,记忆犹新。
以致,现在面试“Verilog设计工程师”的时候,都喜欢问一句“你的C语言如何”。回答很好的人,绝对没有加分的。C 的高手,某种意义上,是一个数字逻辑设计团队的灾难;除非,此人真正了解了程序语言和数字逻辑的区别。
仅仅从语言的语法、关键字这些纸面上的东西来看,“C语言”和“Verilog”似乎真是亲哥俩。他们之间的差别,甚至比“C 语言”和“C++语言”之间的区别还要少。很多人都被这种“相似性”的猪油蒙了心。还有一个问题就是,目前学校教育的安排中,都是程序语言先于硬件描述语言教授的。在学Verilog的时候,很多人多多少少沾染了程序语言的“辐射尘”。这可能是问题的关键。
上面啰嗦了很多,估计有些人正在运气,准备站起来和老僧辩论呢。稍安勿躁,这里不流行“顾客总是对的”,我们一起慢慢掰扯。现在回到问题的原点,来学习“苏格拉底式”教学:“HDL是什么的英文缩写,翻译到汉语是什么?”
听清楚了,记住了:“HDL=Hardware Description Language,汉语是硬件描述语言!”
这不就得了,您都说清楚了“硬件描述”,换句话说,就是用来描述硬件的。硬件和程序的区别,别告诉我您不知道。下面姑且总结几条,叫大家以后面试的时候,可以说得头头是道。
(1)对应于仿真:C语言的代码是一行一行执行的,属于顺序结构;而Verilog是一种硬件描述语言,语句同时进行,属于并行结构,如表1.2所示。
表1.2 两种语言的仿真方式差别
这个特点说起来有点抽象,我们举一个例子吧,就某家上面举出的代码,见证奇迹的时刻到了。
“不看不知道,世界真奇妙”,套用以前《正大综艺》的台词。见到黄河了?佛祖说:“回头是岸,南无阿弥陀佛。”
上面Verilog代码里面,如果采用“阻塞赋值”,表面上C语言与Verilog仿真的结果是一致的。例子里面,采用了“非阻塞赋值”并非要强调论点的正确,故意以偏概全。具体理由请参考上面一讲,简单说“阻塞赋值”不可综合。
(2)对应于实际系统:C 语言,其逻辑分支在代码中体现,但是执行时只执行满足逻辑的部分;而Verilog无论逻辑成立与否,都会在面积中体现,如果控制不好都会计算,然后被选择。
再举一个例子,也来说明一下。任你再坚强,贫僧也把你的头撞撞南墙,倒是看你回不回头。不准翻墙啊!?
表1.3 两种语言的执行方式差别
捎带脚说一句,C语言的优化,可以仅仅考虑优化各个分支;而Verilog优化,则是更多考察整体的优化。
(3)C语言的计算结果与CPU的频率无关;而Verilog的结果与芯片的外部时钟有着强烈的关系。
CPU的频率高低,只是影响C语言的运行时间。你一个C语言做的程序,386上可能要运行一天,i5上可能仅需10分钟。但是,他们的输出是没有差别的。
Verilog综合的电路与时钟的关系,则是一个很大的课题。这个话题,说上三天三夜也说不完。下一讲里面,会对这个问题进行一定的讨论。实际上,整本书都会和这个话题有关。在本书的后面部分,大伙儿将会看到,针对不同频率的时钟,设计相同功能电路的差别,那将是天壤之别。
(4)在很多优化上,C语言和Verilog也有差别。同时,Verilog没有C语言上的不同变量的比特宽度的约束。
这个也是不胜枚举的,用一个简单的例子,以除以2的幂的运算来说明。
表1.4 两种语言的优化方法差别
同样是除以4的操作,也同样是利用移位简化除法的技巧。对于C语言就是移位操作,而对于Verilog语言则可以进一步简化为取输入的若干位。
还不服气,贫僧只好说:“好良言难劝该死的鬼……”。
(5)Verilog综合器一般比C语言编译器“智能”差。
还用一个例子,来稍稍说明一下。
表1.5 两种语言的编译/综合后差别
可能有些人说:Verilog的综合器弱爆了。其实不然,电路里面对于信号d与信号e的时序要求以及建立时间,完全可以不一致。人家这样综合没错,错的是我们自己。记住一个原则:错的永远是我们自己,不要去怀疑和质疑综合器。
您老竟然看到了这里,星爷又说了:“I服了you……”。我能引用孔夫子的话不:“朽木不可雕也,粪土之墙不可污也?”
2.照原理图的猫,画Verilog的虎
贫僧再次强调:“Verilog是硬件描述语言,是用来描述硬件的语言”。自诩 C语言高手的孩儿们啊,看看你们把贫僧逼的,都快成唐僧了。罪过罪过……
稍稍剧透一下,后面的很多内容,都是介绍各种模块如何实现的。所以呢,这里不会展开了讲。表1.6把主要的、可综合的Verilog关键字和操作符实际电路做了一个对应,列位参考。
表1.6 可综合关键字与电路对应关系
(续表)
(续表)
来一段“甄嬛体”,调节一下气氛。
私心想着,数字逻辑这大好河山,怎得和程序语言一般谋划?如此这般下去,却让数字逻辑工程师情何以堪?FPGA自古至今都是并行工作,越发不似程序语言顺序运行。方才主力开会,本宫自是无言以对,料想再搬语言设计,后果定是真真严重的。怎奈积习难改,本宫也只得四处奔走劝说,却也是泥牛入海。宫里王大总管方才回话,要本宫写一流程,也好对孩儿们说明。回想本宫工作多年,却也落得个如此下场,打工的日子真真是越发难过了。
旦逢项目的第一天,切勿忙着编码,却谨记原理图设计为先的要点。虽是用语言表示,逻辑设计归根到底还是电路设计不是?窃思,如此原理图可以放宽表现,以为电路图、时序图与状态机图皆为可用。
妾身……呸呸呸,还是说人话吧:Verilog设计应该“看图说话”、“照猫画虎”。
至于如何设计所说的原理图的“猫”,后文书会有交代,这里暂且按下不表。如何“画虎”也会在后面的内容里面提及,也不多说。
3.老虎分类学
在数字逻辑设计里面,大伙儿总是会听到组合逻辑和时序逻辑的说法。这是老虎的两个分支,按照《数字电路》里面的定义是:
“数字电路根据逻辑功能的不同特点,可以分成两大类,一类叫组合逻辑电路(简称组合逻辑),另一类叫做时序逻辑电路(简称时序逻辑)。组合逻辑电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。而时序逻辑电路在逻辑功能上的特点是任意时刻的输出不仅取决于当时的输入信号,还取决于电路原来的状态,或者说,还与以前的输入有关。”
不去故弄玄虚,贫僧这就来解释一下。两种逻辑的比较,如表1.7所示。
表1.7 组合逻辑与时序逻辑的比较
看到上面的定义,有一个有趣的问题:单位的D触发器是否属于时序逻辑。感觉上,它应该是;实际上,它也是。注意一下组合逻辑和时序逻辑定义里面,组合里面多了一个“当前”的限制,这个很重要。
上面表里的电路结构图是一种抽象。实际中,更加实用的是图1.10的样子。可以证明,这个结构和表里面的结构是等价的。但是,这种图才方便大家“看图说话”。
图1.10 时序逻辑的工程结构图
还有,按照正规的原理图,还需要画出时钟信号(Clock,或者简写成Clk)和复位信号(Reset,或者简写成RST)。本书除非有特殊要求,会忽略掉这些信号。实际中,这些信号的处理方法都是一个路数,忽略掉不会影响理解。贫僧很懒,大家需要体谅。人老了,画那么详细的图,累啊。
这正是:“电路程序本不同,语言相似迷雾浓;他年自当临绝顶,当悔比较无用功。组合逻辑多品种,时序驱动靠时钟;看图说话基本法,电路映射程序中。”