]> rtime.felk.cvut.cz Git - fpga/uart.git/blob - baud_gen.vhd
Resets changed from asynchronous to synchronous.
[fpga/uart.git] / baud_gen.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 --------------------------------------------------------------------------------
7 -- Baud generator is an adjustable clock frequency divider. Division factor
8 -- is determined by the value present on the input vector named 'scale' and is
9 -- equal to:
10 --              f_OUT = f_IN / (2 * (1 + 'scale'))
11 --
12 -- The divided clock signal has a duty cycle of 50%.
13 --
14 -- Change of 'scale' doesn't affect current half-period.
15 --
16 -- The reset input signal is asynchronous. All others are synchronous to clk
17 -- rising egde. In default state (when stopped), output is low. When CE goes
18 -- high, 'clk_baud' goes high with next clock rising edge. When CE goes low,
19 -- eventual high half-period is finished and then generator stops with low
20 -- output.
21 --
22 --             _   _   _   _   _   _   _   _   _   _   _   _
23 --  CLK      _| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
24 --                            _____
25 --  RESET    ________________|     |__________________________
26 --                _____________________________
27 --  CE       ____|                             |______________
28 --                 ___     __          ___     ___    
29 --  CLK_BAUD _____|   |___|  |________|   |___|   |___________
30 --
31 --------------------------------------------------------------------------------
32
33 entity baud_gen is
34   generic (
35     SCALE_WIDTH : integer := 16
36   );
37   port (
38     clk      : in  std_logic;
39     ce       : in  std_logic;
40     reset    : in  std_logic;
41     scale    : in  std_logic_vector (SCALE_WIDTH-1 downto 0);
42     clk_baud : out std_logic
43   );
44 end baud_gen;
45
46 --------------------------------------------------------------------------------
47
48 architecture behavioral of baud_gen is
49
50   signal counter    : std_logic_vector (SCALE_WIDTH-1 downto 0) := (others => '0');
51   signal clk_baud_s : std_logic := '0';
52
53 --------------------------------------------------------------------------------
54
55 begin
56
57   process (clk, reset)
58   begin
59     if (rising_edge(clk)) then
60       if (reset = '1') then
61         counter <= (others => '0');
62         clk_baud_s <= '0';
63
64       else
65         if (clk_baud_s = '0' and ce = '0') then
66           counter <= (others => '0');
67
68         else
69           if (counter = 0) then
70             counter    <= scale;
71             clk_baud_s <= not clk_baud_s;
72
73           else
74             counter <= counter - 1;
75
76           end if;
77         end if;
78       end if;
79     end if;
80   end process;
81
82 --------------------------------------------------------------------------------
83   
84   clk_baud <= clk_baud_s;
85   
86 end behavioral;
87