小数分频VHDL源代码(完全原创)

上一篇 / 下一篇  2008-01-06 10:04:51 / 个人分类:FPGA

      前言

      本文介绍基于前置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;

三、仿真波形见上传图片


TAG: 小数分频 VHDL vhdl

引用 删除 秦关   /   2008-11-28 09:46:15
没学过vhdl,看不懂,有用Verilog编的吗?那些分频的我们是用Verilog编的
Garfield's Home 引用 删除 liuxiting   /   2008-04-11 17:13:23
将输入端的n设为1,x设为101就可以了
b421lxm的个人空间 引用 删除 b421lxm   /   2008-03-06 20:01:08
刚好我可以借来用一哈
谢谢哈
引用 删除 a-gan   /   2008-02-28 11:44:13
如何进行1.5 分频?
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2008-12-04  
 123456
78910111213
14151617181920
21222324252627
28293031   

数据统计

  • 访问量: 1185
  • 日志数: 4
  • 建立时间: 2008-01-06
  • 更新时间: 2008-10-01

RSS订阅

Open Toolbar