-- 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 ); -- declare functions and procedure procedure ReadMem(NextCtx : inout natural;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;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; AdrVect:in std_logic_vector; Data:in std_logic_vector); 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 : 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:=Std_logic_vector(to_unsigned(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 and dcount <=3 then if interf.ramsel='0' then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; WritePtr (put_adr,dcount,SysRam); if dcount =4 then -- fin de l'écriture du pointeur en mémoire end if; end if; elsif dcount=4 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; adresse:=core_put_adr; sysRam.Data_in<=MPI_PUT & std_logic_vector(to_unsigned(Target_Rank,4)); --code fonction sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=5 then adresse:=core_put_adr+1; sysRam.Data_in<=std_logic_vector(to_unsigned(Orig_Count,8)) ;--la longueur sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=6 then adresse:=core_put_adr+2; sysRam.Data_in<= Addr1(ADRLEN-1 downto Word) ; --source Haut sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=7 then adresse:=core_put_adr+3; sysRam.Data_in<=Addr1(Word-1 downto 0); --source Bas sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=8 then adresse:=core_put_adr+4; sysRam.Data_in<= Addr2(ADRLEN-1 downto Word) ; -- destination haut sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=9 then adresse:=core_put_adr+5; sysRam.Data_in<=Addr2(Word-1 downto 0); -- destination bas sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; elsif dcount=10 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='1'; adresse:=core_base_adr+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); sysRam.Data_in<=x"01"; --instruction pulse enable via la mémoire; Interf.Instr_En<='1'; --active la prise en compte de l'instruction dcount:=dcount+1; elsif dcount=11 then if Interf.Instr_ack='1' then -- le Core a reçu l'instruction ? Interf.Instr_En<='0'; --désactiver la prise en compte de l'instruction dcount:=dcount+1; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; end if; adresse:=core_base_adr+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); SysRam.addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); --SysRam.Ram_busy<='0'; --?? SysRam.we<='0'; SysRam.ena<='0'; -- préparer la lecture du résultat du Put SysRam.enb<='1'; elsif dcount=12 then adresse:=core_base_adr+1; SysRam.we<='1'; SysRam.ena<='1'; -- préparer l'écriture du résultat du Put SysRam.enb<='1'; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=13 then SysRam.we<='1'; SysRam.ena<='1'; -- préparer l'écriture du résultat du Put SysRam.enb<='0'; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; adresse:=core_base_adr+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=14 then SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; if Interf.RamSel='0' then SysRam.addr_rd<=Std_logic_vector(to_unsigned(Core_put_adr+6,Adrlen)); if SysRam.Data_out(0)='1' then --fin du MPI PUT ici pour l'envoie ! dcount:=dcount+1; end if; end if; elsif dcount=15 then dcount:=0; --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,dcount : 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 get_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 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 and dcount <=3 then if interf.ramsel='0' then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; WritePtr (get_adr,dcount,SysRam); if dcount =4 then -- fin de l'écriture du pointeur en mémoire end if; end if; elsif dcount=4 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; adresse:=core_get_adr; sysRam.Data_in<=MPI_GET & std_logic_vector(to_unsigned(Target_Rank,4)); --code fonction sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=5 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; adresse:=core_get_adr+1; sysRam.Data_in<=std_logic_vector(to_unsigned(Orig_Count,8)) ;--la longueur sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=6 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; adresse:=core_get_adr+2; sysRam.Data_in<= Addr1(ADRLEN-1 downto Word) ; --source Haut sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=7 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; adresse:=core_get_adr+3; sysRam.Data_in<=Addr1(Word-1 downto 0); --source Bas sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=8 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; adresse:=core_get_adr+4; sysRam.Data_in<= Addr2(ADRLEN-1 downto Word) ; -- destination haut sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=9 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; adresse:=core_get_adr+5; sysRam.Data_in<=Addr2(Word-1 downto 0); -- destination bas sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); dcount:=dcount+1; end if; elsif dcount=10 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='1'; adresse:=core_base_adr+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); sysRam.Data_in<=x"01"; --instruction pulse enable via la mémoire; Interf.Instr_En<='1'; --active la prise en compte de l'instruction dcount:=dcount+1; end if; elsif dcount=11 then if Interf.Instr_ack='1' then -- le Core a reçu l'instruction ? Interf.Instr_En<='0'; --désactiver la prise en compte de l'instruction dcount:=dcount+1; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; end if; adresse:=core_base_adr+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); SysRam.addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); --SysRam.Ram_busy<='0'; --?? SysRam.we<='0'; SysRam.ena<='0'; -- préparer la lecture du résultat du get SysRam.enb<='1'; elsif dcount=12 then if Interf.RamSel='0' then adresse:=core_base_adr+1; SysRam.we<='1'; SysRam.ena<='1'; -- préparer l'écriture du résultat du get SysRam.enb<='1'; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; SysRam.addr_rd<=std_logic_vector(to_unsigned(core_base_adr+1,ADRLEN)); sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); end if; elsif dcount=13 then if Interf.RamSel='0' then SysRam.we<='1'; SysRam.ena<='1'; -- préparer l'écriture du résultat du GET SysRam.enb<='0'; config_reg:=SysRam.data_out and x"f6"; SysRam.Data_in<=config_reg ; --ramener le IPulse à 0; dcount:=dcount+1; adresse:=core_base_adr+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); end if; elsif dcount=14 then SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; if Interf.RamSel='0' then SysRam.addr_rd<=Std_logic_vector(to_unsigned(Core_get_adr+6,Adrlen)); if SysRam.Data_out(0)='1' then --fin du MPI get ici pour l'envoie ! dcount:=dcount+1; end if; end if; elsif dcount=15 then dcount:=0; --fin normale de la fonction 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.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; sysRam.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if Interf.Ramsel='0' then NextCtx:=1; end if; elsif NextCtx=1 then SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; sysRam.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if Interf.Ramsel='0' then Rank<=SysRam.Data_out(3 downto 0); NextCtx:=2; end if; elsif NextCtx=2 then SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; sysRam.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if Interf.Ramsel='0' then Rank<=SysRam.Data_out(3 downto 0); NextCtx:=3; end if; elsif NextCtx=3 then SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; adresse_rd:=CORE_INIT_ADR+1; sysRam.Addr_rd<=Std_logic_vector(to_unsigned(adresse_rd,ADRLEN)); if interf.ramsel='0' then Rank<=SysRam.Data_out(3 downto 0); NextCtx:=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.Intstate1<=count; elsif NextCtx>=1 and NextCtx <= 4 then count:=Interf.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.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.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.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.winid<=interf.winid+1; count:=Interf.intstate1; Writemem(count,interf,SysRam,AdrWin+1,stdlv(interf.winid,8)); --win id de la fenêtre Interf.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.intstate1; Writemem(count,interf,SysRam,AdrWin+2,base(7 downto 0)); --adresse basse Interf.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.intstate1; Writemem(count,interf,SysRam,AdrWin+3,base(15 downto 8)); --adresse haute Interf.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.intstate1; Writemem(count,interf,SysRam,AdrWin+4,sizewin); -- taille de la fenêtre Interf.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_WINCREATE & std_logic_vector(to_unsigned(0,4)); --code fonction count:=Interf.intstate1; Writemem(count,interf,SysRam,wcreate_adr,w0); Interf.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.intstate1; Writemem(count,interf,SysRam,wcreate_adr+1,w0); Interf.intstate1<=count; if count=0 then NextCtx:=NextCtx+1; end if; elsif NextCtx=14 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; count:=Interf.intstate1; if interf.Ramsel='0' then WritePtr (wcreate_adr,count,SysRam); --écriture du pointeur d'instruction Interf.intstate1<=count; if count=0 then NextCtx:=NextCtx+1; end if; end if; elsif NextCtx=15 then -- il faut mettre instruction_en à 1 SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='1'; adresse:=stdlv(core_base_adr+1); SysRam.addr_rd<=adresse; sysRam.Addr_wr<=adresse; sysRam.Data_in<=x"01"; --instruction pulse enable via la mémoire; Writemem(count,interf,SysRam,adresse,x"01"); Interf.intstate1<=count; if count=0 then NextCtx:=NextCtx+1; end if; Interf.Instr_En<='1'; adresse:=stdlv(core_base_adr); sysRam.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.Instr_ack='1' then Interf.Instr_En<='0'; NextCtx:=NextCtx+1; end if; SysRam.we<='0'; SysRam.ena<='0'; SysRam.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 begin -- retour de l'adresse de de la fenêtre dans la structure Win -- initialisation des bits concernant end procedure; procedure pMPI_Win_complete( NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram; Win :MPI_Win) is begin 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 begin 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 begin end procedure; Procedure pMPI_Finalize(NextCtx : inout natural;signal Interf:inout Core_io;signal SysRam :inout typ_dpram) is begin 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 : natural:=0; variable adresse :natural; 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)); if NextCtx =0 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; if interf.ramsel='0' then NextCtx:=1; adresse:=core_init_adr; sysRam.Data_in<=MPI_INIT & x"0" ; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.Instr_En<='0'; end if; elsif NextCtx=1 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; if interf.ramsel='0' then NextCtx:=2; adresse:=core_init_adr; sysRam.Data_in<=MPI_INIT & x"0" ; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); Interf.Instr_En<='0'; end if; elsif NextCtx=2 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; sysRam.Data_in<=MPI_INIT & x"0" ; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); NextCtx:=3; elsif NextCtx=3 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='0'; dcount:=1; if interf.ramsel='0' then sysRam.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,ADRLEN)); WritePtr (init_adr,dcount,SysRam); Interf.Instr_En<='0'; --if dcount =0 then NextCtx:=4; --end if; end if; elsif NextCtx>=4 and NextCtx<=7 then SysRam.we<='1'; SysRam.ena<='1'; SysRam.enb<='1'; if interf.ramsel='0' then dcount:=NextCtx-3; WritePtr (init_adr,dcount,SysRam); NextCtx:=NextCtx+1; if dcount =4 then NextCtx:=8; end if; end if; elsif NextCtx=8 then --fin de la fonction SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; dcount:=0; Interf.Instr_En<='1'; sysRam.Addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,AdrLen)); NextCtx:=9; elsif NextCtx=9 then --acquittement de la copie des données dans le tampon if Interf.Instr_ack='1' then Interf.Instr_En<='0'; NextCtx:=10; end if; SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; elsif NextCtx=10 then --lecture de la fin de l'initialisation SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='1'; if Interf.RamSel='0' then SysRam.addr_rd<=Std_logic_vector(to_unsigned(Core_base_adr,Adrlen)); if SysRam.Data_out(4)='1' then NextCtx:=11; end if; end if; elsif NextCtx =11 then Interf.Instr_En<='0'; SysRam.we<='0'; SysRam.ena<='0'; SysRam.enb<='0'; NextCtx:=0; end if; end procedure; procedure WriteMem(NextCtx : inout natural;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.RamSel='0' then dcount :=dcount+1; end if; sysRam.Data_in<=AdrToSet(Word-1 downto 0); sysRam.Addr_wr<=adrToSet; elsif dcount=1 then if Interf.RamSel='0' then dcount :=dcount+1; end if; sysRam.Data_in<=data; sysRam.Addr_wr<=adrToSet; elsif dcount=2 then sysRam.Data_in<=data; dcount :=dcount+1; sysRam.Addr_wr<=AdrToSet; elsif dcount=3 then dcount :=dcount+1; sysRam.Addr_wr<=adrToSet; sysRam.Data_in<=data; elsif dcount=4 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=0; sysRam.Addr_wr<=AdrToSet; end if; NextCtx:=dcount; end procedure; -- écriture dans la mémoire procedure ReadMem(NextCtx : inout natural;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.RamSel='0' then dcount :=dcount+1; end if; sysRam.Addr_rd<=adrToSet; elsif dcount=1 then data:=sysRam.Data_out; dcount :=dcount+1; sysRam.Addr_rd<=adrToSet; elsif dcount=2 then data:=sysRam.Data_out; dcount :=dcount+1; sysRam.Addr_rd<=adrToSet; elsif dcount=3 then if Interf.RamSel='0' then dcount :=dcount+1; sysRam.Addr_rd<=adrToSet; data:=sysRam.Data_out; end if; elsif dcount=4 then -- ce cycle permet juste de vider le tampon d'écriture en RAM dcount:=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; if dcount=0 then sysRam.Data_in<=AdrToSet(Word-1 downto 0); dcount :=dcount+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=1 then sysRam.Data_in<=AdrToSet(Word-1 downto 0); dcount :=dcount+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse,ADRLEN)); elsif dcount=2 then sysRam.Data_in<=AdrToSet(ADRLEN-1 downto Word); dcount :=dcount+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); elsif dcount=3 then dcount :=dcount+1; sysRam.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); sysRam.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.Addr_wr<=Std_logic_vector(to_unsigned(adresse+1,ADRLEN)); end if; count:=dcount; end procedure; end MPI_Rma;