added support for multi word addressable writes
This commit is contained in:
parent
547ff21a53
commit
a5c9190e2d
@ -71,7 +71,7 @@ begin
|
||||
READ_RESPONSE when "01000",
|
||||
READ_RESPONSE when "01100",
|
||||
NO_OP when others;
|
||||
comb_proc: process(ext_in, int_out, curr_response, st)
|
||||
comb_proc: process(ext_in, int_out, curr_response, st, cmd)
|
||||
begin
|
||||
-- Outputs
|
||||
ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg);
|
||||
@ -128,8 +128,12 @@ begin
|
||||
end if;
|
||||
when TX_HEADER =>
|
||||
-- The header only takes one word (cycle) to transmit.
|
||||
-- Continue to body directly afterwards.
|
||||
next_state <= TX_BODY;
|
||||
-- Continue to body or address directly afterwards.
|
||||
if st.cmd_reg = 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.
|
||||
-- Right now, we transfer one single word at a time for simplicity
|
||||
@ -148,7 +152,11 @@ begin
|
||||
when RX_HEADER =>
|
||||
-- The header only takes one word (cycle) to transmit.
|
||||
-- Continue to awaiting response directly afterwards.
|
||||
next_state <= RX_RESPONSE;
|
||||
if st.cmd_reg = WRITE_ADD then
|
||||
next_state <= ADDR1;
|
||||
else
|
||||
next_state <= RX_RESPONSE;
|
||||
end if;
|
||||
when RX_RESPONSE =>
|
||||
-- Wait for read response.
|
||||
if curr_response = READ_RESPONSE then
|
||||
@ -165,6 +173,8 @@ begin
|
||||
when ADDR2 =>
|
||||
next_state <= ADDR3;
|
||||
when ADDR3 =>
|
||||
next_state <= ADDR4;
|
||||
when ADDR4 =>
|
||||
if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then
|
||||
next_state <= TX_BODY;
|
||||
else
|
||||
@ -178,6 +188,11 @@ begin
|
||||
int_in.write_enable_in <= '0';
|
||||
case st.curr_state is
|
||||
when IDLE =>
|
||||
if cmd = WRITE or cmd = WRITE_ADD then
|
||||
ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size);
|
||||
elsif cmd = READ or cmd = READ_ADD then
|
||||
ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size);
|
||||
end if;
|
||||
when TX_HEADER =>
|
||||
if st.cmd_reg = WRITE_ADD then
|
||||
ext_out_data_cmd := st.addr_reg(7 downto 0);
|
||||
@ -186,8 +201,13 @@ begin
|
||||
int_in.is_full_out <= '0';
|
||||
end if;
|
||||
when TX_BODY =>
|
||||
ext_out_data_cmd := int_out.payload;
|
||||
int_in.is_full_out <= '0';
|
||||
if st.write_stage > 0 then
|
||||
int_in.is_full_out <= '0';
|
||||
ext_out_data_cmd := int_out.payload;
|
||||
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);
|
||||
@ -199,6 +219,9 @@ begin
|
||||
ext_out_data_cmd := st.addr_reg(23 downto 16);
|
||||
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;
|
||||
end case;
|
||||
next_parity_out <= calc_parity(ext_out_data_cmd);
|
||||
--- DEBUG GLOBAL BINDINGS ---
|
||||
@ -236,20 +259,20 @@ begin
|
||||
st.cmd_reg <= cmd;
|
||||
end if;
|
||||
when TX_HEADER =>
|
||||
if st.cmd_reg = WRITE then
|
||||
if st.cmd_reg = WRITE_ADD then
|
||||
st.write_stage <= 2**(cmd_size - 1) - 1;
|
||||
else
|
||||
st.write_stage <= 2**(cmd_size - 1) - 1;
|
||||
elsif st.cmd_reg = WRITE_ADD then
|
||||
st.write_stage <= 2**(cmd_size - 1) + 3;
|
||||
end if;
|
||||
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 then
|
||||
if st.cmd_reg = READ_ADD then
|
||||
st.read_stage <= 2**(cmd_size - 1);
|
||||
else
|
||||
st.read_stage <= 2**(cmd_size - 1) - 1;
|
||||
elsif st.cmd_reg = READ_ADD then
|
||||
st.read_stage <= 2**(cmd_size - 1) + 3;
|
||||
end if;
|
||||
when RX_BODY =>
|
||||
if st.read_stage > 0 then
|
||||
|
||||
@ -13,6 +13,7 @@ architecture tb of socbridge_driver_tb is
|
||||
signal clk : std_logic := '0';
|
||||
signal rst : std_logic;
|
||||
signal cmd : command_t;
|
||||
signal address : std_logic_vector(31 downto 0);
|
||||
signal cmd_size : positive;
|
||||
signal ext_in : ext_socbridge_in_t;
|
||||
signal ext_out : ext_socbridge_out_t;
|
||||
@ -62,6 +63,7 @@ architecture tb of socbridge_driver_tb is
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
cmd : in command_t;
|
||||
address : in std_logic_vector(31 downto 0);
|
||||
cmd_size: in positive;
|
||||
ext_in : in ext_socbridge_in_t;
|
||||
ext_out : out ext_socbridge_out_t;
|
||||
@ -76,6 +78,7 @@ begin
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
cmd => cmd,
|
||||
address => address,
|
||||
cmd_size => cmd_size,
|
||||
ext_in => ext_in,
|
||||
ext_out => ext_out,
|
||||
@ -140,7 +143,7 @@ begin
|
||||
check_next_state(TX_ACK);
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
check_next_state(TX_ACK);
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
@ -162,7 +165,30 @@ begin
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD /4;
|
||||
check_next_state(TX_HEADER);
|
||||
wait for CLK_PERIOD * 3 / 4;
|
||||
expected_out <= get_cmd_bits(WRITE_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(TX_BODY);
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00000100";
|
||||
check_next_state(TX_BODY);
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00001000";
|
||||
wait for CLK_PERIOD;
|
||||
expected_out <= "00000000";
|
||||
wait;
|
||||
end process verify_signals;
|
||||
|
||||
@ -175,6 +201,12 @@ begin
|
||||
cmd <= WRITE;
|
||||
wait for CLK_PERIOD;
|
||||
cmd <= NO_OP;
|
||||
wait for CLK_PERIOD * 10;
|
||||
cmd <= WRITE_ADD;
|
||||
address <= x"FA0FA0FA";
|
||||
wait for CLK_PERIOD;
|
||||
cmd <= NO_OP;
|
||||
address <= (others => '0');
|
||||
wait;
|
||||
end process command_stimulus;
|
||||
|
||||
@ -194,8 +226,13 @@ begin
|
||||
wait for 2 * CLK_PERIOD;
|
||||
rst <= '0';
|
||||
wait for CLK_PERIOD / 2;
|
||||
wait for 3* CLK_PERIOD;
|
||||
wait for 4* CLK_PERIOD;
|
||||
curr_word <= "00001001";
|
||||
wait for CLK_PERIOD;
|
||||
curr_word <= "00000000";
|
||||
wait for CLK_PERIOD * 10;
|
||||
curr_word <= "00101001";
|
||||
|
||||
wait;
|
||||
end process external_stimulus;
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ package socbridge_driver_tb_pkg is
|
||||
(NO_OP, WRITE_ACK, READ_RESPONSE);
|
||||
|
||||
type state_t is
|
||||
(IDLE, ADDR1, ADDR2, ADDR3,
|
||||
(IDLE, ADDR1, ADDR2, ADDR3, ADDR4,
|
||||
TX_HEADER, TX_BODY, TX_ACK,
|
||||
RX_HEADER, RX_RESPONSE, RX_BODY);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user