虽然Foundry提供的可用元器件种类较多,但数字设计师并不特别在意这些元器件,在其头脑中,只存在10种简单元器件,即与门、或门、非门、异或门、加法器、乘法器、选择器、比较器、移位器、触发器。至于如何将这些门电路组合成更为复杂的门电路,并应用到电路中是综合器的工作,设计者并不关心。
数字IC设计又称为数字逻辑设计,之所以有这样的别名,是因为数字电路本身就是逻辑的,即只有0和1两种逻辑,非此即彼。为了实现0和1的计算与传输,需要两种类型的电路,一种叫组合逻辑,另一种叫时序逻辑。组合逻辑是电平输入和电平输出。一个与门的逻辑如图2—1所示,其中,与门的符号表示和引脚命名如(a)所示,逻辑波形如(b)所示。当输入 a 或 b 维持0电平时,输出 z 也维持0电平,当输入 a 和 b 同时为1时, z 输出1。
图2—1 与门
组合逻辑虽然符合人的思维习惯,并且元器件结构简单,但问题是如果输入含有毛刺,输出就有毛刺,如图2—2所示,输入 b 突然从0变成1后又在短时间内恢复0,可以视为毛刺,输出 z 受到 b 的影响,也产生了毛刺。
图2—2 带毛刺的输入和输出
时序逻辑就是以时钟作为驱动源的电路。一个触发器,在时钟的驱动下,将D输入端的信号送到Q端输出,如图2—3所示,其中,(a)是触发器的符号和引脚名称,(b)是触发器的输入和输出波形。这里引入节拍的概念,也可称为拍。时序逻辑上的时钟,一个周期为一拍,英文中常写作1T。(b)中共有7拍,在第3拍,复位信号rst_n解复位,该触发器才正常工作。在第4拍,D信号由0变1,如果是组合逻辑,则Q端应该在D变化的同时发生变化,但时序逻辑的特点是必须等待时钟驱动,因此Q端从0变1发生在第5拍。在第6拍,D信号又从1变为0,所以Q端在第7拍之后变为0。时序逻辑能够消除毛刺,D在第5拍和第6拍之间出现毛刺,若是组合逻辑,则Q端会同时出现毛刺,但在触发器中,在出现毛刺的位置上,时钟并没有驱动,因此Q仍然保持原来的状态。这就是所谓“数字电路有去除毛刺的天然特性”说法的由来。在这里必须明确定义什么是时钟驱动。时序逻辑中,时钟的上升沿或下降沿才能驱动电路运行,该时钟边沿就是时钟驱动。定义中用了“或”而不是“和”,是因为普通的触发器是单边沿采样的,即不能同时使用上升和下降两种沿进行采样,至于使用哪种沿采样,要看设计时使用的Verilog语句。这里再定义采样的概念,即时钟边沿出现时,触发器会将当时D端输入的值放在Q端输出,这就是所谓对D信号进行采样。图2—3中凡是时钟的上升沿都标有箭头,即说明该触发器是上升沿触发采样的。触发器也可称为寄存器(Register,reg)。之所以叫寄存器是因为如果没有时钟驱动,则Q端会保持原有状态不变,也就寄存了上一次触发时的D端信息,而对于组合逻辑,输出端是无法寄存信息的,必须随输入的变化而立即发生变化。在第7.2节介绍的综合脚本中,会有reg2reg一项,意思是Register to Register,指的是两个触发器中间的路径。读者在进行前仿时,看到的仿真波形会和本图一样,是理想的,而使用版图网表进行后仿时,仿真波形是带延迟的。很多初学者会认为前仿波形就是电路的实际状况,因而在分析波形时经常发生理解错误。图2—3也画出了触发器的符号表示,它共有4个引脚,除输入的D端和输出的Q端外,三角形位置表示时钟,下方的rst_n表示复位,其上的圆圈表示0电平有效,即rst_n等于0时,寄存器处于复位状态。此时,Q端保持0,即使时钟和D端有动作,Q端也不会变化,只有当rst_n等于1时,才解除复位状态,寄存器方能正常工作。
图2—3 触发器
时序逻辑是整个数字电路的基础,在10种元器件中,只有触发器属于时序逻辑器件,因而触发器是整个数字电路的基础,这一点,从Verilog的另一个称呼RTL就可知晓。RTL意为寄存器传输层,直译过来就是:从一个触发器的输出到另一个触发器的输入,通过触发器的层层传递,最终实现了一个功能完整的数字电路。数字的时序分析,主要是分析两个触发器之间的路径延迟。10种元器件中的其他9种属于组合逻辑。这10种元器件经过复杂地组织,能够实现所有数字芯片的逻辑运算需求,从简单的加、减、乘、除,到复杂的浮点运算、复数运算、矩阵运算都能解决。可能有读者会问一堆问题,诸如“乘法不就是重复的加法吗?”“加法器也可以由与或非门实现呀?”“比较器用异或门也能实现吗?”之类,这里笔者概括为10种,是从Verilog常用的表达形式的角度来讲的,也就是说,虽然加法器也可以由与或非门实现,但一般直接使用“+”这个符号表示加法,较少会使用门电路去搭建加法器,因为现代芯片规模庞大,要实现的功能十分复杂,工程师应该将精力更多地投入到重点难题的实现上,而对于加法如何实现这类最底层问题,都交由综合步骤自动完成,现代EDA工具也更加智能,能够根据设计描述自动匹配出面积最省、速度最快的电路,例如DC综合器中包含的DesignWare器件库。基本元器件中不包括除法,原因是除法的实现不同于乘法,它受到被除数、除数、商的数值范围的限制,有时需要用到迭代等复杂方法实现,还有分母为0等异常情况需要报告,所以并不属于Verilog中常用的直接运算方式。
读者务必注意与或非加乘等指的是元器件,而非C语言中代表的运算含义。写Verilog最忌讳的是用C语言的编程思维来写,虽然两者在语法上十分相似。C语言的代码叫程序,即流程顺序,按照编写顺序逐条执行。数字前端写的Verilog仅仅是代码,而非程序。代码即代替电路图的一种文本语言描述。因而在编写Verilog时,人们脑中会呈现出该代码对应的电路概貌和时序,理解这一点,对于新人格外重要。
10种数字器件的符号表示以及Verilog表示方法见表2—1。
表2—1 10种数字逻辑器件和Verilog表示
真正的元器件库中有很多复杂元器件,如图2—4所示,但这些元器件都可以看作10种基本元器件的组合,不会超出原有的功能范围,因此在设计时,头脑中只需使用这10种元器件进行电路组织。
图2—4 复杂元器件示例