library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.MATH_REAL.all; library gan_ganimede; use gan_ganimede.io_types.all; package socbridge_driver_pkg is subtype command_size_t is integer range 0 to 128; constant MAX_IN_FLIGHT : integer := 1; type transaction_t is (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR, WRITE_ACK, READ_RESPONSE); type rx_state_t is (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, RX_AWAIT, RX_R_BODY, RX_HEADER, RX_W_BODY); type tx_state_t is (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_AWAIT, TX_HEADER, TX_W_BODY, TX_R_BODY); --- TRANSLATOR --- type ctrl_inst_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); type ctrl_inst_t is record request : std_logic; address : std_logic_vector(address_width - 1 downto 0); seq_mem_access_count : integer; instruction : instruction_command_t; end record ctrl_inst_t; type ctrl_inst_state_rec_t is record curr_inst : ctrl_inst_t; curr_state : ctrl_inst_state_t; is_first_word : std_logic; 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); clk : std_logic; parity : std_logic; end record ext_protocol_t; type state_rec_t is record curr_rx_transaction : transaction_t; curr_tx_transaction : transaction_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; tx_stage, rx_stage : NATURAL; tx_data_size, rx_data_size : integer; curr_tx_addr : std_logic_vector(31 downto 0); read_in_flight : boolean; write_in_flight : boolean; last_sent_transaction : transaction_t; manager_addr : std_logic_vector(31 downto 0); manager_data : std_logic_vector(31 downto 0); end record state_rec_t; impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) ) return std_logic; pure function create_io_type_out_from_ext_protocol( input: ext_protocol_t ) return socbridge_driver_to_ext_t; function to_string ( a: std_logic_vector) return string; pure function get_header_bits(transaction : transaction_t; caused_by: transaction_t) return std_logic_vector; pure function get_size_bits(size : command_size_t) return std_logic_vector; pure function get_size_bits_sim(size : command_size_t) return std_logic_vector; end package socbridge_driver_pkg; package body socbridge_driver_pkg is function to_string ( a: std_logic_vector) return string is variable b : string (1 to a'length) := (others => NUL); variable stri : integer := 1; begin for i in a'range loop b(stri) := std_logic'image(a((i)))(2); stri := stri+1; end loop; return b; end function; impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) ) return std_logic is variable parity : std_logic; begin parity := d(0); for x in integer'(1) to d'length - 1 loop parity := parity xor d(x); end loop; return not parity; end function; pure function create_io_type_out_from_ext_protocol( input : ext_protocol_t ) return socbridge_driver_to_ext_t is variable val : socbridge_driver_to_ext_t; begin val.payload:= input.data; val.control(1) := input.clk; val.control(0) := input.parity; return val; end function; pure function get_header_bits(transaction : transaction_t; caused_by : transaction_t) return std_logic_vector is variable val : std_logic_vector(4 downto 0); begin val := "11111"; if transaction = NO_OP then val := "00000"; elsif transaction = WRITE_ADD then val := "10000"; elsif transaction = WRITE then val := "10100"; elsif transaction = READ_ADD then val := "11000"; elsif transaction = READ then val := "11100"; elsif transaction = WRITE_ACK and caused_by = WRITE then val := "00101"; elsif transaction = WRITE_ACK and caused_by = WRITE_ADD then val := "00001"; elsif transaction = READ_RESPONSE and caused_by = READ then val := "01100"; elsif transaction = READ_RESPONSE and caused_by = READ_ADD then val := "01000"; elsif transaction = P_ERR then val := "01001"; end if; return val; end function; pure function get_size_bits(size: command_size_t) return std_logic_vector is variable val : std_logic_vector(2 downto 0); begin if size > 2**6 then val := "111"; elsif size > 2**5 then val := "110"; elsif size > 2**4 then val := "101"; elsif size > 2**3 then val := "100"; elsif size > 2**2 then val := "011"; elsif size > 2**1 then val := "010"; elsif size > 2**0 then val := "001"; elsif size >= 0 then val := "000"; end if; return val; end function; pure function get_size_bits_sim(size: command_size_t) return std_logic_vector is variable pow : integer; variable val : std_logic_vector(2 downto 0); begin pow := integer(CEIL(sqrt(Real(size)))); val := std_logic_vector(TO_UNSIGNED(size - 1, 3)); return val; end function; end package body socbridge_driver_pkg;