logo资料库

使用VHDL进行各种分频器设计.pdf

第1页 / 共22页
第2页 / 共22页
第3页 / 共22页
第4页 / 共22页
第5页 / 共22页
第6页 / 共22页
第7页 / 共22页
第8页 / 共22页
资料共22页,剩余部分请下载后查看
概述
计数器
分频器
非50%占空比的奇数分频
50%占空比的奇数分频
分数分频器
积分分频器
使用 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
rst_tb <= transport '0'; wait for 2000 ns; end process; end testbench; 代码 2 加法计数器的 test bench 代码 图 2 加法计数器的仿真结果波形 在同一时刻,加法计数器的输出可能有多位发生变化,因此,当使用组合 逻辑对输出进行译码时,会导致尖峰脉冲信号。使用约翰逊计数器可以避免这 个问题。 约翰逊计数器 约翰逊计数器是一种移位计数器,采用的是把输出的最高位取非,然后反 馈送到最低位触发器的输入端。约翰逊计数器在每个时钟下只有一个输出发生 变化。下面是约翰逊计数器的 VHDL 实现代码。 --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 johnson is generic (width: integer := 4); port (clk, rst: in std_logic; cnt: out std_logic_vector(width - 1 downto 0)); end johnson; architecture a of johnson is signal cntQ: std_logic_vector(width - 1 downto 0); begin process(clk, rst) begin if(rst = '1') then cntQ <= (others => '0'); elsif (rising_edge(clk)) then cntQ(width - 1 downto 1) <= cntQ(width - 2 downto 0); cntQ(0) <= not cntQ(width - 1); end if; end process; 3
cnt <= cntQ; end a; 代码 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 代码中, architecture a 使用的是第一种 方案, architecture b 使用的是第二种方案。更改 configuration 可查看不同方案的 综合结果。 --filename clk_div1.vhd 4
; t and clk_in = '1') then ; ess(clk_in) k_in'even d_logic; clk_out: out std_logic); --description: 占空比为 50%的 6 分频 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all tity clk_div1 is en port(clk_in: in st end clk_div1; -- 使用第一种方案 of clk_div1 is architecture a '0';--赋初始值仅供仿真使用 signal clk_outQ: std_logic := signal countQ: std_logic_vector(2 downto 0) := "000"; begin proc begin if(cl if(countQ /= 2) then CountQ <= CountQ + 1 else outQ <= not clk_outQ; clk_ CountQ <= (others =>'0'); end if; end if; end process ; clk_out <= clk end a; 种方案 -- of clk_div1 is architecture b signal countQ: std_logic_vect begin proce begin if(c if(countQ < 5) then countQ <= countQ + else Coun end if; end if; ; end process begin if(co clk_out <= '0'; else out <= '1'; clk_ process(countQ) untQ < 3) 1; tQ <= (others =>'0'); _outQ; then 使用第二 or(2 downto 0); ss(clk_in) lk_in'event and clk_in = '1') then 5
分享到:
收藏