178 lines
5.3 KiB
VHDL
178 lines
5.3 KiB
VHDL
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;
|