diff --git a/src/manager/management_unit.vhd b/src/manager/management_unit.vhd index 5880885..33ed118 100644 --- a/src/manager/management_unit.vhd +++ b/src/manager/management_unit.vhd @@ -34,7 +34,7 @@ write_address <= manager_state.memory(1); comb_proc: process(controller_to_manager, socbridge_driver_to_manager,manager_state) variable local_word_address : natural; begin - local_word_address := to_integer(shift_right(unsigned(socbridge_driver_to_manager.address), address_shift)); + local_word_address := to_integer(shift_right(unsigned(socbridge_driver_to_manager.address and address_mask), address_shift)); -- Read data from manager to SoCBridge driver manager_to_socbridge_driver.ready <= '1'; manager_to_socbridge_driver.data <= manager_state.memory(local_word_address); diff --git a/src/manager/management_unit_pkg.vhd b/src/manager/management_unit_pkg.vhd index f61236b..7356ef1 100644 --- a/src/manager/management_unit_pkg.vhd +++ b/src/manager/management_unit_pkg.vhd @@ -1,5 +1,6 @@ library IEEE; use IEEE.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; use IEEE.MATH_REAL.all; library gan_ganimede; use gan_ganimede.io_types.all; @@ -11,6 +12,7 @@ package management_types is subtype manager_word_t is std_logic_vector(WORD_SIZE - 1 downto 0); constant empty_word : std_logic_vector(WORD_SIZE - 1 downto 0) := (others => '0'); constant mem_words : natural := 64; + constant address_mask : std_logic_vector(WORD_SIZE - 1 downto 0) := std_logic_vector(to_unsigned(mem_words - 1, 32)); type memory_t is array (0 to mem_words - 1) of manager_word_t; -- Index in memory array where memory read address is kept. diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index eecbd45..cd709ff 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -231,7 +231,7 @@ begin end if; when TX_R_BODY => if st.tx_stage > 0 then - local_next_data_out := st.curr_read_data(st.tx_stage * 8 - 1 downto (st.tx_stage - 1) * 8); + local_next_data_out := st.curr_read_data((((st.tx_stage - 1) mod 4) + 1) * 8 - 1 downto ((((st.tx_stage - 1) mod 4) + 1) - 1) * 8); end if; when TX_AWAIT => when ADDR1 => @@ -414,18 +414,18 @@ begin when RX_W_BODY => if st.rx_stage > 0 then st.rx_stage <= st.rx_stage - 1; - st.curr_write_data((st.rx_stage) * 8 - 1 downto (st.rx_stage - 1) * 8) <= st.ext_to_socbridge_driver_reg.data; + st.curr_write_data((((st.rx_stage - 1) mod 4) + 1) * 8 - 1 downto ((((st.rx_stage - 1) mod 4) + 1) - 1) * 8) <= st.ext_to_socbridge_driver_reg.data; end if; when RX_AWAIT => st.curr_read_data <= manager_to_socbridge_driver.data; - -- THIS DOESN'T WORK, SHOULD BE FIXED BUT NOT NEEDED IF ONLY 4 BYTE ACCESSES ARRIVE - --if st.curr_tx_transaction = READ_RESPONSE or st.curr_tx_transaction = WRITE_ACK then - -- if st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD then - -- st.curr_rx_read_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_read_addr) + 4), 32)); - -- elsif st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then - -- st.curr_rx_write_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_read_addr) + 4), 32)); - -- end if; - --end if; + -- THIS DOESN'T WORK FOR LARGER THAN 4 BYTE ACCESSES, SHOULD BE FIXED BUT NOT NEEDED IF ONLY 4 BYTE ACCESSES ARRIVE + if st.curr_tx_transaction = READ_RESPONSE or st.curr_tx_transaction = WRITE_ACK then + if (st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD) and (st.tx_stage - 2) mod 4 = 0 then + st.curr_rx_read_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_read_addr) + 4), 32)); + elsif (st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD) and (st.rx_stage - 2) mod 4 = 0 then + st.curr_rx_write_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_write_addr) + 4), 32)); + end if; + end if; when ADDR1 => if st.curr_rx_transaction = READ_ADD then st.curr_rx_read_addr(31 downto 24) <= st.ext_to_socbridge_driver_reg.data;