VerilogHDL数字设计教程(贺敬凯)第4章_第1页
VerilogHDL数字设计教程(贺敬凯)第4章_第2页
VerilogHDL数字设计教程(贺敬凯)第4章_第3页
VerilogHDL数字设计教程(贺敬凯)第4章_第4页
VerilogHDL数字设计教程(贺敬凯)第4章_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

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

文档简介

4.1常用组合逻辑电路设计4.2常用时序逻辑电路设计

4.3小结

习题44.1常用组合逻辑电路设计

理论上,可利用化简真值表并采用逻辑门来实现电路的方法,对所有组合电路进行设计,但使用该方法设计大型组合电路则不太现实。例如,一个有12个输入的电路,在真值表中会有212 = 4 K行。降低复杂度的一种方法就是采用比逻辑门功能更强大的组合元件,图4-1列出了常用的几种组合元件。图4-1组合元件下面使用VerilogHDL分别对上述组合元件及常用的组合逻辑电路进行建模。1.数据选择器例4-1实现了一个n位,m × 1的数据选择器。【例4-1】参数型n位,m × 1数据选择器。

modulemultiplexer_N(X1,X2,X3,X4,sel,Y);

parameterN=8;//该参数定义了一个8位的4选1多路选择器

input[N-1:0]X1,X2,X3,X4;input[1:0]sel;outputreg[N-1:0]Y;always@(sel,X1,X2,X3,X4) case(sel) 2'b00:Y=X1; 2'b01:Y=X2; 2'b10:Y=X3; 2'b11:Y=X4;endcaseendmodule程序说明:(1)程序中定义了4个输入X1、X2、X3、X4,一个输出Y,使用控制信号sel选择4个输入中的1个赋给Y。(2)程序中使用parameter定义了一个参数常量N,通过修改参数可以很容易地改变输入、输出的位数。2.译码器例4-2实现了一个log2n × n的译码器。【例4-2】参数型log2n × n译码器。

moduledecode_N(sel,Y);

parameterN=4; //该参数定义了一个4输出(4位)译码器

input[1:0]sel; //此参数为2位,通过计算log24=2可得到4输出译码器

outputreg[N-1:0]Y;

always@(sel)

case(sel)

2'b00:Y=4'b0001; 2'b01:Y=4'b0010; 2'b10:Y=4'b0100; 2'b11:Y=4'b1000;endcaseendmodule程序说明:

(1)程序中定义了一个输入sel,一个输出Y,使用控制信号sel来确定Y的输出。(2)由于本程序涉及求以2为底的对数计算,因此若修改参数N,sel的位数就要手工做相应调整,这样才可实现任意位数的译码器。3.加法器例4-3实现了N位加法器。【例4-3】参数型N位加法器。moduleadd_N(X,Y,sum,co);

parameterN=8;

input[N-1:0]X,Y;output[N-1:0]sum;outputco;assign{co,sum}=X+Y;endmodule程序说明:(1)程序中,X和Y分别为加数和被加数,sum和co分别为本位和及进位。(2)本例使用数据流建模实现,在综合时会自动映射为QuartusⅡ自带的加法器宏功能模块。4.乘法器例4-4实现了N位乘法器。【例4-4】参数型N位乘法器。

modulemul_N(X,Y,mul);

parameterN=8;

input[N-1:0]X,Y;

output[2*N-1:0]mul;

assignmul=X*Y;

endmodule程序说明:

(1)程序中,X和Y分别为乘数和被乘数,mul为两者的积。(2)本例使用数据流建模实现,在综合时,会自动映射为QuartusⅡ自带的乘法器宏功能模块。5.比较器例4-5实现了N位比较器。【例4-5】参数型N位比较器。

modulecompare_N(X,Y,X_gt_Y,X_eq_Y,X_lt_Y);

parameterN=8;//参与比较的数的位数为8

nput[N-1:0]X,Y;

outputregX_gt_Y,X_eq_Y,X_lt_Y;always@(X,Y)

if(X>Y)

beginX_gt_Y=1;X_eq_Y=0;X_lt_Y=0;end elseif(X==Y) beginX_gt_Y=0;X_eq_Y=1;X_lt_Y=0;end else beginX_gt_Y=0;X_eq_Y=0;X_lt_Y=1;endendmodule程序说明:(1)比较器实现的功能见表4-1。(2)比较器有3个输出,在任一时刻仅有一个输出为1,即仅有一个输出有效。6. ALU例4-6实现了一个n位、m功能的ALU。【例4-6】参数型n位、m功能ALU。

modulealu_N(X,Y,sel,result);

parameterN=8;

input[2:0]sel;//3位可定义m=8功能

input[N-1:0]X,Y;

outputreg[N-1:0]result;

always@(X,Y,sel)

begin case(sel) 3'b000:result=X+Y;//加法

3'b001:result=X-Y;//减法

3'b010:result=X<<1;//左移1位

3'b011:result=X>>1;//右移1位

3'b100:result=X&Y;//相与 3'b101:result=X^Y;//异或 3'b110:result=~X;//求反 3'b111:result=X;//直通 endcaseendendmodule程序说明:(1) ALU实现的功能见表4-2。(2)算术逻辑运算ALU通过一条或多条输入总线完成算术或逻辑运算。ALU是CPU的核心部件之一,是设计CPU时必不可少的内容。7.三态总线引入三态门有许多实际的应用,如CPU设计中的数据和地址总线的构建、RAM或堆栈的数据端口的设计等。在设计中,若对变量赋值为z,则会引入三态门,并在控制下可使其输出呈高阻态,这等效于三态门禁止输出。三态门设计示例如例4-7。【例4-7】设计三态门。moduletri_s(enable,datain,dataout);parameterN=8;inputenable;input[N-1:0]datain;outputreg[N-1:0]dataout;always@(enable,datain) if(enable==1)dataout=datain; elsedataout='bz;endmodule程序说明:(1)本程序在QuartusⅡ中的综合结果如图4-2所示。

从图中可以看出,三态门综合后映射成了VerilogHDL的基本门原语buf。图4-2三态门控制电路的综合结果(2)参数N表示输入、输出的数据位宽,改变参数即可改变输入、输出的数据位宽,从而增强程序的可移植性。为构成数字系统内部的总线系统,必须设计三态总线驱动器电路,这可以有多种表达方法,但必须注意信号多驱动源的处理问题。例4-8、例4-9和例4-10都试图描述一个8位4通道的三态总线驱动器,但其中有一个程序不能得到预期的结果。【例4-8】N位4通道的三态总线驱动器。moduletri_bus(input3,input2,input1,input0,enable,out);parameterN=8;input[N-1:0]input3,input2,input1,input0;input[1:0]enable;outputreg[N-1:0]out;always@(enable,input3,input2,input1,input0)beginif(enable==2'b00)out=input3;elseout='bz;if(enable==2'b01)out=input2;elseout='bz;if(enable==2'b10)out=input1;elseout='bz;if(enable==2'b11)out=input0;elseout='bz;endendmodule【例4-9】N位4通道的三态总线驱动器(实现方法1)。moduletri_bus_2(input3,input2,input1,input0,enable,out);parameterN=8;input[N-1:0]input3,input2,input1,input0;input[1:0]enable;output[N-1:0]out;assignout=(enable==2'b00)?input3:'bz,out=(enable==2'b01)?input2:'bz,out=(enable==2'b10)?input1:'bz,out=(enable==2'b11)?input0:'bz;endmodule【例4-10】N位4通道的三态总线驱动器(实现方法2)。moduletri_bus_3(input3,input2,input1,input0,enable,out);parameterN=8;input[N-1:0]input3,input2,input1,input0;input[1:0]enable;outputreg[N-1:0]out;always@(enable,input3,input2,input1,input0)beginif(enable==2'b00)out=input3; elseout='bz;endalways@(enable,input3,input2,input1,input0)beginif(enable==2'b01)out=input2;elseout='bz;endalways@(enable,input3,input2,input1,input0)beginif(enable==2'b10)out=input1;elseout='bz;

endalways@(enable,input3,input2,input1,input0)begin if(enable==2'b11)out=input0; elseout='bz;endendmodule对例4-8、例4-9和例4-10的程序说明如下:(1)例4-8和例4-9、例4-10在QuartusⅡ中综合的结果分别如图4-3和图4-4所示。图4-3例4-8的综合结果图4-4例4-9、例4-10的综合结果从综合结果来看,例4-8没有得到预期的效果。(2)例4-8和例4-9、例4-10在QuartusⅡ中仿真的结果分别如图4-5和图4-6所示。图4-6例4-9、例4-10的仿真结果从仿真结果也可以看出,例4-8没有得到预期的效果。(3)例4-8在一个always块中放了4个顺序完成的if语句,并且是完整的条件描述语句。粗看此程序认为会产生4个N位的三态控制通道,且输出只有一个信号out。但是,细心的读者可能会发现,在例4-8的always块中输出信号有4个赋值源,也就是4个if语句都是对out进行赋值,这样在综合时,只有最后一个if语句起作用,也就是说前3个if语句没有任何意义,从综合结果可以清楚地看到这一点。下面再通过一个小例子进行说明。【例4-11】多个赋值源的赋值语句。always@(a,b,c,d)begin out=a; out=b; out=c; out=d;end读者很容易理解,out的值为d,always块中的前三条语句没有意义。事实上,例4-8的道理跟这个例子的道理是一样的。(4)例4-9由于使用了4个并列的assign并行语句,因此能综合出正确的结果。这是因为,每一条assign语句都等同于一个独立运行的always块,每一条assign语句右侧表达式中的所有变量等同于always块中的敏感信号列表,只要有一个发生变化,assign语句就立刻执行。因此,例4-9和例4-10是等价的,从综合和仿真的结果也可以证明这一点。(5)例4-9和例4-10表明,要设计出能产生独立控制的多通道的电路结构,必须使用并行语句结构。但应注意,例4-9和例4-10中对同一个输出信号out有4个并行赋值源,在实际电路中完全可能发生“线与”。所以,在程序中,每个赋值源都使用了if…else…结构,保证了条件不满足时,其输出为高阻态值“z”,这样可以保证不会发生“线与”。但如果条件不满足,其输出不为高阻态值,那么就无法得到预期的结果。4.2常用时序逻辑电路设计

时序逻辑电路的一个特点是:任何一个时刻的输出状态不仅取决于当时的输入信号,还与电路的原始状态有关。也就是说,时序电路含有记忆元件,具有反馈通道。时序逻辑电路包括各类触发器、寄存器、计数器、存储器等。就像使用较抽象的组合元件来实现复杂的组合逻辑一样,也可以使用较抽象的时序元件来设计复杂的时序逻辑。图4-7显示了下面几种常用的时序元件。图4-7时序元件下面使用VerilogHDL分别对上述时序元件及常用的时序逻辑电路进行建模。1. D触发器和锁存器D触发器作为时序电路中最基本的单元,每个电路设计人员都必须能够在理解其原理的基础上熟练应用。D触发器的作用是存储一位二进制位的信息,在时钟上升沿把数据从输入端送到输出端,其结构框图如图4-8所示。图4-8D触发器结构框图使用QuartusⅡ综合D触发器极为简捷方便,下面给出在时钟上升沿触发的D触发器的VerilogHDL行为描述。【例4-12】一位D触发器。实现方式一:modulemy_dff(clk,d,q);inputclk;inputd;outputregq;always@(posedgeclk) q<=d;endmoduleQuartusⅡ综合的结果如图4-8所示。实现方式二:调用QuartusⅡ软件中的dff模块实现D触发器。modulemy_dff(clk,d,q);inputclk;inputd;outputq;dffmy_dff(d,clk,,,q);endmoduleQuartusⅡ综合的结果同样如图4-8所示。两种实现方式的仿真波形也是一样的,如图4-9所示。图4-9D触发器仿真波形从仿真波形来看,两种实现方式得到的电路功能完全相同。事实上,对于一个简单的触发器来说,以上两种设计方法,其核心都是一个简单的D触发器内核,QuartusⅡ软件在综合时会自动调用内部模块,自动综合为QuartusⅡ自带的D触发器电路模块,从而使设计更加趋于合理。对于电平敏感的锁存器,只需在D触发器的描述中将上升沿改为电平即可,代码如下例。例:一位电平敏感的锁存器。modulemy_latch(clk,d,q);inputclk;inputd;outputregq;always@(clk,d) if(clk)q<=d;endmodule由一位D触发器和一位锁存器可以很容易地实现寄存器和多位锁存器。2.寄存器寄存器是一种应用广泛的时序逻辑器件,用于暂存数据。寄存器是时钟边沿敏感的。寄存器包括一般寄存器、三态寄存器,还包括具有复位、置位和使能功能的寄存器。下面分别举例说明。【例4-13】参数型n位寄存器。(1)一般寄存器。

moduleregx(clk,d,q);parameterN=8;inputclk;input[N-1:0]d;outputreg[N-1:0]q;always@(posedgeclk) q<=d;endmodule程序说明:① QuartusⅡ综合的结果如图4-10所示。图4-10一般寄存器的综合结果② D触发器相当于一位寄存器,定义多位D触发器即可构成寄存器。从两者的代码中也可以看出,D触发器与寄存器的区别就是位数不同。(2)同步复位、同步置数、异步使能的寄存器。moduleregister_N_0(D,Q,data,en,load,reset,clk);parameterN=8;inputen,load,reset,clk;

input[N-1:0]D,data;

outputreg[N-1:0]Q;reg[N-1:0]temp;always@(posedgeclk)//同步复位、同步置数beginif(reset)temp<=0;elseif(load)temp<=data;elsetemp<=D;endalways@(temp,en)//异步使能beginif(en)Q<=temp;elseQ<='bz;endendmodule程序说明:① QuartusⅡ综合的结果如图4-11所示。从图中可以看出,对于QuartusⅡ软件来说,异步方式是通过在寄存器后增加三态门来实现的,同步方式是通过多路选择器来实现的。图4-11同步复位、同步置数、异步使能的寄存器②同步复位、同步置数要求复位或置数必须在时钟的上升沿发生。③事实上,复位、置数、使能三个信号可以任意选取同步、异步两种方式之一,因此三个信号可以任意组合成8种不同功能的电路,如异步复位、同步置数、异步使能电路等。(3)异步复位、同步置数、异步使能的寄存器。moduleregister_N(D,Q,data,en,load,reset,clk);parameterN=8;inputen,load,reset,clk;

input[N-1:0]D,data;

outputreg[N-1:0]Q;reg[N-1:0]temp;always@(posedgeclkorposedgereset)//异步复位、同步置数beginif(reset)temp<=0;elseif(load)temp<=data;elsetemp<=D;endalways@(temp,en)//异步使能beginif(en)Q<=temp;elseQ<='bz;endendmodule程序说明:① QuartusⅡ综合的结果如图4-12所示。图4-12异步复位、同步置数、异步使能的寄存器②异步复位、同步置数要求只要复位信号为有效电平就复位,而置数必须在时钟的上升沿发生。(4)三态寄存器。moduletri_reg(a,en,clk,q);parameterN=8;input[N-1:0]a;inputen,clk;outputreg[N-1:0]q;reg[N-1:0]val;always@(posedgeclk)begin:triregdataval<=a;endalways@(en,val)begin:trireg3stif(en)q<=val;elseq<='bz;endendmodule程序说明如下:① QuartusⅡ综合的结果如图4-13所示。从综合结果可以看出,三态寄存器是在寄存器后放置了一个三态门,从而实现了相应的功能。图4-13三态寄存器的综合结果②该电路的功能是:在clk的上升沿将数据d存入D触发器,然后在en有效时,将存入Q的d值传给q,en无效时,q的值为高阻态'bz。③引入三态电路有许多实际的应用,如CPU设计中的数据和地址总线的构建、RAM的数据端口的设计等。3.移位寄存器例4-14设计了一个n位移位寄存器,该寄存器具有左移、右移、置数功能。【例4-14】参数型n位移位寄存器。//8位CPU中常用的移位寄存器模块moduleshift_N(clk,Ci,mode,D,Q,Co);inputclk,Ci;//时钟和移位输入input[2:0]mode;//移位模式控制字input[N-1:0]D;//待加载移位的数据output[N-1:0]Q;//移位数据输出outputregCo;//移位输出reg[N-1:0]temp;parameterN=8;//8位移位寄存器always@(posedgeclk)begin case(mode)3'b000:begintemp<=D;end//加载待移数 3'b001:begintemp[0]<=Ci; temp[N-1:1]<=temp[N-2:0];Co<=temp[N-1];//带进位循环左移 end

3'b010:begintemp[0]<=temp[N-1]; temp[N-1:1]<=temp[N-2:0];//自循环左移 end3'b011:begintemp[N-1]<=temp[0]; temp[N-2:0]<=temp[N-1:1];//自循环右移 end 3'b100:begintemp[N-1]<=Ci; temp[N-2:0]<=temp[N-1:1];Co<=temp[0];//带进位循环右移 end default:temp<=temp;//保持 endcaseendassignQ=temp; //移位后输出endmodule程序说明:(1)移位寄存器可以有多种工作模式,这由移位模式控制字mode来控制。(2)仿真波形如图4-14所示。从图中可以看出,第1个时钟上升沿时,mode为3'b000,该模式为加载待置数,因此D的值被装载进Q。第2个时钟上升沿时,mode为3'b001,该模式为带进位循环左移,因此D的值循环左移,同时D的最低位取此时刻Ci的值。从仿真波形图中可以看出,本段代码实现了题目要求的功能。图4-14例4-14的仿真波形4.计数器例4-15设计了一个n位计数器,该计数器有计数、清零功能。【例4-15】参数型n位计数器,带有异步复位和同步时钟使能。

modulecnt_N(clk,rst,en,Q,cout);inputclk,rst,en;outputreg[N-1:0]Q;outputcout;parameterN=4;always@(posedgerst,posedgeclk)begin if(rst)//计数器异步复位 Q<=0;//为了能生成诸如触发器一类的时序逻辑,建议使用非阻塞赋值 else if(en)//计数器同步使能 Q<=Q+1; endassigncout=(Q==0)?1'b1:1'b0;//计数器计满溢出后cout输出1endmodule程序说明:(1)仿真波形如图4-15所示。从图中可以看出,本段代码实现了一个十六进制计数器,并且具有异步复位和同步使能功能,在计数器溢出后将cout置1。图4-15例4-15的仿真波形(2)本计数器实现的是2的整数次幂计数,如果不是2n计数,如何实现呢?这时,需要使用条件语句判断计数是否达到最大值,如果是,则使计数器清零并从零开始计数。例4-16实现了一个十进制加法计数器。【例4-16】十进制加法计数器,带有异步复位和同步时钟使能功能。

modulecnt10(clk,rst,en,Q,cout);inputclk,rst,en;outputreg[N-1:0]Q;outputcout;parameterN=4;always@(posedgerst,posedgeclk)beginif(rst)//计数器异步复位 Q<=0;//为了能生成诸如触发器一类的时序逻辑,建议使用非阻塞赋值 else if(en)//计数器同步使能 if(Q==9)Q<=0; elseQ<=Q+1; endassigncout=(Q==0)?1'b1:1'b0;//计数器计满溢出后cout输出1endmodule例4-16的仿真波形如图4-16所示。从图中可以看出,本段代码实现了一个十进制加法计数器,并在计数器溢出后将cout置1。图4-16例4-16的仿真波形5.分频器在具体的电路设计中,可能需要很多种不同频率的时钟,但实际电路中往往只有一种单一频率的外部时钟输入,这时候就需要分频或倍频以得到我们需要的时钟频率。对于倍频电路,需要具体硬件的支持,本小节暂不阐述。对于分频电路,通过简单的设计即可实现。分频器电路是非常有用的一种电路,分频的方法很多,最常见的是利用加法计数器对时钟信号进行分频。下面通过几个例子分别介绍2的整数次幂分频、奇数分频、偶数分频的方法。【例4-17】参数型2n分频,占空比为50%。moduledivf_2powN(rst,clk,en,clk_N);inputrst,clk,en;outputclk_N;

parameterN=2;

reg[N-1:0]count;always@(posedgeclk)

beginif(rst)count<=0; elseif(en)count<=count+1;endassignclk_N=count[N-1];endmodule程序说明:(1)本例可实现2的任意整数次幂的分频器设计,占空比为50%。(2)本例中N定义为常整数2,也就是说本例实现的是2的2次幂分频,即4分频。如果要实现2的N次幂分频,则仅需要调用该模块,并修改参数N即可。例如要实现8分频,则将参数N修改为3即可,具体实现代码如下:moduledivf_2pow3(rst,clk,en,clk8);inputrst,clk,en;outputclk8;divf_2powN#(3)divf8(rst,clk,en,clk8);endmodule(3)本例除了可以得到2的N次幂分频外,还可以非常容易地得到2的N-1次幂、N-2次幂、…、1次幂分频,只需要多添加几条assign语句即可。例如:moduledivf_2pow4(rst,clk,en,clk2,clk4,clk8,clk16);inputrst,clk,en;outputclk2,clk4,clk8,clk16;reg[3:0]count;always@(posedgeclk)

begin if(rst)count<=0; elseif(en)count<=count+1;endassignclk2=count[0];//2分频assignclk4=count[1];//4分频assignclk8=count[2];//8分频assignclk16=count[3];//16分频endmodule【例4-18】参数型奇数分频,要求占空比为50%。moduledivf_oddn(clk,clk_N);inputclk;outputclk_N;

parameterN=3;

integerp,q;

regclk_p,clk_q;

always@(posedgeclk)//N分频设计实例,体会其算法(占空比为50%)

begin if(p==N-1)beginp=0;clk_p=~clk_p;endelsep=p+1;endalways@(negedgeclk)begin if(q==N-1)q=0;elseq=q+1; if(p==(N-1)/2)clk_q=~clk_q;endassignclk_N=clk_p^clk_q;endmodule程序说明:(1)对于奇数分频,仍然采用加法计数的方法,只是要对时钟的上升沿和下降沿分别计数,这是因为输出波形的改变不仅仅发生在时钟上升沿。(2)本例使用了两个计数器p和q分别对上升沿和下降沿计数,然后通过组合逻辑assignclk_N=clk_p^clk_q;控制输出时钟的电平,从而得到需要的时钟波形。(3)上述模块定义了一个参数化的奇数分频电路,并实现了一个3分频电路。如果设计一个顶层模块,调用该模块并修改参数,则可实现任意奇数分频。例如:moduledivf_oddn_top(clk,clk_3,clk_5,clk_7);inputclk;outputclk_3,clk_5,clk_7;divf_oddn#(3)div_odd3(clk,clk_3);divf_oddn#(5)div_odd5(clk,clk_5);divf_oddn#(7)div_odd7(clk,clk_7);endmodule上述模块的仿真波形如图4-17所示。图4-17任意奇数分频从图4-17可知,上述代码实现了任意奇数分频。【例4-19】参数型偶数分频,要求占空比为50%。moduledivf_even(clk,clk_N);inputclk;outputregclk_N;parameterN=6;integerp;always@(posedgeclk)beginif(p==N/2-1)beginp=0;clk_N=~clk_N;endelsep=p+1;endendmodule程序说明:(1)对于偶数分频,仍然采用加法计数的方法,只是要对时钟的上升沿进行计数,这是因为输出波形的改变仅仅发生在时钟上升沿。本例使用了一个计数器  p对上升沿计数,计数计到一半时,控制输出时钟的电平取反,从而得到需要的时钟波形。(2)上述模块定义了一个参数化的偶数分频电路,并实现了一个6分频电路。如果设计一个顶层模块,调用该模块并修改参数,则可实现任意偶数分频。例如:moduledivf_even_top(clk,clk_12,clk_10);inputclk;outputclk_12,clk_10;divf_even#(12)div_even12(clk,clk_12);divf_even#(10)div_even10(clk,clk_10);endmodule上述模块的仿真波形如图4-18所示。图4-18任意偶数分频从图4-18可知,上述代码实现了任意偶数分频。【例4-20】可设置参数的任意分频器,占空比可变。moduledivf_parameter(rst,clk,en,clkout);inputrst,clk,en;outputclkout;integertemp;//最大值为2的32次方parameterN=7,M=3;//N为分频系数,M/N为占空比always@(posedgeclk)beginif(rst)temp<=0; elseif(en) if(temp==N-1)temp<=0; elsetemp<=temp+1;endassignclkout=(temp<M)?1:0;endmodule(1)对于占空比可变的分频器,这时需要设置两个参数,一个控制分频比,另一个控制占空比,从而得到需要的时钟波形。上例中,N=7,M=3,说明是7分频电路,占空比为3/7。(2)上述模块定义了一个参数化的占空比可变的分频电路。如果设计一个顶层模块,调用该模块并修改参数,则可实现任意占空比的分频器。例如:modulediv_Para_top(rst,clk,en,clk3_2,clk5_1,clk6_3);//顶层设计inputrst,clk,en;outputclk3_2,clk5_1,clk6_3;divf_parameter#(3,2)f1(rst,clk,en,clk3_2);//3分频,占空比为2/3divf_parameter#(5,1)f2(rst,clk,en,clk5_1);//5分频,占空比为1/5divf_parameter#(6,3)f3(rst,clk,en,clk6_3);//6分频,占空比为3/6endmodule上述模块的仿真波形如图4-19所示。图4-19占空比可变的任意分频从图4-19可知,上述代码实现了占空比可变的任意分频功能。分频器是十分有用的电路,实际应用中除了需要得到任意占空比的整数分频器外,有时还需要小数分频器。对于小数分频器,则需要更复杂的算法,感兴趣的读者可查阅相关资料。6.程序存储器ROMROM在数字系统中用于存放指令或者常数。下面给出一个ROM实例,该ROM的数据宽度为16位,相应地它有4根地址线。将其设计为带读使能信号的异步ROM。【例4-21】参数型ROM设计。modulerom_nxm(rom_data,rom_addr,clk,rd,load);parameterM=8,N=4;//4根地址线,8位数据inputclk,rd;//rd读使能信号inputload;//用于初始化ROM值的控制信号input[N-1:0]rom_addr;outputreg[M-1:0]rom_data;reg[M-1:0]memory[0:2**N];//4根地址线,8位数据的存储器always@(posedgeload)begin:init//该always块用于初始化ROM值integeri; for(i=0;i<(2**N);i=i+1) memory[i]=i+1;endalways@(posedgeclk)begin:read//该always块用于读取ROM值 if(rd)rom_data=memory[rom_addr];endendmodule利用QuartusⅡ仿真的波形如图4-20所示。图4-20ROM仿真程序说明:(1)该程序设置了两个参数,M代表该ROM数据总线的宽度,N代表了地址线的数量,即2的N次方是ROM所能包含数据的最大个数。本例描述了一个8位宽,包含16个数据的ROM。(2) ROM的特性是只读,在使用前必须先装入数值,因此本例使用了一个always块为ROM赋初值。该初值需要根据实际情况设置,本例的初值设置只是为了演示其功能,没有实际的用途。(3)波形图为功能仿真结果,可以看到,当rd信号有效时,可将ROM中已存储的数据读出到rom_data中。ROM有时也用于设计组合逻辑电路,例如下面的例子可实现3-8线译码器的功能。modulerom_38(rom_data,rom_addr,load);//3-8线译码器功能parameterM=8,N=3;//3根地址线,8位数据inputload;//用于初始化ROM值的控制信号input[N-1:0]rom_addr;outputreg[M-1:0]rom_data;reg[M-1:0]memory[0:2**N];//3根地址线,8位数据的存储器always@(posedgeload)begin:init//该always块用于初始化ROM值 integeri; for(i=0;i<(2**N);i=i+1) memory[i]=1<<i;endalways@(rom_addr)rom_data=memory[rom_addr];endmodule利用QuartusⅡ对上述设计的仿真结果如图4-21所示。图4-21使用ROM实现3-8线译码器从以上仿真波形可以看出,该设计实现了3

温馨提示

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

评论

0/150

提交评论