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
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';
--------------------------------------------------------------------------------
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;