WIP: bi-dir socbridge driver (fiddling with tb memory atm)
This commit is contained in:
parent
f2a03fab24
commit
77de1ca975
@ -26,17 +26,24 @@ architecture behave of control_unit is
|
||||
end record state_t;
|
||||
|
||||
signal state: state_t;
|
||||
shared variable ored: std_logic;
|
||||
signal ored_reading: std_logic;
|
||||
signal ored_writing: std_logic;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
comb_proc: process(manager_to_controller, drivers_to_controller, state)
|
||||
variable local_ored_reading : std_logic;
|
||||
variable local_ored_writing : std_logic;
|
||||
begin
|
||||
ored := '0';
|
||||
local_ored_reading := '0';
|
||||
local_ored_writing := '0';
|
||||
ready_reduction: for i in 0 to number_of_drivers - 1 loop
|
||||
ored := ored or drivers_to_controller.socbridge.is_active;
|
||||
local_ored_reading := local_ored_reading or drivers_to_controller.socbridge.is_reading;
|
||||
local_ored_writing := local_ored_writing or drivers_to_controller.socbridge.is_writing;
|
||||
end loop ready_reduction;
|
||||
ored_reading <= local_ored_reading;
|
||||
ored_writing <= local_ored_writing;
|
||||
controller_to_drivers.socbridge.request <= state.curr_driver;
|
||||
controller_to_drivers.socbridge.address <= state.address;
|
||||
controller_to_drivers.socbridge.seq_mem_access_count <= state.seq_mem_access_count;
|
||||
@ -48,20 +55,20 @@ begin
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
state <= ((others => '0'),
|
||||
0,
|
||||
'0',
|
||||
'1',
|
||||
NO_OP);
|
||||
state.address <= (others => '0');
|
||||
state.seq_mem_access_count <= 0;
|
||||
state.curr_driver <= '0';
|
||||
state.ready <= '1';
|
||||
state.instruction <= NO_OP;
|
||||
else
|
||||
-- Make sure to tell the management unit instruction is done
|
||||
if ored = '0' and state.ready = '0' then
|
||||
controller_to_manager.done <= '1';
|
||||
if (ored_writing = '0' and ored_reading = '0') and state.ready = '0' then
|
||||
state.ready <= '1';
|
||||
else
|
||||
controller_to_manager.done <= '0';
|
||||
end if;
|
||||
if ored = '0' then
|
||||
controller_to_manager.done_reading <= ored_reading;
|
||||
controller_to_manager.done_writing <= ored_writing;
|
||||
if ored_reading = '0' or ored_writing = '0' then
|
||||
state.address <= manager_to_controller.address;
|
||||
state.seq_mem_access_count <= manager_to_controller.seq_mem_access_count;
|
||||
state.curr_driver <= manager_to_controller.driver_id(0);
|
||||
@ -73,11 +80,11 @@ begin
|
||||
state.instruction <= NO_OP;
|
||||
end if;
|
||||
else
|
||||
state <= ((others => '0'),
|
||||
0,
|
||||
'0',
|
||||
'1',
|
||||
NO_OP);
|
||||
state.address <= (others => '0');
|
||||
state.seq_mem_access_count <= 0;
|
||||
state.curr_driver <= '0';
|
||||
state.ready <= '1';
|
||||
state.instruction <= NO_OP;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@ -7,7 +7,6 @@ use gan_socbridge.socbridge_driver_pkg.all;
|
||||
library gan_controller;
|
||||
library gan_manager;
|
||||
use gan_manager.management_types.all;
|
||||
library gan_buffer;
|
||||
|
||||
entity ganimede_toplevel is
|
||||
port (
|
||||
|
||||
@ -37,7 +37,7 @@ package io_types is
|
||||
end record manager_to_controller_t;
|
||||
|
||||
type controller_to_manager_t is record
|
||||
ready, done : std_logic;
|
||||
ready, done_reading, done_writing : std_logic;
|
||||
end record controller_to_manager_t;
|
||||
|
||||
--- PROTOCOL INFORMATION ---
|
||||
@ -47,7 +47,8 @@ package io_types is
|
||||
|
||||
--- AUTOGENERATED TYPES ---
|
||||
type socbridge_driver_to_controller_t is record
|
||||
is_active : std_logic;
|
||||
is_reading : std_logic;
|
||||
is_writing : std_logic;
|
||||
end record socbridge_driver_to_controller_t;
|
||||
|
||||
type controller_to_socbridge_driver_t is record
|
||||
|
||||
@ -75,24 +75,20 @@ begin
|
||||
or socbridge_driver_to_manager.address = write_address_index then
|
||||
-- CLEAR BUFFER TO IP CORE
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Is the controller done executing an instruction
|
||||
if controller_to_manager.done = '1' then
|
||||
if cmd = "10" then
|
||||
manager_state.memory(0) <= manager_word_reset_val;
|
||||
elsif cmd = "01" then
|
||||
manager_state.memory(1) <= manager_word_reset_val;
|
||||
end if;
|
||||
elsif controller_to_manager.done_reading = '1' then
|
||||
manager_state.memory(0) <= manager_word_reset_val;
|
||||
elsif controller_to_manager.done_writing = '1' then
|
||||
manager_state.memory(1) <= manager_word_reset_val;
|
||||
end if;
|
||||
-- Is there a read instruction in memory
|
||||
if pack(read_address) /= empty_word and controller_to_manager.ready = '1' then
|
||||
if pack(read_address) /= empty_word and controller_to_manager.ready = '1' and controller_to_manager.done_reading = '0' then
|
||||
manager_to_controller.address <= read_address.address & "0000000000";
|
||||
manager_to_controller.driver_id <= "1"; -- Only supprts one driver at present
|
||||
manager_to_controller.seq_mem_access_count <= 2**to_integer(unsigned(read_address.size)) * 2**10;
|
||||
cmd <= "10";
|
||||
-- Is there a write instruction in memory
|
||||
elsif pack(write_address) /= empty_word and controller_to_manager.ready = '1' then
|
||||
elsif pack(write_address) /= empty_word and controller_to_manager.ready = '1' and controller_to_manager.done_writing = '0'then
|
||||
manager_to_controller.address <= write_address.address & "0000000000";
|
||||
manager_to_controller.driver_id <= "1"; -- Only supports one driver at present
|
||||
manager_to_controller.seq_mem_access_count <= 2**to_integer(unsigned(read_address.size)) * 2**10;
|
||||
|
||||
@ -7,6 +7,8 @@ library gan_socbridge;
|
||||
use gan_socbridge.socbridge_driver_pkg.all;
|
||||
library gan_manager;
|
||||
use gan_manager.management_types.all;
|
||||
library grlib;
|
||||
use grlib.stdlib.all;
|
||||
|
||||
|
||||
entity socbridge_driver is
|
||||
@ -41,8 +43,9 @@ architecture rtl of socbridge_driver is
|
||||
signal st : state_rec_t;
|
||||
signal valid_out : std_logic;
|
||||
--- TRANSLATOR ---
|
||||
signal trans_st : translator_state_rec_t;
|
||||
signal trans_next_state : translator_state_t;
|
||||
signal trans_st : translator_state_t;
|
||||
signal trans_read_next_state : ctrl_inst_state_t;
|
||||
signal trans_write_next_state : ctrl_inst_state_t;
|
||||
--- FSM COMMUNICATION ---
|
||||
signal tx_sent_response, rx_received_response : std_logic;
|
||||
--- MANAGEMENT COMMUNICATION ---
|
||||
@ -59,6 +62,7 @@ begin
|
||||
variable local_next_rx_transaction : transaction_t;
|
||||
variable local_next_tx_transaction : transaction_t;
|
||||
variable local_next_data_out : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
variable curr_tx_addr : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
-- Helpful Bindings --
|
||||
next_rx_data_size <= 2 ** to_integer(unsigned(ext_to_socbridge_driver.payload(2 downto 0)));
|
||||
@ -79,15 +83,26 @@ begin
|
||||
local_next_rx_transaction := WRITE_ACK;
|
||||
elsif curr_response_bits = "01100" or curr_response_bits = "01000" then
|
||||
local_next_rx_transaction := READ_RESPONSE;
|
||||
end if;
|
||||
-- determine address to ouput if address is needed
|
||||
if st.curr_tx_transaction = READ or st.curr_tx_transaction = READ_ADD then
|
||||
curr_tx_addr := trans_st.read.curr_inst.address;
|
||||
elsif st.curr_tx_transaction = WRITE or st.curr_tx_transaction = WRITE_ADD then
|
||||
curr_tx_addr := trans_st.write.curr_inst.address;
|
||||
end if;
|
||||
-- Outputs --
|
||||
socbridge_driver_to_ext.payload <= st.socbridge_driver_to_ext_reg.data;
|
||||
socbridge_driver_to_ext.control(0) <= st.socbridge_driver_to_ext_reg.parity;
|
||||
socbridge_driver_to_ext.control(1) <= st.socbridge_driver_to_ext_reg.clk;
|
||||
if trans_st.curr_state = IDLE then
|
||||
socbridge_driver_to_controller.is_active <= '0';
|
||||
if trans_st.read.curr_state = IDLE then
|
||||
socbridge_driver_to_controller.is_reading <= '0';
|
||||
else
|
||||
socbridge_driver_to_controller.is_active <= '1';
|
||||
socbridge_driver_to_controller.is_reading <= '1';
|
||||
end if;
|
||||
if trans_st.write.curr_state = IDLE then
|
||||
socbridge_driver_to_controller.is_writing <= '0';
|
||||
else
|
||||
socbridge_driver_to_controller.is_writing <= '1';
|
||||
end if;
|
||||
|
||||
--- Next State Assignments ---
|
||||
@ -145,7 +160,7 @@ begin
|
||||
and st.curr_rx_transaction = WRITE_ACK then
|
||||
next_tx_state <= IDLE;
|
||||
elsif (st.curr_tx_transaction = READ_ADD or st.curr_tx_transaction = READ)
|
||||
and st.curr_rx_transaction = READ_RESPONSE and st.rx_stage = 1 then
|
||||
and st.curr_rx_transaction = READ_RESPONSE and (st.rx_stage = 1 or next_tx_transaction = WRITE or next_tx_transaction = WRITE_ADD) then
|
||||
next_tx_state <= IDLE;
|
||||
else
|
||||
next_tx_state <= TX_AWAIT;
|
||||
@ -236,13 +251,13 @@ begin
|
||||
end if;
|
||||
when TX_AWAIT =>
|
||||
when ADDR1 =>
|
||||
local_next_data_out := st.curr_tx_addr(31 downto 24);
|
||||
local_next_data_out := curr_tx_addr(31 downto 24);
|
||||
when ADDR2 =>
|
||||
local_next_data_out := st.curr_tx_addr(23 downto 16);
|
||||
local_next_data_out := curr_tx_addr(23 downto 16);
|
||||
when ADDR3 =>
|
||||
local_next_data_out := st.curr_tx_addr(15 downto 8);
|
||||
local_next_data_out := curr_tx_addr(15 downto 8);
|
||||
when ADDR4 =>
|
||||
local_next_data_out := st.curr_tx_addr(7 downto 0);
|
||||
local_next_data_out := curr_tx_addr(7 downto 0);
|
||||
end case;
|
||||
--- ### RX_STATE BASED OUTPUT ### ---
|
||||
socbridge_driver_to_manager.valid <= '0';
|
||||
@ -252,6 +267,11 @@ begin
|
||||
when IDLE =>
|
||||
when RX_HEADER =>
|
||||
when RX_W_BODY =>
|
||||
if st.rx_stage mod 4 = 0 and st.rx_stage /= st.rx_data_size then
|
||||
socbridge_driver_to_manager.data <= st.curr_write_data;
|
||||
socbridge_driver_to_manager.address <= st.curr_rx_write_addr;
|
||||
socbridge_driver_to_manager.valid <= '1';
|
||||
end if;
|
||||
when RX_R_BODY =>
|
||||
when RX_AWAIT =>
|
||||
if st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then
|
||||
@ -269,74 +289,103 @@ begin
|
||||
next_parity_out <= calc_parity(local_next_data_out);
|
||||
--- TRANSLATOR ---
|
||||
--- Next state assignment
|
||||
case trans_st.curr_state is
|
||||
case trans_st.write.curr_state is
|
||||
when IDLE =>
|
||||
if st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD
|
||||
or st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then
|
||||
trans_next_state <= IDLE;
|
||||
elsif trans_st.curr_inst.request = '1' then
|
||||
trans_next_state <= SEND;
|
||||
trans_write_next_state <= IDLE;
|
||||
elsif trans_st.write.curr_inst.request = '1' then
|
||||
trans_write_next_state <= SEND;
|
||||
else
|
||||
trans_next_state <= IDLE;
|
||||
trans_write_next_state <= IDLE;
|
||||
end if;
|
||||
-- Wait for driver to go idle and send next instruction. Then enter AWAIT
|
||||
when SEND =>
|
||||
if st.curr_tx_state /= IDLE then
|
||||
trans_next_state <= SEND_ACCEPTED;
|
||||
if st.curr_tx_transaction = WRITE or st.curr_tx_transaction = WRITE_ADD then
|
||||
trans_write_next_state <= SEND_ACCEPTED;
|
||||
else
|
||||
trans_next_state <= SEND;
|
||||
trans_write_next_state <= SEND;
|
||||
end if;
|
||||
-- Transisitonal state to decrement counter in transition between SEND and AWAIT.
|
||||
when SEND_ACCEPTED =>
|
||||
trans_next_state <= AWAIT;
|
||||
trans_write_next_state <= AWAIT;
|
||||
-- Wait for driver to finish current instruction, then reenter SEND
|
||||
when AWAIT =>
|
||||
if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_next_state <= IDLE;
|
||||
if trans_st.write.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_write_next_state <= IDLE;
|
||||
elsif st.curr_tx_state = IDLE then
|
||||
trans_next_state <= SEND;
|
||||
trans_write_next_state <= SEND;
|
||||
else
|
||||
trans_next_state <= AWAIT;
|
||||
trans_write_next_state <= AWAIT;
|
||||
end if;
|
||||
end case;
|
||||
case trans_st.read.curr_state is
|
||||
when IDLE =>
|
||||
if st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD
|
||||
or st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then
|
||||
trans_read_next_state <= IDLE;
|
||||
elsif trans_st.read.curr_inst.request = '1' then
|
||||
trans_read_next_state <= SEND;
|
||||
else
|
||||
trans_read_next_state <= IDLE;
|
||||
end if;
|
||||
-- Wait for driver to go idle and send next instruction. Then enter AWAIT
|
||||
when SEND =>
|
||||
if st.curr_tx_transaction = READ or st.curr_tx_transaction = READ_ADD then
|
||||
trans_read_next_state <= SEND_ACCEPTED;
|
||||
else
|
||||
trans_read_next_state <= SEND;
|
||||
end if;
|
||||
-- Transisitonal state to decrement counter in transition between SEND and AWAIT.
|
||||
when SEND_ACCEPTED =>
|
||||
trans_read_next_state <= AWAIT;
|
||||
-- Wait for driver to finish current instruction, then reenter SEND
|
||||
when AWAIT =>
|
||||
if trans_st.read.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_read_next_state <= IDLE;
|
||||
elsif st.curr_tx_state = IDLE then
|
||||
trans_read_next_state <= SEND;
|
||||
else
|
||||
trans_read_next_state <= AWAIT;
|
||||
end if;
|
||||
end case;
|
||||
|
||||
--- NEXT TX TRANSACTION ---
|
||||
local_next_tx_transaction := NO_OP;
|
||||
next_tx_data_size <= 0;
|
||||
if trans_st.curr_state = IDLE and st.curr_rx_state = RX_AWAIT then
|
||||
if trans_st.read.curr_state = IDLE and trans_st.write.curr_state = IDLE and st.curr_rx_state = RX_AWAIT then
|
||||
if (st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD) and manager_to_socbridge_driver.ready = '1' then
|
||||
local_next_tx_transaction := WRITE_ACK;
|
||||
elsif (st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD) and manager_to_socbridge_driver.valid = '1' then
|
||||
next_tx_data_size <= st.rx_data_size;
|
||||
local_next_tx_transaction := READ_RESPONSE;
|
||||
end if;
|
||||
else
|
||||
case trans_st.curr_state is
|
||||
when IDLE =>
|
||||
when SEND =>
|
||||
if trans_st.is_first_word = '1' then
|
||||
if trans_st.curr_inst.instruction = READ then
|
||||
local_next_tx_transaction := READ_ADD;
|
||||
elsif trans_st.curr_inst.instruction = WRITE then
|
||||
local_next_tx_transaction := WRITE_ADD;
|
||||
end if;
|
||||
else
|
||||
if trans_st.curr_inst.instruction = READ then
|
||||
local_next_tx_transaction := READ;
|
||||
elsif trans_st.curr_inst.instruction = WRITE then
|
||||
local_next_tx_transaction := WRITE;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if trans_st.curr_inst.seq_mem_access_count > MAX_PKT_SIZE then
|
||||
next_tx_data_size <= MAX_PKT_SIZE;
|
||||
elsif trans_st.curr_inst.seq_mem_access_count > 0 then
|
||||
next_tx_data_size <= trans_st.curr_inst.seq_mem_access_count;
|
||||
else
|
||||
next_tx_data_size <= 0;
|
||||
end if;
|
||||
when others =>
|
||||
end case;
|
||||
elsif trans_st.read.curr_state = SEND then
|
||||
if trans_st.read.is_first_word = '1' then
|
||||
local_next_tx_transaction := READ_ADD;
|
||||
else
|
||||
local_next_tx_transaction := READ;
|
||||
end if;
|
||||
if trans_st.read.curr_inst.seq_mem_access_count > MAX_PKT_SIZE then
|
||||
next_tx_data_size <= MAX_PKT_SIZE;
|
||||
elsif trans_st.read.curr_inst.seq_mem_access_count > 0 then
|
||||
next_tx_data_size <= trans_st.read.curr_inst.seq_mem_access_count;
|
||||
else
|
||||
next_tx_data_size <= 0;
|
||||
end if;
|
||||
elsif trans_st.write.curr_state = SEND then
|
||||
if trans_st.write.is_first_word = '1' then
|
||||
local_next_tx_transaction := WRITE_ADD;
|
||||
else
|
||||
local_next_tx_transaction := WRITE;
|
||||
end if;
|
||||
if trans_st.write.curr_inst.seq_mem_access_count > MAX_PKT_SIZE then
|
||||
next_tx_data_size <= MAX_PKT_SIZE;
|
||||
elsif trans_st.write.curr_inst.seq_mem_access_count > 0 then
|
||||
next_tx_data_size <= trans_st.write.curr_inst.seq_mem_access_count;
|
||||
else
|
||||
next_tx_data_size <= 0;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
next_tx_transaction <= local_next_tx_transaction;
|
||||
@ -360,7 +409,6 @@ begin
|
||||
st.curr_rx_transaction <= NO_OP;
|
||||
st.tx_data_size <= 0;
|
||||
st.rx_data_size <= 0;
|
||||
st.curr_tx_addr <= (others => '0');
|
||||
st.curr_rx_read_addr <= (others => '0');
|
||||
st.curr_rx_write_addr <= (others => '0');
|
||||
st.curr_write_data <= (others => '0');
|
||||
@ -381,7 +429,6 @@ begin
|
||||
when IDLE =>
|
||||
st.curr_tx_transaction <= next_tx_transaction;
|
||||
st.tx_data_size <= next_tx_data_size;
|
||||
st.curr_tx_addr <= trans_st.curr_inst.address;
|
||||
if next_tx_transaction = WRITE_ADD or next_tx_transaction = WRITE
|
||||
or next_tx_transaction = READ_RESPONSE then
|
||||
st.tx_stage <= next_tx_data_size;
|
||||
@ -420,6 +467,9 @@ begin
|
||||
st.rx_stage <= st.rx_stage - 1;
|
||||
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;
|
||||
if (st.rx_stage - 2) mod 4 = 0 and st.rx_data_size - st.rx_stage > 4 then
|
||||
st.curr_rx_write_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_write_addr) + 4), 32));
|
||||
end if;
|
||||
when RX_AWAIT =>
|
||||
st.curr_read_data <= manager_to_socbridge_driver.data;
|
||||
-- THIS DOESN'T WORK FOR LARGER THAN 4 BYTE ACCESSES, SHOULD BE FIXED BUT NOT NEEDED IF ONLY 4 BYTE ACCESSES ARRIVE
|
||||
@ -461,32 +511,65 @@ begin
|
||||
--- TRANSLATOR ---
|
||||
|
||||
if(rst = '1') then
|
||||
trans_st.curr_state <= IDLE;
|
||||
trans_st.curr_inst.request <= '0';
|
||||
trans_st.curr_inst.address <= (others => '0');
|
||||
trans_st.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.curr_inst.instruction <= NO_OP;
|
||||
trans_st.is_first_word <= '1';
|
||||
elsif(rising_edge(clk)) then
|
||||
trans_st.curr_state <= trans_next_state;
|
||||
case trans_st.curr_state is
|
||||
trans_st.read.curr_state <= IDLE;
|
||||
trans_st.read.curr_inst.request <= '0';
|
||||
trans_st.read.curr_inst.address <= (others => '0');
|
||||
trans_st.read.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.read.curr_inst.instruction <= NO_OP;
|
||||
trans_st.read.is_first_word <= '1';
|
||||
trans_st.write.curr_state <= IDLE;
|
||||
trans_st.write.curr_inst.request <= '0';
|
||||
trans_st.write.curr_inst.address <= (others => '0');
|
||||
trans_st.write.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.write.curr_inst.instruction <= NO_OP;
|
||||
trans_st.write.is_first_word <= '1';
|
||||
elsif(rising_edge(ext_to_socbridge_driver_rec.clk)) then
|
||||
trans_st.read.curr_state <= trans_read_next_state;
|
||||
trans_st.write.curr_state <= trans_write_next_state;
|
||||
case trans_st.write.curr_state is
|
||||
when IDLE =>
|
||||
if controller_to_socbridge_driver.request = '1' then
|
||||
trans_st.curr_inst <= controller_to_socbridge_driver;
|
||||
if controller_to_socbridge_driver.request = '1' and controller_to_socbridge_driver.instruction = WRITE then
|
||||
trans_st.write.curr_inst <= controller_to_socbridge_driver;
|
||||
else
|
||||
end if;
|
||||
trans_st.is_first_word <= '1';
|
||||
trans_st.write.is_first_word <= '1';
|
||||
when SEND =>
|
||||
when SEND_ACCEPTED =>
|
||||
trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - MAX_PKT_SIZE;
|
||||
trans_st.write.curr_inst.seq_mem_access_count <= trans_st.write.curr_inst.seq_mem_access_count - MAX_PKT_SIZE;
|
||||
when AWAIT =>
|
||||
if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_st.curr_inst.request <= '0';
|
||||
trans_st.curr_inst.address <= (others => '0');
|
||||
trans_st.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.curr_inst.instruction <= NO_OP;
|
||||
if trans_st.write.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_st.write.curr_inst.request <= '0';
|
||||
trans_st.write.curr_inst.address <= (others => '0');
|
||||
trans_st.write.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.write.curr_inst.instruction <= NO_OP;
|
||||
end if;
|
||||
trans_st.write.is_first_word <= '0';
|
||||
when others =>
|
||||
end case;
|
||||
case trans_st.read.curr_state is
|
||||
when IDLE =>
|
||||
if controller_to_socbridge_driver.request = '1' and controller_to_socbridge_driver.instruction = READ then
|
||||
trans_st.read.curr_inst <= controller_to_socbridge_driver;
|
||||
else
|
||||
end if;
|
||||
trans_st.read.is_first_word <= '1';
|
||||
when SEND =>
|
||||
when SEND_ACCEPTED =>
|
||||
trans_st.read.curr_inst.seq_mem_access_count <= trans_st.read.curr_inst.seq_mem_access_count - MAX_PKT_SIZE;
|
||||
trans_st.read.curr_inst.address <= std_logic_vector(unsigned(trans_st.read.curr_inst.address) + MAX_PKT_SIZE);
|
||||
when AWAIT =>
|
||||
if trans_st.read.curr_inst.seq_mem_access_count <= 0 and st.curr_tx_state = IDLE then
|
||||
trans_st.read.curr_inst.request <= '0';
|
||||
trans_st.read.curr_inst.address <= (others => '0');
|
||||
trans_st.read.curr_inst.seq_mem_access_count <= 0;
|
||||
trans_st.read.curr_inst.instruction <= NO_OP;
|
||||
end if;
|
||||
if trans_st.read.curr_inst.seq_mem_access_count mod 256 = 0 then
|
||||
trans_st.read.is_first_word <= '0';
|
||||
report tost(trans_st.read.curr_inst.address) & " -> " & tost(trans_st.read.curr_inst.address + 256);
|
||||
else
|
||||
trans_st.read.is_first_word <= '0';
|
||||
end if;
|
||||
trans_st.is_first_word <= '0';
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
|
||||
@ -20,13 +20,18 @@ package socbridge_driver_pkg is
|
||||
(IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_AWAIT,
|
||||
TX_HEADER, TX_W_BODY, TX_R_BODY);
|
||||
--- TRANSLATOR ---
|
||||
type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT);
|
||||
type ctrl_inst_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT);
|
||||
|
||||
type translator_state_rec_t is record
|
||||
type ctrl_inst_state_rec_t is record
|
||||
curr_inst : controller_to_socbridge_driver_t;
|
||||
curr_state : translator_state_t;
|
||||
curr_state : ctrl_inst_state_t;
|
||||
is_first_word : std_logic;
|
||||
end record translator_state_rec_t;
|
||||
end record ctrl_inst_state_rec_t;
|
||||
|
||||
type translator_state_t is record
|
||||
read: ctrl_inst_state_rec_t;
|
||||
write: ctrl_inst_state_rec_t;
|
||||
end record translator_state_t;
|
||||
|
||||
type ext_protocol_t is record
|
||||
data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
@ -44,7 +49,6 @@ package socbridge_driver_pkg is
|
||||
tx_data_size, rx_data_size : integer;
|
||||
curr_write_data : std_logic_vector(31 downto 0);
|
||||
curr_read_data : std_logic_vector(31 downto 0);
|
||||
curr_tx_addr : std_logic_vector(31 downto 0);
|
||||
curr_rx_read_addr : std_logic_vector(31 downto 0);
|
||||
curr_rx_write_addr : std_logic_vector(31 downto 0);
|
||||
end record state_rec_t;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user