mmv5_FirmwareMS/odio_repeater.vhd

106 lines
2.3 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
------------------------------------------------------------
entity odio_repeater is
generic (
WAIT_CYCLES : integer := 3
);
port (
clk : in std_logic;
rstn : in std_logic;
signal_n1 : inout std_logic;
signal_n2 : inout std_logic
);
end entity odio_repeater;
------------------------------------------------------------
architecture arch of odio_repeater is
component debounce is
generic (
WAIT_CYCLES : integer := 5
);
port (
signal_in : in std_logic;
signal_out : out std_logic;
clk : in std_logic
);
end component;
type state_t is (idle, n1_to_n2, n2_to_n1);
signal state : state_t := idle;
signal s_n1_i_raw, s_n1_i, s_n1_o, s_n1_prev : std_logic;
signal s_n2_i_raw, s_n2_i, s_n2_o, s_n2_prev : std_logic;
begin
-- Tri-state IO handling
s_n1_i_raw <= signal_n1;
s_n2_i_raw <= signal_n2;
signal_n1 <= '0' when s_n1_o = '0' else 'Z';
signal_n2 <= '0' when s_n2_o = '0' else 'Z';
-- Debounce input lines
n1_debounce : debounce
generic map (
WAIT_CYCLES => WAIT_CYCLES
)
port map (
clk => clk,
signal_in => s_n1_i_raw,
signal_out => s_n1_i
);
n2_debounce : debounce
generic map (
WAIT_CYCLES => WAIT_CYCLES
)
port map (
clk => clk,
signal_in => s_n2_i_raw,
signal_out => s_n2_i
);
-- Main open-drain IO repeater process
rptr_proc: process(clk, rstn, s_n1_i, s_n2_i) is
begin
if rstn = '0' then
s_n1_o <= '1';
s_n2_o <= '1';
s_n1_prev <= s_n1_i;
s_n2_prev <= s_n2_i;
state <= idle;
elsif (rising_edge(clk)) then
s_n1_prev <= s_n1_i;
s_n2_prev <= s_n2_i;
case state is
when idle =>
if (s_n1_prev = '1' and s_n1_i = '0') then
s_n2_o <= '0';
state <= n1_to_n2;
elsif (s_n2_prev = '1' and s_n2_i = '0') then
s_n1_o <= '0';
state <= n2_to_n1;
end if;
when n1_to_n2 =>
if (s_n1_prev = '0' and s_n1_i = '1') then
s_n2_o <= '1';
state <= idle;
end if;
when n2_to_n1 =>
if (s_n2_prev = '0' and s_n2_i = '1') then
s_n1_o <= '1';
state <= idle;
end if;
end case;
end if;
end process;
end architecture arch;