EDA技术及应用-基于FPGA的电子系统设计:基于Verilog hdl的数字电路设计_第1页
EDA技术及应用-基于FPGA的电子系统设计:基于Verilog hdl的数字电路设计_第2页
EDA技术及应用-基于FPGA的电子系统设计:基于Verilog hdl的数字电路设计_第3页
EDA技术及应用-基于FPGA的电子系统设计:基于Verilog hdl的数字电路设计_第4页
EDA技术及应用-基于FPGA的电子系统设计:基于Verilog hdl的数字电路设计_第5页
已阅读5页,还剩105页未读 继续免费阅读

下载本文档

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

文档简介

基于VerilogHDL的

数字电路设计主要内容◆6.1基本组合电路的设计◆6.2基本时序逻辑电路设计◆6.3状态机逻辑电路设计◆6.4多层次结构电路的设计VerilogHDL设计实例

在数字电路设计中,数字电路可简单归纳为两种要素:线和器件。线是器件管脚之间的物理连线;器件也可简单归纳为组合逻辑器件(如与或非门等)和时序逻辑器件(如寄存器、锁存器、RAM等)。

组合逻辑电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。而时序逻辑电路在逻辑功能上的特点是任意时刻的输出不仅取决于当时的输入信号,而且还取决于电路原来的状态,或者说,还与以前的输入有关。下面分别用VerilogHDL语言来设计这两种电路。6.1基本组合电路设计1、设计一个基本门电路

包括一个非门、一个与门、一个与非门、一个或门、一个异或门和一个异或非门。如图1所示为基本门电路描述图元符号。图6-1基本门电路描述图元符号【例6-1】门调用实现图6-1所示模块。moduleALLGATE(IN1,IN2,G_INV,G_AND,G_NAND,G_OR,G_XOR,G_NXOR);inputwireIN1,IN2;outputwireG_INV,G_AND,G_NAND,G_OR,G_XOR,G_NXOR;assignG_INV=~IN1;assignG_AND=IN1&IN2;assignG_NAND=~(IN1&IN2);assignG_OR=IN1|IN2;assignG_XOR=IN1^IN2;assignG_NXOR=~(IN1^IN2);endmodule

仿真结果如图6-2所示。图6-2基本门电路仿真结果图6-3基本门电路综合结果综合结果如图6-3所示。2、

三态逻辑电路

在数字系统中,经常要用到三态逻辑电路,三态门是在普通门的基础上加控制端构成的,在需要信息双向传输的地方,三态门是必需的。下面用三种模式描述图4所示的三态门,当en控制端为高电平时,输出out=in;当en控制端为低电平时,输出out为高阻态。2、

三态逻辑设计【例6-2】行为描述的三态门moduletristate1(in,en,out);inputin,en;outputregout;always@(inoren)beginif(en)out<=in;elseout<=1'bz;endendmodule【例6-3】调用门元件bufif1描述的三态门moduletristate2(in,en,out);inputin,en;outputout;triout;bufif1b1(out,in,en); //注意三态门端口的排列顺序endmodule【例6-4】数据流描述的三态门moduletristate3(out,in,en);inputin,en;outputout;assignout=en?in:1‘bz;//若en=1,out=in; //若en=0,out为高阻态endmodule【例6-5】三态双向总线缓冲器modulettl245(a,b,oe,dir);inputoe,dir; //使能信号和方向控制inout[7:0]a,b; //双向数据线assigna=({oe,dir}==2'b00)?b:8'bz;assignb=({oe,dir}==2'b01)?a:8'bz;endmodule3、数据选择器

以2选1数据选择器为例,模块和真值表如图5所示。从模块图,我们可知2选1数据选择器输入有a,b,s,输出为y,输入与输出关系如真值表所示,当s为0时,y的值为a的值,当s为1时,y的值为b的值。

逻辑电路

卡诺图法a:使用逻辑方程实现的2选1MUX

modulemux21a(inputwirea,inputwireb,inputwires,outputwirey);assigny=~s&a|s&b;endmodule法b:使用if语句实现的2选1MUXmodulemux21b(inputwirea,inputwireb,inputwires,outputregy);always@(a,b,s)if(s==0)y=a;elsey=b;endmodule法c:使用if语句实现的2选1MUXmodulemux21c(inputwirea,inputwireb,inputwires,outputregy);always@(*)if(s==0)y=a;elsey=b;endmodule法d:使用“?”实现的2选1MUXmodulemux21d(inputwirea,inputwireb,inputwires,outputwirey);assigny=s?b:a;endmodule4选1多路选择器4选1多路选择器:模块例化法a:使用模块例化的4选1MUXmodulemux41(inputwire[3:0]c,inputwire[1:0]s,outputwirez);wirev;//outputofmuxM1wirew;//outputofmuxM2//模块例化mux21cM1(.a(c[0]),.b(c[1]),.s(s[0]),.y(v));mux21cM2(.a(c[2]),.b(c[3]),.s(s[0]),.y(w));mux21cM3(.a(v),.b(w),.s(s[1]),.y(z));endmodule法b:使用逻辑方程实现4选1MUXmodulemux41b(inputwire[3:0]c,inputwire[1:0]s,outputwirez);assignz=~s[1]&~s[0]&c[0]|~s[1]&s[0]&c[1]|s[1]&~s[0]&c[2]|s[1]&s[0]&c[3];endmodule法C:使用case语句实现4选1MUXmodulemux41c(inputwire[3:0]c,inputwire[1:0]s,outputregz);always@(*)case(s)0:z=c[0];1:z=c[1];2:z=c[2];3:z=c[3];default:z=c[0];(不能省)endcaseendmodule4位2选1多路选择器法a:使用逻辑方程实现4位2选1MUXmodulemux24a(inputwire[3:0]a,inputwire[3:0]b,inputwires,outputwire[3:0]y);assigny={4{~s}}&a|{4{s}}&b;endmodule法b:使用if语句实现4位2选1MUXmodulemux24b(inputwire[3:0]a,inputwire[3:0]b,inputwires,outputreg[3:0]y);always@(*)if(s==0)y=a;elsey=b;endmodule法c:使用“?”运算符实现4位2选1MUXmodulemux24c(inputwire[3:0]a,inputwire[3:0]b,inputwires,outputwire[3:0]y);assigny=s?b:a;endmodule4、译码器和编码器3-8译码器:for循环//例:3-8译码器moduledecode38b(inputwire[2:0]a,outputreg[7:0]y);integeri;always@(*)for(i=0;i<=7;i=i+1)if(a==i)y[i]=1;elsey[i]=0;endmodule译码器8-3编码器8-3编码器:for循环//8-3编码器:for循环moduleencode83b(inputwire[7:0]x,outputreg[2:0]y,);integeri;always@(*)beginy=0;for(i=0;i<=7;i=i+1)if(x[i]==1)beginy=i;endendendmodule

优先编码器8-3优先编码器//8-3优先编码器modulepencode83(inputwire[7:0]x,outputreg[2:0]y,);integeri;always@(*)beginy=0;for(i=0;i<=7;i=i+1)if(x[i]==1)beginy=i;endendendmodule5、二进制码、8421BCD码、余三码、格雷码用四位二进制代码来表示一位十进制数,称为二--十进制编码,简称BCD(BinaryCodedDecimal)码。根据代码的每一位是否有权值BCD码可分为有权码和无权码两类,应用最多的是8421BCD码,无权码用得较多的是余三码和格雷码,我们通常所说的BCD码指的是8421BCD码。这些编码跟十进制数对应的关系如下:8421BCD码中的“8421”表示从高到低各位二进制位对应的权值分别为8、4、2、1,将各二进制位与权值相乘,并将乘积相加就得相应的十进制数。例如,8421BCD码“0111”,0×8+1×4+1×2+1×1=7D,其中D表示十进制(Decimal)数。

值得特别注意的是,8421BCD码只有0000~1001共十个,而1010、1011...等等不是8421BCD码!!余三码是在8421BCD码的基础上,把每个数的代码加上0011(对应十进制数3)后得到的。格雷码的编码规则是相邻的两代码之间只有一位二进制位不同。不管是8421BCD码还是余三码还是格雷码,总是4个二进制位对应一个十进制数,如十进制数18对应的8421BCD码就是0001

1000。

4位二进制十进制数BCD码8421BCD码余三码4位格雷码000000000000000011000000011000010001010000010010200010001001010011001130001100110110001001004001000100011101100101500101010110000111011060011001101001010101117001110111101001001000801000100010111100100190100110011100110110101010000--111110111110001--111011001210010--101011011310011--101111101410100--100111111510101--10004位二进制到格雷码的转换器//二进制到格雷码的转换器modulebin2gray(inputwire[3:0]b,outputwire[3:0]g);assigng[3]=b[3];assigng[2:0]=b[3:1]^b[2:0];endmodule//格雷码到二进制码的转换器modulegray2bin(inputwire[3:0]g,outputreg[3:0]b);integeri;always@(*)beginb[3]=g[3];for(i=2;i>=0;i=i-1)b[i]=b[i+1]^g[i];endendmodule6、

七段显示管译码电路

七段数码管实际上是由7个长条形的发光二极管组成的(一般用a、b、c、d、e、f、g分别表示7个发光二极管),多用于显示字母、数字.Xabcdefg0123456789ABCDEF共阴极【例6-14】七段数码管显示8421BCD码moduleseg7b(led,a_to_g);outputreg[6:0]a_to_g;input[3:0]led;//输入的4位BCD码always@(*)begincase(led)4'b0000:a_to_g=7'b1111110;//显示04'b0001:a_to_g=7'b0110000;//显示14'b0010:a_to_g=7'b1101101;//显示24'b0011:a_to_g=7'b1111001;//显示34'b0100:a_to_g=7'b0110011;//显示44'b0101:a_to_g=7'b1011011;//显示54'b0110:a_to_g=7'b1011111;//显示64'b0111:a_to_g=7'b1110000;//显示74'b1000:a_to_g=7'b1111111;//显示84'b1001:a_to_g=7'b1111011;//显示9default:a_to_g=7'b0000000;//其他情况不显示endcaseendendmodule7、比较器

使用关系运算符的N位比较器modulecomp#(parameterN=8)(inputwire[N-1:0]x,inputwire[N-1:0]y,outputreggt,outputregeq,outputreglt);always@(*)begingt=0;eq=0;lt=0;if(x>y)gt=1;if(x==y)eq=1;if(x<y)lt=1;endendmodule7、移位器

四位移位器模块d0moduleshift4(inputwire[3:0]d,inputwire[2:0]s,outputreg[3:0]y);always@(*)case(s)0:y=d;//noshift1:y={1'b0,d[3:1]};//shr2:y={d[2:0],1’b0};//shl3:y={d[0],d[3:1]};//ror4:y={d[2:0],d[3]};//rol5:y={d[3],d[3:1]};//asr6:y={d[1:0],d[3:2]};//ror27:y=d;//noshiftdefault:y=d;endcaseendmodule【例6-15】4位移位器8、算术运算器【例6-16】四位二进制数的乘法、除法、求余运算modulemult4(a,b,c,d,e);inputsigned[3:0]a,b;outputsigned[7:0]c;outputsigned[3:0]d,e;assignc=a*b;assignd=a/b;assigne=a%b;endmodule算术运算仿真波形从图中可看出,余数的符号与被除数符号一致。6.2基本时序逻辑电路设计

时序逻辑是具有状态记忆的电路,其输出不仅依赖于当前的输入,而且依赖于以前的输入。可以使用always块和连续赋值assign语句实现时序电路。一、锁存器和触发器

在数字电路中除了需要进行各种算术运算和逻辑运算,还需要对数据进行存储,目前在半导体存储器中采用的存储单元有锁存器和触发器两类。

锁存器和触发器区别在于触发方式不一样,锁存器没有时钟信号控制,而触发器是在时钟信号触发时才能动作的存储单元电路。50触发器概述一、用于记忆1位二进制信号

1.有两个能自行保持的状态

2.根据输入信号可以置成0或1二、分类

1.按触发方式(电平,脉冲,边沿)

2.按逻辑功能(RS,JK,D,T)【例】电平敏感的1位数据锁存器modulelatch1(q,d,le);inputd,le;outputq;assignq=le?d:q; //le为高电平时,将输入端数据锁存endmodule【例】带置位/复位端的1位数据锁存器modulelatch2(q,d,le,set,reset);inputd,le,set,reset;outputq;assignq=reset?0:(set?1:(le?d:q));endmodule【例】8位数据锁存器(74LS373)modulettl373(le,oe,q,d);inputle,oe;input[7:0]d;outputreg[7:0]q;always@* //或写为always@(le,oe,d)beginif(~oe&le)q<=d; //或写为if((!oe)&&(le))elseq<=8'bz;endendmodule

触发器在置位与清零信号的作用下置1或是置0。工作方式有同步和异步之分。对于同步置位与清零的触发器,其置位和清零信号是在时钟信号的有效沿发挥作用的,描述这样触发器的always块的敏感信号只有时钟,但是在块内总是首先检查置位和清零信号。对于高电平置位清零的同步触发器,有如下格式:always@(posedgeclk)beginif(reset)begin/*触发器清零*/endelseif(set)begin/*触发器置位*/endelsebegin/*时钟逻辑*/endend

在异步置位与清零的触发器中,置位与清零信号的作用与时钟信号无关,但是在同步置位与清零的触发器中,置位与清零信号的作用一定等到时钟的有效边沿出现时起作用。对于高电平异步置位和清零的触发器,一般有如下格式:

always@(posedgeclkorposedgesetorposedgereset)beginif(reset)begin/*置位输出为0*/endelseif(set)begin/*置位输出为1*/endelsebegin/*时钟逻辑*/endend1、RS触发器可称为RS锁存器RS触发器的Verilog-HDL描述

moduleRS_FF(R,S,CLK,Q,QB);//模块名及参数定义,范围至endmodule

inputR,S,CLK;

//输入端口定义

outputQ,QB;

//输出端口定义

regQ;

//寄存器定义

assignQB=~Q;

//assign语句,QB=/Q。

always@(posedgeCLK)

//在CLK的上跳沿,执行以下语句。

case({R,S})

//case语句,至于endcase为止。

0:Q<=Q;

//当R,S的组合为00,则令Q=0。

1:Q<=1;

//当R,S的组合为01,则令Q=1。

2:Q<=0;

//当R,S的组合为10,则令Q=0。

3:Q<=1'bx;

//当R,S的组合为11,则令Q为1bit的数,数值为不定(x)。

endcase

//case语句结束

endmodule

//模块结束

逻辑功能表D000010101111特性方程Qn+1=D状态转换图D触发器工作特点:在CP低电平期间存储信号,在CP的上升沿(高电平),状态变化。2、D触发器moduledtrif(CP,D,Q);

inputCP;inputD;

outputQ;

regQ;

always@(CP)

begin

if(CP==1'b1)

beginQ<=D;

end

end

endmodulemoduledtrif(D,clk,Q,QB);

inputD,clk;

outputQ,QB;

regQ;

always@(posedgeclk)

case({D})0:Q<=0;1:Q<=1;

endcaseassignQB=~Q;endmoduleQ<=D;[例6-18]同步带置数和清零端的D触发器moduleDffsc(inputwireclk,inputwireclr,inputwireset,inputwireD,outputregq);always@(posedgeclk)if(set==1)q<=1;elseif(clr==1)q<=0;elseq<=D;endmodule3、JK触发器6364【例6-17】带异步清0/异步置1的JK触发器modulejkff_rs(clk,j,k,q,rs,set);inputclk,j,k,set,rs;outputregq;always@(posedgeclk,negedgers,negedgeset)beginif(!rs)q<=1'b0;elseif(!set)q<=1'b1;elsecase({j,k})2'b00:q<=q;2'b01:q<=1'b0;2'b10:q<=1'b1;2'b11:q<=~q;default:q<=1'bx;endcaseendendmodule6.2基本时序电路设计二、寄存器

寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。工程中的寄存器一般按计算机中字节的位数设计,所以一般有8位寄存器、16位寄存器等。【例】1位寄存器modulereg1bit(inputwireload,inputwireclk,inputwireclr,inputwireinp0,outputregq0);wireD;assignD=q0&~load|inp0&load;//D触发器always@(posedgeclkorposedgeclr)if(clr==1)q0<=0;elseq0<=D;endmodule//1位寄存器modulereg1bitb(inputwireload,inputwireclk,inputwireclr,inputwireinp0,outputregq0);//带load信号的1位寄存器always@(posedgeclkorposedgeclr)if(clr==1)q0<=0;elseif(load==1)q0<=inp0;endmodule4位寄存器【例】4位寄存器modulereg4bit(inputwireload,inputwireclk,inputwireclr,inputwire[3:0]inp,outputreg[3:0]q);//带load信号的4位寄存器always@(posedgeclkorposedgeclr)if(clr==1)q<=0;elseif(load==1)q<=inp;endmoduleN位寄存器【例6-19】带有异步清零和加载信号的8位寄存器moduleregister#(parameterN=8)(inputwireload,inputwireclk,inputwireclr,inputwire[N-1:0]d,outputreg[N-1:0]q);always@(posedgeclkorposedgeclr)if(clr==1)q<=0;elseif(load==1)q<=d;endmodule【例6-20】4位移位寄存器moduleShiftReg(inputwireclk,inputwireclr,inputwiredata_in,outputreg[3:0]q);//4位移位寄存器always@(posedgeclkorposedgeclr)beginif(clr==1)q<=0;elsebeginq[3]<=data_in;q[2:0]<=q[3:1];endendendmodule4位环形寄存器【例6-21】环形寄存器modulering4(inputwireclk,inputwireclr,outputreg[3:0]q);always@(posedgeclkorposedgeclr)beginif(clr==1)q<=1;elsebeginq[3]<=q[0];q[2:0]<=q[3:1];endend endmodule6.2基本时序电路设计三、计数器

计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数器在数字系统中主要是对脉冲的个数进行计数,以实现测量、计数和控制的功能,同时兼有分频功能,计数器是由基本的计数单元和一些控制门所组成,计数单元则由一系列具有存储信息功能的各类触发器构成,这些触发器有RS触发器、T触发器、D触发器及JK触发器等。计数器在数字系统中应用广泛,如在电子计算机的控制器中对指令地址进行计数,以便顺序取出下一条指令,在运算器中作乘法、除法运算时记下加法、减法次数,又如在数字仪器中对脉冲的计数等等。计数器可以用来显示产品的工作状态,一般来说主要是用来表示产品已经完成了多少份的折页配页工作。它主要的指标在于计数器的位数,常见的有3位和4位的。很显然,3位数的计数器最大可以显示到999,4位数的最大可以显示到9999。D2=~q2&q1&q0|q2&~q1|q2&~q0D1=~q1&q0|q1&~q0D0=~q03位二进制计数器modulecount3a(inputwireclr,inputwireclk,outputreg[2:0]q);wire[2:0]D;assignD[2]=~q[2]&q[1]&q[0]|q[2]&~q[1]|q[2]&~q[0];

assignD[1]=~q[1]&q[0]|q[1]&~q[0];

assignD[0]=~q[0];//3个D触发器always@(posedgeclkorposedgeclr)if(clr==1)q<=0;elseq<=D;

endmodule3位二进制计数器modulecount3b(inputwireclr,inputwireclk,outputreg[2:0]q);//3位计数器always@(posedgeclkorposedgeclr)beginif(clr==1)q<=0;elseq<=q+1;endendmodule8位二进制计数器modulecounter#(parameterN=8)(inputwireclr,inputwireclk,outputreg[N-1:0]q);//N-位计数器always@(posedgeclkorposedgeclr)beginif(clr==1)q<=0;elseq<=q+1;endendmodule【例】可变模加法/减法8位二进制计数器moduleupdown_count(d,clk,clear,load,up_down,qd);inputclk,clear,load,up_down;input[7:0]d;output[7:0]qd;reg[7:0]cnt;assignqd=cnt;always@(posedgeclk)beginif(!clear) cnt<=8'h00; //同步清0,低电平有效elseif(load) cnt<=d; //同步预置elseif(up_down) cnt<=cnt+1; //加法计数else cnt<=cnt-1; //减法计数endendmodule模-5计数器(5进制计数器)modulemod5cnt(inputwireclr,inputwireclk,outputreg[2:0]q);//模-5计数器always@(posedgeclkorposedgeclr)beginif(clr==1)q<=0;elseif(q==4)q<=0;elseq<=q+1;endendmodule【例6-22】设计一个带计数使能,异步复位,同步加载的可逆模24计数器。modulecount24(DATA_L,DATA_H,CLK,RST,DIV,CP);outputreg[3:0]DATA_L,DATA_H;inputCP,CLK,RST,DIV;always@(posedgeCLKorposedgeRST)if(RST){DATA_H,DATA_L}=0; elseif(CP){DATA_H,DATA_L}={DATA_H,DATA_L};elseif(DIV) begin if({DATA_H,DATA_L}==8’h23) {DATA_H,DATA_L}=0; elseif(DATA_L==4’h9)beginDATA_H=DATA_H+1;DATA_L=0;endelse{DATA_H,DATA_L}={DATA_H,DATA_L}+1;endelse

beginif({DATA_H,DATA_L}==

) {DATA_H,DATA_L}=

;elseif(DATA_L==

)beginDATA_H=DATA_H-1;DATA_L=4’h9;endelse{DATA_H,DATA_L}={DATA_H,DATA_L}-1;endendmodule图6-1524制计数器仿真波形6.2基本时序电路设计四、分频器

分频器可用来降低信号的频率,是数字系统中常用的电路。分频器的输入信号频率fi和输出信号频率fo之比成为分频比。N进制计数器可实现N分频器。

分频器设计要考虑频率(即周期)和占空比。分为偶数倍分频和奇数倍分频,等占空比和非等占空比设计。

偶数倍分频(等占空比)法一:N进制计数器实现偶数倍分频器。【例6-23】等占空比的八分频器设计modulefp8(clk,rst,clk_8);inputclk,rst;outputclk_8;reg[2:0]q;always@(posedgeclk)if(rst)q=0;elseq=q+1;assignclk_8=q[2];endmodule【例6-23】等占空比的八分频器设计modulefenpin8(clk,reset,clk_8);inputclk,reset;outputclk_8;integerk;regclk_8;always@(posedgeclkorposedgereset)if(reset)begink<=0;clk_8<=0;endelseif(k==3)begin k<=0; clk_8<=~clk_8;endelsek<=k+1;endmodule法二:可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。偶数倍分频(非等占空比)【例6-24】占空比为3/8的八分频器设计modulefenpin8(clk,reset,clk_8);inputclk,reset;outputclk_8;integerk;regclk_8;always@(posedgeclkorposedgereset)if(reset)begink<=0;clk_8<=0;endelseif(k==7)begin k<=0;clk_8<=~clk_8;endelseif(k==4)clk_8<=~clk_8;elsek<=k+1;endmodule奇数倍分频(等占空比)可采用如下的方法:用两个计数器,一个由输入时钟的上升沿触发,另一个由输入时钟的下降沿触发,最后将两个计数器的输出相或,即可得到占空比为50%的方波波形。如下例所示,用parameter语句定义了参数NUM,这样只需要改NUM的赋值(NUM应赋奇数值),就可以得到任意模的奇数分频器。【例6-25】等占空比的13分频器设计modulecount_num(reset,clk,cout);parameterNUM=13;inputclk,reset;outputwirecout;reg[4:0]m,n;regcout1,cout2;assigncout=cout1|cout2;always@(posedgeclk)beginif(!reset)begincout1<=0;m<=0;endelsebegin if(m==NUM-1)beginm<=0;cout1<=~cout1;end elseif(m==(NUM-1)/2)cout1<=~cout1;elsem<=m+1;endendalways@(negedgeclk)begin if(!reset)begincout2<=0;n<=0;endelsebeginif(n==NUM-1)beginn<=0;cout2<=~cout2;end elseif(n==(NUM-1)/2)cout2<=~cout2;elsen<=n+1;endendendmodule五脉冲信号发生器

1、设计并实现一个同步单脉冲发生器。2、设计一个节拍脉冲发生器,当按下start键时,循环产生四个节拍脉冲,当按下stop键时,停止产生节拍脉冲,当按下step键时,只产生一组四个节拍脉冲。

1.理解同步单脉冲发生器同步单脉冲发生器就是能发出单个同步脉冲的线路。它的输入是一串连续脉冲M,它的输出受开关PUL的控制,每当按一次开关后,Q端输出一个与输入脉冲的周期和时间(相位)同步的脉冲。

图1无抖动仿真波形图2有抖动仿真波形图3模块图【例6-26】同步单脉冲发生器实现方法——原理图设计

【例6-27】同步单脉冲发生器实现方法——VerilogHDL语言设计

modulep1(inp,cclk,clr,outp); inputinp,cclk,clr; outputoutp; regdelay1; regdelay2; always@(posedgecclkorposedgeclr) begin if(clr==1) begin delay1<=0; delay2<=0; end else begin delay1<=inp; delay2<=delay1; end end assignoutp=delay1&~delay2;endmodule

仿真分析

仿真时间:0~10sM周期:1ms,频率:1khz

PUL开关:闭合时间0.1s

消抖

当按下FPGA开发板上的任何按钮,在它们稳定下来之前都会有几毫秒的轻微抖动。这就意味着输入到FPGA的并不是清晰的从0到1的变化,而可能是在几毫秒的时间里从0到1来回的抖动。在时序电路中,当在一个时钟信号上升沿到来时发生这种抖动,将是一个严重的问题。因为时钟信号改变的速度要比开关抖动的速度快,这将可能把错误的值所存到寄存器中。所以,当在时序电路中使用按钮开关时,消除它们的抖动时非常必要的。

抖动要求

(1)如果有抖动,必须采用至少3级延迟(3个D触发器)消抖;(2)输入脉冲M频率不应太大,一般小于1Khz,否则抖动不易消除

2.理解节拍脉冲发生器节拍脉冲发生器用来产生计算机工作所需的节拍脉冲。

(1)节拍脉冲发生器的实现方法【例6-28】节拍脉冲发生器设计moduletime_pluse(clk,start,step,stop,p);inputclk,start,step,stop;outputreg[3:0]p;reg[1:0]m;always@(posedgeclk)if(start)beginm<=2'b10;p<=4'b0001;endelseif(step)beginm<=2'b01;p<=4'b0001;endelseif(stop)beginm<=0;p<=0;endelseif(m==2'b10)p<={p[2:0],p[3]};elseif(m==2'b01)p<=p<<1;elsep<=0;endmodule6脉冲宽度调制器(PWM)图6-24PWM信号PWM控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要的波形(含形状和幅值),PWM控制技术在逆变电路中应用最广,应用的逆变电路绝大部分是PWM型,广泛应用在从测量、通信到功率控制与变换的许多领域中。1.使用PWM控制一个直流电机的转速PWM可以应用在许多方面,如电机调速、温度控制、压力控制等。在PWM驱动控制的调整系统中,按一个固定的频率来接通和断开电源,并根据需要改变一个周期内“接通”和“断开”时间的长短。通过改变直流电机电枢上电压的“占空比”来改变平均电压的大小,从而控制电动机的转速。因此,PWM又被称为“开关驱动装置”。图6-24所示的PWM信号的平均直流值和占空比是成比例的。100%的占空比将会使得PWM信号的直流值达到最大,50%的占空比将会使得PWM信号的直流值等于最大值的一半。如果通过电动机的电压和PWM信号是成正比的,那么只要简单的更改一下脉冲宽度,则占空比随之改变,从而就可以改变电动机的转速。【例6-29】PWM信号控制直流电机modulezl(inputclk,

inputrst,

input[1:0]sel,

outputregpwm);reg[11:0]cnt,duty;always@(posedgeclk,posedgerst)if(rst)cnt=0;elsecnt=cnt+1;//周期为4028个clk脉冲always@(sel)case(sel)2'b00:duty=12'd2048;//占空比为1/22'b01:duty=12'd1024;//占空比为1/42'b10:duty=12'd3072;//占空比为3/42'b11:duty=12'd0;//占空比为0,停止转动endcasealways@(*) if(cnt<duty)pwm=1;//高电平 elsepwm=0;//低电平endmodule2.使用PWM控制一个步进电机的转动如图6-25所示为四相反应式步进电机工作原理示意图,该步进电机为一四相步进电机,采用单极性直流电源供电。只要对步进电机的各相绕组按合适的时序通电,就能使步进电机步进转动。图6-25四相反应式步进电机工作原理示意图表6-2所列为按照四相单、双八拍控制方法,电机正转时的控制顺序为A->AB->B->BC->C->CD->D->DA。十六进制二进制通电状态1H0001A3H0011AB2H0010B6H0110BC4H0100CCH1100CD8H1000D9H1001DA表6-2电机正转时,FPGA四位I/O口的值【例6-30】PWM信号控制步进电机modulebj(clk,rst,dir,dcba);//clk为可控制电机转速inputclk,rst,dir;//dir控制电机顺时针转,还是逆时针转动outputreg[3:0]dcba;//单、双八拍工作方式,四相输出reg[2:0]state;always@(posedgeclk,posedgerst)if(rst)begindcba=0;state=0;endelsebeginif(dir)state=state+1;elsestate=state-3'b001;case(state)3'b000:dcba=4'b0001;3'b001:dcba=4'b0011;3'b010:dcba=4'b0010;3'b011:dcba=4'b0110;3'b100:dcba=4'b0100;3'b101:dcba=4'b1101;3'b110:dcba=4'b1000;3'b111:dcba=4'b1001;endcaseendendmodule6.3有限状态机设计

有限状态机(FiniteStateMachine,FSM)是时序电路设计中经常采用的一种方式,尤其适合设计数字系统的控制模块,在一些需要控制高速器件的场合,用状态机进行设计是一种很好的解决问题的方案,具有速度快、结构简单、可靠性高等优点。

有限状态机非常适合用FPGA器件实现,用VerilogHDL的case语句能很好地描述基于状态机的设计,再通过EDA工具软件的综合,一般可以生成性能极优的状态机电路,从而使其在执行时间、运行速度和占用资源等方面优于用CPU实现的方案。

108

有限状态机可以认为是组合逻辑和寄存器逻辑的特殊组合,它一般包括组合逻辑和寄存器逻辑两部分,寄存器逻辑用于存储状态,组合逻辑用于状态译码和产生输出信号。

根据输出信号产生方法的不同,状态机可分为两类:摩尔型(Moore)和米里型(Mealy)。Moore型状态机的输出只和当前状态有关,和输入无关。Mealy型状态机的输出是由当前状态和输入共同决定。如图1和2所示。109图1摩尔型(Moore)状态机图2米里型(Mealy)状态机110VerilogHDL描述状态机代码时应该注意约定:(1)每一个模块只描述一个状态机。。(2)使用参数定义状态编码,而不是使用宏定义`define。(3)在参数定义后,立刻定义现在状态state与次态next信号。(4)所有时序always块使用非阻塞赋值。(5)所有组合always块使用阻塞赋值。(6)组合always块敏感信号列表中的信号为引起状态变化和组合always块的所有输入。(7)在组合always块的顶部应该给出当前次态的缺省值。(8)缺省输出赋值应该优先case语句。111使用VerilogHDL语言设计状态机的步骤:

(1)将实际问题抽象成状态图分析实际问题,找出输入信号、输出信号,最好画出一个具有输入和输出的框图,要给输入、输出信号取字母名。取状态机上电的状态为初始状态,并由此状态开始,根据输入条件决定状态机的次态及输出,直至所有情况描绘素完毕,画出完整的状态图。

(2)定义变量定义描写次态逻辑、状态寄存器中需要的变量,注意在always块中使用的变量应该定义成寄存器变量,而连续赋值语句中使用的变量应该定义成连线变量。

(3)状态编码根据状态图选择状态变量,进行状态编码,虽然有多种编码方式,但可以找一种编码试一试。例如,使用自然二进制码。

(4)描写次态逻辑使用always块或是连续赋值语句描写次态逻辑。

112

(5)描写状态寄存器使用always块描写状态寄存器。

(6)描写输出逻辑使用always块或是连续赋值语句描写输出逻辑(输出逻辑可以与次态逻辑在一个块中描述)。

(7)仿真根据状态机输入信号的要求,用图形或文本方式编辑输入信号波形,然后进行功能仿真,根据仿真结果的正确与否决定是否修改设计,例如在状态转换时出现不该有的尖峰脉冲,则可以更改状态编码试一试。如果仿真成功,就可以在引脚锁定后,进行编译形成文件下载到芯片中,试一试是否成功。(1)用三个过程描述:即现态(CS)、次态(NS)、输出逻辑(OL)各用一个always过程描述。(2)双过程描述(CS+NS、OL双过程描述):使用两个always过程来描述有限状态机,一个过程描述现态和次态时序逻辑(CS+NS);另一个过程描述输出逻辑(OL)。(3)双过程描述(CS、NS+OL双过程描述):一个过程用来描述现态(CS);另一个过程描述次态和输出逻辑(NS+OL)。(4)单过程描述:在单过程描述方式中,将状态机的现态、次态和输出逻辑(CS+NS+OL)放在一个always过程中进行描述。相应的,在用VerilogHDL描述的有限状态机时,有以下几种描述方式。【例6-31】“101”序列检测器的Verilog描述(三个过程)

modulefsm1_seq101(clk,clr,x,z);inputclk,clr,x;outputregz;reg[1:0]state,next_state;parameter S0=2'b00,S1=2'b01,S2=2'b11,S3=2'b10; /*状态编码,采用格雷(Gray)编码方式*/always@(posedgeclkorposedgeclr)/*该过程定义当前状态*/begin if(clr)state<=S0;//异步复位,s0为起始状态

elsestate<=next_state;endalways@(stateorx) /*该过程定义次态*/begincase(state) S0:beginif(x)next_state<=S1; else next_state<=S0;end S1:begin if(x) next_state<=S1; else next_state<=S2;end

6.3.1序列检测器设计S2:begin if(x)next_state<=S3; elsenext_state<=S0;endS3:begin if(x) next_state<=S1; else next_state<=S2;enddefault: next_state<=S0;

/*default语句*/ endcaseendalways@(state) /*该过程产生输出逻辑*/begincase(state) S3:z=1'b1; default:z=1'b0;endcaseendendmodule“101”序列检测器的Verilog描述(三个过程)

“101”序列检测器(单过程描述)modulefsm4_seq101(clk,clr,x,z);inputclk,clr,x;outputregz;reg[1:0]state;parameter S0=2'b00,S1=2'b01,S2=2'b11,S3=2'b10;/*状态编码,采用格雷(Gray)编码方式*/always@(posedgeclkorposedgeclr)Beginif(clr)state<=S0;//异步复位,s0为起始状态

elsecase(state) S0:begin if(x)beginstate<=S1;z=1'b0;end elsebeginstate<=S0;z=1'b0;endend S1:begin if(x)beginstate<=S1;z=1'b0;end elsebeginstate<=S2;z=1'b0;endend S2:begin if(x)beginstate<=S3;z=1'b0;end elsebeginstate<=S0;z=1'b0;endend S3:beginif(x)beginstate<=S1;z=1'b1;end elsebeginstate<=S2;z=1'b1;endend default:beginstate<=S0;z=1'b0;end/*default语句*/ endcaseendendmodule6.3.2流水灯控制器设计S0S1S2S3S4S5S6S70000000100000011000001110000111100011111001111110111111111111111图6-33

流水灯状态转移图根据流水灯的特点,用有限状态机设计方法实现,需要8个状态(S0~S7),每个状态表示的灯的状态如表6-4所列。流水灯状态转移图如图6-33所示。表6-4流水灯各状态取值情况表【例6-32】实现8个LED灯按固定频率依次点亮。(f=1Hz)moduleled3(inputclk,

outputreg[7:0]led);regstate;parameter[2:0]s0=3’d0,s1=3’d1,s2=3’d2,s3=3’d4,s4=3’d5,s5=3’d6,s6=3’d7;always@(posedgeclk)case(state)s0:state<=s1;s1:state<=s2;s2:state<=s3;s3:state<=s4;s4:state<=s5;s5:state<=s6;s6:state<=s7;s7:state<=s0;default:state<=s0;endcasealways@(state)s0:led<=8’b00000001;s1:led<=8’b00000011;s2:

led<=8’b00000111

温馨提示

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

评论

0/150

提交评论