diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 009fd33..0b6d178 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -28,7 +28,8 @@ architecture rtl of socbridge_driver is signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal next_cmd : command_t; signal next_cmd_size : integer; - signal next_state : state_t; + signal next_rx_state : rx_state_t; + signal next_tx_state : tx_state_t; signal curr_cmd_bits : std_logic_vector(4 downto 0); signal curr_response : response_t; signal curr_response_bits : std_logic_vector(4 downto 0); @@ -41,7 +42,7 @@ begin -- synthesis translate_off G_next_parity_out <= next_parity_out; G_ext_to_socbridge_driver_rec <= ext_to_socbridge_driver_rec; - G_next_state <= next_state; + G_next_rx_state <= next_rx_state; G_socbridge_driver_to_ext_data_cmd <=test; G_curr_command_bits <= curr_cmd_bits; G_curr_response <= curr_response; @@ -85,113 +86,143 @@ begin socbridge_driver_to_controller.is_active <= '0' when IDLE, '1' when others; - --- State Transition Diagram --- + --- State Transition Diagram OUTDATED!! --- -- -- -- -- +-----+ -- | | --- \|/ /--+ +-- V /--+ -- IDLE<-------------------+ -- / \ | -- / \ | -- / \ | --- \|/ \|/ | +-- V V | -- TX_HEADER RX_HEADER | -- |\ / | | --- | \ / | | +-- | V V | | -- | ADDR1 | | -- | | | | --- | \|/ | | +-- | V | | -- | ADDR2 | | -- | | | | --- | \|/ | | +-- | V | | -- | ADDR3 | | -- | | | | --- | \|/ | | +-- | V | | -- | ADDR4 | | -- | /\ | | -- | / \ | | -- |-+ +----| +---+ | --- \|/ \|/ \|/ | | +-- V V V | | -- TX_BODY RX_RESPONSE---+ | -- | | | -- | +--+ | | --- \|/\|/ | \|/ | +-- V V | V | -- TX_ACK--+ RX_BODY | -- | | | -- | | | -- +-----------+--------------+ -- - --- Next State Assignment --- - case st.curr_state is + --- Next State Assignment Of RX FSM --- + case st.curr_rx_state is when IDLE => - if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then - next_state <= TX_HEADER; - elsif st.curr_cmd = READ or st.curr_cmd = READ_ADD then - next_state <= RX_HEADER; - else - next_state <= IDLE; - end if; - when TX_HEADER => - -- The header only takes one word (cycle) to transmit. - -- Continue to body or address directly afterwards. if st.curr_cmd = WRITE_ADD then - next_state <= ADDR1; - else - next_state <= TX_BODY; - end if; - when TX_BODY => - -- Here we want to stay in TX_BODY for the duration of a packet. - if st.write_stage = 0 then - next_state <= TX_ACK; - else - next_state <= TX_BODY; - end if; - when TX_ACK => - -- Wait for write acknowledgement. - if curr_response = WRITE_ACK then - next_state <= IDLE; - else - next_state <= TX_ACK; + next_rx_state <= ADDR1; + elsif st.curr_cmd = WRITE then + next_rx_state <= PAYLOAD; + elsif st.curr_cmd = READ_ADD then + next_rx_state <= ADDR1; + elsif st.curr_cmd = READ then + next_rx_state <= RX_RESPONSE; + else + next_rx_state <= IDLE; end if; when RX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to awaiting response directly afterwards. if st.curr_cmd = READ_ADD then - next_state <= ADDR1; + next_rx_state <= ADDR1; else - next_state <= RX_RESPONSE; + next_rx_state <= RX_RESPONSE; end if; when RX_RESPONSE => -- Wait for read response. if curr_response = READ_RESPONSE then - next_state <= RX_BODY; + next_rx_state <= RX_BODY; else - next_state <= RX_RESPONSE; + next_rx_state <= RX_RESPONSE; end if; when RX_BODY => -- Here we want to stay in RX_BODY for the duration of a packet. if st.read_stage = 0 then - next_state <= IDLE; + next_rx_state <= IDLE; else - next_state <= RX_BODY; + next_rx_state <= RX_BODY; end if; when ADDR1 => -- Transmits the entire address and returns to the appropriate - next_state <= ADDR2; + next_rx_state <= ADDR2; when ADDR2 => - next_state <= ADDR3; + next_rx_state <= ADDR3; when ADDR3 => - next_state <= ADDR4; + next_rx_state <= ADDR4; when ADDR4 => if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then - next_state <= TX_BODY; + next_rx_state <= PAYLOAD; else - next_state <= RX_RESPONSE; + next_rx_state <= RX_RESPONSE; end if; end case; + --- Next State Assignment Of TX FSM --- + case st.curr_tx_state is + when IDLE => + if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then + next_tx_state <= TX_HEADER; + elsif st.curr_cmd = READ or st.curr_cmd = READ_ADD then + next_tx_state <= RX_HEADER; + else + next_tx_state <= IDLE; + end if; + when TX_HEADER => + -- The header only takes one word (cycle) to transmit. + -- Continue to body or address directly afterwards. + if st.curr_cmd = WRITE_ADD then + next_tx_state <= ADDR1; + else + next_tx_state <= TX_BODY; + end if; + when TX_BODY => + -- Here we want to stay in TX_BODY for the duration of a packet. + if st.write_stage = 0 then + next_tx_state <= TX_ACK; + else + next_tx_state <= TX_BODY; + end if; + when TX_ACK => + -- Wait for write acknowledgement. + if curr_response = WRITE_ACK then + next_tx_state <= IDLE; + else + next_tx_state <= TX_ACK; + end if; + when ADDR1 => + -- Transmits the entire address and returns to the appropriate + next_tx_state <= ADDR2; + when ADDR2 => + next_tx_state <= ADDR3; + when ADDR3 => + next_tx_state <= ADDR4; + when ADDR4 => + if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then + next_tx_state <= TX_BODY; + else + next_tx_state <= RX_RESPONSE; + end if; + end case; + + --- Combinatorial output based on current state --- socbridge_driver_to_ext_data_cmd := (others => '0'); socbridge_driver_to_ip.is_full_out <= '1'; diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index be1b981..4a8e6f8 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -15,11 +15,15 @@ package socbridge_driver_tb_pkg is type response_t is (NO_OP, WRITE_ACK, READ_RESPONSE); - type state_t is - (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, - TX_HEADER, TX_BODY, TX_ACK, + type rx_state_t is + (IDLE, RESP, ADDR1, ADDR2, ADDR3, ADDR4, + CMD, READ, WRITE, PAYLOAD, RX_HEADER, RX_RESPONSE, RX_BODY); + type tx_state_t is + (IDLE, RESP, ADDR1, ADDR2, ADDR3, ADDR4, + CMD, READ, WRITE, PAYLOAD, + TX_HEADER, TX_BODY, TX_ACK); --- TRANSLATOR --- type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); @@ -36,7 +40,8 @@ package socbridge_driver_tb_pkg is end record ext_protocol_t; type state_rec_t is record - curr_state: state_t; + curr_rx_state: rx_state_t; + curr_tx_state: tx_state_t; ext_to_socbridge_driver_reg, socbridge_driver_to_ext_reg : ext_protocol_t; write_stage, read_stage : NATURAL; curr_cmd : command_t; @@ -58,7 +63,8 @@ package socbridge_driver_tb_pkg is signal G_next_parity_out : std_logic; signal G_ext_to_socbridge_driver_rec : ext_protocol_t; signal G_socbridge_driver_to_ext_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - signal G_next_state : state_t; + signal G_next_rx_state : rx_state_t; + signal G_next_tx_state : tx_state_t; signal G_curr_command : command_t; signal G_curr_command_bits : std_logic_vector(4 downto 0); signal G_curr_response : response_t;