Verilog
经典
教程
夏宇闻
第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-1 第一章第一章 数字信号处理、计算、程序、数字信号处理、计算、程序、算法和硬线逻辑的基本概念算法和硬线逻辑的基本概念 引言:现代计算机与通讯系统电子设备中广泛使用了数字信号处理专用集成电路,它们主要用于数字信号传输中所必需的滤波、变换、加密、解密、编码、解码、纠检错、压缩、解压缩等操作。这些处理工作从本质上说都是数学运算。从原则上讲,它们完全可以用计算机或微处理器来完成。这就是为什么我们常用 C、Pascal 或汇编语言来编写程序,以研究算法的合理性和有效性的道理。在数字信号处理的领域内有相当大的一部分工作是可以事后处理的。我们可以利用通用的计算机系统来处理这类问题。如在石油地质调查中,我们通过钻探和一系列的爆破,记录下各种地层的回波数据,然后用计算机对这些数据进行处理,去除噪声等无用信息,最后我们可以得到地层的构造,从而找到埋藏的石油。因为地层不会在几年内有明显的变化,因此花几十天的时间把地层的构造分析清楚也能满足要求。这种类型的数字信号处理是非实时的,用通用的计算机就能满足需要。还有一类数字信号处理必须在规定的时间内完成,如在军用无线通信系统和机载雷达系统中我们常常需要对检测到的微弱信号增强、加密、编码、压缩,在接收端必须及时地解压缩、解码和解密并重现清晰的信号。我们很难想象用一个通用的计算机系统来完成这项工作,因此,我们不得不自行设计非常轻便小巧的高速专用硬件系统来完成该任务。有的数字信号处理对时间的要求非常苛刻,以至于用高速的通用微处理器芯片也无法在规定的时间内完成必须的运算。我们必须为这样的运算设计专用的硬线逻辑电路,这可以在高速 FPGA 器件上实现或制成高速专用集成电路。这是因为通用微处理器芯片是为一般目的而设计的,运算的步骤必须通过程序编译后生成的机器码指令加载到存贮器中,然后在微处理器芯片控制下,按时钟的节拍,逐条取出指令、分析指令,然后执行指令,直至程序的结束。微处理器芯片中的内部总线和运算部件也是为通用的目的而设计,即使是专为信号处理而设计的通用微处理器,因为它的通用性,也不可能为某一个特殊的算法来设计一系列的专用的运算电路,而且其内部总线的宽度也不能随意改变,只有通过改变程序,才能实现这个特殊的算法。因而其运算速度就受到限制。本章的目的是想通过对数字信号处理、计算(Computing)、算法和数据结构、编程语言和程序、体系结构和硬线逻辑等基本概念的介绍,了解算法与硬线逻辑之间的关系从而引入利用 Verilog HDL 硬件描述语言设计复杂的数字逻辑系统的概念和方法。向读者展示一种九十年代才真正开始在美国等先进的工业国家逐步推广的数字逻辑系统的设计方法。借助于这种方法,在电路设计自动化仿真和综合工具的帮助下,只要我们对并行的计算结构有第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-2 一定程度的了解,对有关算法有深入的研究,我们完全有能力设计并制造出有自己知识产权的 DSP(数字信号处理)类和任何复杂的数字逻辑集成电路芯片,为我国的电子工业和国防现代化作出应有的贡献。1.1 数字信号处理 大规模集成电路设计制造技术和数字信号处理技术,近三十年来,各自得到了迅速的发展。这两个表面上看来没有什么关系的技术领域实质上是紧密相关的。因为数字信号处理系统往往要进行一些复杂的数学运算和数据的处理,并且又有实时响应的要求,它们通常是由高速专用数字逻辑系统或专用数字信号处理器所构成,电路是相当复杂的。因此只有在高速大规模集成电路设计制造技术进步的基础上,才有可能实现真正有意义的实时数字信号处理系统。对实时数字信号处理系统的要求不断提高,也推动了高速大规模集成电路设计制造技术的进步。现代专用集成电路的设计是借助于电子电路设计自动化(EDA)工具完成的。学习和掌握硬件描述语言(HDL)是使用电子电路设计自动化(EDA)工具的基础。1.2 计算(Computing)说到数字信号处理,我们自然就会想到数学计算(或数学运算)。现代计算机和通信系统中广泛采用了数字信号处理的技术和方法。基本思路是先把信号用一系列的数字来表示,如是连续的模拟信号,则需通过采样和模拟数字转换,把信号转换成一系列的数字信号,然后对这些数字信号进行各种快速的数学运算,其目的是多种多样的,有的是为了加密,有的是通过编码来减少误码率以提高信道的通信质量,有的是为了去掉噪声等无关的信息也可以称为滤波,有的是为了数据的压缩以减少占用的频道。有时我们也把某些种类的数字信号处理运算称为变换如离散傅利叶变换(DFT)、离散余弦变换(DCT)、小波变换(Wavelet T)等。我们这里所说的计算是从英语 Computing 翻译过来的,它的含义要比单纯的数学计算广泛得多。“Computing 这门学问研究怎样系统地有步骤地描述和转换信息,实质上它是一门覆盖了多个知识和技术范畴的学问,其中包括了计算的理论、分析、设计、效率和应用。它提出的最基本的问题是什么样的工作能自动完成,什么样的不能。”(摘自 Denning et al.,“Computing as a Discipline,”Communication of ACM,January,1989)。本文中凡提到计算这个词处,指的就是上面一段中 Computing 所包含的意思。由传统的观点出发,我们可以从三个不同的方面来研究计算,即从数学、科学和工程的不同角度。由比较现代的观点出发,我们可以从四个主要的方面来研究计算,即从算法和数据结构、编程语言、体系结构、软件和硬件设计方法学。本课本的主题是从算法到硬线逻辑的实现,因此我们将从算法和数据结构、编程语言和程序、体系结构和硬线逻辑以及设计方法学等方面的基本概念出发来研究和探讨用于数字信号处理等领域的复杂硬线逻辑电路的设计技术和方法。特别强调利用 Verilog 硬件描述语言的 Top-Down 设计方法的介绍。第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-3 1.3 算法和数据结构 为了准确地表示特定问题的信息并顺利地解决有关的计算问题,我们需要采用一些特殊方法并建立相应的模型。所谓算法就是解决特定问题的有序步骤,所谓数据结构就是解决特定问题的相应的模型。1.4 编程语言和程序 程序员利用一种由专家设计的既可以被人理解,也可以被计算机解释的语言来表示算法问题的求解过程。这种语言就是编程语言。由它所表达的算法问题的求解过程就是程序。我们已经熟悉通过编写程序来解决计算问题,C、Pascal、Fortran、Basic 或汇编语言语言是几种常用的编程语言。如果我们只研究算法,只在通用的计算机上运行程序或利用通用的 CPU 来设计专用的微处理器嵌入系统,掌握上述语言就足够了。如果还需要设计和制造能进行快速计算的硬线逻辑专用电路,我们必须学习数字电路的基本知识和硬件描述语言。因为现代复杂数字逻辑系统的设计都是借助于 EDA 工具完成的,无论电路系统的仿真和综合都需要掌握硬件描述语言。在本书中我们将要比较详细地介绍 Verilog 硬件描述语言。1.5 系统结构和硬线逻辑 计算机究竟是如何构成的?为什么它能有效地和正确地执行每一步程序?它能不能用另外一种结构方案来构成?运算速度还能不能再提高?所谓计算机系统结构就是回答以上问题并从硬线逻辑和软件两个角度一起来探讨某种结构的计算机的性能潜力。比如,Von Neumann(冯诺依曼)在 1945 设计的 EDVAC 电子计算机,它的结构是一种最早的顺序机执行标量数据的计算机系统结构。顺序机是从位串行操作到字并行操作,从定点运算到浮点运算逐步改进过来的。由于 Von Neumann 系统结构的程序是顺序执行的,所以速度很慢。随着硬件技术的进步,不断有新的计算机系统结构产生,其计算性能也在不断提高。计算机系统结构是一门讨论和研究通用的计算机中央处理器如何提高运算速度性能的学问。对计算机系统结构的深入了解是设计高性能的专用的硬线逻辑系统的基础,因此将是本书讨论的重点之一。但由于本书的重点是利用 Verilog HDL 进行复杂数字电路的设计技术和方法,大量的篇幅将介绍利用 HDL 进行设计的步骤、语法要点、可综合的风格要点、同步有限状态机和由浅入深的设计实例。1.6 设计方法学 复杂数字系统的设计是一个把思想(即算法)转化为实际数字逻辑电路的过程。我们都知道同一个算法可以用不同结构的数字逻辑电路来实现,从运算的结果说来可能是完全一致的,但其运算速度和性能价格比可以有很大的差别。我们可用许多种不同的方案来实现能实时完成算法运算的复杂数字系统电路,下面列出了常用的四种方案:1)以专用微处理机芯片为中心来构成完成算法所需的电路系统;2)用高密度的 FPGA(从几万门到百万门);3)第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-4 设计专用的大规模集成电路(ASIC);4)利用现成的微处理机的 IP 核并结合专门设计的高速 ASIC 运算电路。究竟采用什么方案要根据具体项目的技术指标、经费、时间进度和批量综合考虑而定。在上述第二、第三、第四种设计方案中,电路结构的考虑和决策至关重要。有的电路结构速度快,但所需的逻辑单元多,成本高;而有的电路结构速度慢,但所需的逻辑单元少,成本低。复杂数字逻辑系统设计的过程往往需要通过多次仿真,从不同的结构方案中找到一种符合工程技术要求的性能价格比最好的结构。一个优秀的有经验的设计师,能通过硬件描述语言的顶层仿真较快地确定合理的系统电路结构,减少由于总体结构设计不合理而造成的返工,从而大大加快系统的设计过程。1.7 专用硬线逻辑与微处理器的比较 在信号处理专用计算电路的设计中,以专用微处理器芯片为中心来构成完成算法所需的电路系统是一种较好的办法。我们可以利用现成的微处理器开发系统,在算法已用 C 语言验证的基础上,在开发系统工具的帮助下,把该 C 语言程序转换为专用微处理器的汇编再编译为机器代码,然后加载到样机系统的存储区,即可以在开发系统工具的环境下开始相关算法的运算仿真或运算。采用这种方法,设计周期短、可以利用的资源多,但速度、能耗、体积等性能受该微处理器芯片和外围电路的限制。用高密度的 FPGA(从几万门到几十万门)来构成完成算法所需的电路系统也是一种较好的办法。我们必须购置有关的 FPGA 开发环境、布局布线和编程工具。有些 FPGA 厂商提供的开发环境不够理想,其仿真工具和综合工具性能不够好,我们还需要利用性能较好的硬件描述语言仿真器、综合工具,才能有效地进行复杂的 DSP 硬线逻辑系统的设计。由于 FPGA是一种通用的器件,它的基本结构决定了对某一种特殊应用,性能不如专用的 ASIC 电路。采用自行设计的专用 ASIC 系统芯片(System On Chip),即利用现成的微处理机 IP 核或根据某一特殊应用设计的微处理机核(也可以没有微处理机核),并结合专门设计的高速ASIC 运算电路,能设计出性能价格比最高的理想数字信号处理系统。这种方法结合了微处理器和专用的大规模集成电路的优点,由于微处理器 IP 核的挑选结合了算法和应用的特点,又加上专用的 ASIC 在需要高速部分的增强,能“量体裁衣”,因而各方面性能优越。但由于设计和制造周期长、投片成本高,往往只有经费充足、批量大的项目或重要的项目才采用这一途径。当然性能优良的硬件描述语言仿真器、综合工具是不可缺少的,另外对所采用的半导体厂家基本器件库和 IP 库的深入了解也是必须的。以上所述算法的专用硬线逻辑实现都需要对算法有深入的了解,还需掌握硬件描述语言和相关的 EDA 仿真、综合和布局布线工具。1.8 C 语言与硬件描述语言在算法运算电路设计的关系和作用 数字电路设计工程师一般都学习过编程语言、数字逻辑基础、各种 EDA 软件工具的使用。第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-5 就编程语言而言,国内外大多数学校都以 C 语言为标准,只有少部分学校使用 Pascal 和Fortran。算法的描述和验证常用 C 语言来做。例如要设计 Reed-Solomen 编码/解码器,我们必须先深入了解 Reed-Solomen 编码/解码的算法,再编写 C 语言的程序来验证算法的正确性。运行描述编码器的 C 语言程序,把在数据文件中的多组待编码的数据转换为相应的编码后数据并存入文件。再编写一个加干扰用的 C 语言程序,用于模拟信道。它能产生随机误码位(并把误码位个数控制在纠错能力范围内)将其加入编码后的数据文件中。运行该加扰程序,产生带误码位的编码后的数据文件。然后再编写一个解码器的 C 语言程序,运行该程序把带误码位的编码文件解码为另一个数据文件。只要比较原始数据文件和生成的文件便可知道编码和解码的程序是否正确(能否自动纠正纠错能力范围内的错码位)。用这种方法我们就可以来验证算法的正确性。但这样的数据处理其运行速度只与程序的大小和计算机的运行速度有关,也不能独立于计算机而存在。如果要设计一个专门的电路来进行这种对速度有要求的实时数据处理,除了以上介绍的 C 程序外,还须编写硬件描述语言(如 Verilog HDL 或 VHDL)的程序,进行仿真以便从电路结构上保证算法能在规定的时间内完成,并能与前端和后端的设备或器件正确无误地交换数据。用硬件描述语言(HDL)的程序设计硬件的好处在于易于理解、易于维护、调试电路速度快、有许多的易于掌握的仿真、综合和布局布线工具,还可以用 C 语言配合 HDL 来做逻辑设计的前后仿真,验证功能是否正确。在算法硬件电路的研制过程中,计算电路的结构和芯片的工艺对运行速度有很大的影响。所以在电路结构确定之前,必须经过多次仿真:1)C 语言的功能仿真。2)C 语言的并行结构仿真。3)Verilog HDL 的行为仿真。4)Verilog HDL RTL 级仿真。5)综合后门级结构仿真。6)布局布线后仿真。7)电路实现验证。下面介绍用 C 语言配合 Verilog HDL 来设计算法的硬件电路块时考虑的三个主要问题:?为什么选择 C 语言与 Verilog HDL 配合使用??C 语言与 Verilog HDL 的使用有何限制??如何利用 C 来加速硬件的设计和故障检测?1)为什么选择为什么选择 C 语言与语言与 Verilog 配合使用配合使用 首先,C 语言很灵活,查错功能强,还可以通过 PLI(编程语言接口)编写自己的系统任务直接与硬件仿真器(如 Verilog-XL)结合使用。C 语言是目前世界上应用最为广泛的一种编程语言,因而 C 程序的设计环境比 Verilog HDL 的完整。此外,C 语言第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-6 可应用于许多领域,有可靠的编译环境,语法完备,缺陷较少。比较起来,Verilog 语言只是针对硬件描述的,在别处使用(如用于算法表达等)并不方便。而且 Verilog 的仿真、综合、查错工具等大部分软件都是商业软件,与 C 语言相比缺乏长期大量的使用,可靠性较差,亦有很多缺陷。所以,只有在 C 语言的配合使用下,Verilog 才能更好地发挥作用。面对上述问题,最好的方法是 C 语言与 Verilog 语言相辅相成,互相配合使用。这就是既要利用 C 语言的完整性,又要结合 Verilog 对硬件描述的精确性,来更快更好地设计出符合性能要求的硬件电路系统。利用 C 语言完善的查错和编译环境,设计者可以先设计出一个功能正确的设计单元,以此作为设计比较的标准。然后,把 C 程序一段一段地改写成用并型结构(类似于 Verilog)描述的 C 程序,此时还是在 C 的环境里,使用的依然是 C 语言。如果运行结果都正确,就将 C 语言关键字用 Verilog 相应的关键字替换,进入 Verilog 的环境。将测试输入同时加到 C 与 Verilog 两个单元,将其输出做比较。这样很容易发现问题的所在,然后更正,再做测试,直至正确无误。剩下的工作就交给后面的设计工程师继续做。2)C 语言与语言与 Verilog 语言互相转换中存在的问题语言互相转换中存在的问题 这样的混合语言设计流程往往会在两种语言的转换中会遇到许多难题。例如,怎样把C 程序转换成类似 Verilog 结构的 C 程序,来增加并行度,以保证用硬件实现时运行速度达到设计要求;又如怎样不使用 C 中较抽象的语法:例如迭代,指针,不确定次数的循环等等,也能来表示算法(因为转换的目的是要用可综合的 Verilog 语句来代替 C程序中的语句,而可用于综合的 Verilog 语法是相当有限的,往往找不到相应的关键字来替换)。C 程序是一行接一行依次执行的,属于顺序结构,而 Verilog 描述的硬件是可以在同一时间同时运行的,属于并行结构。这两者之间有很大的冲突。而 Verilog 的仿真软件也是顺序执行的,在时间关系上同实际的硬件是有差异的,可能会出现一些无法发现的问题。Verilog 可用的输出输入函数很少。C 语言的花样则很多,转换过程中会遇到一些困难。C 语言的函数调用与 Verilog 中模块的调用也有区别。C 程序调用函数是没有延时特性的,一个函数是唯一确定的,对同一个函数的不同调用是一样的。而 Verilog 中对模块的不同调用是不同的,即使调用的是同一个模块,必须用不同的名字来指定。Verilog的语法规则很死,限制很多,能用的判断语句有限。仿真速度较慢,查错功能差,错误信息不完整。仿真软件通常也很昂贵,而且不一定可靠。C 语言没有时间关系,转换后的 Verilog 程序必须要能做到没有任何外加的人工延时信号,也就是必须表达为有限状态机,即 RTL 级的 Verilog,否则将无法使用综合工具把 Verilog 源代码转化为门级逻辑。3)如何利用如何利用 C 语言来加快硬件的设计和查错语言来加快硬件的设计和查错 第一章数字信号处理、计算、程序、算法和硬线逻辑的基本概念-7 下表中列出了常用的 C 与 Verilog 相对应的关键字与控制结构 C Verilog sub-function module,function,task if-then-else if-then-else Case Case ,begin,end For For While While Break Disable Define Define Int Int Printf monitor,display,strobe 下表中,列出了 C 与 Verilog 相对应的运算符 C Verilog 功能功能 *乘 /除 +加 -减%取模 !反逻辑&逻辑且|逻辑或 大于 =大于等于 =右移 综合到布局布线-投片生成这样一系列步骤。HDL 设 计 文 件 HDL 功 能 仿 真 HDL 综合 优 化、布 局 布 线 布 线 后 门 级 仿 真 图 2-6-3 HDL 设 计 流 程 图 电 路 功 能 仿 真 电 路 图 设 计 文 件 电 路 制 造 工 艺 文 件 或 FPGA 码 流 文 件 有 问 题 没 问 题有 问 题 没 问 题 有 问 题 没 问 题 与 实 现 逻 辑 的 物理 器 件 有 关 的 工 艺技 术 文 件确定实现电路的具体库名第二章 Verilog HDL 设计方法概述-192)设计验证:也就是进行各种仿真的一系列步骤,如果在仿真过程中发现问题就返回设计输入进行修改。2.6.4.对应具体工艺器件的优化、映象、和布局布线2.6.4.对应具体工艺器件的优化、映象、和布局布线 由于各种ASIC和FPFA器件的工艺各不相同,因而当用不同厂家的不同器件来实现已验证的逻辑网表(EDIF文件)时,就需要不同的基本单元库与布线延迟模型与之对应才能进行准确的优化、映象、和布局布线。基本单元库与布线延迟模型由熟悉本厂工艺的工程师提供,再由EDA厂商的工程师编入相应的处理程序,而逻辑电路设计师只需用一文件说明所用的工艺器件和约束条件,EDA工具就会自动地根据这一文件选择相应的库和模型进行准确的处理从而大大提高设计效率。2.7.小结 2.7.小结 采用Verilog HDL设计方法比采用电路图输入的方法更有优越性,这就是为什么美国等先进工业国家在进入九十年代以后纷纷采用HDL设计方法的原因。在两种符合IEEE标准的硬件描述语言中,Verilog HDL与VHDL相比更加基础、更易学习,掌握HDL设计方法应从学习Verilog HDL设计方法开始。Verilog HDL可用于复杂数字逻辑电路和系统的总体仿真、子系统仿真和具体电路综合等各个设计阶段。由于TOP_DOWN的设计方法是首先从系统设计入手,从顶层进行功能划分和结构设计。系统的总体仿真是顶层进行功能划分的重要环节,这时的设计是与工艺无关的。由于设计的主要仿真和调试过程是在高层次完成的所以能够早期发现结构设计上的错误,避免设计工作的浪费,同时也减少了逻辑仿真的工作量。自顶向下的设计方法方便了从系统级划分和管理整个项目,使得几十万门甚至几百万门规模的复杂数字电路的设计成为可能,并可减少设计人员,避免不必要的重复设计,提高了设计的一次成功率。从底向上的设计在某种意义上讲可以看作上述TOP_DOWN设计的逆过程。虽然设计也是从系统级开始,即从设计树的树根开始对设计进行逐次划分,但划分时首先考虑的是单元是否存在,即设计划分过程必须从存在的基本单元出发,设计树最末枝上的单元要么是已经制造出的单元,要么是其它项目已开发好的单元或者是可外购得到的单元。自顶向下的设计过程中在每一层次划分时都要对某些目标作优化,TOP_DOWN的设计过程是理想的设计过程,它的缺点是得到的最小单元不标准,制造成本可能很高。从底向上的设计过程全采用标准基本单元,通常比较经济,但有时可能不能满足一些特定的指标要求。复杂数字逻辑电路和系统的设计过程通常是这两种设计方法的结合,设计时需要考虑多个目标的综合平衡。第二章 Verilog HDL 设计方法概述-20 2.8 思考题 2.8 思考题 1.什么是硬件描述语言?它的主要作用是什么?2.目前世界上符合IEEE标准的硬件描述语言有哪两种?它门各有什么特点?3.什么情况下需要采用硬件描述语言的设计方法?4.采用硬件描述语言设计方法的优点是什么?有什么缺点?5.简单叙述一下利用EDA工具并采用硬件描述语言(HDL)的设计方法和流程。6.硬件描述语言可以用哪两种方式参与复杂数字电路的设计?7.用硬件描述语言设计的数字系统需要经过哪些步骤才能与具体的电路相对应?8.为什么说用硬件描述语言设计的数字逻辑系统具有最大的灵活性可以映射到任何工艺的电路上?9.软核是什么?虚拟器件是什么?它们的作用是什么?10.固核是什么?硬核是什么?与软核相比它们各有什么优缺点?11.简述TOP-DOWN设计方法和硬件描述语言的关系。第三章 Verilog HDL 基本语法-17第三章 Verilog HDL的基本语法 第三章 Verilog HDL的基本语法 前言前言 Verilog HDL是一种用于数字逻辑电路设计的语言。用Verilog HDL描述的电路设计就是该电路的Verilog HDL模型。Verilog HDL既是一种行为描述的语言也是一种结构描述的语言。这也就是说,既可以用电路的功能描述也可以用元器件和它们之间的连接来建立所设计电路的Verilog HDL模型。Verilog模型可以是实际电路的不同级别的抽象。这些抽象的级别和它们对应的模型类型共有以下五种:系统级(system):用高级语言结构实现设计模块的外部性能的模型。算法级(algorithm):用高级语言结构实现设计算法的模型。RTL级(Register Transfer Level):描述数据在寄存器之间流动和如何处理这些数据的模型。门级(gate-level):描述逻辑门以及逻辑门之间的连接的模型。开关级(switch-level):描述器件中三极管和储存节点以及它们之间连接的模型。一个复杂电路系统的完整Verilog HDL模型是由若干个Verilog HDL模块构成的,每一个模块又可以由若干个子模块构成。其中有些模块需要综合成具体电路,而有些模块只是与用户所设计的模块交互的现存电路或激励信号源。利用Verilog HDL语言结构所提供的这种功能就可以构造一个模块间的清晰层次结构来描述极其复杂的大型设计,并对所作设计的逻辑电路进行严格的验证。Verilog HDL行为描述语言作为一种结构化和过程性的语言,其语法结构非常适合于算法级和RTL级的模型设计。这种行为描述语言具有以下功能:可描述顺序执行或并行执行的程序结构。用延迟表达式或事件表达式来明确地控制过程的启动时间。通过命名的事件来触发其它过程里的激活行为或停止行为。提供了条件、if-else、case、循环程序结构。提供了可带参数且非零延续时间的任务(task)程序结构。提供了可定义新的操作符的函数结构(function)。提供了用于建立表达式的算术运算符、逻辑运算符、位运算符。Verilog HDL语言作为一种结构化的语言也非常适合于门级和开关级的模型设计。因其结构化的特点又使它具有以下功能:提供了完整的一套组合型原语(primitive);提供了双向通路和电阻器件的原语;可建立MOS器件的电荷分享和电荷衰减动态模型。Verilog HDL的构造性语句可以精确地建立信号的模型。这是因为在Verilog HDL中,提供了延迟和输出强度的原语来建立精确程度很高的信号模型。信号值可以有不同的的强度,可以通过设定宽范围的模糊值来降低不确定条件的影响。Verilog HDL作为一种高级的硬件描述编程语言,有着类似C语言的风格。其中有许多语句如:if语句、case语句等和C语言中的对应语句十分相似。如果读者已经掌握C语言编程的基础,那么学习Verilog HDL并不困难,我们只要对Verilog HDL某些语句的特殊方面着重理解,并加强上机练习就能很好地掌握它,利用它的强大功能来设计复杂的数字逻辑电路。下面我们将对Verilog HDL中的基本语法逐一加以介绍。3.1.简单的Verilog HDL模块 3.1.1.简单的Verilog HDL程序介绍 3.1.简单的Verilog HDL模块 3.1.1.简单的Verilog HDL程序介绍 第三章 Verilog HDL 基本语法-18下面先介绍几个简单的Verilog HDL程序,然后从中分析Verilog HDL程序的特性。例3.1.1:module adder(count,sum,a,b,cin);input 2:0 a,b;input cin;output count;output 2:0 sum;assign count,sum=a+b+cin;endmodule 这个例子通过连续赋值语句描述了一个名为adder的三位加法器可以根据两个三比特数a、b和进位(cin)计算出和(sum)和进位(count)。从例子中可以看出整个Verilog HDL程序是嵌套在module和 endmodule 声明语句里的。例3.1.2:module compare(equal,a,b);output equal;/声明输出信号equal input 1:0 a,b;/声明输入信号a,b assign equal=(a=b)?1:0;/*如果a、b 两个输入信号相等,输出为1。否则为0*/endmodule 这个程序通过连续赋值语句描述了一个名为compare的比较器。对两比特数 a、b 进行比较,如a与b相等,则输出equal为高电平,否则为低电平。在这个程序中,/*.*/和/.表示注释部分,注释只是为了方便程序员理解程序,对编译是不起作用的。例3.1.3:module trist2(out,in,enable);output out;input in,enable;bufif1 mybuf(out,in,enable);endmodule 这个程序描述了一个名为trist2的三态驱动器。程序通过调用一个在Verilog语言库中现存的三态驱动器实例元件bufif1来实现其功能。例3.1.4:module trist1(out,in,enable);output out;input in,enable;mytri tri_inst(out,in,enable);/调用由mytri模块定义的实例元件tri_inst endmodule module mytri(out,in,enable);output out;input in,enable;assign out=enable?in:bz;endmodule 这个程序例子通过另一种方法描述了一个三态门。在这个例子中存在着两个模块。模块trist1调用由模块mytri定义的实例元件tri_inst。模块trist1是顶层模块。模块mytri则被称为子模块。通过上面的例子可以看到:第三章 Verilog HDL 基本语法-19 Verilog HDL程序是由模块构成的。每个模块的内容都是嵌在module和endmodule两个语句之间。每个模块实现特定的功能。模块是可以进行层次嵌套的。正因为如此,才可以将大型的数字电路设计分割成不同的小模块来实现特定的功能,最后通过顶层模块调用子模块来实现整体功能。每个模块要进行端口定义,并说明输入输出口,然后对模块的功能进行行为逻辑描述。Verilog HDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分写多行。除了endmodule语句外,每个语句和数据定义的最后必须有分号。可以用/*.*/和/.对Verilog HDL程序的任何部分作注释。一个好的,有使用价值的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。3.1.2.模块的结构 3.1.2.模块的结构 Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明:请看上面的例子,程序模块旁边有一个电路图的符号。在许多方面,程序模块和电路图符号是一致的,这是因为电路图符号的引脚也就是程序模块的接口。而程序模块描述了电路图符号所实现的逻辑功能。上面的Verilog设计中,模块中的第二、第三行说明接口的信号流向,第四、第五行说明了模块的逻辑功能。以上就是设计一个简单的Verilog程序模块所需的全部内容。从上面的例子可以看出,Verilog结构完全嵌在module和endmodule声明语句之间,每个Verilog程序包括四个主要部分:端口定义、I/O说明、内部信号声明、功能定义。3.1.3.模块的端口定义 3.1.3.模块的端口定义 模块的端口声明了模块的输入输出口。其格式如下:module 模块名(口1,口2,口3,口4,module 模块名(口1,口2,口3,口4,);3.1.4.模块内容 );3.1.4.模块内容 模块的内容包括I/O说明、内部信号声明、功能定义。?I/O说明的格式如下:I/O说明的格式如下:输入口:input 端口名1,端口名2,,端口名i;/(共有i个输入口)输出口:output 端口名1,端口名2,,端口名j;/(共有j个输出口)I/O说明也可以写在端口声明语句里。其格式如下:module module_name(input port1,input port2,module module_name(input port1,input port2,module block(a,b,c,d);input a,b;output c,d;assign c=a|b;assign d=a&b;endmodule abcd第三章 Verilog HDL 基本语法-20output port1,output port2output port1,output port2););?内部信号说明:内部信号说明:在模块内用到的和与端口有关的wire 和 reg 变量的声明。如:reg width-1:0 R变量1,R变量2。;wire width-1:0 W变量1,W变量2。;.?功能定义功能定义:模块中最重要的部分是逻辑功能定义部分。有三种方法可在模块中产生逻辑。1).用“assign”声明语句 如:assign a=b&c;这种方法的句法很简单,只需写一个“assign”,后面再加一个方程式即可。例子中的方程式描述了一个有两个输入的与门。2).用实例元件 如:and and_inst(q,a,b);采用实例元件的方法象在电路图输入方式下,调入库元件一样。键入元件的名字和相连的引脚即可,表示在设计中用到一个跟与门(and)一样的名为and_inst的与门,其输入端为a,b,输出为q。要求每个实例元件的名字必须是唯一的,以避免与其他调用与门(and)的实例混淆。3).用“always”块 如:always(posedge clk or posedge clr)begin if(clr)q=0;else if(en)q=d;end 采用“assign”语句是描述组合逻辑最常用的方法之一。而“always”块既可用于描述组合逻辑也可描述时序逻辑。上面的例子用“always”块生成了一个带有异步清除端的D触发器。“always”块可用很多种描述手段来表达逻辑,例如上例中就用了if.else语句来表达逻辑关系。如按一定的风格来编写“always”块,可以通过综合工具把源代码自动综合成用门级结构表示的组合或时序逻辑电路。注意:注意:如果用Verilog模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。上面三个例子分别采用了“assign”语句、实例元件和“always”块。这三个例子描述的逻辑功能是同时执行的。也就是说,如果把这三项写到一个 VeriIog 模块文件中去,它们的次序不会影响逻辑实现的功能。这三项是同时执行的,也就是并发的。然而,在“always”模块内,逻辑是按照指定的顺序执行的。“always”块中的语句称为“顺序语句”,因为它们是顺序执行的。请注意,两个或更多的“always”模块也是同时执行的,但是模块内部的语句是顺序执行的。看一下“always”内的语句,你就会明白它是如何实现功能的。if.else if必须顺序执行,否则其功能就没有任何意义。如果else语句在if语句之前执行,功能就会不符合要求!为了能实现上述描述的功能,“always”模块内部的语句将按照书写的顺序执行。3.2.数据类型及其常量、变量 3.2.数据类型及其常量、变量 Verilog HDL中总共有十九种数据类型,数据类型是用来表示数字电路硬件中的数据储存和传送元素的。在本教材中我们先只介绍四个最基本的数据类型,它们是:reg型、wire型、integer型、parameter型 其它数据类型在后面的章节里逐步介绍,同学们也可以查阅附录中Verilog HDL语法参考书的有关章节逐步掌握。其它的类型如下:large型、medium型、scalared型、time型、small型、tri型、trio型、tri1型、triand型、trior型、trireg型、vectored型、wand型、wor型。这些数据类型除time型外都与基本逻辑单元建库有关,与系统设计没有很大的关系。在一般电路设计自动化的环境下,仿真用的基本部件库是由半导体厂家和EDA工具厂家共同提供的。系统设计工程师不必过多地关心门级和开关级的Verilog HDL语法现象。第三章 Verilog HDL 基本语法-21Verilog HDL语言中也有常量和变量之分。它们分别属于以上这些类型。下面就最常用的几种进行介绍。3.2.1.常量 3.2.1.常量 在程序运行过程中,其值不能被改变的量称为常量。下面首先对在Verilog HDL语言中使用的数字及其表示方式进行介绍。一数字 一数字?整数整数:在Verilog HDL中,整型常量即整常数有以下四种进制表示形式:1)二进制整数(b或B)2)十进制整数(d或D)3)十六进制整数(h或H)4)八进制整数(o或O)数字表达方式有以下三种:1)这是一种全面的描述方式。2)在这种描述方式中