-- Package File Template -- -- Purpose: This package defines supplemental types, subtypes, -- constants, and functions library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.numeric_std.all; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Library NocLib; use NocLib.CoreTypes.all; use work.PACKET_TYPE.all; package Mpi_Rma is procedure WritePtr(AdrVect:in std_logic_vector; count: inout natural;signal SysRam :out typ_dpram); procedure pMPI_INIT(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram); procedure pMPI_PUT(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram; Orig_Addr: std_logic_vector;Orig_Count : natural; Orig_DataType: natural; Target_Rank : natural; Target_disp : std_logic_vector; Target_Count : natural; Target_Datatype :natural; Win : natural); procedure pMPI_GET(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram; Orig_Addr: std_logic_vector;Orig_Count : natural; Orig_DataType: natural; Target_Rank : natural; Target_disp : std_logic_vector; Target_Count : natural; Target_Datatype :natural; Win : natural); procedure pMPI_Comm_Rank(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; COMM :in natural; signal Rank : out std_logic_vector ); procedure pMPI_Win_create(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; base :std_logic_vector; size : Mpi_Aint;disp_unit:natural; info:natural; comm:Mpi_Comm; Win: inout MPI_Win ); procedure pMPI_Win_start( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; pgroup:MPI_group;asser : natural; Win :MPI_Win); procedure pMPI_Win_wait( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; Win :MPI_Win); procedure pMPI_Win_post( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; pgroup:MPI_group;asser : natural; Win :MPI_Win); procedure pMPI_Win_complete( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; Win :MPI_Win); procedure pMPI_Comm_Spawn(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; command : natural; argv :natural; maxprocs : natural; info : natural; root : natural; comm : natural; signal intercomm :out natural; signal array_of_errcodes : out natural); -- declare functions and procedure procedure MPI_Alloc_mem(NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; SIZE : natural; MPI_INFO: natural; baseptr: out std_logic_vector(ADRLEN-1 downto 0)); procedure ReadMem( NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; AdrVect:in std_logic_vector; data: out std_logic_vector); procedure WriteMem(NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; AdrVect:in std_logic_vector; Data:in std_logic_vector); procedure SetBit( NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; variable AdrVect:in std_logic_vector(ADrLen-1 downto 0); variable BitMask: in std_logic_vector(Word-1 downto 0);bitval:in std_logic); end MPI_Rma; package body MPI_Rma is ----int MPI_Put( -- void *origin_addr, -- int origin_count, -- MPI_Datatype origin_datatype, -- int target_rank, -- MPI_Aint target_disp, -- int target_count, -- MPI_Datatype target_datatype, -- MPI_Win win --); -- Example 1 procedure pMPI_PUT(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram; Orig_Addr: std_logic_vector;Orig_Count : natural; Orig_DataType: natural; Target_Rank : natural; Target_disp : std_logic_vector; Target_Count : natural; Target_Datatype :natural; Win : natural) is variable i,dcount,wr_state : natural:=0; variable adresse :natural; variable addr1 :std_logic_vector(Orig_Addr'length-1 downto 0):=Orig_Addr; variable addr2 :std_logic_vector(Target_Disp'length-1 downto 0):=Target_Disp; variable put_adr : std_logic_vector (ADRLEN-1 downto 0); variable config_reg: std_logic_vector (Word-1 downto 0); constant LeftZero: std_logic_vector(2*Word-ADRLEN to 0):=(others=>'0'); begin put_adr:=conv_Std_logic_vector(Core_put_adr,ADRLEN); addr1:=Orig_Addr; addr2:=Target_Disp; if NextCtx /=0 then --préserver la valeur de count entre les appels dcount:=NextCtx; end if; -- -- if rising_edge(clkin) then if dcount= 0 then dcount:=dcount+1; Interf.S.Intstate1<=0; Interf.O.Instruction<=x"00"; elsif dcount>=1 and dcount <=3 then if interf.I.ramsel='0' then Interf.O.membusy<='0'; --SysRam.O.we<='1'; --SysRam.O.ena<='1'; SysRam.O.enb<='1'; wr_state:=interf.S.Intstate1; WritePtr (put_adr,wr_state,SysRam); interf.S.Intstate1<=wr_state; if wr_state =0 then -- fin de l'écriture du pointeur en mémoire dcount:=4; end if; end if; elsif dcount=4 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; if target_rank <=15 then --limitation de cete version à 16 rang Interf.S.Gstart(Target_rank)<='1'; end if; adresse:=core_put_adr; SysRam.O.Data_in<=MPI_PUT & conv_std_logic_vector(Target_Rank,4); --code fonction SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=5 then if interf.I.ramsel='0' then adresse:=core_put_adr+1; SysRam.O.Data_in<=std_logic_vector(to_unsigned(Orig_Count,8)) ;--la longueur SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; Interf.O.Instruction<=x"06"; -- nombre de mots de l'instruction end if; elsif dcount=6 then if interf.I.ramsel='0' then adresse:=core_put_adr+2; SysRam.O.Data_in<= Addr1(ADRLEN-1 downto Word) ; --source Haut SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=7 then if interf.I.ramsel='0' then adresse:=core_put_adr+3; SysRam.O.Data_in<=Addr1(Word-1 downto 0); --source Bas SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=8 then if interf.I.ramsel='0' then adresse:=core_put_adr+4; SysRam.O.Data_in<= Addr2(ADRLEN-1 downto Word) ; -- destination haut SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=9 then if interf.I.ramsel='0' then adresse:=core_put_adr+5; SysRam.O.Data_in<=Addr2(Word-1 downto 0); -- destination bas SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=10 then if interf.I.ramsel='0' then adresse:=core_put_adr+6; SysRam.O.Data_in<=(others=>'0'); -- valeur d'acquittement SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=11 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; if interf.I.ramsel='0' then adresse:=core_base_adr+1; SysRam.O.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.Data_in<=x"01"; --instruction pulse enable via la mémoire; Interf.O.Instr_En<='1'; --active la prise en compte de l'instruction Interf.O.membusy<='0'; dcount:=dcount+1; end if; elsif dcount=12 then if Interf.I.Instr_ack='1' then -- le Core a reçu l'instruction ? Interf.O.Instr_En<='0'; --désactiver la prise en compte de l'instruction dcount:=dcount+1; config_reg:=SysRam.I.Data_out and x"f6"; SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; else Interf.O.Instr_En<='1'; end if; adresse:=core_base_adr+1; SysRam.O.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); --SysRam.O.Ram_busy<='0'; --?? SysRam.O.we<='0'; SysRam.O.ena<='0'; -- préparer la lecture du résultat du Put SysRam.O.enb<='1'; elsif dcount=13 then adresse:=core_base_adr+1; SysRam.O.we<='1'; SysRam.O.ena<='1'; -- préparer l'écriture du résultat du Put SysRam.O.enb<='1'; if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out and x"f6"; SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; Interf.O.membusy<='1'; end if; SysRam.O.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=14 then SysRam.O.we<='1'; SysRam.O.ena<='1'; -- préparer l'écriture du résultat du Put SysRam.O.enb<='0'; config_reg:=SysRam.I.Data_out and x"f6"; SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; adresse:=core_base_adr+1; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=15 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(Core_put_adr+6,Adrlen)); if SysRam.I.Data_out(0)='1' then --fin du MPI PUT ici pour l'envoie ! dcount:=dcount+1; SysRam.O.addr_rd<=conv_Std_logic_vector(Core_put_adr+7,Adrlen); Interf.S.Intstate2<=255; --timer pour la réception interf.s.tmem(0)<=x"02"; report "MPV pMPI_PUT():Ex1 de HCL a répondu concernant l'envoi"; end if; end if; elsif dcount=16 or dcount=17 or dcount=18 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; SysRam.O.addr_rd<=conv_Std_logic_vector(Core_put_adr+7,Adrlen); -- ce cycle permet d'attendre la donnée en sortie après le changement d'adresse if interf.I.ramsel='0' then dcount:=dcount+1; -- ce cycle permet d'attendre la donnée en sortie après le changement d'adresse elsif Interf.S.Intstate2>0 then dcount:=16; Interf.S.Intstate2<=Interf.S.Intstate2-1; elsif interf.s.tmem(0)>0 then interf.s.tmem(0)<=interf.s.tmem(0)-1; Interf.S.Intstate2<=255; dcount:=16; else dcount:=1;--recommencer l'envoi end if; elsif dcount=19 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; if interf.I.ramsel='0' then SysRam.O.addr_rd<=conv_Std_logic_vector(Core_put_adr+7,Adrlen); if SysRam.I.Data_out(5)='1' then --Message du MPI PUT bien reçu ! dcount:=dcount+1; report "MPV pMPI_PUT():Ex2 de HCL a reçu un acquittement concernant l'envoi"; SysRam.O.addr_rd<=conv_Std_logic_vector(Core_put_adr+7,Adrlen); elsif Interf.S.Intstate2>0 then Interf.S.Intstate2<=Interf.S.Intstate2-1; elsif interf.s.tmem(0)>0 then interf.s.tmem(0)<=interf.s.tmem(0)-1; Interf.S.Intstate2<=255; else dcount:=1;--recommencer l'envoi report "MPV pMPI_PUT():Timeout EX2 n'a pas reçu d'acquitement concernant l'envoi. reémission en cours..."; end if; else dcount:=16; end if; elsif dcount=20 then dcount:=0; --fin normale de la fonction Interf.O.membusy<='0'; report "MPV pMPI_PUT():fin normale de la fonction"; end if; NExtCtx:=dcount; -- end if; end procedure; procedure pMPI_GET(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram; Orig_Addr: std_logic_vector;Orig_Count : natural; Orig_DataType: natural; Target_Rank : natural; Target_disp : std_logic_vector; Target_Count : natural; Target_Datatype :natural; Win : natural) is variable i,wcount,dcount : natural range 0 to 255:=0; variable adresse :natural; variable wdata: std_logic_vector(Word-1 downto 0):=(others=>'0'); variable bitval : std_logic:='0'; variable addr1 :std_logic_vector(Orig_Addr'length-1 downto 0):=Orig_Addr; variable addr2 :std_logic_vector(Target_Disp'length-1 downto 0):=Target_Disp; variable get_adr : std_logic_vector (ADRLEN-1 downto 0); variable config_reg,win_reg: std_logic_vector (Word-1 downto 0); constant LeftZero: std_logic_vector(2*Word-ADRLEN to 0):=(others=>'0'); begin get_adr:=Std_logic_vector(to_unsigned(Core_get_adr,ADRLEN)); addr1:=Orig_Addr; addr2:=Target_Disp; if NextCtx /=0 then --préserver la valeur de count entre les appels dcount:=NextCtx; end if; -- -- if rising_edge(clkin) then if dcount =0 then dcount:=dcount+1; Interf.S.IntState1<=0; elsif dcount>=1 and dcount <=3 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; wcount:=Interf.S.IntState1; WritePtr (get_adr,wcount,SysRam); Interf.S.IntState1<=wcount; Interf.O.membusy<='1'; Interf.O.Instruction<=x"00"; if wcount =0 then dcount:=4; Interf.S.Intstate1<=1; end if; else Interf.S.IntState1<=0; end if; elsif dcount=4 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; if target_rank <=15 then --limitation de cete version à 16 rang Interf.S.Gstart(Target_rank)<='1'; end if; adresse:=core_get_adr; SysRam.O.Data_in<=MPI_GET & conv_Std_logic_vector(Target_Rank,4); --code fonction SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.membusy<='1'; dcount:=dcount+1; end if; elsif dcount=5 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+1; SysRam.O.Data_in<=std_logic_vector(to_unsigned(Orig_Count,8)) ;--la longueur SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); interf.O.Instruction<=x"06"; --le nbre de mots de l'intstruction dcount:=dcount+1; end if; elsif dcount=6 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+2; SysRam.O.Data_in<= Addr1(ADRLEN-1 downto Word) ; --source Haut SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=7 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+3; SysRam.O.Data_in<=Addr1(Word-1 downto 0); --source Bas SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=8 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+4; SysRam.O.Data_in<= Addr2(ADRLEN-1 downto Word) ; -- destination haut SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.membusy<='1'; dcount:=dcount+1; end if; elsif dcount=9 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+5; SysRam.O.Data_in<=Addr2(Word-1 downto 0); -- destination bas SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.membusy<='1'; dcount:=dcount+1; end if; elsif dcount=10 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; adresse:=core_get_adr+7; SysRam.O.Data_in<=x"00"; -- résultat du GET SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.membusy<='1'; Interf.S.IntState2<=0; dcount:=dcount+1; end if; elsif dcount=11 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; addr1:=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); wcount:=Interf.S.IntState2; wdata:=x"01";bitval:='1'; setBit(wcount,Interf,SysRam,addr1(ADrLen-1 downto 0),wdata,bitval); Interf.S.IntState2<=wcount; if wcount=0 then dcount:=dcount+1; Interf.O.Instr_En<='1'; --active la prise en compte de l'instruction end if; elsif dcount=12 then if Interf.I.Instr_ack='1' then -- le Core a reçu l'instruction ? Interf.O.Instr_En<='0'; --désactiver la prise en compte de l'instruction dcount:=dcount+1; config_reg:=SysRam.I.Data_out and x"f6"; --SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; end if; adresse:=core_base_adr+1; SysRam.O.addr_rd<=std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); --SysRam.O.Ram_busy<='0'; --?? SysRam.O.we<='0'; SysRam.O.ena<='0'; -- préparer la lecture du résultat du get SysRam.O.enb<='1'; Interf.O.membusy<='0'; elsif dcount=13 then adresse:=core_base_adr+1; SysRam.O.we<='1'; SysRam.O.ena<='1'; -- préparer l'écriture du résultat du get SysRam.O.enb<='1'; SysRam.O.addr_rd<=std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out and x"f6"; SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; Interf.O.membusy<='1'; end if; Interf.s.IntState2<=255; Interf.s.tmem(0)<=x"08"; --tempo pour l'attente du résultat de Get elsif dcount=14 then SysRam.O.we<='1'; SysRam.O.ena<='1'; -- préparer l'écriture du résultat du GET SysRam.O.enb<='0'; adresse:=core_base_adr+1; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out and x"f6"; SysRam.O.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=18;--dcount+1; Interf.O.membusy<='1'; end if; elsif dcount=15 then SysRam.O.we<='0'; SysRam.O.ena<='0'; -- préparer l'écriture du WBusy SysRam.O.enb<='1'; adresse:=core_base_adr+5; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out or x"40"; --mettre à 1 Wbusy SysRam.O.Data_in<=config_reg ; --mettre à 1 Wbusy dcount:=dcount+1; Interf.O.membusy<='1'; end if; elsif dcount=16 then SysRam.O.we<='0'; SysRam.O.ena<='0'; -- préparer l'écriture du WBusy SysRam.O.enb<='1'; adresse:=core_base_adr+5; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out or x"40"; --mettre à 1 Wbusy SysRam.O.Data_in<=config_reg ; --mettre à 1 Wbusy dcount:=dcount+1; Interf.O.membusy<='1'; end if; elsif dcount=17 then SysRam.O.we<='1'; SysRam.O.ena<='1'; -- préparer l'écriture du résultat du GET SysRam.O.enb<='1'; adresse:=core_base_adr+5; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if interf.I.ramsel='0' then config_reg:=SysRam.I.Data_out or x"40"; SysRam.O.Data_in<=config_reg ; --; dcount:=dcount+1; Interf.O.membusy<='1'; end if; elsif dcount>=18 and dcount <=21 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(Core_get_adr+6,Adrlen)); if SysRam.I.Data_out(0)='1' then --fin du MPI get ici pour l'envoie ! dcount:=dcount+1; end if; end if; elsif dcount>=22 and dcount <=24 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; SysRam.O.addr_rd<=conv_Std_logic_vector(Core_Get_adr+7,Adrlen); if interf.I.ramsel='0' then SysRam.O.addr_rd<=conv_Std_logic_vector(Core_Get_adr+7,Adrlen); if SysRam.I.Data_out(5)='1' then --Message du MPI Get bien reçu ! dcount:=dcount+1; --ce test est fait avant l'arrivée effective des données ce qui pose problème ! SysRam.O.addr_rd<=conv_Std_logic_vector(Core_Get_adr+7,Adrlen); elsif Interf.S.Intstate2>0 then Interf.S.Intstate2<=Interf.S.Intstate2-1; elsif interf.s.tmem(0)>0 then interf.s.tmem(0)<=interf.s.tmem(0)-1; Interf.S.Intstate2<=255; else dcount:=1;--recommencer l'envoi end if; end if; elsif dcount=25 then dcount:=0; --fin normale de la fonction Interf.O.membusy<='0'; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; end if; NExtCtx:=dcount; -- end if; end procedure; Procedure pMPI_Comm_group(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam : inout typ_dpram; COMM :in MPI_Comm; signal grp : out Mpi_group ) is Begin --cette procédure permet de récupérer le groupe qui est associé à un communicateur --dans notre cas c'est la récupération du groupe associé à COMM_WORLD end procedure; --int MPI_Group_incl(MPI_Group group, int n, int *ranks, -- MPI_Group *newgroup) Procedure pMPI_group_incl(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam : inout typ_dpram; GRP: Mpi_group; n:natural;ranks :natural; newgroup: out Mpi_group) is Begin -- cette procedure a pour algo de parcourir les rangs qui sont dans la mémoire pointée par ranks -- et d'activer l'un des bits de position de newgroup. -- -- end procedure; procedure pMPI_Comm_Rank(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; COMM :in natural; signal Rank : out std_logic_vector ) is variable adresse_rd : natural range 0 to 2**ADRLEN-1; begin if NextCtx =0 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); NextCtx:=1; elsif NextCtx=1 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if interf.I.ramsel='0' then Rank<=SysRam.I.Data_out(3 downto 0); NextCtx:=2; Interf.O.membusy<='1'; end if; elsif NextCtx=2 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if interf.I.ramsel='0' then Rank<=SysRam.I.Data_out(3 downto 0); Interf.S.Rank<=conv_integer(SysRam.I.Data_out(3 downto 0)); NextCtx:=3; Interf.O.membusy<='1'; end if; elsif NextCtx=3 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if interf.I.ramsel='0' then Rank<=SysRam.I.Data_out(3 downto 0); Interf.S.Rank<=conv_integer(SysRam.I.Data_out(3 downto 0)); NextCtx:=4; Interf.O.membusy<='1'; end if; elsif NextCtx=4 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if interf.I.ramsel='0' then Rank<=SysRam.I.Data_out(3 downto 0); Interf.S.Rank<=conv_integer(SysRam.I.Data_out(3 downto 0)); NextCtx:=0; Interf.O.membusy<='0'; end if; end if; end procedure; --int MPI_Win_create( -- void *base, -- MPI_Aint size, -- int disp_unit, -- MPI_Info info, -- MPI_Comm comm, -- MPI_Win *win --); procedure pMPI_Win_create(NextCtx : inout natural ;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; base :std_logic_vector; size : Mpi_Aint;disp_unit:natural; info:natural; comm:Mpi_Comm; Win: inout MPI_Win ) is -- parcours de la liste des fenêtres existantes à la recherche d'un emplacement libre -- si fenêtre libre trouvée, et -- mise à 1 du Bit WCreate du registre status type wtype is array (1 to 4 ) of natural range 0 to 255; variable AdrWin: std_logic_vector(ADRLEN-1 downto 0); variable adresse : std_logic_vector(ADRLEN-1 downto 0); variable clkin : std_logic:='1'; variable wcreate_adr : std_logic_vector(ADRLEN-1 downto 0):=std_logic_vector(to_unsigned(Core_wcreate_adr,ADRLEN)); variable w0 : std_logic_vector(Word-1 downto 0); variable adrnat : natural; variable sizewin : std_logic_vector(Word-1 downto 0); variable count : natural range 0 to 255; variable wdisp :wtype:=(4,14,24,34); --stocke l'adresse de la prochaine Win libre begin -- création d'une fenêtre il s'agit d'affecter l'objet Win et de retourner -- le pointeur qui permet de le décrire If NextCtx=0 then NExtCtx:=NextCtx+1; count:=0; Interf.O.membusy<='0'; Interf.S.IntState1<=count; elsif NextCtx>=1 and NextCtx <= 4 then count:=Interf.S.IntState1; AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(NextCtx),16)); readmem(count,interf,sysRam,AdrWin,w0); if count=0 then if w0(0)/='1' then -- cette fenêtre est libre NextCtx:=6; --étape de la création de la fenêtre Win.addr:=base; --l'adresse de la fenêtre Win.id:=NextCtx; -- la référence provisoire de la fenêtre Win.size:=Size; -- la taille de la fenêtre else NextCtx:=NextCtx+1; end if; end if; Interf.S.IntState1<=count;--sauvegarde du statut de la sous-procédure elsif NextCtx=5 then -- Plus de fenêtre disponible erreur NextCtx:=1; -- boucle sans fin :) Win.id:=0; Win.addr:=x"0000"; elsif NextCtx=6 then --Affectation de l'objet Windows car une place est disponible count:=Interf.S.IntState1; AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(Win.id),16)); Writemem(count,interf,SysRam,AdrWin,x"01"); --signal status pour created Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=8 then AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(Win.id),16)); interf.S.winid<=interf.S.winid+1; count:=Interf.S.IntState1; Writemem(count,interf,SysRam,AdrWin+1,stdlv(interf.S.winid,8)); --win id de la fenêtre Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=9 then adrnat:=Core_base_adr+Wdisp(Win.id); AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(Win.id),16)); count:=Interf.S.IntState1; Writemem(count,interf,SysRam,AdrWin+2,base(7 downto 0)); --adresse basse Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=10 then AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(Win.id),16)); count:=Interf.S.IntState1; Writemem(count,interf,SysRam,AdrWin+3,base(15 downto 8)); --adresse haute Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=11 then AdrWin:=std_logic_vector(to_unsigned(Core_base_adr+Wdisp(Win.id),16)); sizewin:=std_logic_vector(to_unsigned(size,8)); count:=Interf.S.IntState1; Writemem(count,interf,SysRam,AdrWin+4,sizewin); -- taille de la fenêtre Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=12 then --cette étape consiste à envoyer le message WINCREATE Sur le réseau et à récupérer -- les informations donnant le numéro de la fenêtre W0:=MPI_WIN_CREATE & std_logic_vector(to_unsigned(0,4)); --code fonction count:=Interf.S.IntState1; Writemem(count,interf,SysRam,wcreate_adr,w0); Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=13 then w0:=std_logic_vector(to_unsigned(Win.Id,8)); -- id proposé pour la fenêtre en création count:=Interf.S.IntState1; Writemem(count,interf,SysRam,wcreate_adr+1,w0); Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=14 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; count:=Interf.S.IntState1; if interf.I.ramsel='0' then WritePtr (wcreate_adr,count,SysRam); --écriture du pointeur d'instruction Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; end if; elsif NextCtx=15 then -- il faut mettre instruction_en à 1 SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; adresse:=stdlv(core_base_adr+1); SysRam.O.addr_rd<=adresse; SysRam.O.Addr_wr<=adresse; SysRam.O.Data_in<=x"01"; --instruction pulse enable via la mémoire; Writemem(count,interf,SysRam,adresse,x"01"); Interf.S.IntState1<=count; if count=0 then NextCtx:=NextCtx+1; end if; Interf.O.Instr_En<='1'; adresse:=stdlv(core_base_adr); SysRam.O.Addr_rd<=adresse; NextCtx:=NextCtx+1; elsif NextCtx=16 then --acquittement de la copie des données dans le tampon de la lib if Interf.I.Instr_ack='1' then Interf.O.Instr_En<='0'; NextCtx:=NextCtx+1; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif NextCtx=17 then -- lecture du résultat de l'instruction else end if; end procedure; --int MPI_Win_start( -- MPI_Group group, -- int assert, -- MPI_Win win --); procedure pMPI_Win_start( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; pgroup:MPI_group;asser : natural; Win :MPI_Win) is --cette fonction active les bits WStart pour chaque processus avec lequel -- la source veut communiquer et par la suite envoie un message de synchro sur le réseau à --chacune de ces cibles variable dcount : natural range 0 to 255:=0; variable cstatus : std_logic_vector(Word-1 downto 0); begin -- retour de l'adresse de de la fenêtre dans la structure Win -- initialisation des bits concernant if NextCtx =0 then NextCtx:=NextCtx+1; elsif NextCtx=1 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(core_base_adr+5,Adrlen)); SysRam.O.Data_in<=x"01"; --mise à 1 du bit WSTART et remise à zero de tous les autres Bits NextCtx:=NextCtx+1; Interf.O.membusy<='1'; Interf.S.GStart<=(others=>'0'); end if; elsif NextCtx=2 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(core_base_adr+5,Adrlen)); SysRam.O.Data_in<=x"01"; NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=3 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(core_base_adr+5,Adrlen)); SysRam.O.Data_in<=x"01"; NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=4 then NextCtx:=0; Interf.O.membusy<='0'; SysRam.O.we<='0'; SysRam.O.ena<='0'; end if; end procedure; procedure pMPI_Win_complete( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; Win :MPI_Win) is variable adresse :natural; variable wcount: natural range 0 to 255:=0; variable LRam : typ_dpRam; variable SyncDest,i : natural range 0 to 15; --destination du message de synchronisation variable W0 :std_logic_vector(Word-1 downto 0); variable wcompl_adr : std_logic_vector(adrlen-1 downto 0):=Std_logic_vector(to_unsigned(Core_wcompl_adr,ADRLEN)); begin -- wcompl_adr:=Std_logic_vector(to_unsigned(Core_wcompl_adr,ADRLEN)); LRam:=SysRam; -- nécessaire pour le débogage if NextCtx =0 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; Interf.O.MemBusy<='1'; --occuper la mémoire Interf.S.IntState1<=0; NextCtx:=1; adresse:=core_wcompl_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instr_En<='0'; Interf.O.Instruction<=x"00"; elsif NextCtx=1 then --écriture du ptr d'intruction SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; if interf.I.ramsel='0' then adresse:=core_wcompl_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instr_En<='0'; Interf.O.membusy<='1'; SysRam.O.we<='1'; SysRam.O.ena<='1'; wcount:=Interf.S.IntState1; WritePtr (wcompl_adr,wcount,SysRam); --attn cette fonction ne met pas à jour (we et ena) ! a voir Interf.S.IntState1<=wcount; if wcount =0 then NextCtx:=2; Interf.S.IntState1<=0; Interf.S.IntState2<=0; Interf.S.tmem(0)<=Interf.S.GStart(7 downto 0); --cibles impactées Interf.S.tmem(1)<=Interf.S.GStart(15 downto 8); --cibles impactées adresse:=core_wcompl_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); end if; else Interf.S.IntState1<=0; --recommencer l'écriture du pointeur end if; elsif NextCtx=2 then if Interf.I.Ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_wcompl_adr; NextCtx:=10; --aller à la fin de la fonction i:=0; l1:for i in 0 to 7 loop -- i:=i+1; if i>=interf.s.intState2 then if interf.s.gstart(i)='1' then SysRam.O.Data_in<=MPI_WIN_SYNC & std_logic_vector(to_unsigned(i,4)); Interf.S.tmem(2)<=MPI_WIN_SYNC & std_logic_vector(to_unsigned(i,4)); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.S.tmem(0)(i)<='0'; --ce dest a été traité ! NextCtx:=4; Interf.S.IntState2<=i+1; exit l1; end if; end if; exit l1 when i=7; end loop l1; end if; elsif NextCtx=3 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_wcompl_adr; wcount:=Interf.S.IntState1; WritePtr (wcompl_adr,wcount,SysRam); --attn cette fonction ne met pas à jour (we et ena) ! a voir Interf.S.IntState1<=wcount; SysRam.O.Data_in<= Interf.S.tmem(2); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); if wcount=0 then NextCtx:=NextCtx+1; end if; end if; elsif NextCtx=4 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_wcompl_adr+1; SysRam.O.Data_in<= x"04" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=NextCtx+1; elsif NextCtx=5 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_wcompl_adr+2; Interf.O.Instruction<=x"04";--longueur de l'instruction SysRam.O.Data_in<=x"00" ;-- SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=6; elsif NextCtx=6 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_wcompl_adr+3; SysRam.O.Data_in<= SYNC_WCOMP & std_logic_vector(to_unsigned(Interf.S.Rank,4)); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=7; elsif NextCtx=7 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; adresse:=core_wcompl_adr+3; SysRam.O.Data_in<=SYNC_WCOMP & std_logic_vector(to_unsigned(Interf.S.Rank,4)); SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=NextCtx+1; elsif NextCtx=8 then --fin de la fonction SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; --dcount:=0; Interf.O.membusy<='0'; Interf.O.Instr_En<='1'; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr+5,AdrLen)); NextCtx:=NextCtx+1; elsif NextCtx=9 then --acquittement de la copie des données dans le tampon if Interf.I.Instr_ack='1' then Interf.O.Instr_En<='0'; NextCtx:=10; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif NextCtx=10 then --lecture de la fin de WComplete SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; if interf.S.IntState2=0 then --aucune instruction MPI exécutée ? NextCtx:=12; elsif Interf.S.tmem(0)/=0 then --plus de message compl à envoyer NextCtx:=2; elsif Interf.S.tmem(0)=0 then if interf.I.ramsel='0' then NextCtx:=NextCtx+1; SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(core_base_adr+5,Adrlen)); end if; end if; elsif NextCtx=11 then --test de la fin des transferts if interf.I.ramsel='0' then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(core_base_adr+5,Adrlen)); if SysRam.I.Data_out(0)='1' and SysRam.I.Data_out(6)='0' then --si WStart=1 et Wbusy=0 --il faut un DSent=1 pour Put ou un DSending pour Get if SysRam.I.Data_out(5)='1' or (SysRam.I.Data_out(4)='1' and SysRam.I.Data_out(1)='1') then NextCtx:=NextCtx+1; end if; end if; end if; elsif NextCtx=12 then Interf.S.IntState1<=0; -- initialisation du compteur d'état Interf.S.IntState2<=0; SysRam.O.enb<='0'; NextCtx:=0; --fin de la fonction end if; end procedure; procedure pMPI_Win_post( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; pgroup:MPI_group;asser : natural; Win :MPI_Win) is --cette fonction active les bits WStart pour chaque processus avec lequel -- la source veut communiquer et par la suite envoie un message de synchro sur le réseau à --chacune de ces cibles variable W_Ptr : natural range 0 to 65535:=0;--adresse de la fenêtre en mémoire variable dcount : natural range 0 to 255:=0; variable cstatus : std_logic_vector(Word-1 downto 0); begin -- retour de l'adresse de de la fenêtre dans la structure Win -- initialisation des bits concernant if Win.id =0 then W_ptr:=Core_Base_Adr+4; end if; if NextCtx =0 then if pgroup.grp=0 then --rien à faire nextCtx:=5; Interf.S.GPost<=(others=>'0'); else NextCtx:=NextCtx+1; end if; Interf.O.Instruction<=x"00"; elsif NextCtx=1 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(W_ptr+W_status,Adrlen)); SysRam.O.Data_in<=x"48"; --mise à 1 du bit WPOST et WBusy et remise à zero de tous les autres Bits NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; --limitation de cete version à 16 rang Interf.S.GPost<=pgroup.grp; elsif NextCtx=2 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(W_ptr+W_status,Adrlen)); SysRam.O.Data_in<=x"48"; --mise à 1 du bit WPOST et WBusy et remise à zero de tous les autres Bits NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=3 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(W_Ptr+W_Gpost,Adrlen)); SysRam.O.Data_in<=pgroup.grp(7 downto 0); NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=4 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(W_ptr+W_Gpost+1,Adrlen)); SysRam.O.Data_in<=pgroup.grp(15 downto 8); NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=6 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; SysRam.O.addr_wr<=Std_logic_vector(to_unsigned(W_ptr+W_Gpost+1,Adrlen)); SysRam.O.Data_in<=pgroup.grp(15 downto 8); NextCtx:=NextCtx+1; Interf.O.membusy<='1'; end if; elsif NextCtx=5 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; NextCtx:=0; Interf.O.membusy<='0'; end if; end procedure; procedure pMPI_Win_wait( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; Win :MPI_Win) is --permet de synchroniser la fin des opérations sur une fenêtre variable dcount : natural range 0 to 255:=0; variable cstatus : std_logic_vector(Word-1 downto 0); variable W_Ptr : natural range 0 to 65535:=0;--adresse de la fenêtre en mémoire begin W_Ptr:=Core_base_adr+4;--adresse du reg status de la première fenêtre if NextCtx =0 then NextCtx:=NextCtx+1; elsif NextCtx=1 then if interf.I.ramsel='0' then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; NextCtx:=NextCtx+1; end if; SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(core_base_adr+4,Adrlen)); If Interf.S.Gpost=0 then NextCtx:=5; --rien à synchroniser end if; elsif (NextCtx>=2) and (NextCtx <=3) then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(W_ptr+W_status,Adrlen)); if interf.I.ramsel='0' then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; NextCtx:=NextCtx+1; else NextCtx:=1; end if; elsif NextCtx=4 then if interf.I.ramsel='0' then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(W_ptr+W_status,Adrlen)); if SysRam.I.Data_out(3)='1' and SysRam.I.Data_out(6)='0' then --si WPost=1 et WBusy=0 --il faut un DSent=1 pour Put ou un DSending pour Get if SysRam.I.Data_out(4)='1' or (SysRam.I.Data_out(5)='1' and SysRam.I.Data_out(2)='1') then NextCtx:=NextCtx+1; Interf.S.GPost<=(others=>'0'); end if; elsif SysRam.I.Data_out(3)='0' then NextCtx:=NextCtx; --pas d'opérations en attente else NextCtx:=NextCtx; --on attend end if; else NextCtx:=2; --retour à l'atente du Bit ! end if; elsif NextCtx=5 then SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; Interf.O.membusy<='0'; NextCtx:=0; end if; end procedure; Procedure pMPI_Finalize(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram) is begin end procedure; procedure pMPI_Comm_Spawn(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; command : natural; argv :natural; maxprocs : natural; info : natural; root : natural; comm : natural; signal intercomm :out natural; signal array_of_errcodes : out natural) is variable i,dcount : natural:=0; variable adresse :natural; variable spawn_adr : std_logic_vector(adrlen-1 downto 0):=Std_logic_vector(to_unsigned(Core_spawn_adr,ADRLEN)); begin spawn_adr:=Std_logic_vector(to_unsigned(Core_spawn_adr,ADRLEN)); if NextCtx =0 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.Instruction<=x"00"; NextCtx:=1; elsif NextCtx=1 then if interf.I.ramsel='0' then NextCtx:=2; adresse:=core_spawn_adr; SysRam.O.Data_in<=MPI_SPAWN & x"0" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.membusy<='1'; Interf.O.Instr_En<='0'; Interf.S.IntState2<=1; -- préparation de la destination du spawn end if; elsif NextCtx=2 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; if interf.I.ramsel='0' then NextCtx:=NextCtx+1; Interf.O.membusy<='1'; adresse:=core_spawn_adr; if interf.I.ismain='1' then ---déclanche l'éxécution de la commande SysRam.O.Data_in<=MPI_spawn & x"0";--Std_logic_vector(to_unsigned(Interf.S.IntState2+2,4)) ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); else -- envoie d'une commande spawn à la main lib SysRam.O.Data_in<=MPI_spawn & x"0" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instr_En<='0'; Interf.O.membusy<='1'; end if; end if; elsif NextCtx=3 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; adresse:=core_spawn_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=NextCtx+1; elsif NextCtx=4 then if interf.I.ramsel='0' then adresse:=core_spawn_adr+1; SysRam.O.Data_in<=std_logic_vector(to_unsigned(4,8)) ;--la longueur SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instruction<=x"04"; NextCtx:=NextCtx+1; end if; elsif NextCtx=5 then if interf.I.ramsel='0' then adresse:=core_spawn_adr+2; SysRam.O.Data_in<=std_logic_vector(to_unsigned(maxprocs,8)) ;--le nombre de processus SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=NextCtx+1; end if; elsif NextCtx=6 then if interf.I.ramsel='0' then adresse:=core_spawn_adr+3; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.Data_in<=SPAWN_LOAD & std_logic_vector(to_unsigned(maxprocs,4)) ;--l'instruction NextCtx:=NextCtx+1; end if; elsif NextCtx=7 then if interf.I.ramsel='0' then adresse:=core_spawn_adr+3; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.Data_in<=SPAWN_LOAD & std_logic_vector(to_unsigned(maxprocs,4)) ;--l'instruction NextCtx:=NextCtx+1; report "MPV SPAWN activé " & integer'image(interf.I.Rank); end if; elsif NextCtx=8 then if interf.I.ramsel='0' then adresse:=core_spawn_adr+7; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); SysRam.O.Data_in<=std_logic_vector(to_unsigned(0,Word)) ;--l'acquittement en retour NextCtx:=NextCtx+1; -- report "MPV SPAWN activé " & integer'image(interf.I.Rank); end if; elsif NextCtx=9 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; dcount:=Interf.S.IntState1; if interf.I.ramsel='0' then SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,ADRLEN)); WritePtr (spawn_adr,dcount,SysRam); Interf.O.Instr_En<='0'; Interf.O.membusy<='1'; Interf.S.IntState1<=dcount; if dcount =0 then NextCtx:=NextCtx+1; end if; end if; elsif NextCtx=10 then --fin de la fonction SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; dcount:=0; Interf.O.membusy<='0'; Interf.O.Instr_En<='1'; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,AdrLen)); NextCtx:=NextCtx+1; elsif NextCtx=11 then --acquittement de la copie des données dans le tampon if Interf.I.Instr_ack='1' then Interf.O.Instr_En<='0'; NextCtx:=NextCtx+1; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif NextCtx=12 then --lecture de la fin de l'initialisation SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse:=core_spawn_adr+7; SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(adresse,Adrlen)); if interf.I.ramsel='0' then NextCtx:=NextCtx+1; end if; elsif NextCtx=13 then --lecture de la fin de l'initialisation SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse:=core_spawn_adr+7; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(adresse,Adrlen)); if SysRam.I.Data_out(5)='1' then --spawned NextCtx:=NextCtx+1; intercomm<=1; end if; Interf.O.membusy<='0'; else NextCtx:=12; end if; elsif NextCtx=14 then --lecture de la fin de l'initialisation SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse:=core_spawn_adr+8; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(adresse,Adrlen)); Intercomm<=conv_integer(SysRam.I.Data_out);-- le groupe des Ht Fils NextCtx:=NextCtx+1; end if; Interf.O.membusy<='0'; elsif NextCtx=15 then --lecture de la fin de l'initialisation SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; adresse:=core_spawn_adr+8; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(adresse,Adrlen)); Intercomm<=conv_integer(SysRam.I.Data_out);-- le groupe des Ht Fils NextCtx:=NextCtx+1; end if; Interf.O.membusy<='0'; elsif NextCtx =16 then Interf.O.Instr_En<='0'; Interf.O.membusy<='0'; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; NextCtx:=0; --array_of_errcodes<=0; end if; array_of_errcodes<=NextCtx; end procedure; procedure pMPI_INIT(NextCtx : inout natural;signal Interf:inout Core_io;signal clkin:std_logic;signal SysRam :inout typ_dpram) is variable i,dcount,wcount : natural range 0 to 255:=0; variable adresse :natural; variable LRam : typ_dpRam; variable W0 :std_logic_vector(Word-1 downto 0); variable init_adr : std_logic_vector(adrlen-1 downto 0):=Std_logic_vector(to_unsigned(Core_init_adr,ADRLEN)); begin init_adr:=Std_logic_vector(to_unsigned(Core_init_adr,ADRLEN)); LRam:=SysRam; -- nécessaire pour le débogage if NextCtx =0 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.S.IntState1<=0; Interf.O.Instruction<=x"00"; NextCtx:=1; adresse:=core_init_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instr_En<='0'; elsif NextCtx=1 then --écriture du ptr d'intruction SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; if interf.I.ramsel='0' then adresse:=core_init_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.O.Instr_En<='0'; Interf.O.membusy<='1'; wcount:=Interf.S.IntState1; WritePtr (Init_adr,wcount,SysRam); Interf.S.IntState1<=wcount; if wcount =0 then NextCtx:=2; Interf.S.IntState1<=0; adresse:=core_init_adr; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); end if; end if; elsif NextCtx=2 then if interf.I.ramsel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; adresse:=core_init_adr; SysRam.O.Data_in<=MPI_INIT & x"0" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=3; Interf.O.membusy<='1'; end if; elsif NextCtx=3 then if Interf.I.ramSel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_init_adr+1; SysRam.O.Data_in<= x"04" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=NextCtx+1; end if; elsif NextCtx=4 then if Interf.I.ramSel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; Interf.O.membusy<='1'; SysRam.O.enb<='0'; adresse:=core_init_adr+1; Interf.O.Instruction<=x"04"; SysRam.O.Data_in<=x"04" ;--longueur de l'instruction SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=5; end if; elsif NextCtx=5 then if Interf.I.ramSel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; Interf.O.membusy<='1'; SysRam.O.enb<='0'; adresse:=core_init_adr+2; SysRam.O.Data_in<= x"00" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=6; end if; elsif NextCtx=6 then if Interf.I.ramSel='0' then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='0'; Interf.O.membusy<='1'; adresse:=core_init_adr+3; SysRam.O.Data_in<=x"00" ; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=7; end if; elsif NextCtx=7 then --fin de la fonction SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; Interf.O.membusy<='0'; dcount:=0; Interf.O.membusy<='0'; Interf.O.Instruction(6)<=Interf.I.Spawned; --- préciser que la HT est dynamique Interf.O.Instr_En<='1'; SysRam.O.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,AdrLen)); NextCtx:=8; elsif NextCtx=8 then --acquittement de la copie des données dans le tampon if Interf.I.Instr_ack='1' then Interf.O.Instr_En<='0'; NextCtx:=9; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif NextCtx=9 then --lecture de la fin de l'initialisation SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; if interf.I.ramsel='0' then SysRam.O.addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,Adrlen)); if SysRam.I.Data_out(4)='1' then NextCtx:=10; Interf.S.IntState1<=0; -- initialisation du compteur d'état end if; Interf.O.membusy<='0'; end if; elsif NextCtx =10 then dcount:=Interf.S.IntState1; --permet de sauvegarder l'état interne du compteur readmem(dcount,interf,sysRam,init_Adr,w0); Interf.S.IntState1<=dcount; w0:=SysRam.I.Data_out; if dcount=0 then Interf.I.ismain<=all_zeros(SysRam.I.Data_out(3 downto 0));--Rank=0 -> MainLib NextCtx:=NextCtx+1; end if; elsif NextCtx =11 then Interf.O.Instruction<=x"00"; Interf.O.Instr_En<='0'; Interf.O.membusy<='0'; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='0'; NextCtx:=0; end if; end procedure; procedure WriteMem(NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; AdrVect:in std_logic_vector; Data:in std_logic_vector) is --cette procédure permet d'écrire un mot dans la mémoire du PE(tâche matérielle) --en ayant vérifié que le bus est bien disponible pour l'écriture variable i,dcount : natural:=0; variable adresse :natural; variable AdrToSet :std_logic_vector(AdrVect'length-1 downto 0):=AdrVect; begin if NextCtx /=0 then --préserver la valeur de count entre les appels dcount:=NextCtx; else end if; if dcount=0 then --if interf.I.ramsel='0' then dcount :=dcount+1; --Interf.O.membusy<='1'; --end if; SysRam.O.Data_in<=AdrToSet(Word-1 downto 0); SysRam.O.Addr_wr<=adrToSet; elsif dcount=1 then if interf.I.ramsel='0' then Interf.O.membusy<='1'; dcount :=dcount+1; end if; SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; SysRam.O.Data_in<=data; SysRam.O.Addr_wr<=adrToSet; elsif dcount=2 then SysRam.O.we<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; SysRam.O.Data_in<=data; dcount :=dcount+1; SysRam.O.Addr_wr<=AdrToSet; elsif dcount=3 then Interf.O.membusy<='1'; dcount :=dcount+1; SysRam.O.Addr_wr<=adrToSet; SysRam.O.Data_in<=data; elsif dcount=4 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=0; Interf.O.membusy<='0'; SysRam.O.Addr_wr<=AdrToSet; end if; NextCtx:=dcount; end procedure; -- écriture dans la mémoire procedure ReadMem( NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; AdrVect:in std_logic_vector; data: out std_logic_vector) is --cette procédure permet d'écrire un mot dans la mémoire du PE(tâche matérielle) --en ayant vérifié que le bus est bien disponible pour l'écriture variable i,dcount : natural:=0; variable adresse :natural; variable AdrToSet :std_logic_vector(AdrVect'length-1 downto 0):=AdrVect; begin if NextCtx /=0 then --préserver la valeur de count entre les appels dcount:=NextCtx; else end if; if dcount=0 then --if interf.I.ramsel='0' then dcount :=dcount+1; -- Interf.O.membusy<='1'; --end if; SysRam.O.Addr_rd<=adrToSet; elsif dcount=1 then if interf.I.ramsel='0' then dcount :=dcount+1; Interf.O.membusy<='0'; end if; data:=SysRam.I.Data_out; SysRam.O.Addr_rd<=adrToSet; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif dcount=2 then if interf.I.ramsel='0' then data:=SysRam.I.Data_out; dcount :=dcount+1; else dcount:=2; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; SysRam.O.Addr_rd<=adrToSet; elsif dcount=3 then if interf.I.ramsel='0' then dcount :=dcount+1; SysRam.O.Addr_rd<=adrToSet; data:=SysRam.I.Data_out; Interf.O.membusy<='0'; else dcount:=2; end if; SysRam.O.we<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; elsif dcount=4 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=0; Interf.O.membusy<='0'; data:=SysRam.I.Data_out; end if; data:=SysRam.I.Data_out; NextCtx:=dcount; end procedure; procedure SetBit( NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; variable AdrVect:in std_logic_vector(ADrLen-1 downto 0); variable BitMask: in std_logic_vector(Word-1 downto 0);bitval:in std_logic) is --cette procédure permet de mettre à jour un Bit un mot dans la mémoire du PE(tâche matérielle) --en ayant vérifié que le bus est bien disponible pour l'écriture variable i,dcount : natural:=0; variable adresse :natural; variable tempdata:std_logic_vector(Word-1 downto 0); begin if NextCtx /=0 then --préserver la valeur de count entre les appels dcount:=NextCtx; else end if; if dcount=0 then if interf.I.ramsel='0' then dcount :=dcount+1; Interf.O.membusy<='1'; end if; SysRam.O.Addr_rd<=adrVect; SysRam.O.Addr_Wr<=adrVect; elsif dcount=1 then if interf.I.ramsel='0' then tempdata:=SysRam.I.Data_out; dcount :=dcount+1; SysRam.O.Addr_rd<=adrVect; end if; SysRam.O.enb<='1'; SySRam.O.ena<='0'; SysRam.O.we<='0'; elsif dcount=2 then tempdata:=SysRam.I.Data_out; dcount :=dcount+1; SysRam.O.Addr_rd<=adrVect; SysRam.O.enb<='1'; SySRam.O.ena<='0'; SysRam.O.we<='0'; elsif dcount=3 then if interf.I.ramsel='0' then dcount :=dcount+1; SysRam.O.Addr_Wr<=adrVect; SysRam.O.We<='0'; SysRam.O.ena<='0'; SysRam.O.enb<='1'; tempdata:=SysRam.I.Data_out; Interf.O.membusy<='1'; end if; elsif dcount=4 then if interf.I.ramsel='0' then dcount :=dcount+1; SysRam.O.Addr_Wr<=adrVect; SysRam.O.We<='1'; SysRam.O.ena<='1'; SysRam.O.enb<='1'; tempdata:=SysRam.I.Data_out; if BitVal='1' then TempData:=Tempdata or BitMask; else TempData:=TempData and not (BitMAsk); end if; SysRam.O.Data_in<=TempData; Interf.O.membusy<='1'; end if; elsif dcount=5 then --attente d'écriture if interf.I.ramsel='0' then dcount :=dcount+1; SysRam.O.Addr_rd<=adrVect; SysRam.O.We<='1'; SysRam.O.ena<='1'; --SysRam.O.Data_in<=TempData; Interf.O.membusy<='1'; end if; elsif dcount=6 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=0; Interf.O.membusy<='0'; SysRam.O.We<='0'; SysRam.O.ena<='0'; end if; NextCtx:=dcount; end procedure; procedure WritePtr(AdrVect:in std_logic_vector; count: inout natural;signal SysRam :out typ_dpram) is --cette procédure permet d'écrire dans la mémoire du PE(tâche matérielle) --les données de l'appel de la procédure variable i,dcount : natural:=0; variable adresse :natural; variable AdrToSet :std_logic_vector(AdrVect'length-1 downto 0):=AdrVect; begin if count /=0 then --préserver la valeur de count entre les appels dcount:=count; else end if; adresse:=Core_base_adr+2; AdrToSet:=AdrVect; if dcount=0 then SysRam.O.Data_in<=AdrToSet(Word-1 downto 0); dcount :=dcount+1; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=1 then SysRam.O.Data_in<=AdrToSet(Word-1 downto 0); SysRam.O.We<='1';SysRam.O.Ena<='1'; dcount :=dcount+1; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=2 then SysRam.O.We<='1';SysRam.O.Ena<='1'; SysRam.O.Data_in<=AdrToSet(ADRLEN-1 downto Word); dcount :=dcount+1; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); SysRam.O.Data_in<=AdrToSet(ADRLEN-1 downto Word); elsif dcount=3 then dcount :=dcount+1; SysRam.O.We<='1';SysRam.O.Ena<='1'; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); SysRam.O.Data_in<=AdrToSet(ADRLEN-1 downto Word); elsif dcount=4 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=0; SysRam.O.We<='0';SysRam.O.Ena<='0'; SysRam.O.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); end if; count:=dcount; end procedure; --int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr) procedure MPI_Alloc_mem(NextCtx : inout natural range 0 to 255;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; SIZE : natural; MPI_INFO: natural; baseptr: out std_logic_vector(ADRLEN-1 downto 0)) is begin --baseptr:=std_logic_vector(unsigned(Interf.S.HeapPtr,ADRLEN)); -- -- Interf.S.HeapPtr<=Interf.S.HeapPtr+SIZE; baseptr:=(others=>'1'); end procedure; end MPI_Rma;