1、芜湖职业技术学院,第4章 Verilog HDL行为语句,赋值语句(assign、=、=) 条件语句(if-else、case) 循环语句(for、forever、repeat、while) 过程语句(initial、always) 块语句(begin-end、fork-join),芜湖职业技术学院,本章介绍Verilog HDL的行为语句,要充分理解硬件描述语言和硬件电路的关系,熟练掌握常用的行为语句,基本的行为语句就可以完成绝大多数电路与系统设计,要对常用语句用心专研、深入理解,对完成硬件电路设计将是非常有用的。,本章概述,芜湖职业技术学院,4.1 赋值语句,Verilog HDL赋值语句
2、包括连续赋值语句和过程赋值语句两种。,1. 连续赋值语句,数据流的描述是采用连续赋值语句(assign )语句来实现的,语法如下: assign net_type=表达式;,连续赋值语句用于组合逻辑的建模。等式左边是wire类型的变量,等式右边可以是常量,或是由运算符如逻辑运算符、算术运算符参与的表达。例如, wire 3:0 Z, Preset, Clear; /线网说明 assign Z = Preset /连续赋值语句,芜湖职业技术学院,注意两个方面的问题: (1)连续赋值语句的执行是:只要右边表达式任一个变量有变化,表达式立即被计算,计算的结果立即赋给左边信号。 (2)连续赋值语句之间
3、是并行语句,因此与位置顺序无关。,2. 过程赋值语句,过程赋值语句多用于对reg型变量进行赋值。过程赋值有阻塞赋值和非阻塞赋值两种方式。阻塞语句是顺序执行的,在该语句结束时就立即完成赋值,那么在前面的语句没有完成之前,后面的就不能被执行,仿佛被阻塞了一样,常用于组合逻辑电路设计中;而非阻塞语句是同时执行的,在整个过程块结束时才完成赋值操作,即被赋值的变量的值不是立刻就改变的,常用于时序逻辑电路设计中。,芜湖职业技术学院,阻塞赋值语句,从字面上理解,该条语句阻塞了下面语句的执行,“=”用于阻塞的赋值,凡是在组合逻辑(如在assign语句中)赋值的请用阻塞赋值。,非阻塞赋值操作符用小于等于号(即=
4、)表示,只能用于对寄存器类型变量进行赋值,因此只能用在“initial ”和“always”等过程块中,不能用在assign语句中。,阻塞赋值,非阻塞赋值,注:在同一个进程块中,最好不要同时用阻塞赋值和非阻塞赋值语句。,芜湖职业技术学院,4.2 条件语句,条件语句有if-else语句和case语句两种,它们都是顺序语句,应放在always块内。,1. if-else语句,格式与C语言中的if-else语句类似,使用方法有三种:,(1)If(表达式) 语句1; (2)If(表达式) 语句1;else 语句2; (3)if(条件表达式1) 语句1;else if (条件表达式2) 语句2;else
5、 if (条件表达式3) 语句3;else 语句n;,芜湖职业技术学院,例如,if(Sum 60)beginGrade = C;Total_C = Total _c + 1;end else if(Sum 75)beginGrade = B;Total_B = Total_B + 1;end elsebeginGrade = A;Total_A = Total_A + 1;end,“表达式”一般为逻辑表达式或关系表达式,也可能是一位的变量。条件表达式必须总是被括起来的。对表达式的值进行判断,若为0, x或z,按“假”处理;若为1,按“真”处理,执行指定语句。,芜湖职业技术学院,2. case语
6、句,相对于if语句只有两个分支而言,case语句是一种多分支语句,故case语句可用于多条件译码电路,如:描述译码器、数据选择器、状态机及微处理器的指令译码等。,case语句的使用格式: case (敏感表达式)值1: 语句1;值2: 语句2;值n: 语句n;default:语句n+1; endcase,当敏感表达式的值为值1时,执行语句1;为n时执行语句n;如果敏感表达式的值与列出的值都不相同的话,则执行default后面的语句。 建议:case的默认项必须写,防止产生锁存器。,芜湖职业技术学院,例如,begin case (HEX) 4b0001 : LED = 7b1111001; /
7、1 4b0010: LED = 7b0100100; / 2 4b0011: LED = 7b0110000; / 3 4b0100: LED = 7b0011001; / 4 4b0101: LED = 7b0010010; / 5 4b0110: LED = 7b0000010; / 6 4b0111: LED = 7b1111000; / 7 4b1000: LED = 7b0000000; / 8 4b1001: LED = 7b0010000; / 9 4b1010: LED = 7b0001000; / A 4b1011: LED = 7b0000011; / B 4b1100:
8、LED = 7b1000110; / C 4b1101: LED = 7b0100001; / D 4b1110: LED = 7b0000110; / E 4b1111: LED = 7b0001110; / F default :LED = 7b1000000; / 0 Endcase,芜湖职业技术学院,3. 条件语句使用要点,在使用条件语句时,应注意列出所有条件分支,否则,编译器认为条件不满足时,会引起一个触发器保持原值。这一点可用于设计时序电路,例如在计数器设计中,条件满足则加1,否则保持不变;而在组合电路设计中,应避免这种隐含触发器的存在。当然,一般不可能列出所有分支,因为每一变量至
9、少有4种取值0、1、z、x。为包含所有分支,可在if语句最后加上else;在case语句的最后加上default语句。,设计者原意是设计一个二输入与门,但因if语句中无else语句,在逻辑综合时会认为else语句为:“c=c”,即保持不变,形成了一个隐含锁存器。因此需要加一条语句: else c=0;,芜湖职业技术学院,4.3 循环语句,在Verilog HDL中存在4种类型的循环语句,可用来控制语句执行次数。这4种语句分别为:,(1)forever:连续地执行语句,多用在“initial”块中,以生成时钟等周期性波形。 (2)repeat:连续执行一条语句n次; (3)while:执行一条语
10、句,直到某个条件不满足; (4)for:有条件的循环语句,芜湖职业技术学院,1. for语句,for语句使用格式: for(表达式1;表达式2;表达式3) 语句; 即: for(循环变量赋初值;循环结束条件;循环变量增值) 执行语句;,2. repeat语句,repeat语句的使用格式为: repeat(循环次数表达式) 语句; 或repeat(循环次数表达式) begin end,芜湖职业技术学院,3. while 和forever语句,While语句while语句的使用格式如下:while(循环执行条件表达式)语句; 或 while(循环执行条件表达式)beginendwhile语句在执行
11、时,首先判断循环执行条件表达式是否为真,若为真,执行后面的语句或语句块,然后再回头判断循环执行条件表达式是否为真,为真的话,再执行一遍后面的语句,如此不断,直到条件表达式不为真。因此,在执行语句中,必须有一条改变循环执行条件表达式的值的语句。,芜湖职业技术学院,forever语句forever语句的使用格式如下:forever 语句; 或 forever beginendforever循环语句连续不断地执行后面的语句或语句块,常用来产生周期性的波形,作为仿真激励信号for语句一般用在initial过程语句中,若要用它来进行模块描述,可用disable语句进行中断。,芜湖职业技术学院,举例:3个
12、分别用for、repeat、while语句实现的同一个循环,芜湖职业技术学院,应用举例:采用for循环语句设计一个“七人表决器”,通过一个for循环语句统计赞成人数,若超过4人赞成则通过。,芜湖职业技术学院,用vote6:0表示7个人的投票情况,“1”代表赞成,即votei为第“1”代表第i个赞成,pass=“1”表示表决通过,芜湖职业技术学院,4.4 过程语句,Verilog HDL中的多数过程模块都从属于以下2种过程语句: initial always在一个模块中,使用always和initial语句的次数是不受限制的。Initial语句常用于仿真中的初始化,initial过程块中的语句仅
13、执行一次;always块内的语句则是不断重复执行的。Always过程语句是可综合的,在综合的电路设计中广泛采用。,芜湖职业技术学院,1. always过程语句,always过程语句使用模板如下: always () begin /过程赋值 /if-else,case选择语句 /while,repeat,for循环 /task,function调用 end,芜湖职业技术学院,“always”过程语句通常是带有触发条件的,触发条件写在敏感信号表达式中,只有当触发条件满足时,其后的“begin-end”块语句才能被执行。下面讨论敏感信号表达式“event-expression”的含义以及如何写敏感信
14、号表达式。,敏感信号表达式,所谓敏感信号表达式,又称事件表达式或敏感信号列表,即当该表达式中变量的值改变时,就会引发块内语句的 执行。因此,敏感信号表达式中应列出影响块内取值的所有信号。若有两个或两个以上信号,它们之间用“or”连接。,芜湖职业技术学院,例如: (a) /当信号a值发生改变时 (a or b) /当信号a或信号b的值发生改变时 (posedge clock) /当clock的上升沿到来时 (negedge clock) /当clock的下降沿到来时 (posedge clk or negedge reset) /当clk的上升沿到来或/reset信号的下降沿到来时敏感信号可以分
15、为两种类型:一种为边沿敏感型,一种为电平敏感型。每一个always过程最好只由一种类型的敏感信号来触发,而不要将边沿敏感型和电平敏感型列在一起。,芜湖职业技术学院,例如: always (posedge clk or posedge clr)/两个敏感信号都是边沿敏感型 always (a or b)/两个敏感信号都是电平敏感型 always (posedge clk or clr)/不建议这样用,最好不要将边沿敏感型和电平/敏感型列在一起,芜湖职业技术学院,同步和异步操作,对于时序电路,事件通常是由时钟边沿触发的。为表达边沿这个概念,Verilog HDL 提供了posedge和negedg
16、e两个关键字来进行描述。根据过程语句中表述方式不同, 可实现信号的同步操作和异步操作。,此为同步置数,同步清零的例子,芜湖职业技术学院,对于上例中的load、reset信号没有写在敏感信号表达式当中,他们是同步置数、同步清零,这些信号要起作用,必须有时钟的上升沿到来。对于异步的清零/置数,应按以下格式书写敏感信号表达式。,always (posedge clk or posedge clear)/clear信号上升沿到来时清零,故高电平清零有效 always (posedge clk or negedge clear)/clear信号下降沿到来时清零,故低电平清零有效,注:块内的逻辑描述要与敏
17、感信号表达式中信号的有效电平一致。例如:,芜湖职业技术学院,用always过程块实现较复杂的组合逻辑电路,always过程语句通常用来对寄存器类型的数据进行赋值,但always过程语句也可以用来设计组合逻辑。在有的情况下,使用assign来实现组合逻辑电路,很多地方会显得冗长且效率低下,而适当地采用always过程语句来设计组合逻辑,能收到更好的效果。,下面是一个简单的指令译码电路设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、求与、求或、求反,并且无论是指令作用的数据还是指令本身发生变化,结果都应做出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assig
18、n语句描述,表达起来非常复杂。本例中采用电平敏感的always块,并运用case结构来进行分析判断,使设计思想得到直观体现,代码整齐有序,便于理解。,芜湖职业技术学院,2. initial过程语句,initial语句的使用格式如下: Initial语句的使用格式如下:initialbegin语句1;语句2;end initial语句不带触发条件,initial过程中的块语句沿时间轴只执行一次。initial语句通常用于仿真模块中对激励向量的描述,或用于给寄存器变量赋初值,它是面向模拟仿真的过程语句,通常不能被逻辑综合工具所支持。,芜湖职业技术学院,4.5 块语句,块语句是由标志符begin-e
19、nd或fork-join界定的一组语句,当块语句只包含一条语句时,块标识符可以缺省。,1. 串行块begin-end,begin-end串行块中的语句按串行方式顺序执行。,比如:beginregb=rega;regc=regb;end,由于begin-end块内的语句顺序执行,在最后,将regb,regc的值都更新为rega的值,最终regb,regc的值是相同的。,仿真时,begin-end块中的每条语句前面的延时都是相对于前一条语句执行结束的相对时间。,芜湖职业技术学院,2. 并行块fork-join,并行块fork-join中的所有语句是并发执行的。,比如:forkregb=rega;regc=regb;join,由于fork-join并行块中的语句是同时执行的,在上面的块语句执行完后,regb更新为rega的值,而regc的值更新为没有改变前的regb的值,故执行完后,regb与regc的值是不同的。,在进行仿真时,fork-join并行块中的每条语句前面的延时都是相对于该并行块的起始执行时间的。,芜湖职业技术学院,芜湖职业技术学院,芜湖职业技术学院,芜湖职业技术学院,芜湖职业技术学院,芜湖职业技术学院,芜湖职业技术学院,