VHDL语言实现的任意整数分频器

fpga中,一般外接的晶振是50Mhz,如果电路中一个模块需要25mhz时钟,那么进行一个2分频,这个是相当容易的,下面是一种方法,还有可以用一个二进制计数器实现。这里就不写代码了。easy.同样的原理 ,四分频也很容易。

process(clk)--clk输入时钟;
begin
  if(rst = '0') then  --rst复位信号;
     clkout <= '0';
  elsif(clk;event and clk = '1')then
     clkout <= not clk;
  end if;
end process;
但是如果实现一个三分频呢?? 是不是3分频器应该是每1.5clock0110,但问题来了,哪来的1.5clock?计数器并不能产生1.5!!正源触发与负源触发的间隔时间刚好是0.5clock?所以我们产生两个clock,一个是posedge clk,一个是negedge clk,最后将两个clockor,这样就可以产生出0.5clock了。下面给出代码:::
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity clk_div_n is

    port(clk : in std_logic;
         rst : in std_logic; 
         clkout :out std_logic
         );
end clk_div_n;

architecture rtl of clk_div_n is
    
constant n   : integer range 0 to 10 := 6;  --这里的n可以是任意值,当然要大于1.
signal clk_p : std_logic;
signal clk_n : std_logic;

signal cnt_p : integer range 0 to n;
signal cnt_n : integer range 0 to n;

begin 
    process(clk_p, clk_n)
    begin
        if((n mod 2) = 0)then
            clkout <= clk_p;
        else
            clkout <= clk_p or clk_n;
        end if;
    end process;


     process(clk, rst)
     begin
        if(rst = '0') then
           cnt_p <= 0;
        elsif(clk'event and clk = '1') then
          if(cnt_p = n-1) then
              cnt_p <= 0;
          else
              cnt_p <= cnt_p + 1;
          end if;
        end if;
     end process;
        
     process(clk, rst)
     begin
          if(rst = '0') then
             clk_p <= '0';
          elsif(clk'event and clk = '1')then
            if (cnt_p < (n/2)) then
                clk_p <= '1';
            else
                clk_p <= '0';
            end if ;
          end if;
     end process; 
     
     
     process(clk, rst)
     begin
        if(rst = '0') then
           cnt_n <= 0;
        elsif(clk'event and clk = '0')then
          if(cnt_n = n-1) then
              cnt_n <= 0;
          else
              cnt_n <= cnt_n + 1;
          end if;
        end if;
     end process;
     
     process(clk, rst)
     begin
          if(rst = '0') then
             clk_n <= '0';
          elsif(clk'event and clk = '0')then
            if (cnt_n < (n/2)) then
                clk_n <= '1';
            else
                clk_n <= '0';
            end if ;
          end if;
     end process; 
end rtl;             
接下来我给出对应的testbench::有兴趣可以用make a simulation in modelsim 
LIBRARY ieee  ; 
USE ieee.std_logic_1164.all  ; 
USE ieee.std_logic_arith.all  ; 
USE ieee.std_logic_unsigned.all  ; 
ENTITY clk_div_n_tb  IS 
END clk_div_n_tb; 
 
ARCHITECTURE clk_div_tb_arch OF clk_div_n_tb IS
  SIGNAL clkout   :  std_logic  ; 
  SIGNAL rst   :  std_logic := '0' ; 
  SIGNAL clk   :  std_logic := '1' ; 
  COMPONENT clk_div_n  
    PORT ( 
      clk  : in std_logic ;
      rst  : in std_logic ; 
      clkout  : out std_logic
       ); 
  END COMPONENT ; 
BEGIN
  process
    begin
    wait for 50ns;
       clk <= not clk;
  end process;
  rst <= '1' after 200ns;
    test:clk_div_n
    PORT MAP ( 
      clk    => clk,
      rst    => rst,
      clkout => clkout) ; 
END clk_div_tb_arch; 




posted @ 2015-05-26 23:39  IAmAProgrammer  阅读(3441)  评论(0编辑  收藏  举报