dynamic_freq_div.vhd
98 lines
| 3.6 KiB
| text/x-vhdl
|
VhdlLexer
Alexis Jeandet
|
r530 | ------------------------------------------------------------------------------ | |
-- This file is a part of the LPP VHDL IP LIBRARY | |||
-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS | |||
-- | |||
-- This program is free software; you can redistribute it and/or modify | |||
-- it under the terms of the GNU General Public License as published by | |||
-- the Free Software Foundation; either version 3 of the License, or | |||
-- (at your option) any later version. | |||
-- | |||
-- This program is distributed in the hope that it will be useful, | |||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
-- GNU General Public License for more details. | |||
-- | |||
-- You should have received a copy of the GNU General Public License | |||
-- along with this program; if not, write to the Free Software | |||
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
------------------------------------------------------------------------------ | |||
-- Author : Alexis Jeandet | |||
-- Mail : alexis.jeandet@member.fsf.org | |||
------------------------------------------------------------------------------ | |||
library IEEE; | |||
use IEEE.STD_LOGIC_1164.ALL; | |||
use IEEE.NUMERIC_STD.ALL; | |||
entity dynamic_freq_div is | |||
generic( | |||
PRESZ : integer range 1 to 32:=4; | |||
PREMAX : integer := 16#FFFFFF#; | |||
CPTSZ : integer range 1 to 32:=16 | |||
); | |||
Port ( | |||
clk : in STD_LOGIC; | |||
rstn : in STD_LOGIC; | |||
pre : in STD_LOGIC_VECTOR(PRESZ-1 downto 0); | |||
N : in STD_LOGIC_VECTOR(CPTSZ-1 downto 0); | |||
Reload : in std_logic; | |||
clk_out : out STD_LOGIC | |||
); | |||
end dynamic_freq_div; | |||
architecture Behavioral of dynamic_freq_div is | |||
constant prescaller_reg_sz : integer := 2**PRESZ; | |||
constant PREMAX_max : STD_LOGIC_VECTOR(PRESZ-1 downto 0):=(others => '1'); | |||
signal cpt_reg : std_logic_vector(CPTSZ-1 downto 0):=(others => '0'); | |||
pellion
|
r547 | signal prescaller_reg : std_logic_vector(prescaller_reg_sz-1 downto 0);--:=(others => '0'); | |
Alexis Jeandet
|
r530 | signal internal_clk : std_logic:='0'; | |
signal internal_clk_reg : std_logic:='0'; | |||
signal clk_out_reg : std_logic:='0'; | |||
begin | |||
max0: if (UNSIGNED(PREMAX_max) < PREMAX) generate | |||
internal_clk <= prescaller_reg(to_integer(unsigned(pre))) when (to_integer(unsigned(pre))<=UNSIGNED(PREMAX_max)) else | |||
prescaller_reg(to_integer(UNSIGNED(PREMAX_max))); | |||
end generate; | |||
max1: if UNSIGNED(PREMAX_max) > PREMAX generate | |||
internal_clk <= prescaller_reg(to_integer(unsigned(pre))) when (to_integer(unsigned(pre))<=PREMAX) else | |||
prescaller_reg(PREMAX); | |||
end generate; | |||
prescaller: process(rstn, clk) | |||
begin | |||
if rstn='0' then | |||
prescaller_reg <= (others => '0'); | |||
elsif clk'event and clk = '1' then | |||
prescaller_reg <= std_logic_vector(UNSIGNED(prescaller_reg) + 1); | |||
end if; | |||
end process; | |||
clk_out <= clk_out_reg; | |||
counter: process(rstn, clk) | |||
begin | |||
if rstn='0' then | |||
cpt_reg <= (others => '0'); | |||
internal_clk_reg <= '0'; | |||
clk_out_reg <= '0'; | |||
elsif clk'event and clk = '1' then | |||
internal_clk_reg <= internal_clk; | |||
if Reload = '1' then | |||
clk_out_reg <= '0'; | |||
cpt_reg <= (others => '0'); | |||
elsif (internal_clk = '1' and internal_clk_reg = '0') then | |||
if cpt_reg = N then | |||
clk_out_reg <= not clk_out_reg; | |||
cpt_reg <= (others => '0'); | |||
else | |||
cpt_reg <= std_logic_vector(UNSIGNED(cpt_reg) + 1); | |||
end if; | |||
end if; | |||
end if; | |||
end process; | |||
pellion
|
r547 | end Behavioral; |