1、10.1 引言,第10章 Verilog 硬件描述语言实例,Verilog HDL描述逻辑电路时常用3种描述方式,分别为:行为型描述、数据流型描述和结构型描述。,行为型描述只描述行为特征,不涉及逻辑电路的实现,是一种高级语言描述方式,具有很强的通用性和有效性;数据流型描述指通过assign连续赋值实现组合逻辑功能的描述方式;结构型描述指描述实体连接的结构方式,所谓实体一般指Verilog语言已定义的基元,也就是说结构型描述指利用Verilog语言已定义的基元描述逻辑电路的描述方式。,行为型描述语句更简练,不能被综合;结构型描述语句通常容易被综合,但语句显得复杂。在实际开发中往往结合使用多种描述
2、方法。,10.2 2选1数据选择器,2选1数据选择器可以有多种描述方式,通过4个实例和3种描述方式对例子中出现的语法现象进行解释。,10.2.1 2选1数据选择器的行为型描述方式;10.2.2 2选1数据选择器的数据流型描述方式;10.2.3 2选1数据选择器的数据流型描述方式;10.2.4 2选1数据选择器的结构型描述方式;,10.2.1 2选1数据选择器实例1,/例10.2.1 module Mux21 (a,b,s,y); /-1input a,b;input s;output y; assign y = (s=0)? a : b; /-2 endmodule /-3,10.2.1 2选
3、1数据选择器实例 1,/例10.2.1 module Mux21 (a,b,s,y); /-1input a,b;input s;output y; assign y = (s=0)? a : b; /-2 endmodule /-3,1. Verilog语言描述,2. 程序说明,(1) 注释行 (2) 模块定义语句module和endmodule所有的程序都置于模块(module)框架结构内。模块是Verilog最基本的构成单元。一个模块可以是一个元件或者一个设计单元。,module (端口列表)endmodule,模块名是该模块的唯一标识符。端口列表列举了该模块与外部电路连接的所有端口,包
4、括输入、输出及双向端口。该模块共包括四个端口:输入端口a,b,s和输出端口y。图10.2.1为定义的二选一数据选择器。,(3) 连续赋值语句assign“assign y = (s= =0)? a : b;”为一条连续赋值语句。连续赋值语句assign能够给网表变量赋值。只要等号右边的表达式值发生变化,这种赋值行为就会立刻发生。连续赋值语句能模拟组合逻辑电路。 (4) 条件操作符“?”s=0?a:b为一条件表达式。式中条件操作符“?”为三目操作符,由两个操作符隔离三个操作数构成,语法格式如下:表达式1? 表达式2: 表达式3执行操作时,首先会计算表达式1的值,如果表达式1的值为1,那么将计算表
5、达式2的值,做为条件表达式的最后结果;如果表达式1的值为0,则计算表达式3的值,并做为条件表达式最后的结果。,(5) 连续赋值语句assign等式运算符程序行2中表达式s=0为等式运算符 ,当“=”两边相等时,结果为1,否则为0。“!=”为不等于运算符。因此例10.2.1中程序行2的功能为使用assign给wire型变量y赋值,当s为0时y状态和a相同,否则和b相同,实现了2选1数据选择器功能。,仿真结果,10.2.2 2选1数据选择器实例 2,/例10.2.2 module Mux21 (a,b,s,y); input a,b;input s;output y; /-1wire d,e; /
6、-2assign d = a endmodule,(1)连线类型wire程序中出现的中间变量d和e定义为wire类型,表示内部结点或连线。程序行1输出端口y的数据类型默认为wire类型。网表类型可通过连续赋值语句(assign语句)或逻辑门驱动,并需要驱动源持续驱动。如果一个网表没有和任何驱动源连接,其值为高阻状态。,1. Verilog语言描述,2. 程序说明,(2)位运算符按位取反()、按位与(&)和按位或(|),按位异或()、按位同或(,异或非)。参与运算两个数位数不同时,采用右对齐。,10.2.3 2选1数据选择器实例 3,/例10.2.3 module mux21 (a,b,s,y)
7、; input a,b,s; output y; reg y;always ( a or b or s) /-1if (!s) y = a; /-2else y = b; /-3 endmodule,(1)寄存器类型reg输出端口y的数据类型申明为reg即寄存器型,在always 块中被赋值的信号必须定义为reg型。寄存器 ( reg )类型不一定是触发器。只能在always语句中通过过程赋值语句进行赋值。,1. Verilog语言描述,2. 程序说明,(2)重复执行语句always程序行1“always ( a or b or s)”为重复执行语句。always后面跟了一个时间控制语句,时间
8、控制通过事件表达式(关键词“”)实现,时间控制部分为完整敏感信号列表,只要任意敏感信号发生变化,过程块将重复连续执行,持续整个模拟过程。 (3) 条件语句(if-else)条件语句if-else语句可用来选择是否执行某条语句。 (4)逻辑运算符三种逻辑运算符:逻辑与“&”、逻辑或“|”和逻辑非“!”,逻辑运算 的真值表,10.2.3 2选1数据选择器实例 4,/例10.2.4 module mux21(y, a, b, s);input a, b, s;output y;not u1 (ns, s); and u2 (sela, a, ns);and u3 (selb, b, s);or u4
9、 (y, sela, selb); endmodule,例10.2.4调用了多个底层模块的实例。调用模块的过程,称为实例化。实例的使用格式为:,1. Verilog语言描述,2. 程序说明, ;,非模块,与模块,或模块,例10.2.4为门级结构描述,它提供了模型和实际电路之间直接的一一对应的关系。Verilog HDL中一些基元与关键字对应关系如下:,not非门; buf缓冲器; and与门; or非门; nand与非门; nor或非门; xor异或门; xnor同或门。,这些模块称为Verilog语言的基元(Primitive),图10.2.5 例10.2.4仿真电路图,10.3 4选1数据
10、选择器,10.3.1 4选1数据选择器实例1,4选1数据选择器功能表如表10.3.1所示。4个数据输入端口in0、in1、in2、in3,也称为输入变量,两位选择变量sel(1)和sel(0),数据输出端为out。,四选一数据选择器功能表,/例10.3.1 module mux4_1(out,in0,in1,in2,in3,sel); output out; input in0,in1,in2,in3; input1:0 sel; /-1 reg out; always (in0 or in1 or in2 or in3 or sel) /- -2 case(sel) 2b00: out=in
11、0; 2b01: out=in1; 2b10: out=in2; 2b11: out=in3; default: out=1bx; endcase endmodule,1.Verilog 语言描述,2. 程序说明,Verilog中如果一个网表型变量和寄存器型变量定义时没有指定位长度,则它被认为是1位标量,如果设定了位长度,则被认为是一个矢量。,(1)矢量类型,wire 7:0 bus; /8位矢量网表 bus reg 0:40 addr; /41位矢量寄存器addr,reg -1:4 b; /6位矢量寄存器b,位长度定义时高位和低位甚至可以是负数。,矢量的引用方式比较灵活,比如对前面定义过的矢
12、量:,bus0 /bus的第0位 bus2:0 /bus的三位最低有效位。注意不能用bus0:2,应和定义中保持一致。 addr0:1 /addr的两位最高有效位,(2) 数的表示方法,按进制划分,整数可以表示成十进制数,十六进制数,八进制和二进制数。Verilog中整数通常有两种表述方式,分别为十进制数和指定位数表述方式。,十进制数表述方式:,指定位数表述方式:,用0到9的数字序列表示。, 。,在硬件描述语言中,x表示不定值,z表示高阻态。可以在十六进制,八进制和二进制中使用x和z,十六进制中一个x表示4位都是x,八进制中一个x表示3位都是x,二进制中则表示一位是x。z用法同理。,整数的表示
13、示例:, h 123F /无位长度的十六进制数 o 123 /无位长度的八进制数 3 b101 /3位二进制数 5 D 3 /5位十进制数 12 h x /12位不确定数 16 o z /16位高阻态 16 b 1001_0110_1111_zzzz /16位二进制数,以下表示是不正确的:,123af /十六进制数,缺少进制符号 h,在表示长数据时还可以用下划线“_”进行分割以增加程序的可读性,,(3) case 语句的语法结构,case (表达式)选项值1: 语句1;选项值2: 语句2;选项值3: 语句3;default: 缺省语句; endcase,语句1,语句2,缺省语句可以是一条语句或
14、者语句块。,case表达式结果的位长度应和选项值的位长度一致,如果不一致,会按照位长度最长的项进行扩充对齐。,4选1数据选择器的仿真电路图:,4选1数据选择器的仿真波形图:,3. 仿真结果,10.3.2 4选1数据选择器实例2,1.if-else 语句实现的4选1数据选择器,/例10.3.2module mux4_1(out,in0,in1,in2,in3,sel);output out;input in0,in1,in2,in3;input1:0 sel;reg out;always (in0 or in1 or in2 or in3 or sel) beginif(sel=2b00) ou
15、t=in0;else if(sel=2b01) out=in1;else if(sel=2b10) out=in2;else if(sel=2b11) out=in3;,else out=1bx; endendmodule,2. 程序说明,(1)if条件语句除了if-else结构外,还有if-else-if结构,if (表达式1)语句1;else if (表达式2)语句2;else if else语句n;,(2) 顺序块语句 begin-end,顺序块语句通常用来将两条或多条语句组合在一起,使其在格式上更象一条语句。,begin 语句1; 语句2; 语句n; end,顺序块有以下特点: 1)
16、块内的语句是按顺序执行的,即只有上面一条语句执行完后下面的语句才能执行。2) 直到最后一条语句执行完,程序才跳出该语句块。,(3) 缺省项问题,条件语句和分支条件语句都存在着缺省项的问题。 对于条件语句,else语句称为缺省项,对于case语句,default语句称为缺省项。缺省项是可以省略的,但省略缺省项会引入锁存器,在组合逻辑电路设计中可能会带来一些问题。,/例10.3.3module ex3reg(y, a, b, c);input a, b, c; output y;reg y, rega;always (a or b or c)begin,if(aendendmodule,rega被
17、综合为一个数据选择器:,省略了缺省项的Verilog语言程序,/例10.3.4module ex4reg(y, a, b, c);input a, b, c; output y;reg y, rega;always (a or b or c)beginif(aend endmodule,if-else结构的缺省项省略了,当a&b为1时,rega被赋予c的值,但当a&b为0时,rega将保持原值,这时需要一个锁存器把rega的值保持下来,因此综合时rega被综合为一个锁存器,锁存器是多余的部分。,综合后的电路:,对于case语句存在同样的问题,也会由于缺少缺省项,产生了不必要的锁存器。,/例10
18、.3.5module inccase(a, b, c, d, e);input a, b, c, d;output e; reg e;always (a or b or c or d)case (a,b) /-12b11: e=d ;2b10: e=c ;endcaseendmodule,程序行1的“ ”为拼接操作符,将a和b组成一个二进制数。,仿真电路:,由此可见,If条件语句和case条件语句在省略缺省项时,会产生锁存器。因此,在设计组合逻辑电路时缺省项不能省略。,10.4 四位加法器,1. Verilog 语言描述,4位加法器的功能是实现2个4位二进制数的加法运算。由两个模块组成,分别为
19、底层全加器模块和顶层模块。,/例10.4.1 /全加器module add_full(A,B,C,Carry,S); input A,B,C;output Carry,S; /全加器进位和assign S = ABC;assign Carry = (Aendmodule,/四位加法器module add_full4(A,B,C,S); input3:0 A,B;output3:0 S; /加法器和output4:0 C; /加法器进位 assign C0=0;add_full u1(A0,B0,C0,C1,S0), /-1 u2(A1,B1,C1,C2,S1),u3(A2,B2,C2,C3,S
20、2),u4(A3,B3,C3,C4,S3); endmodule,2. 程序说明,实例(Instances),实例化(instantiation),设计中我们可能需要调用一些已经定义好的模块,作为我们电路中的单元。调用这些模块的过程,称为实例化(instantiation),调用完之后,这些电路中的模块单元称为实例(Instance)。实例的使用格式为:;模块的定义只是说明该模块的功能与接口,它只提供了一个模板,它要在电路中获得实际应用与实现需要被调用(实例化)。,Verilog中不允许嵌套定义模块,即一对module和endmodule之间只能定义一个模块。但一个模块内可以通过实例的方式多次
21、调用其他模块。,实例的调用格式2:,add_full u1(.A(A0),.B(B0),.C(C0),.Carry(C1),.S(S0), u2(.A(A1),.B(B1),.C(C1),.Carry(C2),.S(S1), u3(.A(A2),.B(B2),.C(C2),.Carry(C3),.S(S2), u4(.A(A3),.B(B3),.C(C3),.Carry(C4),.S(S3);, ;,3. 仿真结果,仿真电路图,仿真波形图,10.5 七段数码管显示译码器,例10.5.1实现的是将BCD码转换成七段数码管的显示码,并假设LED数码管是共阴极。电路有4个输入端,7个输出端。,/例1
22、0.5.1module decode48(a,b,c,d,e,f,g,D3,D2,D1,D0);output a,b,c,d,e,f,g;input D3,D2,D1,D0; /输入4 位BCD 码reg a,b,c,d,e,f,g; /输出驱动7个笔划段always (D3 or D2 or D1 or D0) begincase(D3,D2,D1,D0) /用case 语句进行译码,1. Verilog 语言描述,4d0: a,b,c,d,e,f,g=7b1111110;4d1: a,b,c,d,e,f,g=7b0110000;4d2: a,b,c,d,e,f,g=7b1101101;4d
23、3: a,b,c,d,e,f,g=7b1111001;4d4: a,b,c,d,e,f,g=7b0110011;4d5: a,b,c,d,e,f,g=7b1011011;4d6: a,b,c,d,e,f,g=7b1011111;4d7: a,b,c,d,e,f,g=7b1110000;4d8: a,b,c,d,e,f,g=7b1111111;4d9: a,b,c,d,e,f,g=7b1111011;default: a,b,c,d,e,f,g=7bx;endcase endendmodule,2. 程序说明,拼接操作符( ):拼接操作符将两个或者更多的表达式结果的各个位进行连接。其表达式由大括
24、弧中的用逗号分割的表达式构成:,表达式1, 表达式2 , ,a, b1:2, c , 4b0010 4y,第一行等同于a, b1, b2, c, 1b0, 1b0, 1b1, 1b0,第二行是嵌套反复多次调用,它等同于y, y, y, y,例如:,3. 仿真结果,仿真波形图:,由图可知,输入D3、D2、D1、D0为0001时,输出a、b、c、d、e、f为011000,数码管显示1,例10.5.1可以实现显示译码器的功能。,10.6 D触发器,/例10.6.1module d_ff (q, d, clk); output q;input d, clk;reg q; always (posedge
25、 clk) q=d; endmodule,1. Verilog 语言描述,2. 程序说明,上升沿和下降沿检测语句功能表,上升沿触发指变量值从0变为1、0变为x和z、或者从x,z变为1,用posedge表示。下降沿触发指变量值从1变为0、1变为x和z或者从x,z变为0,用negedge表示。,Verilog语言有两种赋值方式:连续赋值和过程赋值。过程赋值包括阻塞赋值和非阻塞赋值两种。,/例10.6.2module d_ff (q1,q2, d, clk); output q1,q2;input d, clk;reg q1,q2; always (posedge clk) begin q1=d;
26、/-1q2= q1; /-2end endmodule,阻塞赋值:,例10.6.2的仿真电路图:,例10.6.2仿真波形图 :,非阻塞赋值:,/例10.6.3module d_ff (q1,q2, d, clk); output q1,q2;input d, clk;reg q1,q2; always (posedge clk) beginq1=d; /-1q2= q1; /-2endendmodule,例10.6.3的仿真电路图:,例10.6.3的仿真波形图:,3仿真结果,例10.6.1的仿真电路图:,例10.6.1的仿真波形图:,10.7 计数器,10.7.1 4位二进制加法计数器,1.
27、Verilog语言描述,/例10.7.1module count4(out,reset,clk);output3:0 out;input reset,clk;reg3:0 out;always (posedge clk) beginif (reset) out=0; /同步清零else out=out+1; /计数 endendmodule,2. 程序说明,这个计数器只有同步复位和计数功能。时钟的上升沿有效,当clk信号的上升沿到来时,如果清零信号为1,则计数器清零,否则计数器进行计数。,3仿真结果,例10.7.1的仿真电路图,例10.7.1的仿真波形图:,由仿真电路图可知例10.7.1实现了
28、4位二进制加法计数器的逻辑功能。reset为高电平时,计数器清零。,10.7.2 同步置数同步清零加法计数器,/例10.7.2module count(out,data,load,reset,clk);output7:0 out;input7:0 data;input load,clk,reset;reg7:0 out;always (posedge clk) /clk上升沿触发 beginif (!reset) out = 8h00; /同步清零,低电平有效else if (!load) out = data; /同步预置else out = out + 1; /计数 endendmodul
29、e,1. Verilog 语言描述,2. 程序说明,计数器功能表,这是一个8位计数器,计数范围为0到255,上升沿到来时计数,具有同步置数和同步清零功能,在时钟的上升沿进行判断。,3仿真结果,例10.7.2的仿真波形图:,由图可知,当reset=0时,计数器清零;reset=1、load=0时计数器置数;当reset=1、load=1时,计数器计数。,10.7.3 异步清零计数器,1. Verilog语言描述,/例10.7.3module count2(out,reset,clk);output7:0 out;input clk, reset;reg7:0 out;always (posedg
30、e clk or negedge reset) beginif(!reset)out= 0; elseout= out + 1; /计数 endendmodule,2. 仿真结果,例10.7.3的仿真电路图:,例10.7.3的仿真波形图:,10.7.4 扭环型计数器,扭环型计数器状态转换表,1.Verilog 语言描述,/例10.7.4module johnson(clk,clr,out); input clk,clr;output3:0 out; reg3:0 out;always (posedge clk or negedge clr)beginif (!clr) out 1); /-1o
31、ut3= out0; end endendmodule,2程序说明,程序行1的out 1)语句使用了右移运算符来实现右移运算功能,移位运算符包括右移位运算符“”和左移位运算符“”。,其使用方法如下: a n 或 a n a代表要进行移位的操作数,n代表要移几位。这种移位运算都用0来填补移出的空位。,3. 仿真结果,例10.7.4的仿真电路图:,例10.7.4的仿真波形图:,Moore型:输出是当前状态的函数;Mealy型:输出是当前状态和输入的函数。,在有限的状态内,在时钟的驱动下,通过给定初始状态,能够自动完成状态间的循环和相应状态输出的时序逻辑电路。,(1)状态机的概念,(2)状态机的分类
32、,在verilog设计的实用时序逻辑系统中,有很多都是用状态机来描述的。,10.8 状态机,(3)Moore型状态机的Verilog语言描述,Moore型状态机的结构图,Moore型状态机的状态图,module moore (clk,din,op); input clk,din; output op; reg1:0 current_state,next_state; reg op; parameter S0=2b00,S1=2b01,S2=2b10,S3=2b11; /第一个always进程时序逻辑电路 always( posedge clk) begin current_state = ne
33、xt_state; end,S0: beginop =0;if (din=0)next_state = S0;elsenext_state = S1; end,/第二个always进程组合逻辑电路 always(current_state or din) begin case( current_state ),S1: beginop =1;if (din=1)next_state = S1;elsenext_state = S2; end,S2: beginop =0;if (din=1)next_state = S2;elsenext_state = S3; end,S3: beginop
34、=0;if (din=0)next_state = S3;elsenext_state = S0; end,default: /case缺省项,防止产生锁存器 begin op =0;next_state = S0; end endcase end endmodule,(4)Mealy型状态机的Verilog语言描述,Mealy型状态机结构图,Mealy型状态机状态图,Mealy型:输出是当前状态和输入的函数。,module mealy_machine(clk,din,op); input clk,din; output op; reg1:0 current_state,next_state;
35、 reg op; parameter S0=2b00,S1=2b01,S2=2b10,S3=2b11; /第一个always进程时序逻辑电路 always( posedge clk) begin current_state = next_state; end,/第二个always进程 always(current_state or din) begin case( current_state ) S0: beginif (din=0)beginnext_state = S0;op =0;endelsebeginnext_state = S1;op =1;end end,S1: beginif
36、(din=1)beginnext_state = S1;op =1;endelsebeginnext_state = S2;op =0;end end,S2: beginif (din=1)beginnext_state = S2;op =0; endelsebeginnext_state = S3;op =1;end end,S3: begin if (din=0)beginnext_state = S3;op =0;endelsebeginnext_state = S0;op =1;end end,default: begin /case缺省项,防止产生锁存器op =0;next_stat
37、e = S0; end endcase end endmodule,Mealy型状态机的仿真波形图,Moore型状态机的仿真波形图,仿真结果,自动售货机功能:,(4) 用状态机设计一个自动售货机,它的投币口每次只能投入一枚五角或一元的硬币。投入一元五角钱硬币后机器自动给出一杯饮料;投入两元(两枚一元)硬币后,在给出饮料的同时找回一枚五角的硬币,投币时只能一个一个地投。,根据设计要求,共有7个变量,分别为: clk:时钟输入; reset:系统复位信号; half_dollar:代表投入5角硬币; one_dollar:代表投入1元硬币; half_out:售货机找回一枚5角硬币信号; disp
38、ense:机器售出一瓶饮料; collect:提示投币者取走饮料。,设计分析:,输入:高位一元,低位五角;00 不投币,01 投币五角,10投币一元; 输出:高位为售出饮料,低位为找回五角硬币;00没有输出,10售出饮料,11售出饮料的 同时找回五角硬币。,状态转换图的确定,/* clk:时钟; reset: 系统复位输入:half_dollar:投入五角硬币; one_dollar: 投入一元 硬币;状 态:idle:空闲状态;half:五角硬币状态;one:一元硬币状态;输 出:dispense: 售出一瓶饮料 ;half_out: 找回五角硬币;collect: 提示投币者取走饮料 */
39、,Verilog语言描述,module machine(one_dollar, half_dollar, collect,half_out, dispense, reset,clk); parameter idle=2b00, half=2b01, one =2b10; input one_dollar, half_dollar, reset, clk; output collect, half_out, dispense; reg collect, half_out, dispense; reg1:0 D;,/always进程 always (posedge clk) begin if(re
40、set) /当reset为1时,系统复位,初始为idle状态 begin dispense=0; collect=0; half_out=0; D=idle; end else case(D),idle: if(half_dollar) begin dispense=0; collect=0; half_out=0; D=half; end else if(one_dollar) begin dispense=0; collect=0; half_out=0; D=one; end else begin dispense=0; collect=0; half_out=0; D=idle; en
41、d,half: if(half_dollar) begin dispense=0; collect=0; half_out=0; D=one; end else if(one_dollar) begin dispense=1; collect=1; half_out=0; D=idle; end else begin dispense=0; collect=0; half_out=0; D=half; end,one: if(half_dollar) begin dispense=1; collect=1; half_out=0; D=idle; end else if(one_dollar) begin dispense=1; collect=1; half_out=1; D=idle; end else begin dispense=0; collect=0; half_out=0; D=one; end,default: /case缺省项 begindispense=0; collect=0; half_out=0; D=idle; end endcase end endmodule,自动售货机的仿真波形图:,仿真结果,连续两次投入一元硬币后输出结果。,连续三次投入五角硬币后输出结果。,