Download presentation
Presentation is loading. Please wait.
1
4.1 Verilog HDL入门 4.1.1 Verilog HDL程序模块结构 模块端口定义 模块内容 设 计 模 块 I/O说明
功能描述 模块内容 变量类型说明 2017/3/13 1
2
4.1.1 模块端口定义 模块端口定义用来声明设计电路模块的输入输出端口,端口定义格式如下
模块端口定义 模块端口定义用来声明设计电路模块的输入输出端口,端口定义格式如下 module 模块名(端口1,端口2,端口3,…); 在端口定义的圆括弧中,是设计电路模块与外界联系的全部输入输出端口信号或引脚,它是设计实体对外的一个通信界面,是外界可以看到的部分(不包含电源和接地端),多个端口名之间用“,”分隔。例如, module adder(sum,cout,a,b,cin); 2017/3/13 2
3
4.1.2 模块内容 模块内容包括I/O说明、变量类型声明和功能描述。 1. 模块的I/O说明
模块内容 模块内容包括I/O说明、变量类型声明和功能描述。 1. 模块的I/O说明 模块的I/O说明用来声明模块端口定义中各端口数据流动方向包括输入(input)、输出(output)和双向(inout)。I/O说明格式如下 input 端口1,端口2,端口3,…; output 端口1,端口2,端口3,…; 例如 input ina, inb, cin; output sum, cout; 2017/3/13 3
4
2. 信号类型声明 变量类型声明用来说明设计电路的功能描述中,所用的信号的数据类型以及函数声明。
2. 信号类型声明 变量类型声明用来说明设计电路的功能描述中,所用的信号的数据类型以及函数声明。 变量的数据类型主要有连线(wire)、寄存器(reg)、整型(integer)、实型(real)和时间(time)等类型。 2017/3/13 4
5
功能描述是Verilog HDL程序设计中最主要的部分,用来描述设计模块的内部结构和模块端口间的逻辑关系,在电路上相当于器件的内部电路结构。
3. 功能描述 功能描述是Verilog HDL程序设计中最主要的部分,用来描述设计模块的内部结构和模块端口间的逻辑关系,在电路上相当于器件的内部电路结构。 功能描述可以用assign语句、元件例化(instantiate)、always块语句、initial块语句等方法来实现,通常把确定这些设计模块描述的方法称为建模。 (1)用assign语句建模 用assign语句建模的方法很简单,只需要在“assign”后面再加一个表达式即可。assign语句一般适合对组合逻辑进行赋值,称为连续赋值方式。 2017/3/13 5
6
module adder1(sum,cout,a,b,cin); input a, b, cin; output sum, cout;
【例4.1】1位全加器的设计。 a b cin adder1 sum cout Verilog HDL源程序如下 module adder1(sum,cout,a,b,cin); input a, b, cin; output sum, cout; assign {cout,sum} = a+b+cin; endmodule 2017/3/13 6
7
(2)用元件例化(instantiate)方式建模
元件例化方式建模是利用Verilog HDL提供的元件库实现的。 例如,用与门例化元件定义一个3输入端与门可以写为 and myand3(y,a,b,c); 注意:myand3是可选例化名,可省略。 2017/3/13 7
8
(3)用always块语句建模 always块语句可以产生各种逻辑,常用于时序逻辑的功能描述。一个程序设计模块中,可以包含一个或多个always语句。程序运行中,在某种条件满足时,就重复执行一遍always结构中的语句。 【例4.2】8位二进制加法计数器的设计。 D[7..0]是8位数据输入端,load是预置控制输入端,en是使能控制输入端,clk是时钟输入端,clr是清除输入端,q[7..0]是8位数据输出端,cout是进位输出端。 8位二进制加法计数器的元件符号 2017/3/13 8
9
8位二进制加法计数器的Verilog HDL源程序: module cnt8(q,cout,d,load,en,clk,clr);
input [7:0] d; input load,en,clk,clr; output reg[7:0] q; output reg cout; clk) begin if (clr) q= 0; else if (load) q =d; else if (en) begin q = q+1; if (q==255) cout = 1; else cout=0; end end endmodule 2017/3/13 9
10
(4)用initial块语句建模 initial块语句预always语句类似,不过在程序中它只执行1次就结束了。
Verilog HDL程序设计模块的基本结构小结: ① Verilog HDL程序是由模块构成的。每个模块的内容都是嵌在module和endmodule两语句之间,每个模块实现特定的功能,模块是可以进行层次嵌套的。 ② 每个模块首先要进行端口定义,并说明输入(input)、输出(output)或双向(inout),然后对模块的功能进行逻辑描述。 2017/3/13 10
11
③ Verilog HDL程序的书写格式自由,一行可以一条或多条语句,一条语句也可以分为多行写。
④ 除了end或含end(如endmodule)语句外,每条语句后必须要有分号“;”。 ⑤ 可以用/*……*/或//……对Verilog HDL程序的任何部分作注释。一个完整的源程序都应当加上需要的注释,以加强程序的可读性。 块注释:/*……*/ 行注释://…… 2017/3/13 11
12
4.2 Verilog HDL的词法 空白符和注释 Verilog HDL的空白符包括空格、tab符号、换行和换页。空白符如果不是出现在字符串中,编译源程序时将被忽略。 注释分为行注释和块注释两种方式。行注释用符号//(两个斜杠)开始,注释到本行结束。块注释用/*开始,用*/结束。块注释可以跨越多行,但它们不能嵌套。 2017/3/13 12
13
常数 Verilog HDL的常数包括数字、未知x和高阻z三种。数字可以用二进制、十进制、八进制和十六进制等4种不同数制来表示,完整的数字格式为 <位宽>’<进制符号><数字> 其中,位宽表示数字对应的二进制数的位数宽度;进制符号包括b或B(表示二进制数),d或D(表示十进制数),h或H(表示十六进制数),o或O(表示八进制数)。 2017/3/13 13
14
例如 8’b10110001 //表示位宽为8位的二进制数 8’hf5 //表示位宽为8位的十六进制数
十进制数的位宽和进制符号可以缺省,例如 //表示十进制数125 8’b1111xxxx //等价8’hfx 8’b1101zzzz //等价8’hdz 2017/3/13 14
15
4.2.3 字符串 字符串是用双引号括起来的可打印字符序列,它必须包含在同一行中。例如, ”ABC”,”A BOY.”,”A”,”1234”
字符串 字符串是用双引号括起来的可打印字符序列,它必须包含在同一行中。例如, ”ABC”,”A BOY.”,”A”,”1234” 都是字符串。 2017/3/13 15
16
关键字 关键字是Verilog HDL预先定义的单词,它们在程序中有不同的使用目的。例如,module和endmodule来指出源程序模块的开始和结束;用assign来描述一个逻辑表达式等。 Verilog HDL1995版本(Verilog-1995)的关键字有97个,Verilog-2001增加了5个,共102个(见如表4.1所示),每个关键词全部由小写字母组成,少数关键词中包含“0”或“1”数字。 2017/3/13 16
17
标识符 标识符是用户编程时为常量、变量、模块、寄存器、端口、连线、示例和begin-end块等元素定义的名称。标识符可以是字母、数字和下划线“_”等符号组成的任意序列。定义标识符时应遵循如下规则 ① 首字符不能是数字。 ② 字符数不能多于1024个。 ③ 大小写字母是不同的。 ④ 不要与关键字同名。 2017/3/13 17
18
操作符 操作符也称为运算符,是Verilog HDL预定义的函数名字,这些函数对被操作的对象(即操作数)进行规定的运算,得到一个结果。 操作符通常由1~3个字符组成,例如,“+”表示加操作,“==”(两个=字符)表示逻辑等操作,“===”(3个=字符)表示全等操作。有些操作符的操作数只有1个,称为单目操作;有些操作符的操作数有2个,称为双目操作;有些操作符的操作数有3个,称为三目操作。 2017/3/13 18
19
1. 算术操作符(Arithmetic operators)
常用的算术操作符: +(加)、-(减)、*(乘)、/(除)、 %(求余)、**(乘方) 其中%是求余操作符, 在两个整数相除的基础上,取出其余数。例如,5 % 6的值为5;13 % 5的值是3。 2017/3/13 19
20
2. 逻辑操作符(Logical operators )
逻辑操作符包括: &&(逻辑与)、||(逻辑或)、!(逻辑非) 3. 位运算(Bitwise operators) 位运算是将两个操作数按对应位进行逻辑操作。位运算操作符包括:~(按位取反)、&(按位与)、|(按位或)、^(按位异或)、^~或~^(按位同或)。 在进行位运算时,当两个操作数的位宽不同时,计算机会自动将两个操作数按右端对齐,位数少的操作数会在高位用0补齐。 2017/3/13 20
21
4. 关系操作符(Pelational operators)
关系操作符有: <(小于)、<=(小于等于)、>(大于)、>=(大于等于)。 其中,<=也是赋值运算的赋值符号。 关系运算的结果是1位逻辑值。在进行关系运算时,如果关系是真,则计算结果为1;如果关系是假,则计算结果为0;如果某个操作数的值不定,则计算结果不定(未知),表示结果是模糊的。 2017/3/13 21
22
5. 等式操作符(Equality operators)
等值操作符包括: ==(等于)、!=(不等于)、 ===(全等)、!==(不全等) 等值运算的结果也是1位逻辑值,当运算结果为真时,返回值1;为假则返回值0。相等操作符(==)与全等操作符(===)的区别是:当进行相等运算时,两个操作数必须逐位相等,其比较结果的值才为1(真),如果某些位是不定或高阻状态,其相等比较的结果就会是不定值;而进行全等运算时,对不定或高阻状态位也进行比较,当两个操作数完全一致时,其结果的值才为1(真),否则结果为0(假)。 2017/3/13 22
23
6. 缩减操作符(Reduction operators)
缩减操作符包括: &(与)、~&(与非)、|(或)、~|(或非)、 ^(异或)、^~或~^(同或)。 缩减操作运算法则与逻辑运算操作相同,但操作的运算对象只有一个。在进行缩减操作运算时,对操作数进行与、与非、或、或非、异或、同或等缩减操作运算,运算结果有1位1或0。例如,设A = 8’b ,则& A = 0(在与缩减运算中,只有A中的数字全为1时,结果才为1);|A = 1(在或缩减运算中,只有A中的数字全为0时,结果才为0)。 缩减操作符的功能相当相应的门电路,例如,对8位输入数据的缩减与非运算相当一个8输入端的与非门的功能。 & 2017/3/13 23
24
7. 转移操作符(Shift operators)
转移操作符包括: >>(右移)、<<(左移) 操作数 >> n ; //将操作数的内容右移n位,同时从左边开始用0来填补移出的位数。 操作数 << n; //将操作数的内容左移n位,同时从右边开始用0来填补移出的位数。 例如,设A = 8’b ,则A >> 4的结果是A = 8’b ;而A << 4的结果是A = 8’b 。 2017/3/13 24
25
8. 条件操作符(Conditional operators)
条件操作符为:?: 条件操作符的操作数有3个,其使用格式为 操作数 = 条件 ? 表达式1:表达式2; 即当条件为真(条件结果值为1)时,操作数 = 表达式1;为假(条件结果值为0)时,操作数 = 表达式2。 【例4.3】用条件操作符设计三态输出缓冲器的语句如下: assign f = en ? a:’bz; en a f 源程序如下 module tri_1(f,a,en); input a,en; output f; assign f = en? a:’bz; endmodule 2017/3/13 25
26
9. 位并接操作符(Concatenation operators)
并接操作符为:{} 并接操作符的使用格式为 {操作数1,操作数2,…,操作数n}; 即将操作数1的某些位与操作数2的某些位与…与操作数n的某些位并接在一起。例如,将1位全加器进位cont与和sum并接在一起使用,它们的结果由两个加数a、b及低位进位cin相加决定的表达式为 {cont,sum}= a+b+cin; 2017/3/13 26
27
4.2.7 Verilog HDL数据对象 1. 常量 Verilog HDL数据对象是指用来存放各种类型数据的容器,包括常量和变量。
1. 常量 常量是一个恒定不变的值数,一般在程序前部定义。常量定义格式为 parameter 常量名1 = 表达式,常量名2 = 表达式,…,常量名n = 表达式; parameter是常量定义关键字,常量名是用户定义的标识符,表达式是为常量赋的值。例如 parameter Vcc = 5,fbus = 8’b ; 2017/3/13 27
28
2. 变量 变量是在程序运行时其值可以改变的量。在Verilog HDL中,变量分为网络型(nets type)和寄存器型(register type)两种。 (1)网络型变量(nets type) nets型变量是输出值始终根据输入变化而更新的变量,它一般用来定义硬件电路中的各种物理连线。Verilog HDL提供的nets型变量如下。 2017/3/13 28
29
类 型 功能说明 wire、tri 连线类型(两者功能完全相同) wor、trior 具有线或特性的连线(两者功能一致)
类 型 功能说明 wire、tri 连线类型(两者功能完全相同) wor、trior 具有线或特性的连线(两者功能一致) wand、triand 具有线与特性的连线(两者功能一致) tri1、tri0 分别为上拉电阻和下拉电阻 supply1、supply0 分别为电源(逻辑1)和地(逻辑0) 2017/3/13 29
30
(2)寄存器型变量(register type)
register型变量也是一种连接线,可以作为设计模块中各器件间的信息传送通道。register型变量与wire型变量的根本区别在于register型变量需要被明确地赋值,并且在被重新赋值前一直保持原值。register型变量是在always、initial等过程语句中定义,并通过过程语句赋值。 2017/3/13 30
31
常用的register型变量及说明 类 型 功 能 说 明 reg 常用的寄存器型变量 integer 32位带符号整数型变量 real
类 型 功 能 说 明 reg 常用的寄存器型变量 integer 32位带符号整数型变量 real 64位带符号实数型变量 time 无符号时间型变量 2017/3/13 31
32
reg型变量是数字系统中存储设备的抽象,常用于的具体的硬件描述,因此是最常用的寄存器型变量。
integer、real和time等3种寄存器型变量都是纯数学的抽象描述,不对应任何具体的硬件电路,但它们可以描述与模拟有关的计算。例如,可以利用time型变量控制经过特定的时间后关闭显示等。 reg型变量是数字系统中存储设备的抽象,常用于的具体的硬件描述,因此是最常用的寄存器型变量。 reg型变量定义的关键字是reg,定义格式如下 reg [位宽] 变量1,变量2,…,变量n; 用reg定义的变量有一个范围选项(即位宽),默认的位宽是1。位宽为1位的变量称为标量,位宽超过1位的变量称为向量。标量的定义不需要加位宽选项,例如 reg a,b; //定义两个reg型变量a,b 2017/3/13 32
33
reg[7:0] data; //定义1个8位寄存器型变量,最高有效位是7,最低有效位是0
向量定义时需要位宽选项,例如 reg[7:0] data; //定义1个8位寄存器型变量,最高有效位是7,最低有效位是0 reg[0:7] data; //定义1个8位寄存器型变量,最高有效位是0,最低有效位是7 向量定义后可以采有多种使用形式(即赋值) data=8’b ; data[5:3]=3’B111; data[7]=1; 2017/3/13 33
34
若干个相同宽度的向量构成数组。在数字系统中,reg型数组变量即为memory(存储器)型变量。
(3)数组 若干个相同宽度的向量构成数组。在数字系统中,reg型数组变量即为memory(存储器)型变量。 存储器型可以用如下语句定义 reg[7:0] myram[1023:0]; 上述语句定义了一个1024个字存储器变量myram,每个字的字长为8位。在表达式中可以用下面的语句来使用存储器: myram[7]=75;//存储器myram的第7个字被赋值75(写入) A= myram[7] ;//将存储器的第7个字的值赋给A(读出) 2017/3/13 34
35
4.3 Verilog HDL的语句 语句是构成Verilog HDL程序不可缺少的部分。Verilog HDL的语句包括赋值语句、条件语句、循环语句、结构说明语句和编译预处理语句等类型,每一类语句又包括几种不同的语句。在这些语句中,有些语句属于顺序执行语句,有些语句属于并行执行语句。 2017/3/13 35
36
4.3.1 赋值语句 1. 门基元赋值语句 格式: 基本逻辑门关键字(门输出,门输入1,门输入2,…,门输入n);
赋值语句 1. 门基元赋值语句 格式: 基本逻辑门关键字(门输出,门输入1,门输入2,…,门输入n); 基本逻辑门关键字是Verilog HDL预定义的逻辑门,包括and、or、not、xor、nand、nor等;圆括弧中内容是被描述门的输出和输入信号。 例如,具有a、b、c、d四个输入和y为输出与非门的门基元赋值语句为: nand(y,a,b,c,d); 该语句与assign y = ~(a & b & c & d)等效 2017/3/13 36
37
2. 连续赋值语句 格式 assign 赋值变量 = 表达式; 例如 assign y = ~(a & b & c & d);
2. 连续赋值语句 格式 assign 赋值变量 = 表达式; 例如 assign y = ~(a & b & c & d); 连续赋值语句的“=”号两边的变量都应该是wire型变量。在执行中,输出y的变化跟随输入a、b、c、d的变化而变化,反映了信息传送的连续性。 2017/3/13 37
38
【例4.4】4输入端与非门的Verilog HDL源程序。 module example_4_4(y,a,b,c,d); output y;
input a,b,c,d; assign #1 y = ~(a&b&c&d); endmodule #1——表示该门的输出与输入信号之间具有1个单位的 时间延迟。 2017/3/13 38
39
3. 过程赋值语句 过程赋值语句出现在initial和always块语句中,赋值符号是“=”,格式为 赋值变量 = 表达式;
3. 过程赋值语句 过程赋值语句出现在initial和always块语句中,赋值符号是“=”,格式为 赋值变量 = 表达式; 在过程赋值语句中,赋值号“=”左边的赋值变量必须是reg(寄存器)型变量,其值在该语句结束即可得到。如果一个块语句中包含若干条过程赋值语句,那么这些过程赋值语句是按照语句编写的顺序由上至下一条一条地执行,前面的语句没有完成,后面的语句就不能执行,就象被阻塞了一样。因此,过程赋值语句也称为阻塞赋值语句。 2017/3/13 39
40
4. 非阻塞赋值语句 非阻塞赋值语句也是出现在initial和always块语句中,赋值符号是“<=”,格式为
4. 非阻塞赋值语句 非阻塞赋值语句也是出现在initial和always块语句中,赋值符号是“<=”,格式为 赋值变量 <= 表达式; 在非阻塞赋值语句中,赋值号“<=”左边的赋值变量也必须是reg型变量,其值在该块语句结束才可得到。而不象在过程赋值语句那样,语句结束时即刻得到。 2017/3/13 40
41
always @(posedge clock) m = 3; n = 75; n <= m; r = n;
例如,在下面的块语句中包含4条赋值语句 clock) m = 3; n = 75; n <= m; r = n; 语句执行结束后,r的值是75,而不是3,因为第3行是非阻塞赋值语句“n <= clock)”是定时控制敏感函数,表示时钟信号clock的上升沿到来的敏感时刻。 2017/3/13 41
42
module D_FF(q,d,clock); input d,clock; output q; reg q;
clock) q <= d; endmodule q是触发器的输出,属于reg型变量;d和clock是输入,属于wire型变量(由隐含规则定义)。 2017/3/13 42
43
条件语句包含if语句和case语句,它们都是顺序语句,应放在always块中。
条件语句 条件语句包含if语句和case语句,它们都是顺序语句,应放在always块中。 1. if语句 完整的Verilog HDL的if语句结构如下: if (表达式) begin 语句; end else if (表达式) begin 语句; end else begin 语句; end 2017/3/13 43
44
【例4.6】8线-3线优先编码器的设计 输入 输出 a0 a1 a2 a3 a4 a5 a6 a7 y2 y1 y0
x x x x x x x 0 x x x x x x x x x x x x x x x x x x x x x 2017/3/13 44
45
output reg[2:0] y; Verilog HDL源代码如下 module example_4_6(y,a);
input[7:0] a; output[2:0] y; reg[2:0] y; begin if(~a[7]) y='b111; else if(~a[6]) y='b110; output reg[2:0] y; 2017/3/13 45
46
else if(~a[5]) y='b101; else if(~a[4]) y='b100;
else y='b000; end endmodule 2017/3/13 46
47
case语句是一种多分支的条件语句,完整的case语句的格式为 case (表达式) 选择值1 : 语句1; 选择值2 : 语句2; …
选择值1 : 语句1; 选择值2 : 语句2; … 选择值n : 语句n; default : 语句n+1; endcase 2017/3/13 47
48
【例4.7】用case语句描述4选1数据选择器。 module example_4_7(z,a,b,c,d,s1,s2);
module example_4_7(z,a,b,c,d,s1,s2); input s1,s2; input a,b,c,d; output z; reg z; or s2) begin case ({s1,s2}) 'b00: z=a; 'b01: z=b; 'b10: z=c; 'b11: z=d; endcase end endmodule a b c d s1 s2 数据 选择 器 z 2017/3/13 48
49
在casex语句中,把不予以考虑的位扩展到未知x,即不考虑值为高阻z和未知x的那些位,只关注其他位的比较结果。
case语句还有两种变体语句形式,即casez和casex语句。casez和casex语句与case语句的格式完全相同,它们的区别是:在casez语句中,如果分支表达式某些位的值为高阻z,那么对这些位的比较就不予以考虑,只关注其他位的比较结果。 在casex语句中,把不予以考虑的位扩展到未知x,即不考虑值为高阻z和未知x的那些位,只关注其他位的比较结果。 2017/3/13 49
50
4.3.3 循环语句 循环语句包含for语句、repeat语句、while语句和forever语句4种。 1. for语句
循环语句 循环语句包含for语句、repeat语句、while语句和forever语句4种。 1. for语句 for语句的语法格式为 for (循环指针 = 初值; 循环指针 < 终值; 循环指针 = 循环指针 + 步长值) begin 语句; end 2017/3/13 50
51
【例4.8】8位奇偶校验器的描述。 module example_4_8(a,out); input[7:0] a; output out;
reg out; integer n; begin out = 0; for (n = 0; n < 8; n = n + 1) out =out ^ a[n]; end endmodule 2017/3/13 51
52
语法格式 :repeat(循环次数表达式) 语句; 用repeat语句实现8位奇偶校验器
module example_4_8_1(a,out); parameter size = 7; input[7:0] a; output out; reg out; integer n; begin out = 0; n = 0; repeat(size) begin out =out ^ a[n]; n = n+1;end end endmodule 注意:MAX+plusII软件不支持repeat语句,但Quartus II软件支持。 2017/3/13 52
53
结构声明语句 Verilog HDL的任何过程模块都是放在结构声明语句中,结构声明语句包括always、initial、task和function等4种结构。 1. always块语句 在一个Verilog HDL模块(module)中,always块语句的使用次数是不受限制的,块内的语句也是不断重复执行的。always块语句的语法结构为 2017/3/13 53
54
// for语句,while语句,repeat语句; // tast语句、function语句; end
begin // 过程赋值语句; // if语句,case语句; // for语句,while语句,repeat语句; // tast语句、function语句; end 2017/3/13 54
55
敏感信号表达式中用“posedge”和“negedge”这两个关键字来声明事件是由时钟的上升沿或下降沿触发。
在always块语句中,敏感信号表达式(event-expression)应该列出影响块内取值的所有信号(一般指设计电路的输入信号),多个信号之间用“or”连接。当表达式中任何信号发生变化时,就会执行一遍块内的语句。块内语句可以包括:过程赋值、if、case、 for、while、repeat、tast和function等语句。 敏感信号表达式中用“posedge”和“negedge”这两个关键字来声明事件是由时钟的上升沿或下降沿触发。 posedge negedge clk)表示事件由clk的下降沿触发。 2017/3/13 55
56
initial语句的使用次数也是不受限制的,但块内的语句仅执行一次,因此initial语句常用于仿真中的初始化。
begin 语句1; 语句2; … end initial语句的使用次数也是不受限制的,但块内的语句仅执行一次,因此initial语句常用于仿真中的初始化。 2017/3/13 56
57
可以被调用的任务必须事先用task语句定义,定义格式如下
2017/3/13 57
58
task 任务名; 端口声明语句; 类型声明语句; begin 语句; …… end endtask 例如,8位加法器任务的定义如下
task adder8; output[7:0] sum; output cout; input[7:0] a,b; input cin; assign {cout,sum}=a+b+cin; endtask 2017/3/13 58
59
adder8(tsum,tcout,ta,tb, cin );
任务调用的格式如下 任务名 (端口名列表); 例如,8位加法器任务调用 adder8(tsum,tcout,ta,tb, cin ); 2017/3/13 59
60
function语句用来定义函数,函数定义格式如下 function [最高有效位:最低有效位] 函数名; 端口声明语句; 类型声明语句;
begin 语句; end endfunction 2017/3/13 60
61
【例4.9】求最大值的函数。 function [7:0] max; input[7:0] a,b; begin
if (a>=b) max=a; else max=b; end endfunction 2017/3/13 61
62
函数调用一般是出现在模块、任务或函数语句中。通过函数的调用来完成某些数据的运算或转换。例如,调用例4.9编制的求最大值的函数
函数调用的格式如下 函数名(关联参数表); 函数调用一般是出现在模块、任务或函数语句中。通过函数的调用来完成某些数据的运算或转换。例如,调用例4.9编制的求最大值的函数 peak=max(data,peak); 其中,data和peak是与函数定义的两个参数a、b关联的关联参数。通过函数的调用,求出data和peak中的最大值,并用函数名max返回。 2017/3/13 62
63
4.4 不同抽象级别的Verilog HDL模型 Verilog HDL是一种用于逻辑电路设计的硬件描述语言。用Verilog HDL描述的电路称为该设计电路的Verilog HDL模型。 Verilog HDL具有行为描述和结构描述功能。行为描述是对设计电路的逻辑功能的描述,并不用关心设计电路使用那些元件以及这些元件之间的连接关系。行为描述属于高层次的描述方法,在Verilog HDL中,行为描述包括系统级(System Level)、算法级(Algorithm Level)和寄存器传输级(RTL:Register Transfer Level)等3种抽象级别。 2017/3/13 63
64
在Verilog HDL的学习中,应重点掌握高层次描述方法,但门级描述在一些电路设计中也有一定的实际意义。
结构描述是对设计电路的结构进行描述,即描述设计电路使用的元件及这些元件之间的连接关系。结构描述属于低层次的描述方法,在Verilog HDL,结构描述包括门级(Gate Level)和开关级(Switch Level)2种抽象级别。 在Verilog HDL的学习中,应重点掌握高层次描述方法,但门级描述在一些电路设计中也有一定的实际意义。 2017/3/13 64
65
Verilog HDL门级描述 用于门级描述关键字包括:not(非门)、and(与门)、nand(与非门)、or(或门)、nor(或非门)、xor(异或门)、xnor(异或非门)、buf(缓冲器)以及bufif1、bufif0、notif1、notif0等各种三态门。 门级描述语句格式为 门类型关键字 <例化门的名称>(端口列表); 其中,“例化门的名称”是用户定义的标识符,属于可选项;端口列表按:(输出,输入,使能控制端)的顺序列出。 例如 nand nand2(y,a,b); //2输入端与非门 xor myxor(y,a,b); //异或门 bufif0 mybuf(y,a,en); //低电平使能的三态缓冲器 2017/3/13 65
66
【例4.11】采用结构描述方式描述下图所示的硬件电路 。
S2 S3 S1 module example_4_11(y,a,b,c); input a,b,c; output y; wire s1,s2,s3; not (s1,a); nand (s2,c,s1); nand (s3,a,b); nand (y,s2,s3); endmodule 2017/3/13 66
67
Verilog HDL的行为级描述 Verilog HDL的行为级描述是最能体现EDA风格的硬件描述方式,它既可以描述简单的逻辑门,也可以描述复杂的数字系统乃至微处理器;既可以描述组合逻辑电路,也可以描述时序逻辑电路。 【例4.12】3线-8线译码器的设计。 2017/3/13 67
68
module example_4_12(a,b,c,y,en); input a,b,c,en; output[7:0] y;
reg[7:0] y; or a or b or c) begin if (en) y = 'b ; else case({c,b,a}) 'b000: y='b ; 'b001:y='b ; 'b010: y='b ;'b011: y='b ; 'b100: y='b ;'b101: y='b ; 'b110: y='b ;'b111: y='b ; endcase end endmodule 2017/3/13 68
69
module example_4_13(d,q,en); input en; input[7:0] d; output[7:0] q;
reg[7:0] q; always @(en or d) begin if (en) q = 8'bzzzzzzzz; else q=d; end endmodule 2017/3/13 69
70
module cnt10(clr,clk,q,cout); input clr,clk; output reg [3:0] q;
【例4.14】异步清除十进制加法计数器的设计。 module cnt10(clr,clk,q,cout); input clr,clk; output reg [3:0] q; output reg cout; clk or negedge clr) begin if (~clr) q=0; else begin if (q<9) q=q+1; else q=0; if (q==9) cout=1; else cout=0;end end endmodule 2017/3/13 70
71
用结构描述实现电路系统设计 任何用Verilog HDL描述的电路设计模块(module),均可用模块例化语句,例化一个元件,来实现电路系统的设计。 模块例化语句格式与逻辑门例化语句格式相同,具体为 设计模块名 <例化电路名>(端口列表); 其中,“例化电路名”是用户为系统设计定义的标识符,相当系统电路板上为插入设计模块元件的插座,而端口列表相当插座上引脚名表,应与设计模块的输入/输出端口一一对应。 【例4.15】用模块例化方式设计8位计数译码器电路系统。 第一步:设计一个4位二进制加法计数器cnt4e模块和一个7段数码显示器的译码器dec7s模块 2017/3/13 71
72
Cnt4e的Verilog HDL源程序如下: module cnt4e(clk,clr,ena,cout,q);
input clk,clr,ena; output [3:0] q; output cout; reg [3:0] q; clr or posedge clk) begin if (clr) q = 'b0000; else if (ena) q = q+1; end assign cout = &q; endmodule 2017/3/13 72
73
Dec7s的Verilog HDL源程序如下: module Dec7s(a,q); input [3:0] a;
output [7:0] q; reg [7:0] q; begin case(a) 0:q=8'b ; 1:q=8'b ; 2:q=8'b ; 3:q=8'b ; 2017/3/13 73
74
4:q=8'b01100110; 5:q=8'b01101101; 6:q=8'b01111101; 7:q=8'b00000111;
endcase end endmodule 2017/3/13 74
75
第二步:设计计数译码系统电路。计数译码系统电路的结构图如图4
第二步:设计计数译码系统电路。计数译码系统电路的结构图如图4.13所示,其中u1和u2是两个cnt4e元件的例化模块名,相当cnt4e系统电路板上的插座;u3和u4是dec7s元件的例化模块名,相当dec7s在系统电路板上的插座。x、q1、q2是电路中的连线。 计数译码系统电路的结构图 u1 u2 u3 u4 x q1 q2 2017/3/13 75
76
module cnt_Dec_v(clk,clr,ena,cout,q); input clk,clr,ena;
cnt_dec7s的源程序如下: module cnt_Dec_v(clk,clr,ena,cout,q); input clk,clr,ena; output[15:0] q; output cout; reg [15:0] q; wire [3:0] q1,q2; wire x; cnt4e u1(clk,clr,ena,x,q1); //模块例化 cnt4e u2(clk,clr,x,cout,q2); dec7s u3(q1,q[7:0]); dec7s u4(q2,q[15:8]); endmodule 2017/3/13 76
77
4.5 Verilog HDL设计流程 Verilog HDL设计流程与第3章叙述的VHDL设计流程基本相同,这里不再重复。
2017/3/13 77
Similar presentations