added support for reads with and without addresses

This commit is contained in:
Erik Örtenberg 2025-03-04 17:10:48 +01:00
parent a5c9190e2d
commit c522997e79
3 changed files with 110 additions and 41 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);