使用VHDL进行分频器设计.docx

上传人:b****5 文档编号:8099443 上传时间:2023-01-28 格式:DOCX 页数:30 大小:22.80KB
下载 相关 举报
使用VHDL进行分频器设计.docx_第1页
第1页 / 共30页
使用VHDL进行分频器设计.docx_第2页
第2页 / 共30页
使用VHDL进行分频器设计.docx_第3页
第3页 / 共30页
使用VHDL进行分频器设计.docx_第4页
第4页 / 共30页
使用VHDL进行分频器设计.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

使用VHDL进行分频器设计.docx

《使用VHDL进行分频器设计.docx》由会员分享,可在线阅读,更多相关《使用VHDL进行分频器设计.docx(30页珍藏版)》请在冰豆网上搜索。

使用VHDL进行分频器设计.docx

使用VHDL进行分频器设计

 

使用VHDL进行分频器设计

 

作者:

ChongyangLee

 

摘要

 

使用VHDL进行分频器设计

作者:

ChongyangLee

 

本文使用实例描述了在FPGA/CPLD上使用VHDL进行分频器设

计,包括偶数分频、非50%占空比和50%占空比的奇数分频、半整数

(N+0.5)分频、小数分频、分数分频以及积分分频。

所有实现均可

通过SynplifyPro或FPGA生产厂商的综合器进行综合,形成可使

用的电路,并在ModelSim上进行验证。

 

概述.......................................................................................................................................1

计数器..................................................................................................................................1

普通计数器..................................................................................................................1

约翰逊计数器.............................................................................................................3

分频器..................................................................................................................................4

偶数分频器..................................................................................................................4

奇数分频器..................................................................................................................6

半整数分频器.............................................................................................................9

小数分频器................................................................................................................11

分数分频器................................................................................................................15

积分分频器................................................................................................................18

 

概述

分频器是数字电路中最常用的电路之一,在FPGA的设计中也是使用效率

非常高的基本设计。

基于FPGA实现的分频电路一般有两种方法:

一是使用

FPGA芯片内部提供的锁相环电路,如ALTERA提供的PLL(PhaseLocked

Loop),Xilinx提供的DLL(DelayLockedLoop);二是使用硬件描述语言,如

VHDL、VerilogHDL等。

使用锁相环电路有许多优点,如可以实现倍频;相位

偏移;占空比可调等。

但FPGA提供的锁相环个数极为有限,不能满足使用要

求。

因此使用硬件描述语言实现分频电路经常使用在数字电路设计中,消耗不

多的逻辑单元就可以实现对时钟的操作,具有成本低、可编程等优点。

 

计数器

计数器是实现分频电路的基础,计数器有普通计数器和约翰逊计数器两

种。

这两种计数器均可应用在分频电路中。

普通计数器

最普通的计数器是加法(或减法)计数器。

下面是加法计数器的VHDL实

现,其SynplifyPro下的RTLView如图1所示。

--fileName:

ripple.vhd

--Description:

带复位功能的加法计数器

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityrippleis

generic(width:

integer:

=4);

port(clk,rst:

instd_logic;

cnt:

outstd_logic_vector(width-1downto0));

endripple;

architectureaofrippleis

signalcntQ:

std_logic_vector(width-1downto0);

begin

process(clk,rst)

begin

if(rst='1')then

cntQ<=(others=>'0');

elsif(clk'eventandclk='1')then

cntQ<=cntQ+1;

 

1

 

endif;

endprocess;

cnt<=cntQ;

enda;

 

代码1加法计数器VHDL代码

 

图1加法计数器RTL视图

加法计数器的TestBench代码如下所示,在ModelSim下进行功能仿真,仿真

波形结果如图2所示。

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityripple_tbis

endripple_tb;

architecturetestbenchofripple_tbis

componentripple

generic(width:

integer:

=4);

port(clk,rst:

instd_logic;

cnt:

outstd_logic_vector(width-1downto0));

endcomponent;

signalclk_tb:

std_logic:

='0';

signalrst_tb:

std_logic:

='0';

signalcnt_tb:

std_logic_vector(3downto0);

begin

UUT:

ripplegenericmap(width=>4)

portmap(clk=>clk_tb,rst=>rst_tb,cnt=>cnt_tb);

clk_tb<=notclk_tbafter50ns;

process

begin

rst_tb<=transport'1';

waitfor200ns;

 

2

 

rst_tb<=transport'0';

waitfor2000ns;

endprocess;

endtestbench;

代码2加法计数器的testbench代码

 

图2加法计数器的仿真结果波形

在同一时刻,加法计数器的输出可能有多位发生变化,因此,当使用组合

逻辑对输出进行译码时,会导致尖峰脉冲信号。

使用约翰逊计数器可以避免这

个问题。

约翰逊计数器

约翰逊计数器是一种移位计数器,采用的是把输出的最高位取非,然后反

馈送到最低位触发器的输入端。

约翰逊计数器在每个时钟下只有一个输出发生

变化。

下面是约翰逊计数器的VHDL实现代码。

--fileName:

ripple.vhd

--Description:

带复位功能的约翰逊计数器

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

 

entityjohnsonis

generic(width:

integer:

=4);

port(clk,rst:

instd_logic;

cnt:

outstd_logic_vector(width-1downto0));

endjohnson;

architectureaofjohnsonis

signalcntQ:

std_logic_vector(width-1downto0);

begin

process(clk,rst)

begin

if(rst='1')then

cntQ<=(others=>'0');

elsif(rising_edge(clk))then

cntQ(width-1downto1)<=cntQ(width-2downto0);

cntQ(0)<=notcntQ(width-1);

endif;

endprocess;

3

 

cnt<=cntQ;

enda;

 

代码3约翰逊计数器VHDL代码

 

图3约翰逊计数器RTL视图

显然,约翰逊计数器没有有效利用寄存器的所有状态,假设最初值或复位

状态为0000,则依次为0000、0001、0011、0111、1111、1110、1100、1000、

0000如此循环。

再者,如果由于干扰噪声引入一个无效状态,如0010,则无法

恢复到有效到循环中去,需要我们加入错误恢复处理,在此不再赘述。

 

分频器

如前所述,分频器的基础是计数器,设计分频器的关键在于输出电平翻转

的时机。

下面使用加法计数器分别描述各种分频器的实现。

偶数分频器

偶数分频最易于实现,欲实现占空比为50%的偶数N分频,一般来说有两

种方案:

一是当计数器计数到N/2-1时,将输出电平进行一次翻转,同时给计

数器一个复位信号,如此循环下去;二是当计数器输出为0到N/2-1时,时钟输

出为0或1,计数器输出为N/2到N-1时,时钟输出为1或0,当计数器计数到

N-1时,复位计数器,如此循环下去。

需要说明的是,第一种方案仅仅能实现占

空比为50%的分频器,第二种方案可以有限度的调整占空比,参考非50%占空

比的奇数分频实现。

在如下所示的以6分频为例的VHDL代码中,architecturea使用的是第一种

方案,architectureb使用的是第二种方案。

更改configuration可查看不同方案的

综合结果。

--filenameclk_div1.vhd

4

 

--description:

占空比为50%的6分频

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityclk_div1is

port(clk_in:

instd_logic;clk_out:

outstd_logic);

endclk_div1;

--使用第一种方案

architecturea

ofclk_div1is

signalclk_outQ:

std_logic:

='0';--赋初始值仅供仿真使用

signalcountQ:

std_logic_vector(2downto0):

="000";

begin

process(clk_in)

begin

if(clk_in'eventandclk_in='1')then

if(countQ/=2)then

CountQ<=CountQ+1;

else

clk_outQ<=notclk_outQ;

CountQ<=(others=>'0');

endif;

endif;

endprocess;

clk_out<=clk_outQ;

enda;

--使用第二种方案

architectureb

ofclk_div1is

signalcountQ:

std_logic_vector(2downto0);

begin

process(clk_in)

begin

if(clk_in'eventandclk_in='1')then

if(countQ<5)then

countQ<=countQ+1;

else

CountQ<=(others=>'0');

endif;

endif;

endprocess;

process(countQ)

begin

if(countQ<3)then

clk_out<='0';

else

clk_out<='1';

 

5

 

endif;

endprocess;

endb;

configurationcfgofclk_div1is

fora

endfor;

endcfg;

代码4偶数分频的VHDL代码

图4图5所示的分别是使用architecturea和architectureb的仿真结果波形。

两者均

正确的实现了50%占空比的6分频。

 

图4architecturea的仿真结果

 

图5architectureb的仿真结果

奇数分频器

实现非

50%占空比的奇数分频,如实现占空比为20%(1/5)、40%

(2/5)、60%(3/5)、80%(4/5)的5

种方案;但如果实现占空比为50%的奇数分频,就不能使用偶数分频中所采用

的方案了。

非50%占空比的奇数分频

下面就以实现占空比为40%的5分频分频器为例,说明非50%占空比的奇数

分频器的实现。

该分频器的实现对于我们实现50%占空比的分频器有一定的借

鉴意义。

--filenameclk_div2.vhd

--description:

占空比为40%的5分频

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityclk_div2is

port(clk_in:

instd_logic;clk_out:

outstd_logic);

endclk_div2;

6

 

architectureaofclk_div2is

signalcountQ:

std_logic_vector(2downto0);

begin

process(clk_in)

begin

if(clk_in'eventandclk_in='1')then

if(countQ<4)then

countQ<=countQ+1;

else

CountQ<=(others=>'0');

endif;

endif;

endprocess;

process(countQ)

begin

if(countQ<3)then

clk_out<='0';

else

clk_out<='1';

endif;

endprocess;

enda;

代码5占空比为40%的5分频

仿真波形如图6所示。

 

图6占空比为40%的5分频仿真波形

50%占空比的奇数分频

通过待分频时钟下降沿触发计数,产生一个占空比为40%(2/5)的5分频

的时钟相或,即可得到一个占空比为50%

器。

将产生的时钟与上升沿触发产生

的5分频器。

推广为一般方法:

欲实现占空比为50%的2N+1分频器,则需要对待分频时

钟上升沿和下降沿分别进行N/(2N+1)分频,然后将两个分频所得的时钟信号相

或得到占空比为50%的2N+1分频器。

下面的代码就是利用上述思想获得占空比为50%的7分频器。

需要我们分别

对上升沿和下降沿进行3/7分频,再将分频获得的信号相或。

 

7

 

--filenameclk_div3.vhd

--description:

占空比为50%的7分频

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arth.all;

useieee.std_logic_unsigned.all;

entityclk_div3is

port(clk_in:

instd_logic;clk_out:

outstd_logic);

endclk_div3;

architectureaofclk_div3is

signalcnt1,cnt2:

integerrange0to6;

signalclk1,

begin

clk2:

std_logic;

process(clk_in)--上升沿

begin

if(rising_edge(clk_in))then

if(cnt1<6)then

cnt1<=cnt1+1;

else

cnt1<=0;

endif;

if(cnt1<3)then

clk1<='1';

else

clk1<='0';

endif;

endif;

endprocess;

process(clk_in)--下降沿

begin

if(falling_edge(clk_in))then

if(cnt2<6)then

cnt2<=cnt2+1;

else

cnt2<=0;

endif;

if(cnt2<3)then

clk2<='1';

else

clk2<='0';

endif;

endif;

endprocess;

clk_out<=clk1orclk2;

 

8

 

enda;

 

代码6占空比为50%的7分频VHDL代码

综合得到的RTL视图如图7所示,仿真结果如图8所示。

 

图7占空比为50%的7分频RTL视图

 

图8占空比为50%的7分频仿真波形

占空比为50%的奇数分频可以帮助我们实现半整数分频。

半整数分频器

仅仅采用数字分频,不可能获得占空比为50%的N+0.5分频,我们只可以

设计出占空比为(M+0.5)/(N+0.5)或者M/(N+0.5)的分频器,M小于N。

这种半整

数分频方法是对输入时钟进行操作,让计数器计数到某一个数值时,将输入时

钟电平进行一次反转,这样,该计数值只保持了半个时钟周期,因此实现半整

数分频。

如上所述,占空比为50%的奇数分频可以帮助我们实现半整数分频,将占

空比为50%的奇数分频与待分频时钟异或得到计数脉冲,下面的代码就是依靠

占空比为50%的5分频实现2.5分频器的。

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityclk_div4is

9

 

port(clk_in:

instd_logic;clk_out:

outstd_logic);

endclk_div4;

architectureaofclk_div4is

signalcnt1,cnt2:

integerrange0to4;

signalclk1,clk2:

std_logic;

signalPclk,

signalcnt3:

begin

Lclk:

std_logic;

integerrange0to2;

process(clk_in)

begin

if(rising_edge(clk_in))then

if(cnt1<4)then

cnt1<=cnt1+1;

else

cnt1<=0;

endif;

endif;

endprocess;

process(clk_in)

begin

if(falling_edge(clk_in))then

if(cnt2<4)then

cnt2<=cnt2+1;

else

cnt2<=0;

endif;

endif;

endprocess;

process(cnt1)

begin

if(cnt1<

3)then

clk1<='0';

else

clk1<='1';

endif;

endprocess;

process(cnt2)

begin

if(cnt2<3)then

clk2<='0';

else

clk2<='1';

endif;

endprocess;

process(Lclk)

begin

 

10

 

if(rising_edge(Lclk))then

if(cnt3<2)then

cnt3<=cnt3+1;

else

cnt3<=0;

endif;

endif;

endprocess;

process(cnt3)

begin

if(cnt3<1)then

clk_out<='0';

else

clk_out<='1';

endif;

endprocess;

Pclk

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

当前位置:首页 > 职业教育 > 职高对口

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1