~ruther/vhdl-i2c

57bc4031f549c4c98b9f726cf3ca7681299aa521 — Rutherther 1 year, 3 months ago 01263b8
feat: store address, rw in address generator or detector
M src/i2c/address_detector.vhd => src/i2c/address_detector.vhd +21 -12
@@ 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;

M src/i2c/address_generator.vhd => src/i2c/address_generator.vhd +10 -2
@@ 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;

M src/i2c/master.vhd => src/i2c/master.vhd +3 -0
@@ 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,

M src/i2c/master_state.vhd => src/i2c/master_state.vhd +2 -0
@@ 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';

M src/i2c/slave.vhd => src/i2c/slave.vhd +4 -1
@@ 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,

M src/i2c/slave_state.vhd => src/i2c/slave_state.vhd +12 -4
@@ 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

M tb/i2c/address_detector_tb.vhd => tb/i2c/address_detector_tb.vhd +2 -1
@@ 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,

M tb/i2c/address_generator_tb.vhd => tb/i2c/address_generator_tb.vhd +1 -0
@@ 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,

Do not follow this link