A src/utils/delay.vhd => src/utils/delay.vhd +36 -0
@@ 0,0 1,36 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity delay is
+ generic (
+ DELAY : natural);
+
+ port (
+ clk_i : in std_logic;
+ rst_in : in std_logic;
+ signal_i : in std_logic;
+ signal_o : out std_logic);
+
+end entity delay;
+
+architecture a1 of delay is
+ signal DELAYED_PULSE_POS : natural := DELAY - 1;
+ signal curr_pulses : std_logic_vector(DELAYED_PULSE_POS downto 0);
+ signal next_pulses : std_logic_vector(DELAYED_PULSE_POS downto 0);
+begin -- architecture a1
+
+ signal_o <= curr_pulses(DELAYED_PULSE_POS);
+ next_pulses <= curr_pulses(DELAYED_PULSE_POS - 1 downto 1) & signal_i;
+
+ set_regs: process (clk_i) is
+ begin -- process set_regs
+ if rising_edge(clk_i) then -- rising clock edge
+ if rst_in = '0' then -- synchronous reset (active low)
+ curr_pulses <= (others => '0');
+ else
+ curr_pulses <= next_pulses;
+ end if;
+ end if;
+ end process set_regs;
+
+end architecture a1;
A src/utils/metastability_filter.vhd => src/utils/metastability_filter.vhd +26 -0
@@ 0,0 1,26 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity metastability_filter is
+
+ port (
+ clk_i : in std_logic;
+ signal_i : in std_logic;
+ signal_o : out std_logic);
+
+end entity metastability_filter;
+
+architecture a1 of metastability_filter is
+
+begin -- architecture a1
+
+ entity work.delay
+ generic map (
+ DELAY => 2)
+ port map (
+ clk_i => clk_i,
+ rst_in => '1',
+ signal_i => signal_i,
+ signal_o => signal_o);
+
+end architecture a1;
A src/utils/open_drain_buffer.vhd => src/utils/open_drain_buffer.vhd +25 -0
@@ 0,0 1,25 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity open_drain_buffer is
+
+ port (
+ pad_io : inout std_logic; -- The pad itself, will be set to 'Z'
+ -- when enable_i = '0'
+ enable_i : in std_logic; -- Whether to enable output, ie. set
+ -- pad to '0' for enable_i = '1'
+ state_o : out std_logic); -- The state of the pad, relevant if
+ -- enable_i = '0'
+
+end entity open_drain_buffer;
+
+architecture a1 of open_drain_buffer is
+
+begin -- architecture a1
+
+ pad_io <= '0' when enable_i = '0' else
+ 'Z';
+
+ state_o <= pad_io;
+
+end architecture a1;
A src/utils/pulse_delay.vhd => src/utils/pulse_delay.vhd +0 -0
A src/utils/sync_edge_detector.vhd => src/utils/sync_edge_detector.vhd +54 -0
@@ 0,0 1,54 @@
+-------------------------------------------------------------------------------
+-- Title : Synchronous edge detector
+-- Project :
+-------------------------------------------------------------------------------
+-- File : sync_edge_detector.vhd
+-- Author : Frantisek Bohacek <rutherther@protonmail.com>
+-- Created : 2023-11-26
+-- Last update: 2023-11-26
+-- Platform :
+-- Standard : VHDL'93/02
+-------------------------------------------------------------------------------
+-- Description: Detects edges in signal_i, synchronously to clk_i
+-------------------------------------------------------------------------------
+-- Copyright (c) 2023
+-------------------------------------------------------------------------------
+-- Revisions :
+-- Date Version Author Description
+-- 2023-11-26 1.0 ruther Created
+-------------------------------------------------------------------------------
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity sync_edge_detector is
+
+ port (
+ clk_i : in std_logic;
+ signal_i : in std_logic;
+ rising_edge_o : out std_logic;
+ falling_edge_o : out std_logic);
+
+end entity sync_edge_detector;
+
+architecture a1 of sync_edge_detector is
+ signal reg_prev_signal : std_logic;
+ signal next_prev_signal : std_logic;
+begin -- architecture a1
+ next_prev_signal <= signal_i;
+
+ rising_edge_o <= '1' when reg_prev_signal = '0' and signal_i = '1' else
+ '0';
+
+ falling_edge_o <= '1' when reg_prev_signal = '1' and signal_i = '0' else
+ '0';
+
+ set_next: process (clk_i) is
+ begin -- process set_next
+ if rising_edge(clk_i) then -- rising clock edge
+ reg_prev_signal <= next_prev_signal;
+ end if;
+ end process set_next;
+
+end architecture a1;