library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library utils;
library i2c;
entity counter is
generic (
DELAY : integer := 15;
MAX : integer := 100);
port (
clk_i : in std_logic;
rst_i : in std_logic;
err_noack_data_o : out std_logic;
err_noack_address_o : out std_logic;
err_arbitration_o : out std_logic;
err_general_o : out std_logic;
bus_busy_o : out std_logic;
dev_busy_o : out std_logic;
sda_io : inout std_logic;
scl_io : inout std_logic);
end entity counter;
architecture a1 of counter is
constant ADDRESS : std_logic_vector(6 downto 0) := "1110100";
signal curr_count : unsigned(7 downto 0);
signal next_count : unsigned(7 downto 0);
signal go_next : std_logic;
signal rst_n : std_logic;
signal rst_sync : std_logic;
signal sda, scl : std_logic;
signal sda_enable, scl_enable : std_logic;
signal tx_valid, tx_ready : std_logic;
signal tx_data : std_logic_vector(7 downto 0);
begin
rst_n <= not rst_sync;
sync_reset: entity utils.metastability_filter
port map (
clk_i => clk_i,
signal_i => rst_i,
signal_o => rst_sync);
next_count <= (curr_count + 1) mod MAX when go_next = '1' else
curr_count;
go_next <= tx_ready;
tx_valid <= tx_ready;
tx_data <= std_logic_vector(curr_count);
i2c_slave: entity i2c.slave
generic map (
SCL_FALLING_DELAY => DELAY)
port map (
clk_i => clk_i,
rst_in => rst_n,
address_i => ADDRESS,
generate_ack_i => '1',
expect_ack_i => '1',
rx_valid_o => open,
rx_data_o => open,
rx_confirm_i => '1',
rx_stretch_i => '0',
tx_ready_o => tx_ready,
tx_valid_i => tx_valid,
tx_data_i => tx_data,
tx_stretch_i => '0',
tx_clear_buffer_i => '0',
err_noack_o => err_noack_data_o,
rw_o => open,
dev_busy_o => dev_busy_o,
bus_busy_o => bus_busy_o,
sda_i => sda,
scl_i => scl,
sda_enable_o => sda_enable,
scl_enable_o => scl_enable);
sda_open_buffer: entity utils.open_drain_buffer
port map (
pad_io => sda_io,
enable_i => sda_enable,
state_o => sda);
scl_open_buffer: entity utils.open_drain_buffer
port map (
pad_io => scl_io,
enable_i => scl_enable,
state_o => scl);
set_regs: process (clk_i) is
begin -- process set_regs
if rising_edge(clk_i) then -- rising clock edge
if rst_n = '0' then -- synchronous reset (active low)
curr_count <= "00000000";
else
curr_count <= next_count;
end if;
end if;
end process set_regs;
end architecture a1;