From e29d030c7ccc11c4c880908901d7a6c63a11ce34 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Thu, 28 Dec 2023 15:38:09 +0100 Subject: [PATCH] feat: add utility entities Delay, metastability filter, open drain buffer, synchronous edge detector --- src/utils/delay.vhd | 36 ++++++++++++++++++++ src/utils/metastability_filter.vhd | 26 ++++++++++++++ src/utils/open_drain_buffer.vhd | 25 ++++++++++++++ src/utils/pulse_delay.vhd | 0 src/utils/sync_edge_detector.vhd | 54 ++++++++++++++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 src/utils/delay.vhd create mode 100644 src/utils/metastability_filter.vhd create mode 100644 src/utils/open_drain_buffer.vhd create mode 100644 src/utils/pulse_delay.vhd create mode 100644 src/utils/sync_edge_detector.vhd diff --git a/src/utils/delay.vhd b/src/utils/delay.vhd new file mode 100644 index 0000000000000000000000000000000000000000..3b8380fcc04602eeb60ce63d9568218c9e5f51d2 --- /dev/null +++ b/src/utils/delay.vhd @@ -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; diff --git a/src/utils/metastability_filter.vhd b/src/utils/metastability_filter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..cb507717668907bf8e1fbaea0ac23fa8139a3480 --- /dev/null +++ b/src/utils/metastability_filter.vhd @@ -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; diff --git a/src/utils/open_drain_buffer.vhd b/src/utils/open_drain_buffer.vhd new file mode 100644 index 0000000000000000000000000000000000000000..dbfa2d62233262f3754be0a64a53fa160d38fcb6 --- /dev/null +++ b/src/utils/open_drain_buffer.vhd @@ -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; diff --git a/src/utils/pulse_delay.vhd b/src/utils/pulse_delay.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/utils/sync_edge_detector.vhd b/src/utils/sync_edge_detector.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0a75f774d1474c9733a864365c05c829404b9e48 --- /dev/null +++ b/src/utils/sync_edge_detector.vhd @@ -0,0 +1,54 @@ +------------------------------------------------------------------------------- +-- Title : Synchronous edge detector +-- Project : +------------------------------------------------------------------------------- +-- File : sync_edge_detector.vhd +-- Author : Frantisek Bohacek +-- 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;