使用 VHDL 进行分频器设计
作者:ChongyangLee
摘要
使用 VHDL 进行分频器设计
作者:ChongyangLee
本文使用实例描述了在 FPGA/CPLD 上使用 VHDL 进行分频器设
计,包括偶数分频、非 50%占空比和 50%占空比的奇数分频、半整数
(N+0.5)分频、小数分频、分数分频以及积分分频。所有实现均可
通过 Synplify Pro 或 FPGA 生产厂商的综合器进行综合,形成可使
用的电路,并在 ModelSim 上进行验证。
目录
概述....................................................................................................................................... 1
计数器 .................................................................................................................................. 1
普通计数器..................................................................................................................1
约翰逊计数器.............................................................................................................3
分频器 .................................................................................................................................. 4
偶数分频器..................................................................................................................4
奇数分频器..................................................................................................................6
半整数分频器.............................................................................................................9
小数分频器................................................................................................................11
分数分频器................................................................................................................15
积分分频器................................................................................................................18
概述
分频器是数字电路中最常用的电路之一,在 FPGA 的设计中也是使用效率
非常高的基本设计。基于 FPGA 实现的分频电路一般有两种方法:一是使用
FPGA 芯片内部提供的锁相环电路,如 ALTERA 提供的 PLL(Phase Locked
Loop),Xilinx 提供的 DLL(Delay Locked Loop);二是使用硬件描述语言,如
VHDL、Verilog HDL 等。使用锁相环电路有许多优点,如可以实现倍频;相位
偏移;占空比可调等。但 FPGA 提供的锁相环个数极为有限,不能满足使用要
求。因此使用硬件描述语言实现分频电路经常使用在数字电路设计中,消耗不
多的逻辑单元就可以实现对时钟的操作,具有成本低、可编程等优点。
计数器
计数器是实现分频电路的基础,计数器有普通计数器和约翰逊计数器两
种。这两种计数器均可应用在分频电路中。
普通计数器
最普通的计数器是加法(或减法)计数器。下面是加法计数器的VHDL实
现,其Synplify Pro下的RTL View如图 1所示。
--file Name: ripple.vhd
--Description: 带复位功能的加法计数器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ripple is
generic (width: integer := 4);
port(clk, rst: in std_logic;
cnt: out std_logic_vector(width - 1 downto 0));
end
ripple;
architecture a of ripple is
signal cntQ: std_logic_vector(width - 1 downto 0);
begin
process(clk, rst)
begin
if (rst = '1') then
cntQ <= (others => '0');
elsif (clk'event and clk = '1') then
cntQ <= cntQ + 1;
1
end if;
end process;
cnt <= cntQ;
end a;
代码 1 加法计数器 VHDL 代码
图 1 加法计数器 RTL 视图
加法计数器的Test Bench代码如下所示,在ModelSim下进行功能仿真,仿真
波形结果如图 2所示。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ripple_tb is
end ripple_tb;
architecture testbench of ripple_tb is
component ripple
generic(width: integer := 4);
port(clk, rst: in std_logic;
cnt: out std_logic_vector(width - 1 downto 0));
end component;
signal clk_tb: std_logic := '0';
signal rst_tb: std_logic := '0';
signal cnt_tb: std_logic_vector(3 downto 0);
begin
UUT: ripple generic map(width => 4)
port map(clk => clk_tb, rst => rst_tb, cnt => cnt_tb);
clk_tb <= not clk_tb after 50 ns;
process
begin
rst_tb <= transport '1';
wait for 200 ns;
2