verilog 判断上升沿怎么将一个边沿触发信号的上升沿作为控制变量

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
Verilog语言入门1要点.ppt 79页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:350 &&
Verilog语言入门1要点
你可能关注的文档:
··········
··········
时序模块及其Verilog表述
异步复位型锁存器及其Verilog表述
RST=0时,不管CLK是何种状态,Q即刻被清0。
RST=1时,CLK=1时,Q随D的变化而变化,CLK=0时,Q保持CLK=1时的值。
时序模块及其Verilog表述
Verilog的时钟过程表述的特点和规律
1)敏感信号表含有negedge和posedge时,选择性地改变敏感信号的放置是可以影响综合结果的,例如,同步复位型触发器和异步复位型触发器;
2)敏感信号表中一旦含有negedge或posedge的边沿敏感信号后,所有其他电平敏感型信号都不能放在敏感信号表中; 3)如果在同一模块中含有独立于主时钟的时序或组合逻辑,必须在另一过程描述。
时序模块及其Verilog表述
Verilog的时钟过程表述的特点和规律
对于边沿触发型时序电路,遵循以下规律: 1)如果将信号定义为边沿敏感信号,则必须在敏感信号表中用negedge或posedge给出表述, 但在always@过程结构中不能再出现该信号了,例如,时钟触发器时钟CLK。 2)如果一个对应于时钟的电平敏感的异步控制信号,则除了在敏感信号表中给出对应的表述外,在always@过程结构中必须明示这一信号的逻辑功能,如异步RST。 3)如果一个信号是对应于时钟的同步控制信号,则不允许在敏感信号表中出现,如同步RST。 4)敏感信号分为两种类型:电平敏感信号和边沿敏感信号,在同一过程的敏感信号表中,只能放置一种敏感信号,不能混放。 3.2
时序模块及其Verilog表述
异步时序模块的Verilog表述
时序模块及其Verilog表述
异步时序模块的Verilog表述
module AMOD(D,A,CLK,Q);
input D,A,CLK;
always@(posedge CLK)begin
Q1=~(A|Q);
always@(posedge Q1)begin
end endmodule 3.3
二进制计数器及其Verilog设计
4位二进制计数器及其Verilog表述
分析:最简单的4位二进制计数器应该有一个时钟输入CLK,4位二进制的计数值输出Q[3:0],每进入一个时钟,输出数据Q将增加1,随着时钟CLK的不断出现,计数值Q从循环输出值。
二进制计数器及其Verilog设计
4位二进制计数器及其Verilog表述
module CNT4(CLK,Q);
input CLK;
output [3:0] Q;
reg [3:0]Q1;
always@(posedge CLK)
assign Q=Q1; endmodule 3.3
二进制计数器及其Verilog设计
4位二进制计数器及其Verilog表述
二进制计数器及其Verilog设计
4位二进制计数器及其Verilog表述
二进制计数器及其Verilog设计
功能更全面的计数器设计
带有异步复位、同步使能和预置型十进制计数器。
输入输出分析:
输入信号包括时钟信号CLK、异步复位信号RST,同步使能信号EN,同步预置信号LOAD,预置数DATA[3:0]。
输出信号包括计数输出DOUT[3:0],计数溢出时的进位信号COUT。
逻辑功能分析:
1)异步复位:任意时刻,只要RST为0,计数器都有清0;
2)当RST=1、使能EN=1,且CLK上升沿到来时,当LOAD=0将DATA预置给计数输出值;LOAD为1时,计数器正常计数,当计数值为9时,COUT输出进位值1。 3.3
二进制计数器及其Verilog设计
功能更全面的计数器设计
二进制计数器及其Verilog设计
功能更全面的计数器设计
3.1 组合电路的Verilog描述
加法器及其Verilog描述
4. 算数操作符的使用 3.1 组合电路的Verilog描述
5. 全加器描述用半加器模块和或门模块描述
正在加载中,请稍后...查看: 3792|回复: 12
always中敏感信号可以双边沿触发吗?
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间0 小时
reg [15:0]
always@(posedge clk,negedge clk)begin
& & & & if(!rst_n)
& & & & & & & & cnt&=0;
& & & & else
& & & & & & & & cnt&=cnt+1;
上语句在QuartusII中报语法错误;
reg [15:0]
always@(clk)begin
& & & & if(!rst_n)
& & & & & & & & cnt&=0;
& & & & else
& & & & & & & & cnt&=cnt+1;
上语法个人理解clk发生变化触发敏感信号这与always@(posedge clk,negedge clk)在逻辑上是相通的啊!
其大牛正解!!!
想要对时钟进行双边沿触发主要有三种方法。
一种就是像楼上所说,使用电平敏感触发,能够实现时钟的双边沿触发,但是一般不推荐这种方法触发,这种方法虽然在逻辑上是可行的,但verilog终归不是C一样的高级语言,它的每段代码都需经过综合布线实现的,因此在用verilog实现算法的时候还需考虑代码书写风格的合理性,而对时钟信号使用电平触发,很有可能在某些情况下就不能满足时序。
第二种就是就是将上升沿和下降沿分成两个a ...
主题帖子精华
新手上路, 积分 21, 距离下一级还需 29 积分
在线时间0 小时
想要对时钟进行双边沿触发主要有三种方法。
一种就是像楼上所说,使用电平敏感触发,能够实现时钟的双边沿触发,但是一般不推荐这种方法触发,这种方法虽然在逻辑上是可行的,但verilog终归不是C一样的高级语言,它的每段代码都需经过综合布线实现的,因此在用verilog实现算法的时候还需考虑代码书写风格的合理性,而对时钟信号使用电平触发,很有可能在某些情况下就不能满足时序。
第二种就是就是将上升沿和下降沿分成两个always快来写,这样子写的缺点就是不能在两个always块中对同一个reg变量做操作,同时这样写总觉得会很蛋疼。
第三种就是利用pll将时钟信号延迟或者滞后180°,分别对上升沿触发,或者干脆将时钟倍频,这样子就不需要考虑太多了。
另外,对于频率不是很快的时钟信号或者是一些异步信号建议采用脉冲形式同步,也就是在一个足够快的时钟下(如50M),可以实时监测输入信号的电平,当两次相邻电平异或之后为1,就表示有上升沿或者下降沿(01表示有上升沿,10表示有下降沿),这样子的好处就是,你的所有模块都可以在同一个工作时钟下工作,而不会因为一些其他时钟信号或异步信号而将电路变成异步电路。
(以上有些是参考网上资料,有些是我实际操作的经验,还望采纳)
主题帖子精华
金钱116900
在线时间893 小时
帮顶。。。。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
当我早晨上网看到有人回我的帖子了,先是一激动。定眼一看是原子哥,顿时心里一凉,点进去一看果然“帮顶。。。”
开玩笑,原子哥莫介意啊!希望原子哥的M3板子越做越好!
主题帖子精华
金钱116900
在线时间893 小时
回复【3楼】a:
---------------------------------
这个我不懂,所以没办法。。。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 103, 距离下一级还需 97 积分
在线时间14 小时
回复【3楼】a:
---------------------------------
你语法错误吧!!
reg&[15:0]
&always@(posedge&clk&or&negedge&clk)begin
&&&&&&&&&if(!rst_n)
&&&&&&&&&&&&&&&&&cnt&=0;
&&&&&&&&&else
&&&&&&&&&&&&&&&&&cnt&=cnt+1;
&end
这样才行吧!
主题帖子精华
初级会员, 积分 136, 距离下一级还需 64 积分
在线时间5 小时
怎么不把报错内容贴上来??看看应该能看出来啊。。
程序的语法最好规范一下,数据写清楚位数,如
cnt&&=&16'd0&;
cnt&&=&cnt&+&1'b1&;
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间0 小时
回复【5楼】denike:
---------------------------------
&always@(posedge&clk&or&negedge&clk)begin&
&&&&&&&&&if(!rst_n)&
&&&&&&&&&&&&&&&&&cnt&=0;&
&&&&&&&&&else&
&&&&&&&&&&&&&&&&&cnt&=cnt+1;&
&end&
这样是个语法错误的!
&always@(clk&)begin&
&&&&&&&&&if(!rst_n)&
&&&&&&&&&&&&&&&&&cnt&=0;&
&&&&&&&&&else&
&&&&&&&&&&&&&&&&&cnt&=cnt+1;&
&end&
这样语法通过了,可是不知道是不是漏洞。在综合的时候会不会有问题。
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间0 小时
回复【6楼】tangkunjyy:
---------------------------------
就是想了解一下always@语句中的敏感信号触发的问题,我一般都不会这么写,这只是做测试写了一下。
最近在一本书上看到了这样的写法:
always@(clk&)begin&&
&&&&&&&&&if(!rst_n)&&
&&&&&&&&&&&&&&&&&cnt&=0;&&
&&&&&&&&&else&&
&&&&&&&&&&&&&&&&&cnt&=cnt+1;&&
&end&
以前一直以为不可能双边沿触发的,事实也是always@(posedge&clk&or&negedge&clk)这样的语句编译无法通过!
不理解always@(clk&)begin&这语句的具体含义
主题帖子精华
初级会员, 积分 103, 距离下一级还需 97 积分
在线时间14 小时
always@(clk&)begin&&这样就行了有变化就触发相当于上下降沿了。
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间0 小时
回复【10楼】随思远:
---------------------------------
多谢,讲的很好!
不过我求问过同事,他更我说了一种FPGA中的一个硬核也可以用于这种操作模式,也就是像DDR操作模式一样。不知道你知道吗?
主题帖子精华
高级会员, 积分 754, 距离下一级还需 246 积分
在线时间39 小时
大家都知道是硬體描述語言,你如果能畫的出來就可以理解.....
如果您畫不出來,,,...此技術與施主無緣,盡快放棄學習吧.....
主题帖子精华
新手上路, 积分 22, 距离下一级还需 28 积分
在线时间0 小时
回复【10楼】随思远:
---------------------------------
多谢,讲的很好!
不过我求问过同事,他更我说了 ...
这个问题我也遇到过,verilog不像VHDL可以实现同一信号不同边沿做敏感信号,所以简单点的方法是将敏感信号取反,再进入程序
Powered byVerilog HDL教程_学霸学习网
Verilog HDL教程
第二部分 硬件描述语言Verilogapjiang@ime.1 为什么要采用硬件描述语言(HDL)? 随着设计复杂性的提高,无法再用硬件直接 实现需要的功能,利用HDL可以提高描述的 抽象层次 ? 易于通过EDA工具完成工艺无关的设计,有 利于保证设计正确性和对设计进行管理 ? 便于对设计进行管理、归档和重用 ? 易于对设计进行修改,以探索不同的设计可 能性 ? 便于提高设计的效率 apjiang@ime. 2 硬件描述语言(HDL)的特点? 采用高级程序设计语言的结构,但与一 般软件程序设计语言有差别,它是针对 硬件系统与部件设计的。C 在不同的抽象层次上描述电路的功能和连接 关系,可以描述电路的结构 C 除了描述功能之外还描述时序关系 C 并行性:同时进行多个任务 C 时间:具有描述延迟等时间概念的能力 apjiang@ime. 3 常见的两种硬件描述语言? VHDL:VHSIC(very high-speed IC) hardware description language,得到美国 军方支持,1987年成为IEEE标准,1993 年进行修订。类似ADA语言。 ? Verilog:由民间发展起来,1995年成为 IEEE标准,2001年进行了修订。类似C语 言。 apjiang@ime. 4 Verilog语言的功能? 可以描述数字电子系统 ? 可以完成不同抽象层次的描述 ? 除了描述器件的功能外还可以建立比较 完整的模拟环境来验证设计的正确性, 也就是说设计和模拟都可以用Verilog完 成。 ? 用于测试 ? 用于设计文档管理 apjiang@ime. 5 Verilog语言的用途? ASIC和FPGA设计人员可以用来编写用 于综合的代码 ? 可以对系统建模,完成系统高层级仿真 ? 编写用于各级设计仿真的测试环境 ? 描述基本单元或更高级的部件apjiang@ime.6 Verilog在不同设计层次上的作用(1)? 行为级C 描述系统中数据在不同模块之间的传输 C 描述必要的操作? 寄存器传输级(RTL)C 描述系统中的数据流和功能模块之间和 内部的控制信号 C 按照定义的时钟周期建立模型apjiang@ime.7 Verilog在不同设计层次上的作用(2)? 门级(结构)C 描述底层单元之间的连接,可以更精确地 描述系统的行为 C 在进行综合时使用特定工艺库完成RTL到 门级的映射apjiang@ime.8 Verilog发展历史(1)? 1985年,Gateway Design Automation公 司为其仿真器产品开发了Verilog语 言。 ? 1989年,Cadence收购Gateway公司, 并继续推广该语言和仿真器。 ? 1990年,组织了OVI(Open Verilog International) ? 1993年,IEEE开始了Verilog的标准化
工作 apjiang@ime. 9 Verilog发展历史(1)? 1995年公布了IEEE
Verilog标 准 ? 2001年公布了IEEE
Verilog标 准,对IEEE
进行了修订apjiang@ime.10 Verilog举例(1)module muxtwo (out, a, b, sel); input a, b, // 输入端口说明 // 输出端口说明 always @( sel or a or b) if (!sel) out = else out = endmodule apjiang@ime. 11 Verilog举例(2)module twomux (out, a, b, sl); input a, b, not u1 (nsl, sl ); and #1 u2 (sela, a, nsl); and #1 u3 (selb, b, sl); or #2 u4 (out, sela, selb); endmodule apjiang@ime. 12 Verilog举例(3)`timescale 1ns/1 // declare reg data type for the // declare integer data type for the count initial // initialize things - this executes once at start begin clock = 0; count = 0; // initialize signals #340 $ // finish after 340 time ticks end /* an always statement to generate the clock, only one statement follows the always so we don't need a begin and an end */ apjiang@ime. 13 Verilog举例(3续1)always #10 clock = ~ // delay is set to half the clock cycle /* an always statement to do the counting, runs at the same time (concurrently) as the other always statement */ always begin // wait here until the clock goes from 1 to 0 @ (negedge clock); // now handle the counting if (count == 7) count = 0; apjiang@ime. 14 Verilog举例(3续2)else count = count + 1; $display(&time = &,$time,& count = &, count); end endmoduleapjiang@ime.15 例3的结果time = 20 count = time = 40 count = (... 12 lines omitted...) time = 300 count = time = 320 count = 1 2 7 0apjiang@ime.16 Verilog HDL结构框图module端口参数参数覆盖netvariable事件模块调用 过程块 连续赋值函数任务specify原语或UDP实体化inputoutputinoutwiretri tri0 tri1 supply0 supply1 triand trior trireg wand worreg integer real timerealtimeinitialalways赋值条件循环延迟控 事件触 制 发等待块任务 调用禁止 disableassign deassignforce release系统任务 调用阻塞非阻塞ifcaseforwhile repeatforever顺序块 并行块apjiang@ime.17 Verilog语言基础apjiang@ime.18 标识符(identifier)? ? ? ? 标识符是用户提供的一个描述目标的名称 最长1023个字符 标识符是大小写敏感的,所有的关键词是小写的 BNF表示 identifier ::= simple_identifier | escaped_identifier simple_identifier ::= [a-zA-Z_][a-zA-Z0-9_$] escaped_identifier ::=\{Any_ASCII_character_except_white_space} white_spacewhite_space ::= space | tab | newlineapjiang@ime.19 转义标识符? 转义标识符必须以反斜线开头,以空白 字符结尾 ? 转义标识符中可以包含任何可打印字符 ? 对转义标识符的支持可能因工具不同而 异apjiang@ime.20 简单标识符举例? 合法的标识符shift_reg_a busa_index _bus3? 不合法的标识符34net a*b_net n@238 apjiang@ime. 21 转义标识符举例\~#@sel \busa+index \{A,B} 最后必须用空白符(包括空格、制表符 Tab和换行符)结束。apjiang@ime.22 Verilog逻辑值? Verilog内采用四值逻辑,即0,1,x, z。 ? 0表示0,低电平,假,逻辑低,地等 ? 1表示1,高电平,真,逻辑高,电源等 ? x表示未被初始化的逻辑或未知逻辑值 (无法确定的逻辑)。 ? z表示高阻状态,没有驱动的线等。 apjiang@ime. 23 数字的表示(1)? 整数的表示 width'radix valueC width指明占用的二进制长度(可选),如果不指 明占用的长度和实现相关,通常可能是一个字长 C radix指明采用的基数(进制) ? 十进制 decimal ( d or D ) ? 十六进制 hex ( h or H ) ? 八进制 octal ( o or O ) ? 二进制binary ( b or B ) C value 是在相应基数下的值 apjiang@ime. 24 数字的表示(2)? 整数的表示举例 5’O42 4’D9 8’haB -6’b100_X1z 10’D-20 //错误 (2+4)’b011000 //错误 apjiang@ime. 25 数字的表示(3)? 实数的表示C 十进制表示 10.2 123.456 -34.5 C 科学计数法表示 23_5.1e2 // .2E6 // - 3E-2 // 0.03 apjiang@ime. 26 字符串? 使用双引号括起来的多个字符 ? 不能跨行 ? 其中可使用反斜线(\)对特殊字符进行转 义 ? 举例 “MESSAGE \n” “Finished \\” apjiang@ime. 27 Verilog数据类型? Verilog中的数据类型有两大类,即线网 (nets)和变量(variables),表示数据的存储 和传输元件。 ? 线网:表示器件之间的物理连接,不保存数据 值,由驱动元件决定起信号值 ? 变量:表示抽象存储元件 ? 线网和变量的定义中可以带有范围,形成向 量。当定义时没有指定范围时认为宽度是1的 标量。 apjiang@ime. 28 线网的种类? 线网需要被持续地驱动,驱动它的可以是门、 模块或逻辑等 ? 默认的初试值是 z ? 种类 wire, tri:标准的互连线,功能上相同 supply1, supply0:电源和地 wor, trior:通过线或连接的多个驱动 wand, triand:通过线与连接的多个驱动 trireg:有电容保存的线网 tri1, tri0:在不驱动时上拉或下拉的线网 apjiang@ime. 29 不同类型线网对逻辑冲突的处理apjiang@ime.30 线网的说明&net_ type& [range] [delay] &net_ name& [, net_ name]* net_ type 是线网的类型 range 是用[MSB: LSB]格式描述的向量范围, 一位的是标量,多位的是向量 delay 定义与该线网相关的延迟 net_ name 是线网的名称,一次可以定义多个 线网,中间用逗号分开 apjiang@ime. 31 变量类型? 保存原有的值直到赋予新的值 ? 种类 reg:数据保存元件的抽象,向量可以表示无符 号整数,初值是x integer:有符号32位整数变量,初值是x real:双精度带符号浮点数,初值是0.0 time:64位无符号整数变量,初值是x realtime:与real内容一致,但可以被用做描述 仿真的时间,初值是0.0 apjiang@ime. 32 变量说明? reg [signed][range] reg_name(变量标识符列表) C range 是向量范围,只对 reg 类型有效,一位 的是标量,多位的是向量 C reg_name是寄存器的名称,一次可以定义多 个寄存器,中间用逗号分开 ? integer 变量标识符列表 ? real 变量标识符列表 ? time 变量标识符列表 ? realtime 变量标识符列表 apjiang@ime. 33 举例(1) // A sc // A scalar net of type &wand& reg [3: 0] // A 4- bit vector register from //msb to lsb reg [7: 0] m, // Two 8- bit registers tri [15: 0] // A 16- bit tri- state bus wire [0: 31] w1, w2; /* Two 32- bit wires with msb = bit 0 */ apjiang@ime. 34 举例(2)module declarations_1; wire pwr_good, pwr_on, pwr_ // Explicitly declare wires. // 32-bit, signed (2's complement). // 64-bit, unsigned, behaves like a 64-bit reg. // Declare an event data type. // Real data type of implementation defined size. // An assign statement continuously drives a wire: assign pwr_stable = 1'b1; assign pwr_on = 1; // 1 or 1'b1 assign pwr_good = pwr_on & pwr_ apjiang@ime. 35 举例(2续)initial begin i = 123.456; // There must be a digit on either side r = ; // of the decimal point if it is present. t = ; // Time is rounded to 1 second by default. $display(&i=%0g&,i,& t=%6.2f&,t,& r=%f&,r); #2 $display(&TIME=%0d&,$time,& ON=&,pwr_on, & STABLE=&,pwr_stable,& GOOD=&,pwr_good); $ end endmoduleapjiang@ime.36 例2的输出i=123 t=123.00 r=123.456000 TIME=2 ON=1 STABLE=1 GOOD=1apjiang@ime.37 举例(3)module declarations_2; reg Q, C wire D; assign D = 1; // 对 wire D 的赋值 // 下面的过程块是将 D 的值在时钟的上升边赋值给Q always @(posedge Clk) Q = D; initial Clk = 0; always #10 Clk = ~ C apjiang@ime. 38 举例(3续)initial begin #50; $ // 经过50个时间单位结束 end always begin $display(&T=%2g&, $time,& D=&,D,& Clk=&,Clk, & Q=&,Q); #10; end endmodule apjiang@ime. 39 例3的输出T= 0 D=z Clk=0 Q=x T=10 D=1 Clk=1 Q=x T=20 D=1 Clk=0 Q=1 T=30 D=1 Clk=1 Q=1 T=40 D=1 Clk=0 Q=1注意同步操作和事件之间的顺序对结果带来的影响!apjiang@ime.40 举例(4)module declarations_4; wire D // wire类型的标量 wire [31:0] ABus, DB // 两个32位的wire类型向量 reg [3:0] // 4位的reg类型向量 reg [4:7] // 4位的reg类型向量 initial begin i = 1; vector = ‘b1010; // 向量赋值 nibble = #1; $display(&T=%0g&,$time,& vector=&, vector,& nibble=&, nibble); apjiang@ime. 41 举例(4续)#2; $display(&T=%0g&,$time,& Bus=%b&,DBus[15:0]); end assign DBus [1] = 1; // 向量中的一位赋值 assign DBus [3:0] = ‘b1111; // 向量中的一部分赋值 endmoduleapjiang@ime.42 例4的输出T=1 vector=10 nibble=10 T=3 Bus=zzzzzzzzzzzz1111 %g对‘real’以指数或十进制形式中较短的方 式进行显示。 在%和指定基数的字符之间插入一个0可以 用最小尺寸显示(不按照显示的自动尺 寸约定)。 apjiang@ime. 43 数组(Array)? Verilog 中的线网或变量可以构成数组 ? 数组元素可以是标量或向量 ? 数组的赋值只能对其中的一个元素进行,不能同时 对整个数组或其中的一部分段进行 ? 线网数组可以连接一组实体化模块的端口 ? 对各种变量都可以定义变量类型的数组 ? 在过去的标准(IEEE)中没有多维数组, 用一维数组可以定义寄存器阵列。新的标准 (IEEE)中可以定义多维数组。apjiang@ime.44 数组(续)? 一维数组定义reg 类型的阵列可以构成存储器,其格 式如下: reg [MSB: LSB] &memory_ name& [first_ addr: last_ addr]; MSB 和 LSB定义了存储器字的长度 memory_ name说明了存储器名 first_ addr 和 last_ addr 定义了占用的地址空间 在定义中可以使用参数 ? 其他的数组定义形式是类似的apjiang@ime.45 数组举例integer NUMS [7: 0]; //8个integer类型的变量构成的数组 time t_vals [3: 0]; // 4个time 类型的变量构成的数组 reg [15: 0] MEM [0: 1023]; // 1K x 16位存储器 reg [7: 0] PREP ['hFFFE: 'hFFFF]; // 2 x 8位存储器 parameter wordsize = 16; parameter memsize = 1024; reg [wordsize - 1: 0] MEM3 [memsize - 1: 0]; // 使用参数的定义 apjiang@ime. 46 数组举例(2)reg arrayb [7:0] [0:255]; // 定义的是一个二维数组,其中的数组元素是一位的reg wire w_array [7:0] [0:5]; // 定义元素是wire类型的二维数组 数组赋值: arrayb[3][5] = 1’b0; t_vals[2] = $apjiang@ime.47 参数? 参数不属于变量或线网,它们表示一些 常数,控制设计中使用的参数 ? 参数的定义是局部化的,只在本模块中 有效 ? 可以在任何使用文字数量的地方使用 ? 参数有两类,模块参数和specify参数 ? 模块参数可以在设计时进行调整 apjiang@ime. 48 参数的定义parameter &list_ of_ assignments& list_ of_ assignments 是用逗号隔开的 参数和它们的数值apjiang@ime.49 举例parameter cycle = 8, real_ constant = 2.039, x_ word = 16’bx, file = &/ usr1/ jdough/design/mem_ file. dat&;apjiang@ime.50 覆盖参数值? 通过 defparam 语句可以覆盖原来的参数 定义。defparam 语句需要在实体化的层 次结构中使用。 ? 在模块的实体调用时也可以改变参数。 不需要改变所有的参数,但次序必须正 确。apjiang@ime.51 覆盖参数值举例(1)module mod1( out, in1, in2); ... parameter p1 = 8, real_ constant = 2.039, x_ word = 16’bx, file = &/usr1/ jdough/design/mem_ file. dat&; ... e ... mod1 I1( out, in1, in2); defparam I1. p1 = 6, I1. file = &../ my_ mem. dat&; ... endmodule apjiang@ime. 52 覆盖参数值举例(2)module mod1( out, in1, in2); ... parameter p1 = 8, real_constant = 2.039, x_word = 16’bx, file = &/usr1/ jdough/design/mem_ file. dat&; ...
... mod1 #( 5, 3.0, 16’bx, &../ my_ mem. dat&) I1( out, in1, in2); ... endmodule apjiang@ime. 53 运算符apjiang@ime.54 运算符(Operators)? ? ? ? ? ? ? ? ?算术运算符(+,-,*,/,%) 关系运算符(&,&,&=,&=) 等式运算符(= =,!=,= = =,!= =) 逻辑运算符(&&,||,!) 条件运算符(?:) 位运算符(~,|,^,&,~^,^~) 移位运算符(&&,&&) 拼接运算符({}) 赋值运算符(=,&=)apjiang@ime. 55 算术运算符(+,-,*,/,%)? ? ? ? ? +:加法(二元)或正值(一元) -:减法(二元)或负值(一元) *:乘法 /:除法 %:模apjiang@ime.56 举例:module arithops (); integer ans, parameter five = 5; reg [3: 0] rega, reg [3: 0] initial begin rega = 3; regb = 4'b1010; int = -3; endinitial fork #10 ans = five * // -15 #20 ans = (int + 5)/ 2; // 1 #30 ans = five/ // -1 #40 num = rega + // 1101 #50 num = rega + 1; // 0100 #60 num = // 1101 #70 num = regb % // 1 #80 $ join endmoduleapjiang@ime.57 关系运算符(&,&,&=,&=)? ? ? ? &:大于 &:小于 &=:大于或等于 &=:小于或等于apjiang@ime.58 举例:module relationals (); reg [3: 0] rega, regb, initial begin rega = 4'b0011; regb = 4'b1010; regc = 4'b0x10; endinitial fork #10 val = regc & // val = x #20 val = regb & // val = 0 #30 val = regb &= // val = 1 #40 val = regb & // val = 1 #50 $ join endmoduleapjiang@ime.59 等式运算符(= =,!=,= = =,!= =)? ? ? ? = =:逻辑相等 !=:逻辑不等 = = =:全等(对x和z严格按位比较) != =:非全等? 说明apjiang@ime.60 = = 与 = = = 的差别apjiang@ime.61 举例1:module equalities1(); reg [3: 0] rega, regb, initial begin rega = 4'b0011; regb = 4'b1010; regc = 4'b1x10; end initial fork #10 val = rega == #20 val = rega != #30 val = regb != #40 val = regc == #50 $ join endmoduleapjiang@ime.// val = 0 // val = 1 // val = x // val = x62 举例2:module equalities2(); reg [3: 0] rega, regb, initial begin rega = 4'b0011; regb = 4'b1010; regc = 4'b1x10; end initial fork #10 val = rega === // val = 0 #20 val = rega !== // val = 1 #30 val = regb === // val = 0 #40 val = regc === // val = 1 #50 $ join endmoduleapjiang@ime.63 逻辑运算符(&&,||,!)? &&:逻辑与 ? ||:逻辑或 ? !:逻辑非apjiang@ime.64 举例:module logical (); parameter five = 5; reg [3:0] rega, regb, initial begin rega = 4'b0011; regb = 4'b10 regc = 4'b0z0x; endinitial fork #10 ans = rega && 0; // ans = 0 #20 ans = rega || 0; // ans = 1 #30 ans = rega && // ans = 1 #40 ans = regb && // ans = 1 #50 ans = regc || 0; // ans = X #60 $ join endmoduleapjiang@ime.65 条件运算符(?:)? 表达式为: &LHS& = &condition& ? &true_ expression& : &false_ expression& 表达的含义是: “if condition is TRUE, then LHS = true_ expression , else LHS = false_ expression ”apjiang@ime.66 举例(1):module likebufif( in, en, out); assign out = (en == 1) ? in : ' endmoduleapjiang@ime.67 举例(2): module like4to1( a, b, c, d, sel, out); input a, b, c, input [1: 0] assign out = sel == 2'b00 ? a : sel == 2'b01 ? b : sel == 2'b10 ? c : endmoduleapjiang@ime.68 位运算符(~,|,^,&, ~^,^~)? ? ? ? ? ? ~:not &:and |:or ^ :xor ~^ :xnor ^~ :xnorapjiang@ime. 69 ? 举例module bitwise (); reg [3: 0] rega, regb, reg [3: 0] initial begin rega = 4'b1001; regb = 4'b1010; regc = 4'b11x0; end initial fork #10 num = rega & 0; #20 num = rega & #30 num = rega | #40 num = regb & #50 num = regb | #60 $ join endmodule apjiang@ime.// num = 0000 // num = 1000 // num = 1011 // num = 10x0 // num = 111070 一元缩减运算举例:module reduction(); reg [3: 0] rega, initial begin rega = 4'b0100; regb = 4'b1111; end initial fork #10 val = & // val = 0 #20 val = | // val = 1 #30 val = & // val = 1 #40 val = | // val = 1 #50 val = ^ // val = 1 #60 val = ^ // val = 0 #70 val = ~| // (nor) val = 0 #80 val = ~& // (nand) val = 1 #90 val = ^rega && & // val = 1 $ join endmoduleapjiang@ime. 71 移位运算符(&&,&&)? &&:左移 ? &&:右移apjiang@ime.72 举例module shift (); reg [9: 0] reg [7: 0] initial rega = 8'b; initial fork #10 num &= rega && 5 ; #20 num &= rega && 3; #30 $ join endmodule// num =
// num = apjiang@ime.73 拼接运算符({})? {}:将若干位构成新的向量 ? 可以嵌套复制apjiang@ime.74 举例1:
reg [7: 0] rega, regb, regc, reg [7: 0] initial begin rega = 8'b; regb = 8'b; regc = 8'b; regd = 8'b; end initial fork #10 new = {regc[ 4: 3], regd[ 7: 5], regb[ 2], rega[ 1: 0]}; // new = 8'b $ join endmodule apjiang@ime. 75 举例2 module replicate (); reg [3: 0] reg [1: 0] regb, reg [7: 0] initial begin rega = 4’b1001; regb = 2'b11; regc = 2'b00; end initial fork #10 bus &= {4{regb}}; // bus = , regb 重复4次 #20 bus &= { {2{regb}}, {2{regc}} }; // bus = . #30 bus &= { {4{rega[3]}}, rega }; // bus = . #40 $ join endmodule apjiang@ime. 76 运算的优先级apjiang@ime.77 Verilog的层次结构apjiang@ime.78 module? module是Verilog中的基本单位 ? 一个module可以是一个物理模块,一个逻辑 模块或一个完整的系统 ? BNF表达式 &module& ::= module &name_of_module& &list_of_ports&? ; &module_item&* endmodule apjiang@ime. 79 port? 模块通过port与外界进行通讯,它们对应于硬 件的端口 ? port的种类:in,out,inout ? 可选的类型:C in:输入端口可以被net或variable驱动(模块外 部);它只能驱动net(模块内部),也就是在端 口信号的定义中只能用net C out:输出端口可以被net或variable驱动(模块内 部),也就是在信号类型定义时可以用net或 variable;它只能驱动net (模块外部) C inout:双向端口只能被net驱动,也只能驱动net apjiang@ime. 80 Port与驱动的信号类型input net net/variable net output net/variable netinoutnetapjiang@ime.81 模块的实体化? 必须有实体名 ? 端口信号的映射可以有两种: C 按位置映射:次序与模块说明时端口次序 相同 C 按名映射:与位置无关,通过指定端口的 内部名和外部名建立联系,格式为: .internal_ port_ name( external_ name_ of_ signal_ connected_ to_ port) ? 可以存在没有连接的端口,但可能产生警告 信息 apjiang@ime. 82 模块实体化举例module comp (o1, o2, i1, i2); output o1, o2; input i1, i2; ... e comp c1 (Q, R, J, K); // 按位置映射 comp c2 (. i2( K),. o1( Q),. o2( R),. i1( J)); // 按名映射 comp c3 (Q,, J, K); // 按位置映射,有一个端口未连接 comp c4 (. i1( J),. o1( Q)); //按名映射,2个端口未连接 endmodule apjiang@ime. 83 模块实体化举例(2)―闹钟`timescale 100s/1s // 时间单位100秒,精度1秒 wire [3:0] wire wake_7am, wake_8 // 分别表示工作日7点和周末8点启动闹铃 assign n = 1 + (days % 7); // 表示星期一到星期日 always @(wake_8am or wake_7am) $display(&Day=&,n,& hours=%0d &,($time/36)%24, & 8am = &, wake_8am,& 7am = &,wake_7am, & m2.weekday = &, m2.weekday); initial days = 0; apjiang@ime. 84 模块实体化举例 (2)―闹钟(续1)initial begin #(24*36*10); $ end // 控制仿真时间为10天 always #(24*36) days = days + 1; // 每过24小时日期加1 rest m1(n, wake_8am); /* 模块实体化,模块名为rest,实体名为m1,按位置 映射端口 */ work m2(.weekday(wake_7am), .day(n)); /* 模块实体化,模块名为work,实体名为m2,按端口 名映射端口 */ endmodule apjiang@ime. 85 模块实体化举例 (2)―闹钟(续2)module rest(day, weekend); // 判断是否周末 input [3:0] always begin #36 weekend = day & 5; end // Need a delay here. endmodule module work(day, weekday); // 判断是否工作日 input [3:0] always begin #36 weekday = day & 6; end // Need a delay here. endmodule apjiang@ime. 86 模块实体化举例 (2)―闹钟运行结果Day= 1 hours=0 Day= 1 hours=1 Day= 6 hours=1 Day= 1 hours=1 8am = 0 8am = 0 8am = 1 8am = 0 7am = 0 7am = 1 7am = 0 7am = 1 m2.weekday = 0 m2.weekday = 1 m2.weekday = 0 m2.weekday = 1apjiang@ime.87 实体化阵列? 在实体名后指定一个范围可以实现一组 实体化。格式为:&name& &instance_ name& &range& (& ports&);? 产生的实体名与按位访问的向量类似 ? 每个实体名只能对应一个范围值 ? 如果范围的上下限相同,只产生一个实 体 apjiang@ime. 88 实体化阵列举例(1)wire [2:0] out, buf b[2:0] (out, in) 产生的实体如下: buf b[2] (out[2], in[2]); buf b[1] (out[1], in[1]); buf b[0] (out[0], in[0]); apjiang@ime. 89 实体化阵列举例(2)以下两个模块的作用相同 module driver (in, out, en); input [2: 0] output [2: 0] bufif0 u[2: 0] (out, in, en); // array of buffers endmodule module driver_ equiv (in, out, en); input [2: 0] output [2: 0] // Each primitive instantiation is done separately bufif0 u2 (out[2], in[2], en); bufif0 u1 (out[1], in[1], en); bufif0 u0 (out[0], in[0], en); endmodule apjiang@ime. 90 实体化阵列举例(3) wire y1, a1, b1; wire [3: 0] a2, b2, y2, a3, b3, y3; comp u1 [5: 5] (y1, a1, b1); // One instance of comp comp m1 [0: 3] (y2, a2, b2); comp m1 [4: 7] (y3, a3, b3); // Illegal! endmoduleapjiang@ime.91 行为建模与赋值过程与赋值apjiang@ime.92 行为建模的目的? 在较高抽象层次上描述系统的行为或功 能,可以完成和具体实现无关的描述 ? 行为建模是通过描述若干并行的活动过 程块完成的 ? 在描述中可以使用高级编程语言结构, 如wait, while, if else, case和 forever等apjiang@ime.93 过程块(Procedural Blocks)? 过程块是行为建模的基础 ? 有两种过程块C initial 过程块:只执行一次 C always 过模块:反复执行? 过程块可以包含如下内容:C 过程赋值:描述块内的数据流 C 高级结构(循环,条件):描述块的功能 C 时间控制:控制块中语句的执行情况 apjiang@ime. 94 赋值apjiang@ime.95 赋值? 过程赋值(包括过程持续赋值) ? 持续赋值apjiang@ime.96 过程赋值? 过程赋值:在过程块内的赋值 ? 过程赋值针对variable类型的数据 ? 要赋予的值可以是任何合法的表达式 ? 过程赋值可以分成:C 阻塞赋值:赋值操作在下一个顺序语句完成调度之 前执行 C 非阻塞赋值:模拟器读入一条赋值语句并对它进行 调度后就可以处理下一条语句apjiang@ime.97 阻塞过程赋值举例(=)module adder (out, a, b, cin); input a, b, output [1: 0] wire a, b, reg half_ sum, half_ reg [1: 0] always @( a or b or cin) begin half_ sum = a ^ b ^ // OK half_ carry = a & b | a & !b & cin | !a & b & out = {half_ carry, half_ sum} ; // 半加和与进位 end endmodule apjiang@ime. 98 非阻塞过程赋值举例(&=)module swap_ reg a, b, initial begin a = 0; b = 1; clk = 0; end always #5 clk = ~ always @( posedge clk) begin a &= // 非阻塞过程赋值 b &= // 交换a 和 b的值 end endmodule apjiang@ime. 99 非阻塞过程赋值举例(2)module non_ block1; reg a, b, c, d, e, initial begin // 阻塞赋值 a = #10 1; // time 10 b = #2 0; // time 12 c = #4 1; // time 16 end initial begin // 非阻塞赋值 d &= #10 1; // time 10 e &= #2 0; // time 2 f &= #4 1; // time 4 end initial begin $monitor($time,& a= %b b= %b c= %b &,a, b, c, “ d= %b e= %b f= %b”, d, e, f); #100 $ end endmodule apjiang@ime. 100 上例的结果0 a= x b= x c= x d= x e= x f= x 2 a= x b= x c= x d= x e= 0 f= x 4 a= x b= x c= x d= x e= 0 f= 1 10 a= 1 b= x c= x d= 1 e= 0 f= 1 12 a= 1 b= 0 c= x d= 1 e= 0 f= 1 16 a= 1 b= 0 c= 1 d= 1 e= 0 f= 1 apjiang@ime. 101 持续赋值(Continuous Assignment )? 持续赋值在过程块之外进行 ? 赋值对象是线网(net) ? 采用的格式如下: &assign& [# delay] [strength] &net_ name& = &expression& C 当等号右边信号的表达式发生变化后经过 # delay 规定的延迟等号左边信号发生变化 ? 可以有隐式(implicit)和显式(explicit)两种赋值方 式 assign out = a & // 显式 wire inv = ~ // 隐式 apjiang@ime. 102 持续赋值举例(1)module assigns (o1, o2, eq, AND, OR, even, odd, one, SUM, COUT, a, b, in, sel, A, B, CIN); output [7: 0] o1, o2; output [31: 0] SUM; output eq, AND, OR, even, odd, one, COUT; input a, b, CIN; input [1: 0] input [7: 0] input [31: 0] A, B; wire [7: 0] #3 o2; // 定义中带有延迟 tri AND = a& b, OR = a| // 对两个线网的赋值 wire #10 eq = (a == b); // 带延迟的隐式赋值 apjiang@ime. 103 持续赋值举例(1续)wire [7: 0] (strong1, weak0) #( 3,5,2) o1 = // 带有信号驱动强度和延迟 assign o2[ 7: 4] = in[ 3: 0], o2[ 3: 0] = in[ 7: 4]; // 对向量中的一部分赋值 tri #5 even = ~^in, odd = ^ // 带有延迟的两个线网的赋值 wire one = 1’b1; // 用常量赋值 assign {COUT, SUM} = A + B + CIN ; // 对用连接运算结合起来的线网赋值 endmodule apjiang@ime. 104 持续赋值举例(2)module cond_ assigns (MUX1, MUX2, a, b, c, d); output MUX1, MUX2; input a, b, c, assign MUX1 = sel == 2'b00 ? a : sel == 2'b01 ? b : sel == 2'b10 ? c : tri1 MUX2 = sel == 0 ? a : ’bz, MUX2 = sel == 1 ? b : ’bz, MUX2 = sel == 2 ? c : ’bz, MUX2 = sel == 3 ? d : ’ /* 在任何时刻MUX2最多有一个非高阻驱动,无驱动 时上拉到1 */ endmodule apjiang@ime. 105 时间控制apjiang@ime.106 时间控制? 在verilog语言中时间控制可以分成三类C 简单延迟(# &delay&):延迟若干时间单位 C 边沿敏感时间控制(@(& signal&)):等待信号的 边沿,可以使用or指定几个变量 ? 正边沿:posedge ? 负边沿:negedge ? 任意边沿: C 电平敏感时间控制(wait(& expr&)):等待表达式 成立,如果表达式已经成立立即执行相应动作apjiang@ime.107 简单延迟举例module muxtwo (out, a, b, sl); input a, b, always @( sl or a or b) if (!sl) #10 out = // The delay from a to out is 10 time units else #12 out = // The delay from b to out is 12 time units endmoduleapjiang@ime.108 简单延迟举例(2)-使用参数module clock_ gen (clk); parameter cycle = 20; initial clk = 0; always #(cycle/2) clk = ~ endmodule apjiang@ime. 109 边沿时间控制举例module reg_adder (out, a, b, clk); input [2: 0] a, output [3: 0] reg [3: 0] reg [3: 0] always @( a or b) // 等待a或b的任意变化 #5 sum = a + always @( negedge clk) // 等待 clk 的下降边 out = endmodule apjiang@ime. 110 电平时间控制举例module latch_adder (out, a, b, enable); input [2: 0] a, output [3: 0] reg [3: 0] always @( a or b) begin wait (!enable) // 当enable为0时进行后面的加法 out = a + end endmodule apjiang@ime. 111 命名的事件(Named Events)? 命名的事件是一种可以在过程块中触发引起某 些活动的数据类型 ? 使用event进行说明 ? ? ? ? 必须先说明后引用 只能在定义它的模块中使用 不可综合 使用 -& 进行触发? 本身不具有数值 apjiang@ime. 112 命名的事件举例module add_ mult (out, a, b); input [2: 0] a, output [3: 0] reg [3: 0] event add, // 事件定义 always @ (a or b) if (a& b) -& // 触发事件 else -& // 触发事件 always @(add) // 对事件的响应 out = a + always @(mult) //对事件的响应 out = a * endmodule apjiang@ime. 113 块语句(block statements)apjiang@ime.114 块语句? 用来将两个或更多的语句结合在一起 ? 可以分成两种: C 顺序块:包含在 begin……end 中的语句,按顺序 方式执行 C 并行块:包含在 fork……join 中的语句,按并行 方式执行。当编写测试激励时,使用并行块可以 方便地控制绝对时间apjiang@ime.115 块语句举例以下是两个功能相同的块:begin #5 a = 3; #5 a = 5; #5 a = 4; end fork #5 a = 3; #15 a = 4; #10 a = 5; join apjiang@ime. 116 控制语句apjiang@ime.117 条件语句(1)? if 和 if……else语句C 可以多层嵌套 C else和最接近的 if 相关联 C 可以使用 begin……end 来指定作用范围apjiang@ime.118 if条件语句举例always #20 if (index & 0) // 外层 if 开始 if (rega & regb) // 第一个内层 if 开始 result = else result = 0; // 第一个内层 if 结束 else // 外层 if 的else分支 if (index == 0) // 第二个内层 if 开始 begin $display(& Note : Index is zero&); result = end else $display(& Note : Index is negative&); apjiang@ime. 119 条件语句(2)case语句 ?可以使用default语句作为条件判断都不成立 时的选择 ?判断多路条件分支选择,只有当分支的条件 (0、1、x、z)完全符合时才进入这个分支 ?casez是一种case语句,?和z被当作无关项 ?casex是一种case语句,x、?和z被当作无关项 ?无关项在比较时不做考虑apjiang@ime.120 case条件语句举例(1)module compute (result, rega, regb, opcode); input [7: 0] rega, input [2: 0] output [7: 0] reg [7: 0] always @( rega or regb or opcode) case (opcode) 3'b000 : result = rega + 3'b001 : result = rega - 3'b010 , // specify multiple cases with the same result 3'b100 : result = rega /apjiang@ime.121 case条件语句举例(1续)default : begin result = ' $display (& no match&); end endcase endmoduleapjiang@ime.122 case条件语句举例(2)module test_ reg a, b, mux mux_1(a, b, out, select); initial begin #2; select = 0; a = 0; b = 1; #2; select = 1' #2; select = 1' #2; select = 1; end initial $monitor(&T=%2g&,$time,& Select=&,select, & Out=&,out); initial #10 $ endmodule apjiang@ime. 123 case条件语句举例(2续)module mux(a, b, mux_output, mux_select); input a, b, mux_ output mux_ reg mux_ always begin #1; case(mux_select) 0: mux_output = 1: mux_output = default : mux_output = 1' // If select = x or z set output to x. endcase end endmodule apjiang@ime. 124 case条件语句举例(2续-分析)时间 0 1 2 3 4 5 6 7 8 9select x x 0 0 x x z z 1 1a x x 0 0 0 0 0 0 0 0b x x 1 1 1 1 1 1 1 1out x x x 0 0 x x x x 1注释 结果输出 结果没有变化 结果输出 结果输出 结果输出 结果输出 结果输出 结果没有变化 结果输出 结果输出125apjiang@ime. 例2的结果T= 0 T= 2 T= 3 T= 4 T= 5 T= 6 T= 8 T= 9Select=x Select=0 Select=0 Select=x Select=x Select=z Select=1 Select=1Out=x Out=x Out=0 Out=0 Out=x Out=x Out=x Out=1apjiang@ime. 126 case条件语句举例(3)-casexcasex (instruction_register[31:29]) 3’b??1 : 3’b?1? : 3’b1?? : endcaseapjiang@ime.127 循环语句apjiang@ime.128 循环语句? repeat:执行确定次数repeat ( &expression& ) &statement&? while:在条件表达式为真的情况下一直执行while ( &expression& ) &statement&? forever:重复执行直到仿真结束forever &statement&? for:在执行过程中对指定变量进行修改和判 断,在满足条件的情况下执行for ( &assignment& ; &expression& ; &assignment& ) &statement& apjiang@ime. 129 repeat循环举例// 通过加法和移位实现的乘法器设计 module multiplier( result, op_a, op_b); parameter size = 8; input [size:1] op_a, op_b; output [2*size:1] reg [2*size:1] shift_opa, reg [size:1] shift_ always @( op_a or op_b) begin result = 0; shift_opa = op_a; // Zero extend left shift_opb = op_b; repeat (size) begin #10 if (shift_opb[1]) result = result + shift_ shift_opa = shift_opa && 1; // 左移1位 shift_opb = shift_opb && 1; // 右移1位 end end endmodule apjiang@ime. 130 while循环举例... reg [7: 0] reg [3: 0] ... count = 0; // 计算tempreg中1的个数 while (tempreg) // 当tempreg中有1时进行 begin if (tempreg[0]) count = count + 1; tempreg = tempreg && 1; // 右移1位 end ... apjiang@ime. 131 forever循环举例... initial begin clk = 0; forever begin #10 clk = 1; #10 clk = 0; end end ... apjiang@ime. 132 for 循环语句C for (& initialization&; &condition&; &operation&) ? 首先进行循环控制变量的初始化 &initialization& ? 在条件&condition&为真的情况下执行循环 体的操作 ? 每次循环完成后对控制变量进行相应操作 &operation&apjiang@ime.133 for循环举例// X detection for (index = 0; index & index = index + 1) i f (val[index] === 1'bx) $display (& found an X&); // M &!= 0& is simulated efficiently for (i = i != 0; i = i - 1) memory[ i- 1] = 0; // 阶乘 factorial = 1; for (j = j != 0; j = j - 1) factorial = factorial * apjiang@ime. 134 零延迟循环? 仿真过程在当前时间的事件队列中的所有事件 都处理完成时继续后面的操作 ? 如果某个时间的事件队列中待处理事件不断增 加仿真无法推进。零延迟循环可能产生这个结 果。 ? 当一个反馈环路中没有延迟时,可以形成一个 零延迟循环。 ? 零延迟循环可能使仿真事件不断发生,但时间 不能前进。 ? 通过在环路中加入延迟可以避免零延迟循环。 apjiang@ime. 135 零延迟循环举例always areg = ~always @ (a) b = !a; always @ (b) c = !b; always @ (c) a = !c; apjiang@ime. 136 task与functionapjiang@ime.137 task与function? 为了将模块的设计划分成更小的部分,可以使 用task与function ? task与function都必须在模块内定义和调用 ? 对task与function来说,所有的输入和输出实际 上都是局部寄存器 ? 在task与function中不能定义wire类型 ? task与function的输出只有在它们完成时才返 回。如果task与function中包括了一个forever循 环,将无法返回结果 apjiang@ime. 138 task? ? ? ? ? ? ? 通常用于仿真或对硬件的行为描述 通过task的名字调用 可以包含时间控制( # delays, @ , wait ) 可以有input , output 和 inout参数,按照定义的次序传 递参数 可以调用其它的task和function 用于时间控制的信号不应作为task的输入信号,因为 输入值只向task传递一次 对一个task从代码的不同部分进行调用时要小心,因 为task只保留一份局部变量的值。两个并发的调用可 能产生错误结果 可以使用disable命令一个task失去作用apjiang@ime. 139? task举例(1) reg clk, a, DUT u1 (out, a, b, clk); always #5 clk = ! task neg_ input [31:0] number_of_ repeat( number_of_edges) @( negedge clk); endtask initial begin clk = 0; a = 1; b = 1; neg_clocks (3); // task invocation a = 0; neg_clocks (5); b = 0; end endmodule apjiang@ime. 140 task举例(2)module mult (clk, a, b, out, en_mult); input clk, en_ input [3: 0] a, output [7: 0] reg [7: 0] always @( posedge clk) multme (a, b, out); // task in // task definition input [3: 0] xme, output [7: 0] wait (en_mult); result = xme * endtask endmodule apjiang@ime. 141 task举例(3)module traffic_ reg clock, red, amber, parameter on = 1, off = 0, red_tics = 350, amber_tics = 30, green_tics = 200; // initialize colors initial red = initial amber = initial green = // sequence to control the lights always begin red = // turn red light on light(red, red_tics); // and wait. green = // turn green light on light(green, green_tics); // and wait. amber = // turn amber light on light(amber, amber_tics); // and wait. end apjiang@ime. 142 task举例(3续)// task to wait for ’tics’ positive edge clocks // before turning ’color’
input [31:0] begin repeat (tics) @(posedge clock); color = // turn light off end endtask // waveform for the clock always begin #100 clock = 0; #100 clock = 1; end endmodule // traffic_lights apjiang@ime. 143 function? 通常用于完成计算或表示组合逻辑 ? 不能包含时间控制语句 ? 必须至少有一个input参数,不能有output 或inout参数 ? 通过function的名字返回唯一的一个值 ? 可以调用其它function,但不能调用task apjiang@ime. 144 function举例(1)module orand (a, b, c, d, e, out); input [7: 0] a, b, c, d, output [7: 0] reg [7: 0] always @( a or b or c or d or e) out = f_or_and (a, b, c, d, e); // function invocation function [7: 0] f_or_ input [7: 0] a, b, c, d, if (e == 1) f_or_and = (a|b) & (c|d); else f_or_and = 0; endfunction endmodule apjiang@ime. 145 function举例(2) input [7:0] output [7:0] wire [7:0] goo = zero_count ( loo); // 持续赋值调用函数 function [3:0] zero_ // 计算0的个数 input [7:0] in_ integer I; begin zero_count = 0; for (I = 0; I & 8; I = I + 1) if (!in_bus[I]) zero_count = zero_count + 1; end endfunction endmodule apjiang@ime. 146 function举例(3)module checksub (neg, in_a, in_b); input a, fu // integer 类型的函数 input [7: 0] in_a, in_b; subtr = in_a - in_b; // result can be negative endfunction always @ (a or b) if (subtr( a, b) & 0) neg = 1; else neg = 0; endmodule apjiang@ime. 147 命名的块与disableapjiang@ime.148 命名的块(Named Blocks)? 可以在 begin 或 fork 之后加上块名实现 对一个块进行命名 ? 在命名的块中可以定义局部变量 ? 可以用关键字disable使一个命名的块失 去作用 ? 使用命名的块会影响仿真速度apjiang@ime.149 命名的块举例module named_ ... begin : seq_ blk ... end ... fork : par_ blk ... join ... endmodule apjiang@ime. 150 disable的使用? disable可以终止命名的块或task的活动, 语法格式是:disable &name_of_block& disable &task_name&? disable通常不可综合apjiang@ime.151 disable的举例module do_arith (out, a, b, c, d, e, clk, en_ mult); input clk, en_ input [7: 0] a, b, c, d, output [15: 0] reg [15: 0] always @( posedge clk) begin : arith_block // 命名的块 reg [3: 0] tmp1, tmp2; // 局部变量定义 {tmp1, tmp2} = f_or_and (a, b, c, d, e); // function调用 if (en_mult) multme(tmp1, tmp2, out); // task调用 end apjiang@ime. 152 disable的举例(续)always @( negedge en_mult) begin // Abort the arithm // *** Disable task *** disable arith_ // *** Disable named block *** end // Task and function definitions go here endmoduleapjiang@ime.153 原语(primitive)apjiang@ime.154 Verilog的原语(primitive)? Verilog提供基本的逻辑功能作为预定义 的原语,这些原语很多情况下是作为内 建的基本门提供的。 ? 这些原语可以直接使用,不用再定义。 很多ASIC和FPGA的库是利用原语开发 的。apjiang@ime.155 Verilog原语的种类Primitive Name and or not buf xor nand nor xnorFunctionality Logical And Logical Or Inverter Buffer Logical Exclusive Or Logical And Inverted Logical Or Inverted Logical Exclusive Or Invertedapjiang@ime. 156 Verilog原语的输入与输出? 这些原语的输入输出的数量由连接的信 号数目决定,不是固定的 ? 除 not 和 buf 外,其它的原语只有一个输 出(在端口序列的最左面),可以有多 个输入 ? not 和 buf只有一个输入,但可以有多个 输出 apjiang@ime. 157 原语举例apjiang@ime.158 条件原语(Conditional Primitives)? Verilog有四种条件原语,每种都有三个端口, 即output, input 和 enable。通过enable控制其输 出,当不使能时,输出为高阻态。Primitive Name bufif1 bufif0 notif1 notif0Functionality Conditional buffer with logic 1 as enabling input Conditional buffer with logic 0 as enabling input Conditional inverter with logic 1 as enabling input Conditional inverter with logic 0 as enabling inputapjiang@ime. 159 条件原语示例? 表中的L表示值为0或Z,H表示值为1或Z apjiang@ime. 160 原语的实体化? 必须先说明输出,再说明输入信号 ? 原语的实体名字是可选的 ? 可以指定延迟和信号的强度apjiang@ime.161 原语实体化举例and (out, in1, in2, in3, in4); // 无实体名的调用 buf b1 (out1, out2, in); // 有实体名的调用 notif0 #3.1 n1 (out, in, cntrl); // 调用时说明延迟 not (strong1, weak0) n1 (inv, bit); // 调用时说明强度apjiang@ime.162 用户自定义原语 User Defined Primitives (UDPs)apjiang@ime.163 用户自定义原语 User Defined Primitives (UDPs)? ? ? ? ? ? ? UDP适用于单元库、小规模和中规模的芯片 用户可以用UDP实现自己需要的原语 UDP可以定义组合或时序功能 UDP通过真值表表示其功能 UDP 不能实体化模块( module) 使用UDP可以加快仿真速度 UDP的端口只能是标量apjiang@ime. 164? 不允许使用双向端口 用户自定义原语(续)? 每个UDP可以有一个输出和1~10个输入,输 出端口放在端口列表的第一个。不同输入端 口数量的UDP占用的内存如下:# inputs 1- 5 6 7 8 9 10 Memory (k bytes) &1 5 17 56 187 623? 不支持高阻逻辑值 ? UDP不能被综合 apjiang@ime. 165 一个二路选择器的UDPapjiang@ime.166 全加器的UDPapjiang@ime.167 UDP的定义(1)? UDP的定义在module之外进行 ? 对于没有定义的输入组合情况UDP的输 出是x ? 真值表的列次序与端口的次序相同 ? 真值表的 ? 表示0、1或xapjiang@ime.168 UDP的定义(2) 电平敏感的时序逻辑? 用于保存信号的输出必须被定义为reg类 型 ? 通过增加的一个列表示状态,状态用两 边的冒号 “:” 进行分隔,分别为现态和 次态。 ? 表示状态的 “-” 代表保持原来的状态。apjiang@ime.169 电平敏感UDP举例apjiang@ime.170 UDP的定义(3) 边沿敏感的时序逻辑? 在描述输入的表项中有边沿的描述 ? 所有输入中每次最多有一个发生边沿变 化apjiang@ime.171 边沿敏感UDP举例apjiang@ime.172 UDP中的简略记号记号 含义 ? b r f p n *注释 次态值与当前值相同 任意值 任意已确定的值 0-& 1 transition 1-& 0 transition Any positive edge Any negative edge Any transition173不改变 0 or 1 or x 0 or 1 (01) (10) (01) or (0x) or (x1) (10) or (1x) or (x0) (??)apjiang@ime. 使用简略记号的真值表举例table // clk dat state next r 0:?:0; r 1:?:1; (0x) 1 : 1 : 1 ; (0x) 0 : 0 : 0 ; (x1) 1 : 1 : 1 ; (x1) 0 : 0 : 0 ; // 忽略时钟信号的负边沿 n ?:?:-; // 忽略时钟信号稳定时的数据变化 ? *:?:-; endtable apjiang@ime. 174 使用简略记号的真值表举例(2)primitive U_ ff_ p_ cl( q, d, clk, cl); input d, clk, table // d clk cl :q: q+ 1 1 r 1 :?: 1; // 通过时钟上升沿打入1 0 r ? :?: 0; // 通过时钟上升沿打入0 ? r 0 :?: 0; // 复位 ? p 0 :0: -; 1 p 1 :1: -; 0 p ? :0: -; ? n ? :?: -; // 忽略时钟下降边 * ? ? :?: -; // 忽略d的变化 ? ? * :?: -; // 忽略cl的变化 endtable endprimitive apjiang@ime. 175 信号强度apjiang@ime.176 信号强度? Verilog提供了不同级别的信号强度,通过不 同的组合情况尽可能精确地描述硬件的动作 ? Verilog的信号强度级别分成8级 ? 在原语实体化时可以指定对信号的驱动强度 ? 最高强度的信号覆盖其它强度的信号 ? 在进行输出时可以通过%v格式输出信号的强 度值apjiang@ime.177 各级信号强度Level Supply 7 Strong 6 Pull 5 Large 4 Weak 3 Medium 2 Small 1 High Z 0 Type %v formats Drive Su0 Su1 Drive(default) St0 St1 Drive Pu0 Pu1 Capacitive La0 La1 Drive We0 We1 Capacitive Me0 Me1 Capacitive Sm0 Sm1 Impedance Hi0 Hi1 Specification supply0, supply1 strong0, strong1 pull0, pull1 large weak0, weak1 medium small highz0, highz1电容型强度( large , medium , small )只适用于 trireg类型的 线网和 tran类的原语 apjiang@ime. 178 不同强度信号之间的关系? 最高强度的驱动覆盖其它强度的驱动apjiang@ime.179 原语实体化时的强度说明? 说明格式&primitive_ name& [strength] [delay] [instance] (& ports&);? 举例nand (strong1, pull0) #( 2: 3: 4) n1 (o, a, b); // 带有强度和延迟说明,使用了实体名 or (supply0, highz1) (out, in1, in2, in3); // 无实体名apjiang@ime.180 延迟描述apjiang@ime.181 几个基本概念? 模块路径(Module Path):经过模块连接一个 输入端口(包括input和inout)与一个输出端口 (包括output和inout)的路径 ? 路径延迟(Path Delay):一条特定路径的延迟 ? 上升延迟(Rise delay):与变化到1相关的延 迟 ? 下降延迟(Fall delay):与变化到0相关的延迟 ? 关断延迟( Turn-off delay):与变化到高阻Z 相关的延迟 apjiang@ime. 182 延迟模型的种类? 集中延迟(lumped delay):将所有的延迟放 在最后的门上,所有路径延迟相同 ? 分布延迟(Distributed Delays):将延迟分配 在不同的门上,不同的路径可以有不同的延迟 ? 模块路径延迟(Module Path Delays):说明一 个模块从输入到输出的延迟。所有路径可以精 确描述,时间关系和功能可以划分开apjiang@ime.183 延迟模型的种类(2)apjiang@ime.184 不同延迟模型的特点? 集中延迟:延迟可以集中在驱动输出的最后一个门上 C 集中延迟易于描述 C 但只有在简单的情况才比较精确 ? 分布延迟:将延迟分布在各个门上 C 比集中延迟精确,但也不是总能精确描述 ? 模块路径延迟:在一个specify块中说明模块的路径延迟 C 易于描述 C 可以精确匹配延迟说明 C 对0、1和Z之间的转化可以指定不同的延迟 C 可以将时序与功能分开 C 是最常用的延迟类型 apjiang@ime. 185 集中延迟举例`timescale 1ns/ 1ns module noror( Out, A, B, C); output O input A, B, C; nor n1 (net1, A, B); or #3 o1 (Out, C, net1); endmodule 描述的路径延迟: A-& Out is 3 B-& Out is 3 C-& Out is 3 简单,无法描述不同路径的延迟 apjiang@ime. 186 分布式延迟举例module noror( Out, A, B, C); output O input A, B, C; nor #2 n1 (net1, A, B); or #1 o1 (Out, C, net1); endmodule 描述的路径延迟: A-& Out is 3 B-& Out is 3 C-& Out is 1 对实际模块可能变得很复杂;对同一个原语的输入延迟 相同 apjiang@ime. 187 路径延迟举例module noror( O, A, B, C); output O; input A, B, C; nor n1 (net1, A, B); or o1 (O, C, net1); specify (A =& O) = 2; (B =& O) = 3; (C =& O) = 1 endspecify endmodule 描述的路径延迟 A-& Out is 2 B-& Out is 3 C-& Out is 1 用specify指定路径的延迟,可以达到最大精度 apjiang@ime. 188 specify块? specify 块指定了模块的时间信息,这个时间信息和 功能是独立的。 ? specify 块以 specify 开始,以 endspecify结束。 ? specify 块出现在module范围中。 ? 在 specify 块中可以使用specparam定义参数 ? 在 specify 块中通常完成如下任务: 指定跨过模块的不同路径及其延迟 指定时间检查内容apjiang@ime.189 精确延迟控制(1)? 对门和模块路径指定上升、下降和关断延迟: and #( 2,3) (out, in1, in2, in3); //上升、下降 bufif0 #( 3,3,7) (out, in, ctrl); //上升、下降和关断 (in =& out) = (1, 2); //上升、下降 (a =& b) = (5, 4, 7); //上升、下降和关断 ? 对路径延迟指定6个延迟值(包括 0-&1, 1-&0, 0-&Z, Z&1, 1-&Z, Z-&0)。次序图:apjiang@ime.190 精确延迟控制(2)举例:(C =& Q) = (5, 12, 17, 10, 6, 22); ? 对路径延迟指定所有12个延迟值 (包括0-&1, 1-&0, 0-&Z, Z-&1, 1-&Z, Z-&0, 0-&X, X-&1, 1-&X, X-&0, X-&Z, Z-&X)例如: (C =& Q) = (5, 12, 17, 10, 6, 22, 11, 8, 9, 17, 12, 16); apjiang@ime. 191 精确延迟控制(3)? 指定每个延迟的最小、典型和最大值or #( 3.2: 4.0: 6.3) o1( out, in1, in2); // 最小:典型:最大值 not #( 1: 2: 3, 2: 3: 5) (o, in); // 上升和下降的最小:典型:最大值 (b =& y) = (2: 3: 4, 3: 4: 6, 4: 5: 8); // 上升、下降和关断延迟的最小:典型:最大值apjiang@ime.192 精确延迟控制(4)? 在上述描述中, C 上升延迟:指从0变换到1的延迟 C 下降延迟:指从1变换到0的延迟 C 关断延迟:指变换到高阻态Z的延迟 C 当有些与X相关的时间没有指定时,采用的原则 是:到X的变化尽可能快地发生,从X开始的变化 尽可能慢地发生。例如, ? 指定了上升、下降和关断延迟,0-&X的变化是 潜在的上升或关断延迟,取两个值中的较小 值;X-&0的变化是潜在的下降延迟,就取该 值; X-&Z是潜在的关断变化 apjiang@ime. 193 精确延迟控制(5)? 如果只指定上升和下降延迟,1-&X和X-&0使 用下降延迟, X-&Z是潜在的上升或下降变 化,使用这两个延迟中的最大值 ? 如果只指定一个延迟,所有的变化都使用这 个值 ? 如果指定了6个变化,1-&X是潜在的1-&0或1&Z变化,使用这两个值中的最小值; X-&0使 用1-&0或Z-& 0延迟中的最大值;X-&Z使用1&Z和0-&Z的最大值apjiang@ime.194 apjiang@ime.195 并行和完全连接模块路径? *&表示完全连接,所有的输入连接到所 有的输出 ? =&表示并行连接,描述有相同大小的 信号或信号组apjiang@ime.196 并行和完全连接模块路径举例(1)apjiang@ime.197 并行和完全连接模块路径举例(2)// Path delay specified from a to out and from b to out. (a, b =& out, out) = 2.2; // Rise and Fall delay specified from r to o1 and o2. (r *& o1, o2) = (1, 2); /* Path delays specified from a[1] to b[ 1] and from a[ 0] to b[ 0]. */ (a[1: 0] =& b[1: 0]) = 3; // parallel connection // Path delays specified for all paths from a to o. (a[7: 0] *& o[7: 0]) = 6.3; // full connection apjiang@ime. 198 specparam举例module noror (O, A, B, C); output O; input A, B, C; nor n1 (net1, A, B); or o1 (O, C, net1); specify specparam ao = 2, bo = 3, co = 1; (A =& O) = (B =& O) = (C =& O) = endspecify endmodule apjiang@ime. 199 依赖于状态的路径延迟? 当指定条件成立时赋予指定模块路径的延迟。其中的 if不能使用else项。 ? 举例 module XOR2 (x, a, b); input a, xor (x, a, b); specify if (a) (b=& x) = (5: 6: 7); if (!a) (b=& x) = (5: 7: 8); if (b) (a=& x) = (4: 5: 7); if (!b) (a=& x) = (5: 7: 9); endspecify endmodule apjiang@ime. 200 惯性延迟(Inertial Delay)和传输延迟 (Transport Delay) ? 采用惯性延迟时,比门的固有延迟小的路径 延迟将被取消 ? 采用传输延迟时,所有输入的变化都会反映 到输出上 ? 可能通过命令行选项或与仿真器相关的编译 指导命令对其进行改变 ? 在Cadence仿真工具的一些版本中使用 +transport_path_delays 指定采用传输延迟 方式 ? 默认状态是采用惯性延迟 apjiang@ime. 201 惯性延迟和传输延迟说明apjiang@ime.202 作用域规则和层次名apjiang@ime.203 作用域规则? 一个标识符的作用域是verilog描述中该标识符可以被 识别的范围。作用域规则定义了这个范围。 ? 作用域规则: C 模块名称是全局可见的。 C 可以定义标识符的实体包括:模块、任务、函数 和命名的块。每个实体定义了标识符的局部作用 域。局部作用域分别是: ? 模块:module - endmodule ? 任务:task - endtask ? 函数:function - endfunction ? 命名的块:begin: name - end apjiang@ime. 204 作用域规则(2)C 标识符在局部作用域之外也是可见的。规则:? 超前引用:在标识符定义之前就引用。模块、任 务、函数和命名的块的标识符可以超前引用。可以 在这些实体定义之前进行一个module的实体化,调 用一个任务或函数,或终止一个命名的块。 ? 非超前引用:寄存器和线网不能超前引用。需要先 定义后使用。通常是在使用它们的局部作用域开始 处定义它们。 ? 可以超前引用的实体(模块、任务、函数和命名的 块)中,由模块实体化构成了一个向上作用域。从 低层可以识别每一个比它层次高的局部作用域中的 超前引用标识符。 apjiang@ime. 205 作用域和层次名称举例 // hierarchical name is top. // hierarchical name is top.w b instance1 (); always begin : // hierarchical name is top.y. begin:c // hierarchical name is top.t. // hierarchical name is top.t.c. // OK end endtask endmodule apjiang@ime. 206 作用域和层次名称举例(续1) // hierarchical name is top.instance1. // OK // OK // Nope, c is not known disable t.c; // OK s = 1; // OK r = 1; // Nope, r is not known top.r = 1; // OK t.c.q = 1; // OK y.q = 1; // OK, a different q than t.c.q end endmodule apjiang@ime. 207 作用域和层次名称举例(续2)top: tinstance1c: reg q apjiang@ime. 208 层次名? 层次名可以唯一标识整个设计中的任何一个任 务、函数、命名的块、寄存器和线网。 ? 层次中的各名称是超前引用的,在模块实体化 之前不能被识别。 ? 层次名是由“.”隔开的一系列标识符组成的路径 名称。 ? 通过层次命名,任何元素可以访问其它任何元 素,但应尽量坚持局部和向上作用域规则,避 免违反局部化设计风格。 apjiang@ime. 209 系统任务与系统函数apjiang@ime.210 波形记录与输出apjiang@ime.211 记录波形的两种常用格式? VCD:Value Change Dump ? SHM:Simulation History Managerapjiang@ime.212 VCD (Value Change Dump) 格式的图形输出系统任务 $dumpfile(“ file. dump”); $dumpvars(); $ 功能打开波形记录文件 选择要记录的信号名 将文件缓冲区中的数据 存入文件 $ 停止记录波形 $ 开始记录波形 $dumplimit (& file_ size&); 限制波形记录文件的大小, 以字节为单位 $ 记录所有确定的信号 apjiang@ime. 213 命令介绍(1)? $dumpfile:指定VCD文件 ? $dumpfile任务只在仿真开始时指定一 次,所有的VCD数据记入该文件 ? 格式: $dumpfile(&filename&); ? 举例:initial $dumpfile (&module1.dump&); apjiang@ime. 214 命令介绍(2)? $dumpvars:指定要记录的信号。 ? $dumpvars在仿真中可以使用多次,但记录数据的开 始时间应当一致。否则后面开始的$dumpvars无法记 录数据。 ? 格式: $dumpvars(&levels& &, &module|var&&* ); ? 举例: $ $dumpvars (1, top); $dumpvars (0, top); $dumpvars (0, top.mod1, top.mod2.net1); $dumpvars (3, top. u2, top. u1); /* Dump signals in top. u1 and top. u2, and in all their subscopes of them, two levels down.*/ apjiang@ime. 215 命令介绍(3)? $dumpall:在VCD文件中生成一个检查 点,记录所有VCD变量的当前值 ? 格式: $dumpall;apjiang@ime.216 命令介绍(4)? $dumplimit:指定VCD文件的大小(以 字节为单位)。当VCD文件达到指定大 小时,新的数据不再记录,仿真继续进 行。 ? 格式: $dumplimit(&filesize&);apjiang@ime.217 命令介绍(5)? $dumpflush:清空VCD文件的数据缓冲区,保证 缓冲区中的所有数据记录到VCD文件中。 ? 格式: $dumpflush ? 举例: initial begin $dumpvars . . $dumpflush $(applications program) end apjiang@ime. 218 命令介绍(6)? $dumpoff :暂停数据记录 ? $dumpon :重新开始数据记录 ? 在$dumpoff 与$dumpon 之间的数据变化不做记 录 ? 举例: initial begin #10 $dumpvars( . . . ); #200 $ #800 $ #900 $ end apjiang@ime. 219 举例 event do_ // 事件定义 initial $dumpfile(“verilog.dump”); //指定波形记录文件 initial @do_dump $ //Dump variables in the design always @do_dump // 在事件do_dump触发下开始 begin $ // 开始记录 repeat (500) @(posedge clock); //重复500个时钟周期 $ // 停止记录 end initial @(do_dump) forever #10000 $ //记录所有的信号 endmodule apjiang@ime. 220 SHM(Simulation History Manager) 格式的图形数据输出System task $shm_ open(“ waves. shm”); $shm_ probe(); $shm_ $shm_ Description 打开一个记录文件, 一次只能打开一个文件 选择要记录波形的信号 关闭波形记录数据库 将波形记录数据苦 存储到文件中apjiang@ime.221 指定SHM格式的记录信号? 命令格式$shm_ probe(scope0,node0,scope1,node1,...);? 如果不指定scope,缺省按当前范围处理 ? 如果不指定node,记录指定范围内所有的 in、out和inout信号。apjiang@ime.222 指定SHM格式的记录信号 (续)? 指定节点范围的参数apjiang@ime.223 举例initial begin $shm_ open(& lab. shm&); $shm_ probe(); end $shm_ probe(); // 记录所有当前范围内的端口信号 $shm_ probe(“ A”); // 记录当前范围内所有节点的信号 $shm_ probe( alu, adder); // 记录实体 alu 和 adder中的所有端口信号 $shm_ probe(& S&, top. alu, &AC&); /*记录当前范围及其以下层次中所有节点的信号,但不 包含单元库中的节点; 记录 模块top. alu 及其以下层 次中的所有节点的信号包括在单元库中的节点 */ apjiang@ime. 224 文本输出apjiang@ime.225 输出格式控制格式 %h %o %d %b %c %s %v %t %m hex octal decimal binary ASCII string strength time module,display hierarchical name 转义符 \t tab \n new line \\ backslash \“ double quote \& 1- 3 digit octal number& ASCII representation of aboveapjiang@ime.226 对时间输出格式的说明$timeformat(& unit&,& precision&,& suffix&,& min_ width&); Parameter unit precision suffix min_ width Definition 0 (s)到-15 (fs)的整数,说明时间尺度 要显示的数值精度 时间值之后的后缀 显示占用的最小宽度apjiang@ime.227 举例`timescale 10ns / 100 reg in1; not m1( o1, in1); initial begin $timeformat(-9, 2, & ns&, 10); in1 = 0; #8 in1 = 1; #10 $display(&%t %b %b&, $realtime, in1, o1); #10 $ end endmodule apjiang@ime. 228 文本输出$monitor? 当在列表中的任何信号变化时, $monitor输出列表中各信号的值 ? 对不同的信号可以采用不同的基数 ? $time的变化不引起$monitor的输出 ? 可以使用 $monitoron 和 $monitoroff 对 输出监控进行控制 ? 举例 apjiang@ime. 229 文本输出$monitor举例 // Data type declaration reg a, b, // MUX instance MUX2_1 mux (out, a, b, sel); // Apply stimulus initial begin a = 0; b = 1; sel = 0; #5 b = 0; #5 b = 1; sel = 1; #5 a = 1; #5 $ end apjiang@ime. 230 文本输出$monitor举例(续)// Display results initial $monitor($time,& out=%b a=%b b=%b sel=%b&, out, a, b, sel); endmoduleapjiang@ime.231 文本输出$monitor举例结果0 out= 0 a= 0 b= 1 sel= 0 5 out= 0 a= 0 b= 0 sel= 0 10 out= 1 a= 0 b= 1 sel= 1 15 out= 1 a= 1 b= 1 sel= 1apjiang@ime.232 $display与$write? $display与$write用于按指定格式输出信 息,其中第一个参数指定格式控制,后面 的参数是输出列表。 ? 格式如下:$display([“ format_ specifiers”,] &argument_ list&) $write([“ format_ specifiers”,] &argument_ list&)? $display在输出完毕后自动换行,$write不 自动换行 apjiang@ime. 233 举例apjiang@ime.234 $strobe? $strobe 的格式与$display和$write相同。 它在相应时间单位结束时显示指定的信 息,因此其结果是最终的结果。 ? 举例forever @(negedge clock) $strobe (&At time %d, data is %h&,$time,data);在每个时钟信号的下降边,在仿真时间 向前推进之前输出时间和data信号的 值。 apjiang@ime. 235 对文件的操作? 相关的系统任务与函数$fdisplay(&multi_channel_descriptor&, P1, P2, ... , Pn); $fwrite(&multi_channel_descriptor&, P1, P2, ... , Pn); $fstrobe(&multi_channel_descriptor&, P1, P2, ..., Pn); $fmonitor(&multi_channel_descriptor&, P1, P2, ..., Pn); $fopen(&&name_of_file&&) $fclose(&multichannel_descriptor&);? 第一个参数指定了文件的通道号 ? 文件名可以用字符串表示 ? 文件通道号用整数表示 apjiang@ime. 236 对文件的操作 C 举例1reg [ 50*8 : 1 ] mem_ integer memory_ initial begin case ($reset_count) 0 : mem_file = &./test_1/stimuli/boot_file&; 1 : mem_file = &./test_2/stimuli/boot_file&; 2 : mem_file = &./test_3/stimuli/boot_file&; endcase end initial begin memory_dump = $fopen(mem_file); // 打开文件 end apjiang@ime. 237 对文件的操作 C 举例2integer messages, broadcast, cpu_chann, alu_chann, mem_ initial begin cpu_chann = $fopen(&cpu.dat&); if(cpu_chann == 0) $ alu_chann = $fopen(&alu.dat&); if(alu_chann == 0) $ mem_chann = $fopen(&mem.dat&); if(mem_chann == 0) $ messages = cpu_chann | alu_chann | mem_ broadcast = 1 | // includes standard output end apjiang@ime. 238 对文件的操作 C 举例2(续)initial begin $fdisplay( broadcast, &system reset at time %d&, $time ); $fdisplay( messages, &Error occurred on address bus at time %d,address = %h&, $time, address ); forever @(posedge clock) $fdisplay( alu_chann, &acc= %h f=%h a=%h b=%h&, acc, f, a, b ); end apjiang@ime. 239 输出函数的缺省基数? 可以通过不同的输出函数改变缺省基数值$display $fdisplay $displayh $fdisplayh $displayb $fdisplayb $displayo $fdisplayo $strobe $fstrobe $strobeh $fstrobeh $strobeb $fstrobeb $strobeo $fstrobeo$write $writeh $writeb $writeo $monitor $monitorh $monitorb $monitoro$fwrite $fwriteh $fwriteb $fwriteo $fmonitor $fmonitorh $fmonitorb $fmonitoro240apjiang@ime. 读文件? $readmemb:按2进制读文件 $readmemb (& file_ name&, &memory_ name&); $readmemb (& file_ name&, &memory_ name&, &start_ addr&); $readmemb (& file_ name&, &memory_ name&, &start_ addr&, &finish_ addr&); ? $readmemh:按16进制读文件 $readmemh (& file_ name&, &memory_ name&); $readmemh (& file_ name&, &memory_ name&, &start_ addr&); $readmemh (& file_ name&, &memory_ name&, &start_ addr&, &finish_ addr&); ? 在IEEE 标准中增加了很多新的用于读文 件处理的系统任务。 apjiang@ime. 241 读文件举例reg[7:0] mem[1:256]; initial $readmemh(&mem.data&, mem); // // //第一条语句读入的是1~256的内容 第二条语句读入的是16~256的内容 第三条语句读入的是128~1的内容apjiang@ime. 242initial $readmemh(&mem.data&, mem, 16); initial $readmemh(&mem.data&, mem, 128, 1); 时序检查apjiang@ime.243 时序检查? 目的:检查设计的时序关系 ? 过程:C 确定两个事件之间的时间消耗 C 比较消耗的时间与特定的限制 C 当消耗的时间超过限制时报错 C C C C C C? 可以进行的时序检查包括setup hold pulse width clock period skew recoveryapjiang@ime. 244 支持仿真调试的系统任务? 用于在specify块中进行时间检查的系统 任务:$setup( data_ event, clk_ event, limit, notifier); $hold( clk_ event, data_ event, limit, notifier); $setuphold( clk_ event, data_ event, s_ limit, h_ limit, notifier); $recovery( ctrl_ event1, ctrl_ event2, limit, notifier); $width( ctrl_ event, limit, threshold, notifier); $period( ctrl_ event, limit, notifier); $skew( ctrl_ event1, ctrl_ event2, limit, notifier); apjiang@ime. 245 其中的参数? ctrl_ event是时钟或控制信号的单个边沿 变化 ? data_ event是其变化用来和ctrl_ event比 较的数据信号 ? limit是用于检测时间违反的时间限制 ? notifier是一个Verilog 寄存器。每次报告 规则违反时它的值翻转一次。 ? threshold是用于过滤信号毛刺的可选参数 apjiang@ime. 246 notifier? notifier是一个可选的参数 ? 说明成1位的寄存器型(reg) ? 每当时间检查违反时,Verilog报告违反, notifier发生翻 转? 当发生时间违反时可以使用notifier使输出变成未定义值 ? 可以使用notifier以两种方式影响输出: C 可以将notifier作为UDP的一个输入端口 C 不指定端口时,高层行为模块可以按notifier的值动作 apjiang@ime. 247 notifier举例`timescale 1ns/ 1ns module dff_ notifier (q, ck, d, rst, FLAG); input ck, d, output q, FLAG; reg FLAG; // 1- bit notifier // 这里描述dff的网表 specify (ck =& q) = (2: 3: 4); $setup( d, posedge ck , 2, FLAG); endspecify endmodule apjiang@ime. 248 notifier举例(续) reg ck, d, dff_notifier INS1 (q, ck, d, rst, notifer); // 这里加入仿真激励和响应检查 always @( notifier) begin rst = 1; #10 rst = 0; end endmodule notifier FLAG 的初始值是 X。第一个时间检查出错使它 变成1。以后每次时间检查出错使它的值反转一次。 apjiang@ime. 249 $setup? 确定数据信号是否在使能信号变化之前保持足够长 时间的稳定? 格式: $setup(data_event,clk_event,setup_limit,notifier);apjiang@ime.250 $setup(续)? 举例:specify specparam setup_param=10; $setup( data, posedge clock, setup_param ) ; $setup( data, posedge clock, setup_param, flag ) ; endspecifyapjiang@ime.251 $hold? 检查数据信号是否在使能控制信号变化之后保持 足够长时间的稳定? 格式: $hold(clk_event,data_event,hold_limit,notifier); apjiang@ime. 252 $hold(续)? 举例:specify specparam hold_param=11; $hold( posedge clk, data, hold_param ); $hold( posedge clk, data, hold_param, flag ) ; endspecifyapjiang@ime.253 $period? 检查时钟的相同边之间的时间间隔是否小于 指定值? 格式 $period(clk_event, period_limit, notifier); apjiang@ime. 254 $period(续)? 举例specify specparam period_param=13; $period( negedge clk, period_param ) ; $period( negedge clk, period_param, flag ) ; endspecifyapjiang@ime.255 $recovery(1)? 控制异步控制信号和随后的时钟脉冲时 间间隔。可以有一或两个时间限制,当 指定两个时间限制时也可以指定负值 ? 格式$recovery(control_event, clk_event, recovery_limit, notifier); $recovery(control_event, clk_event, removal_limit, recovery_limit, notifier, tstamp_cond, tcheck_cond, delayed_clk, delayed_data); apjiang@ime. 256 $recovery(2)? 指定一个时间限制时:? 指定两个正值的时间限制时:apjiang@ime.257 $recovery(3)? 指定两个时间限制,removal_limit为负? 指定两个时间限制, recovery_limit 为负apjiang@ime.258 $recovery(4)? 举例specify specparam recovery_param=3; $recovery( posedge set, posedge clk, ecovery_param ); $recovery( posedge set, posedge clk, recovery_param, flag ); endspecifyapjiang@ime.259 $setuphold(1)? 将$setup和$hold的功能结合在一起,也 可以提供为负值的参数 ? 格式:$setuphold(clk_event, data_event, setup_limit, hold_limit, notifier, tstamp_cond, tcheck_cond, delayed_clk, delayed_data);apjiang@ime.260 $setuphold(2)? 指定两个正值时间参数的情况? setup_limit为负值的情况apjiang@ime.261 $setuphold(3)? hold_limit为负值的情况? 举例 specify specparam tSU=16, tHLD=17; $setuphold( posedge clk, data, tSU, tHLD ) ; $setuphold( posedge clk, data, tSU, tHLD, flag ) ; endspecify apjiang@ime. 2}

我要回帖

更多关于 verilog 上升沿检测 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信