---------------------------------------------------------------------------------- -- 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 mdule 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 : out 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 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=>'Z'); 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; dma_rd_request<=dma_rd_request_i; instruction_ack<=instruction_ack_i; count<=count_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,Ram_address_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=>'Z'); 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=>'Z'); 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=>'Z'); 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=>'Z'); 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=>'Z'); 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=>'Z'); Base_AdrSet_i<='1'; end case; end process; NEXT_STATE_DECODE: process (etloadinst, Base_AdrSet,Ram_data,Instruction,instruction_en, fifo_full,dma_rd_grant,count) 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 --insert statements to decode next_state --below is a simple example case (etloadinst) is when init => if base_adrset='1' and Instruction_en='1' then next_loadinst<=getbus; elsif Instruction_en='1' then next_loadinst<=Setadr; Base_Adr<=X"0000"; else next_loadinst<=init; Base_Adr<=X"0000"; end if; fifo_wr_i<='0'; count_i<=0; -- When Setadr => if Base_adrSet='0' then Base_Adr<=instruction & X"00"; --récupération des bits de poids forts de l'instruction -- end if; next_loadinst<=init; Ram_address_i<=(others=>'Z'); 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=>'Z'); count_i<=0; When readptr => if dma_rd_grant = '1' then --s'assurer que le bus est disponible if count=0 then Ram_address_i<=std_logic_vector(to_unsigned(BASE_AD+2,16)); count_i <=count+1; elsif count=1 then-- attend que la donnée soit positionnée count_i <=count+1; elsif count=2 then count_i <=count+1; elsif count=3 then ptr(Word-1 downto 0):=Ram_data; Ram_address_i<=incr_vec(ram_address_i,'1'); count_i <=count+1; elsif count=4 then count_i <=count+1; elsif count=5 then ptr(15 downto 8):=Ram_data; --count_i <=count+1; --elsif count=6 then --ptr(15 downto 8):=Ram_data; count_i<=0; timeout:=0; next_loadinst <= readmem; else end if; else timeout:=timeout+1; end if; when readmem => if dma_rd_grant = '1' then --s'assurer que le bus est disponible if fifo_full='0' then if count=0 then iptr:=to_integer(unsigned(ptr)); AdrTmp:=iptr; count_i <=count+1; fifo_wr_i<='0'; elsif count=1 then count_i <=count+1; fifo_wr_i<='0'; elsif count=2 then count_i <=count+1; AdrTmp:=iptr+1; --incrémentation de l'adresse fifo_wr_i<='0'; elsif count=3 then count_i <=count+1; fifo_wr_i<='1'; --écriture de la donnée dans le fifo elsif count=4 then fifo_wr_i<='0'; count_i <=count+1; elsif count=5 then fifo_wr_i<='1'; --lecture de la donnée 2 count_i <=count+1; AdrTmp:=iptr+2; elsif count=6 then count_i <=count+1; fifo_wr_i<='0'; elsif count=7 then count_i <=count+1; fifo_wr_i<='0'; elsif count=8 then fifo_wr_i<='1';--lecture de la donnée 3 count_i <=count+1; AdrTmp:=iptr+3; elsif count =9 then count_i <=count+1; fifo_wr_i<='0'; elsif count=10 then count_i <=count+1; fifo_wr_i<='0'; elsif count=11 then fifo_wr_i<='1'; --lecture de la donnée 4 count_i <=count+1; ADRTmp:=iptr+4;--incrémente l'adresse elsif count =12 then count_i <=count+1; fifo_wr_i<='0'; elsif count=13 then count_i <=count+1; fifo_wr_i<='0'; elsif count=14 then fifo_wr_i<='1';--lecture de la donnée 5 count_i <=count+1; ADRtmp:=iptr+5; elsif count =15 then count_i <=count+1; fifo_wr_i<='0'; elsif count=16 then count_i <=count+1; fifo_wr_i<='0'; elsif count=17 then fifo_wr_i<='1';--lecture de la donnée 6 count_i <=count+1; next_loadinst <= freebus; end if; Ram_address_i<=STD_LOGIC_VECTOR(to_unsigned(AdrTmp,16)); end if; else timeout:=timeout+1; if timeout=50 then next_loadinst<=st_timeout; end if; Ram_address_i<=(others=>'Z'); -- le bus n'est pas libre end if; when freebus => fifo_wr_i<='0'; count_i<=0; Ram_address_i<=(others=>'Z'); if instruction_en='0' then next_loadinst <= init; end if; when st_timeout => fifo_wr_i<='0'; Ram_address_i<=(others=>'Z'); next_loadinst<=init; count_i<=0; end case; end process; end Behavioral;