library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;
library unisim;
use unisim.vcomponents.all;
entity uart_brg is
port (
i_clock : in std_logic;
i_prescale : in unsigned (3 downto 0);
i_divisor : in unsigned (7 downto 0);
i_fraction : in unsigned (3 downto 0);
o_baud_tick : out std_logic;
o_baud_16x_tick : out std_logic
);
end uart_brg;
architecture a of uart_brg is
signal uart_brg_cntr : unsigned(7 downto 0) := ( others => '0' );
signal uart_brg_acc : unsigned(4 downto 0) := ( others => '0' );
signal value_cmp : unsigned (7 downto 0);
signal prescale : std_logic;
signal prescale_r : std_logic := '1';
signal value_adj : std_logic := '0';
signal baud_tick : std_logic;
signal baud_16x_tick : std_logic;
attribute INIT : string;
attribute INIT of prescale_srl16e : label is "0000";
attribute INIT of baud_tick_srl16e : label is "0001";
begin
o_baud_16x_tick <= baud_16x_tick; and prescale_r;
o_baud_tick <= baud_tick and prescale_r;
prescale_r <= prescale when rising_edge( i_clock );
prescale_srl16e : SRL16E
--synthesis translate_off
generic map (INIT => X"0000")
--synthesis translate_on
port map(
D => prescale_r,
CE => '1',
CLK => i_clock,
A0 => i_prescale(0),
A1 => i_prescale(1),
A2 => i_prescale(2),
A3 => i_prescale(3),
Q => prescale );
baud_tick_srl16e : SRL16E
--synthesis translate_off
generic map (INIT => X"0001")
--synthesis translate_on
port map(
D => baud_tick,
CE => baud_16x_tick,
CLK => i_clock,
A0 => '1',
A1 => '1',
A2 => '1',
A3 => '1',
Q => baud_tick );
value_adj <= uart_brg_acc(4);
value_cmp <= i_divisor - ("0000000" & value_adj) ;
process(i_clock)
begin
if (rising_edge(i_clock)) then
if ( prescale_r = '1' ) then
if ( baud_16x_tick = '1' ) then
uart_brg_acc <= '0' & uart_brg_acc(3 downto 0) + i_fraction;
end if;
end if;
end if;
end process;
process(i_clock)
begin
if (rising_edge(i_clock)) then
if ( prescale_r = '1' ) then
if ( uart_brg_cntr < value_cmp ) then
baud_16x_tick <= '0';
uart_brg_cntr <= uart_brg_cntr + 1;
else
baud_16x_tick <= '1';
uart_brg_cntr <= ( others => '0' );
end if;
end if;
end if;
end process;
end a;
library ieee;
use ieee.std_logic_1164.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.numeric_std.all;
entity uart_brg_tb is
end uart_brg_tb;
architecture behavior of uart_brg_tb is
-- Component Declaration for the Unit Under Test (UUT)
component uart_brg
port(
i_clock : in std_logic;
i_prescale : in unsigned(3 downto 0);
i_divisor : in unsigned(7 downto 0);
i_fraction : in unsigned(3 downto 0);
o_baud_tick : out std_logic;
o_baud_16x_tick : out std_logic
);
end component;
--Inputs
signal i_clock : std_logic := '0';
signal i_prescale : unsigned(3 downto 0) := "0010";
signal i_divisor : unsigned(7 downto 0) := "10000000";
signal i_fraction : unsigned(3 downto 0) := "0010";
--Outputs
signal o_baud_tick : std_logic;
signal o_baud_16x_tick : std_logic;
-- Clock period definitions
constant i_clock_period : time := 10 ns;
signal tx_delta : time := 0 ns;
signal rx_delta : time := 0 ns;
signal tx_cntr : unsigned ( 3 downto 0) := ( others => '0' );
begin
-- Instantiate the Unit Under Test (UUT)
uut : uart_brg port map (
i_clock => i_clock,
i_prescale => i_prescale,
i_divisor => i_divisor,
i_fraction => i_fraction,
o_baud_tick => o_baud_tick,
o_baud_16x_tick => o_baud_16x_tick
);
-- Clock process definitions
i_clock_process : process
begin
i_clock <= '0';
wait for i_clock_period/2;
i_clock <= '1';
wait for i_clock_period/2;
end process;
process
begin
wait until rising_edge( o_baud_tick );
tx_cntr <= tx_cntr + 1;
if tx_cntr = "1001" then
tx_cntr <= "0000";
report time'image( now - tx_delta ) & " TX ";
tx_delta <= now;
end if;
end process;
process
begin
wait until rising_edge( o_baud_16x_tick );
report time'image( now - rx_delta ) & " RX ";
rx_delta <= now;
end process;
-- Stimulus process
stim_proc : process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
wait for i_clock_period*10;
-- insert stimulus here
wait;
end process;
end;