  --	Package File Template
--
--	Purpose: This package defines supplemental types, subtypes, 
--		 constants, and components 


library IEEE;
use IEEE.STD_LOGIC_1164.all;

package CoreTypes is
CONSTANT Word :POSITIVE:= 8;
CONSTANT ADRLEN:POSITIVE:=16;
CONSTANT LZFILL :std_logic_vector(2*Word-ADRLEN to 0):=(others=>'0');--indique le nombre de zero à utiliser pour completer le bus de données lorsque la longueur restante du bus d'adresse est inférueure à la largeur du bus de données
CONSTANT IADR0 : NATURAL :=2; --Adresse basse de l'instruction
CONSTANT IADR1 : natural :=3;
CONSTANT CORE_BASE_ADR :natural range 0 to 65535:=4096;
CONSTANT CORE_UPPER_ADR : natural range 0 to 255:=16;
CONSTANT CORE_GET_ADR:natural:=CORE_BASE_ADR+526;
CONSTANT CORE_PUT_ADR :natural:=CORE_BASE_ADR+516;
CONSTANT core_INIT_ADR : natural:=CORE_BASE_ADR+512;
CONSTANT CORE_WCREATE_ADR : natural := CORE_BASE_ADR+536;
CONSTANT CORE_WCOMPL_ADR : natural := CORE_BASE_ADR+546;
CONSTANT CORE_WPOST_ADR : natural := CORE_BASE_ADR+556;
CONSTANT CORE_WWAIT_ADR : natural := CORE_BASE_ADR+566;
CONSTANT CORE_Rank2port_BASE :NATURAL:=32;
CONSTANT WIN0_ADR :natural :=4;
CONSTANT WIN1_ADR :natural :=14;
CONSTANT WIN2_ADR :natural :=24;
CONSTANT WIN3_ADR :natural :=34;
CONSTANT GETPORTID : std_logic_vector(3 downto 0):="0001";
  
  type Typ_PortIO is
   array(natural range <>) of std_logic_vector( Word-1 downto 0);
	
	type memory is 
	array (natural range <>) of std_logic_vector(word-1 downto 0);
	
type Core_io is
	record
		Instr_en :std_logic;  -- active une instruction MPI
		Instr_ack :std_logic;-- signal la prise en compte de l'instruction
		Ready   :std_logic;-- indique que la dernière fonction est terminée
		InitOk :std_logic; -- l'initialisation est terminée
		Hold_Req :std_logic;--Demande DMA 
		Hold_Ack :std_logic;-- Autorisation DMA
		MemBusy :std_logic;-- active le refus de DMA (1 -> ignoré la requête DMA) 
		RamSel :std_logic;-- indique le statut de la RAM (0 ->dispo 1->occupé par Core_MPI)
		IntState1 : natural range 0 to 255; --permet de stocker l'état des MAE interne dans les procédures
		IntState2 : natural range 0 to 255;
		Instruction :std_logic_vector (word-1 downto 0);
		WinId :natural range  0 to 255; --stocke le dernier Id utilisé par WinCreate
		IsMain : std_logic; -- indique si la librairie est principal
		Rank : natural range 0 to 16; --donne le rang du processus courant
end record;

type typ_dpram is
record
			  
           
	    clk_wr :  STD_LOGIC;
	    clk_rd :  STD_LOGIC;
		we     :  STD_LOGIC;
		ena    :  STD_LOGIC;
		enb    :  STD_LOGIC;
		addr_wr:  STD_LOGIC_VECTOR (ADRLEN-1 downto 0);
		addr_rd :  STD_LOGIC_VECTOR (ADRLEN-1 downto 0);
		data_in  :  STD_LOGIC_VECTOR (Word-1 downto 0);
		data_out :  STD_LOGIC_VECTOR (Word-1 downto 0); 
			  
           		  
end record;        
type Typ_MPIPort_in is
record
			  instruction :   STD_LOGIC_VECTOR (Word -1 downto 0);
           instruction_en :  STD_LOGIC;
           		  

			  packet_ack : std_logic;
           ram_data_out :  STD_LOGIC_VECTOR (Word-1 downto 0);
			  
			  hold_ack       :  STD_Logic;  --autorisation par l'application
			  clk :  STD_LOGIC;
           reset :  STD_LOGIC;
           		  
end record;
type Typ_MPIPort_out is
record		  
          
			  
           ram_we :  STD_LOGIC;
			  ram_en :  STD_LOGIC;
			  ram_data_in : STD_LOGIC_VECTOR (WORD-1 downto 0);
           ram_address_rd :  STD_LOGIC_VECTOR (ADRLEN-1 downto 0);
			  ram_address_wr :  STD_LOGIC_VECTOR (ADRLEN-1 downto 0);
			  packet_received : STD_LOGIC;
			  barrier_completed : STD_LOGIC;
           instruction_fifo_full : STD_LOGIC;
			  PushOut :  STD_LOGIC_VECTOR (WORD-1 downto 0);
			   
           hold_req       : STD_Logic;  --requete vers application
end record;

Type Ar_MPIPort_In is array (positive range <>) of Typ_MPIPort_in;
Type Ar_MPIPort_out is array (positive range <>) of Typ_MPIPort_out;

-- Declare constants

--  constant <constant_name>		: time := <time_unit> ns;
--  constant <constant_name>		: integer := <value>;
-- 
-- Declare functions and procedure
Component  SWITCH_GEN is     
 generic(number_of_ports : positive := 8);
     port(
	        -- ports d'entree
           Port_in : in typ_portIO(1 to number_of_ports) ;
--			  
			 
			  -- port de sortie
			  Port_out : out  typ_portIO(1 to number_of_ports);
--			  
			  -- signaux de controle
			  cmd_in_en : in std_logic_vector(number_of_ports downto 1);
			  data_in_en : in std_logic_vector(number_of_ports downto 1);
			  data_out_en : in std_logic_vector(number_of_ports downto 1);
			  fifo_in_full : out std_logic_vector(number_of_ports downto 1);
			  fifo_in_empty : out std_logic_vector(number_of_ports downto 1);
			  data_available : out std_logic_vector(number_of_ports downto 1);
			  clk       : in   STD_LOGIC;
			  reset     : in   STD_LOGIC);
end component SWITCH_GEN;
-- déclaration des fonctions utilisées
 
 FUNCTION all_ones(s1:std_logic_vector) return std_logic; 
  --This function returns if the input vector has all ones and no zeros
 FUNCTION all_zeros(s1:std_logic_vector) return std_logic; 
  --This function returns if the input vector has all zeros and no ones
 FUNCTION incr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector; 
  --This function increments an std_logic_vector type by '1', without 
  --using any arithmatic

  FUNCTION dcr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector; 
  --This function decrements an std_logic_vector type by '1', without 
  --using any arithmatic
  FUNCTION Rol_Vec(s1:std_logic_vector) return std_logic_vector;
  --renvoie un std_logic_vector de taille ADRLEN
  Function Stdlv (s1 : natural ) return std_logic_vector;
end CoreTypes;


Package body CoreTypes is


FUNCTION incr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector is 
                  --this function increments a std_logic_vector type by '1' 
        VARIABLE V : std_logic_vector(s1'high downto s1'low) ; 
        VARIABLE tb : std_logic_vector(s1'high downto s1'low); 
        BEGIN 
        tb(s1'low) := en; 
        V := s1; 
        for i in (V'low + 1) to V'high loop 
            tb(i) := V(i - 1) and tb(i -1); 
        end loop; 
        for i in V'low to V'high loop 
            if(tb(i) = '1') then 
                V(i) := not(V(i)); 
            end if; 
        end loop; 
        return V; 
        end incr_vec; -- end function

FUNCTION  dcr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector is 
                  --this function decrements a std_logic_vector type by '1' 
        VARIABLE V : std_logic_vector(s1'high downto s1'low) ; 
        VARIABLE tb : std_logic_vector(s1'high downto s1'low); 
        BEGIN 
        tb(s1'low) := not(en); 
        V := s1; 
        for i in (V'low + 1) to V'high loop 
            tb(i) := V(i - 1) or tb(i -1); 
        end loop; 
        for i in V'low to V'high loop 
            if(tb(i) = '0') then 
                V(i) := not(V(i)); 
            end if; 
        end loop; 
        return V; 
        end dcr_vec; -- end function
FUNCTION all_ones(s1:std_logic_vector) return std_logic is 
                  --this function tells if all bits of a vector are '1' 
                  --return value Z is '1', then vector has all 1 bits 
        --VARIABLE V : std_logic_vector(s1'high downto s1'low) ; 
        VARIABLE Z : std_logic; 
        BEGIN 
        Z := s1(s1'low); 
        FOR i IN (s1'low+1) to s1'high LOOP 
            Z := Z AND s1(i); 
        END LOOP; 
        RETURN Z; 
        END all_ones; -- end function
FUNCTION all_zeros(s1:std_logic_vector) return std_logic is 
                  --this function tells if all bits of a vector are '0' 
                  --return value Z if '1', then vector has all 0 bits 
        --VARIABLE V : std_logic_vector(s1'high downto s1'low) ; 
        VARIABLE Z : std_logic; 
        BEGIN 
        Z := '0'; 
        FOR i IN (s1'low) to s1'high LOOP 
            Z := Z OR s1(i); 
        END LOOP; 
        RETURN not(Z); 
        END all_zeros; -- end function
		  
FUNCTION Rol_Vec(s1:std_logic_vector) return std_logic_vector is
--cette fonction fait roter un STD_logic d'un pas vers la gauche
VARIABLE V : std_logic_vector(s1'high downto s1'low) ; 
        VARIABLE lb : std_logic :=s1(s1'left);
        BEGIN 
     
        for i in V'left  downto (V'right+1) loop 
            V(i) := s1(i - 1) ; 
        end loop; 
        V(V'right):=lb;
        return V; 
        end Rol_vec;
 Function Stdlv (s1 : natural ) return std_logic_vector is
VARIABLE V : std_logic_vector(ADRLEN-1 downto 0)
 begin
	V:=std_logic_vector(to_unsigned(s1,ADRLEN));
	return V;
 end stdlv;
end CoreTypes;
