]> rtime.felk.cvut.cz Git - fpga/uart.git/blobdiff - baud_gen.vhd
Resets changed from asynchronous to synchronous.
[fpga/uart.git] / baud_gen.vhd
index 20f80100b09b9cf8b6b4c21cd8f94a3614aeee01..b752d08a612acb81db515af8508790d274beaed1 100644 (file)
@@ -3,12 +3,40 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 
+--------------------------------------------------------------------------------
+-- Baud generator is an adjustable clock frequency divider. Division factor
+-- is determined by the value present on the input vector named 'scale' and is
+-- equal to:
+--              f_OUT = f_IN / (2 * (1 + 'scale'))
+--
+-- The divided clock signal has a duty cycle of 50%.
+--
+-- Change of 'scale' doesn't affect current half-period.
+--
+-- The reset input signal is asynchronous. All others are synchronous to clk
+-- rising egde. In default state (when stopped), output is low. When CE goes
+-- high, 'clk_baud' goes high with next clock rising edge. When CE goes low,
+-- eventual high half-period is finished and then generator stops with low
+-- output.
+--
+--             _   _   _   _   _   _   _   _   _   _   _   _
+--  CLK      _| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
+--                            _____
+--  RESET    ________________|     |__________________________
+--                _____________________________
+--  CE       ____|                             |______________
+--                 ___     __          ___     ___    
+--  CLK_BAUD _____|   |___|  |________|   |___|   |___________
+--
+--------------------------------------------------------------------------------
+
 entity baud_gen is
   generic (
     SCALE_WIDTH : integer := 16
   );
   port (
     clk      : in  std_logic;
+    ce       : in  std_logic;
     reset    : in  std_logic;
     scale    : in  std_logic_vector (SCALE_WIDTH-1 downto 0);
     clk_baud : out std_logic
@@ -19,8 +47,8 @@ end baud_gen;
 
 architecture behavioral of baud_gen is
 
-  signal counter    : std_logic_vector (SCALE_WIDTH-1 downto 0);
-  signal clk_baud_s : std_logic;
+  signal counter    : std_logic_vector (SCALE_WIDTH-1 downto 0) := (others => '0');
+  signal clk_baud_s : std_logic := '0';
 
 --------------------------------------------------------------------------------
 
@@ -28,18 +56,25 @@ begin
 
   process (clk, reset)
   begin
-    if (reset = '1') then
-      counter <= (others => '0');
-      clk_baud_s <= '0';
-      
-    elsif (rising_edge(clk)) then
-      if (counter = 0) then
-        counter <= scale;
-        clk_baud_s <= not clk_baud_s;
-        
+    if (rising_edge(clk)) then
+      if (reset = '1') then
+        counter <= (others => '0');
+        clk_baud_s <= '0';
+
       else
-        counter <= counter - 1;
+        if (clk_baud_s = '0' and ce = '0') then
+          counter <= (others => '0');
+
+        else
+          if (counter = 0) then
+            counter    <= scale;
+            clk_baud_s <= not clk_baud_s;
+
+          else
+            counter <= counter - 1;
 
+          end if;
+        end if;
       end if;
     end if;
   end process;