VerilogHDL中的语句_第1页
VerilogHDL中的语句_第2页
VerilogHDL中的语句_第3页
VerilogHDL中的语句_第4页
VerilogHDL中的语句_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第三章 Verilog-HDL中的语句1.基本语句1.1赋值语句赋值语句分为连续赋值语句和过程赋值语句。连续赋值语句1.连续赋值语句用于把值赋给wire型变量(不能为reg型变量赋值)。 语句形式为:assign A = B & C;a.只要在右端表达式的操作数上有事件(事件为值的变化)发生时,表达式即被计算;b.如果计算的结果值有变化,新结果就赋给左边的线网。2.连续赋值的目标类型w 标量线网 wire a;w 向量线网 wire 7:0 a;w 向量线网的常数型位选择 a1w 向量线网的常数型部分选择 a3:1w 上述类型的任意的拼接运算结果 3a2,a2:1注:多条assign语

2、句可以合并到一起。3.线网说明赋值v 连续赋值可作为线网说明本身的一部分。这样的赋值被称为线网说明赋值。如:wire Clear = 'b1;等价于 wire clear; assign clear=b1;1.1.2 过程赋值语句 1.a过程性赋值是仅仅在initial语句或always语句内的赋值 b它只能对reg型的变量赋值。表达式的右端可以是任何表达式。 c过程性赋值分两类:阻塞性过程赋值 = 非阻塞性过程赋值<=2.语句内部时延与句间时延a在赋值语句中表达式右端出现的时延是语句内部时延。Done = #5 1'b1;b通过语句内部时延表达式,右端的值在赋给左端目标

3、前被延迟。即右端表达式在语句内部时延之前计算,随后进入时延等待,再对左端目标赋值。c对比以下语句间的时延beginTemp = 1'b1;#5 Done = Temp; /语句间时延控制end 3.阻塞性过程赋值a赋值运算符是“=”的过程赋值是阻塞性过程赋值。b阻塞性过程赋值在在下一语句执行前,执行该赋值语句。例:initialbeginClr = #5 0; Clr = #4 1; Clr = #10 0; end4.非阻塞性过程赋值a在非阻塞性过程赋值中,使用赋值符号“ <=”。对目标的赋值是非阻塞的,但可预定在将来某个时间步发生。b当非阻塞性过程赋值被执行时,计算右端表达式

4、,右端值被赋于左端目标,并继续执行下一条语句。c在当前时间步结束或任意输出被调度时,即完成对左端目标赋值。例如:initialbeginClr <= #5 1; Clr <= #4 0; Clr <= #10 0;end注:在编写可综合的时序逻辑模块时,这是最常用的赋值方法。5.阻塞性赋值与非阻塞型赋值比较a非阻塞性赋值:always (posedge clk)begin b <= a; c <= b;endb.阻塞性赋值:always(posedge clk)begin b = a; c = b;end 6.过程赋值与连续赋值的比较7.使用过程赋值八原则

5、7; 规则1: 建立时序逻辑模型时,采用非阻塞赋值语句。§ 规则2: 建立latch模型时,采用非阻塞赋值语句。§ 规则3: 在always块中建立组合逻辑模型时,采用阻塞赋值语句。§ 规则4: 在一个always块中同时有组合和时序逻辑时时, 采用非阻塞赋值语句。§ 规则5: 不要在一个always块中同时采用阻塞和非阻塞赋值语句。    § 规则6: 同一个变量不要在多个always块中赋值。 § 规则7: 调用$strobe系统函数显示用非阻塞赋值语句赋值。§ 规则8: 不要使用#0延时赋

6、值。1.2 条件语句1.2.1 if语句1.2.2 case语句case语句是多路条件分支形式,其语法如下:case(case_expr)case_item_expr:procedural_statement; .default:procedural_statement; endcase case语句首先对条件表达式case_expr求值,然后依次对各分支项求值并进行比较。 第一个与条件表达式值相匹配的分支中的语句被执行。 可以在1个分支中定义多个分支项;这些值不需要互斥。 缺省分支(default)覆盖所有没有被分支表达式覆盖的其他分支。 如果case表达式和分支项表达式的长度不同情况下,在

7、进行任何比较前所有的case表达式都统一为这些表达式的最长长度。 在casez语句中,出现在case表达式和任意分支项表达式中的值z被认为是无关值,即那个位被忽略(不比较)。 在casex语句中,值x和z都被认为是无关位。 casex( Mask )4'b1? : Dbus4 = 0;4'b01? : Dbus3 = 0;4'b001? : Dbus2 = 0;4'b0001 : Dbus1 = 0;defalut : Dbus=4hf; endcase 1.2.3 条件语句的优先级§ case语句和ifelse嵌套描述结构有很大的区别。在Verilo

8、g语法中,ifelse语句是有优先级的§ 一般来说第一个if的优先级最高,最后一个else的优先级最低。§ case语句是“平行”的结构,所有的case的条件和执行都没有“优先级”。§ 建立优先级结构会消耗大量的组合逻辑,所以如果能够使用case语句的地方,尽量用case替换if.else结构。 1.3 循环语句1.3.1 for语句v 一个for循环语句按照指定的次数重复执行过程赋值语句若干次。v for 循环语句的形式如下:for(initial_assignment ; condition ; step_assign) procedural_statemen

9、t v 初始赋值initial_assignment给出循环变量的初始值。condition条件表达式指定循环条件;step_assign给出要修改的赋值,通常为增加或减少循环变量计数。例:integer K;for(K=0 ; K7 ; K=K+1)beginif(AbusK=0)AbusK=1;else if(Abusk=1)AbusK=0;else$display("AbusK is an x or a z");end1.3.2 while语句v while语句连续执行过程赋值语句,直到不满足指定的条件。v while 循环语句语法如下:while(condition

10、) procedural _statement;v 如果表达式在开始时为假,那么过程语句便永远不会执行。如果条件表达式为x或z,它也同样按0(假)处理。例如:while (BY > 0 )beginAcc = Acc << 1;BY = BY - 1;end1.3.3 forever语句v forever循环语句连续执行语句,常用在“initial” 语句中生成周期性的输入波形。 initial begin Clock = 0; # 5; forever #10 Clock = Clock; end1.3.4 repeat语句v repeat执行指定循环次数的过程语句。 v

11、repeat 循环语句形式如下:repeat(loop_count) procedural_statement;v 如果循环计数表达式的值不确定,即为x或z时,那么循环次数按0处理。 repeat(Count) Sum=Sum+10; repeat(ShiftBy) P_Reg=P_Reg<<1;1.4 结构说明语句Verilog-HDL中任何语句模块都从属于以下四种结构的说明语句:1. initial语句2. always语句3. task语句4. function语句1.4.1 initial语句v initial 语句主要用于仿真初始化,并且在仿真开始时便执行,而且只执行一次

12、v initial 语句的语法如下:initial begin . . . end 例:module stimulus;  reg x,y, a,b, m;  initial      m = 1'b0;   initial  begin       #5 a = 1'b1;        #25 b = 1'b0;  end  initial  begin

13、60;      #10 x = 1'b0;       #25 y = 1'b1;  end  initial     #50 $finish;  endmodule 1.4.2 always语句v always语句重复执行,且必须带有某种时序控制。例如:always #5 Clk = Clk; / /产生时钟周期为1 0的波形。或者:always (posedge clk) counter=counter+1;注:时序控制可以

14、是时延控制,即等待一个确定的时间;或事件控制,即等待确定的事件发生或某一特定的条件为真。1.4.3 事件控制事件控制分为边沿触发事件控制和电平敏感事件控制。1)边沿触发事件控制v 格式为 : 事件声明例如 (posedge clock) v posedge 表示上升沿(正沿); nededge表示下降沿(负沿)。v 也可以两个边沿触发事件同时使用 如:always (posedge clk or negedge reset)注:正沿包括:0 -> x、0 -> z、0 -> 1、x -> 1、z -> 1负沿包括:1 -> x、1 -> z、1 -&g

15、t; 0、x -> 0、z -> 02)电平敏感事件控制v 在电平敏感事件控制中,只要敏感变量发生变化,就执行后面的语句。 如: always (a or b or c) sum=a+b+c; 1.4.4 task语句v 一个任务就像一个过程,通过调用任务可以在程序的不同位置执行共同的代码段。v 任务也能调用其它任务和函数。v 任务可以没有或有一个或多个参数,值通过参数传入和传出任务。v 任务的格式:task <任务名> < 端口及数据类型声明语句> <语句1> endtask 任务的调用: <任务名> (端口1,端口2,); 应用举

16、例:交通灯在某一十字路口,红黄绿灯变换的规律如下:同一时间内只有一种颜色的指示灯亮,其两种颜色的指示灯灭。红灯亮350s之后,红灯灭,绿灯亮200s,之后绿灯灭,黄灯亮30s之后,黄灯灭,红灯亮,如此循环。module traffic_lights; reg  clock, red, amber, green; parameter  on=1, off=0, red_tics=350, amber_tics=30, green_tics=200; /交通灯初始化 initial red=off; initial amber=off; initial green=off; /

17、交通灯控制时序 always   begin red=on; /开红灯 light(red,red_tics);/调用等待任务 green=on; /开绿灯 light(green,green_tics);/等待 amber=on; /开黄灯 light(amber,amber_tics); /等待   end/定义交通灯开启时间的任务task  light; output  color; input 31:0 tics; begin repeat(tics)   (posedge clock);/等待tics个时钟的上升沿 color=off

18、;/关灯 end endtask/产生时钟脉冲的always块 always begin     #100 clock=0;     #100 clock=1; end endmodule 这个例子描述了一个简单的交通灯的时序控制,并且该交通灯有它自己的时钟产生器。 注:任务调用语句中参数列表必须与任务定义中的输入、输出和输入输出参数说明的顺序匹配,且输出和输入输出参数必须是reg型的。1.4.5 function语句v 函数可以在程序中的一处或多处调用,提高了代码的可读性。v 定义函数的语法: § function <返回值的类型或范围

19、> (函数名); § <端口说明语句> § <变量类型说明语句> § begin § <语句> § end § endfunction v 函数的目的是返回一个用于表达式的值。函数在其内部隐式地声明一个reg型变量,该reg型变量与函数同名并且取值范围相同。函数通过在函数定义中显式地对该寄存器赋值来返回函数值。对这一寄存器的赋值必须出现在函数定义中。例:定义一个8位二进制数加法器的函数,加数为a7:0和b7:0,并将结果赋给函数名。程序如下:function 7:0adder; input 7

20、:0a,b; reg c; integer i; begin c=0;for(i=0;i<=7;i=i+1) begin adderi=aibic; c=ai&bi |ai&c |bi&c; end endendfunction v 调用函数最常用的形式是将函数的返回值作为表达式中的一个操作数。对上例的调用可用以下语句完成:sum=adder(w,y);1.4.6 函数的使用规则v 1) 函数的定义不能包含有任何的时间控制语句,即任何用或来标识的语句。 v 2) 函数不能启动任务。 v 3) 定义函数时至少要有一个输入参量。 v 4) 在函数的定义中必须有一条赋值

21、语句给函数中的一个内部变量赋以函数的结果 值,该内部变量具有和函数名相同的名字。 1.4.7 函数与任务的区别v (1)函数不能启动任务,而任务能启动其他任务和函数。v (2)函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量。v (3)函数返回一个值,而任务则不返回值。 v (4)函数的关键词是function;任务的关键词是task2. 块语句v 语句块提供将两条或更多条语句组合成语法结构上相当于一条语句的机制。在Verilog HDL中有两类语句块,即:1.顺序语句块(begin . . . end):语句块中的语句按给定次序顺序执行。2.并行语句块(fork . . . j

22、oin):语句块中的语句并行执行。2.1 顺序块(beginend)v 顺序语句块(begin with )中的语句按顺序方式执行。v 一旦顺序语句块执行结束,跟随顺序语句块过程的下一条语句继续执行。begin:example_1#10 stream =0;#2 stream = 1;#5 stream= 0;#3 stream= 1;#4 stream= 0;#2 stream= 1;#5 stream= 0;endv 上例中example_1为语句块的标识符,语句块的标识符是可选的,如果有标识符,寄存器变量可在语句块内部声明。带标识符的语句块可被引用。2.2 并行块(forkjoin)v

23、并行语句块带有定界符fork join,并行语句块中的各语句并行执行。并行语句块内的各条语句指定的时延值都与语句块开始执行的时间相关。v 当并行语句块中最后的动作执行完成时(最后的动作并不一定是最后的语句),顺序语句块的语句继续执行。例:/如果并行语句块在第10个时间单位开始执行fork#2 stream= 1;#7 stream= 0;#10 stream= 1;#14 stream= 0;#16 stream= 1;#21 stream= 0;join3.系统任务和函数v Verilog-HDL提供了内置的系统任务和系统函数,即在语言中预定义的任务和函数1.显示任务( display ta

24、sk)2.文件输入/输出任务(File I/O task)3.时间标度任务(timescale task)4.模拟控制任务(simulation control task)5.时序验证任务(timing check task)6.PLA建模任务(PLA modeling task)7.随机建模任务(stochastic modeling task)8.实数变换函数(conversion functions for real)9.概率分布函数(probabilistic distribution function)3.1 显示任务$display和$write任务§ $display(

25、p1,p2,.pn);§ $write(p1,p2,.pn);§ 这两个系统任务的作用是用来输出信息,即将参数p2到pn按参数p1给定的格式输出。参数p1通常称为“格式控制”,参数p2至pn通常称为“输出表列”。 § $display和$write的作用基本相同。但$display任务能自动换行,$write任务则不能。(1)格式说明,由“%”和格式字符组成。它的作用是将输出的数据转换成指定的格式输出。下表给出了常用的几种输出格式。v %h 或%H : 十六进制v %d 或%D : 十进制v %o 或%O : 八进制v %b 或%B : 二进制v %c 或%C :

26、 ASCII字符v %v 或%V : 线网信号长度v %m 或%M : 层次名v %s 或%S : 字符串v %t 或%T : 当前时间格式(2) 下面表中的字符形式用于格式字符串参数中,用来显示特殊的字符。(3) 显示任务的格式控制举例module disp;  begin    $display(“t%n”123”) ;  endendmodule结果是: % "s3.2 时间度量系统函数 $timev 系统函数$time: $time可以返回一个64比特的整数来表示的当前仿真时刻值。该时刻是以模块的仿真时间尺度为基准的

27、。v 系统函数$realtime: $realtime和$time的作用是一样的,只是$realtime返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。3.3 系统任务 $readmemb 和$readmemh v 系统任务$readmemb和$readmemh用来从文件中读取数据到存贮器中。这两个系统任务可以在仿真的任何时刻被执行使用。1) $readmemb("<数据文件名>",<存贮器名>);2) $readmemb("<数据文件名>",<存贮器名>,<起始地址>);3) $re

28、admemb("<数据文件名>",<存贮器名>,<起始地址>,<结束地址>); $readmemh用法和$readmemb用法相同v 文件包含空白空间、注释和二进制(对于$readmemb)或十六进制(对于$readmemh)数字。每个数字由空白空间隔离。当执行系统任务时,每个读取的数字被指派给存储器内的一个地址。开始地址对应于存储器最左边的索引。例1: reg 0:3 Mem_A 0:63; initial $readmemb("ones_and_zero.vec", Mem_A); /读入的每个数字都被

29、指派给从0开始到63的存储器单元。例2: $readmemb("rx.vec", Mem_A, 15, 30); /从文件“rx.vec”中读取的第一个数字被存储在地址15中,下一个 存储在地址16,并以此类推直到地址30。3.4 系统任务 $randomv 系统函数$random提供了一个产生随机数的手段。当函数被调用时返回一个32bit的随机数。它是一个带符号的整形数。 $ramdom % b ,其中 b>0. 它给出了一个范围在(-b+1):(b-1)中的随机数。reg7:0 rand;rand = $random % 60; 给出了一个范围在59到59之间的随

30、机数v 并置操作符()将$random函数返回的有符号整数变换为无符号数。reg7:0 rand;rand = $random %60; 通过位并接操作产生一个值在0到59之间的数4.编译预处理Verilog-HDL语言中有几种特殊命令,编译系统先对这些特殊命令进行“预处理”,然后将预处理的结果和源程序一起进行通常的编译处理。这些预处理命令:§ 以重音符号开头§ 行末尾不加分号常用预处理命令:include, define, undef , timescaleifdef, else, endif, default_nettype resetall 4.1 include指令

31、v include 编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用全路径名定义, 例如:include " ././primitives. v"v 编译时,这一行由文件“ ././primitives.v” 的内容替代。v 常常在一个芯片设计之前定义一系列全局型的参数,放在define.v文件里面,然后在每个模块中来引入。可以有效地提高编码效率和可扩展性。4.2 define命令和undef命令v define指令用于文本替换,它很像C语言中的#define指令,如:§ define MAX_BUS_SIZE 32§ .§

32、; reg MAX_BUS_SIZE-1:0 AddReg;§ 一旦define指令被编译,其在整个编译过程中都有效。调用时候,前面要用,注意与参数parameter的不同。v undef指令取消前面定义的宏。例如:§ define WORD 16 /建立一个文本宏替代。§ .§ wire WORD:0 Bus;§ .§ undef WORD /在undef编译指令后,WORD的宏定义不再有效。 4.3 ifdef、else 和endifv 这些编译指令用于条件编译,如下所示:§ ifdef WINDOWS§ pa

33、rameter WORD_SIZE=16§ else§ parameter WORD_SIZE=32§ endif v 在编译过程中,如果已定义了名字为WINDOWS的文本宏,就选择第一种参数声明,否则选择第二种参数说明。v else程序指令对于ifdef指令是可选的。4.4 default_nettype和resetall命令v default_nettype指令用于为隐式线网指定线网类型。也就是将那些没有被说明的连线定义线网类型。例如: default_nettype wandv 该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连线,那么该线网被假定为线与类型。v resetall指令将所有的编译指令重新设置为缺省值。该指令使得缺省连线类型为线网类型。4.5 timescale命令v 在Verilog HDL 模型中,所有时延都用单位时间表述。使用timescale编译器指令将时间单位与实际时间相关联。该指令用于定义时延的单位和时延精度。v 格式为:timescale

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论