---------------------------------------------------------------------------------- -- Company: -- Engineer:GAMOM /KIEGAING -- -- Create Date: 08:12:29 06/16/2011 -- Design Name: -- Module Name: EX1_FSM - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: Ce module est chargé de recevoir les instructions du programme MPI et -- de les exécuter (PUT) il coopère avec EX2 qui reçoit les instructions venant du NoC -- (GET) -- -- Dependencies: -- -- Revision: 09/07/2012 -- Revision 0.03 - File updated -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; --use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library NocLib ; use Work.Packet_type.ALL; USE ieee.numeric_std.ALL; use NocLib.CoreTypes.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity EX1_FSM is -- parametres generiques du module : Port ( --instruction_available : in STD_LOGIC; clk : in STD_LOGIC; reset : in STD_LOGIC; instruction : in std_logic_vector(Word-1 downto 0); instruction_en : in std_logic:='0'; -- active le module instruction pid : in std_logic_vector(3 downto 0) ; -- id du processeur nprocs : in std_logic_vector(3 downto 0);-- nombre de processeur du MPSOC - 1 Result : out STD_LOGIC_VECTOR (7 downto 0):=(others=>'0'); -- le résultat de l'exécution de ce module Ready : out std_logic; --indique la fin de l'éxécution d'une instruction AppInitReq :out STD_LOGIC:='0'; -- requête d'initialisation de l'application AppInitAck :in STD_LOGIC; -- Acquitement d'initialisation Initialized:in std_logic ; -- état de la Lib -- Accès au Fifo d'instructions priority_rotation : out STD_LOGIC:='0'; fifo_rd_en : out STD_LOGIC:='0'; fifo_empty : in STD_LOGIC; fifo_data_out : in STD_LOGIC_VECTOR (7 downto 0); fifo_src : in STD_LOGIC; --permet de désigner le fifo qui est en service Snd_Data : IN Typ_PortIO(0 to 3); Snd_Start : IN std_logic; Snd_Ack : OUT std_logic; -- Accès au réseau sur puce switch_port_in_full : in std_logic; switch_port_in_data : out STD_LOGIC_VECTOR (7 downto 0):=(others=>'0'); switch_port_in_wr_en : out STD_LOGIC:='0'; -- Accès à la mémoire RAM du PE ram_data_in : in std_logic_vector(7 downto 0); ram_data_out : out std_logic_vector(7 downto 0):=(others=>'0'); ram_rd,ram_wr : out std_logic:='0'; ram_address : out std_logic_vector(15 downto 0):=(others=>'0'); dma_wr_request : OUT std_logic:='0'; dma_rd_request : OUT std_logic:='0'; dma_wr_grant : in STD_LOGIC; dma_rd_grant : in STD_LOGIC); end EX1_FSM; architecture Behavioral of EX1_FSM is component proto_send is generic (sizemem : natural := 64); port ( clk,reset : in std_logic; fifo_in_empty,fifo_in_full : in std_logic; --signaux pour le fifo d'entrée fifo_out_empty,fifo_out_full : in std_logic; --signaux pour le fifo de sortie fifo_out_wr_en : out std_logic:='0'; --écriture autorisée dans la fifo de sortie fifo_in_rd_en : out std_logic:='0'; --lecture autorisée dans la fifo d'entrée fifo_in_data_out : in std_logic_vector(Word-1 downto 0); fifo_out_data_in : out std_logic_vector(Word-1 downto 0); packet_len : in std_logic_vector(Word-1 downto 0); --la longueur du paquet copy_mode : in std_logic; --Fifo_to_mem ou Fifo_to_fifo snd_start : in std_logic; --début de la réception snd_ack :in std_logic; -- acquittement de la réception snd_comp : out std_logic; -- fin de la réception mem :in memory(0 to sizemem-1)); --données à copier vers le fifo end component proto_send; -- definition du type etat pour le codage des etats des fsm type fsm_states is (fifo_select, fetch_packet_type, decode_packet_type, fetch_addresses, decode_packet_type2, read_status1,read_status2,ex1_barrier1, ex1_barrier2, ex1_barrier3, ex1_barrier4, ex1_get1, ex1_get2,ex1_get3,ex1_get4, ex1_put1, ex1_put2, ex1_put3, ex1_put4,ex1_put5, ex1_init1,ex1_init_run,ex1_init2,ex1_init3,ex1_spawn,ex1_ready,ex1_send_ack,ex1_Wsync); -- machine a etat du module signal ex1_state,Next_Ex1_state : fsm_states; -- les variables utilisées dans la fsm signal snd_start1,snd_start_sync,snd_comp,snd_ack1,push:std_logic:='0'; signal mem : memory(0 to 3); signal data_to_send,noc_fifo_in : std_logic_vector(Word-1 downto 0); signal packet_type : std_logic_vector(3 downto 0); --signal dpid : std_logic_vector(3 downto 0); signal pid_counter : std_logic_vector(3 downto 0); signal p_len,p_len_i: std_logic_vector(Word-1 downto 0); signal src_address,src_address_i : std_logic_vector(ADRLEN-1 downto 0); signal dma_rd,dma_wr,Wr_ok,rd_ok:std_logic:='0'; --signal res_address : std_logic_vector(15 downto 0); signal dest_address : std_logic_vector(ADRLEN-1 downto 0); signal n,n_i : natural range 0 to 15; signal len,len_i : natural range 0 to 255; signal fifo_rd,fifo_wr,fifo_copy:std_logic:='0'; signal fifo_sel:std_logic:='0'; signal run_init:std_logic:='0'; begin -- connection des signaux avec les ports ram_address <= src_address; sw_send: proto_send generic map (sizemem=>4) port map ( clk=>clk, reset=>reset, fifo_in_empty=>fifo_empty, fifo_in_full=>'0',--pas utilisé fifo_out_empty=>'0', packet_len=>p_len, copy_mode=>fifo_copy, fifo_out_full => switch_port_in_full, fifo_in_rd_en=>fifo_rd, fifo_in_data_out=>fifo_data_out, fifo_out_wr_en =>fifo_wr, fifo_out_data_in =>noc_fifo_in, snd_start =>snd_start_sync, snd_ack =>snd_ack1, snd_comp=>snd_comp, mem =>mem ); ex1_fsm_sync:process(clk) begin if rising_edge(clk) then if reset = '1' then ex1_state <= fifo_select; n<=0; len<=0; p_len<=(others=>'0'); snd_ack<='0'; src_address<=(others=>'0'); else ex1_state<=next_ex1_state; n<=n_i; len<=len_i; p_len<=p_len_i; src_address <= src_address_i; snd_ack<=snd_ack1; --acquittement de l'envoie des données pour EX4 snd_start_sync<=snd_start1; end if; end if; end process ex1_fsm_sync; -- processus de transistion entre les etats fsm_nst_logic : process(ex1_state,n,instruction_en,fifo_empty,fifo_data_out, switch_port_in_full,pid, pid_counter,len,p_len,snd_start,snd_comp, ram_data_in,dma_rd_grant,dma_wr_grant,AppInitAck,src_address) variable tempval : std_logic_vector(Word-1 downto 0); variable onepop,fifo_vide : std_logic:='0'; --indique que le fifo a été dépilé begin n_i<=n; --valeur par défaut Next_ex1_state <=Ex1_state; case ex1_state is when fifo_select => if instruction_en='1' and fifo_empty ='0' then Next_ex1_state <= fetch_packet_type; else Next_ex1_state <= fifo_select; end if; rd_ok<='0'; wr_ok<='0'; if instruction_en='1' and snd_start='1' then run_init<='1'; Next_ex1_state<=ex1_init_run; end if; --lecture du registre status de la mib MPI when read_status1 => if dma_rd_grant = '1' then -- fin du mpi_put Next_ex1_state <= read_status2; else Next_ex1_state <= read_status1; end if; src_address_i<=std_logic_vector(to_unsigned(core_base_adr,16)); when read_status2 => Next_ex1_state <= fifo_select; when fetch_packet_type => rd_ok<='0'; if fifo_empty ='1' then Next_ex1_state <= fifo_select; else packet_type <= fifo_data_out(7 downto 4); data_to_send <= fifo_data_out; Next_ex1_state <= decode_packet_type; rd_ok<='1'; end if; when decode_packet_type => rd_ok<='0'; if fifo_empty='0' then if packet_type = MPI_PUT then p_len_i <= fifo_data_out + 4; n_i <= 0;rd_ok<='1'; Next_ex1_state <= fetch_addresses; elsif packet_type = MPI_GET then len_i <= to_integer(unsigned(fifo_data_out)); p_len_i <= fifo_data_out; n_i <= 0; rd_ok<='1'; Next_ex1_state <= fetch_addresses; elsif packet_type = MPI_BARRIER_REACHED or packet_type = MPI_BARRIER_COMPLETED then p_len_i <= "00000011"; -- = 3 pid_counter <= "0000"; rd_ok<='1'; Next_ex1_state <= ex1_barrier1; elsif packet_type = MPI_INIT then Next_ex1_state<=ex1_init1; len_i <= to_integer(unsigned(fifo_data_out)); p_len_i<=fifo_data_out; n_i<=0;rd_ok<='1'; elsif packet_type = MPI_ACK then len_i <= to_integer(unsigned(fifo_data_out)); p_len_i<=fifo_data_out; n_i <= 0; rd_ok<='0'; Next_ex1_state <= ex1_send_Ack; elsif packet_type = MPI_WIN_SYNC then len_i <= to_integer(unsigned(fifo_data_out)); p_len_i<=fifo_data_out; n_i <= 0; rd_ok<='0'; Next_ex1_state <= ex1_WSynC; elsif packet_type = MPI_SPAWN then Next_ex1_state<=ex1_SPAWN; len_i <= to_integer(unsigned(fifo_data_out)); p_len_i<=fifo_data_out; onepop:='1';--il y a une donnée lue src_address_i<=std_logic_vector(to_unsigned(Core_spawn_adr+1,16)); rd_ok<='0'; else -- packet non reconnu --synthesis translate_off report "Ex1 : ATTENTION paquet non reconnu !!!!!!!!!" ; --synthesis translate_on if fifo_empty = '1' then Next_ex1_state <= fifo_select; else rd_ok<='1'; packet_type <= fifo_data_out(7 downto 4); --lire le prochain paquet data_to_send <= fifo_data_out; Next_ex1_state <= decode_packet_type;-- pas necessaire mais plus sure end if; end if; end if; when fetch_addresses => n_i<=n;rd_ok<='1'; if fifo_empty = '0' and n = 0 then src_address_i(15 downto 8) <= fifo_data_out; n_i <= n + 1; Next_ex1_state <= fetch_addresses; elsif fifo_empty = '0' and n = 1 then src_address_i(7 downto 0) <= fifo_data_out; n_i <= n + 1; Next_ex1_state <= fetch_addresses; elsif fifo_empty = '0' and n = 2 then dest_address(15 downto 8) <= fifo_data_out; n_i <= n + 1; Next_ex1_state <= fetch_addresses; elsif fifo_empty = '0' and n = 3 then dest_address(7 downto 0) <= fifo_data_out; n_i <= n+1; elsif n=4 then rd_ok<='0'; n_i<=0; Next_ex1_state <= decode_packet_type2; elsif fifo_empty='1' then rd_ok<='0'; Next_ex1_state <= fetch_addresses; --attendre les données manquantes else Next_ex1_state <= fifo_select; end if; when decode_packet_type2 => if packet_type = MPI_PUT then Next_ex1_state <= ex1_put1; elsif packet_type = MPI_GET then Next_ex1_state <= ex1_get1; end if; -- execution du mpi put when ex1_put1 => if dma_rd_grant = '1' then Next_ex1_state <= ex1_put2; else Next_ex1_state <= ex1_put1; end if; Wr_ok<='0'; when ex1_put2 =>Wr_ok<='0'; if switch_port_in_full = '0' and n = 0 then --envoie du code MPI_PUT n_i<= n + 1; wr_ok<='1'; Next_ex1_state <= ex1_put2; elsif switch_port_in_full = '0' and n = 1 then data_to_send <= p_len; n_i<= n + 1; wr_ok<='1'; Next_ex1_state <= ex1_put2; elsif switch_port_in_full = '0' and n = 2 then data_to_send <= dest_address(15 downto 8); n_i<= n + 1; wr_ok<='1'; Next_ex1_state <= ex1_put2; elsif switch_port_in_full = '0' and n = 3 then data_to_send <= dest_address(7 downto 0); n_i<= n +1; wr_ok<='1'; Next_ex1_state <= ex1_put2; elsif switch_port_in_full = '0' and n = 4 then p_len_i <= p_len - 4; Next_ex1_state <= ex1_put3; Wr_ok<='0'; n_i<=0; else Next_ex1_state <= ex1_put2; end if; when ex1_put3 => wr_ok<='0'; if unsigned(p_len)>0 then --if n=0 then -- n_i<=1; --cycle d'attente pour la RAM -- Wr_ok<='0'; -- elsif n=1 then if switch_port_in_full = '0' then if n=1 then --creer un délai sur ces signaux par rapport à src_adress p_len_i <= p_len - 1; Wr_Ok<='1'; end if; n_i<=1; src_address_i <= src_address+1; Next_ex1_state <= ex1_put3; else Wr_Ok<='0'; src_address_i <= src_address; n_i<=0; end if; --elsif n=2 then -- n_i<=0; --cycle d'attente pour la RAM -- Wr_ok<='0'; -- src_address_i <= src_address ; --prochaine lecture -- -- end if; else Wr_Ok<='0'; Next_ex1_state <= ex1_put4; end if; when ex1_put4 =>rd_ok<='1'; wr_ok<='0'; if dma_rd_grant = '1' then -- fin du mpi_put Next_ex1_state <= ex1_put5; rd_ok<='0'; n_i<=0; data_to_send<="00000001"; else Next_ex1_state <= ex1_put4; end if; if fifo_src='0' then --détection Put ou Get src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); else src_address_i<=std_logic_vector(to_unsigned(core_base_adr+4,16)); end if; when ex1_put5 => if n >0 then dma_wr<='1'; --demander un accès exclusif au bus dma_rd<='1'; -- pour éviter une mauvaise mise à jour des données else dma_wr<='0'; dma_rd<='0'; end if; if n=0 then n_i<=n+1; elsif n=1 then if dma_rd_grant='1' then n_i<=n+1; end if; rd_ok<='1'; wr_ok<='0'; dma_wr<='1'; dma_rd<='1'; elsif n=2 then if dma_rd_grant='1' then n_i<=n+1; dma_wr<='1'; tempval:=Ram_data_in; end if; rd_ok<='1'; wr_ok<='0'; dma_rd<='1'; elsif n=3 then if dma_rd_grant='1' and dma_wr_grant='1' then n_i<=n+1; tempval:=Ram_data_in; --src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); if fifo_src='0' then -- c'est un put qui est exécuté tempval(5):='1'; -- SET du bit DSENT else -- c'est un Get qui est exécuté tempval(2):='1'; -- ne pas annuler le sending après un GET end if; data_to_send<=tempval; rd_ok<='0'; wr_ok<='1'; dma_wr<='1'; dma_rd<='1'; else rd_ok<='1'; wr_ok<='0'; dma_rd<='0'; --libérer le bus et revenir en arrière dma_wr<='0'; n_i<=0; end if; elsif n=3 then if dma_wr_grant = '1' and dma_rd_grant='1' then n_i<=n+1; --src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); end if; rd_ok<='0'; wr_ok<='1'; dma_wr<='1'; dma_rd<='1'; elsif n=4 then if dma_wr_grant = '1' and dma_rd_grant='1' then n_i<=n+1; src_address_i<=std_logic_vector(to_unsigned(core_put_adr+6,16)); end if; rd_ok<='0'; wr_ok<='1'; dma_wr<='1'; dma_rd<='0'; elsif n=5 then if dma_wr_grant = '1' then n_i<=n+1; -- SET du bit DSENT data_to_send<="00000001"; end if; rd_ok<='0'; wr_ok<='1'; dma_wr<='1'; dma_rd<='0'; elsif n=6 then n_i<=0; Next_ex1_state <= fifo_select; rd_ok<='0'; wr_ok<='0'; dma_wr<='0'; dma_rd<='0'; end if; when ex1_get1 => wr_ok<='0'; if switch_port_in_full = '0' and n = 0 then -- execution du mpi get --écrire l'entête de la fonction n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 1 then -- execution du mpi get data_to_send <= "00001000"; -- longueur du paquet sur le réseau ? n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 2 then data_to_send <= "0000"&pid; -- Rang source n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 3 then data_to_send <= p_len; n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 4 then data_to_send <= src_address(15 downto 8); n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 5 then data_to_send <= src_address(7 downto 0); n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 6 then data_to_send <= dest_address(15 downto 8); n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 7 then data_to_send <= dest_address(7 downto 0); n_i<= n + 1; Wr_ok<='1'; Next_ex1_state <= ex1_get1; elsif switch_port_in_full = '0' and n = 8 then Next_ex1_state <= ex1_get2; n_i<=0; else Next_ex1_state <= ex1_get1; end if; when ex1_get2 => if dma_wr_grant = '1' then Next_ex1_state <= ex1_get3; src_address_i<=std_logic_vector(to_unsigned(core_get_adr+6,16)); data_to_send<="00000001"; else Next_ex1_state <= ex1_get2; end if; dma_wr<='1'; when ex1_send_ack |ex1_Wsync=> rd_ok<='0'; if n = 0 then -- execution du mpi ack /ou Mpi_Win_sync if switch_port_in_full = '0' then wr_Ok<='1'; --envoie de la première donnée(code ack) n_i<= n + 1; onepop:='0'; end if; elsif n = 1 then if fifo_empty='0' and onepop='0' then data_to_send <=p_len ; rd_Ok<='1'; --passe la longueur onepop:=not onepop; --une donnée lue il faut arrêter de dépiler else rd_Ok<='0'; end if; if (switch_port_in_full = '0') and onepop='1' then wr_ok<='1'; onepop:=not onepop; n_i<= n + 1; wr_ok<='1'; elsif (switch_port_in_full = '1') then wr_Ok<='0'; end if; elsif (n= 2) then if fifo_empty='0' and onepop='0' then data_to_send <=fifo_data_out; rd_Ok<='1'; onepop:=not onepop; --une donnée lue il faut arrêter de dépiler else rd_Ok<='0'; end if; if (switch_port_in_full = '0') and onepop='1' then wr_ok<='1'; onepop:=not onepop; n_i<= n + 1; wr_ok<='1'; else wr_Ok<='0'; end if; elsif (n= 3) then if fifo_empty='0' and onepop='0' then data_to_send <=fifo_data_out; rd_Ok<='1'; onepop:=not onepop; --une donnée lue il faut arrêter de dépiler else rd_Ok<='0'; end if; if (switch_port_in_full = '0') and onepop='1' then wr_ok<='1'; onepop:=not onepop; n_i<= n + 1; wr_ok<='1'; else wr_Ok<='0'; end if; elsif n = 4 then n_i<=0; Wr_Ok<='0'; rd_ok<='0';--vider le tampon Next_ex1_state <= fifo_select; end if; when ex1_get3 =>if n<3 then --ecriture de la fin d'envoie if dma_wr_grant = '1' then -- fin du post de mpi_get n_i<=n+1; data_to_send<="00000001"; wr_ok<='1'; rd_ok<='0'; end if; elsif n=3 then n_i<=0; Next_ex1_state <= ex1_get4; end if; src_address_i<=std_logic_vector(to_unsigned(core_get_adr+6,16)); when ex1_get4 => wr_ok<='0'; rd_ok<='0'; dma_wr<='1'; dma_rd<='1'; src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); if n=0 then if dma_rd_grant='1' then n_i<=n+1; end if; rd_ok<='1'; wr_ok<='0'; elsif n=1 then src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); if dma_rd_grant='1' then n_i<=n+1; end if; rd_ok<='1'; wr_ok<='0'; elsif n=2 then if dma_rd_grant='1' then n_i<=n+1; rd_ok<='1'; src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); end if; elsif n=3 then if dma_rd_grant='1' and dma_wr_grant='1' then n_i<=n+1; tempval:=Ram_data_in; rd_ok<='1'; wr_ok<='0'; dma_wr<='1'; dma_rd<='1'; else dma_wr<='0'; dma_rd<='0'; n_i<=n-1; end if; src_address_i<=std_logic_vector(to_unsigned(core_base_adr+5,16)); elsif n=4 then if dma_wr_grant = '1' and dma_rd_grant='1' then n_i<=n+1; tempval(6):='1'; --SET du bit Windows Busy --car réception Get tempval(1):='1'; -- SET du bit DReceiving data_to_send<=tempval; else rd_ok<='0'; wr_ok<='1'; end if; dma_wr<='1'; dma_rd<='1'; elsif n=5 then n_i<=0; Next_ex1_state <= fifo_select; dma_wr<='0'; dma_rd<='0'; end if; when ex1_spawn => rd_ok<='0'; if n = 0 then -- execution du mpi spawn if switch_port_in_full = '0' then wr_Ok<='1'; n_i<= n + 1; onepop:='0'; --data_to_send<=len; end if; elsif n = 1 then if fifo_empty='0' and onepop='0' then data_to_send <=p_len ; rd_Ok<='1'; onepop:='1'; --une donnée lue il faut arrêter de dépiler end if; if (switch_port_in_full = '0') and onepop='1' then wr_ok<='1'; onepop:='0'; n_i<= n + 1; wr_ok<='1'; else wr_Ok<='0'; end if; elsif (n= 2) or (n=3) then if fifo_empty='0' and onepop='0' then data_to_send <=fifo_data_out; rd_Ok<='1'; onepop:='1'; --une donnée lue il faut arrêter de dépiler end if; if (switch_port_in_full = '0') and onepop='1' then wr_ok<='1'; onepop:='0'; n_i<= n + 1; wr_ok<='1'; else wr_Ok<='0'; end if; elsif n=4 then n_i<=0; Wr_Ok<='0'; rd_ok<='0'; Next_ex1_state <= fifo_select; end if; -- execution du barrier when ex1_barrier1 => if switch_port_in_full = '0' then Next_ex1_state <= ex1_barrier2; else Next_ex1_state <= ex1_barrier1; end if; when ex1_barrier2 => if switch_port_in_full = '0' then Next_ex1_state <= ex1_barrier3; else Next_ex1_state <= ex1_barrier2; end if; when ex1_barrier3 => if switch_port_in_full = '0' then Next_ex1_state <= ex1_barrier4; else Next_ex1_state <= ex1_barrier3; end if; when ex1_barrier4 => if packet_type = MPI_BARRIER_COMPLETED and pid_counter < nprocs then pid_counter <= pid_counter + 1; Next_ex1_state <= ex1_barrier1; else Next_ex1_state <= fifo_select; end if; when ex1_init1 => rd_ok<='0'; if n=0 then n_i<=n+1; Len_i<=len-2; --deux données a été dépilée elsif n=1 then --vider le fifo instruction if len>0 then if fifo_empty='0' then rd_ok<='1'; Len_i<=len-1; else rd_ok<='0'; Len_i<=Len; end if; else n_i<=n+1; end if; elsif n=2 then -- n_i<=0; rd_ok<='0'; Next_ex1_state<=ex1_init_run; end if; when ex1_init_run=> if n=0 then if snd_start='1' then --le module ex4 veut envoyer des données if snd_data(0)(7 downto 4)=MPI_INIT or snd_data(0)(7 downto 4)=MPI_SPAWN then n_i<=n+1; for i in 0 to 3 loop mem(i)<=snd_data(i); end loop; end if; P_len_i<=x"04"; fifo_copy<='0'; snd_ack1<='0'; end if; if AppInitAck='1' then Next_ex1_state<=ex1_init2; end if; elsif n=1 then fifo_sel<='0';--pas de rotation du fifo instruction snd_start1<='1'; P_len_i<=x"04"; fifo_copy<='0'; snd_ack1<='0'; n_i<=n+1; elsif n=2 then if snd_comp='1' then snd_ack1<='1'; snd_start1<='0'; n_i<=n+1; end if; elsif n=3 then snd_start1<='0'; snd_ack1<='1'; fifo_sel<='0'; if snd_start='0' then --attente l'annulation de l'envoie n_i<=0; snd_ack1<='0'; if run_init='1' then Next_EX1_state<=fifo_select; run_init<='0'; end if; end if; end if; when ex1_init2 => if n=0 then --envoie du message Spawn Ack sur le réseau if instruction(6)='1' then --Spawned=1 ? n_i<=1; else n_i<=4; --écrire le résultat de la fn end if; elsif n=1 then n_i<=n+1; mem(0)<=MPI_INIT & x"0"; --répondre au premier mem(1)<=x"04"; mem(2)<=x"00"; mem(3)<=INIT_SPAWN & pid;-- indiquer qui répond au elsif n=2 then snd_start1<='1'; n_i<=n+1; elsif n=3 then if snd_comp='1' then snd_ack1<='1'; snd_start1<='0'; n_i<=n+1; end if; elsif n=4 then wr_ok<='1'; if dma_wr_grant = '1' then -- fin du mpi_init n_i<=n+1; end if; elsif n=5 then Next_ex1_state <= ex1_init3; n_i<=0; wr_ok<='0'; end if; -- écriture dans le registre status reg. src_address_i<=std_logic_vector(to_unsigned(core_base_adr,16)); when ex1_init3 =>--if AppInitAck='1' then Next_ex1_state <= fifo_select; --end if; when ex1_ready => Next_ex1_state <= fifo_select; when others => Next_ex1_state <= fifo_select; end case; end process; -- sortie de la machine à etat ex1_fsm_action : process(ex1_state, fifo_empty, switch_port_in_full, p_len,pid, pid_counter, dma_rd,dma_wr,ram_data_in,AppInitAck,fifo_wr,noc_fifo_in,data_to_send, packet_type, wr_ok,rd_ok) variable status_reg : std_logic_vector(word-1 downto 0):=(others=>'0'); begin -- code fonctionnel case Next_ex1_state is when fifo_select => priority_rotation <='1'; -- on peut changer la priorité fifo_rd_en <= '0'; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='0'; Result <=(others=>'0'); Ready<='1'; when read_status1 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; dma_rd_request <= '1'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='0'; Result <=(others=>'0'); Ready<='0'; when read_status2 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; dma_rd_request <= '1'; dma_wr_request <= '0'; Ram_rd<='1'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='0'; status_reg:=Ram_data_in; Result <=(others=>'0'); Ready<='0'; when fetch_packet_type => priority_rotation <='0'; fifo_rd_en <= rd_ok; switch_port_in_data <= (others =>'0'); AppInitReq<='0'; switch_port_in_wr_en <= '0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; when decode_packet_type => priority_rotation <='0'; fifo_rd_en <= rd_ok; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; when fetch_addresses => priority_rotation <='0'; fifo_rd_en <= rd_ok; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; when decode_packet_type2 =>priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= data_to_send; switch_port_in_wr_en <= '0'; AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_barrier1 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= packet_type & pid_counter; switch_port_in_wr_en <= not(switch_port_in_full); AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_barrier2 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= p_len; switch_port_in_wr_en <= not(switch_port_in_full); AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_barrier3 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= "0000" & pid; switch_port_in_wr_en <= not(switch_port_in_full); AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_barrier4 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= "0000" & pid; switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_get1 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= data_to_send; switch_port_in_wr_en <= Wr_ok; AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_get2 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= data_to_send; switch_port_in_wr_en <='0'; AppInitReq<='0'; Ram_rd<='0'; Ram_wr<='0'; dma_rd_request <= '0'; dma_wr_request <= dma_Wr; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_get3 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= (others=>'0');---??? switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= '0'; dma_wr_request <= '1'; Ram_rd<='0'; Ram_wr<=wr_ok; Ram_data_out<=data_to_send; -- le résultat de l'exécution Ready<='0'; -- fin du module Result <=(2=>'1',others=>'0');--Get completed when ex1_get4 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= ram_Data_in; switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= dma_rd; dma_wr_request <= dma_wr; Ram_rd<=rd_ok; Ram_wr<=wr_ok; Ram_data_out<=data_to_send; --"00000001"; Result <=(2=>'1',others=>'0'); --get completed Ready<='0'; -- fin du module when ex1_put1 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= data_to_send; switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= '1'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_put2 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= data_to_send; switch_port_in_wr_en <= wr_ok; AppInitReq<='0'; Ram_rd<='1'; Ram_wr<='0'; dma_rd_request <= '1'; dma_wr_request <= '0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_put3 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= ram_data_in; switch_port_in_wr_en <= wr_ok; AppInitReq<='0'; dma_rd_request <= '1'; dma_wr_request <= '0'; Ram_rd<='1'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); Ready<='0'; -- fin du module when ex1_put4 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= ram_data_in;---??? switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= rd_ok; dma_wr_request <= wr_ok; Ram_rd<=rd_ok; Ram_wr<=wr_ok; Ram_data_out<=data_to_send; --"00000001"; -- le résultat de l'exécution --result(1)<='1'; Result <=(1=>'1',others=>'0');--put completed Ready<='0'; -- fin du module when ex1_put5 => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= ram_Data_in; switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= dma_rd; dma_wr_request <= dma_wr; Ram_rd<=rd_ok; Ram_wr<=wr_ok; Ram_data_out<=data_to_send; --"00000001"; Result <=(1=>'1',others=>'0'); --put completed Ready<='0'; -- fin du module when ex1_init1 => priority_rotation <='0'; if fifo_empty='0' then fifo_rd_en <= rd_ok; else fifo_rd_en<='0'; end if; switch_port_in_data <= data_to_send; switch_port_in_wr_en <= wr_ok; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='1'; Result <=(others=>'0'); when ex1_init_run => priority_rotation <='0'; fifo_rd_en <= fifo_rd; switch_port_in_data <= noc_fifo_in; switch_port_in_wr_en <= fifo_wr; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='1'; Result <=(others=>'0'); when ex1_init2=> priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= noc_fifo_in; switch_port_in_wr_en <= push; AppInitReq<='1'; dma_rd_request <= '0'; dma_wr_request <= '1'; Ram_rd<='0'; Ram_wr<=wr_ok; Ram_data_out<="00010000"; -- le résultat de l'exécution -- dans le registre status Result <=(others=>'0');-- when ex1_init3=> priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= ram_Data_in; switch_port_in_wr_en <= '0'; AppInitReq<='0'; dma_rd_request <= '0'; dma_wr_request <= '1'; Ram_rd<='0'; Ram_wr<='1'; Ram_data_out<="00010000"; Ready<='0'; -- fin du module Result<=(0=>'1',others=>'0'); --le résultat de l'initialisation est écrit when ex1_spawn => priority_rotation <='0'; fifo_rd_en <= rd_ok; switch_port_in_data <= Data_to_send; switch_port_in_wr_en <= wr_ok; AppInitReq<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); when ex1_send_ack|ex1_Wsync => priority_rotation <='0'; fifo_rd_en <= rd_ok; switch_port_in_data <= Data_to_send; switch_port_in_wr_en <= wr_ok; AppInitReq<='0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); Result <=(others=>'0'); when ex1_ready => Ready<='1'; -- fin du module priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='0'; --Result <=Result; when others => priority_rotation <='0'; fifo_rd_en <= '0'; switch_port_in_data <= (others =>'0'); switch_port_in_wr_en <= '0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'0'); AppInitReq<='0'; Result <=(others=>'0'); end case; end process; end Behavioral;