verilog条件语句课件例程.ppt

上传人:本田雅阁 文档编号:3486202 上传时间:2019-09-02 格式:PPT 页数:99 大小:217.55KB
返回 下载 相关 举报
verilog条件语句课件例程.ppt_第1页
第1页 / 共99页
verilog条件语句课件例程.ppt_第2页
第2页 / 共99页
verilog条件语句课件例程.ppt_第3页
第3页 / 共99页
verilog条件语句课件例程.ppt_第4页
第4页 / 共99页
verilog条件语句课件例程.ppt_第5页
第5页 / 共99页
点击查看更多>>
资源描述

《verilog条件语句课件例程.ppt》由会员分享,可在线阅读,更多相关《verilog条件语句课件例程.ppt(99页珍藏版)》请在三一文库上搜索。

1、【例】同时由两个时钟沿:clk1上升沿和clk2下降沿进行控制的8位移位寄存器。 module 8bits_shift_register(d_in,d_out,clk1,clk2); input clk1,clk2,d_in; output d_out; reg d_out; /d_out保存1bit reg1:7 data; / reg1:7保存其余7bits reg1:4 i ; / i用于循环计数 always ( posedge clk1 or negedge clk2) begin d_out=data1; for ( i=1;i7;i=i+1) datai=datai+1; dat

2、a7=d_in; end endmodule,编译的警告,Warning: Design contains 2 input pin(s) that do not drive logic Warning: No output dependent on input pin “clk1“ Warning: No output dependent on input pin “clk2“,module shift_regester(data_in,data_out,clk1); input data_in,clk1; output data_out; reg1:7 reg_data; reg data_

3、out; integer i; always( negedge clk1 ) begin data_out=reg_data1; for(i=1;i=7;i=i+1) reg_datai=reg_datai+1; reg_data7=data_in; end endmodule,6.5 条件语句,与常用的高级程序语言一样,为了描述较为复杂 的时序关系,Verilog HDL提供了条件语句供分支判 断时使用。在可综合风格的Verilog HDL模型中常用 的条件语句有ifelse和caseendcase两种结构, 用法和C程序语言中类似。两者相较,ifelse用于 不很复杂的分支关系,实际编写可

4、综合风格的模 块、特别是用状态机构成的模块时,更常用的是 caseendcase风格的代码 If_else语句 Case语句,6.5.1 if-else条件语句,if-else条件分支语句的作用是根据指定的判断条件是否满足来 确定下一步要执行的操作。它在使用时可以采用如下三种形式: (1) 使用形式1: if ( ) 语句或语句块; 在if-else条件分支语句的这种使用形式中没有出现else项 这种情况下条件分支语句的执行过程将是: 如果指定的“”成立(也就是这个条件表达式的 逻辑值为“1”),则执行条件分支语句内给出的“语句或语句块”, 然后退出条件分支语句的执行。 如果“”不成立(也就是

5、条件表达式的逻辑值为 “0”、“x”或“z”时),则不执行条件分支语句内给出的“语句或语句 块”,而是直接退出条件分支语句的执行。 一条没有else选项的if语句映射到硬件上,形成的是一个锁存器,例如下面这条条件分支语句: if(enable = 1) out = data_in; 在执行时就会根据条件表达式“enable=1”是否成立来决定 是否执行赋值语句“out=data_in;”:如果enable取值为 “1”,则赋值语句得到执行,输出信号out得到data的值;如 果enable的值为“0”、“x”或“z”(取值不为“1”),则不 执行指定的赋值语句,输出信号out保持原有值不变。

6、(2) 使用形式2: if ( ) 语句或语句块1 else 语句或语句块2 这种形式的条件分支语句将以如下方式得到执行: 如果指定的“”成立(也就是这个条件 表达式的逻辑值为“1”),则执行条件分支语句第一行所指 定的“语句或语句块1”,然后结束条件分支语句的执行。 如果“”不成立,则执行由条件分支语 句内第二行的else项所指定的“语句或语句块2”,然后结 束条件分支语句的执行。,一条带有else选项的if语句映射到硬件上,通常形成的是一个多路选择器(MUX) 例如,下面这条条件分支语句: if(select=1) out=input1; else out=input0; 在执行时会根据条

7、件表达式“select=1”是否成立来 决定执行两条过程赋值语句中的哪一条。如果select 取值为“1”,则第一行if这一项所指定的赋值语句 “out=input1;”得到执行,输出信号out得到input1的 取值;如果select取值不为“1”(取值为“0”、“x”或 “z”),则执行第二行else项所指定的赋值语句 “out=input0;”,输出信号out将得到input0的取值。,(3) 使用形式3: if () 语句或语句块1 else if () 语句或语句块2 else if () 语句或语句块n else 语句或语句块n+1 在这种使用形式中一共出现了n+1个条件分支项,其

8、中每个分支项都指定了当该分支项的条件满足时所要执行的操作。,在执行这种形式的if-else条件分支语句时,将按照各分支项的排列顺序对各个条件表达式是否成立作出判断,当遇到某一项的条件表达式成立时,就执行这一项所指定的“语句或语句块”。比如假设“”成立,那么就执行“语句或语句块m”。 如果所有的条件表达式都不成立,则执行最后的else项(这一项没有给出条件表达式)所指定的操作(语句或语句块n+1)。 这种形式的if-else条件分支语句实现了一种多路分支选择控制。 比如在例6-21给出的模块中就使用了这种形式的if-else条件分支语句。,【例6-21】第三种形式的if-else条件分支语句。

9、module sel_from_three(q,sela,selb,a,b,c ); input sela,selb,a,b,c; output q; reg q; always (sela or selb or a or b or c) begin if (sela) q = a; else if (selb) q = b; else q = c; end endmodule,在例6-21模块内的if-else条件分支语句中出现了三个分支项,这个条件分支语句在执行时将依次对控制信号sela和selb的取值是否为“1”进行判断: (1) 如果sela的取值为1,则第一个分支项的条件表达式“(s

10、ela)”成立,因而第一个分支项所指定的赋值操作“q=a;”将得到执行。 (2) 如果sela的取值不为1,而selb的取值为1,则第二个分支项的条件表达式“(selb)”成立,因而第二个分支项所指定的赋值操作“q=b;”将得到执行。 (3) 如果sela和selb的取值都不为1,则“(sela)”和“(selb)”这两个条件表达式都不成立,这时else分支项所指定的赋值操作“q=c;”将得到执行。 (4) 如果sela和selb的取值都是1,那么第一个条件表达式“(sela)”以及第二个条件表达式“(selb)”都是成立的。在这种情形下,由于首先被检测为成立的条件表达式是第一个分支项的条件表

11、达式“(sela)”,所以此时将执行第一分支项指定的赋值操作q=a;”。,图6.11 例6-21所示模块描述的电路功能,因此,例621所示模块描述的是图6.11所示的硬件电路功能。由上例条件表达式取值的第四种情况我们可以看出:这种形式的if-else条件分支语句(第三种使用形式)内各个条件表达式的排列顺序决定了对各个条件进行判断的先后次序,这种排列顺序隐含着一种优先级关系,也就是说排在前面的分支项所指定的操作具有较高的优先级。比如,在前面讨论过的例中条件分支语句的第四种执行情况下,虽然两个条件表达式都是成立的,但是由于条件表达式“(sela)”排在“(selb)”的前面,所以“(sela)”这

12、一项所对应的赋值语句“q=a;”具有较高优先级,因此这时得到执行的将是语句“q=a;”而不是“q=b;”。,说明,(1)三种形式的if语句中在if后面都有“表达式”,一般为逻辑表达式或关系表达式。系统对表达式的值进行判断,若为0,x,z,按“假”处理,若为1,按“真”处理,执行指定的语句。 (2)第二、第三种形式的if语句中,在每个else前面有一分号,整个语句结束处有一分号。 例如: If (ab) out1 =int1; else out1 =int2; 分号是Verilog HDL语句中不可缺少的部分,这个分号是if语 句中的内嵌套语句所要求的。如果无此分号,则出现语法错误。 但应注意,

13、不要误认为上面是两个语句(if语句和else语句)。 它们都属于同一个if语句Else子句不能作为语句单独使用,它必 须是if语句的一部分,与if配对使用。,(3).在if和else后面可以包含一个内嵌的操作语句(如上例),也可以有多个操作语句,此时用begin和end这两个关键词将几个语句包含起来成为一个复合块语句。如: if(ab) begin out1=int1;out2=int2; end else begin out1=int2; out2=int1; end 注意在end后不需要再加分号。因为begin_end内是一个完整的复合语句,不需再附加分号,(4).允许一定形式的表达式简写

14、方式。如下面的例子: if(expression) 等同与 if( expression = 1 ) if(!expression) 等同与 if( expression != 1 ) 描述一个具有同步清零功能(低电平有效)的上升沿D触发器 module dff_sync(q, d, clear, clk); output q; input d, clear, clk; reg q; always (posedge clk) if(!clear) q=0;/清零 else q=d;/正常D触发器 ednmodule,由于要实现的是同步清零方式,所以触发器状态的改变都是发生在时钟下降沿的。alw

15、ays过程块中的if-else条件分支语句首先对清零控制信号clear进行检测,从而判断是否需要执行清零操作(因为清零操作具有较高优先级):如果清零控制信号clear有效(取值为“0”),则对q赋值“0”,实现清零操作;如果清零控制信号clear无效(取值为“1”),则将输入端d的数据传送到输出端q,实现D触发器正常工作时的功能。,描述一个具有异步清零功能(低电平有效)的上升沿D触发器(不能综合) module dff_asyn2(q,d,clear,clk); output q; input d,clear,clk; reg q; always (clear) /该过程块用来处理清零操作 i

16、f(!clear) q=0; /异步清零 always (negedge clk)/该过程块用来实现正常的D触发器功能 if(!clear) q=0;/考虑clear信号和clk信号在同一时刻发生变化的情况 else q=d; /正常D触发器功能 endmodule,两个always过程块分别用来监测清零控制信号clear和时钟clk的变化,其中第一个always过程块用于实现清零功能;第二个always过程块则用于实现正常的D触发器功能。而且在第二个always过程块中还考虑了清零信号与时钟信号同时发生跳变的情况,由于其中的if-else条件分支语句中对清零信号的处理优先于对时钟信号的处理,

17、所以在这种情况下也能正确实现异步清零功能。,(5).if语句的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套。一般形式如下: if(expression1) if(expression2) 语句1 (内嵌if) else 语句2 else if(expression3) 语句3 (内嵌if) else 语句4 应当注意if与else的配对关系,else总是与它上 面的最近的if配对。如果if与else的数目不一样,为 了实现程序设计者的企图,可以用begin_end块语句来 确定配对关系,例如: if( ) begin if( ) 语句1 (内嵌if) end else 语句2

18、这时begin_end块语句限定了内嵌if语句的范围, 因此else与第一个if配对。注意begin_end块语句在 if_else语句中的使用。因为有时begin_end块语句的不慎使用会改变逻辑行为,判断,if(index0) for(scani=0;scani0) begin $display(“.“); memoryscani=0; end else /*WRONG*/ $display(“error-indexiszero“) 错误,if(index0) begin for(scani=0;scani0) begin $display(“.“); memoryscani=0; end

19、 end else /*WRONG*/ $display(“error-indexiszero“); 正确,(6).if_else例子。 下面的例子是取自某程序中的一部分。这部分程序用if_else语句来检测变量index以决定三个寄存器modify_segn中哪一个的值应当与index相加作为memory的寻址地址。并且将相加值存入寄存器index以备下次检测使用。程序的前十行定义寄存器和参数,/定义寄存器和参数。 reg 31:0 instruction, segment_area255:0; reg 7:0 index; reg 5:0 modify_seg1, modify_seg2,

20、 modify_seg3; parameter segment1=0, inc_seg1=1, segment2=20, inc_seg2=2, segment3=64, inc_seg3=4, data=128; /检测寄存器index的值 if(indexsegment2) begin instruction = segment_areaindex + modify_seg1; index = index + inc_seg1; end,else if(indexsegment3) begin instruction = segment_areaindex + modify_seg2; i

21、ndex = index + inc_seg2; end else if (indexdata) begin instruction = segment_areaindex + modify_seg3; index = index + inc_seg3; end else instruction = segment_areaindex,模为60的BCD码加法计数器,module count60(qout,cout,data,load,reset,clk); output7:0 qout; output cout; input7:0 data; input load,cin,clk,reset;

22、 reg7:0 qout; always (posedge clk) begin if (reset) qout=0; else if (load) qout=data; else if (in) begin,if(qout3:0=9) begin qout3:0=0; if(qout7:4=5) qout7:4=0; else qout7:4=qout7:4+1; end else qout3:0=qout3:0+1; end end assign cout=(qout=8h59) endmodule,1/2分频器的设计,module half_clk(reset,clk_in,clk_ou

23、t); input clk_in,reset; output clk_out; reg clk_out; always (posedge clk_in) begin if(!reset) clk_out=0; else clk_out=clk_out; end endmodule,时钟分频器的设计,将10M的时钟分频为500K的时钟。基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/20分频 module fdivision(RESET,F10M,F500K); input F10M,RESET; output F500K; reg F500K; reg 7:0j;,al

24、ways (posedge F10M) if(!RESET) /低电平复位。 begin F500K = 0; j = 0; end else begin if(j=19) /对计数器进行判断,以确定F500K信号是否反转。 begin j = 0; F500K = F500K; end else j = j+1; end endmodule,6.5.2 Case语句,当多路选择的控制条件集中在某个变量的变 化上时,用case语句加以表达显得更为方便 与直观 case语句最适宜于对CPU的译码等部件的 描述以及对有限状态机的描述 case语句分为case、casez、casex共三种表示方式,

25、case语句的表示形式,case语句的格式如下: case () :语句块1; :语句块2; :语句块n; default: 语句块n +1; endcase 在上述格式中: “”代表着对程序流向进行控制的控制信号; 各个“”则是控制表达式的某些具体状态取值, 在实际使用中这些分支项表达式通常是一些常量表达式;各个 “语句块”则指定了在各个分支下所要执行的操作,它们也可以是 由单条语句构成的;处于最后的、以关键词 “default”开头的那 个分支项被称为“default分支项”,它是可以缺省的。,说明,1 case括弧内的表达式称为控制表达式,case分支项 中的表达式称为分支表达式。控制表

26、达式通常表示为 控制信号的某些位,分支表达式则用这些控制信号的 具体状态值来表示,因此分支表达式又可以称为常量 表达式。 2 当控制表达式的值与分支表达式的值相等时,就执 行分支表达式后面的语句。如果所有的分支表达式的 值都没有与控制表达式的值相匹配的,就执行default 后面的语句。 3 default项可有可无,一个case语句里只准有一个 default项。,4 每一个case分项的分支表达式的值必须互不相同,否则就会出现矛盾现象(对表达式的同一个值,有多种执行方案)。 5 执行完case分项后的语句,则跳出该case语句结构,终止case语句的执行。 6 在用case语句表达式进行比

27、较的过程中,只有当信号的对应位的值能明确进行比较时,比较才能成功。因此要注意详细说明case分项的分支表达式的值。 7 case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用bx, bz 来替代 nbx, nbz,这样写是不对的,因为信号x, z的缺省宽度是机器的字节宽度,通常是32位(此处 n 是case控制表达式的位宽)。,case语句的执行过程,(1) 当“控制表达式”的取值等于“分支项表达式1”时,执行第一个分支项所包含的“语句块1”。 (2) 当“控制表达式”的取值等于“分支项表达式2”时,执行第二个分支项所包含的“语句块

28、2”。 (3) 如果“控制表达式”的取值与所有n个分支项表达式的值都不相同,则执行“default分支项”所包含的“语句块n+1”。 (4) 在执行了某一分支项内的语句块后,跳出case语句结构,终止case语句的执行。,case语句中各个“分支项表达式”的取值必须是互不相同的,否则就会出现矛盾现象。 如果“控制表达式”有几种不同取值情况对应着同一操作,则 上述格式可以这样进行简写:用逗号将代表着这几种不同取 值情况的多个“分支项表达式”隔开,再将在这些情况下需要 执行的语句块放在这几个分支项表达式的后面。比如下面的 语句: case(op_code) 2b00: out=a|b; / op_

29、code取值为“2b00”时的分支项 2b01, 2b10, 2b11: out=a&b;/op_code取值为“2b01”、“2b10”或 “2b11”时要执行的操作都是“out=a&b;” default: out=0; / default分支项 endcase,在上面的语句中,三个分支项表达式“2b01”、“2b10”和“2b11”之间用“,”隔开,同时在这几个分支项表达式后面指定了要执行的语句“out=a&b;”。这表明当控制信号op_code取值为2b01、2b10或2b11时,对应的操作都是由语句“out=a&b;”指定的赋值操作。上例是如下多条语句的简写形式: case(op_c

30、ode) 2b00: out=a|b; / op_code取值为“2b00”时的分支项 2b01: out=a&b; / op_code取值为“2b01”时的分支项 2b10: out=a&b; / op_code取值为“2b10”时的分支项 2b11: out=a&b; / op_code取值为“2b11”时的分支项 default: out=0; / default分支项 endcase,case语句在执行时,控制表达式和分支项表达式之间进行的比较是一种按位进行的“全等比较”,也就是说,只有在分支项表达式和控制表达式对应的每一位都彼此相等的情况下才认为分支项表达式和控制表达式两者是“相等”

31、的。在进行对应位的比较时,“x”和“z”这两种逻辑状态也与“0”、“1”逻辑状态一样作为合法的状态参与比较。这些逻辑状态在进行位取值比较时的真值表如表1所示,其中第一行和第一列是参加比较的两个位的可能逻辑状态,在表中用符号“yes”表示比较结果为“两者相等”,用符号“no”表示比较结果为“两者不相等”。,case, casez, casex 的真值表,我们举一个例子来说明这种“全等比较”的特点, 如例下所示。 例6-22 case语句执行时对“x”状态和“z”状态的处理。 module demo_xz(sig); input sig; always (sig) case(sig) 1b1:$d

32、isplay(“signalvalue is 1”); 1b0:$display(“signalvalue is 0”); 1bx:$display(“signalis in unknown state”); 1bz:$display(“signalis in high impedance state”); endcase endmodule,在例6-22所示模块中,控制表达式为“a”,同时还列出了四个分支项。在进行控制表达式和各个分支项表达式的比较时,“0”、“1”、“x”和“z”这四个逻辑状态将作为四个不同的合法状态参与比较。所以当输入信号a的取值为“x”时,只有第三个分支项表达式与控制表

33、达式的比较结果是“两者相等”,此时第三个分支项后面指定的语句将得到执行;同样,当输入a取值为“z”时,只有第四个分支项表达式与控制表达式的比较结果是“两者相等”,此时将执行第四个分支项后面所指定的语句。 由于case语句有上面这种按位进行全等比较的特点,case语句中的控制表达式和所有分支项表达式必须具有相同的位宽,因为只有这样控制表达式和分支表达式才能进行对应位的比较;当各个分支项表达式以常数形式给出时,必须显式地标明每个常数的位宽,否则Verilog编译器会认为它们具有与机器字长相同的位宽。,例6-23是一个用case语句来实现操作码译码的例子。 module decode_of_opco

34、de_use_case(a,b,opcode,out); input7:0 a,b; input2:1 opcode; output7:0 out; reg 7:0 out; always (a or b or opcode) begin case(opcode) 2b10: out=a+b; 2b11: out=a-b; 2b01: out=(a)+1; 2b00: out=(b)+1; endcase end endmodule,在例6-23所示模块中,输入信号opcode是宽度为两位的操作码,它的取值指定了对输入a,b执行的运算类型: 如果操作码为“2b10”,则求a,b的和(第一个分支

35、项)。 如果操作码为“2b11”,则求a,b的差(第二个分支项)。 如果操作码为“2b01”,则求a的补码(第三个分支项)。 如果操作码为“2b00”,则求b的补码(第四个分支项)。,【例】BCD 码七段数码管显示译码器 module decode4_7(decodeout,indec); output6:0 decodeout; input3:0 indec; reg6:0 decodeout; always (indec) begin,case(indec) 4d0:decodeout=7b1111110; 4d1:decodeout=7b0110000; 4d2:decodeout=7b

36、1101101; 4d3:decodeout=7b1111001; 4d4:decodeout=7b0110011; 4d5:decodeout=7b1011011; 4d6:decodeout=7b1011111; 4d7:decodeout=7b1110000; 4d8:decodeout=7b1111111; 4d9:decodeout=7b1111011; default: decodeout=7bx; endcase end,2 Casez、 Casex语句,Verilog HDL还提供了另外两种形式的case分支语 句,它们是casez语句和casex语句。可以利用它们来 实现这样

37、的分支控制:由控制表达式和分支项表达式 的一部分数位的比较结果来决定程序的流向。 casez语句执行时的比较过程将不考虑控制表达式 及分支项表达式中处于高阻态“z”的那些位的比较, 而casex语句则将高阻状态“z”和不定状态“x”都视为不 必关心的情况。通过这两种形式的分支控制语句,就 可以通过对控制表达式和分支项表达式的灵活设定来 实现由一部分数位取值决定的分支控制。,1) casez语句 casez语句的格式如下: casez () :语句块1; :语句块2; :语句块n; default : 语句块n +1; endcase 从上面的格式我们可以看出:casez语句与case语句的使用

38、格式完全相同,两者唯一的差别是关键词“casez”和“case”的不同。,在casez语句中,如果控制表达式或分支项表达式的某一位取值为“z”,则在分支语句执行时将忽略该位的比较,也就是说这种情况下控制表达式和分支项表达式在这一位的取值将不会对程序流程分支的选择产生任何影响。casez语句进行位取值比较时的真值表如表1所示,其中第一行和第一列是参加比较的两个位的可能取值状态,我们在表中用符号“yes”来表示比较结果为“两者相等”,用符号“no”来表示比较结果为“两者不相等”。,例【6.24】用casez 描述的数据选择器 module mux_casez (out, a, b, c, d, s

39、elect); output out; input a,b,c,d; input3:0 select; reg out; always (select or a or b or c or d) begin Casez (select) 4bzzz1: out = a; 4b?1?: out = b; 4b?1?: out = c; 4b1?: out = d; endcase end endmodule,在例6-24所示的模块中,输入信号select为四位宽的选择信号,它用来指定对于输入a,b,c,d执行的输出,casez语句内的控制表达式为操作码“select”,各个分支项表达式以常量形式给

40、出: 第一个分支项表达式是4bzzz1 ,它的第4、3、2位为“z”,所以控制表达式在与该分支项表达式进行比较时将忽略这三位而只对最低位进行比较。所以只要选择信号select的最高位取值为“1”,两个表达式的比较结果就是“相等”,该分支项对应的语句“out=a;”就得到执行。 第二个分支项表达式是4b?1?: ,它的高二位和低位数值为“?”,这里符号“?”的含义就代表“z”。所以在进行两个表达式的比较时将忽略?位而只对3二位数值进行比较。所以只要选择信号select第3位取值为“1”,就执行第二个分支项对应的语句“out=b;”。,2) casex语句 casex语句的格式如下: casex

41、() :语句块1; :语句块2; :语句块n; default: 语句块n +l; endcase casex语句与case语句以及casez语句所使用的格式完全相同,唯一的差别是这里的关键词为“casex”。,与casez语句一样,casex语句中的控制表达式和分支项表达式在进行比较时将忽略某些位的比较,casex语句和casez语句的不同之处在于:在casex语句中,处于“x”或“z”这两种逻辑状态的位都被忽略;而在casez语句中只忽略处于“z”状态的位。 casex语句在进行数位比较时的真值表如表1所示。,【例6-25】用casex语句实现操作码译码。 module decode_of

42、_opcode_use_casex(a,b,opcode,out); input7:0 a,b; input4:1 opcode; output7:0 out; reg 7:0 out; always (a or b or opcode) begin casex (opcode) 4b1zzx: out=a+b; /分支项1 4b01xx: out=a-b; /分支项2 4b001?: out=(a)+1; /分支项3 4b0001: out=(b)+1; /分支项4 endcase end endmodule,例6-25所示模块中的控制表达式“opcode”在与各个分支项表达式进行比较时,将

43、分别忽略其中取值为“z”、“x”、“?”的位。所以与例6-24的执行一样: 只要操作码opcode最高位取值为“1”,就执行第一个分支项对应的语句“out=a+b;”。 只要操作码opcode最高二位取值为“01”,就执行第二个分支项对应的语句“out=a-b;”。 只要操作码opcode最高三位取值为“001”,就执行第三个分支项对应的语句“out=(a)+1;”。 当操作码opcode等于“4b0001”时,执行第四个分支项对应的语句“out=(b)+1;”。,条件语句使用要点,1 在使用条件语句时,要列出所有条件分支,否则,编译器认为条件不满足时,会引进一个触发器保持原值,这一点可以用在

44、时序逻辑中,但在组合逻辑设计中,应避免这种隐含触发器的存在。可在if语句,写上else项。在case语句,写上default项 2 在硬件语句中使用if语句和case语句的区别。如果有分支情况,尽量使用case语句,这是因为case语句是并行执行的,没有优先级的区别。而if语句的选择分支是串行执行的,是按照书写的顺序逐次判断的。如果设计中没有优先级的考虑,if语句和case语句相比,会占用更多的硬件资源。,错误使用if语句,always (al or d) begin if(al)q=d; end 有锁存器,always (al or d) begin if(al) q=d; else q=0

45、 end 无锁存器,在“always“块内,如果在给定的条件下变量没有赋值,这个变量将保持原值,也就是说会生成一个锁存器!,错误使用case语句,always (sel1:0 or a or b) case(sel1:0) 2b00: q=a; 2b11: q=b; endcase 有锁存器,always (sel1:0 or a or b) case(sel1:0) 2b00: q=a; 2b11: q=b; default: q=b0; endcase 无锁存器,6.6 循环语句,Verilog HDL中有四类循环语句,它们是: 1) forever循环 2) repeat循环 3) wh

46、ile循环 4) for 循环 For循环语句是典型的能用于综合的循环语句。 一个f o r 循环语句按照指定的次数重复执行过程赋值语句若干次。(前三个循环语句综合器一般不支持)。,6.6.1 forever 循环语句,forever循环语句的形式定义: forever 块语句 或 Forever begin 多条语句 end forever循环语句在过程语句中必须使用某种形式的时序控制,否则,forever循环将在0时延后永远循环下去。 forever循环语句常用于产生周期性的波形,用来作为仿真测试信号。它与always不同处在于不能独立写在程序中,而必须写在initial块中,【例6-26

47、】一个由t=1000 ns时刻开始的周期为50 ns的时钟产生器。 module clk_gen(clk); output clk; initial begin clk = 0; #1000; /时间控制 forever #25 clk = clk; /被指定循环执行的语句 end endmodule,上例所产生的时钟信号clk的波形是:在t=0时刻时钟信号首先被初始化为0,并一直保持到t=1000 ns时刻。此后每隔25 ns,时钟信号clk的取值翻转一次。这样就产生了周期为50 ns的时钟波形。 如果需要在某个时刻跳出forever循环语句所指定的 无限循环,则可以通过在循环体语句块中使用

48、中止 语句 (disable语句) 来实现这一目的,比如如下语 句: module clk_gen(clk); output clk; integer counter; initial,begin counter=0; clk = 0; #1000; begin: FOREVER_PART /外层块,有名块 forever begin /内层块,被循环执行的语句块 count=count+1; if(count200) disable FOREVER_PART; #25 clk = clk; end /内层块结束标志 end / FOREVER_PART语句块的结束标志 end endmodule,6.6.2 repeat 循环语句,repeat循环语句实现的是一种循环次数预先指定的循环,这种循环语句内的循环体部分将被重复执行指定的次数。 repeat循环语句的格式如下: repeat () 语句或语句块; 在上述格式中: “”用于指定循环次数,它可以是一个整数、变量或一个数值表达式。如果是变量或数值表达式,其

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1