diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index c6f2cbb..9261c85 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -75,7 +75,6 @@ begin begin -- Outputs ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); - int_in.payload <= st.ext_in_reg.data; --- State Transition Diagram --- @@ -136,7 +135,6 @@ begin end if; when TX_BODY => -- Here we want to stay in TX_BODY for the duration of a packet. - -- Right now, we transfer one single word at a time for simplicity if st.write_stage = 0 then next_state <= TX_ACK; else @@ -152,7 +150,7 @@ begin when RX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to awaiting response directly afterwards. - if st.cmd_reg = WRITE_ADD then + if st.cmd_reg = READ_ADD then next_state <= ADDR1; else next_state <= RX_RESPONSE; @@ -160,15 +158,21 @@ begin when RX_RESPONSE => -- Wait for read response. if curr_response = READ_RESPONSE then - next_state <= RX_BODY; + next_state <= RX_BODY_NO_OUT; else next_state <= RX_RESPONSE; end if; + when RX_BODY_NO_OUT => + next_state <= RX_BODY; when RX_BODY => -- Here we want to stay in RX_BODY for the duration of a packet. - -- Right now, we receive only one single word at a time for simplicity - next_state <= IDLE; + if st.read_stage = 0 then + next_state <= IDLE; + else + next_state <= RX_BODY; + end if; when ADDR1 => + -- Transmits the entire address and returns to the appropriate next_state <= ADDR2; when ADDR2 => next_state <= ADDR3; @@ -178,7 +182,7 @@ begin if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then next_state <= TX_BODY; else - next_state <= RX_BODY; + next_state <= RX_RESPONSE; end if; end case; @@ -186,6 +190,7 @@ begin ext_out_data_cmd := (others => '0'); int_in.is_full_out <= '1'; int_in.write_enable_in <= '0'; + int_in.payload <= (others => '0'); case st.curr_state is when IDLE => if cmd = WRITE or cmd = WRITE_ADD then @@ -207,12 +212,16 @@ begin else ext_out_data_cmd := (others => '0'); end if; - when TX_ACK => when RX_HEADER => - ext_out_data_cmd := get_cmd_bits(st.cmd_reg) & get_size_bits(cmd_size); + if st.cmd_reg = READ_ADD then + ext_out_data_cmd := st.addr_reg(7 downto 0); + end if; when RX_RESPONSE => + when RX_BODY_NO_OUT => when RX_BODY => + int_in.payload <= st.ext_in_reg.data; + int_in.write_enable_in <= '1'; when ADDR1 => ext_out_data_cmd := st.addr_reg(15 downto 8); when ADDR2 => @@ -220,8 +229,10 @@ begin when ADDR3 => ext_out_data_cmd := st.addr_reg(31 downto 24); when ADDR4 => - int_in.is_full_out <= '0'; - ext_out_data_cmd := int_out.payload; + if st.cmd_reg = WRITE_ADD then + int_in.is_full_out <= '0'; + ext_out_data_cmd := int_out.payload; + end if; end case; next_parity_out <= calc_parity(ext_out_data_cmd); --- DEBUG GLOBAL BINDINGS --- @@ -259,21 +270,13 @@ begin st.cmd_reg <= cmd; end if; when TX_HEADER => - if st.cmd_reg = WRITE_ADD then - st.write_stage <= 2**(cmd_size - 1) - 1; - else - st.write_stage <= 2**(cmd_size - 1) - 1; - end if; + st.write_stage <= 2**(cmd_size - 1) - 1; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; when RX_HEADER => - if st.cmd_reg = READ_ADD then - st.read_stage <= 2**(cmd_size - 1); - else - st.read_stage <= 2**(cmd_size - 1) - 1; - end if; + st.read_stage <= 2**(cmd_size - 1) - 1; when RX_BODY => if st.read_stage > 0 then st.read_stage <= st.read_stage - 1; diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index e99093b..ae74ab4 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -145,24 +145,8 @@ begin expected_out <= "00000000"; check_next_state(TX_ACK); wait for CLK_PERIOD; - expected_out <= "00000000"; check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; + wait for CLK_PERIOD * 6; expected_out <= "00000000"; check_next_state(IDLE); wait for CLK_PERIOD /4; @@ -187,8 +171,61 @@ begin check_next_state(TX_BODY); wait for CLK_PERIOD; expected_out <= "00001000"; + check_next_state(TX_ACK); wait for CLK_PERIOD; expected_out <= "00000000"; + check_next_state(TX_ACK); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(IDLE); + wait for CLK_PERIOD * 2; + wait for CLK_PERIOD /4; + check_next_state(RX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_cmd_bits(READ) & get_size_bits(2); + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + wait for CLK_PERIOD / 4; + check_next_state(RX_BODY_NO_OUT); + wait for CLK_PERIOD * 3 /4; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(IDLE); + wait for CLK_PERIOD * 5; + wait for CLK_PERIOD /4; + check_next_state(RX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_cmd_bits(READ_ADD) & get_size_bits(2); + check_next_state(ADDR1); + wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(ADDR2); + wait for CLK_PERIOD; + expected_out <= x"A0"; + check_next_state(ADDR3); + wait for CLK_PERIOD; + expected_out <= x"0F"; + check_next_state(ADDR4); + wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + wait for CLK_PERIOD / 4; + check_next_state(RX_BODY_NO_OUT); + wait for CLK_PERIOD * 3 /4; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(IDLE); wait; end process verify_signals; @@ -207,6 +244,16 @@ begin wait for CLK_PERIOD; cmd <= NO_OP; address <= (others => '0'); + wait for CLK_PERIOD * 10; + cmd <= READ; + wait for CLK_PERIOD; + cmd <= NO_OP; + wait for CLK_PERIOD * 10; + cmd <= READ_ADD; + address <= x"FA0FA0FA"; + wait for CLK_PERIOD; + cmd <= NO_OP; + address <= (others => '0'); wait; end process command_stimulus; @@ -230,8 +277,27 @@ begin curr_word <= "00001001"; wait for CLK_PERIOD; curr_word <= "00000000"; - wait for CLK_PERIOD * 10; + wait for CLK_PERIOD * 14; curr_word <= "00101001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*5; + curr_word <= "01000001"; + wait for CLK_PERIOD; + curr_word <= "10000000"; + wait for CLK_PERIOD; + curr_word <= "01000000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*12; + curr_word <= "01100001"; + wait for CLK_PERIOD; + curr_word <= "00100000"; + wait for CLK_PERIOD; + curr_word <= "00010000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait; end process external_stimulus; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index 19b7b7a..11acdf6 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -16,9 +16,9 @@ package socbridge_driver_tb_pkg is (NO_OP, WRITE_ACK, READ_RESPONSE); type state_t is - (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, + (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_HEADER, TX_BODY, TX_ACK, - RX_HEADER, RX_RESPONSE, RX_BODY); + RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); type ext_protocol_t is record data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);