资源描述
Verilog HDL 基础基础 第一部分第一部分 初级篇初级篇 第一讲第一讲 Verilog 的基本概念的基本概念4/21/20222n硬件描述语言HDL(Hardware Description Language)是硬件设计人员和电子设计自动化(EDA)工具之间的接口,其主要目的是用来编写设计文件,建立电子系统行为级的仿真模型。1.1 1.1 硬件描述语言硬件描述语言HDLHDL4/21/202231.1 1.1 硬件描述语言硬件描述语言HDLHDLn硬件描述语言利用计算机的巨大能力对用HDL建模的复杂数字逻辑进行仿真,然后再自动综合以生成符合要求且在电路结构上可以实现的数字逻辑网表(Netlist),根据网表和某种工艺的器件自动生成具体电路然后生成该工艺条件下这种具体电路的延时模型。仿真验证无误后用于制造ASIC芯片或写入CPLD和FPGA器件中。4/21/20224什么是硬件描述语言n具有特殊结构能够对硬件逻辑电路的功能进行描述的一种高级编程语言n这种特殊结构能够:q描述电路的连接描述电路的连接q描述电路的功能描述电路的功能q在不同抽象级上描述电路在不同抽象级上描述电路q描述电路的时序描述电路的时序q表达具有并行性表达具有并行性nHDL主要有两种:Verilog和VHDLqVerilog起源于起源于C语言,因此非常类似于语言,因此非常类似于C语言,容易掌握语言,容易掌握qVHDL格式严谨格式严谨qVHDL出现较晚,但标准化早。出现较晚,但标准化早。IEEE 1706-1985标准。标准。4/21/20225为什么要使用硬件描述语言4/21/202261.2 Verilog HDL 1.2 Verilog HDL 的历史的历史1.2.1 什么是什么是Verilog HDL Verilog HDL是硬件描述语言的一种,用于数字电子系统设计。设计者可用它进行各种级别的逻辑设计,可用它进行数字逻辑系统的仿真验证、时序分析、逻辑综合。它是目前应用最广泛的一种硬件描述语言。 4/21/202271.2 Verilog HDL 1.2 Verilog HDL 的历史的历史1.2.2 Verilog HDL的产生及发展的产生及发展lVerilog HDL是在是在1983年由年由GDA(GateWay Design Automation)公司的公司的Phil Moorby所创。所创。Phi Moorby后来成为后来成为Verilog-XL的主的主要设计者和要设计者和Cadence公司的第一个合伙人。公司的第一个合伙人。l在在19841985年间,年间,Moorby设计出了第一个设计出了第一个Verilog-XL的仿真器。的仿真器。l1986年,年,Moorby提出了用于快速门级仿真的提出了用于快速门级仿真的XL算法。算法。l1990年,年,Cadence公司收购了公司收购了GDA公司公司l1991年,年,Cadence公司公开发表公司公开发表Verilog语言,成立了语言,成立了OVI(Open Verilog International)组织来负责组织来负责Verilog HDL语言的发展。语言的发展。l1995年制定了年制定了Verilog HDL的的IEEE标准,即标准,即IEEE1364。4/21/202281.2 Verilog HDL 1.2 Verilog HDL 的历史的历史4/21/20229- 比比VerilogHDL早几年成为早几年成为I EEE标准;标准; - 语法语法/结构比较严格,因而编写出的结构比较严格,因而编写出的 模块风格比较清晰;模块风格比较清晰; - 比较适合由较多的设计人员合作完成比较适合由较多的设计人员合作完成 的特大型项目(一百万门以上)。的特大型项目(一百万门以上)。1.3 Verilog HDL 和和 VHDL的比较的比较4/21/202210- 较多的第三方工具的支持较多的第三方工具的支持 - 语法结构比语法结构比VHDL简单简单 - 学习起来比学习起来比VHDL容易容易 - 仿真工具比较好使仿真工具比较好使 - 测试激励模块容易编写测试激励模块容易编写1.3 Verilog HDL 和和 VHDL的比较的比较4/21/2022111.3 Verilog HDL 和和 VHDL的比较的比较4/21/2022121.4 Verilog 目前的应用情况和适用的设计目前的应用情况和适用的设计nVerilog的主要应用包括:的主要应用包括:qASICASIC和和FPGAFPGA工程师编写可综合的工程师编写可综合的RTLRTL代码代码q高抽象级系统仿真进行系统结构开发高抽象级系统仿真进行系统结构开发q测试工程师用于编写各种层次的测试程序测试工程师用于编写各种层次的测试程序q用于用于ASICASIC和和FPGAFPGA单元或更高层次的模块的模型单元或更高层次的模块的模型开发开发4/21/2022131.4 Verilog 目前的应用情况和适用的设计目前的应用情况和适用的设计 Verilog 较为适合系统级(System)、算法级(Alogrithem)、寄存器传输级(RTL)、逻辑(Logic)、门级(Gate)和电路开关级(Switch)的设计,而对于特大型(千万门级以上)的系统级(System)设计,则VHDL更为合适。4/21/2022141.5 采用采用 Verilog HDL 设计复杂数字电路的优点设计复杂数字电路的优点1.5.1 传统设计方法传统设计方法电路原理图输入法电路原理图输入法 采用电路原理图输入法进行设计,周期长、需要专门的设计工具、需手工布线等。这种低水平的设计方法大大延长了设计周期。4/21/202215 采用Verilog输入法,可以很容易地把完成的设计移植到不同厂家的不同芯片中去,并在不同规模应用时可以较容易地作修改。 采用Verilog输入法最大的优点是其。实际上这是利用了计算机的巨大能力并在EDA工具帮助下,把逻辑验证与具体工艺库匹配、布线即时延计算分成不同的阶段来实现,从而减轻了人们的繁琐劳动。4/21/2022161.5.3 Verilog 的标准化与软核的重用的标准化与软核的重用 Verilog 是在1983年由GDA公司首先开发成功的,经过诸多改进,于1995年11月正式被批准为Verilog IEEE13631995标准,又于2001年3月在原标准的基础上经过改进和补充推出Verilog IEEE13642001新标准。 由于Verilog HDL设计方法与工艺无关性,因而大大提高了Verilog 模型的可重用性。我们把功能经过验证的、可综合的、实现后电路结构总门数在5000门以上的Verilog HDL模型称之为“软核”(Softcore),而把由软核构成的器件成为虚拟器件。利用软核和虚拟器件的可重复利用的特性就可利用软核和虚拟器件的可重复利用的特性就可大大缩短设计周期,加快了复杂电路的设计。大大缩短设计周期,加快了复杂电路的设计。4/21/2022171.5.4 软核、固核和硬核的概念以及它软核、固核和硬核的概念以及它 们的重用们的重用 显而易见,在具体实现手段和工艺技术尚未确定的逻辑设计阶段,软核具有最大的灵活性。而近年来电路实现工艺技术的发展是相当迅速的,为了逻辑电路设计成果的积累,和更快更好地设计更大规模的电路,发展软核的设发展软核的设计和推广软核的重用技术是非常有必要的。计和推广软核的重用技术是非常有必要的。 把在某一种专用半导体集成电路工艺的(ASIC)器件上实现的经验证是正确的总门数在5000门以上的电路结构掩膜,称之为“硬核硬核”。 把在某一种现场可编程门阵列(FPGA)器件上实现的,经验证是正确的总门数在5000门以上电路结构编码文件,称之为“固核固核”。4/21/2022181.6 Verilog HDL 的设计流程简介的设计流程简介 自顶向下的设计是从系自顶向下的设计是从系统级开始,把系统级划分为统级开始,把系统级划分为若干个基本单元,然后再把若干个基本单元,然后再把每个基本单元划分为下一层每个基本单元划分为下一层次的基本单元,一直这样做次的基本单元,一直这样做下去,直到可以直接用下去,直到可以直接用EDAEDA元件库的基本元件来实现为元件库的基本元件来实现为止图止图1.1.31.1.3为自顶向下为自顶向下(Top-(Top-Down)Down)的示意图,以设计树的示意图,以设计树的形式绘出。的形式绘出。 1.6.1 1.6.1 自顶向下自顶向下(Top-Down)(Top-Down)设计的基本概念设计的基本概念图图 1.1.3 Top-Down 1.1.3 Top-Down 设计思想设计思想4/21/2022191.6 Verilog HDL 1.6 Verilog HDL 的设计流程简介的设计流程简介1.6.2 1.6.2 层次管理的基本概念层次管理的基本概念 复杂数字逻辑电路和系统的层次化、结构化设计隐含着硬复杂数字逻辑电路和系统的层次化、结构化设计隐含着硬件设计方案的逐次分解。完整的硬件设计可以由图件设计方案的逐次分解。完整的硬件设计可以由图1.1.31.1.3所示的设所示的设计树描述。在这个设计树上,节点对应着该层次上基本单元的行计树描述。在这个设计树上,节点对应着该层次上基本单元的行为描述,树枝对应着基本单元的结构分解。在不同的层次都可以为描述,树枝对应着基本单元的结构分解。在不同的层次都可以进行仿真以对设计思想进行验证。进行仿真以对设计思想进行验证。EDAEDA工具提供了有效的手段来管工具提供了有效的手段来管理错综复杂的层次,即可以很方便地查看某一层次某模块的源代理错综复杂的层次,即可以很方便地查看某一层次某模块的源代码或电路图以改正仿真时发现的错误。码或电路图以改正仿真时发现的错误。4/21/2022201.6.3 1.6.3 具体模块的设计编译和仿真的过程具体模块的设计编译和仿真的过程1.6 Verilog HDL 1.6 Verilog HDL 的设计流程简介的设计流程简介 从左图可以看出,模块设计流程主要由两大主要功能部分组成:即从编写设计文件综合到布局布线投片生成这样一系列步骤。也就是进行各种仿真的一系列步骤,如果在仿真过程中发现问题就返回设计输入进行修改。4/21/2022211.6 Verilog HDL 1.6 Verilog HDL 的设计流程简介的设计流程简介 1.6.4 1.6.4 对应具体工艺器件的优化、映象和布局布线对应具体工艺器件的优化、映象和布局布线 由于各种ASIC和FPFA器件的工艺各不相同,因而当用不同厂家的不同器件来实现已验证的逻辑网表(EDIF文件)时,就需要不同的基本单元库与布线延迟模型与之对应才能进行准确的优化、映象、和布局布线。基本单元库与布线延迟模型由熟悉本厂工艺的工程师提供,再由EDA厂商的工程师编入相应的处理程序,而逻辑电路设计师只需用一文件说明所用的工艺器件和约束条件,EDA工具就会自动地根据这一文件选择相应的库和模型进行准确的处理从而大大提高设计效率。4/21/2022221.7 小结n掌握掌握HDLHDL设计方法应从学习设计方法应从学习Verilog HDLVerilog HDL设计方法开始。设计方法开始。n由于由于Top-DownTop-Down的设计方法是首先从系统设计入手的,因而从顶层的设计方法是首先从系统设计入手的,因而从顶层进行功能划分和结构设计。系统的总体仿真是顶层进行功能化分进行功能划分和结构设计。系统的总体仿真是顶层进行功能化分的重要环节,这时的设计与工艺无关。的重要环节,这时的设计与工艺无关。n从底向上的设计在某种意义上讲是从底向上的设计在某种意义上讲是Top-DownTop-Down设计的逆过程。设计的逆过程。Verilog Verilog 数字系统设计教程数字系统设计教程第二讲第二讲 Verilog Verilog 语法的基本概念语法的基本概念4/21/202224nVerilogVerilog既是一种行为描述的语言也是一种结构描述语言。既是一种行为描述的语言也是一种结构描述语言。VerilogVerilog模型模型可以是实际电路的不同级别的抽象。这些抽象的级别包括:可以是实际电路的不同级别的抽象。这些抽象的级别包括: 系统级系统级(system):(system):用高级语言结构实现设计模块的外部性能的模型。用高级语言结构实现设计模块的外部性能的模型。 算法级算法级(algorithm):(algorithm):用高级语言结构实现设计算法的模型。用高级语言结构实现设计算法的模型。 RTL RTL级级(Register Transfer Level):(Register Transfer Level):描述数据在寄存器之间流动和如何描述数据在寄存器之间流动和如何处理、控制这些数据流动的模型。处理、控制这些数据流动的模型。 以上三种都属于行为描述,只有以上三种都属于行为描述,只有RTLRTL级才与逻辑电路有明确的对应关系。级才与逻辑电路有明确的对应关系。 门级门级(gate-level):(gate-level):描述逻辑门以及逻辑门之间的连接的模型。描述逻辑门以及逻辑门之间的连接的模型。 开关级开关级(switch-level):(switch-level):描述器件中三极管和储存节点以及它们之间连描述器件中三极管和储存节点以及它们之间连接的模型。接的模型。4/21/202225: 可描述顺序执行或并行执行的程序结构。可描述顺序执行或并行执行的程序结构。 用延迟表达式或事件表达式来明确地控制过程的启动时间。用延迟表达式或事件表达式来明确地控制过程的启动时间。 通过命名的事件来触发其它过程里的激活行为或停止行为。通过命名的事件来触发其它过程里的激活行为或停止行为。 提供了条件如提供了条件如if-elseif-else、casecase、循环程序结构。、循环程序结构。 提供了可带参数且非零延续时间的任务提供了可带参数且非零延续时间的任务(task)(task)程序结构。程序结构。 提供了可定义新的操作符的函数结构提供了可定义新的操作符的函数结构(function)(function)。 提供了用于建立表达式的算术运算符、逻辑运算符、位运算提供了用于建立表达式的算术运算符、逻辑运算符、位运算符。符。 Verilog HDL Verilog HDL语言作为一种结构化的语言也非常适合于门级语言作为一种结构化的语言也非常适合于门级和开关级的模型设计。和开关级的模型设计。4/21/202226 u提供了一套完整的表示组合逻辑的基本元件的原语提供了一套完整的表示组合逻辑的基本元件的原语( (primitiveprimitive););u提供了双向通路(总线)和电阻器件的原语提供了双向通路(总线)和电阻器件的原语; ;u可建立可建立MOSMOS器件的电荷分享和电荷衰减动态模型。器件的电荷分享和电荷衰减动态模型。 4/21/202227 【例【例 2.1】 module muxtwo (out, a, b, sl); input a,b,sl; output out; reg out; always (sl or a or b) if (! sl) out = a; else out = b; endmoduleabslout4/21/202228nMUX(多路选择器)的行为可以描述为:只要信号a或b或sl发生变化,如果sl为0则选择a输出;否则选择b输出。n这个行为的描述并没有说明如果输入 a 或 b是三态的(高阻时)输出应该是什么,但有具体结构的真实电路是有一定的输出的。n没有考虑延时问题4/21/202229【例【例2.2】module twomux (out, a, b, sl);module twomux (out, a, b, sl); input a, b, sl; input a, b, sl; output out; output out; not u1 (nsl, sl ); not u1 (nsl, sl ); and #1 u2 (sela, a, and #1 u2 (sela, a, nsel);nsel); and #1 u3 (selb, b, sl); and #1 u3 (selb, b, sl); or #2 u4 (out, sela, or #2 u4 (out, sela, selb);selb);endmoduleendmoduleabslselbselansel MUXMUX的结构级描述,采用的结构级描述,采用VerilogVerilog基本单元基本单元( (门门) )描述。描描述。描述中含有传输延时。述中含有传输延时。4/21/202230【例【例 2.3】 module adder ( count,sum,a,b,cin );module adder ( count,sum,a,b,cin ); input 2:0 a,b; input 2:0 a,b; input cin; input cin; output count; output count; output 2:0 sum; output 2:0 sum; assign count,sum=a+b+cin; assign count,sum=a+b+cin; endmodule endmodule 4/21/202231【例【例 2.4】 module compare ( equal,a,b ); output equal; /声明输出信号声明输出信号equal input 1:0 a,b; /声明输入信号声明输入信号a,b assign equal=(a=b)?)?1:0; /*如果两个输入信号相等则输出为如果两个输入信号相等则输出为1。否则输出。否则输出为为0*/ endmodule 这个程序描述了一个比较器这个程序描述了一个比较器. .在这个程在这个程中中,/,/* *.* */ /和和/./.表示注释部分表示注释部分, ,注释只是注释只是为了方便程序员理解程序为了方便程序员理解程序, ,对编译是不起作用的。对编译是不起作用的。4/21/202232n【例【例2.52.5】nmodule trist2(out,in,enable);module trist2(out,in,enable);n output out; output out;n input in ,enable; input in ,enable;n bufil1 mybuf(out,in,enable); bufil1 mybuf(out,in,enable);nendmoduleendmodule程序通过调用一个在Verilog语言提供的原语库中现存的三态驱动器元件bufil1来实现其逻辑功能。这个调用过程也称为库元件bufif1的实例化,在本模块中它被具体化为mybuf.33【例【例2.62.6】module trist1(sout,sin,ena);module trist1(sout,sin,ena); output sout; output sout; input sin,ena; input sin,ena; mytri tri_inst(.out(sout),.in(sin),.enable(ena); mytri tri_inst(.out(sout),.in(sin),.enable(ena);/调用由调用由mytrimytri模块定义的实例元件模块定义的实例元件tri_insttri_inst,即把已定义的模块,即把已定义的模块myfrimyfri在本模块中具体化为在本模块中具体化为tri_insttri_instendmoduleendmodulemodule mytri(out,in,enable);module mytri(out,in,enable); output out; output out; input in,enable; input in,enable; assign out=enable?in: assign out=enable?in:bz;bz;endmoduleendmodule4/21/202234n如何检查上述例子其功能是否正确?如何检查上述例子其功能是否正确?n 需要有测试激励信号输入到被测模块需要有测试激励信号输入到被测模块n 需要记录被测模块的输出信号需要记录被测模块的输出信号n 需要把用功能和行为描述的需要把用功能和行为描述的VerilogVerilog模块转换为门模块转换为门级电路互连的电路结构(综合)。级电路互连的电路结构(综合)。n 需要对已经转换为门级电路结构的逻辑进行测试需要对已经转换为门级电路结构的逻辑进行测试(门级电路仿真)。(门级电路仿真)。n 需要对布局布线后的电路结构进行测试。需要对布局布线后的电路结构进行测试。 (布局布线后仿真)。(布局布线后仿真)。35被测模块被测模块激励和控激励和控制信号制信号输出响应输出响应和验证和验证36通过上面的例子可以看到通过上面的例子可以看到: :(1 1)Verilog HDLVerilog HDL程序是由模块构成的。每个模块的内容都是位于程序是由模块构成的。每个模块的内容都是位于modulemodule和和endmoduleendmodule两个语句之间。每个模块实现特定的功能。两个语句之间。每个模块实现特定的功能。(2 2)模块是可以进行层次嵌套的。)模块是可以进行层次嵌套的。(3 3)每个模块要进行端口定义)每个模块要进行端口定义, ,并说明输入输出口并说明输入输出口, ,然后对模块的功能进行然后对模块的功能进行描述。描述。(4 4)Verilog HDLVerilog HDL程序的书写格式自由程序的书写格式自由, ,一行可以写几个语句一行可以写几个语句, ,一个语句也可一个语句也可以分写多行。以分写多行。(5 5)除了)除了endmoduleendmodule语句外语句外, ,每个语句和数据定义的最后必须有分号。每个语句和数据定义的最后必须有分号。(6 6)可以用)可以用/ /* *.* */ /和和/./.对对Verilog HDLVerilog HDL程序的任何部分作注释。一个程序的任何部分作注释。一个好的好的, ,有使用价值的源程序都应当加上必要的注释有使用价值的源程序都应当加上必要的注释, ,以增强程序的可读以增强程序的可读性和可维护性。性和可维护性。Verilog 数字系统设计教程数字系统设计教程第三讲第三讲 常用常用Verilog 语法之一语法之一 VerilogVerilog的基本设计单元是的基本设计单元是“模块模块”(block)(block) 。一个模。一个模块是由两部分块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是义输入是如何影响输出的。如何影响输出的。 module block1(a, b, c, d); module block1(a, b, c, d); input a, b; input a, b; output c, d; output c, d; assign c = a | b; assign c = a | b; assign d = a & b; assign d = a & b; endmodule endmoduleabcd Verilog Verilog 模块的结构由在模块的结构由在modulemodule和和endmodule endmodule 关关键词之间的四个主要部分组成:键词之间的四个主要部分组成: module block1(a, b, c, d ); input a, b, c ; output d ; wire x; assign d = a | x ; assign x = ( b & c ); endmodule 3.1.1 3.1.1 模块的端口定义模块的端口定义 模块的端口声明了模块的输入输出口。其格式如下:模块的端口声明了模块的输入输出口。其格式如下: module module 模块名模块名( (口口1 1,口,口2 2,口,口3 3,口,口4, 4, ););3.1.2 3.1.2 模块内容模块内容 模块的内容包括模块的内容包括I/OI/O说明、内部信号声明、功能定义。说明、内部信号声明、功能定义。 输入口: input信号位宽1:0 端口名1; input信号位宽1:0 端口名2; input信号位宽1:0 端口名i; /(共有i个输入口)输出口输出口 outputoutput信号位宽信号位宽1 1:0 0 端口名端口名1 1; outputoutput信号位宽信号位宽1 1:0 0 端口名端口名2 2; output output信号位宽信号位宽1 1:0 0 端口名端口名j j; /(/(共有共有j j个个输出口输出口) )输入输入/ /输出口:输出口: inoutinout信号位宽信号位宽1 1:0 0 端口名端口名1 1; inoutinout信号位宽信号位宽1 1:0 0 端口名端口名2 2; inout inout信号位宽信号位宽1 1:0 0 端口名端口名k k; /(/(共有共有k k个个双向总线端口双向总线端口) ) I/O I/O说明也可以写在端口声明语句里。其格式如下:说明也可以写在端口声明语句里。其格式如下: module module_name(input port1,input port2,module module_name(input port1,input port2, output port1,output port2 output port1,output port2 ); ); 在模块内用到的和与端口有关的在模块内用到的和与端口有关的wire wire 和和 reg reg 变量的声明。变量的声明。 如:如: reg width-1 : 0 Rreg width-1 : 0 R变量变量1 1,R R变量变量2 2 ; wire width-1 : 0 Wwire width-1 : 0 W变量变量1 1,W W变量变量2 2 ; 模块中最重要的部分是逻辑功能定义部分。有三种方法可在模块中最重要的部分是逻辑功能定义部分。有三种方法可在模块中产生逻辑。模块中产生逻辑。 assign a = b & c ;assign a = b & c ; and2 and_inst ( q, a, b);and2 and_inst ( q, a, b); always (posedge clk or posedge clr)always (posedge clk or posedge clr) begin begin if (clr) q= 0; else if (en) q= d; if (clr) q= 0; else if (en) q= d; end end如在模块中逻辑功能由下面三个语句块组成如在模块中逻辑功能由下面三个语句块组成 : assign cs = ( a0 & a1 & a2 ) ; / -1 and2 and_inst ( qout, a, b); / -2 always (posedge clk or posedge clr) /-3 begin if (clr) q= 0; else if (en) q= d; end三条语句是并行的,它们产生独立的逻辑电路;三条语句是并行的,它们产生独立的逻辑电路;而在而在 always 块中块中: begin 与与 end 之间是顺序执行的。之间是顺序执行的。 在在Verilog HDLVerilog HDL中中, ,整型常量即整常数有以下四种进制表示整型常量即整常数有以下四种进制表示形式形式: :1) 1) 二进制整数二进制整数(b(b或或B)B)2) 2) 十进制整数十进制整数(d(d或或D)D)3) 3) 十六进制整数十六进制整数(h(h或或H)H)4) 4) 八进制整数八进制整数(o(o或或O)O) 数字表达方式有以下三种数字表达方式有以下三种: :1) 1) 这是一种全面的描述方式。这是一种全面的描述方式。2) 2) 在这种描述方式中在这种描述方式中, ,数字的位宽采用缺省位宽数字的位宽采用缺省位宽( (这由具体的机器系统决定这由具体的机器系统决定, ,但至少但至少3232位位) )。3) 3) 在这种描述方式中在这种描述方式中, ,采用缺省进制十进制。采用缺省进制十进制。3.1.2 数值1. Verilog HDL中的数值可取下面的四类值:0逻辑零、逻辑非、低电平1逻辑1、逻辑真、高电平x或X不确定的逻辑状态z或Z高阻态Verilog HDL中有两类数值常量 整型数和实型数 下划线符号“_”除了不能放于数值的首位以外,可以随意用在整型数与实型数中,他们对数值的大小没有任何改变,只是为了提高可读性。 1)整型数及其表示 Verilog HDL的整数可以使二进制(b或B)、十进制(d或D)、十六进制(h或H)与八进制(o或O),有下面三种书写形式(1)简单的十进制格式;(2)缺省位宽的基数格式;(3)指定位宽的基数格式。Verilog HDL中有两类数值常量 整型数和实型数()简单的十进制格式:()简单的十进制格式:用的数字串组成的十进制数,可以用符号用的数字串组成的十进制数,可以用符号“”或或“”来表示数的来表示数的正负正负()缺省位宽的基数格式;()缺省位宽的基数格式; 表示形式为:表示形式为:符号符号“”为基数格式表示的固有字符,该字符不能省略,否则为非法表示形为基数格式表示的固有字符,该字符不能省略,否则为非法表示形式;参数式;参数用于说明数值采用的进制格式;参数用于说明数值采用的进制格式;参数为为相应进制格式下的一串数字这种格式未指定位宽,其缺省值至少为位相应进制格式下的一串数字这种格式未指定位宽,其缺省值至少为位()指定位宽的基数格式:()指定位宽的基数格式: 表示形式为:表示形式为:sizebase_formatnumber参数参数size用来指定所表示数字的位宽当位宽小于数值的实际大小时,用来指定所表示数字的位宽当位宽小于数值的实际大小时,相应的高位部分被忽略;当位宽大于数值的实际位数,且数值的最高位是或相应的高位部分被忽略;当位宽大于数值的实际位数,且数值的最高位是或时,相应的高位部分补;而当位宽大于数值的实际位数,但数值的最高位是时,相应的高位部分补;而当位宽大于数值的实际位数,但数值的最高位是x或或z时,相应的高位部分补或时,相应的高位部分补或数制基数符号合法的表示值二进制b or B0,1,x,X,z,Z,?,_八进制o or O07,x,X,z,Z,?,_十进制d or D09,_十六进制h or H09,af,AF,x,X,z,Z,?,_Verilog HDL中有两类数值常量 整型数和实型数基数符号及其合法的表示值数值表示位宽数制等效二进制值及其解书释10缺省十进制00_1010(32位或以上)4ac缺省十进制非法,十进制表示不允许出现ac字样h4ac缺省十六进制0_0100_1010_1100(32位或以上)9o6719位八进制0110_0111_00019o-6719位八进制非法,符号位只能出现在表示的最左端6hf36位十六进制11_0011,高位部分被舍去6hf6位十六进制00_1111,高位部分由0补足3b10 x3位二进制10 x12h2x612位十六进制0010_xxxx_10106hx6位十六进制xx_xxxx,高位部分由x补足Verilog HDL中有两类数值常量 整型数和实型数例;三种格式的整数表示法15(十进制15)简单的十进制h15(十进制21,十六进制15)缺省位宽的十六进制5b10011(十进制19,二进制10011)位的二进制12h01F(十进制31,十六进制01F)位的十六进制Syntax: Integer 存为 表示 1 00000000000000000000000000000001 unsized 32bits 8hAA 10101010 sized hex6b10_0011 100011 sized binary hF00000000000000000000000000001111 unsized hex 32 bits 8Hfz 1111zzzzsized hex 1bx Xsized binaryVerilog HDL中有两类数值常量 整型数和实型数Verilog HDL中的实数可以用十进制与科学计数法两种格式来表示,如果采用十进制格式,小数点两边必须都有数字,否则为非法的表示形式实数表示法的实例1.8 /十进制计数法3.8e10 /科学计数法2.1E-9 /科学计数法可用e或E表示,其结果相同3_2387.3398_3047 /使用下划线提高可读性3. /非法表示,小数点两遍都必须有数.2e6 /非法表示,小数点两遍都必须有数.12 /非法表示,小数点两遍都必须有数实型数及其表示Verilog HDL中有两类数值常量 整型数和实型数l在数字电路中在数字电路中,x,x代表不定值代表不定值,z,z代表高阻值。一代表高阻值。一个个x x可以用来定义十六进制数的可以用来定义十六进制数的4 4位二进制数的位二进制数的状态状态, ,八进制数的八进制数的3 3位位, ,二进制数的二进制数的1 1位。位。z z的表的表示方式同示方式同x x类似。类似。z z还有一种表达方式是可以写还有一种表达方式是可以写作作“?”?”。一个数字可以被定义为负数一个数字可以被定义为负数, ,只需在位宽表达式前加一个减号只需在位宽表达式前加一个减号, ,减号减号必须写在数字定义表达式的最前面。注意减号不可以放在位宽和进制之间必须写在数字定义表达式的最前面。注意减号不可以放在位宽和进制之间也不也不可以放在进制和具体的数之间。可以放在进制和具体的数之间。 -8d5 /-8d5 /这个表达式代表这个表达式代表5 5的补数(用八位二进制数表示的补数(用八位二进制数表示) ) 8d-5 / 8d-5 /非法格式非法格式。下划线可以用来分隔开数的表达以提高程序可。下划线可以用来分隔开数的表达以提高程序可读性。但不可以用在位宽和进制处读性。但不可以用在位宽和进制处, ,只能用在具体的数字之间。只能用在具体的数字之间。 16b1010_1011_1111_1010 /16b1010_1011_1111_1010 /合法格式合法格式 8b_0011_1010 /8b_0011_1010 /非法格式非法格式 当常量不说明位数时,默认值是当常量不说明位数时,默认值是3232位,每个字母用位,每个字母用8 8位的位的ASCIIASCII值表值表示。示。用参数声明一个可变常量,常用于定义延时及宽度变量。用参数声明一个可变常量,常用于定义延时及宽度变量。参数定义的语法:参数定义的语法:parameter ;可一次定义多个参数,用逗号隔开。可一次定义多个参数,用逗号隔开。在使用文字在使用文字(literal)的地方都可以使用参数。的地方都可以使用参数。参数的定义是局部的,只在当前模块中有效。参数的定义是局部的,只在当前模块中有效。参数定义可使用以前定义的整数和实数参数。参数定义可使用以前定义的整数和实数参数。module mod1( out, in1, in2); . . .parameter cycle = 20, prop_ del = 3, setup = cycle/2 - prop_del, p1 = 8, x_ word = 16bx, file = / usr1/ jdough/ design/ mem_ file. dat; . . . wire p1: 0 w1; / A wire declaration using parameter . . .endmodule注意注意:参数:参数file不是不是string,而是一个整数,而是一个整数,其值是所有字母的扩展其值是所有字母的扩展ASCII值。若值。若file=“AB”,则则file值为值为8h4142。用。用法:法:$fopen(file);$display(“%s”, file);3.2.2 变量变量 变量即在程序运行过程中其值可以改变的量。常用的网络数据类型包括wirewire型和型和tritri型型。wire型变量通常是用来表示单个门驱动或连续赋值语句驱动的网络型数据,tri型变量则用来表示多驱动器驱动的网络型数据。 表 1.3.1 Wire/tri 变量的真值 wire型数据常用来表示用于以assign关键字指定的组合逻辑信号。Verilog程序模块中输入输出信号类型缺省时自动定义为wire型。其格式如下: wire n-1:0 数据名1,数据名2,数据名i; /共有i条总线,每条总线内有n条线路,或 wire n:1 数据名1,数据名2,数据名i; 寄存器是数据储存单元的抽象。寄存器数据类型的关键寄存器是数据储存单元的抽象。寄存器数据类型的关键字是字是 regreg。 regreg类型数据的默认初始值为不定值类型数据的默认初始值为不定值x x。 regreg型数据常用来表示用于型数据常用来表示用于“always”always”模块内的指定信号,模块内的指定信号,常代常代表触发器。表触发器。在在“always”always”块内被赋值的每一个信号都必须定块内被赋值的每一个信号都必须定义成义成regreg型。型。 regreg型数据的格式如下:型数据的格式如下: reg n-1:0 reg n-1:0 数据名数据名1,1,数据名数据名2,2, 数据名数据名i;i;或或 reg n:1 reg n:1 数据名数据名1,1,数据名数据名2,2, 数据名数据名i;i;module top;module top;wire y;wire y; reg a, b; reg a, b; DUT u1(y,a,b); DUT u1(y,a,b); initial initial begin begin a = 0; b = 0; a = 0; b = 0; #10 a =1; #10 a =1; . . end endendmodule endmodule module DUT(Y, A, B_);output Y;input A,B: wire Y, A, B; and (Y, A, B);endmodule模块DUT的边界输入口输出口输出/入口netnetnet/registernetnet/registernetinout举例说明数据类型的选择举例说明数据类型的选择n输入口(输入口(inputinput)可以由寄存器或网络连接)可以由寄存器或网络连接驱动,但它本身只能驱动网络连接。驱动,但它本身只能驱动网络连接。n输出口输出口 (output)(output)可以由寄存器或网络连接可以由寄存器或网络连接驱动,但它本身只能驱动网络连接。驱动,但它本身只能驱动网络连接。n输入输入/ /输出口输出口(inout)(inout)只可以由网络连接驱动,只可以由网络连接驱动,它本身也只能驱动网络连接。它本身也只能驱动网络连接。n如果信号变量是在过程块如果信号变量是在过程块 (initial(initial块块 或或 alwaysalways块块) )中被赋值的,必须把它声明为寄中被赋值的,必须把它声明为寄存器类型变量存器类型变量 如何选择正确的数据类型?如何选择正确的数据类型?如何选择正确的数据类型如何选择正确的数据类型module top;wire y; reg a, b;DUT u1 (y, a, b) ;initial begina = 0; b = 0; #5 a = 1; endendmodulemodule DUT (Y, A, B);output Y;input A, B;wire Y, A, B;and (Y, A, B) ;endmodule输入端口可以由输入端口可以由net/register驱动,但驱动,但输入端口只能是输入端口只能是net输出端口可以是输出端口可以是net/register类型,输类型,输出端口只能驱动出端口只能驱动net在过程块中只能给在过程块中只能给register类型赋值类型赋值若若Y,A,B说明为说明为reg则会产生错误。则会产生错误。in1in2OABY双向端口输入双向端口输入/输出输出只能是只能是net类型类型选择数据类型时常犯的错误举例选择数据类型时常犯的错误举例修改前:修改前:module example(o1, o2, a, b, c, d); input a, b, c, d; output o1, o2; reg c, d; reg o2 and u1(o2, c, d); always (a or b) if (a) o1 = b; else o1 = 0;endmodule修改后:修改后:module example(o1, o2, a, b, c, d); input a, b, c, d; output o1, o2;/ reg c, d;/ reg o2 reg o1; and u1(o2, c, d); always (a or b) if (a) o1 = b; else o1 = 0;endmoduleexample.v选择数据类型时常犯的错误举例Compiling source file example.vError! Illegal left-hand-side assignment Verilog-ILHSA example.v, 11: o1 = b;Error! Illegal left-hand-side assignment Verilog-ILHSA example.v, 12: o1 = 0;2 errors第一次编译信息第一次编译信息verilog c example.v第二次编译信息第二次编译信息Compiling source file example.vError! Incompatible declaration, (c) defined as input at line 2 Verilog-IDDIL example.v, 5: Error! Incompatible declaration, (d) defined as input at line 2 Verilog-IDDIL example.v, 5: Error! Gate (u1) has illegal output specification Verilog-GHIOS example.v, 8: 3 errors Verilog HDLVerilog HDL通过对通过对regreg型变量建立数组来对存储器建模,型变量建立数组来对存储器建模,可以描述可以描述RAMRAM型存储器,型存储器,ROMROM存储器和存储器和regreg文件。数组中的每一个单元文件。数组中的每一个单元通过一个通过一个数组索引进行寻址。在数组索引进行寻址。在VerilogVerilog语言中没有多维数组存在。语言中没有多维数组存在。 memorymemory型数型数据是通过扩展据是通过扩展regreg型数据的地址范围来生成的。其格式如下:型数据的地址范围来生成的。其格式如下: reg n-1:0 reg n-1:0 存储器名存储器名m-1:0m-1:0;或或 reg n-1:0 reg n-1:0 存储器名存储器名m:1m:1; Verilog HDLVerilog HDL语言的运算符范围很广,其运算符按其功能可分语言的运算符范围很广,其运算符按其功能可分为以下几类为以下几类: :运算符分类所含运算符算术运算符+,-,*,/,%逻辑运算符!,&,|关系运算符,=相等运算符=,!=,=,!=位运算符,&,|,or归约运算符&,&,|,|,or移位运算符条件运算符?:连接运算符 在在Verilog HDL语言中运算符所带的操作数是不同的,按其所带语言中运算符所带的操作数是不同的,按其所带操作数的个数运算符可分为三种操作数的个数运算符可分为三种:1) 单目运算符单目运算符(unary operator):可以带一个操作数可以带一个操作数,操作数放在运算符的右边。操作数放在运算符的右边。2) 二目运算符二目运算符(binary operator):可以带二个操作数可以带二个操作数,操作数放在运算符的两边。操作数放在运算符的两边。3) 三目运算符三目运算符(ternary operator):可以带三个操作可以带三个操作,这三个操作数用三目运算符这三个操作数用三目运算符分隔开。分隔开。 见下例见下例: clock = clock; / 是一个单目取反运算符是一个单目取反运算符, clock是操作数。是操作数。 c = a | b; / 是一个二目按位或运算符是一个二目按位或运算符, a 和和 b是操作数。是操作数。 r = s ? t : u; / ?: 是一个三目条件运算符是一个三目条件运算符, s,t,u是操作数。是操作数。3.3.1.基本的算术运算符基本的算术运算符 + 加加 - 减减 * 乘乘 / 除除 % 模模 将负数赋值给将负数赋值给reg或其它无符号变或其它无符号变量使用量使用2的补码算术。的补码算术。 如果操作数的某一位是如果操作数的某一位是x或或z,则,则结果为结果为x 在整数除法中,余数舍弃在整数除法中,余数舍弃 模运算中使用第一个操作数的符模运算中使用第一个操作数的符号号module arithops (); parameter five = 5; integer ans, int; reg 3: 0 rega, regb; reg 3: 0 num; initial begin rega = 3; regb = 4b1010; int = -3; /int = 11111111_1101 end initial fork #10 ans = five * int; / ans = -15 #20 ans = (int + 5)/ 2; / ans = 1 #30 ans = five/ int; / ans = -1 #40 num = rega + regb; / num = 1101 #50 num = rega + 1; / num = 0100 #60 num = int; / num = 1101 #70 num = regb % rega; / num = 1 #80 $finish;joinendmodule注意integer和reg类型在算术运算时的差别。integer是有符号数,而reg是无符号数。3.3.2.位运算符位运算符 not & and | or xor xnor xnor 按位操作符对矢量中相对应位运算。按位操作符对矢量中相对应位运算。regb = 4b1 0 1 0regb = 4b1 0 1 0regc = 4b1 x 1 0regc = 4b1 x 1 0num = regb & regc = 1 0 1 0 ;num = regb & regc = 1 0 1 0 ; 位值为位值为x x时不一定产生时不一定产生x x结果。如结果。如#50#50时的时的oror计算。计算。module bitwise (); reg 3: 0 rega, regb, regc; reg 3: 0 num; initial begin rega = 4b1001; regb = 4b1010; regc = 4b11x0; end initial fork #10 num = rega & 0; / num = 0000 #20 num = rega & regb; / num = 1000 #30 num = rega | regb; / num = 1011 #40 num = regb & regc; / num = 10 x0 #50 num = regb | regc
展开阅读全文