第3章〓硬件描述语言Verilog HDL基础 3.1学习要点 1. 硬件描述语言概述 硬件描述语言(Hardware Description Language,HDL)是一种用形式化方法来描述数字逻辑电路和系统的语言。利用这种语言,数字电路系统的设计可以从上层到下层、从抽象到具体逐层描述,用一系列分层次的模块实现复杂的数字系统。 硬件描述语言可以在结构级(也称逻辑门级)、行为级、寄存器传输级(Register Transfer Level,RTL)这几种不同的层次上对电路进行描述。通过逻辑综合,后两种层次的硬件描述语言源文件可以被转换到低抽象级别的门级描述。 硬件描述语言有两种用途: 系统仿真和硬件实现。如果仅用于仿真,那么所有的语法和编程方法都可以使用。如果用于硬件实现,则必须保证程序“可综合”。也就是说,所有的硬件描述语言描述都可以用于仿真,但不是所有的硬件描述语言描述都能用于硬件实现。 2. Verilog语言基本概念 1) Verilog程序基本结构 以全加器为例,见图311和图312,描述了一个名为full_adder的模块,模块(module)是Verilog的基本描述单位,用于描述逻辑电路的功能或结构,以及与子模块端口的关系。full_adder模块有5个端口: 3个输入端口和2个输出端口。全加器为顶层模块,半加器为底层模块,通过模块例化调用底层模块。 图311全加器full_adder.v 图312半加器half_adder.v 模块以关键词module开始,以关键词endmodule结尾,模块包括4部分: 端口定义、I/O说明、内部信号声明、功能定义。 2) Verilog语言要素 在Verilog程序中,有各种符号,例如,标识符、操作符、字符串、注释等。 (1) 标识符。 标识符用于定义模块、端口、实例等名称。标识符可以是任意一组字母、数字、$符号和_(下画线)符号的组合,标识符的第一个字符必须是字母或者下画线,字符数不能多于1024个。标识符是区分字母大小写的。 (2) 关键词。 Verilog语言内部已经使用的词称为关键词或保留字,关键词不能随便使用。需注意关键词都是小写字母。例如,always是关键词,ALWAYS不是关键词。 (3) 注释。 Verilog程序的注释有2种: 多行注释和单行注释。多行注释: 以“/*”符号开始,到“*/”结束; 在两个符号之间的语句都是注释语句。单行注释: 以“//”开始到本行结束都属于注释语句,不允许续行。 (4) 逻辑值。 在Verilog中有4种逻辑值。 ① 逻辑0: 表示低电平,在逻辑电路中通常接地; ② 逻辑1: 表示高电平,在逻辑电路中通常接电源; ③ 逻辑x: 表示逻辑状态不定,有可能是高电平,也有可能是低电平; ④ 逻辑z: 表示高阻态,是一个悬空状态。 (5) 常量。 在程序运行过程中,其值不能被改变的量称为常量。常量有整型常量、字符型常量、参数、线网(wire)和寄存器(reg)等数据类型。 3) Verilog运算符 (1) 算术运算符。 算术运算符又称为二进制运算符,有下面5种。 ① +: 加法运算符,或正值运算符,如a+b、+3; ② -: 减法运算符,或负值运算符,如a-3,-3; ③ *: 乘法运算符,如a*3; ④ /: 除法运算符,如5/3; ⑤ %: 模运算符,也称为求余运算符,要求%两侧均为整型数据。 (2) 关系运算符。 在进行关系运算时,如果声明的关系是假的(false),则返回值是0; 如果声明的关系是真(true),则返回值是1。关系运算符如下: ① a<ba小于b ② a>ba大于b ③ a<=ba小于或等于b ④ a>=ba大于或等于b ⑤ a==ba逻辑相等b ⑥ a!=ba逻辑不等于b (3) 逻辑运算符。 逻辑运算符包括3种运算: && (逻辑与)、||(逻辑或)、!(逻辑非)。 (4) 位逻辑运算符。 如果操作数长度不相等,那么长度短的操作数在高位补0。按位逻辑运算有5种。 ① ~: 非运算; ② &: 与运算,例如,4'b0100 & 4'b0110运算结果为4'b0100; ③ |: 或运算,例如,4'b0100 | 4'b0110运算结果为4'b0110; ④ ^: 异或运算,例如,4'b0100 ^ 4'b0110运算结果为4'b0010; ⑤ ~^,^~: 同或运算,例如,4'b0100~^ 4'b0110运算结果为4'b1101。 (5) 条件运算符。 条件操作符是三目运算符,根据条件表达式的值选择表达式,形式如下: 条件 ? 表达式1 : 表达式2 如果条件为真(即值为1),则执行表达式1; 如果条件为假(值为0),则执行表达式2。 (6) 连接运算符。 连接运算{}也称拼接运算,是将{}内的小表达式合并成大表达式,形式如下: {expr1,expr2,…,exprN} (7) 移位运算符。 在Verilog中,有两种移位运算符: <<(左移位运算符)和>>(右移位运算符)。执行移位运算时,操作数空出的位置填0。 (8) 操作符优先级。 操作符优先级见表311,顶部优先级最高,底部优先级最低; 同一行的操作符具有相同的优先级。 表311操作符优先级 操作符优先级 !~ 最高级 */% | +- | <<>> | <<=>>= | ==!====!== | & | ^^~ | | | && | || ↓ ? : 最低级 3. Verilog行为语句 Verilog行为语句有过程语句、块语句、赋值语句、条件语句、循环语句等,如表312所示。 表312Verilog行为语句 类别 语句 可综合 过程语句 initial always 是 块语句 串行块beginend 是 并行块forkjoin 赋值语句 持续赋值assign 是 过程赋值 =<= 是 条件语句 if else 是 case 是 循环语句 for 范围必须是静态时可综合 repeat 重复值是常数时可综合 while forever 编译预处理 'define 是 'include 是 'ifdef'else'endif 是 1) 赋值语句 在Verilog语言中,有持续赋值语句和过程赋值语句,过程赋值有非阻塞赋值和阻塞赋值。 (1) 持续赋值语句。 assign为持续赋值语句,主要对wire型变量赋值。 (2) 过程赋值语句。 过程赋值语句主要对reg型变量赋值。 ① 非阻塞赋值方式。符号“<=”用于非阻塞赋值,非阻塞赋值语句在执行时不会阻塞后面的语句执行,也就是后面的赋值语句也同时执行。 ② 阻塞赋值方式。符号“=”用于阻塞的赋值,阻塞赋值“=”在begin和end之间的语句是顺序执行,属于串行语句。 2) 条件语句 (1) ifelse语句。if语句是用来判定所给定的条件是否满足,根据判定的结果决定执行给出的两种操作之一。 (2) case语句。case语句是一种多分支选择语句,if语句只有两个分支可供选择,而实际问题中常常需要用到多分支选择,case语句直接处理多分支选择。 3) 循环语句 在Verilog中有4种类型的循环语句,用来控制执行语句的执行次数。 (1) forever: 连续地执行语句,用在initial块中,生成时钟等周期性波形。 (2) repeat: 反复执行一条语句n次。 (3) while: 执行一条语句直到某个条件不满足。如果一开始条件就不满足(为假),则语句一次也不能被执行。 (4) for: 有条件循环语句。 4. Verilog语言的描述语句 一个复杂的数字逻辑系统的Verilog模型是由若干个Verilog模块构成的,每个模块又由若干个子模块构成。用Verilog描述的数字逻辑电路就是该逻辑电路的Verilog模型(也称模块),是Verilog的基本描述单位。 模块的几种描述形式(也称建模方式)包括行为级描述形式、结构级描述形式以及数据流描述形式。如果从逻辑电路结构描述电路模块,则称为结构描述形式; 如果对线性变量进行操作,则称为数据流描述形式; 如果从功能和行为描述电路模块,则称为行为级描述形式。 1) 数据流描述形式 数据流描述是用连续赋值语句assign实现,主要实现组合逻辑电路。 2) 结构描述形式 结构描述就是在设计中实例化已有的功能模块,这些模块包括Verilog语言自带的和用户自行开发的。 3) 行为描述形式 行为描述是对实体的数学模型的描述,只需要描述清楚输入和输出信号的行为,其抽象程度高于结构描述。可综合的行为描述大多采用always过程语句,适用于时序逻辑电路,也适用于组合逻辑电路。 5. Verilog仿真验证 仿真(Simulation)是对所设计逻辑电路的一种检测方法,Verilog HDL不仅提供了设计描述的能力,而且提供了对激励、响应和设计验证的建模能力。 要进行逻辑电路的仿真就需要用仿真器,ModelSim是常用的仿真器。在Verilog语言中,将测试程序称为testbench,意思是测试平台。测试程序与逻辑电路描述的Verilog程序类似,也是由模块组成,模块将描述测试激励、被测试模块和测试结果。测试激励用初始化语句产生,被测试模块在测试程序中作为一个实例嵌入,通过被测试模块的输出响应,判断模块功能是否正确。 3.2例题解析 例31画出如图321所示的Verilog语句描述的逻辑电路,其中A、B、C、D、E是输入,F是输出。 解: 根据Verilog语句描述,可以画出如图322所示的逻辑电路图。 例32图323是逻辑电路的Verilog源程序,图324是逻辑电路的Verilog仿真源程序,确定仿真结果F的值。 图321例31 Verilog源程序 图322例31逻辑电路 图323例32 Verilog源程序 图324例32 Verilog仿真源程序 解: 在如图323所示的Verilog源程序中,语句“assign F = {~B,4'b0111} & {A,1'b1}| {1'b1,A};”中的并置运算有{~B,4'b0111}、{A,1'b1}、{1'b1,A}。 在如图324所示的Verilog仿真源程序中,语 句“A = 8'b00101101,B = 5'b10010”中的 并置运算结果有{~B,4'b0111}为“011010111”、{A,1'b1}为“001011011”、{1'b1,A}为“100101101”。 F= “011010111” AND “001011011” OR “100101101” = 101111111 例33逻辑电路如图325所示,编写实现逻辑电路的Verilog源程序,通过ModelSim确定该逻辑电路的逻辑功能。 解: 由如图325所示的逻辑电路,编写实现逻辑电路的Verilog源程序,如图326所示。Verilog仿真源程序见图327,ModelSim仿真结果见图328。 由图328可知,当D=0,E=0时,输出F=A; 当D=1,E=0时,输出F=B; 当E=1时,输出F=C。该逻辑电路的功能是数据选择器,输入数据为A、B、C,输入控制端为D、E。 图325例33逻辑电路 图326例33 Verilog源程序 图327例33 Verilog仿真源程序 图328例33 ModelSim仿真结果 3.3习题解答 图331习题31逻辑电路 31用Verilog语言描述如图331所示的逻辑电路。 解: 由如图331所示的逻辑电路,可以写出Verilog语言的源程序,如图332所示。 32用Verilog实现二输入异或门F=AB的逻辑功能。 解: 由表达式F=AB,可以写出Verilog语言的源程序,如图333所示。 图332习题31 Verilog源程序 图333习题32 Verilog源程序 33用Verilog语言实现如图334所示的逻辑电路。编写如图335所示输入波形的ModelSim仿真Verilog程序,给出Q和Qn的仿真结果。 图334习题33逻辑电路 图335习题33输入波形 解: 由如图334所示的逻辑电路,可以写出Verilog语言的源程序如图336所示。由如图335所示的输入波形,可以写出Verilog语言的仿真源程序如图337所示。ModelSim仿真结果见图338,观察仿真结果,说明门控D锁存器的输出Q和Qn是正确的。 34在Verilog源程序文件中,怎样标明注释? 解: Verilog程序的注释有两种: 多行注释和单行注释。 (1) 多行注释: 以“/*”符号开始,到“*/”结束; 在两个符号之间的语句都是注释语句。 (2) 单行注释: 以“//”开始到本行结束都属于注释语句,不允许续行。 35用Verilog语言实现如图339所示的4选1数据选择器。 解: 由如图339所示的逻辑电路,可以写出Verilog语言的源程序如图3310所示。 图336习题33 Verilog源程序 图337习题33 Verilog仿真源程序 图338习题33 ModelSim仿真结果 图339 图3310习题35 Verilog源程序