前言
本文介绍基于前置N/N+1分频器的小数分频基本原理,以及基于此原理的一位小数分频器的源代码,受数据位宽的影响,本文给出的代码系数整数部分的范围为0-15,如需更大数值可自行修改代码。建议引用本文代码时请注明作者,但不强求谢谢合作。
一、原理介绍:
假设分频系数为N.X,则N*(10-X)+(N+1)*X=10*N-N*X+N*X+X=10*N+X=N.X*10由上式可见只要满足输出十个脉冲的时间内输入脉冲为10*N+X就可实现N.X分频.可对输入时钟进行(10-X)次N分频和X次(N+1)分频实现,由于先进行(10-X)次分频后进行X次(N+1)分频会造成相位有很大变化,可采用N分频和(N+1)分频交替进行的方法来改善相伴变化.实现原理不再过多介绍,请参看sel部分源代码。
二、源代码
1:NdotXfd,顶层文件
----------------------------------------------------------------------------------
-- Company: Hiline
-- Engineer: Liu Xiting
-- Email: Liu_xitin@163.com;liuxiting@foxmail.com
--
-- Create Date: 21:13:54 01/03/2008
-- Design Name: N.x frequency deviation
-- Module Name: NdotXfd
-- Project Name: NdotXfd
-- Target Devices: EP1C6Q240C8 or other FPGA/CPLD Device
-- Tool versions: Quartus II 7.2
-- Description: Topview of the project
--
-- Dependencies:
--
-- Revision: V1.0
--
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity NdotXfd is
port (
clock : in std_logic;
n : in std_logic_vector(3 downto 0);
x : in std_logic_vector(3 downto 0);
clock_out : out std_logic
);
end entity;
architecture arch of NdotXfd is
component number
port(
n : in std_logic_vector(3 downto 0);
number0 : out std_logic_vector(3 downto 0);
number1 : out std_logic_vector(3 downto 0)
);
end component;
component fdn
port(
clock_in : in std_logic;
enable : in std_logic;
n_of_fd : in std_logic_vector(3 downto 0);
clock_out : out std_logic
);
end component;
component sel
port(
clock_in : in std_logic;
Xnumber : in std_logic_vector(3 downto 0);
sel_out : out std_logic
);
end component;
component mux_21
port(
a : in std_logic;
b : in std_logic;
s : in std_logic;
y : out std_logic
);
end component;
signal selt : std_logic;
signal selt_not : std_logic;
signal clock_1 : std_logic;
signal clock_2 : std_logic;
signal clock_sel: std_logic;
signal n_fd : std_logic_vector(3 downto 0);
signal n1_fd : std_logic_vector(3 downto 0);
begin
number0 : number port map (n, n_fd, n1_fd);
fdn0 : fdn port map (clock, selt_not, n_fd, clock_1);
fdn1 : fdn port map (clock, selt, n1_fd, clock_2);
mux_210 : mux_21 port map (clock_2, clock_1, selt, clock_sel);
sel0 : sel port map (clock_sel, x, selt);
selt_not <= not selt;
clock_out <= clock_sel;
end arch;
2:fdn,任意整数分频器(分步系数2--15,可自行修改代码增加分频系数)
----------------------------------------------------------------------------------
-- Company: Hiline
-- Engineer: Liu Xiting
-- Email: Liu_xitin@163.com;liuxiting@foxmail.com
--
-- Create Date: 21:13:54 01/03/2008
-- Design Name: N.x frequency deviation
-- Module Name: fdn
-- Project Name: NdotXfd
-- Target Devices: EP1C6Q240C8 or other FPGA/CPLD Device
-- Tool versions: Quartus II 7.2
-- Description: natural coefficient frequency deviation
--
-- Dependencies: The input n_of_fd must be natural number
--
-- Revision: V1.0
--
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fdn is
port
(
clock_in : in std_logic;
enable : in std_logic;
n_of_fd : in std_logic_vector(3 downto 0);
clock_out : out std_logic
);
end entity;
architecture bhv of fdn is
signal clock : std_logic;
signal q0 : std_logic;
signal q1 : std_logic;
signal number : std_logic_vector(2 downto 0);
signal counter0 : std_logic_vector(3 downto 0);
signal counter1 : std_logic_vector(3 downto 0);
begin
fdn: process(enable, clock_in, n_of_fd, clock, q0, q1)
begin
number(2 downto 0) <= n_of_fd(3 downto 1);
if q1 = '0' then
clock <= not clock_in;
else
clock <= clock_in;
end if;
if (enable='1') then
if (n_of_fd(0)='0')then
counter1 <= (others=>'0');
q1 <= '0';
if rising_edge(clock_in) then
if (number="001") then
q0 <= not q0;
else
if counter0 = number-1 then
counter0 <= (others=>'0');
q0 <= not q0;
else
counter0 <= counter0 + 1;
end if;
end if;
end if;
else
counter0 <= (others=>'0');
q0 <= '0';
if rising_edge(clock) then
if counter1 = number then
counter1 <= (others=>'0');
q1 <= not q1;
else
counter1 <= counter1 + 1;
end if;
end if;
end if;
else
q0 <= '0';
q1 <= '0';
counter0 <= (others=>'0');
counter1 <= (others=>'0');
end if;
end process fdn;
output: process (enable, n_of_fd(0), q0, q1)
begin
if (enable='1') then
if (n_of_fd(0)='0')then
clock_out <= q0;
else
clock_out <= q1;
end if;
else
clock_out <= '0';
end if;
end process output;
end bhv;
3:sel,分频器选择信号判断产生器
----------------------------------------------------------------------------------
-- Company: Hiline
-- Engineer: Liu Xiting
-- Email: Liu_xitin@163.com;liuxiting@foxmail.com
--
-- Create Date: 21:13:54 01/03/2008
-- Design Name: N.x frequency deviation
-- Module Name: sel
-- Project Name: NdotXfd
-- Target Devices: EP1C6Q240C8 or other FPGA/CPLD Device
-- Tool versions: Quartus II 7.2
-- Description: Judge to seletc N fd or N+1 fd
-- sel_out=1 to seletc N fd;
-- sel_out=0 to select N+1 fd;
--
-- Dependencies:
--
-- Revision: V1.0
--
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity sel is
port
(
clock_in : in std_logic;
Xnumber : in std_logic_vector(3 downto 0);
sel_out : out std_logic
);
end entity;
architecture bhv of sel is
signal XsubTen : std_logic_vector(3 downto 0);
signal q : std_logic_vector(4 downto 0);
begin
XsubTen <= 10 - Xnumber;
sel: process(clock_in, q)
begin
if (clock_in'event and clock_in = '0') then
if q + XsubTen >= 10 then
q <= q + XsubTen - 10;
else
q <= q + XsubTen;
end if;
end if;
if q >= Xnumber then
sel_out <= '0';
else
sel_out <= '1';
end if;
end process sel;
end bhv;
4:mux2_1,2选1数据选择器
----------------------------------------------------------------------------------
-- Company: Hiline
-- Engineer: Liu Xiting
-- Email: Liu_xitin@163.com;liuxiting@foxmail.com
--
-- Create Date: 21:13:54 01/03/2008
-- Design Name: N.x frequency deviation
-- Module Name: mux_21
-- Project Name: NdotXfd
-- Target Devices: EP1C6Q240C8 or other FPGA/CPLD Device
-- Tool versions: Quartus II 7.2
-- Description: 21mux
-- y=a (if s=1);
-- y=b (if s=0);
--
-- Dependencies: none
--
-- Revision: V1.0
--
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity mux_21 is
port(
a : in std_logic;
b : in std_logic;
s : in std_logic;
y : out std_logic
);
end entity;
architecture bhv of mux_21 is
begin
with s select
y <= a when '1' ,
b when others;
end bhv;
5:number,分频器系数处理器
----------------------------------------------------------------------------------
-- Company: Hiline
-- Engineer: Liu Xiting
-- Email: Liu_xitin@163.com;liuxiting@foxmail.com
--
-- Create Date: 21:13:54 01/03/2008
-- Design Name: N.x frequency deviation
-- Module Name: number
-- Project Name: NdotXfd
-- Target Devices: EP1C6Q240C8 or other FPGA/CPLD Device
-- Tool versions: Quartus II 7.2
-- Description: coefficient of fdn;
-- number0 is the coefficient of fdn;
-- numger1 is the coefficient of fdn1(number1=number0+1);
--
-- Dependencies:
--
-- Revision: V1.0
--
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity number is
port
( n : in std_logic_vector(3 downto 0);
number0 : out std_logic_vector(3 downto 0);
number1 : out std_logic_vector(3 downto 0)
);
end entity;
architecture bhv of number is
begin
number0 <= n;
number1 <= n+1;
end bhv;
三、仿真波形见上传图片