《CPLD FPGA设计与应用基础教程》课件第二章.ppt

上传人(卖家):momomo 文档编号:5716105 上传时间:2023-05-05 格式:PPT 页数:71 大小:1.34MB
下载 相关 举报
《CPLD FPGA设计与应用基础教程》课件第二章.ppt_第1页
第1页 / 共71页
《CPLD FPGA设计与应用基础教程》课件第二章.ppt_第2页
第2页 / 共71页
《CPLD FPGA设计与应用基础教程》课件第二章.ppt_第3页
第3页 / 共71页
《CPLD FPGA设计与应用基础教程》课件第二章.ppt_第4页
第4页 / 共71页
《CPLD FPGA设计与应用基础教程》课件第二章.ppt_第5页
第5页 / 共71页
点击查看更多>>
资源描述

1、第2章 Verilog HDL 入门指南LOREM IPSUM DOLOR目 录CONCENT2.1 模块2.2 模块端口及声明2.3 注释2.4 数据流描述2.5 行为级描述2.6 结构体描述2.7 混合描述 2.1 模块GRADUATION THESIS2.1 模块Verilog HDL 是基于模块的设计。模块是 Verilog HDL 语言的基本描述单元。模块是用来描述某个设计的功能或结构及其与其他模块通信的外部端口,与高级软件语言的函数相似。模块的定义比较宽泛。大至可以描述一个系统,小至可以只描述一个基本的逻辑门。整个块的基本语法如下:2.1 模块module 模块名称(端口列表);/

2、端口定义声明;input,output,inout /内部变数和参数声明 wire,reg,function,task,parameter,define,等等 /模块功能实现 数据流描述:assign 行为级描述:initial,always 结构化描述:门级例化、UDP 例化、模块例化endmodule2.1 模块【可以看出,整个模块由关键词“moduleendmodule”包含。每个 module 关键词后紧跟着模块名称,并会注明整个模块对外的端口。模块内部首先会进行端口声明和内部变量和参数说明,当然,说明可以放置到模块内部的任何位置,但为了模块的描述清晰以及可读性,通常会要求端口声明和内

3、部变量及参数说明放到执行语句前。接着根据设计的需求,采用数据流、行为级或者结构化模型来对模块功能进行具体实现,也可能同时会使用到三种模型。最后,需要以 endmodule 结束,表示整个 module 设计完毕。【例 2-1】采用 Verilog HDL 实现一个二选一选择器module mux2to1(out,s,a,b);input s,a,b;output out;asssign out#2=s?a:b;endmodule2.1 模块任例 2-1 为采用 Verilog HDL 实现的一个二选一选择器,综合后生成的 RTL 电路如图 2-1所示。Mux2to1 为该模块的模块名称。该模块

4、共有四个端口:两个输入端口 a 和 b、一个选择信号端口 s 及一个输出端口 out。端口默认为 1 位位宽。整个模块没有对各个端口进行数据类型说明,因此默认为线网数据类型。整个模块通过一个连续赋值语句完成,描述该电路在选择信号 s 为高时,把输入信号 a传送给输出 out,否则传送输入信号 b 给 out。Verilog HDL 可以采用多种方式来实现一个模块的功能。如图 2-2 所示。2.2 模块端口及声明GRADUATION THESIS2.2 模块端口及声明在模块名之后,一般会有以小括号包围的一个端口列表,端口与端口之间用“,”隔开。端口列表结束后,在小括号外以“;”结束。需要注意的是

5、,并不是所有的模块都需要有端口列表,比如顶层仿真模块就不需要端口列表因为顶层仿真模块是一个封闭系统,端口已经在内部实例化。端口通常有三种类型:input输入端口,信号从该端口流入模块;output输出端口,该端口的信号由模块驱动输出;inout双向端口,该端口的信号既可以由外部驱动,也可以由模块驱动。端口信号通常需要声明位宽,如果没有声明,则默认为 1 位位宽端口。2.2 模块端口及声明【例 2-2】端口声明端口类型 信号宽度 信号名 示例input 4:0 a_in;/5b10101inout b;/1b1output 1:0 c_out;/2h3从 Verilog HDL 2001 标准开

6、始,为了简化端口声明,可以允许把端口声明写入端口列表中,并且可以针对每个信号进行注释。需要注意的是,端口列表中是不允许出现“;”。例 2-3为例 2-1 修改后的端口声明。【例 2-3】端口声明module mux2to1(input s,input a,input b,output out);2.2 模块端口及声明5.2.2 函数调用函数调用对于模块中的信号,包括端口信号,都需要进行变量声明。如果没有显式声明,则默认为 wire 线网类型。例 2-1 到 2-3 中的各端口信号,均没有显式进行变量声明,则暗示为 wire线网类型。线网类型的关键词为 wire。wire 型的线网是不具备数据存

7、储功能的,只能被连续赋值,用于数据流描述。reg 类型的信号类型可以用来存储最后一次赋给它的值。因而它一般用来做行为级描述。信号变量声明与端口类型声明相似,也是声明信号类型和位宽,如果没有声明位宽,则默认为 1 位。2.2 模块端口及声明【例 2-4】变数声明端口类型 变量类型 信号/变量宽度 信号/变量名 示例output reg 3:0 out_ff;/4hFoutput 3:0 out_ff;reg 3:0 out_ff;reg d;/1b1 wire 4:0 e;/4h1f例 2-4 中,前三行表示输出端口的变量声明,后面两行表示内部信号的变量声明。在前三行中,第一行把变量类型和端口类

8、型写在一起,其效果和第二、三行分开写的结果一样。但是代码会更加简洁。2.2 模块端口及声明注意:注意:1.Verilog HDL 对于关键词的大小写敏感。所有关键词必须是小写。如:reg 是关键词,但 REG 为普通的信号变量2.定义为 reg 类型的信号不一定会生成寄存器3.尽管信号和内部变量声明只要出现在第一次被调用的语句之前就可以,但代码风格一般要求在执行语句之前就定义好,提高代码的可读性。4.任何一个模块都必须以“endmodule”结束2.3 注释GRADUATION THESIS2.3 注释为了提高代码的可读性,CPLD/FPGA工程师通常在代码设计时会做一定量的代码注释,采用自然

9、文字说明以确保每一个关键代码的设计容易被理解或者注释部分代码以备用。Verilog HDL 提供了两种注释方式:行注释以“/”开始,注释一行中的余下部分;块注释以“/*”开始,以“*/”结束,中间的整个代码逻辑全部被注释,它可以用来注释一行或者多行代码。2.3 注释5.3.1 显示任务显示任务【例 2-5】二选一选择器module mux2to1(input s,/输入选择控制信号input a,/输入信号input b,/输入信号output out/输出信号);/reg out;/采用 always 语句实现二选一选择器 asssign out#2=s?a:b;/*always(s or

10、a or b)out#2=s?a:b;*/endmodule例 2-5 中,既采用了行注释,也采用了块注释。第 2-5 行,采用了行注释,用来说明每个信号的用途。第 6 行行注释主要是说明此 reg 类型寄存器的用途。第 8-10 行采用块注释,注释了一段功能代码,这段功能代码结合第 6 行的代码,可以实现第 7 行代码所能实现的功能。从例 2-5 中也可以看出,reg 类型的信号和变量类型,生成的不一定是寄存器。2.4 数据流描述GRADUATION THESIS2.4 数据流显示在数字电路中,信号经过组合电路逻辑时就像数据在流动,没有任何存储。当输入发生任何变化时,输出也会随着发生相应的变

11、化,该变化可能是立即发生,也可能会经过一定的延时后发生。Verilog HDL 对此数字电路的行为建模称之为数据流描述,采用的是连续赋值语句。【例 2-6】四选一选择器如图 2-3 所示,输入选择信号 s0 是第一级两个二选一选择器的选择信号,s0 是第二级也就是输出级二选一选择器的选择信号,通过 s0 和 s1 的组合,选择 a、b、c、d 四个信号之一输出到输出端口 o。2.4 数据流显示相应的 Verilog HDL 代码如下:timescale 1ns/100psmodule four_to_one_mux(input a,input b,input c,input d,input s

12、0,input s1,output o);wire m0,m1;/数据流描述,连续赋值语句assign m0=s0?a:b;assign m1=s0?c:d;assign o=s1?m0:m1;endmodule采用 Lattice MACH XO3 CPLD,基于 Synplify Pro 综合软件综合后生成的门级网表如图2-4 所示。可以看出,真实的逻辑功能与要达成的设计要求相一致,尽管生成的底层门级单元与图 2-3 不一致这与综合软件和 CPLD/FPGA 芯片有关系。2.4 数据流显示2.4 数据流显示2.4.1 连续赋值语句连续赋值语句从例 2-6 中可以看出,整个设计都是采用组合电

13、路,中间没有任何寄存器,也就是此电路没有任何记忆功能。连续赋值语句采用关键词 assign 来实现,其基本格式如下:assign Destination=Logical Expression;等号右边的逻辑表达式作为赋值的驱动和来源,一旦任何有任何变化,就会立即进行计算,并且把计算得出来的结果立即传送给等号左边的赋值对象。例 2-6 中 four_to_one_mux模块代码中,第 12 行是标准的连续赋值语句,任何 a 和 b 以及 s0 发生变化,会直接进行计算,并且把计算结果立即回馈给 m0。相似的,第 13 和 14 行也是同样的行为。第 12 到 14行的代码是并行的,不存在先来后到

14、的顺序。同样连续赋值语句和行为语句块、例化模块以及其他连续赋值语句是并行进行的,不会因为哪家语句的顺序改变而导致执行的时间改变2.4 数据流显示连续赋值语句有时可以作为线网类型声明的一部分,采用线网说明赋值,这样就省去了关键词 assign。如例 2-7 所示。【例 2-7】线网说明赋值wire out=in1&in2;等效于:wire out;assign out=in1&in2;连续赋值语句还经常采用有条件的连续赋值方式,其基本格式如下:assign Destination=Condition?1st_Expression:2nd_Expression;如果 Condition 为真,则把

15、 1st_Expression 计算的结果赋值给 Destination,否则就把2nd_Expression 计算的结果传送给 Destination。例 2-6 中的连续赋值语句就是采用这样的结果。条件连续赋值语句可以采用级联方式来设置多个条件,从而把多个表达式传送给赋值对象。其基本格式如下:assign Destination=Condition1?(Condition2?1st_Expression:2nd_Expression):(Condition3?3rd_Expression:4th_Expression);2.4 数据流显示一般不建议采用此结构来对赋值对象进行赋值,特别是级联

16、级数较多的情况,容易出错,同时在综合是容易出现冗余和无效代码。因此,在设计级联代码时,可以采用小括号来显示信号处理的优先级,提升代码的可读性同时,建议采用带有优先级的 case 语句来替换实现。Verilog HDL 语言中定义为 wire 型的连续赋值语句的赋值对象不能多重赋值。一旦出现,综合软件会直接报错,仿真软件会直接赋值 x。如例 2-8 把例 2-6 的 m1 错误地写成了m0,从而出现了多重赋值,这是一个错误的示范。在综合时Lattice Diamond 将会报出如图 2-5 的错误。【例 2-8】多重赋值错误示例wire m0;assign m0=s0?a:b;assign m0

17、=s0?c:d;2.4 数据流显示2.4.2 时延例 2-6 中没有在连续赋值语句中定义时延,那么右端的条件表达式计算出来的值会立即赋给左端表达式,时延为 0。例 2-1 和例 2-5 均采用了带时延的连续赋值语句。assign out#2=s?a:b;#2 表示为两个时间单位。该程序的意思是当输入选择信号 s 为高电平时,把输入信号 a延时两个时间单位再传送给输出端口 out,否则把输入信号 b 延时两个时间单位再传送给输出端口 out。这行代码模拟的是选择器输入和输出之间的延时,如图 2-6 所示。2.4 数据流显示如果输入信号的脉冲宽度没有时延长,则右端的输入信号会在发生时间的间隔里被过

18、滤掉。假设:assign out#4=in;从图 2-7 中可以看出,输入 in 有两个脉冲,一个是一个时间单位的脉冲,另外一个是四个时间单位的脉冲,但从输出信号 out 来看,第一个一个时间单位的脉冲来不及输出,便被过滤掉。这也是组合逻辑的特点之一。当信号脉冲宽度小于组合逻辑器件时延的时候,相应的脉冲会被过滤掉。有些电路设计也是采用组合逻辑这样的特性,来屏蔽相应的信号干扰。2.4 数据流显示时间单位与 CPLD/FPGA 的物理时间相关。因此,除了输入和输出时延外,信号跳变的时延也是各不相同。在 Verilog HDL 中,有四种时延模型来描述信号跳变:上升时延、下降时延、关闭时延以及变成

19、x 的时延。其中,变为 x 的时延为前三者中的最小值。其基本语法是:assign#(rise,fall,turn_off)Destination=Logical expression;【例 2-9】各种时延表示方式示例assign out=in1&in2;assign#5 out=in1&in2;assign#(4,8)out=in1&in2;assign#(4,5,6)out=in1&in2;在第一个赋值语句中,没有显式显示时延,因此时延为 0。第二个赋值语句中,只有一个时延参数,表示上市时延、下降时延、关闭时延以及变为 x 的时延相同,均为 5。第三个赋值语句,有两个时延参数,分别表示上升

20、时延为 4,下降时延为 8,关闭时延和变为 x 的时延相同,为上升时延和下降时延的最小值,即为 4。第四个赋值语句,有三个时延参数,分别表示上升时延为 4,下降时延为 5,关闭时延为 6,变为 x 的时延为三者的最小值,即为 4。2.4 数据流显示在现实世界中,即使是其中的某一个时延,也会因为制程工艺、布线布局等各种客观因素而有细微差异。在 Verilog HDL 语言中,为精确建模这种行为,会针对每个时延采用“min:typ:max”的格式来表示某个时延的最小值、典型值和最大值。如:assign#(1:2:3,4:5:6)out=in1&in2;该赋值语句中,最小上升时延为 1,最大为 3,

21、典型值为 2,下降时延最小值为 4,最大值为 6,典型值为 5 个时间单位。6,典型值为 5 个时间单位。在 Verilog HDL 设计中,有时会在变量声明中会显式定义时延,说明该变量的驱动源改变到该变量本身变化之间的时延。如:wire#2 out;若在后续的数据流描述过程中,对该变量进行赋值,如:assign#2 out=in1&in2;则表示为当右边表达式中 in1 和 in2 两个输入信号发生任何变化时,将立即计算并把计算结果延时 4 个时间单位(2+2)再赋值给输出端口 out,而不是两个时延单位。2.4 数据流显示以上的时延均只指定相应的时延量,没有涉及到时延单位和时间精度。在 V

22、erilog HDL中,使用关键词timescale 来定义时间单位及精度。如:timescale 1ns/10ps表示为时间单位为 1ns,时间精度为 10ps。如果把此指令定义在例 2-1 和例 2-5 模块之上,则表示为二选一选择器的输入输出延时为 2ns,抖动在 10ps 之内。该指令需要在模块描述前就定义。Verilog HDL 没有缺省的时间单位。如果没有显式定义,Verilog HDL 的仿真器会假设一个时间单位。时延不仅仅可以定义信号的输入与输出之间的逻辑延时。同时,针对信号跳变此时延只能用于模拟,不能被综合。2.5 行为级描述GRADUATION THESIS2.5 行为级描

23、述数字电路有两类基本逻辑电路,一类是组合逻辑电路,一类是时序逻辑电路。数据流描述只能用来描述组合逻辑电路。而要描述时序逻辑,需要采用行为级描述。采用行为级描述的 Verilog HDL 模块不会包含内部的结构细节,它用抽象、算法描述的方式简单定义硬件行为。Verilog HDL 中有两种行为级建模机制:initial 语句和 always 语句。一个模块可以包含一个或者多个 initial 语句和 always 语句。这些语句在 0 时刻不论先后顺序并发执行。一个initial 语句或者 always 语句中可能只有一条语句,也可能有多条语句,多条语句需要采用beginend 或者 forkj

24、oin 等限定符来进行限定。2.5 行为级描述initial 语句中所有的语句构成 initial 语句块。Initial 语句在模拟时刻 0 就可以执行,并且只能执行一次,语句块内的语句顺序执行。initial 语句通常用来生成波形以及信号的初始化。用符号“#”来控制语句的执行或者对变量进行赋值。其基本语法结构是:initial#time procedural_statement;其 中#time 为 可 选 项,如 果 没 有 显 示,意 思 是 仿 真 从 时 刻 0 立 即 开 始 执 行procedual_statement 过程语句或者过程语句块。过程语句可以是单条语句,也可以是多

25、条语句组成的语句块,包括阻塞和非阻塞语句、wait 语句、case 语句、条件语句、循环语句、并发语句块、时序语句块以及过程连续赋值语句等。2.5.1 initial 语句语句2.5 行为级描述【例 2-10】initial 赋值示例reg rst_n;reg clk;.initial begin rst_n=1b0;#10 rst_n=1b1;#1000$finish;end initial begin clk=1b0;forever#2 clk=clk;end此例含有两个 initial 语句,分别对 rst_n 信号变量进行赋值和生成时钟信号。两个 initial语句并行执行,都是从模拟

26、时刻 0 开始执行。在第一个 initial 语句块中,时刻 0 给 rst_n 信号变量赋值 0,然后等待 10 个时间单位,给 rst_n 信号变量置位,接着等待 1000 个时间单位,结束仿真。$finish 是仿真结束关键词,执行到此语句时,仿真窗口关闭,仿真结束。第二个 initial 语句用于生成一个周期为 4 个时间单位的时钟信号。注意:在应用关键词 forever生成时钟信号之前,必须对时钟信号进行初始化,可以是 0 或者 1。否则时钟信号永远是未定状态,模拟波形为 x。2.5 行为级描述 在模块中,initial 语句只能顺序执行一次,因此适合信号和值序列初始化。但现实世界更

27、多的是各种重复事件。always 语句可以很好的解决此问题,只要敏感事件一直有效,always语句块就会一直执行。与 initial 语句从模拟时刻 0 开始运行不同,always 语句需要触发敏感事件才会执行。因此 always 语句不仅可以用于模拟,同时也可以被综合,生成具体的逻辑电路。2.5.2 always 语句语句 always 的基本语法是:always(event1 or event2 or.)procedural_statement;procedural_statement_block;关键词 always 后的(event1 or event2 or)用来表示敏感事件,敏感事

28、件后会有过程状态和过程状态块的执行。所有过程状态和过程状态块中被赋值的信号变量必须采用关键词“reg”声明其类型。多个敏感事件采用关键词“or”来连接。在 Verilog136-2001 及后续版本中,关键词“or”也可以用“,”替代。敏感事件可以是电平事件,也可以是边沿事件,但多个敏感事件同时存在时,敏感事件类型必须是相同类型要么全部是电平事件,要么全部是边沿事件。当然,也存在没有敏感事件的情况如例 2-11,采用 always 语句生成时钟信号。2.5 行为级描述【例 2-11】采用 always 语句生成周期为 4 的时钟信号module clk_gen(clk);output reg

29、clk;initial clk=0;/initial the clk to be logic 0always#2 clk=clk;/toggle clock every 2 time unitsendmodule注意:当无敏感信号时,需要有一定的时序控制结合在一起才能使用。如例 2-11 中,如果把#2 去掉,则这个 always 语句生成一个 0 时延的无限循环跳变信号,将直接导致放置死锁。敏感事件可以是单个事件,也可以多个事件的组合。当敏感事件为电平事件时,如果能够综合,通常生成的是组合逻辑或者锁存器。当敏感事件为边沿事件时,生成的是时序逻辑或者锁存器。2.5 行为级描述【例 2-12】把

30、例 2-5 数据流描述的二选一选择器修改为 always 语句实现的选择器module mux2to1(input s,/输入选择控制信号input a,/输入信号input b,/输入信号output out/输出信号);reg out;/采用 always 语句实现二选一选择器/asssign out#2=s?a:b;always(s or a or b)out#2=s?a:b;endmodule 图 2-8 为综合后生成的门级电路,可以很清晰地看出,该代码和数据流描述的功能完全一样。注意:由于敏感信号为电平事件,生成选择器时,采用的是阻塞赋值“=”,而不是非阻塞赋值“=”。2.5 行为级

31、描述always 语句也可以生成锁存器。如例 2-13 所示。与例 2-12 相比,敏感事件都是电平事件,而且均是采用阻塞赋值,不同的是例 2-12 采用的完整的条件赋值语句,而例 2-13 的第12 行存在一个不完整的条件赋值语句,因而生成了一个锁存器。锁存器生成方式有许多种,并且很多情况都是隐藏得比较深。大多数锁存器都是设计中不愿看到的情形。在进行CPLD/FPGA 代码设计时一定要特别小心。当敏感事件为边沿事件时,一般会生成时序逻辑除非有如例 2-13 中存在的不完整条件赋值语句出现。2.5 行为级描述【例 2-13】always 语句生成锁存器示例module dlatch(input

32、 rst,input enable,input d,output reg q);always(rst,enable,d)begin if(rst)q=0;else if(enable)q=d;end endmodule2.5 行为级描述例 2-14 为采用触发器的二选一选择器。从综合后生成的门级电路可以看出,整个电路是例 2-12 生成的二选一选择器的输出后再接一级 D 触发器。要生成一个能够被综合的 D 触发器,需要注意:1.在整个 always 语句的敏感事件列表中,有且只有一个时钟事件以及一个复位或者置位边沿事件(复位和置位事件不在敏感事件列表中同步复位/置位;复位和置位事件在敏感事件列

33、表中异步复位/置位;)2.整个边沿触发器中,存在的一个条件赋值语句,关键词“if”作为高优先级,通常用来对 D 触发器进行置位或者复位3.关键词“else”作为低优先级,用来定义连接到 D 触发器的电路逻辑。本例的电路逻辑为一个二选一的选择器。2.5 行为级描述 当敏感事件列表存在多个电平敏感事件的时候,编写敏感列表容易出错且分繁琐,可以采用“*”或者“(*)”来表示整个的敏感事件列表,其表示整个 always 语句块中所有的输入变量都是敏感的。例 2-15 就是把例 1-1 的一位全加器的敏感列表采用“*”代替的结果。【例 2-15】*操作符的应用module fadder(a,b,cin,

34、cout,sum);input a,b,cin;output cout,sum;reg cout,sum;CPLD/FPGA 设计与应用基础教程30always*begin sum=a+b+cin;cout=(a&b)|(b&cin)|(a&cin);endendmodule2.5 行为级描述和数据流的时延控制不同,行为级的时序控制可以采用多种方式来表示,包括在数据流描述中采用的“#”方式的时延控制,同时还有基于事件的时间控制。采用“#”方式的时延控制,其基本格式为:#time Destination=Drive_Source;或者Destination=#time Drive_Source;

35、其中,第一条语句表示是语句间时延,第二条语句表示是语句内时延。两个语句的物理意义不太一样。2.5.3 时序控制时序控制【例 2-16】采用“#”方式的时延控制initial begin rst_n=1b0;in=1b0;#10 rst_n=1b1;in=#5 1b1;end例 2-16 分别采用了两种时延控制。一旦仿真开始,就立即对 rst_n 和 in 初始化为 0。等待 10 个时间单位后,再把 rst_n 信号置位,同时计算第 6 行的右边表达式的值,并把计算结果等待 5 个时间单位后,再赋值给 in。由上可知,语句间时延主要是描述信号的时序变化,语句内时延主要是描述元器件输入输出的信号

36、时延。2.5 行为级描述当然,时延有多种表现形式,不一定是常量表示,也可以采用参数定义或者表达式定义,这样的优势在于可以通过修改参数值或者表达式值就可以影响到时延,不容易出错。如例2-17 所示。【例 2-17】采用参数化定义时延parameter DELAY=10;parameter PERIOD=6;initial begin clk=1b0;rst_n=1b0;#DELAY rst_n=1b1;endalways#(PERIOD/2)clk=clk;事件控制分别为边沿事件时序控制和电平事件时序控制两类。边沿事件时序控制采用关键词“”来表示,电平事件时序控制采用关键词“”或 wait 语句

37、来执行。边沿事件一般有两类:上升沿采用关键词“posedge”表示,下降沿采用关键词“negedge”表示。在 Verilog HDL 中,信号表示为 4 态:0、1、x 和 z 态。上升沿和下降沿出现的情形主要有如下表所示:2.5 行为级描述边沿事件时序控制的基本格式如下:edge_event procedural_statement;或者Destination=edge_event Drive source;前者表示语句间边沿事件时序控制,强调在边沿事件触发下发生的事件;后者表示语句内边沿事件时序控制,强调组件的输入和输出在边沿事件下的控制。【例 2-18】边沿事件时序控制示例initia

38、l begin(posedge clk)out=in1&in2;end initial q_out=(negedge clk)in1&in2;2.5 行为级描述例 2-18 中,一旦开始模拟,就会一直等待 clk 的边沿的出现。一旦第一个 clk 的上升沿出现,第一个 initial 语句中的执行语句触发,开始计算 in1&in2 的值并立即把计算结果传送给out。一旦第一个clk的下降沿出现,第二个initial语句中的执行语句触发,开始计算in1&in2的值并立即把计算结果传送给 q_out。在边沿事件触发前,out 和 q_out 都是处于 x 状态。边沿事件时序控制可以不止一个,可以有

39、多个,采用“or”或者“,”来连接多个敏感事件。电平事件时序控制采用关键词或 wait 语句来表示,其基本格式如下:event Procedural_statement;或者wait(condition)Procedural_statement;前者表示当 event 为真,才开始执行 Procedural_statement。后者表示当 condition,也就是电平事件为真时,就开始执行 Procedural_statement。否则一直等待 condition。2.5 行为级描述【例 2-19】电平敏感时序控制示例initial begin in1=1b0;in2=1b0;#10 in1

40、=1b1;#10 in2=1b1;#100$finish;endinitial begin(in1 or in2)out=data;wait(in1&in2)q_out=data;end例 2-19 中,模拟一旦开始,首先初始化 in1 和 in2,然后等待 5 个时间单位,对 in1 置位,再等待 10 个时间单位,对 in2 置位,并延续 100 个时间单位直达仿真结束。第二个 initial语句一直监视第一个 initial 语句中的信号变化,一旦 in1 和 in2 任何一个为 1 时,触发语句,从而立即把 data 值传送给 out,这个时间首先出现在模拟开始后第 5 个时间单位。一

41、旦in1和 in2同时为 1,wait 语句后的条件为真,从而立即计算data值并把计算结果传送给 q_out,这个时间出现在模拟开始后第 15 个时间单位。2.6 结构体描述GRADUATION THESIS2.6 结构体描述结构化描述主要由三种设计对象的实例来组成:内建原语(built_in primitive)用户自定义原语(UDP,User-Defined Primitives)设计模块(module)结构化描述就是对这三种设计对象进行例化(instantiation)。例化是指把包含内建原语在内的低层次模块用联机连接在一起,组成更高层次的模块,完成结构化建模的全过程。被例化的对象称之

42、为实例(instance)。2.6 结构体描述Verilog HDL 有丰富的内建门级原语用于建模电路网表。每个门的输出声明为 wire 型,输入可以是 wire 型或 reg 型。采用门级描述更像是画电路图电路图中的每个逻辑门和Verilog HDL 内建门级原语之间有紧密的对应关系2.6.1 门级建模及描述门级建模及描述内置门级原语包含如下基本门。1.多输入门:and、nand、or、nor、xor、xnor2.多输出门:buf、not3.三态门:bufif0、bufif1、notif0、notif14.上拉、下拉电阻:pullup、pulldown5.MOS 开关:cmos、nmos、p

43、mos、rcmos、rnmos、rpmos6.双向开关:tran、transif0、transif1、rtran、rtranif0、rtranif1本章着重讲述结构体建模,也就是门级应用,对于每个基本门的具体介绍,将在后续章节进行2.6 结构体描述门级原语例化的基本格式如下:Gate_type instance_name(term1,term2,termN);当例化两个或者两个以上相同类型的门实例时,可以采用如下格式:Gate_type inst1(term1_1,term1_2,term1_N),inst2(term2_1,term2_2,term2_N),instm(termm_1,ter

44、mm_2,termm_N);其中,小括号里面的端口根据门的类型而有所不同。如多输入门,第一个参数为输出端口,其余都为输入端口;多输出门,前 N-1 个为输出端口,第 N 个端口为输入端口。在描述三态门时,第一个参数为输出端口,第二个参数为输入端口,第三个参数为控制输入端口,等等。如例 2-20 所示:2.6 结构体描述【例 2-20】各个门级原语例化示例xor u_xor(out,in1,in2,in3);/三输入的异或门,输出为 outbuf buf1(out1,out2,out3,out4,clk);/输入为 clk 的四输出的缓冲器notif0 nf0(out,in,enable);/如

45、果 enable 为高,out 输出为高阻,如果为低,则把 in 取反传给 outpullup pup(pwr);/只有输出,没有输入pmos p0(out,in,control);/如果 control 为高,out 输出为高阻,如果为低,把 in 输出给 outcmos cm(out,in,nc,pc);/此描述为 CMOS 门,nc 和 pc 分别表示 NMOS 控制和 PMOS 控制tran tr0(signalA,signalB);/两信号无条件双向流动transif0 tr1(signalA,signalB,control);/control 信号为 0 是,signalA 和 s

46、ignalB 双向流动,否则断开2.6 结构体描述【例 2-21】使用门级建模设计二-四译码器module dec2to4(input a,b,en,output 3:0 Z);wire Abar,Bbar;not#(2,3)V0(Abar,a);not#(2,3)V1(Bbar,b);nand#(3,4)ND0(Z0,Abar,Bbar,en);nand#(3,4)ND1(Z1,Abar,b,en);nand#(3,4)ND2(Z2,a,Bbar,en);nand#(3,4)ND3(Z3,a,b,en);endmodule例 2-21 采用了两种门级原语例化,not 以及三输入 nan 原语

47、。这两种原语均可以被综合成逻辑网表。注意:有些原语只能用于模拟,不能用于综合。在例 2-21 中,每个门级原语例化都采用了显式时延。在现实世界中,所有的门都有传播时延(Propagation Delay)信号从输入端口(输入引脚)穿过所有内部电路到达输出端口(引脚)的时间。默认时延为 0。门时延的基本格式如下:Gate_type delay instance_name(term list);其中delay和instance_name为可选项。2.6 结构体描述门时延有四种类型:上升时延、下降时延、截止时延以及转换到 x 的时延。各种类型的时延如例 2-22 所示【例 2-22】各种门时延举例x

48、or u_xor(out,in1,in2);/零时延xor#6 u_xor(out,in1,in2);/所有时延均为 6xor#(6,8)u_xor(out,in1,in2);/上升时延为 6,下降时延为 8,转换到 x 的时延为者最小值 6notif0#(6,7,8)u_xor(out,in1,in2);/上升时延为 6,下降时延为 7,截止时延为 8,转换到 x 的时延为,三者最小值 6如前面数据流描述中所说到的一样,每种时延类型都可以有最小值、最大值和典型值。2.6 结构体描述三个时延的表现形式如下:最小值:典型值:最大值如:xor#(6:7:8),(4:5:6)u_xor(out,in

49、1,in2);表示该器件的上升时间最小值为 6,最大值为 8,典型值为 7 个时间单位,下降时间最小值为 4,最大值为 6,典型值为 7 个时间单位。又如:xor#(6:7:8,4:5:6)u_xor(out,in1,in2);该语句和上一个门级例化语句很像。主要是用来模拟时选择使用哪种时延作为选项。例如,如果执行最小时延仿真,该异或门单元使用上升时延 6 和下降时延 42.6 结构体描述2.6.2 用户定义原语(用户定义原语(UDP)除了内建原语,Verilog HDL 还支持使用者根据自己的需求设计自定义原语。通常,UDP的逻辑功能要比内建原语的层次要高一些。它们是独立的原语,不对其他原语

50、或模块进行例化。UDP 在模块中被例化的方式和内建原语的方式一样。UDP 需要定义在对其例化的模块之外。UDP 有两种:组合逻辑 UDP 和时序逻辑 UDP。UDP 的语法和模块很相似。整个 UDP 模块由关键词“primitive”开始,结束于“endprimitive”。在 primitive 之后紧跟着 UDP 名称以及输入输出端口列表。端口列表后将对端口信号类型进行声明主要有两类端口:输入端口 input 和输出端口 output,不支持双向端口 inout。如果是时序逻辑 UDP,输出端口还需要被声明为 reg 类型。UDP 可以有多个标量输入,只有一个标量输出。在 UDP 表内,是

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 大学
版权提示 | 免责声明

1,本文(《CPLD FPGA设计与应用基础教程》课件第二章.ppt)为本站会员(momomo)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|