版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VerilogHDL数字逻辑电路设计方法11/11/202414.1VerilogHDL语言设计思想和可综合特性11/11/20242例4.1-1:用VerilogHDL设计模256(8bits)计数器(a)可综合程序描述方式modulecounter(count,clk,reset);output[7:0]count;inputclk,reset;reg[7:0]count;always@(posedgeclk)if(!reset)count<=0;elseif(count==8'b11111111)count<=0;elsecount<=count+1;endmodule(b)常见的错误描述方式modulecounter(count,clk,reset);output[7:0]count;inputreset,clk;reg[7:0]count;integeri;always@(posedgeclk,reset)beginif(!reset)count<=0;elsefor(i=0;i<=255;i=i+1)count<=count+1;endendmodule同时VerilogHDL的电路描述方式具有多样性,这也决定了对于电路设计的多样性。11/11/20243例4.1-2:用VerilogHDL设计数字多路选择器(a)采用真值表形式的代码:moduleMUX(out,data,sel);outputout;input[3:0]data;input[1:0]sel;regout;always@(dataorsel)case(sel) 2'b00:out<=data[0];2'b01:out<=data[1];2'b10:out<=data[2];2'b11:out<=data[3];endcaseendmodule(b)采用逻辑表达式形式的代码:moduleMUX(out,data,sel);outputout;input[3:0]data;input[1:0]sel;wirew1,w2,w3,w4;assignw1=(~sel[1])&(~sel[0])&data[0];assignw2=(~sel[1])&sel[0]&data[1];assignw3=sel[1]&(~sel[0])&data[2];assignw4=sel[1]&sel[0]&data[3];assignout=w1|w2|w3|w4;endmodule11/11/20244(c)采用结构性描述的代码:moduleMUX(out,data,sel);outputout;input[3:0]data;input[1:0]sel;wirew1,w2,w3,w4;not U1(w1,sel[1]); U2(w2,sel[0]);and U3(w3,w1,w2,data[0]); U4(w4,w1,sel[0],data[1]); U5(w5,sel[1],w2,data[2]); U6(w6,sel[1],sel[0],data[3]);or U7(out,w3,w4,w5,w6);endmodule在现阶段,作为设计人员熟练掌握VerilogHDL程序设计的多样性和可综合性,是至关重要的。作为数字集成电路的基础,基本数字逻辑电路的设计是进行复杂电路的前提。本章通过对数字电路中基本逻辑电路的VerilogHDL程序设计进行讲述,掌握基本逻辑电路的可综合性设计,为具有特定功能的复杂电路的设计打下基础。4.2VerilogHDL组合电路设计组合电路的特点是:电路中任意时刻的稳态输出仅仅取决于该时刻的输入,而与电路原来的状态无关。组合电路的设计需要从以下几个方面考虑:所用的逻辑器件数目最少,器件的种类最少,且器件之间的连线最简单。这样的电路称“最小化”电路;其次,为了满足速度要求,应使级数尽量少,以减少门电路的延迟;电路的功耗应尽可能的小,工作时稳定可靠。描述组合逻辑电路有四种方式:结构描述、逻辑代数、真值表、抽象描述。11/11/20245例4.2-1:设计一个3个裁判的表决电路,当两个或两个以上裁判同意时,判决器输出“1”,否则输出“0”。方法1:真值表方式真值表是对电路功能最直接和简单的描述方式。根据电路的功能,可以通过真值表直接建立起输出与输入之间的逻辑关系。例4.2-1有三个输入端A、B、C和一个输出端OUT。11/11/20246ABCOUT0000001001001000011110111101111111/11/20247在VerilogHDL中,可以使用“case”语句对电路进行描述性设计,表4.2-1真值表设计代码如下:moduledesingn(OUT,A,B,C);outputOUT;inputA,B,C;regOUT;always@(AorBorC)case({A,B,C})3'b000:OUT<=0;3'b001:OUT<=0;3'b010:OUT<=0;3'b100:OUT<=0;3'b011:OUT<=1;3'b101:OUT<=1;3'b110:OUT<=1;3'b111:OUT<=1;endcaseendmodule方法2:逻辑代数方式对于组合电路的另一种表达方法是逻辑代数方法。主要思想是将真值表用卡诺图表示,然后化简电路,得出逻辑函数表达式。通过对卡诺图的化简,可以得到组合电路逻辑输出与输入之间的逻辑函数表达式:
11/11/20248根据逻辑函数表达式可以很方便写出采用逻辑代数描述方式的VerilogHDL程序。moduledesingn(OUT,A,B,C);outputOUT;inputA,B,C;assignOUT=(A&B)|(B&C)|(A&C);endmodule11/11/20249方法3:结构描述方式结构性描述方式是对电路最直接的表示,早期的数字电路设计通常采用的原理图设计实际上就是一种结构性描述方式。moduledesingn(OUT,A,B,C);outputOUT;inputA,B,C;andU1(w1,A,B);andU2(w2,B,C);andU3(w3,A,C);orU4(OUT,w1,w2,w3);
endmodule方法4:抽象描述方式VerilogHDL还提供了采用抽象描述进行电路设计的方法,可以直接从电路功能出发,编写代码。例如判决器设计,将三个输入的判决相加,当判决成功时相加器之和大于1,即表示投票成功。11/11/202410moduledesingn(OUT,A,B,C);outputOUT;inputA,B,C;wire[1:0]sum;regOUT;assignsum=A+B+C;always@(sum)if(sum>1) OUT=1; else OUT=0;endmoduleEDA综合工具可以将VerilogHDL程序综合成物理电路形式,通过电路优化,可以得到符合设计要求的最简化电路。采用Synplify软件对上面四种方法设计的VerilogHDL程序进行综合(采用Altera公司StratixII器件),可以得相同的最简化电路。11/11/2024114.2.1数字加法器
数字加法器是最为常用的一种数字运算逻辑,被广泛用于计算机、通信和多媒体数字集成电路中例4.2-2:2输入1bit信号全加器。如果运算考虑了来自低位的进位那么该运算就为全加运算,实现全加运算的电路称为全加器。11/11/202412ABC_INSUMC_OUT0000000110010100110110010101011100111111代数逻辑表示为11/11/202413
对应的电路为图
SUM=A⊕B⊕C_INVerilogHDL可以用不同的描述方式写出一位全加器,其综合电路是相同的,仅仅是描述风格不同。11/11/202414(1)利用连续赋值语句实现moduleone_bit_fulladder(SUM,C_OUT,A,B,C_IN);input A,B,C_IN;output SUM,C_OUT;assign SUM=(A^B)^C_IN;assignC_OUT=(A&B)|((A^B)&C_IN);//functionofoutputendmodule(2)利用行为描述实现moduleone_bit_fulladder(SUM,C_OUT,A,B,C_IN);output SUM,C_OUT;input A,B,C_IN;assign {C_OUT,SUM}=A+B+C_IN;endmodule采用行为描述可以提高设计的效率,对于一个典型的多位加法器的行为描述设计,仅需改变代码中输入和输出信号的位宽即可,例如一个2输入8bits加法器,可以采用下面的VerilogHDL程序代码实现。11/11/202415moduleeight_bit_fulladder(SUM,C_OUT,A,B,C_IN);output[7:0] SUM;output C_OUT;input[7:0] A,B;input C_IN;assign{C_OUT,SUM}=A+B+C_IN;endmodule例4.2-3:4位超前进位加法器超前进位加法器是一种高速加法器,每级进位由附加的组合电路产生,高位的运算不需等待低位运算完成,因此可以提高运算速度。根据对于输入信号位宽为N的全加器,其进位信号是:输出的加法结果是超前进位标志信号是进位产生函数是11/11/202416
进位传输函数是上述公式中N为加法器位数,在4位加法器中,N=4。由式可以推出各级进位信号表达式,并构成快速进位逻辑电路。11/11/2024174位超前进位加法器的电路如图所示11/11/2024184位超前进位加法器对应的VerilogHDL代码是:11/11/202419modulefour_bits_fast_addder(sum_out,c_out,a,b,c_in);input[3:0] a,b; //theotherofaddnumberinput c_in; //carryinfrombeforeleveloutput[3:0] sum_out; //theaddoftwoinputoutput c_out; //carryouttonextlevelwire[4:0] g,p,c; //wirebetweeneveryc_outandc_inassignc[0]=c_in;assignp=a|b;assigng=a&b;assignc[1]=g[0]|(p[0]&c[0]);assignc[2]=g[1]|(p[1]&(g[0]|(p[0]&c[0])));assignc[3]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))));assignc[4]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));assignsum_out=p^c[3:0];assignc_out=c[4];endmodule4.2.2数据比较器数据比较器是用来对两个二进制数的大小进行比较,或检测是否相等的逻辑电路。数据比较器包含两个部分:一是比较两个数的大小;二是检测两个数是否一致。例4.2-4:4位数值比较器多位数值比较器的比较过程是由高位到底位逐位进行比较,而且只有在高位相等时,才进行低位比较。4位数值比较器中进行A3A2A1A0和B3B2B1B0的比较时,应首先比较最高位A3和B3。如果A3>B3,那么不管其它几位数为何值,结果为A>B;若A3<B3,结果为A<B。如果A3=B3,就必须通过比较低一位A2和B2来判断A和B的大小。如果A2=B2,还必须通过比较更低一位A1和B1来判断,直到最后一位的比较。如果完全相等,则由前一级结果C确定。11/11/2024204位数据比较器真值表11/11/202421输入输出A3B3A2B2A1B1A0B0CA>BCA=BCA<BFA>BFA=BFA<BA3>B3xxxxxxxxx100A3<B3xxxxxxxxx001A3=B3A2>B2xxxxxxx100A3=B3A2<B2xxxxxxx001A3=B3A2=B2A1>B1xxxxx100A3=B3A2=B2A1<B1xxxxx001A3=B3A2=B2A1=B1A0>B0xxx100A3=B3A2=B2A1=B1A0<B0xxx001A3=B3A2=B2A1=B1A0=B0CA>BCA=BCA<BCA>BCA=BCA<Bmodulefour_bits_comp1(F,A,B,C);parametercomp_width=4;output[2:0]F;input[2:0]C;input[comp_width-1:0]A;input[comp_width-1:0]B;reg[2:0]F;always@(AorBorC)if(A>B) F=3'b100;elseif(A<B) F=3'b001;else F=C;endmodule4.2.3数据选择器数据选择器又称多路选择器(Multiplexer,简称MUX),它有n位地址输入、2n位数据输入,1位数据输出。每次在输入地址的控制下,从多路输入数据中选择一路输出,其功能类似于一个单刀多掷开关,如图所示。11/11/202422例4.2-5:8选1数据选择器8选1数据选择器可以由多个2选1数据选择器搭成,也可以采用抽象描述方式进行设计。可以采用2选1数据选择器串行连接,也可以用树形连接分成三级实现。11/11/202423(1)多个2选1数据选择器的结构级描述modulemux8to1_2(d_out,d_in,sel);output d_out;input[7:0] d_in;input[2:0] sel;wire[3:0] w1;wire[1:0] w2;assignw1=sel[0]?{d_in[7],d_in[5],d_in[3],d_in[1]}:{d_in[6],d_in[4],d_in[2],d_in[0]};assignw2=sel[1]?{w1[3],w1[1]}:{w1[2],w1[0]};assignd_out=sel[2]?w2[1]:w2[0];endmodule(2)抽象描述方式对于多路选择器的设计,可以采用“case”语句直接进行设计,在这种设计方式中,只需考虑选择信号列表,就可以实现功能更为复杂的数据选择器。11/11/202424modulemux8to1(out,sel,data_in);outputout;input[7:0]data_in;input[3:0]sel;regout;always@(data_inorsel)case(sel)3'b000:out<=data_in[0];3'b001:out<=data_in[1];3'b010:out<=data_in[2];3'b011:out<=data_in[3];3'b100:out<=data_in[4];3'b101:out<=data_in[5];3'b110:out<=data_in[6];3'b111:out<=data_in[7];endcaseendmodule4.2.4数字编码器用文字、符号或数码表示特定对象的过程称为编码。在数字电路中用二进制代码表示有关的信号称为二进制编码。实现编码操作的电路叫做编码器。例4.2-6:3位二进制8-3线编码器用n位二进制代码对N=2n个一般信号进行编码的电路,叫做二进制编码器。例如n=3,可以对8个一般信号进行编码。这种编码器有一个特点:任何时刻只允许输入一个有效信号,不允许同时出现两个或两个以上的有效信号。11/11/202425右图是3位二进制8线—3线编码器框图3位二进制8线—3线编码器真值表11/11/202426输入输出I0I1I2I3I4I5I6I7F2F1F01000000000001000000001001000000100001000001100001000100000001001010000001011000000001111modulecode_8to3(F,I);output[2:0]F;input[7:0]I;reg[2:0]F;always@(I)case(I)8'b00000001:F=3'b000;8'b00000010:F=3'b001;8'b00000100:F=3'b010;8'b00001000:F=3'b011;8'b00010000:F=3'b100;8'b00100000:F=3'b101;8'b01000000:F=3'b110;8'b10000000:F=3'b111;default:F=3'bx;endcaseendmodule例4.2-7:8线—3线优先编码器二进制编码器电路要求任何时刻只有一个输入有效,若同时有两个或更多个输入信号有效时,将造成输出混乱状态,因此在使用过程中有一定局限性。为了克服对于输入信号的要求,一种方法是采用优先编码器。优先编码器允许多个输入信号同时有效,但它只按其中优先级别最高的有效输入信号编码,对级别低的输入信号不予理睬。11/11/2024278线—3线优先编码器功能表11/11/202428输入输出1xxxxXxxx111110xxxxXxx0000100xxxxXx01001100xxxxX011010100xxxx0111011100xxx01111100100xx011111101100x0111111110100011111111111001111111111101功能表说明:=1时,电路处于禁制工作状态,此时无论8个输入为何种状态,三个输出端均为高电平,和也为高电平,编码器不工作。当=0时,电路处于正常工作状态,允许~当中同时几个输入端为低电平,即同时有几路编码输入信号有效。在8个输入中,的优先权最高,的优先权最低。表中出现的3种输出=111的情况可以用和的不同状态来区别,即如果=111且=10,则表示电路处于工作状态而且有编码信号输入;如果=111且=01,则表示电路处于工作状态但没有输入编码信号。由于没有输入编码信号时=0,因此也可以称为“无编码输入”信号。11/11/202429modulemux8to3_p(data_out,Ys,Yex,sel,data_in);output[2:0]data_out;outputYs,Yex;input[7:0]data_in;inputsel;reg[2:0]data_out;regYs,Yex;always@(data_inorsel)if(sel){data_out,Ys,Yex}={3'b111,1'b1,1'b1};elsebegincasex(data_in)8'b0???????:{data_out,Ys,Yex}={3'b000,1'b1,1'b0};8'b10??????:{data_out,Ys,Yex}={3'b001,1'b1,1'b0};8'b110?????:{data_out,Ys,Yex}={3'b010,1'b1,1'b0};8'b1110????:{data_out,Ys,Yex}={3'b011,1'b1,1'b0};8'b11110???:{data_out,Ys,Yex}={3'b100,1'b1,1'b0};8'b111110??:{data_out,Ys,Yex}={3'b101,1'b1,1'b0};8'b1111110?:{data_out,Ys,Yex}={3'b110,1'b1,1'b0};8'b11111110:{data_out,Ys,Yex}={3'b111,1'b1,1'b0};8'b11111111:{data_out,Ys,Yex}={3'b111,1'b0,1'b1};endcaseendendmodule例4.2-8:二进制转化十进制8421BCD编码器将十进制数0、1、2、3、4、5、6、7、8、9等十个信号编成二进制代码的电路叫做二进制转化十进制编码器。它的输入是代表0~9这10个数子的状态信息,有效信号为1(即某信号为1时,则表示要对它进行编码),输出是相应的BCD码,因此也称10线—4线编码器。它和二进制编码器特点一样,任何时刻只允许输入一个有效信号。11/11/2024308421BCD码编码表11/11/202431十进制数DCBA0(Y0)00001(Y1)00012(Y2)00103(Y3)00114(Y4)01005(Y5)01016(Y6)01107(Y7)01118(Y8)10009(Y9)1001moduleBCD8421(data_out,data_in);output[3:0]data_out;input[8:0]data_in;reg[3:0]data_out;always@(data_in)case(data_in)9'b000000000:data_out=4'b0000;9'b000000001:data_out=4'b0001;9'b000000010:data_out=4'b0010;9'b000000100:data_out=4'b0011;9'b000001000:data_out=4'b0100;9'b000010000:data_out=4'b0101;9'b000100000:data_out=4'b0110;9'b001000000:data_out=4'b0111;9'b010000000:data_out=4'b1000;9'b100000000:data_out=4'b1001;default:data_out=4'b0000;endcaseendmodule例4.2-9:8421BCD十进制余3编码器和8421BCD编码一样,余3码是也一种BCD编码,这种编码的特点是,余3码作十进制加法运算的时候,若2数之和是10,正好等于二进制数的16,于是便从高位自动产生进位信号,因此可以使用余3码简化计算。余3码是8421BCD码加3,并将其转换为等价二进制数就得到了该十进制数的余3码。余3码编码表:11/11/202432十进制数8421BCD码余00000001110001010020010010130011011040100011150101100060110100170111101081000101191001110011/11/202433modulecode_change(B_out,B_in);output[3:0]B_out;input[3:0]B_in;assignB_out=B_in+2'b11;endmodule4.2.5数字译码器译码是编码的逆过程,它将二进制代码所表示的信息翻译成相应的状态信息。实现译码功能的电路成为译码器。11/11/202434图为2线—4线译码器的逻辑电路及逻辑符号。图中A1,A0为地址输入端,A1为高位。、、、为状态信号输出端,非号表示低点平有效。E为使能端(或称选通控制端),低电平有效。当E=0时,允许译码器工作,~中只允许一个为有效电平输出;当E=1时,禁制译码器工作,所有输出~均为高电平。一般使能端有两个用途:一是可以引入选通脉冲,以抑制冒险脉冲的发生;二是可以用来扩展输入变量数(功能扩展)。2线—4线译码器功能表从表还可以看出,当E=0时,2线—4线译码器的输出函数分别为:,,,,如果用表示i端的输出,mi表示输入地址变量A1,A0的一个最小项,则输出函数可写成
(i=0,1,2,3)可见,译码器的每一个输出函数对应输入变量的一组取值,当使能端有效(E=0)时,它正好是输入变量最小项的非。因此变量译码器也称最小项发生器。11/11/202435EA1A21XX1111000011100110110101101011111011/11/202436moduledecode_2to4(Y,E,A);output[3:0]Y;input[1:0]A;inputE;assignY[0]=~(~E&~A[1]&~A[0]);assignY[1]=~(~E&~A[1]&A[0]);assignY[2]=~(~E&A[1]&~A[0]);assignY[3]=~(~E&A[1]&A[0]);endmodule也可以采用抽象描述方式进行设计,VerilogHDL程序代码是:moduledecode_2to4(Y,E,A);output[3:0]Y;input[1:0]A;inputE;reg[3:0]Y;always@(EorA)case({E,A})3'b1??:Y=4'b0000;3'b000:Y=4'b0001;3'b001:Y=4'b0010;3'b010:Y=4'b0100;3'b011:Y=4'b1000;default:Y=4'b0000;endcaseendmodule4.2.6奇偶校验器奇偶校验器的功能是检测数据中包含“1”的个数是奇数还是偶数。在计算机和一些数字通信系统中,常用奇偶校验器来检查数据传输和数码记录中是否存在错误。奇偶校验包含两种方式:奇校验和偶校验。奇校验保证传输数据和校验位中“1”的总数为奇数。如果数据中包含奇数个“1”,则校验位置“0”,如果数据中包含偶数个“1”,则校验位置“1”。偶校验保证传输数据和校验位中“1”的总数为偶数。如果数据中包含奇数个“1”,则校验位置“1”,如果数据中包含偶数个“1”,则校验位置“0”。奇偶校验只能检测部分传输错误,它不能确定错误发生在哪位或哪几位,所以不能进行错误校正。当数据发生错误时只能重新发送数据。11/11/202437例4.2-10:8bits奇偶校验器8bits奇偶校验器的原理图如图所示:图中,校验器的输入b0~b7由7bits数据和1bit校验位组成。FOD为判奇输出,FEV为判偶输出。当采用奇校验时,FOD=1,FEV=0;当采用偶校验时,FOD=0,FEV=1。11/11/20243811/11/202439(a)结构性描述代码:modulechecker(Fod,Fev,b);outputFod,Fev;input[7:0]b;wirew1,w2,w3,w4,w5,w6;xorU1(w1,b[0],b[1]);xorU2(w2,b[2],b[3]);xorU3(w3,b[4],b[5]);xorU4(w4,b[6],b[7]);xorU5(w5,w1,w2);xorU6(w6,w3,w4);xorU7(Fod,w5,w6);notU8(Fev,Fod);endmodule(b)采用抽象性描述代码:modulechecker(Fod,Fev,b);outputFod,Fev;input[7:0]b;assignFod=^b;assignFev=~Fod;endmodule4.3时序电路设计
与组合逻辑电路不同,时序逻辑电路的输出不仅与当前时刻输入变量的取值有关,而且与电路的原状态,即与过去的输入情况有关。时序逻辑电路有两个特点:(1)时序逻辑电路包括组合逻辑电路和存储电路两部分,存储电路具有记忆功能,通常由触发器组成;(2)存储电路的状态反馈到组合逻辑电路输入端,与外部输入信号共同决定组合逻辑电路的输出。11/11/20244011/11/202441同步时序电路设计流程:例4.3-1:用VerilogHDL设计一个“111”的序列检测器,当输入三个或三个以上“1”时,电路输出为1,否则为0。(1)状态转移图方法S0:初始状态,表示电路还没有收到一个有效的1。S1:表示电路收到了一个1。S2:表示电路收到了连续两个1。S3:表示电路收到了连续三个1。11/11/20244211/11/202443modulechecker(z,x,clk);parameters0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;outputz;inputx,clk;reg[1:0]state,next_state;regz;always@(stateorx)case(state)s0:if(x)beginnext_state<=s1;z=0;endelsebeginnext_state<=s0;z=0;ends1:if(x)beginnext_state<=s2;z=0;endelse
beginnext_state<=s0;z=0;ends2:if(x)beginnext_state<=s3;z=1;endelsebeginnext_state<=s0;z=0;ends3:if(x)beginnext_state<=s3;z=1;endelsebeginnext_state<=s0;z=0;endendcasealways@(posedgeclk) state<=next_state;endmodule(2)基于状态化简的结构性描述方法
对状态转移图化简,仅剩三个状态,需要两位二进制表示,即需要两个D触发器储存状态。设Q1表示高位寄存器的输出,Q0表示地位寄存器的输出。将状态的跳转以及输出Z用卡诺图表的形式示出,如下:11/11/202444由卡诺图可以得出电路的输出方程和状态方程:11/11/202445Q1n+1=Q0n
Q0n+1=XZ=Q1nQ0nX//序列检测器模块modulechecker(z,x,clk);outputz;inputx,clk;wirew1,w2;DFFU1(.clk(clk),.D(x),.Q(w1));DFFU2(.clk(clk),.D(w1),.Q(w2));assignz=x&w1&w2;endmodule//D触发器模块moduleDFF(Q,D,clk);outputQ;inputD,clk;regQ; always@(posedgeclk)Q<=D;endmodule(3)VerilogHDL抽象性描述方法在VerilogHDL中还可以对电路进行抽象的描述。实现序列“111”的检测,可以使用一个三位的移位寄存器,将输出X作为移位寄存器的输出,当寄存器中为111时,输出Z为1。11/11/202446VerilogHDL程序代码是:modulechecker(z,x,clk);outputz;inputx,clk;reg[2:0]q;regz; always@(posedgeclk) q<={q[1:0],x}; always@(posedgeclk) if(q==3'b111) z=1; else z=0;endmodule4.3.1触发器触发器是时序电路的最基本电路单元,主要有D触发器、JK触发器、T触发器和RS触发器等。根据功能要求的不同,触发器还具有置位、复位、使能、选择等功能。例4.3-2:最简D触发器输入端的数据D在时钟clk的上升沿被送入触发器,使得Q=D。其特征方程可描述为Qn+1=Dn。11/11/202447clkDQnQn+10X000X111X001X11↑000↑010↑101↑111VerilogHDL程序代码是:module DFF(q,clk,data_in);outputq;inputclk,data_in;regq;always@(posedgeclk) q<=data_in;endmodule例4.3-3:带复位端D触发器在D触发器的实际使用中,有时需要一个复位端(也称清零端)。11/11/202448同步清0的D触发器moduleDFF_rst(q,clk,rst_n,data_in);outputq;inputclk,rst_n,data_in;regq;always@(posedgeclk)if(!rst_n) q<=0;else q<=data_in;endmodule异步清0的D触发器moduleDFF_srst(q,clk,rst_n,data_in,);outputq;inputclk,rst_n,data_in;regq;always@(posedgeclkornegedgerst_n)if(!rst_n) q<=0;else q<=data_in;endmodule例4.3-4:复杂功能D触发器同步清零、置1和异步清零、置1共同在一个触发器上的复杂D触发器例子。11/11/202449moduleDFF_1(q,qb,clk,rst_n1,set1,rst_n2,set2,data_in,);outputq,qb;inputclk,rst_n1,rst_n2,set1,set2,data_in;regq,qb;always@(posedgeclk)if(!rst_n1) q<=0;else q<=data_in;always@(posedgeclkorrst_n2)if(!rst_n2) q<=0;else q<=data_in;endmodulemoduleDFF_1(q,qb,clk,rst_n1,set1,rst_n2,set2,data_in,);outputq,qb;inputclk,rst_n1,rst_n2,set1,set2,data_in;regq,qb;always@(posedgeclk)if(!rst_n1) q<=0;else q<=data_in;always@(posedgeclkorrst_n2)if(!rst_n2) q<=0;else q<=data_in;endmodule例4.3-5:T触发器T触发器的逻辑符号如图4.3-10所示,其逻辑功能为:当时钟的有效边沿到来时,如果T=1,则触发器翻转;如果T=0,则触发器的状态保持不变。R为复位端,异步复位,低电平有效。11/11/202450T触发器VerilogHDL程序代码是:moduleTFF(data_out,T,clk,rst_n);outputdata_out;inputT,clk,rst_n;regdata_out;always@(posedgeclkornegedgerst_n)if(!rst_n) data_out<=1'b0;elseif(T) data_out<=~data_out;endmodule4.3.2计数器例4.3-6:2进制的计数器11/11/202451modulecomp2bit(Q,clk,rst_n);outputQ;inputclk,rst_n;regQ;always@(posedgeclkornegedgerst_n)if(!rst_n)Q<=1'b0;elseQ<=~Q;endmodule例4.3-7:任意模值的计数器任意模值M的计数器,第一步需要确定计数器所需要触发器个数。N个触发器对应了2N个状态。应有2N>M。任意模值计数器选取满足条件的最小N,N为计数器中触发器的个数。有两种方法实现:反馈清零法和反馈置数法。11/11/202452下面是采用反馈清零法设计的模11计数器的VerilogHDL程序代码:modulecomp_11(count,clk,rst);output[3:0]count;inputclk,rst;reg[3:0]count;always@(posedgeclk)if(rst) count<=4'b0000;elseif(count==4'b1010)count<=4'b0000;elsecount<=count+1;endmodule4.3.3移位寄存器移位寄存器可以用来实现数据的串并转换,也可以构成移位行计数器,进行计数、分频,还可以构成序列码发生器、序列码检测器等,它也是数字系统中应用非常广泛的时序逻辑部件之一。例4.3-8:环形移位寄存器N位环型寄存器由N个移位寄存器组成,它可以实现环型移位11/11/202453这个例子中,将每个寄存器的输出作为下一位寄存器的输入,并将高位寄存器的输出作为循环的输入。11/11/202454moduleshiftregist1(D,clk,rst_n);parametershiftregist_width=4;output[shiftregist_width-1:0]D;inputclk,rst_n;reg[shiftregist_width-1:0]D;always@(posedgeclk)if(!rst_n)D<=4'b0000;elseD<={D[shiftregist_width-2:0],D[shiftregist_width-1]};endmodule4.3.4序列信号发生器序列信号是数字电路系统中常用的功能单元,按照序列循环长度M和触发器数目n的关系一般可分为三种:(1)最大循环长度序列码,M=2n。(2)最长线形序列码(m序列码),M=2n-1。(3)任意循环长度序列码,M<2n。序列信号发生器是能够产生一组或多组序列信号的时序电路,它可以由纯时序电路构成,也可以由包含时序和组合逻辑的混合电路构成。11/11/202455例4.3-9:用VerilogHDL设计一个产生100111序列的信号发生器。方法(1):由移位寄存器构成由于移位寄存器输入和输出信号之间没有组合电路,不需要进过组合逻辑的反馈运算,因此这种序列产生电路的工作频率很高。缺点是移位寄存器长度取决于序列长度,因此占用电路的面积很大。11/11/202456modulesignal_maker(out,clk,load,D);parameterM=6;outputout;inputclk,load;input[M-1:0]D;reg[M-1:0]Q;always@(posedgeclk)if(load) Q<=D;else Q<={Q[M-2:0],Q[M-1]};assignout=Q[M-1];endmodule方法(2):由移位寄存器和组合逻辑电路构成反馈移位型序列码发生器的结构框图如图所示,它由移位寄存器和组合逻辑网络组成,从移位寄存器的某一输出端可以得到周期性的序列码。其设计按以下步骤进行:(1)根据给定序列信号的循环周期M,确定移位寄存器位数n,2n-1<M≤2n。(2)确定移位寄存器的M个独立状态。11/11/202457将给定的序列码按照移位规律每n位一组,划分为M个状态。若M个状态中出现重复现象,则应增加移位寄存器位数。用n+1位再重复上述过程,直到划分为M个独立状态为止。(3)根据M个不同的状态列出移位寄存器的态序表和反馈函数表,求出反馈函数F的表达式。(4)检查自启动性能。与上面的序列信号发生器相比,各个寄存器的输出需要经过反馈网络,然后才连接到移位寄存器的输入端。因此,电路的速度必然下降,但反馈网络的好处在于它可以节省寄存器。对于“100111”序列的信号发生器。首先,确定所需移位寄存器的个数n。因M=6,故n≥3。然后,确定移位寄存器的六个独立状态。11/11/202458按照规律每三位一组,划分六个状态为100、001、011、111、111、110。其中状态111重复出现,故取n=4,并重新划分状态,得到:1001、0011、0111、1111、1110、1100。因此确定n=4。第三,列态序表和反馈激励函数表,求反馈函数F的表达式。首先列出态序表,然后根据每一状态所需要的移位输入即反馈输入信号,列出反馈激励函数表,如下表所示。求得反馈激励函数:11/11/202459Q0Q1Q2Q3F10011001110111111110111001100111/11/202460反馈移位型序列信号发生器的VerilogHDL程序代码是:modulesignal_maker(out,clk,load,D);parameterM=4;outputout;inputclk,load;input[M-1:0]D;reg[M-1:0]Q;wirew1;always@(posedgeclk)if(load)Q<=D;elseQ<={Q[M-2:0],w1};assignw1=(~Q[3])|((~Q[1])&(~Q[0]))|(Q[3]&(~Q[2]));assignout=Q[M-1];endmodule方法(3):由计数器构成计数型序列信号发生器和反馈型序列信号发生器大体相同,它们都是由时序电路和组合电路两部分构成。不同在于,反馈型序列信号发生器的时序状态由移位寄存器产生,输出取寄存器的最高位;而在计数型序列信号发生器中,采用计数器代替移位寄存器产生时序状态,输出由组合电路产生。11/11/202461计数型的好处在于,计数器的状态设置与输出序列没有直接关系,不需要像上面一样,根据输出确定状态。只需要将反馈网络设计好就可以了。因此计数结构对于输出序列的更改比较方便,而且只要连接到不同的反馈网络,它可以同时产生多组序列码。设计过程分为两步:第一,根据序列码的长度M设计模M计数器,状态可以自定;第二,按计数器的状态转移关系和序列码的要求设计组合输出网络。对于“100111”序列的信号发生器。序列信号的M值为6,因为需选用模6的计数器。计数器的状态选择从000到101。可以得到输出的组合逻辑真值表。11/11/202462Q2Q1Q0OUT000100100100011110011011由真值表可画出输出Z的卡诺图,得到输出函数:VerilogHDL程序代码是:11/11/202463modulesignal_maker(OUT,clk,reset);parameterM=3;outputOUT;inputclk,reset;reg[M-1:0]counter;always@(posedgeclk)if(!reset) counter<=3'b000;elseif(counter==3’b101)counter=3’b000;elsecounter<=counter+1;assignOUT=counter[2]|((~counter[1])&(~counter[0]))|(counter[1]&counter[0]);endmodule例4.3-10:用VerilogHDL设计伪随机码发生器随机码是一种变化规律与随机码类似的二进制代码,可以作为数字通信中的一个信号源,通过信道发送到接收机,用于检测数字通信系统错码的概率,即误码率。在传统的数字电路设计中,伪随机序列信号发生器是用移位存型计数器来实现的,反馈网络输入信号从移位寄存器的部分输出端(QN-1~Q0)中取出,它的输出端F反馈到移位寄存器的串行输入端。11/11/20246411/11/202465NF1021,031,041,052,061,071,084,3,2,0通过不同的反馈网络,可以形成不同的移存型计数器。以m序列码为例,反馈函数如左表所示,表中的N是触发器的级数,F是反馈函数的列表。例如N=4,则反馈函数如下:下面以N=4为例,在15位最长线性序列移存型计数器中,有一个由“0000”构成的死循环,为了打破死循环,可以修改式为根据N=4的最长线形序列移存型计数器的功能实现的伪随机码发生器VerilogHDL程序代码是:11/11/202466modulesignal15(out,clk,load_n,D_load);outputout;inputload_n,clk;input[3:0]D_load;reg[3:0]Q;wireF;always@(posedgeclk)if(~load_n)Q<=D_load;elseQ<={Q[2:0],F};assignF=(Q[1]^Q[0])|(~Q[3]&~Q[2]&~Q[1]&~Q[0]);assignout=Q[3];endmodule4.4有限同步状态机有限状态机是时序电路的通用模型,任何时序电路都可以表示为有限状态机。有限状态机从本质上讲是由寄存器与组合逻辑构成的时序电路,各个状态之间的转移总是在时钟的触发下进行的,状态信息存储在寄存器中。因为状态的个数是有限的所以称为有限状态机。同其它时序电路一样,有限状态机也是由两部分组成:存储电路和组合逻辑电路。存储电路,用来生成状态机的状态;组合逻辑电路,用来提供输出以及状态机跳转的条件。11/11/202467根据输出信号的产生方式,有限状态机可以分为米利型(Mealy)和摩尔型(Moore)两类。Mealy型状态机的输出与当前状态和输入有关系,Moore型状态机的输出仅依赖当前状态而与输入无关。11/11/202468状态机编码方式很多,由此产生的电路也不相同,常见的编码方式有三种:二进制编码、格雷编码和一位独热编码。(1)二进制编码:状态寄存器是由触发器组成的。N个触发器可以构成2n个状态。二进制编码的优点是使用的触发器个数较少,节省资源;缺点是状态跳转时可能有多个bit位同时变化,引起毛刺,造成逻辑错误。(2)格雷编码:格雷编码和二进制编码类似。格雷编码状态跳转时只有一个bit位发生变化,减少了产生毛刺和一些暂态的可能。(3)Onehot编码:是对于n个状态采用n个bit位来编码,每个状态编码中只有一个bit位为1,如:0001,0010,0100,1000。Onehot编码增加了使用触发器的个数,但是这种编码方便译码,可以有效地节省和化简组合电路。11/11/202469在VerilogHDL中,有限状态机的写法较多,常用的有两段式和三段式两种。11/11/202470(1)状态机两段式描述方式://第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器always@(posedgeclkornegedgerst_n)
//异步复位
if(!rst_n)current_state<=IDLE;
else
current_state<=next_state;//注意,使用的是非阻塞赋值
//第二个进程,组合逻辑always模块,描述状态转移条件判断always@(current_state和输入信号)
//电平触发
begin
next_state=x;
//要初始化,使得系统复位后能进入正确的状态
case(current_state)
S1:if(...)
next_state=S2;
//阻塞赋值
out1<=1'b1;
//注意是非阻塞逻辑...
endcaseend11/11/202471//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器always@(posedgeclkornegedgerst_n)
//异步复位
if(!rst_n) current_state<=IDLE;
else current_state<=next_state;//注意,使用的是非阻塞赋值//第二个进程,组合逻辑always模块,描述状态转移条件判断always@(current_state和输入信号)
//电平触发
begin
next_state=x;
//要初始化,使得系统复位后能进入正确的状态
case(current_state)
S1:if(...)
next_state=S2;
//阻塞赋值...
endcaseend(2)状态机三段式描述方式:11/11/202472
//第三个进程,同步时序always模块,格式化描述次态寄存器输出always@(current_state和输入信号)...//初始化
case(next_state)S1:
out1<=1'b1;
//注意是非阻塞逻辑S2:
out1<=1'b0;default:...
//default的作用是免除综合工具综合出锁存器。endcaseend三段式并不是一定要写三个always块,如果状态机更为复杂,always块也会相应增加。例4.4-1:用VerilogHDL设计顺序脉冲发生器顺序脉冲发生器又称脉冲分配器,它将高电平的脉冲依次分配到不同输出上。保证在每个时钟内只有一路输出上是高电平脉冲,不同时钟上脉冲电平依次出现在所有输出。11/11/202473以4位顺序脉冲发生器为例,它有四路输出W0W1W2W3,每路输出上高电平脉冲依次出现,输出在1000,0100,0010,0001之间循环。4位顺序脉冲发生器的状态转移图,如图所示。它由4个状态构成,每个状态中“1”的个数都是1个,表示每个时钟周期内只有一路输出端为高电平(脉冲),而且是轮流出现,因此生成顺序脉冲信号。对四状态状态机编码时,只需要两位二进制编码即可,VerilogHDL程序设计代码是:11/11/202474modulestate4(OUT,clk);output[3:0]OUT;inputclk;reg[3:0]OUT;reg[1:0]STATE,next_STATE;always@(STATE)case(STATE)2'b00:beginOUT<=4'b1000;next_STATE<=2'b01;end2'b01:beginOUT<=4'b0100;next_STATE<=2'b10;end2'b10:beginOUT<=4'b0010;next_STATE<=2'b11;end2'b11:beginOUT<=4'b0001;next_STATE<=2'b00;endendcasealways@(posedgeclk)STATE<=next_STATE;endmodule例4.4-2:设计一个卖报机,报纸价钱八角,纸币有1角,2角,5角,一元。该卖报机不考虑投币为大额面值等特殊情况。11/11/202475右图是卖报机的状态转移图,图中S0~S7为状态机的8个状态,角标代表已投币的总合,如S0代表没有投币,S1代表已投入1角,依此类推。M代表输入,M1表示投入1角硬币,M2代表投入2角硬币,M5代表投入5角硬币,M10代表投入一元。data_out=1表示给出报纸,data_out_return1=1表示找回1角硬币,data_out_return2=1表示找回2角硬币。卖报机VerilogHDL程序代码是:11/11/202476moduleauto_sellor(current_state,data_out,data_out_return1,data_out_return2,clk,rst_n,data_in);parameterstate_width=3,data_in_width=3;output[state_width-1:0]current_state;outputdata_out,data_out_return1,data_out_return2;input[data_in_width-1:0]data_in;inputclk,rst_n;reg[state_width-1:0]current_state,next_state;regdata_out,data_out_return1,data_out_return2;always@(current_state)case(current_state)11/11/2024773'b000:case(data_in)3'b000:beginnext_state<=3'b000;data_out<=1'b0;data_out_return1<=1'b0;data_out_return2<=1'b0;end3'b001:beginnext_state<=3'b001;data_out<=1'b0;data_out_return1<=1'b0;data_out_return2<=1'b0;end3'b010:beginnext_state<=3'b010;data_out<=1'b0;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 脑梗死患者康复护理伦理
- 水产加工废弃物回收协议
- 2026年科技助力下的化工安全保障
- 2025年工业物联网数字孪生协同仿真平台
- 2026年智能安防系统集成接口协议
- 2026年手术室激光设备安全使用与防护制度
- 常年知识产权顾问合同
- 书店经营培训及咨询服务合同
- 2026年远程项目合同管理特殊条款
- 2025年工业物联网设备身份管理架构实践
- 城市轨道交通车辆机械系统检修 课件 项目3 任务3.1 客室车门的日常检查与维护
- 中药基本知识和用药护理专家讲座
- 企业安全生产组织架构与责任制(课件)
- 杭州西溪湿地案例分析报告
- 哈尔滨工程大学-理想流体力学-大作业
- 烟气余热回收计算
- 中国电建法库县150MW风电项目环境影响报告书
- 江吕商业油库设计-毕业设计
- 湘教版五年级音乐下册全册教案
- DL-T 2318-2021 配电带电作业机器人作业规程
- 机械设计-联接
评论
0/150
提交评论