第7章--Verilog-HDL语言简介-课件

上传人:无*** 文档编号:241969887 上传时间:2024-08-08 格式:PPT 页数:215 大小:1.91MB
返回 下载 相关 举报
第7章--Verilog-HDL语言简介-课件_第1页
第1页 / 共215页
第7章--Verilog-HDL语言简介-课件_第2页
第2页 / 共215页
第7章--Verilog-HDL语言简介-课件_第3页
第3页 / 共215页
点击查看更多>>
资源描述
第7章 Verilog HDL语言简介,7.1 Verilog HDL语言总体结构,7.2 端口声明与数据类型声明,7.3 数值的表示,7.4 连续赋值,7.5 模块实例化,7.6 验证设计,7.7 运算符(operator),7.8 Verilog HDL行为级建模,7.9 任务和函数介绍,7.10 综合设计:交通信号灯控制器,7.11 Verilog HDL语言的仿真工具,习题,第7章 Verilog HDL语言简介,7.1 Verilog HDL语言总体结构第7章 Ver,Verilog HDL语言是一种硬件描述语言,在20世纪80年代由Gateway DesignAutomation公司开发,用于电路的模拟。1995年,Verilog HDL成为IEEE(Instituteof Electrical and Electronics Engineers,电子电气工程师协会)标准,即IEEE1364标准(Verilog-1995),2001年对该标准进行了修改(Verilog-2001)。Verilog-2001在Verilog-95上增加了一些新的特性,使Verilog HDL的表述更简洁。目前大部分EDA工具都支持两个标准。本书按Verilog-95标准对Verilog HDL进行简要的介绍。,Verilog HDL语言是一种硬件描述语言,在20世纪,Verilog HDL语言可以在系统级、算法级、寄存器传输级RTL(RegisteredTransferLevel)、门级和开关级(晶体管级)等多个抽象设计层次对数字电路或者系统进行建模。Verilog HDL本质是一种复杂的描述数字系统的语言,句法上与语言相似,延用了C语言的多种操作符和结构,但是其语义上是基于并发硬件操作,完全不同于顺序执行的C语言。Verilog HDL是一种仿真能力非常强大的语言,语言中包含了一部分可以用EDA工具进行逻辑综合的子集。所谓的逻辑综合就是指利用电子设计自动化EDA(Electronic Design Automation)工具将Verilog HDL代码转换成电路。,Verilog HDL语言可以在系统级、算法级、寄存器传,Verilog HDL可以用于描述系统中的一个元件,也可以用于描述一个完整的系统。,7.1 Verilog HDL语言总体结构,Verilog HDL可以用于描述系统中的一个元,Verilog HDL语言描述主要由三个部分构成:端口声明(Port Declaration)、信号数据类型声明(Data Type Declaration)、电路模块功能描述(Circuit Functionality),图7-1给出了一个基本Verilog HDL程序的组成结构。Verilog HDL程序以关键词module开始,以关键字endmodule结束。module后面是一个模块名标识符,它唯一地标识一个模块,模块名后括号中的port_list是模块的输入和输出列表。当portlist是空的时候,该模块是一个仿真中模块。,Verilog HDL语言描述主要由三个部分构成:端口声,图7-1 Verilog HDL的模块组成结构,图7-1 Verilog HDL的模块组成结构,端口声明(Port Declarations):声明一个端口的性质,如输入(Input)、输出(Output)还是双向口(inout)以及端口的宽度(PORT_WIDTH 1:0)。信号数据类型声明(Data Type Declarations):声明module中用到的数据类型,如reg,port1,,,wire port2,。电路模块功能描述,(Circuit functionality),:描述电路功能。与,C,语言一样,在,Verilog HDL,语言中,除了关键字,endmodule,行外,每行以“;”号结束。Verilog HDL是大小写敏感语言,语言中所有的关键字都是小写,其注释方式有两种:一是单行注释,注释内容在“/”之后,直至本行末;二是多行注释,注释内容自“/*”开始,至“*/”结束。,端口声明(Port Declarations):声明一个,【例7-1】,用Verilog语言描述两输入的异或门。图7-2(a)给出了一个异或门的Verilog描述,图(b)给出了图(a)的综合结果。图7-3是Verilog HDL语言的基本元素组成图,本章将按图7-3对Verilog HDL语言的各个部分作简单的介绍。,【例7-1】用Verilog语言描述两输入的异或门。,图7-2 异或门的Verilog HDL 描述,图7-2 异或门的Verilog HDL 描述,图7-3 Verilog HDL语言的基本组成,图7-3 Verilog HDL语言的基本组成,一个电路由多个不同的部件(模块)构成,这些部件之间并行地工作。一个部件可以是一个门,也可以是一个完成某些特殊功能的电路,如译码器、多路选择器和计数器等,还可以是完成复杂任务的子系统,如嵌入式微处理器等。Verilog语言中可以用三种方式来描述系统各个部件的功能:连续赋值(Continuous Assignment)、过程模块(Procedural Block)和模块实例化(ModuleInstantiation)。此外,Verilog还可以用各种子程序如任务(task)、函数(function)或者系统任务(system task)来描述电路的行为或者仿真的行为。,一个电路由多个不同的部件(模块)构成,这些部件之间并行地,1.I/O端口声明,I/O端口是一个模块和其周围环境进行通信的信号接口,模块内部的信号对于环境而言是不可见的。例如,图7-4是一个两输入异或门的I/O端口。Verilog HDL语言在模块内必须对输入、输出列表中的每个信号进行声明,同时对输入和输出信号的数据类型进行声明。,7.2 端口声明与数据类型声明,1.I/O端口声明I/O端口是一个模块和其周围环,图7-4 两输入XOR门的I/O端口,图7-4 两输入XOR门的I/O端口,基本语法是:module identifier(port_name1,port_name2,port_nameN);mode port_name1;/声明端口类型 modeport_nameN;data_type port_name1;/声明端口数据类型 data_type port_nameN;endmodule mode类型有三种:input(输入端口)、output(输出端口)和inout(双向端口)。,基本语法是:module identifier(,这些都是关键字,不能用于信号名。(port_name1,port_nameN)是一个模块的输入和输出端口名称列表,这些名称之间用“,”进行分离,输入、输出列表的最后一项没有“,”。JP2data_type port_name1,data_type port_nameN是对端口的数据类型进行声明。,这些都是关键字,不能用于信号名。(port_name1,【例7-2】,两输入异或门的I/O端口声明。module xor_2(in1,in2,out);input in1,in2;/声明输入信号 output out;/声明输出信号 wire in1,in2;/声明输入端口的数据类型 wire out;/声明输出端口的数据类型 endmodule,【例7-2】两输入异或门的I/O端口声明。m,要特别注意的是:在模块中不能再次定义模块,即模块不能嵌套。例如,下面的写法是错误的。module and_2(in1,in2,ou1);module dff(clk,rst,din,dout);/错误定义!endmodule endmodule,要特别注意的是:在模块中不能再次定义模块,即模块不能嵌套,2.信号的数据类型声明,在Verilog HDL中使用四值逻辑,它们分别是:(1)“0”:表示逻辑0或者判定条件假。(2)“1”:表示逻辑或者判定条件为真。(3)“z”:高阻状态。(4)“x”:未知状态。“z”表示高阻态,通常用于描述一个三态门;而“x”则是用于仿真或者建模,表示当前值不确定,当输入没有初始化或者输出有冲突的时候,会出现“x”状态。信号的取值是这四种逻辑值中的任意一种。,2.信号的数据类型声明在Verilog HD,信号数据类型的声明说明在本模块中使用的信号和参数的数据类型。简单的语法是:data_type range signal_name;/声明一个信号变量或者 data_type range signal_name1,signal_name2,signal_nameN;/同时声明N个类型、范围相同的信号变量 Verilog HDL 有两大类数据类型:线网类型组及寄存器类型组。,信号数据类型的声明说明在本模块中使用的信号和参数的数据类,(1)线网类型组(net group)。,在Verilog HDL语言中,线网类型组用于描述硬件元件间的物理连线。线网类型的变量是连续赋值的输出,也是不同部件之间的连接信号,它的值由驱动元件的值决定,如图7-5所示。如果没有驱动元件连接到线网,线网的缺省值为“z”。在net类型中最常用的类型是wire类型。正如其名字所表示,它表示一个连接线。,(1)线网类型组(net group)。在Ver,图7-5 线网类型组,图7-5 线网类型组,wire数据类型表示比特信号。例如:wire p1,p2;/声明两个1比特的信号线网类型组(net group)中的其它数据类型包括:wand(线与)、supply0(电路地连接)、supply1(电源连接)等等,表示某类逻辑操作和功能,本书不涉及这些类型,有兴趣的读者可以参看本书后面列出的参考文献。,wire数据类型表示比特信号。例如:w,(2)寄存器类型组(register group)。,寄存器组中的数据类型在行为模型中表示抽象存储,是过程赋值的输出。这个组中包括四种类型:reg、integer、real和time。大多数变量用reg类型,reg类型是可以综合的。注意:综合出来的电路既可以包含也可以不包含存储元件。后三种数据类型只是用于建模和仿真。,(2)寄存器类型组(register group)。,例如:reg d_flip;/声明一个reg类型的信号变量 在Verilog HDL中可用rang表示一组信号。wire和reg类型的变量可以声明成多位宽度的向量(vectors)。如果变量的宽度是一位,该变量即是标量(scalar)。我们可以用一维向量表示一组信号(总线)。,例如:reg d_flip;/声明一个,例如:wire sel;/标量信号wire 7:0 data1,data2;/8比特数据wire 31:0 addr;/32比特地址reg 7:0 out;/8比特reg变量信号的索引范围可以是升序low#:high#,也可以是降序high#:low#,但是信号数据最左边的那位就是二进制数的最高位。,例如:wire sel;,可以用一个二维向量表示一个存储器,例如一个32*4的存储器(表示一个存储器有32个字,每个字有4位),用Verilog HDL可以表示成 reg 3:0 data_mem 31:0;在Verilog HDL语言中允许使用一个向量中的一位或者多位,如:Data11;/向量data1的第2位;Data23:2;/向量data2中的第4比特和第3比特;,可以用一个二维向量表示一个存储器,例如一个32*4的存储,在Verilog语言中,整数常量可以表示成各种各样的形式,一般的格式是:size base value 其中,base说明数字的基数,当一个数用十进制表示,可省略该项。该项有4种形式:b or B:二进制;o or O:八进制;h or H:十六进制;d or D:十进制。,7.3 数 值 的 表 示,在Verilog语言中,整数常量可以表示成各种各样的形式,value:说明在对应的基数表示方式下对应的数。为了方便阅读,一个数可以用“_”分割表示。如8b 1000_0011。size:说明一个数值用几位表示,这项是可选的。如果在一个数的表示中存在该项,那么这个数被认为是有位数表示的,否则是无位数表示的数。size项显式地表示了一个数值所用的位数。如果一个数所用位数小于 size所规定的位数,需要对该数扩展到size规定的位数。如果一个数值的最高位是x或z,那么在该数前用x或者z填充,扩展到规定的位数;如果一个数有符号位,那么用符号位填充,扩展到规定的位数;其它情况下,在该数前用0填充,扩展至规定的位数。,value:说明在对应的基数表示方式下对应的数。为,如果一个数前省略了size项,那么它实际的表示依赖于计算机的结构,但是至少扩展到32位。例如,表7-1所示为有位数表示的常数,表7-2所示为无位数表示的常数。,如果一个数前省略了size项,那么它实际的表示依赖于,表7-1 有位数表示的常数示例,表7-1 有位数表示的常数示例,表7-2 无位数表示的常数示例,表7-2 无位数表示的常数示例,可以通过连续赋值描述组合电路的功能,基本语法是:assign signalname=expression;assign是Verilog HDL语言的关键词;signalname的数据类型必须是wire类型;expression的数据类型没有限制,它是由操作数和操作符变量构成的表达式或者是函数。操作数类型可以是前面定义的任意数据类型。操作数可以是常数、整数、实数,线网、寄存器、向量或者向量的一位或者多位。,7.4 连 续 赋 值,可以通过连续赋值描述组合电路的功能,基本语法是:a,在连续赋值语句中,等式右边表达式中的任何一个信号变量发生变化,表达式都要计算,例如:wire 9:0 addr;wire 31:0 bus;wire out;wire 7:0 result;assign addr=10b 0000_0010_11;/表达式是常数,在连续赋值语句中,等式右边表达式中的任何一个信号变量发生,assign data=bus 32h 0000_ffff;/变量、常数和运算符构成的表达式 assign out=in1|in2;/变量、操作符和变量构成的表达式 assign result=mult(a,b);/表达式是函数值,assign data=bus 32h 0000,模块实例化是创建模块的另外一个应用实例。通过模块的实例化可以构建更复杂的设计模块或者系统。实例化的一般语法形式:module_nameinstance_name(.port_name1(signal_name1),.port_name2(signal_name2),.port_nameN(signal_nameN);,7.5 模 块 实 例 化,模块实例化是创建模块的另外一个应用实例。通过模块的实例,【例7-3】,一个两位的比较器可以通过两个一位比较器按照图7-6所示的连接方式实现。一位/两位的比较器verilog的描述方式有如下两种。第1种:module eq_1bit(i0,i1,eq);input i0,i1;output eq;wire p0,p1,eq;assign p0=i0endmodule,【例7-3】一个两位的比较器可以通过两个一位比较器按,图7-6 一个两位比较器,图7-6 一个两位比较器,第2种:module eq_2bit(a,b,a_eq_b);input 1:0 a,b;,output a_eq_b;,wire e0,e1,a_eq_b;eq_1bit eq_bit0_unit(.i0(a0),.i1(b0),.eq(e0);/实例化模块eq_1biteq_1bit eq_bit1_unit(.i0(a1),.i1(b1),.eq(e1);/实例化模块eq_1bit,第2种:module eq_2bit(a,b,a_eq,assign a_eq_b=e0endmodule在第2种描述方式中,句子eq_1bit eq_bit0_unit(.i0(a0),.i1(b0),.eq(e0)表示实例化eq_1bit模块,eq_bit0_unit是eq_1bit模块的一个实例,(.i0(a0),.i1(b0),.eq(e0)表示实例eq_bit0_unit的输入/输出信号在本模块中和其它模块之间的信号连接关系。在本例中,实例eq_bit0_unit是一个一位比较器,其输入端i0、i1在本模块中连接到信号a0和b0,其输出端连接到e0上。注意“.”不可缺少。,assign a_eq_b=e0e,一个设计完成后,必须要确认设计是否满足设计者所要求的功能。一种方法就是利用EDA软件,在计算机上通过仿真确认所完成电路是否正确,我们称之为电路验证。为了验证一个电路是否正确,需要对所设计的电路提供输入激励,然后通过软件观察输出是否正确。因此,除了设计模块之外,还需要编写激励模块,我们把这种模块称为testbench模块。下面介绍如何编写一个设计的testbench模块。,7.6 验 证 设 计,一个设计完成后,必须要确认设计是否满足设计者所要求的功能,在testbench模块中,实例化设计模块,按照模块的功能编写模块的输入激励,检查和显示输出信息。以两输入的比较器为例,图7-7给出了testbench模块tb_eq_2bit和被仿真模块eq_2bit之间的关系。从图中可以看出,仿真模块tb_eq_2bit本身没有输入和输出,包含了模块eq_2bit(设计模块)的一个实例eq_2bit_inst。tb_eq_2bit内产生eq_2bit_inst实例所需要的输入激励a、b,检查和显示其输出信号a_eq_b。,在testbench模块中,实例化设计模块,按照模块的功,图7-7 测试模块和设计模块之间的关系,图7-7 测试模块和设计模块之间的关系,【例7-4】,编写eq_2bit的测试模块。module tb_eq_2bit;/两位比较器电路的testbench模块名 reg1:0 a,b;/比较器输入信号 wire a_eq_b;/比较器输出信号 initial begin /给出所有可能的输入值 a=2b00;b=2b00;/初始时刻,给a,b赋值,【例7-4】编写eq_2bit的测试模块。,#10 a=2b00;b=2b01;/10个时间单位后,给a,b赋不同的值#10 a=2b00;b=2b10;/20个时间单位后,给a,b赋不同的值#10 a=2b00;b=2b11;/30个时间单位后,给a,b赋不同的值#10 a=2b01;b=2b00;/40个时间单位后,给a,b赋不同的值#10 a=2b01;b=2b01;/50个时间单位后,给a,b赋不同的值#10 a=2b01;b=2b10;/60个时间单位后,给a,b赋不同的值#10 a=2b01;b=2b11;/70个时间单位后,给a,b赋不同的值,#10 a=2b00;b=2b01;/10个时间,#10 a=2b10;b=2b00;/80个时间单位后,给a,b赋不同的值#10 a=2b10;b=2b01;/90个时间单位后,给a,b赋不同的值#10 a=2b10;b=2b10;/100个时间单位后,给a,b赋不同的值#10 a=2b10;b=2b11;/110个时间单位后,给a,b赋不同的值#10 a=2b11;b=2b00;/120个时间单位后,给a,b赋不同的值#10 a=2b11;b=2b01;/130个时间单位后,给a,b赋不同的值,#10 a=2b11;b=2b10;/140个时间单位后,给a,b赋不同的值#10 a=2b11;b=2b11;/150个时间单元后,给a,b赋不同的值 end eq_2bit eq_2bit_inst(.a(a),.b(b),.a_eq_b(a_eq_b);/两位比较器实例化 endmodule,#10 a=2b10;b=2b00;/80个,在上面的例子中,initial begin.end是一个过程块,下节将详细介绍。#10表示10个时间单位的延时。该过程块给出了随时间变化的输入值,完整的仿真eq_2bit设计需要输入a、b的全部组合,一共是16种,结果如图7-8所示。,在上面的例子中,initial begin.,图7-8 两位比较器完整测试波形图,图7-8 两位比较器完整测试波形图,上面的例子介绍了如何建立一个验证程序。验证程序也是一个module,但是它没有任何的输入和输出。在验证程序中,需要实例化被验证的设计;定义设计所需要的输入和输出;为输入加载输入激励。,上面的例子介绍了如何建立一个验证程序。验证程序也是一个m,在Verilog语言中包含了10类操作符、24种运算符。这些运算符对应着简单的器件,比如加法器和比较器。表7-3说明了Verilog HDL中的运算符,表7-4给出了运算符的优先级。,7.7 运算符(operator),在Verilog语言中包含了10类操作符、24种运算符,表7-3 Verilog HDL中的运算符,表7-3 Verilog HDL中的运算符,表7-4 运算符优先级,表7-4 运算符优先级,1.算术运算符,在Verilog中,算术运算符共有六个:“+”、“-”、“*”、“/”、“%”和“*”,分别代表加、减、乘、除、取模和指数运算。“+”和“-”也可以作为一元运算符,例如:-a。在算术运算操作中,“+”和“-”运算符可以用EDA工具直接综合成加法器和减法器。乘法是一个复杂的操作,对于乘法运算符“*”的综合取决于综合软件以及目标器件的工艺。除法运算符“/”、求模运算符“%”和指数运算符“*”在通常情况下是不可综合的。,1.算术运算符在Verilog中,算术运算符,2.移位运算符,移位运算符有四个:“”、“”,分别表示逻辑左移、逻辑右移、算术左移、算术右移。这组运算符是将一个向量向左或者向右移动给定的位数,如果是逻辑移位,则用0填充在向量的高位(左移)或者低位(右移)。算术左移高位用低位填充,最低位用0来填充,符号位移出后,则丢弃,这样,算术左移和逻辑左移的运算结果一样。而算术右移低位用高位填充,把数的最高位看成符号位,用符号位填充高位,最低位移出后丢弃。,2.移位运算符移位运算符有四个:“2;/x=0001_0011,y=b2;,/y=1111_0011 z=c3;/z=1111_0100 算术右移将b的最高位看成符号位,用符号位填充;z=a2;/z=0011_1100;w=b”、“=”、“”、“=”、“10),【例7-6】,表7-11给出了逻辑运算和位运算的一些例子。由于Verilog HDL中用0和1来代表假和真,所以位运算和逻辑运算在某些条件下可以交换使用。,例如:if(state=idle,表7-11 逻辑运算例子,表7-11 逻辑运算例子,5.拼接运算符和复制运算符1)拼接运算符,用表示拼接运算,使用这个运算符可以把两个或多个信号的某些位拼接形成一个向量,进行运算操作,多个信号变量用“,”隔开。wire a1;wire 3:0 a4;wire 7:0 b8,c8,d8;assign b8=a4,a4;assign c8=a1,a1,a4,2b00;assign d8=b83:0,c83:0;,5.拼接运算符和复制运算符1)拼接运算符,拼接运算的一个应用是进行信号变量移位或循环操作,举例如下:wire 7:0 a;wire 7:0 rot,shl,sha;assign rot=a2:0,a7:3;/a向右循环3位assign shl=3b000,a8:3;/a逻辑右移3位assign sha=a8,a8,a8,a8:3;/a算术右移3位,拼接运算的一个应用是进行信号变量移位或循环操作,举例如下,2)复制运算符,用N 表示对内的数复制N次,形成新的向量。该操作可以用于化简拼接的写法。例如,42b01等价于 8b01010101又如,assign sha=3a8,a8:3;/a算术右移3位等价于:assign sha=a8,a8,a8,a8:3;/a算术右移3位,2)复制运算符 用N 表示对内的数,6.条件运算符,条件运算符“?:”是三目运算符,其基本格式如下:signal_name=boolean_exp?true_exp:false_exp;其中,boolean_exp是指布尔表达式,返回值是真(1b1)或假(1b0)。如果boolean_exp为真,则signal为true_exp的值,否则为false_exp的值。例如,wire 2:0 max;assign max=(a b)?a:b;,6.条件运算符条件运算符“?:”是三目运算符,,该运算用if-else语句表示如下:if boolean_exp signal=true_exp;else signal=false_exp;条件运算符还可以嵌套,例如:assign max =(a b)?(a c)?a:c):(b c)?b:c);在综合时,条件运算符会被综合成二选一选择器。,该运算用if-else语句表示如下:if b,7 表达式的位宽,Verilog HDL程序中的信号,连线和变量通常都具有不同的位宽,在存储中,选择的位数与位宽一致。例如,wire 7:0 a,b;assign a=8b00000000;assign b=0;,7 表达式的位宽Verilog HDL程序中的,上述代码中,第一条assign语句是将8位的二进制数“00000000”赋给a,而第二条assign 语句是指将整数0赋给b。在Verilog中整数是32位,即“0000_0000_0000_0000_0000_0000_0000_0000”。由于b事先声明为8位,故正确地从32位中截取8位的“00000000”。尽管这两条assign语句的结果都是8位的“00000000”,但是我们必须清楚a和b分别是怎样获得的值。,上述代码中,第一条assign语句是将8位的二进制数“,例如,wire 7:0 a,b;wire 7:0 sum8;wire 8:0 sum9;assign sum8=a+b;assign sum9=a+b;上述代码中,第一条assign语句中所有的操作数都是8位,等号左边的sum8也是8位的,而附加的进位位被丢弃了。在第二条assign语句中,由于sum9是9位的,所有“a”和“b”也被扩展成9位,而sum99就是进位位的值。我们同样可以利用拼接运算符来完成上述运算:assign c_out,sum8=a+b;,例如,wire 7:0 a,b;,1 过程块结构,在Verilog HDL语言中有两种结构化过程语句always和initial,它们是行为建模中最基本的两个语句,所有其它的行为语句可以出现在这两个结构化过程中。always和initial语句不能嵌套。,7.8 Verilog HDL行为级建模,1 过程块结构在Verilog HDL语言中有,1)initial 语句,initial语句只用于建立行为仿真,不能综合。所有出现在initial中的语句构成一个initial 块(initial block),一个initial块从时间0开始执行,在仿真过程中每个语句只执行一次。如果一个仿真程序中出现了多个initial块,这些块都是在0时刻开始执行的,每个initial 块的执行是相互独立的。,1)initial 语句initial语句只用,基本的语法是:initial begin statements_sequence;end,【例7-7】,initial 模块示例。module stimulus;/验证模块,reg x,y,a,b,m;,initial,m=1b0;/,只有一个语句,可以省略,begin/end,基本的语法是:initial begi,initial begin#5 a=1b1;,/,多条语句,需要用,begin/end#25 b=1b0;,end initial begin#10 x=1b0;#25 y=1b1;,end initial#50$finish;endmodule,initial begin#5 a,在上面的例子中有一个延时#delay,表示等待delay个时间单位。其执行的结果如下:time statement executed 0 m=1b0;5 a=1b1;10 x=1b0;30 b=1b0;35 y=1b1;50$finish;,在上面的例子中有一个延时#delay,表示等待delay,2)always块,always块是Verilog语言中另外一种描述电路行为的语句,它是可综合语句。所有出现在always中的语句构成一个always块。always块使用行为语句描述电路的功能。always的一般形式为 always(event_list)begin statements_sequence end,2)always块always块是Veril,执行always块的条件是事件列表(event_list)中任何信号发生变化,即只要事件列表中的任何事件发生变化,就重复执行语句序列。如果always块的语句只有一条,可以省略begin/end。statement_sequence是指过程赋值语句序列。过程赋值语句和(event_list)将在后续小节详细介绍。例如,reg out1;always(in1 or in2)/in1 或者in2发生变化,执行out1=in1|in2语句 out1=in1|in2;,执行always块的条件是事件列表(event_lis,2 过程赋值语句,过程赋值语句的基本语法:lhs =rhs;lhs rhs;上面两个语句都是过程赋值语句,前者我们称为阻塞赋值(=),而后者称为非阻塞赋值。过程赋值语句的作用是用等式右边的表达式(rhs)更新等式左边的变量值(lhs)。,2 过程赋值语句过程赋值语句的基本语法:,等式左边的变量值的类型有reg、integer、real和time。过程赋值与连续赋值的不同之处是:在连续赋值语句中,等式右边表达式的值连续不断地赋给等式的左边,而在过程赋值语句中,一个变量存储的值保持不变,直到过程赋值语句用不同的值更新该变量。等式右边的表达式可以是下面的几种形式:(1)reg、integer、real和time型变量,如a,b,c;(2)变量的比特选择,如addr0;(3)变量的部分选择,如addr31:16;(4)上述类型的连接形式,如4h0,addr15:0,a。,等式左边的变量值的类型有reg、integer、real,1)阻塞赋值语句,用“=”进行赋值的语句是阻塞赋值语句。阻塞赋值可以按照它们在过程块中的次序顺序执行,在它执行结束之前,将阻止后续语句的执行,【例7-8】,下面的表达式形式都是合法的:reg a,b,c;reg 15:0 data;integer counter;initial begina=1b0;b=1b1;c=1b1;/在0时刻,将3b011分别赋给a,b,c;,1)阻塞赋值语句用“=”进行赋值的语句是阻塞赋,counter=0;/在0时刻,counter赋初值0;#10 data1=a;/在第10个时间单位,将a赋给data1;data7:2=6b00_1011;/将二进制数001011赋给data7:2;#20 counter=counter+1;/在第30个时间单位,将counter加1 a,b,c=counter2:0;/在第30个时间单位,将counter的低三位分别赋给a,b,cend,counter=0;/在0时,注意,:如果等式右边的数据宽度大于等式左边变量的宽度,那么抛弃高位,而保留低位。如果等式右边的数据宽度小于等式左边变量的宽度,则高位用0填充。,2)非阻塞赋值语句,一条非阻塞赋值语句不阻止后续语句的执行。,【例7-9】,阻塞与非阻塞赋值语句的执行情况。如下两段代码分别为阻塞和非阻塞赋值语句。,注意:如果等式右边的数据宽度大于等式左边变量的宽度,那,阻塞赋值:reg A,B;initial begin A=#10 1b1;B=#5 1b0;A=#20 1b0;B=#15 1b1;end,阻塞赋值:reg A,B;initial b,非阻塞赋值:reg A,Binitial begin A=#10 1b1;B=#5 1b0;A=#20 1b0;B=#15 1b1;end,非阻塞赋值:reg A,Biniti,我们来考察阻塞语句与非阻塞语句的执行情况,在本例中的时间单位是ns,如图7-9 所示,图(a)是阻塞赋值结果,图(b)是非阻塞赋值结果。初始,A、B值均为高阻态。对于非阻塞语句描述,10 ns执行语句A=1b1;在该句执行结束后的5 s,即第15 ns执行B=1b0;而此后的20 ns,即到35 ns前,A一直为1;35 ns时执行语句A=1b1;在50 ns的时候执行B=1b1。可以看出阻塞语句一定是本句执行结束后,才允许运行其它语句的执行。在一个过程块中,它们是顺序执行的。,我们来考察阻塞语句与非阻塞语句的执行情况,在本例中的时,图7-9 阻塞赋值和非阻塞赋值的输出波形,图7-9 阻塞赋值和非阻塞赋值的输出波形,而对于非阻塞语句,它的执行并不阻塞后续语句的执行。因此,调度器在5 ns时候执行B=0;在10 ns的时候执行A=1;在15 ns的时候执行B=1,而在20 ns的时候执行A=0,如图7-9(b)所示。为了进一步看清楚阻塞语句与非阻塞语句的区别,我们再举一个例子。,而对于非阻塞语句,它的执行并不阻塞后续语句的执行。因此,,【例7-10】,阻塞语句与非阻塞语句的综合。阻塞赋值:module dff(clk,din,dout);input din,clk;output dout;reg a,dout;always(posedge clk)begin a =din;dout=a;endendmodule,【例7-10】阻塞语句与非阻塞语句的综合。阻塞赋值:,非阻塞赋值:module dff(clk,din,dout);input din,clk;output dout;reg a,dout;always(posedge clk)begin a=din;dout=a;endendmodule,非阻塞赋值:module dff(clk,di,在阻塞赋值代码中,由于a=din在瞬间完成后,执行dout=a,然后在时钟的上升沿到达的时候,更新等式左边的值。因此,从仿真结果看,a和dout的值相同,其综合的结果就是一个D触发器。而非阻塞赋值代码的综合结果是一个两位的移位寄存器,两个等式右边的表达式按照当前期的值计算出结果,然后保存在临时变量中,在时钟上升沿到达时,同时更新表达式的左边。这样,寄存器dout的结果是上一周期a的结果,而a则是上一个周期din的结果。图7-10给出了阻塞赋值与非阻塞赋值的综合结果。,在阻塞赋值代码中,由于a=din在瞬间完成后,执行dou,图7-10 阻塞赋值和非阻塞赋值综合结果,图7-10 阻塞赋值和非阻塞赋值综合结果,3.时序控制,时序控制用于说明过程语句执行的仿真时间。有三种基本的时间控制语句:基于延时控制的时序控制、基于事件的时序控制和电平敏感的时序控制。,1)基于延时的时序控制,表达式中基于延时的时序控制说明了仿真器遇到语句和执行语句之间的间隔。在Verilog 语言中用“#delay”说明延时。在过程赋值语句中,主要的两类延时控制是:(1)正则延时(regular delay):在过程表达式的左边说明非零延时。,3.时序控制时序控制用于说明过程语句执行的仿,如#delay lhs=rhs;等待delay时间后将rhs的值赋给lhs。(2)内定延时(intradelay):在赋值语句的右边说明延时。#delay1 lhs=#delay2 rhs;仿真器执行的过程如下:,等待delay1;,计算等式的右边rhs;,等待delay2后,将rhs的值赋给lhs。,如#delay lhs=rhs;,【例7-11】,时间赋值语句举例,其延时时序图如图7-11所示。module test parameter latency=10,delta=2;reg 10:0 a,b;reg w1,w2;integer i1,i2,delay3;initial begin w1=1b0;w2=1b1;delay3=10;,【例7-11】时间赋值语句举例,其延时时序图如图7-,图7-11 例7-25延时时序图,图7-11 例7-25延时时序图,#delay3 a=-23;/使用标识符控制#5 i1=10;/在5时间单位后将10赋给整型变量i1#latency b=a+10d 15;/用参数标识符(parameter_identifer)延时控制i1=#(latency+delta)a endendmodule,#delay3 a=-23;/使用标识符控制,我们将上述代码做一定的修改,加深对延时语义的理解。timescale 1 ns/1 ps/Section below this comment is automatically maintained/and may be overwritten/module test1module test;parameter latency=10,delta=2;reg 10:0 a,b;reg 10:0 c,d;,reg w1,w2;,我们将上述代码做一定的修改,加深对延时语义的理解。,integer i1,i2,i3,i4,delay3;initial begin w1=1b0;w2=1b1;delay3=10;#delay3 a=-23;/使用标识符控制#5 i1=10;i3=10;i4=10;/在5时间单位后将10赋给整型变量i1#latency b=a+10d 15;d=a+10d 15;/用参数标识符(parameter_identifer)延时控制,integer i1,i2,i3,i4,delay3;,i1=#(latency+delta)a end,i1=#(latency+delta)a&b+,initial begin#10 c=-23;#5;#(latency+1)c=21;#(latency+delta+9)c=20;end endmodule,initial begin ,【例7-12】,在上述代码中,i1、i3、i4在不同时刻的值分别是多少?说明i3=#(latency+delta)c在赋值上的区别。,解,图7-12所示时序图能够说明问题,由图中可以看出,i3和i1是一样的,i4和i3的区别在于:i3=#(latency+delta)c而#(latency+delta)i4表示,触发的事件可以用符号来识别。这类事件并不保持任何数据,仅仅用于仿真。限于篇幅关系,本书对这类事件不予介绍,有兴趣读者可读参考相关文献。,例如,always(*)begin,(4)用关键词wait实现电平敏感的时序控制。例如,wait(count_able)#10 count=count+1;当count_able为高电平10 s后,执行count=count+1,如果count_able为1,那么每隔10个时间单位,count计数器加1直到count_able变成0。,注意:,(3)和(4)语句都不可以综合成电路。,(4)用关键词wait实现电平敏感的时序控制。,4.条件语句,Verilog语言中包含了两种条件语句:If条件语句和Case语句。,1)If条件语句,If是一种具有优先级的条件分支结构。它有三种格式:格式1:If()statement_sequence;如果expression为真,则执行语句序列(statement_sequence)。格式2:If()statement_sequence1 else statement_sequence2如果表达式成立,则执行序列1;不成立,则执行语句序列2。,4.条件语句Verilog语言中包含了两种条,格式3:If()statement_sequence1 else if()statement_sequence2 else if else statement_sequence_default,格式3:If(),这是嵌套If条件语句格式,当expression 1为真时,执行statement_sequence1;不为真时,计算expression 2是否为真。如果所有的表达式都不为真,则执行statement_sequence_default。,这是嵌套If条件语句格式,当expression 1为真,【例7-13】,用If语句设计一个三选一的选择器。always(*)beginif(sela)q=a;else if(selb)q=b;else q=c;end,【例7-13】用If语句设计一个三选一的选择器。,【例7-14】,用If语句设计一个两位的比较器。module comparator(a,b,eq,gt,lt);input1:0a,b;output gt,lt,eq;reg gt,lt,eq;always(*)begin,【例7-14】用If语句设计一个两位的比较器。,gt=1b0;/gt默认的值 eq=1b0;/eq默认的值 lt=1b0;/lt默认的值 if(a b)gt=1b1;else if(a=b)eq=1b1;else lt=1b1;end endmodule,gt=1b0;/gt默,2)case 语句,case 语句的语法形式为 case():statement_sequence1:sequence of statement(s)default:statement_sequence1endcase,2)case 语句case 语句的语法形式为,case语句是一种没有优先级的多路分支结构。按照它们在case语句中的次序匹配不同的条件,,如果条件满足,则执行的相应的语句序列;如果条件不满足,则执行default后面的语句序列。case语句的行为类似于一个多路选择器。,case语句是一种没有优先级的多路分支结构。expre,【例7-15】,用case语句实现一个四选一电路。module mux4_to_1(i0,i1,i2,i3,sel,out);,input i0,i1,i2,i3;input 1:0 sel;output out;,【例7-15】用case语句实现一个四选一电路。,reg out;always(*)case(sel)2d0:out=i0;2d1:out=i1;2d2:out=i2;default:out=i3;endcaseendmodule,reg out;always(*)case(,除此之外,如果case语句中的条件(condition)包含了z和x,那么我们需要用case语句的另外两种形式:casez和casex。在casex中把所有的x和z当成无关项;而在casez中把所有的z当成无关项,z也可以用?代替。在casez和casex语句中只把表达式和条件中的非-z和非-x位置的值进行比较。,除此之外,如果case语句中的条件(condition),【例7-16】casex和casez的使用。casex(encoder)4b1xxx:high_lvl=3;4b01xx:high_lvl=2;4b001x:high_lvl=1;4b0001:high_lvl=0;default:high_lvl=0;,【例7-16】casex和casez的使用。,endcasecasez(encoder)4b1?:high_lvl=3;4b01?:high_lvl=2;4b001?:high_lvl=1;4b0001:high_lvl=0;default:high_lvl=0;endcase上面的代码完成一个编码器。,endcasecasez(encoder)4b1,5.循环语句 在Verilog语言中还提供了四种循环机制来描述电路的行为:While循环、Repeat循环、For循环以及Forever循环。循环的句法形式与C语言非常相似,它们只能用于initial块和always块中。,1)While 循环,While语句的语法形式为 While()statement_sequence,5.循环语句 在Verilog语言中还提,当为真时,执行statement_sequence。例如:integer count;initial begin count=0;while(count 101),当为真时,执行statement,begin /计数值小于100时,执行循环体内语句序列$display(Count=%d,count);count=count+1;end end,注意:,$display用于在标准输出设备上输出count的值,参考系统任务一节。,begin /计数值小于100时,执行循环体,2)For 循环,For语句的语法形式为 For(initial_condition;termination_condition;proceduralassignment)statement_sequenceFor循环从初始条件(initial_condition)开始执行,每执行一次,检查终止条件(termination_condition)是否满足;过程赋值语句(procedural_assignment)用于改变控制变量的值。,2)For 循环For语句的语法形式为,【例7-17】,用For循环实现一个四位左移功能,图7-13给出了移位的示意图。integer i;/为For循环进行的变量声明always(*)beginresult=0,inp;/inp是一个四位的变量If(cnt=1)begin for(i=4;i=7;i=i+1)resulti=resulti-4;result3:0=0;end,【例7-17】用For循环实现一个四位左移功能,图7,图7-13 移位示意图,图7-13 移位示意图,3)Repeat 循环,Repeat语句的语法形式为 Repeat(number)Sequence of statement(s)Repeat循环中number可以是一个数字、一个变量或者信号值,但不能是逻辑表达式。如果number是一个变量或者信号,则变量和信号值只在repeat循环开始计算,在循环执行过程中不计算其值。,3)Repeat 循环Repeat语句的语法,【例7-18】,用repeat语句实现数据的接收,要求当外部信号data_start为高后的8个周期连续接收数据。module data_buffer(data_start,data,clock);parameter cycles=8;input data_start;input 15:0 data;input clock;reg 15:0 buffer0:7;/二维存储器,【例7-18】用repeat语句实现数据的接收,要求,integer i;always(posedge clock)begin if(data_start)begin /开始接收数据 i=0;repeat(cycles)begin (posedge clock)bufferi=data;/在时钟上升沿接收数据,并放置在缓冲区中 i=i+1;/缓冲区地址加1 end endendendmodule,integer i;always(posedge c,在上述模块中,在时钟上升沿检测到data_start为高电平,则连续8次在每个时钟的上升沿接收数据,并将数据放入到buffer中。在8次结束后,再次检测data_start信号。,在上述模块中,在时钟上升沿检测到data_start为高,4)Forever循环,Forever语句的语法形式为 Forever statement_sequenceForever语句没有任何条件,在遇到系统任务$finish或者$stop之前,它一
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!