SURF  1.0
ClockDivider.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : ClockDivider.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-06-01
5 -- Last update: 2016-09-22
6 -------------------------------------------------------------------------------
7 -- Description: A clock divider with programmable duty cycle and phase delay.
8 -------------------------------------------------------------------------------
9 -- This file is part of StdLib. It is subject to
10 -- the license terms in the LICENSE.txt file found in the top-level directory
11 -- of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of StdLib, including this file, may be
14 -- copied, modified, propagated, or distributed except according to the terms
15 -- contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 
19 library ieee;
20 use ieee.std_logic_1164.all;
21 use ieee.std_logic_arith.all;
22 use ieee.std_logic_unsigned.all;
23 use work.StdRtlPkg.all;
24 
25 --! @see entity
26  --! @ingroup base_general
27 entity ClockDivider is
28 
29  generic (
30  TPD_G : time := 1 ns;
31  LEADING_EDGE_G : sl := '1';
32  COUNT_WIDTH_G : integer range 1 to 32 := 16);
33  port (
34  clk : in sl;
35  rst : in sl;
36  highCount : in slv(COUNT_WIDTH_G-1 downto 0);
37  lowCount : in slv(COUNT_WIDTH_G-1 downto 0);
38  delayCount : in slv(COUNT_WIDTH_G-1 downto 0);
39  divClk : out sl;
40  preRise : out sl;
41  preFall : out sl);
42 
43 end entity ClockDivider;
44 
45 architecture rtl of ClockDivider is
46 
47  type StateType is (DELAY_S, CLOCK_S);
48 
49  type RegType is record
50  state : StateType;
51  divClk : sl;
52  preRise : sl;
53  preFall : sl;
54  counter : slv(COUNT_WIDTH_G-1 downto 0);
55  end record RegType;
56 
57  constant REG_INIT_C : RegType := (
58  state => DELAY_S,
59  divClk => not LEADING_EDGE_G,
60  preRise => '0',
61  preFall => '0',
62  counter => (others => '0'));
63 
64  signal r : RegType := REG_INIT_C;
65  signal rin : RegType;
66 
67 begin
68 
69  comb : process (delayCount, highCount, lowCount, r, rst) is
70  variable v : RegType;
71  begin
72  v := r;
73 
74  v.counter := r.counter + 1;
75  v.preRise := '0';
76  v.preFall := '0';
77 
78  case (r.state) is
79  when DELAY_S =>
80  if (r.counter = delayCount -1) then
81  if (LEADING_EDGE_G = '1') then
82  v.preRise := '1';
83  else
84  v.preFall := '1';
85  end if;
86  end if;
87  if (r.counter = delayCount) then
89  v.state := CLOCK_S;
90  v.counter := (others => '0');
91  end if;
92 
93  when CLOCK_S =>
94  if (r.divClk = '1' and r.counter = highCount-1) then
95  v.preFall := '1';
96  end if;
97 
98  if (r.divClk = '0' and r.counter = lowCount-1) then
99  v.preRise := '1';
100  end if;
101 
102  if ((r.divClk = '1' and (r.counter = highCount)) or (r.divClk = '0' and (r.counter = lowCount))) then
103  v.divClk := not r.divClk;
104  v.counter := (others => '0');
105  end if;
106  end case;
107 
108  if (rst = '1') then
109  v := REG_INIT_C;
110  end if;
111 
112  rin <= v;
113 
114  divClk <= r.divClk;
115  preRise <= r.preRise;
116  preFall <= r.preFall;
117  end process comb;
118 
119  seq : process (clk) is
120  begin
121  if (rising_edge(clk)) then
122  r <= rin after TPD_G;
123  end if;
124  end process seq;
125 
126 
127 end architecture rtl;
in highCountslv( COUNT_WIDTH_G- 1 downto 0)
in delayCountslv( COUNT_WIDTH_G- 1 downto 0)
TPD_Gtime := 1 ns
std_logic sl
Definition: StdRtlPkg.vhd:28
out preFallsl
LEADING_EDGE_Gsl := '1'
_library_ ieeeieee
Definition: ArbiterPkg.vhd:18
COUNT_WIDTH_Ginteger range 1 to 32:= 16
out preRisesl
in lowCountslv( COUNT_WIDTH_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29