--! Baud generator
|
--! Baud generator
|
--! http://www.fpga4fun.com/SerialInterface.html
|
--! http://www.fpga4fun.com/SerialInterface.html
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
--! Use CPU Definitions package
|
--! Use CPU Definitions package
|
use work.pkgDefinitions.all;
|
use work.pkgDefinitions.all;
|
|
|
entity baud_generator is
|
entity baud_generator is
|
Port ( rst : in STD_LOGIC;
|
Port ( rst : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
cycle_wait : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
cycle_wait : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
baud_oversample : out std_logic;
|
baud_oversample : out std_logic;
|
baud : out STD_LOGIC);
|
baud : out STD_LOGIC);
|
end baud_generator;
|
end baud_generator;
|
|
|
architecture Behavioral of baud_generator is
|
architecture Behavioral of baud_generator is
|
signal genTick : std_logic;
|
signal genTick : std_logic;
|
signal genTickOverSample : std_logic;
|
signal genTickOverSample : std_logic;
|
begin
|
begin
|
process (rst, clk, cycle_wait)
|
process (rst, clk, cycle_wait)
|
variable wait_clk_cycles : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable wait_clk_cycles : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable half_cycle : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable half_cycle : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
begin
|
begin
|
if rst = '1' then
|
if rst = '1' then
|
wait_clk_cycles := (others => '0');
|
wait_clk_cycles := (others => '0');
|
half_cycle := '0' & cycle_wait(cycle_wait'high downto 1);
|
half_cycle := '0' & cycle_wait(cycle_wait'high downto 1);
|
genTick <= '0';
|
genTick <= '0';
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
-- Just decremented the cycle_wait by one because genTick would be updated on the next cycle
|
-- Just decremented the cycle_wait by one because genTick would be updated on the next cycle
|
-- and we really want to bring genTick <= '1' when (wait_clk_cycles = cycle_wait)
|
-- and we really want to bring genTick <= '1' when (wait_clk_cycles = cycle_wait)
|
if wait_clk_cycles = (cycle_wait - conv_std_logic_vector(1, nBitsLarge)) then
|
if wait_clk_cycles = (cycle_wait - conv_std_logic_vector(1, nBitsLarge)) then
|
genTick <= '1';
|
genTick <= '1';
|
wait_clk_cycles := (others => '0');
|
wait_clk_cycles := (others => '0');
|
else
|
else
|
wait_clk_cycles := wait_clk_cycles + conv_std_logic_vector(1, nBitsLarge);
|
wait_clk_cycles := wait_clk_cycles + conv_std_logic_vector(1, nBitsLarge);
|
-- If we're at half of the cycle
|
-- If we're at half of the cycle
|
if wait_clk_cycles = half_cycle then
|
if wait_clk_cycles = half_cycle then
|
genTick <= '0';
|
genTick <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- Avoid creation of transparent latch (By default the VHDL will create an register for vectors that are assigned only in one
|
-- Avoid creation of transparent latch (By default the VHDL will create an register for vectors that are assigned only in one
|
-- ocasion of a (if, case) instruction
|
-- ocasion of a (if, case) instruction
|
half_cycle := '0' & cycle_wait(cycle_wait'high downto 1);
|
half_cycle := '0' & cycle_wait(cycle_wait'high downto 1);
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
baud <= genTick;
|
baud <= genTick;
|
baud_oversample <= genTickOverSample;
|
baud_oversample <= genTickOverSample;
|
|
|
-- Process to generate the overclocked (8x) sample
|
-- Process to generate the overclocked (8x) sample
|
process (rst, clk, cycle_wait)
|
process (rst, clk, cycle_wait)
|
variable wait_clk_cycles : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable wait_clk_cycles : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable half_cycle : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable half_cycle : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable cycle_wait_oversample : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
variable cycle_wait_oversample : STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
begin
|
begin
|
if rst = '1' then
|
if rst = '1' then
|
wait_clk_cycles := (others => '0');
|
wait_clk_cycles := (others => '0');
|
|
|
-- Divide cycle_wait by 4
|
-- Divide cycle_wait by 4
|
--cycle_wait_oversample := '0' & cycle_wait(cycle_wait'high downto 1);
|
--cycle_wait_oversample := '0' & cycle_wait(cycle_wait'high downto 1);
|
--cycle_wait_oversample := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1);
|
--cycle_wait_oversample := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1);
|
cycle_wait_oversample := "00" & cycle_wait(cycle_wait'high downto 2); -- Shift right by 2
|
cycle_wait_oversample := "00" & cycle_wait(cycle_wait'high downto 2); -- Shift right by 2
|
|
|
|
|
-- Half of cycle_wait_oversample
|
-- Half of cycle_wait_oversample
|
half_cycle := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1); -- Shift right by 1
|
half_cycle := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1); -- Shift right by 1
|
genTickOverSample <= '0';
|
genTickOverSample <= '0';
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
-- Just decremented the cycle_wait by one because genTick would be updated on the next cycle
|
-- Just decremented the cycle_wait by one because genTick would be updated on the next cycle
|
-- and we really want to bring genTick <= '1' when (wait_clk_cycles = cycle_wait)
|
-- and we really want to bring genTick <= '1' when (wait_clk_cycles = cycle_wait)
|
if wait_clk_cycles = (cycle_wait_oversample - conv_std_logic_vector(1, nBitsLarge)) then
|
if wait_clk_cycles = (cycle_wait_oversample - conv_std_logic_vector(1, nBitsLarge)) then
|
genTickOverSample <= '1';
|
genTickOverSample <= '1';
|
wait_clk_cycles := (others => '0');
|
wait_clk_cycles := (others => '0');
|
else
|
else
|
wait_clk_cycles := wait_clk_cycles + conv_std_logic_vector(1, nBitsLarge);
|
wait_clk_cycles := wait_clk_cycles + conv_std_logic_vector(1, nBitsLarge);
|
-- If we're at half of the cycle
|
-- If we're at half of the cycle
|
if wait_clk_cycles = half_cycle then
|
if wait_clk_cycles = half_cycle then
|
genTickOverSample <= '0';
|
genTickOverSample <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- Avoid creation of transparent latch (By default the VHDL will create an register for vectors that are assigned only in one
|
-- Avoid creation of transparent latch (By default the VHDL will create an register for vectors that are assigned only in one
|
-- ocasion of a (if, case) instruction
|
-- ocasion of a (if, case) instruction
|
cycle_wait_oversample := "00" & cycle_wait(cycle_wait'high downto 2);
|
cycle_wait_oversample := "00" & cycle_wait(cycle_wait'high downto 2);
|
half_cycle := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1);
|
half_cycle := '0' & cycle_wait_oversample(cycle_wait_oversample'high downto 1);
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end Behavioral;
|
end Behavioral;
|
|
|
|
|