---------------------------------------------------------------------------------- -- Company: GRIIA - ETIS -- Engineer: GAMOM, KIEGAING -- -- Create Date: 01:02:10 06/17/2011 -- Design Name: -- Module Name: EX2_FSM - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- machine a etat qui execute la reception des packet dans le core mpi -- Dependencies: --ss -- Revision: 26/01/2012 -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; library NocLib ; use IEEE.STD_LOGIC_1164.ALL; use IEEE.Numeric_std.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use Work.Packet_type.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 EX2_FSM is generic ( pid : std_logic_vector(3 downto 0) :="0001"; -- id du processeur nprocs : std_logic_vector(3 downto 0):="0100"-- nombre de processeur du MPSOC - 1 ); Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; Instruction_en : in std_logic; dma_wr_grant : in STD_LOGIC; dma_wr_request : out STD_LOGIC; dma_rd_grant : in STD_LOGIC; dma_rd_request : out STD_LOGIC; ram_rd : out std_logic; ram_wr : out std_logic; ram_address : out std_logic_vector(ADRLEN-1 downto 0); Ram_data_in : in STD_LOGIC_VECTOR (Word-1 downto 0); Ram_data_out : out STD_LOGIC_VECTOR (Word-1 downto 0); fifo_data : out STD_LOGIC_VECTOR (Word-1 downto 0); fifo_wr_en : out STD_LOGIC; fifo_full : in STD_LOGIC; AppRank : in STD_LOGIC_VECTOR(3 downto 0); AppSize : in STD_LOGIC_VECTOR(3 downto 0); packet_received : out STD_LOGIC; packet_ack : in STD_LOGIC; barrier_completed : out STD_LOGIC; Ready : Out std_logic; AppInitReq :out STD_LOGIC; -- requête d'initialisation de l'application AppInitAck :in STD_LOGIC; -- Acquitement d'initialisation Initialized:in std_logic ; -- état de la Lib switch_data_available : in STD_LOGIC; switch_port_out_data : in STD_LOGIC_VECTOR (Word-1 downto 0); switch_port_out_rd_en : out STD_LOGIC ); end EX2_FSM; architecture Behavioral of EX2_FSM is -- définition du type etat de la machine à etat type fsm_states is (fetch_packet_type, decode_packet_type, decode_packet_type2, fetch_addresses,execute_spawn,execute_put1,execute_put2,execute_put3 ,execute_put4, execute_put5,execute_get1, execute_get2,execute_get3,execute_get4, execute_barrier1, execute_barrier2, execute_barrier3, execute_barrier4, execute_barrier5, execute_barrier6, execute_barrier7,execute_init1,execute_init2); signal ex2_state_mach :fsm_states; -- machine a etat du module signal packet_type : std_logic_vector(3 downto 0); signal packet_length : std_logic_vector(Word-1 downto 0); signal barrier_counter : std_logic_vector(3 downto 0); signal pading_data,data_to_ram : std_logic_vector(Word-1 downto 0):=(others=>'0'); signal n : std_logic_vector(3 downto 0); signal dest_address : std_logic_vector(ADRLEN-1 downto 0):=(others=>'Z'); signal data_to_write_fifo : std_logic_vector(Word-1 downto 0); signal Ex2_on : std_logic:='0'; signal dma_rd,dma_wr,rd_ok ,wr_ok:std_logic:='0'; begin ram_address <= dest_address; fifo_data <= data_to_write_fifo; -- processus de transistion entre les etats fsm_nst_logic : process(clk) variable delai : natural range 0 to 1:=0; --permet de détecter que l'écriture en RAM doit être décalée variable tempval : std_logic_vector(Word-1 downto 0); begin if rising_edge(clk) then if reset = '1' then ex2_state_mach <= fetch_packet_type; Ex2_on<='0'; barrier_counter <= "0000"; else Ex2_on<=Instruction_en; --détermine si le module peut être activer ou non case ex2_state_mach is when fetch_packet_type => if switch_data_available ='1' and Ex2_on='1' then --and initialized ='1' ex2_state_mach <= decode_packet_type; packet_type<=switch_port_out_data(7 downto 4); else ex2_state_mach <= fetch_packet_type; end if; when decode_packet_type => if switch_data_available ='0' then ex2_state_mach <= decode_packet_type; else if packet_type = MPI_PUT then packet_length <= switch_port_out_data - 2; n <="0000"; ex2_state_mach <= decode_packet_type2; elsif packet_type = MPI_GET then packet_length <=switch_port_out_data-2; ex2_state_mach <= decode_packet_type2; elsif packet_type = MPI_BARRIER_REACHED or packet_type = MPI_BARRIER_COMPLETED then packet_length <= switch_port_out_data; n <= "0000"; ex2_state_mach <= execute_barrier1; elsif packet_type = MPI_INIT or packet_type =INIT_SETRANK or packet_type =INIT_SEEKMAIN then ex2_state_mach <= execute_init1; else ex2_state_mach <= decode_packet_type; end if; end if; when decode_packet_type2 => if packet_type = MPI_PUT then ex2_state_mach <= fetch_addresses; else ex2_state_mach <= execute_get1; end if; when fetch_addresses => if switch_data_available = '1' and n = 0 then dest_address(15 downto 8) <= switch_port_out_data; n <= n + 1; ex2_state_mach <= fetch_addresses; elsif switch_data_available = '1' and n = 1 then dest_address(Word-1 downto 0) <= switch_port_out_data; packet_length <= packet_length - 2; ex2_state_mach <= execute_put1; else ex2_state_mach <= fetch_addresses; end if; -- execution du mpi Init when execute_init1 =>if Initialized='1' then ex2_state_mach<=execute_init2; end if; when execute_init2=> if AppInitAck='1' then ex2_state_mach<=fetch_packet_type; end if; when execute_put1 => if dma_wr_grant = '1' then ex2_state_mach <= execute_put2; data_to_ram<=switch_port_out_data; rd_ok<='1'; n<="0000"; delai:=0; else ex2_state_mach <= execute_put1; end if; when execute_put2 => if unsigned( packet_length) > 1 then if switch_data_available = '1' and dma_wr_grant='1' then packet_length <= packet_length - 1; dest_address <= dest_address + 1; ex2_state_mach <= execute_put2; rd_ok<='1'; wr_ok<='1'; data_to_ram<=switch_port_out_data; else if switch_data_available = '1' and dma_wr_grant='0' then if delai=0 then data_to_ram<=switch_port_out_data; --met en registre la donnée présente sur le port du switch end if; delai:=1;--indique qu'un temps supplémentaire est --nécessaire pour écrire la donnée en RAM end if; ex2_state_mach <= execute_put2; rd_ok<='0'; --bloaque la lecture du switch pour ne pas perdre les données end if; else if switch_data_available = '1' then --la dernière donnée à écrire en RAM data_to_ram<=switch_port_out_data; rd_ok<='0'; wr_ok<='1'; else rd_ok<='1'; wr_ok<='0'; end if; if dma_wr_grant='1' then ex2_state_mach <= execute_put3; Wr_ok<='0'; end if; end if; when execute_put3 => if dma_rd_grant='1' then dest_address<=std_logic_vector(to_unsigned(core_base_adr+4,16)); ex2_state_mach <= execute_put4; n<="0000"; rd_ok<='1'; wr_ok<='0'; end if; when execute_put4 => if n <=4 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 if dma_rd_grant='1' then n<=n+1; else rd_ok<='1'; wr_ok<='0'; end if; elsif n=1 then if dma_rd_grant='1' then n<=n+1; else rd_ok<='1'; wr_ok<='0'; end if; elsif n=2 then if dma_rd_grant='1' then n<=n+1; tempval:=Ram_data_in; tempval(4):='1'; --SET du bit DReceived tempval(1):='0'; --reset du bit DRING !! data_to_ram<=tempval; rd_ok<='0'; wr_ok<='1'; else rd_ok<='1'; wr_ok<='0'; n<=n-1; end if; elsif n=3 then if dma_wr_grant='1' then rd_ok<='0'; wr_ok<='1'; n<=n+1; end if; elsif n=4 then if dma_wr_grant='1' then rd_ok<='0'; wr_ok<='1'; ex2_state_mach <= execute_put5; n<="0000"; end if; end if; dest_address<=std_logic_vector(to_unsigned(core_base_adr+4,16));--Adr de gest de la transaction when execute_put5 => ex2_state_mach <= fetch_packet_type; -- fin du mpi_put when execute_get1 => if switch_data_available = '1' then -- conversion du get en put en empilement dans le fifo data_to_write_fifo <= MPI_PUT & switch_port_out_data(3 downto 0); packet_length <= packet_length - 1; ex2_state_mach <= execute_get2; wr_ok<='1'; end if; when execute_get2 => if fifo_full = '0' and switch_data_available ='1' and packet_length > 0 then data_to_write_fifo <= switch_port_out_data; packet_length <= packet_length - 1; ex2_state_mach <= execute_get2; wr_ok<='1'; elsif packet_length = 0 and switch_data_available ='1' then-- ex2_state_mach <= fetch_packet_type; wr_ok<='0'; else ex2_state_mach <= execute_get3; wr_ok<='0'; end if; when execute_get3 => if dma_rd_grant='1' then -- fin du mpi_put ex2_state_mach <= execute_get4; n<="0000"; --activer le bit sending du registre de transfert else ex2_state_mach <= execute_get3; end if; dest_address<=std_logic_vector(to_unsigned(core_base_adr+4,16)); when execute_get4 => if n <4 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 if dma_rd_grant='1' then n<=n+1; end if; rd_ok<='1'; wr_ok<='0'; elsif n=1 then if dma_rd_grant='1' then n<=n+1; end if; rd_ok<='1'; wr_ok<='0'; elsif n=2 then if dma_rd_grant='1' and dma_wr_grant='1' then n<=n+1; tempval:=Ram_data_in; tempval(2):='1'; --mise à 1 du Bit Dreceiving --tempval(5):='0'; --Mise à 0 du Bit Sent data_to_ram<=tempval; rd_ok<='0'; wr_ok<='1'; else rd_ok<='1'; wr_ok<='0'; end if; elsif n=3 then if dma_wr_grant = '1' then n<=n+1; rd_ok<='0'; wr_ok<='1'; end if; elsif n=4 then if dma_wr_grant = '1' then n<="0000"; ex2_state_mach <= fetch_packet_type; -- fin du mpi_get else rd_ok<='0'; wr_ok<='1'; --n<=n-1; end if; end if; dest_address<=std_logic_vector(to_unsigned(core_base_adr+4,16)); -- execution du barrier when execute_barrier1 => if switch_data_available = '1' then pading_data <= switch_port_out_data; ex2_state_mach <= execute_barrier2; else ex2_state_mach <= execute_barrier1; end if; when execute_barrier2 => if packet_type = MPI_BARRIER_REACHED then barrier_counter <= barrier_counter + 1; ex2_state_mach <= execute_barrier4; else ex2_state_mach <= execute_barrier3; end if; when execute_barrier3 => if n < 10 then n <= n + 1; ex2_state_mach <= execute_barrier3; else ex2_state_mach <= fetch_packet_type; end if; when execute_barrier4 => if barrier_counter = nprocs then -- entete du packet MPI_BARRIER_COMPLETED data_to_write_fifo <= MPI_BARRIER_COMPLETED & "0000"; ex2_state_mach <= execute_barrier5; else ex2_state_mach <= fetch_packet_type; end if; when execute_barrier5 => if fifo_full = '0' then -- taille du packet MPI_BARRIER_COMPLETED data_to_write_fifo <= "00000011"; ex2_state_mach <= execute_barrier6; else ex2_state_mach <= execute_barrier5; end if; when execute_barrier6 => if fifo_full ='0' then -- troisième octet du packet MPI_BARRIER_COMPLETED data_to_write_fifo <= "00000000"; ex2_state_mach <= execute_barrier7; else ex2_state_mach <= execute_barrier6; end if; when execute_barrier7 => if fifo_full = '0' then barrier_counter <= "0000"; ex2_state_mach <= fetch_packet_type; else ex2_state_mach <= execute_barrier7; end if; when others => ex2_state_mach <= fetch_packet_type; end case; end if; end if; end process; -- sortie de la machine à etat -- ex2_fsm_action : process(ex2_state_mach, fifo_full, packet_length, data_to_write_fifo, packet_type, switch_data_available,switch_port_out_data,Ram_data_in,rd_ok) variable transact : std_logic_vector(Word-1 downto 0); begin -- code fonctionnel case ex2_state_mach is when fetch_packet_type => fifo_wr_en <= '0'; switch_port_out_rd_en <= switch_data_available; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; barrier_completed <= '0'; Ram_data_out<=(others=>'Z'); Ram_rd<='0'; Ram_wr<='0'; Ready<='1'; AppInitReq<='0'; when decode_packet_type => fifo_wr_en <= '0'; switch_port_out_rd_en <= switch_data_available; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when decode_packet_type2 => fifo_wr_en <= '0'; switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when fetch_addresses => fifo_wr_en <= '0'; switch_port_out_rd_en <= switch_data_available; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_put1 => fifo_wr_en <= '0'; switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '1'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_put2 => Ready<='0'; fifo_wr_en <= '0'; switch_port_out_rd_en <=rd_ok; if rd_ok = '1' then Ram_data_out<=switch_port_out_data; else Ram_data_out<=data_to_ram; end if; Ram_wr<='1'; Ram_rd<='0'; packet_received <= '0'; dma_rd_request <= '0'; dma_wr_request <= '1'; AppInitReq<='0'; barrier_completed <= '0'; when execute_put3 => Ready<='0'; fifo_wr_en <= '0'; switch_port_out_rd_en <=rd_ok; --ne pas corrompre le contenu de la RAM --Ram_data_out<=data_to_ram; Ram_wr<='0'; Ram_rd<='1'; packet_received <= '0'; dma_rd_request <= '1'; dma_wr_request <= '0'; AppInitReq<='0'; barrier_completed <= '0'; when execute_put4 => fifo_wr_en <= '0'; Ready<='0'; switch_port_out_rd_en <= '0'; packet_received <= '1'; dma_rd_request <= dma_rd; dma_wr_request <=dma_wr; Ram_wr<=wr_ok; Ram_rd<=rd_ok; AppInitReq<='0'; barrier_completed <= '0'; Ram_data_out<=data_to_ram;--Ram_data_in or "00000010"; -- le résultat de l'exécution when execute_put5 => Ready<='0'; switch_port_out_rd_en<='0'; fifo_wr_en <= '0'; packet_received <= '1'; AppInitReq<='0'; barrier_completed <= '0'; dma_rd_request <= dma_rd; dma_wr_request <= dma_wr; Ram_rd<=rd_ok; Ram_wr<=wr_ok; Ram_data_out<=data_to_ram; --Result <=(1=>'1',others=>'0'); --put completed when execute_get1=> fifo_wr_en <= '0'; switch_port_out_rd_en <= switch_data_available; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_get2 => if fifo_full = '0' and switch_data_available = '1' and packet_length > 0 then switch_port_out_rd_en <='1'; else switch_port_out_rd_en <='0'; end if; fifo_wr_en <= Wr_ok; Ready<='0'; packet_received <= '0'; dma_rd_request <= '0'; dma_wr_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; when execute_get3 => fifo_wr_en <= '0'; Ready<='0'; switch_port_out_rd_en <= '0'; packet_received <= '1'; dma_rd_request <= '1'; dma_wr_request <='0'; Ram_wr<='0'; Ram_rd<='1'; AppInitReq<='0'; barrier_completed <= '0'; --Ram_data_out<=Ram_data_in or "00000010"; -- activer le bit DSending when execute_get4 => Ready<='0'; barrier_completed <= '0'; switch_port_out_rd_en<='0'; fifo_wr_en <= '0'; packet_received <= '1'; 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_ram; --activer le bit DSending when execute_barrier1 => fifo_wr_en <= '0'; switch_port_out_rd_en <= switch_data_available; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; Ready<='0'; AppInitReq<='0'; when execute_barrier2 => fifo_wr_en <= '0'; Ready<='0'; switch_port_out_rd_en <='0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; when execute_barrier3 => fifo_wr_en <= '0'; switch_port_out_rd_en <='0'; Ready<='0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '1'; AppInitReq<='0'; when execute_barrier4 => fifo_wr_en <= '0'; switch_port_out_rd_en <='0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_barrier5 => fifo_wr_en <= not(fifo_full); switch_port_out_rd_en <='0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_barrier6 => fifo_wr_en <= not(fifo_full); switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_barrier7 => fifo_wr_en <= not(fifo_full); switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; Ram_data_out<=(others=>'Z'); barrier_completed <= '0'; AppInitReq<='0'; Ready<='0'; when execute_init1 => fifo_wr_en <= not(fifo_full); switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; barrier_completed <= '0'; Ready<='0'; Ram_data_out<=(others =>'Z'); AppInitReq<='1'; when execute_init2 => fifo_wr_en <= not(fifo_full); switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; Ram_rd<='0'; Ram_wr<='0'; barrier_completed <= '0'; Ram_data_out<=(others =>'Z'); AppInitReq<='1'; Ready<='0'; when others => Ready<='1'; -- le module est à nouveau libre fifo_wr_en <= '0'; switch_port_out_rd_en <= '0'; packet_received <= '0'; dma_wr_request <= '0'; dma_rd_request <= '0'; barrier_completed <= '0'; Ram_data_out<=(others=>'Z'); Ram_rd<='0'; Ram_wr<='0'; Ready<='1'; AppInitReq<='0'; end case; end process; end Behavioral;