From 57bc4031f549c4c98b9f726cf3ca7681299aa521 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 7 Jan 2024 12:50:36 +0100 Subject: [PATCH] feat: store address, rw in address generator or detector --- src/i2c/address_detector.vhd | 33 +++++++++++++++++++++------------ src/i2c/address_generator.vhd | 12 ++++++++++-- src/i2c/master.vhd | 3 +++ src/i2c/master_state.vhd | 2 ++ src/i2c/slave.vhd | 5 ++++- src/i2c/slave_state.vhd | 16 ++++++++++++---- tb/i2c/address_detector_tb.vhd | 3 ++- tb/i2c/address_generator_tb.vhd | 1 + 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/i2c/address_detector.vhd b/src/i2c/address_detector.vhd index 16855aaf3fc147b678a8211296ba0e1fb7206d3d..047bce63f310c5682d0fce1a6ee30396f9714d78 100644 --- a/src/i2c/address_detector.vhd +++ b/src/i2c/address_detector.vhd @@ -4,18 +4,19 @@ use ieee.std_logic_1164.all; entity address_detector is port ( - clk_i : in std_logic; -- Input clock - rst_in : in std_logic; -- Reset the detection - address_i : in std_logic_vector(6 downto 0); - scl_rising : in std_logic; + clk_i : in std_logic; -- Input clock + rst_in : in std_logic; -- Reset the detection + address_i : in std_logic_vector(6 downto 0); + store_address_i : in std_logic; + scl_rising : in std_logic; scl_falling_delayed_i : in std_logic; - sda_enable_o : out std_logic; - sda_i : in std_logic; -- The data that could contain the address - start_i : in std_logic; -- When to start looking for the - -- address. Will clear success_o - rw_o : out std_logic; - success_o : out std_logic; -- Whether full address matches - fail_o : out std_logic); -- Whether matching failed. Will stay 0 + sda_enable_o : out std_logic; + sda_i : in std_logic; -- The data that could contain the address + start_i : in std_logic; -- When to start looking for the + -- address. Will clear success_o + rw_o : out std_logic; + success_o : out std_logic; -- Whether full address matches + fail_o : out std_logic); -- Whether matching failed. Will stay 0 -- as long as bits are matching. Will -- be set to 1 the first bit that does -- not match the address @@ -30,6 +31,9 @@ architecture a1 of address_detector is signal curr_index : integer range 0 to 7; signal next_index : integer range 0 to 7; + signal curr_address : std_logic_vector(6 downto 0); + signal next_address : std_logic_vector(6 downto 0); + signal curr_read_rw : std_logic; signal next_read_rw : std_logic; @@ -40,6 +44,9 @@ begin -- architecture a1 success_o <= '1' when curr_state = MATCH else '0'; rw_o <= curr_read_rw when curr_state = MATCH else '0'; + next_address <= address_i when store_address_i = '1' else + curr_address; + next_read_rw <= sda_i when scl_rising = '1' and curr_index = 7 else curr_read_rw; @@ -47,7 +54,7 @@ begin -- architecture a1 curr_index when curr_state = CHECKING else 0; - mismatch <= '1' when curr_index <= 6 and address_i(6 - curr_index) /= sda_i and scl_rising = '1' else '0'; + mismatch <= '1' when curr_index <= 6 and curr_address(6 - curr_index) /= sda_i and scl_rising = '1' else '0'; sda_enable_o <= '1' when curr_state = ACK_ON else '0'; @@ -89,10 +96,12 @@ begin -- architecture a1 curr_state <= IDLE; curr_index <= 0; curr_read_rw <= '0'; + curr_address <= (others => '0'); else curr_state <= next_state; curr_index <= next_index; curr_read_rw <= next_read_rw; + curr_address <= next_address; end if; end if; end process set_regs; diff --git a/src/i2c/address_generator.vhd b/src/i2c/address_generator.vhd index efc60192bd149b338d9efe3ed859a607d557fc18..acda47320372feb0593deaff16af78f7660a2ec8 100644 --- a/src/i2c/address_generator.vhd +++ b/src/i2c/address_generator.vhd @@ -8,6 +8,7 @@ entity address_generator is rst_in : in std_logic; -- Synchronous reset (active low) address_i : in std_logic_vector(6 downto 0); rw_i : in std_logic; -- Read (not write) + store_address_rw_i : in std_logic; start_i : in std_logic; -- When to start sending the address. -- A pulse. Every time it's '1', -- address will be sent from beginning @@ -26,6 +27,9 @@ architecture a1 of address_generator is signal curr_state : state_t; signal next_state : state_t; + signal curr_data : std_logic_vector(7 downto 0); + signal next_data : std_logic_vector(7 downto 0); + signal curr_index : integer range 0 to 8; signal next_index : integer range 0 to 8; @@ -36,10 +40,12 @@ architecture a1 of address_generator is signal next_done : std_logic; begin -- architecture a1 - sda_enable_o <= not address_i(6 - curr_index) when curr_index <= 6 and curr_state = GEN else - not rw_i when curr_index = 7 and curr_state = GEN else + sda_enable_o <= not curr_data(7 - curr_index) when curr_index <= 7 and curr_state = GEN else '0'; + next_data <= address_i & rw_i when store_address_rw_i = '1' else + curr_data; + next_index <= 0 when start_i = '1' else curr_index + 1 when curr_index < 8 and scl_falling_delayed_i = '1' and curr_state = GEN else curr_index; @@ -96,11 +102,13 @@ begin -- architecture a1 curr_index <= 0; curr_scl <= '1'; curr_done <= '0'; + curr_data <= (others => '0'); else curr_state <= next_state; curr_index <= next_index; curr_scl <= next_scl; curr_done <= next_done; + curr_data <= next_data; end if; end if; end process set_regs; diff --git a/src/i2c/master.vhd b/src/i2c/master.vhd index 81ae9cfdc7da45bde0abc1ee7e3bcdd99ef806b4..009d075efe9cfb66ac408450833eeea09b3f4d8b 100644 --- a/src/i2c/master.vhd +++ b/src/i2c/master.vhd @@ -71,6 +71,7 @@ architecture a1 of master is signal adr_noack : std_logic; signal adr_unexpected_sda : std_logic; signal adr_done : std_logic; + signal adr_gen_store : std_logic; signal adr_gen_start : std_logic; signal cond_gen : std_logic; @@ -223,6 +224,7 @@ begin -- architecture a1 clk_i => clk_i, rst_in => rst_in, address_i => slave_address_i, + store_address_rw_i => adr_gen_store, scl_rising_i => scl_rising, scl_falling_delayed_i => scl_falling_delayed, sda_enable_o => adr_sda_enable, @@ -265,6 +267,7 @@ begin -- architecture a1 -- address_gen_start_o => adr_gen_start, address_gen_done_i => adr_done, + address_gen_store_o => adr_gen_store, -- req_start_o => cond_gen_start, req_stop_o => cond_gen_stop, diff --git a/src/i2c/master_state.vhd b/src/i2c/master_state.vhd index df0f626ba11c784163e3a0ef7ec250170a78da1f..490be8bad3166837b76a49db5f955cb42737c0c1 100644 --- a/src/i2c/master_state.vhd +++ b/src/i2c/master_state.vhd @@ -35,6 +35,7 @@ entity master_state is -- data for address_generator address_gen_start_o : out std_logic; address_gen_done_i : in std_logic; + address_gen_store_o : out std_logic; -- data for cond generator req_start_o : out std_logic; req_stop_o : out std_logic; @@ -106,6 +107,7 @@ begin -- architecture a1 dev_busy_o <= '1' when curr_state /= IDLE and curr_state /= BUS_BUSY and curr_state /= ERR else '0'; address_gen_start_o <= '1' when curr_state = GENERATED_START and next_state = GENERATING_ADDRESS else '0'; + address_gen_store_o <= start_i; receive_o <= '1' when curr_state = RECEIVING else '0'; transmit_o <= '1' when curr_state = TRANSMITTING else '0'; diff --git a/src/i2c/slave.vhd b/src/i2c/slave.vhd index eabf161c594576e9cc81a3b8200f262d87bc2857..c7d5896e4df562ce799565805b10deb57be83b27 100644 --- a/src/i2c/slave.vhd +++ b/src/i2c/slave.vhd @@ -69,6 +69,7 @@ architecture a1 of slave is signal address_detect_activate : std_logic; signal address_detect_success : std_logic; signal address_detect_fail : std_logic; + signal address_detect_store : std_logic; signal address_detection : std_logic; signal rw : std_logic; @@ -168,7 +169,8 @@ begin -- architecture a1 clk_i => clk_i, rst_in => rst_in, address_i => address_i, - scl_rising => scl_rising, + store_address_i => address_detect_store, + scl_rising => scl_rising, scl_falling_delayed_i => scl_falling_delayed, sda_enable_o => address_detect_sda_enable, sda_i => sync_sda, @@ -193,6 +195,7 @@ begin -- architecture a1 address_detect_success_i => address_detect_success, address_detect_fail_i => address_detect_fail, address_detect_start_o => address_detect_activate, + address_detect_store_o => address_detect_store, address_detect_o => address_detection, receive_o => receiving, transmit_o => transmitting, diff --git a/src/i2c/slave_state.vhd b/src/i2c/slave_state.vhd index 5cc5f81a1ee4f0041ef026b51331dcd7a410bd95..a90bee1f63b90a5b3ec3fb26aa40f998329346e2 100644 --- a/src/i2c/slave_state.vhd +++ b/src/i2c/slave_state.vhd @@ -20,6 +20,7 @@ entity i2c_slave_state is address_detect_success_i : in std_logic; address_detect_fail_i : in std_logic; address_detect_start_o : out std_logic; + address_detect_store_o : out std_logic; address_detect_o : out std_logic; receive_o : out std_logic; @@ -48,17 +49,24 @@ architecture a1 of i2c_slave_state is signal communicating_with_master : std_logic; begin -- architecture a1 - communicating_with_master <= '1' when curr_state = BUS_ADDRESS or curr_state = RECEIVING or curr_state = TRANSMITTING else '0'; - address_detect_start_o <= '1' when start_condition_i = '1' else '0'; - address_detect_o <= '1' when curr_state = BUS_ADDRESS else '0'; + rst_i2c_o <= curr_err_noack or curr_err_sda or start_condition_i or stop_condition_i; + + address_detect_start_o <= start_condition_i; + address_detect_store_o <= start_condition_i; + address_detect_o <= '1' when curr_state = BUS_ADDRESS else '0'; + err_noack_o <= curr_err_noack; err_sda_o <= curr_err_sda; - rst_i2c_o <= curr_err_noack or curr_err_sda or start_condition_i or stop_condition_i; receive_o <= '1' when curr_state = RECEIVING else '0'; transmit_o <= '1' when curr_state = TRANSMITTING else '0'; bus_busy_o <= '1' when curr_state = BUS_BUSY else '0'; + communicating_with_master <= '1' when curr_state = BUS_ADDRESS or + curr_state = RECEIVING or + curr_state = TRANSMITTING else + '0'; + next_err_sda <= '0' when start_condition_i = '1' or stop_condition_i = '1' else '1' when curr_err_sda = '1' else '1' when unexpected_sda_i = '1' and curr_state = TRANSMITTING else diff --git a/tb/i2c/address_detector_tb.vhd b/tb/i2c/address_detector_tb.vhd index f289172f9e5af69c7c8d71af93ac92865993d0f5..0964df1def2a8c3fe85e5150dcac2b3fd320742e 100644 --- a/tb/i2c/address_detector_tb.vhd +++ b/tb/i2c/address_detector_tb.vhd @@ -44,8 +44,9 @@ begin -- architecture tb port map ( clk_i => clk, rst_in => rst_n, + store_address_i => '1', address_i => address, - scl_rising => scl_rising, + scl_rising => scl_rising, scl_falling_delayed_i => scl_falling, sda_i => sda, sda_enable_o => sda_enable, diff --git a/tb/i2c/address_generator_tb.vhd b/tb/i2c/address_generator_tb.vhd index e1e7b9cdb60a8e05347e15108e344875f15b9117..2c561b4cae7351bd0e8ff6ceb19fae269a041689 100644 --- a/tb/i2c/address_generator_tb.vhd +++ b/tb/i2c/address_generator_tb.vhd @@ -55,6 +55,7 @@ begin -- architecture tb clk_i => clk, rst_in => rst_n, start_i => start, + store_address_rw_i => '1', address_i => address, rw_i => rw, sda_i => slave_sda,