LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cores > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: ezaffar@v...
    Date: Tue, 18 Nov 2003 08:28:56 +0100
    Subject: [oc] implementing prefetch and instruction cache
    Top

    Hi,
    
    I am trying to add a prefetch queue and instruction cache to a 5 stage 
    pipeline 16 bit processor. I am kind of stuck. I am fairly new to vhdl.
    
    here is the code for prefetch, I haven't included the condition for branch 
    yet. :
    
    use STD.standard.all;
    use STD.textio.all;
    library IEEE;
    use IEEE.std_logic_1164.all;
    
    entity prefetch64 is
       port(
           CLK      : in   std_logic;
           CEN      : in   std_logic;
           A        : in   std_logic_vector(15 downto 0);
           iadsin   : in   std_logic;
           aout     : out  std_logic_vector(15 downto 0);
           iadsout  : out  std_logic;
           din      : in   std_logic_vector(63 downto 0);
           irdyin    : in   std_logic;
           irdy     : out  std_logic;
           Q        : out  std_logic_vector(15 downto 0));
    end prefetch64;
    
    architecture prefetch64_arc of prefetch64 is
    -- declare signals
    signal line : std_logic_vector(63 downto 0);
    
    signal empty     : boolean := true;
    
    --signal prev_addr : std_logic_vector(15 downto 0);
    begin
    --process(clk)
    --begin
    
    --end process;
    process(clk)	
    variable prev_addr : integer := 0;
    variable address   : integer := 0;
    variable counter   : integer := 0;
    --variable empty     : boolean := true;
    begin   
    
    address := 0;
    if a(0) = '1' then
      address := address + 1;
    end if;
    if a(1) = '1' then
      address := address + 2;
    end if;
    if a(2) = '1' then
      address := address + 4;
    end if;
    if a(3) = '1' then
      address := address + 8;
    end if;
    if a(4) = '1' then
      address := address + 16;
    end if;
    if a(5) = '1' then
      address := address + 32;
    end if;
    
    --if (address /= prev_addr + 1) then -- branch or first inst? shall I 
    compare the prev addr here?
    --  empty <= true;
    --  irdy <= '0';
    --  iadsout <= '1';
    --  aout <= a;
    --else
    --if (iadsin = '1') then
       
       if (empty) then
         irdy <= '0'; aout <= a; iadsout <= '1';
         if (irdyin = '1') then
           empty <= false;
           line <= din;
           --iadsout <= '0';
           case A(1 downto 0) is
    	when "00" => 
    	  Q <= line(15 downto 0);
    	  irdy <= '1'; --iadsout <= '0';
    	when "01" =>
    
    	  Q <= line(31 downto 16);
    	  irdy <= '1'; --iadsout <= '0';
    	when "10" =>
    
    	  Q <= line(47 downto 32);
    	  irdy <= '1'; --iadsout <= '0';
    	when "11" =>
    
    	  Q <= line(63 downto 48);
    	  irdy <= '1'; empty <= true; --iadsout <= '0'; 
    	when others =>    
    	  Q <= (others => 'Z');
    	  irdy <= '0'; --iadsout <= '0';
            end case;
         end if;
    
       else    
          case A(1 downto 0) is
    	when "00" => 
    	  Q <= line(15 downto 0);
    	  irdy <= '1'; iadsout <= '0';
    	when "01" =>
    
    	  Q <= line(31 downto 16);
    	  irdy <= '1'; iadsout <= '0';
    	when "10" =>
    
    	  Q <= line(47 downto 32);
    	  irdy <= '1'; iadsout <= '0';
    	when "11" =>
    
    	  Q <= line(63 downto 48);
    	  irdy <= '1'; empty <= true; iadsout <= '0'; 
    	when others =>    
    	  Q <= (others => 'Z');
    	  irdy <= '0'; iadsout <= '0';
          end case;
        end if;
        
       
    --  end if;
    --end if;
      prev_addr := address;
    end process;
    end prefetch64_arc;
    
    ===============
    use STD.standard.all;
    use STD.textio.all;
    library IEEE;
    use IEEE.std_logic_1164.all;
    
    entity icache_4x64 is
       generic(delay : time := 5 ns);
       port(
           CLK      : in   std_logic;
           cen      : in   std_logic;
           a        : in   std_logic_vector(15 downto 0);
           iadsin   : in   std_logic;
           aout     : out  std_logic_vector(15 downto 0);
           iadsout  : out  std_logic;
           irdyin   : in   std_logic;
           irdyout  : out  std_logic;
           burst    : out  std_logic;
           dbin     : in   std_logic_vector(15 downto 0);
           dbout    : out  std_logic_vector(63 downto 0));
    end icache_4x64;
    
    use STD.standard.all;
    use STD.textio.all;
    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_arith.all;
    
    architecture icache_arc of icache_4x64 is
      type CacheLine is
        record 
          tag : std_logic_vector(11 downto 0);
          valid : std_logic;
          data : std_logic_vector(63 downto 0);
        end record;
      type cacheType is array(0 to 3) of CacheLine;
      --signal word : integer range 0 to 3;
      --signal line : integer range 0 to 3;
      --signal burstcount : integer range 0 to 3 := 0 ;
      signal iCache : cacheType;
      signal miss : std_logic;
    -- declare signals  
    begin
    
    process(clk)
    -- implement array, how to implement tag, valid etc., get data in bursts
    -- 
      variable word : integer range 0 to 3;
      variable line : integer range 0 to 3;
      variable burstcount : integer range 0 to 3 := 0 ;
    --  variable iCache : cacheType;
      --variable miss : boolean := true;
    begin
      -- get cache line
      line := 0;
      if a(2) = '1' then
        line := line + 1;
      end if;
      if a(3) = '1' then
        line := line + 2;
      end if;
      word := 0;
      if a(0) = '1' then
        word := word + 1;
      end if;
      if a(1) = '1' then
        word := word + 2;
      end if;
    if clk'event and clk = '1' then        
      if cen = '0' then
        if iadsin = '1' then
          -- match tag
          --irdyout <= '0';
          if (iCache(line).tag = a(15 downto 4)) and (iCache(line).valid = '1') 
    then -- cache hit
            dbout <= iCache(line).data after delay;
            miss <= '0'; iadsout <= '0'; burst <= '0'; irdyout <= '0', '1' after 
    delay;
          else -- cache miss, get from ROM
            miss <= '1'; irdyout <= '0'; aout <= a; iadsout <= '1'; burst <= '1'; 
            -- wait until irdyin becomes high, need this???
            
            -- data comes in one clk at a time?
    
    	if (irdyin = '1') then
    	    case burstcount is
    		when 0 =>
    		    case word is
    		      when 0 =>
    			iCache(line).data(15 downto 0) <=  dbin;
    		      when 1 =>
    			iCache(line).data(31 downto 16) <= dbin;
    		      when 2 =>
    			iCache(line).data(47 downto 32) <= dbin;
    		      when 3 =>
    			iCache(line).data(63 downto 48) <= dbin;
    		    end case;
    		when 1 =>
    		    case word is
    		      when 0 =>
    			iCache(line).data(31 downto 16) <=  dbin;
    		      when 1 =>
    			iCache(line).data(47 downto 32) <= dbin;
    		      when 2 =>
    			iCache(line).data(63 downto 48) <= dbin;
    		      when 3 =>
    			iCache(line).data(15 downto 0) <= dbin;
    		    end case;
    		when 2 =>
    		    case word is
    		      when 0 =>
    			iCache(line).data(47 downto 32) <=  dbin;
    		      when 1 =>
    			iCache(line).data(63 downto 48) <= dbin;
    		      when 2 =>
    			iCache(line).data(15 downto 0) <= dbin;
    		      when 3 =>
    			iCache(line).data(31 downto 16) <= dbin;
    		    end case;
    		when 3 =>
    		    case word is
    		      when 0 =>
    			iCache(line).data(63 downto 48) <=  dbin;
    		      when 1 =>
    			iCache(line).data(15 downto 0) <= dbin;
    		      when 2 =>
    			iCache(line).data(31 downto 16) <= dbin;
    		      when 3 =>
    			iCache(line).data(47 downto 32) <= dbin;
    		    end case;
    		    iCache(line).valid <= '1';	
    		    iCache(line).tag <= a(15 downto 4);	 
    	    end case;
    	    burstcount := (burstcount + 1) mod 4;
    	 end if;
    	
          end if;
        end if;
      end if;
    end if;  
    end process;
    end icache_arc;
    
    
    
     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.