已阅读5页,还剩94页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【例】同时由两个时钟沿:clk1上升沿和clk2下降沿进行控制的8位移位寄存器。module8bits_shift_register(d_in,d_out,clk1,clk2);inputclk1,clk2,d_in;outputd_out;regd_out;/d_out保存1bitreg1:7data;/reg1:7保存其余7bitsreg1:4i;/i用于循环计数always(posedgeclk1ornegedgeclk2)begind_out=data1;for(i=1;i7;i=i+1)datai=datai+1;data7=d_in;endendmodule,编译的警告,Warning:Designcontains2inputpin(s)thatdonotdrivelogicWarning:Nooutputdependentoninputpinclk1Warning:Nooutputdependentoninputpinclk2,moduleshift_regester(data_in,data_out,clk1);inputdata_in,clk1;outputdata_out;reg1:7reg_data;regdata_out;integeri;always(negedgeclk1)begindata_out=reg_data1;for(i=1;ib)out1=int1;elseout1b)beginout1=int1;out2=int2;endelsebeginout1=int2;out2=int1;end注意在end后不需要再加分号。因为begin_end内是一个完整的复合语句,不需再附加分号,(4).允许一定形式的表达式简写方式。如下面的例子:if(expression)等同与if(expression=1)if(!expression)等同与if(expression!=1)描述一个具有同步清零功能(低电平有效)的上升沿D触发器moduledff_sync(q,d,clear,clk);outputq;inputd,clear,clk;regq;always(posedgeclk)if(!clear)q0)beginfor(scani=0;scani0)begin$display(.);memoryscani=0;endendelse/*WRONG*/$display(error-indexiszero);正确,(6).if_else例子。下面的例子是取自某程序中的一部分。这部分程序用if_else语句来检测变量index以决定三个寄存器modify_segn中哪一个的值应当与index相加作为memory的寻址地址。并且将相加值存入寄存器index以备下次检测使用。程序的前十行定义寄存器和参数,/定义寄存器和参数。reg31:0instruction,segment_area255:0;reg7:0index;reg5:0modify_seg1,modify_seg2,modify_seg3;parametersegment1=0,inc_seg1=1,segment2=20,inc_seg2=2,segment3=64,inc_seg3=4,data=128;/检测寄存器index的值if(indexsegment2)begininstruction=segment_areaindex+modify_seg1;index=index+inc_seg1;end,elseif(indexsegment3)begininstruction=segment_areaindex+modify_seg2;index=index+inc_seg2;endelseif(indexdata)begininstruction=segment_areaindex+modify_seg3;index=index+inc_seg3;endelseinstruction=segment_areaindex,模为60的BCD码加法计数器,modulecount60(qout,cout,data,load,reset,clk);output7:0qout;outputcout;input7:0data;inputload,cin,clk,reset;reg7:0qout;always(posedgeclk)beginif(reset)qout=0;elseif(load)qout=data;elseif(in)begin,if(qout3:0=9)beginqout3:0=0;if(qout7:4=5)qout7:4=0;elseqout7:4=qout7:4+1;endelseqout3:0=qout3:0+1;endendassigncout=(qout=8h59)endmodule,1/2分频器的设计,modulehalf_clk(reset,clk_in,clk_out);inputclk_in,reset;outputclk_out;regclk_out;always(posedgeclk_in)beginif(!reset)clk_out=0;elseclk_out=clk_out;endendmodule,时钟分频器的设计,将10M的时钟分频为500K的时钟。基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/20分频modulefdivision(RESET,F10M,F500K);inputF10M,RESET;outputF500K;regF500K;reg7:0j;,always(posedgeF10M)if(!RESET)/低电平复位。beginF500K=0;j=0;endelsebeginif(j=19)/对计数器进行判断,以确定F500K信号是否反转。beginj=0;F500K=F500K;endelsej=j+1;endendmodule,6.5.2Case语句,当多路选择的控制条件集中在某个变量的变化上时,用case语句加以表达显得更为方便与直观case语句最适宜于对CPU的译码等部件的描述以及对有限状态机的描述case语句分为case、casez、casex共三种表示方式,case语句的表示形式,case语句的格式如下:case():语句块1;:语句块2;:语句块n;default:语句块n+1;endcase在上述格式中:“”代表着对程序流向进行控制的控制信号;各个“”则是控制表达式的某些具体状态取值,在实际使用中这些分支项表达式通常是一些常量表达式;各个“语句块”则指定了在各个分支下所要执行的操作,它们也可以是由单条语句构成的;处于最后的、以关键词“default”开头的那个分支项被称为“default分支项”,它是可以缺省的。,说明,1case括弧内的表达式称为控制表达式,case分支项中的表达式称为分支表达式。控制表达式通常表示为控制信号的某些位,分支表达式则用这些控制信号的具体状态值来表示,因此分支表达式又可以称为常量表达式。2当控制表达式的值与分支表达式的值相等时,就执行分支表达式后面的语句。如果所有的分支表达式的值都没有与控制表达式的值相匹配的,就执行default后面的语句。3default项可有可无,一个case语句里只准有一个default项。,4每一个case分项的分支表达式的值必须互不相同,否则就会出现矛盾现象(对表达式的同一个值,有多种执行方案)。5执行完case分项后的语句,则跳出该case语句结构,终止case语句的执行。6在用case语句表达式进行比较的过程中,只有当信号的对应位的值能明确进行比较时,比较才能成功。因此要注意详细说明case分项的分支表达式的值。7case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用bx,bz来替代nbx,nbz,这样写是不对的,因为信号x,z的缺省宽度是机器的字节宽度,通常是32位(此处n是case控制表达式的位宽)。,case语句的执行过程,(1)当“控制表达式”的取值等于“分支项表达式1”时,执行第一个分支项所包含的“语句块1”。(2)当“控制表达式”的取值等于“分支项表达式2”时,执行第二个分支项所包含的“语句块2”。(3)如果“控制表达式”的取值与所有n个分支项表达式的值都不相同,则执行“default分支项”所包含的“语句块n+1”。(4)在执行了某一分支项内的语句块后,跳出case语句结构,终止case语句的执行。,case语句中各个“分支项表达式”的取值必须是互不相同的,否则就会出现矛盾现象。如果“控制表达式”有几种不同取值情况对应着同一操作,则上述格式可以这样进行简写:用逗号将代表着这几种不同取值情况的多个“分支项表达式”隔开,再将在这些情况下需要执行的语句块放在这几个分支项表达式的后面。比如下面的语句:case(op_code)2b00:out=a|b;/op_code取值为“2b00”时的分支项2b01,2b10,2b11:out=ainputsig;always(sig)case(sig)1b1:$display(“signalvalueis1”);1b0:$display(“signalvalueis0”);1bx:$display(“signalisinunknownstate”);1bz:$display(“signalisinhighimpedancestate”);endcaseendmodule,在例6-22所示模块中,控制表达式为“a”,同时还列出了四个分支项。在进行控制表达式和各个分支项表达式的比较时,“0”、“1”、“x”和“z”这四个逻辑状态将作为四个不同的合法状态参与比较。所以当输入信号a的取值为“x”时,只有第三个分支项表达式与控制表达式的比较结果是“两者相等”,此时第三个分支项后面指定的语句将得到执行;同样,当输入a取值为“z”时,只有第四个分支项表达式与控制表达式的比较结果是“两者相等”,此时将执行第四个分支项后面所指定的语句。由于case语句有上面这种按位进行全等比较的特点,case语句中的控制表达式和所有分支项表达式必须具有相同的位宽,因为只有这样控制表达式和分支表达式才能进行对应位的比较;当各个分支项表达式以常数形式给出时,必须显式地标明每个常数的位宽,否则Verilog编译器会认为它们具有与机器字长相同的位宽。,例6-23是一个用case语句来实现操作码译码的例子。moduledecode_of_opcode_use_case(a,b,opcode,out);input7:0a,b;input2:1opcode;output7:0out;reg7:0out;always(aorboropcode)begincase(opcode)2b10:out=a+b;2b11:out=a-b;2b01:out=(a)+1;2b00:out=(b)+1;endcaseendendmodule,在例6-23所示模块中,输入信号opcode是宽度为两位的操作码,它的取值指定了对输入a,b执行的运算类型:如果操作码为“2b10”,则求a,b的和(第一个分支项)。如果操作码为“2b11”,则求a,b的差(第二个分支项)。如果操作码为“2b01”,则求a的补码(第三个分支项)。如果操作码为“2b00”,则求b的补码(第四个分支项)。,【例】BCD码七段数码管显示译码器moduledecode4_7(decodeout,indec);output6:0decodeout;input3:0indec;reg6:0decodeout;always(indec)begin,case(indec)4d0:decodeout=7b1111110;4d1:decodeout=7b0110000;4d2:decodeout=7b1101101;4d3:decodeout=7b1111001;4d4:decodeout=7b0110011;4d5:decodeout=7b1011011;4d6:decodeout=7b1011111;4d7:decodeout=7b1110000;4d8:decodeout=7b1111111;4d9:decodeout=7b1111011;default:decodeout=7bx;endcaseend,2Casez、Casex语句,VerilogHDL还提供了另外两种形式的case分支语句,它们是casez语句和casex语句。可以利用它们来实现这样的分支控制:由控制表达式和分支项表达式的一部分数位的比较结果来决定程序的流向。casez语句执行时的比较过程将不考虑控制表达式及分支项表达式中处于高阻态“z”的那些位的比较,而casex语句则将高阻状态“z”和不定状态“x”都视为不必关心的情况。通过这两种形式的分支控制语句,就可以通过对控制表达式和分支项表达式的灵活设定来实现由一部分数位取值决定的分支控制。,1)casez语句casez语句的格式如下:casez():语句块1;:语句块2;:语句块n;default:语句块n+1;endcase从上面的格式我们可以看出:casez语句与case语句的使用格式完全相同,两者唯一的差别是关键词“casez”和“case”的不同。,在casez语句中,如果控制表达式或分支项表达式的某一位取值为“z”,则在分支语句执行时将忽略该位的比较,也就是说这种情况下控制表达式和分支项表达式在这一位的取值将不会对程序流程分支的选择产生任何影响。casez语句进行位取值比较时的真值表如表1所示,其中第一行和第一列是参加比较的两个位的可能取值状态,我们在表中用符号“yes”来表示比较结果为“两者相等”,用符号“no”来表示比较结果为“两者不相等”。,例【6.24】用casez描述的数据选择器modulemux_casez(out,a,b,c,d,select);outputout;inputa,b,c,d;input3:0select;regout;always(selectoraorborcord)beginCasez(select)4bzzz1:out=a;4b?1?:out=b;4b?1?:out=c;4b1?:out=d;endcaseendendmodule,在例6-24所示的模块中,输入信号select为四位宽的选择信号,它用来指定对于输入a,b,c,d执行的输出,casez语句内的控制表达式为操作码“select”,各个分支项表达式以常量形式给出:第一个分支项表达式是4bzzz1,它的第4、3、2位为“z”,所以控制表达式在与该分支项表达式进行比较时将忽略这三位而只对最低位进行比较。所以只要选择信号select的最高位取值为“1”,两个表达式的比较结果就是“相等”,该分支项对应的语句“out=a;”就得到执行。第二个分支项表达式是4b?1?:,它的高二位和低位数值为“?”,这里符号“?”的含义就代表“z”。所以在进行两个表达式的比较时将忽略?位而只对3二位数值进行比较。所以只要选择信号select第3位取值为“1”,就执行第二个分支项对应的语句“out=b;”。,2)casex语句casex语句的格式如下:casex():语句块1;:语句块2;:语句块n;default:语句块n+l;endcasecasex语句与case语句以及casez语句所使用的格式完全相同,唯一的差别是这里的关键词为“casex”。,与casez语句一样,casex语句中的控制表达式和分支项表达式在进行比较时将忽略某些位的比较,casex语句和casez语句的不同之处在于:在casex语句中,处于“x”或“z”这两种逻辑状态的位都被忽略;而在casez语句中只忽略处于“z”状态的位。casex语句在进行数位比较时的真值表如表1所示。,【例6-25】用casex语句实现操作码译码。moduledecode_of_opcode_use_casex(a,b,opcode,out);input7:0a,b;input4:1opcode;output7:0out;reg7:0out;always(aorboropcode)begincasex(opcode)4b1zzx:out=a+b;/分支项14b01xx:out=a-b;/分支项24b001?:out=(a)+1;/分支项34b0001:out=(b)+1;/分支项4endcaseendendmodule,例6-25所示模块中的控制表达式“opcode”在与各个分支项表达式进行比较时,将分别忽略其中取值为“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在使用条件语句时,要列出所有条件分支,否则,编译器认为条件不满足时,会引进一个触发器保持原值,这一点可以用在时序逻辑中,但在组合逻辑设计中,应避免这种隐含触发器的存在。可在if语句,写上else项。在case语句,写上default项2在硬件语句中使用if语句和case语句的区别。如果有分支情况,尽量使用case语句,这是因为case语句是并行执行的,没有优先级的区别。而if语句的选择分支是串行执行的,是按照书写的顺序逐次判断的。如果设计中没有优先级的考虑,if语句和case语句相比,会占用更多的硬件资源。,错误使用if语句,always(alord)beginif(al)q=d;end有锁存器,always(alord)beginif(al)q=d;elseq=0end无锁存器,在always块内,如果在给定的条件下变量没有赋值,这个变量将保持原值,也就是说会生成一个锁存器!,错误使用case语句,always(sel1:0oraorb)case(sel1:0)2b00:q=a;2b11:q=b;endcase有锁存器,always(sel1:0oraorb)case(sel1:0)2b00:q=a;2b11:q1;end/循环体语句块结束标志endendmodule,在上例中,repeat循环语句内指定的“循环次数表达式”是一个参数“SIZE”,它代表了数值“8”,于是后面的循环体将被重复执行8次;循环体部分由一个begin-end语句块构成,这个语句块每执行一次就进行一次移位相加操作,在重复执行8次后就完成了两个8位输入操作数的相乘运算。repeat循环语句还有一种特别的用法在此必须加以说明,我们看如下语句块:initialbeginout=0;repeat(NUM)(posedgeclk);out=1;end,在上述initial过程块中,repeat循环语句后面的循环体部分是一条时间控制语句“(posedgeclk);”。在这种情况下,这条repeat循环语句的作用是:等待时钟信号clk的NUM次正跳变。因此下一条语句“out=1;”将在时钟第NUM次正跳变后得到执行,out的低电平状态共保持了NUM个时钟周期的时间。,6.6.3while循环语句,while循环语句实现的循环是一种“条件循环”,就是说只有在指定的条件表达式取值为“真”时才会重复执行循环体,否则就不执行循环体。while循环语句的格式如下:while()语句或语句块;在上述格式中:“”代表了循环体得到继续重复执行时必须满足的条件,它常常是一个逻辑表达式。在每一次执行循环体之前都要对这个条件表达式是否成立进行判断。“语句或语句块”代表了被重复执行的循环体部分。,while循环语句的执行过程是这样的:首先判断条件表达式是否成立,如果成立,则执行后面指定的“语句或语句块(循环体部分)”,然后再次对条件表达式是否成立作出判断,只要其取值为“真”就再次重复执行循环体,直到在某一次循环后判断出条件表达式不成立,循环过程才结束,程序流程退出while循环语句。假如条件表达式在一开始就不成立,则循环体一次也不被执行。例6-29所示过程块是用while循环语句来实现从0计数到100,并在第101次计数时退出循环。,【例6-29】while循环语句。initialbegincount=0;while(count100)begin/循环体语句块$display(“count=%d”,count);#5count=count+1;endend在上例的描述中,while循环控制语句执行时首先判断条件表达式“count1;endendendmodule,6.6.4for循环语句,与while循环语句一样,for循环语句实现的循环也是一种“条件循环”,只有在指定的条件表达式成立时才进行循环。for循环语句的格式如下:for(;)循环体语句或语句块;在上述格式中:“”和“”是两条过程赋值语句,它们分别用来对循环计数变量执行赋初值操作和增值操作。“”代表着循环继续进行时必须满足的条件,它常常是一个逻辑表达式。在每一次执行循环体之前都要对这个条件表达式是否成立进行判断。“循环体语句或语句块”是要被重复执行的循环体部分。,for循环语句的执行过程可以分成如下几步:(1)执行“”。(2)对“”是否成立做出判断:若“条件表达式”取值为真,则执行for循环语句中指定的“循环体语句或语句块”,然后继续执行下面的第(3)步;若“条件表达式”取值不为真,则不再执行循环体部分,循环过程结束,退出for循环语句的执行。(3)执行“”,然后转到(2)继续执行。,由上面说明的执行步骤可以看出:“”只在第一次循环开始之前被执行了一次,它通常是一条给循环计数变量赋初值的过程赋值语句;“”是在每次循环结束后、下一次循环开始前被执行的,它通常用于对循环计数变量的取值进行修改;而“条件表达式”取值的判断是在每次循环开始前发生的,它的结果决定着“是否继续执行循环”。条件表达式的取值往往是随着循环的进行而发生变化的。这是因为:如果条件表达式的取值在整个循环过程中一直保持不变,那么循环体要么是一次都得不到执行,要么是进入被执行无限次循环的死循环状态。,因此,for循环语句实际上等价于由while循环语句构建的如下循环结构:begin;while()begin循环体语句或语句块;endend这样,对于使用while循环语句时需要3条语句才能完成的一个循环控制,for循环语句只需一条语句就可以实现。下面使用for循环语句来描述与例7-11相同的功能。,【例6-30】for循环语句。initialfor(count=0;count100;count=count+1)begin/循环体语句块$display(count=%d,count);#5;end,上例中for循环语句的执行过程是:首先执行“count=0;”,给循环变量count赋初值0;然后判断条件表达式“count100”是否成立,根据判断结果确定是否要继续执行循环体语句块:如果条件表达式成立,则执行循环体语句块,然后语句“count=count+1”得到执行,实现循环变量count的增值操作,然后再重新转回到判断条件表达式那一步。如果条件表达式“count100”不成立,则循环体语句块不被执行,结束循环过程,退出for循环语句的执行。,所以循环变量count将由初值0开始,在每次循环后其值增1。这样条件表达式在前100次循环时始终是成立的,而在开始第101次循环前,count取值为100,此时条件表达式“count100”不再成立,因此这时将结束循环并退出for循环语句的执行。下面再举两个使用for循环语句的例子。例6-31所示模块利用for循环语句实现了在例6-28中用repeat语句来实现的乘法器功能,而例6-32则用for循环语句实现了一个4位左移器。,例用for语句实现2个8位数相乘modulemult_for(outcome,a,b);parametersize=8;inputsize:1a,b;/两个操作数output2*size:1outcome;/结果reg2*size:1outcome;Integeri;always(aorb)beginoutcome=0;for(i=1;i=size;i=i+1)/for语句if(bi)outcome=outcome+(a(i-1);endendmodule,【例6-31】用for循环语句来实现一个8位乘法器。module8_bits_multiplier(result,opa,opb);parameterSIZE=8,LONGSIZE=16;inputSIZE:1opa,opb;outputLONGSIZE:1result;regSIZE:1opa,opb;regLONGSIZE:1result;always(opaoropb)begin:multintegerindex;/循环变量(index)定义result0;for(index=1;index=SIZE;index=index+1)/for循环语句if(opbindex=1)/循环体语句是一条if语句result=result+(opa(index-1);endendmodule,【例6-32】4位左移器。modulefour-bit_left_shifter(result,a,ctrl);input7:0a;inputctrl;output7:0result;reg7:0result;always(aorctrl),begin:DRIFTintegeri;/循环变量(i)定义result=a;if(ctrl=1)/判断控制信号ctrl是否为1begin/如ctrl为1,则执行4位左移操作for(i=4;i=7;i=i+1)resulti=resulti-4;/循环体语句result3:0=0;/低4位赋值为0endendendmodule,同一循环的不同实现方式,moduleloop1;/方式1integeri;initialfor(i=0;i4;i=i+1)/for语句begin$display(“i=%h”,i);endendmodule,moduleloop2;/方式2integeri;initialbegini=0;while(i4)/while语句begin$display(i=%h,i);i=i+1;endendendmodule,moduleloop3;/方式3integeri;initialbegini=0;repeat(4)/repeat语句begin$display(i=%h,i);i=i+1;endendendmodule,6.7生成块,生成语句可以动态生成Verilog代码,使用生成语句能够大大简化程序的编写过程。具体应用如下:对矢量中的多个位进行重复操作时;当进行多个模块的实例引用的重复操作;或者根据参数的定义来确定是否包含某段代码;它的本质是使用循环内的一条语句来代替多条重复的Verilog语句,简化用户的编程。,生成语句能够控制变量的声明、任何和函数的调用,还能对实例引用进行全面的控制。生成块使用关键字enerate_endgenerate来描述并指定范围。生成实例可以是以下的一个或多种类型:1模块2UDP3primitve4连续赋值语句5initial和always块生成的实例有唯一的标识名,可以用层次命名规则引用。,允许在生成范围内声明的数据类型:1net、reg2integer、real、time、realtime3evet生成的数据类型有唯一的标识名,可以被层次引用不允许出现在生成范围之中的模块项声明包括:1参数、局部参数2输入、输出和输入/输出声明3指定块。,创建生成语句的方法,1循环生成2条件生成3case生成,6.7.1循环生成语句,循环生成语句允许对下面的模块和模块项进行多次实例调用:1变量声明2模块3UDP、Primitve4连续复制语句5initial和always块,程序完成的功能是实现对两个N位总线变量进行按位异或;Verilog中生成块的有效范围为generate_endgenerate;genvar用来声明一个临时循环变量,parameterN=32
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 论文的研究目标怎么写 范例
- 成本管理的参考论文范文
- 二级甲等医院复核评审检查反馈意见整改方案
- 略论贺铸词的艺术特色
- 文学类论文提纲范文
- 085210控制工程领域工程硕士专业学位基本要求
- 本科毕业设计(论文)专用书【模板】
- 工程合同一方是假印章(3篇)
- 工程合同收款方银行账户(3篇)
- 兰州交通大学文学与国际汉学院毕业论文撰写规范
- 《投资银行》或《资本运营》风险投资业务课件
- DBJ50T-163-2021 既有公共建筑绿色改造技术标准 清晰正式版
- 低阶煤、褐煤干法制备气化用高浓度水煤浆技术
- GB∕T 37458-2019 城郊干道交通安全评价指南
- 盘锦浩业芳烃抽提装置操作规程
- DB33_T 2301-2020番茄水肥一体化技术规程(高清正版)
- 路面病害处理专项施工组织方案
- 农药基础知识培训
- (高清版)辐射供暖供冷技术规程JGJ142-2012
- 利雅路燃气燃烧器说明书
- 校长在教育教学质量分析会上的表态发言
评论
0/150
提交评论