---------------------------------------------------------------------------------- -- Company: -- Engineer: GAMOM NGOUNOU -- -- Create Date: 04:57:14 07/15/2012 -- Design Name: -- Module Name: load_instr - Behavioral -- Project Name: MPI CORE -- Target Devices: -- Tool versions: -- Description: Ce module permet de charger une instruction dans le FIFO 1 -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; library NocLib; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values 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 load_instr is Port ( Instruction : in STD_LOGIC_VECTOR (Word-1 downto 0); Instruction_en : in STD_LOGIC; clk : in STD_LOGIC; reset : in STD_LOGIC; dma_rd_grant : in STD_LOGIC; dma_rd_request : out STD_LOGIC:='0'; instruction_ack : out STD_LOGIC:='0'; fifo_din : out STD_LOGIC_VECTOR (Word-1 downto 0); fifo_wr :out std_logic:='0'; copying :out std_logic:='0'; fifo_full : in STD_LOGIC; ram_address_rd : buffer STD_LOGIC_VECTOR (ADRLEN-1 downto 0); ram_data : in STD_LOGIC_VECTOR (WORD-1 downto 0); Ram_rd_en : out std_logic); end load_instr; architecture Behavioral of load_instr is --déclaration des types manipulés type typ_loadinst is (init,setadr,readptr,getbus,readmem,freebus,st_timeout); --déclaration des signaux signal Ram_address_i:STD_LOGIC_VECTOR (ADRLEN-1 downto 0):=(others=>'0'); --signal ptr, ptr_i:STD_LOGIC_VECTOR (ADRLEN-1 downto 0):=(others=>'0'); --pointeur vers l'instruction en RAM signal Base_Adr : STD_LOGIC_VECTOR (ADRLEN-1 downto 0):=(others=>'0'); signal adr_ptr : natural range 0 to 65536:=0; signal Base_AdrSet : std_logic:='0' ; --indique l'adresse de base des instructions positionée signal fifo_din_i:std_logic_vector(WORD-1 downto 0):=(others=>'-'); signal iLen,iLen_i : natural range 0 to 15:=0; --longueur de l'instruction à copier dans le Fifo signal fifo_wr_i :std_logic:='0'; signal base_adrset_i : std_logic:='0'; signal instruction_ack_i :std_logic:='0'; signal Dma_rd_request_i :std_logic:='0'; signal count,count_i : natural range 0 to 31:=0; --permet de faie évoluer la sous-MAE signal etloadinst,next_loadinst : typ_loadinst; begin SYNC_PROC: process (clk) begin if rising_edge(clk) then if (reset = '1') or instruction_en='0' then etloadinst <= init; Base_adrSet<= '0'; dma_rd_request<='0'; instruction_ack<='0'; else etloadinst <= next_loadinst; fifo_din <= fifo_din_i; Base_AdrSet<=Base_adrSet_i; ram_address_rd<=ram_address_i; adr_ptr<=to_integer(unsigned(ram_address_i)); dma_rd_request<=dma_rd_request_i; instruction_ack<=instruction_ack_i; count<=count_i; Ilen<=Ilen_i; -- assign other outputs to internal signals end if; end if; end process; -- OUTPUT_DECODE: process (etloadinst,Count_i,Ram_data,Dma_rd_grant,fifo_wr_i) variable Adr_inst1,adr_inst2 : natural; begin --insert statements to decode internal output signals --below is simple example case etloadinst is when init => Dma_rd_request_i<='0'; fifo_wr<='0'; copying<='0'; Ram_rd_en<='0'; Instruction_ack_i<='0'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='0'; when SetAdr => Dma_rd_request_i<='0'; Instruction_ack_i<='0'; fifo_wr<='0'; copying<='0'; Ram_rd_en<='0'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='1'; when getbus => fifo_wr<='0'; copying<='1'; Ram_rd_en<=Dma_rd_grant; Dma_rd_request_i<='1'; Instruction_ack_i<='0'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='1'; when readptr => fifo_wr<='0'; copying<='1'; Ram_rd_en<='1'; Dma_rd_request_i<='1'; Instruction_ack_i<='0'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='1'; when readmem => Dma_rd_request_i<='1'; copying<='1'; Ram_rd_en<='1'; fifo_wr<=fifo_wr_i; fifo_din_i<=Ram_data; Base_AdrSet_i<='1'; Instruction_ack_i<='0'; when freebus => Dma_rd_request_i<='0'; fifo_wr<='0'; copying<='0'; Ram_rd_en<='0'; Instruction_ack_i<='1'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='1'; when st_timeout => Dma_rd_request_i<='0'; fifo_wr<='0'; copying<='0'; Ram_rd_en<='0'; Instruction_ack_i<='0'; fifo_din_i<=(others=>'-'); Base_AdrSet_i<='1'; end case; end process; NEXT_STATE_DECODE: process (etloadinst, Ram_address_rd,Base_AdrSet,Ram_data,Instruction,instruction_en, fifo_full,dma_rd_grant,count,Ilen) variable ptr : std_logic_vector(ADRLEN-1 downto 0); variable timeout: natural range 0 to 255; variable Base_AD,ADRtmp,iptr : natural range 0 to 65535; begin --declare default state for next_state to avoid latches next_loadinst <= etloadinst; --default is to stay in current state Ram_address_i<=Ram_address_rd; --below is a simple example case (etloadinst) is when init => if base_adrset='1' and Instruction_en='1' then Ilen_i<=to_integer(unsigned(Instruction(3 downto 0)));--initialisation de longueur next_loadinst<=getbus; elsif Instruction_en='1' then next_loadinst<=Setadr; Base_Adr<=X"0000"; else next_loadinst<=init; Base_Adr<=X"0000"; Ilen_i<=0; end if; fifo_wr_i<='0'; count_i<=0; -- When Setadr => if Base_adrSet='0' then Base_Adr<=std_logic_vector(to_unsigned(Core_upper_adr,8)) & X"00"; --récupération des bits de poids forts de l'instruction -- end if; next_loadinst<=init; Ram_address_i<=(others=>'0'); count_i<=0; when getbus => BASE_AD:=to_integer(unsigned(base_adr)); if dma_rd_grant = '1' then next_loadinst <= readptr; -- prépare la prochaine lecture else end if; Ram_address_i<=(others=>'0'); count_i<=0; When readptr => --s'assurer que le bus est disponible if count=0 then Ram_address_i<=std_logic_vector(to_unsigned(BASE_AD+2,16)); if dma_rd_grant='1' then count_i <=count+1; end if; elsif count=1 then-- attend que la donnée soit positionnée if dma_rd_grant = '1' then count_i <=count+1; end if; elsif count=2 then if dma_rd_grant = '1' then count_i <=count+1; ptr(Word-1 downto 0):=Ram_data; else count_i<=0; end if; Ram_address_i<=std_logic_vector(to_unsigned(BASE_AD+3,16)); elsif count=3 then Ram_address_i<=std_logic_vector(to_unsigned(BASE_AD+3,16)); if dma_rd_grant = '1' then count_i <=count+1; end if; elsif count=4 then if dma_rd_grant = '1' then ptr(15 downto 8):=Ram_data; count_i<=0; timeout:=0; next_loadinst <= readmem; else count_i<=3; end if; report "Readptr " & image(ptr); else end if; if dma_rd_grant = '0' then assert true report "Mauvaise lecture" severity failure; timeout:=timeout+1; end if; when readmem => if fifo_full='0' then if ilen >0 then if count=0 then iptr:=to_integer(unsigned(ptr)); AdrTmp:=iptr; if dma_rd_grant = '1' then count_i <=count+1; fifo_wr_i<='0'; end if; elsif count=1 then if dma_rd_grant = '1' then count_i <=count+1; fifo_wr_i<='0'; end if; elsif count=2 then if dma_rd_grant = '1' then count_i <=count+1; fifo_wr_i<='0'; else count_i<=1; end if; elsif count=3 then count_i <=count+1; fifo_wr_i<='1'; --écriture de la donnée dans le fifo Ilen_i<=Ilen-1; AdrTmp:=Adr_Ptr+1; elsif count=4 then fifo_wr_i<='0'; count_i<=1; end if; else --Ilen=0 ? fifo_wr_i<='0'; next_loadinst<=freebus; end if; end if; Ram_address_i<=STD_LOGIC_VECTOR(to_unsigned(AdrTmp,16)); if dma_rd_grant = '0' or Fifo_full='1' then timeout:=timeout+1; fifo_wr_i<='0'; Count_i<=1; --recommencer les cycles d'attente de la donnée if timeout=200 then next_loadinst<=st_timeout; end if; end if; when freebus => fifo_wr_i<='0'; count_i<=0; Ram_address_i<=(others=>'0'); if instruction_en='0' then next_loadinst <= init; end if; when st_timeout => fifo_wr_i<='0'; Ram_address_i<=(others=>'0'); next_loadinst<=init; report "Copie D'instruction *** RAM/Fifo a été indisponible pour trop longtemps !!!"; count_i<=0; end case; end process; end Behavioral;