⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icache.vhd

📁 sparc org, vhdl rtl code
💻 VHD
📖 第 1 页 / 共 2 页
字号:
	if not (cacheon and hit and valid) = '1' then  
	  v.istate := "01"; v.req := '1'; 
          v.holdn := '0'; v.overrun := '1';
	else
          if (ISETS > 1) and (ICREPLACE = lru) then vl.write := '1'; end if;
        end if;
        v.waddress := ici.fpc(31 downto PCLOW);

      end if;
      if dco.icdiag.enable = '1' then
	diagen := '1';
      end if;
      ddatain := dci.maddress;
      if (ISETS > 1) then
        if (ICREPLACE = lru) then
	  vl.set := std_logic_vector(conv_unsigned(set, SETBITS)); 
	  vl.waddr := ici.fpc(OFFSET_HIGH downto OFFSET_LOW);
	end if;
        v.setrepl := std_logic_vector(conv_unsigned(set, SETBITS));
 	if (((not hit) and (not r.flush)) = '1') then
          case ICREPLACE is
	  when rnd =>
            if ICLOCK_BIT = 1 then 
              if lock(conv_integer(r.rndcnt)) = '0' then v.setrepl := r.rndcnt;
              else
                v.setrepl := std_logic_vector(conv_unsigned(ISETS-1, SETBITS));
                for i in ISETS-1 downto 0 loop
                  if (lock(i) = '0') and (i>conv_integer(r.rndcnt)) then
                    v.setrepl := std_logic_vector(conv_unsigned(i, SETBITS));
                  end if;
                end loop;
              end if;
            else
              v.setrepl := r.rndcnt;
            end if;
          when lru =>
-- pragma translate_off
            if not is_x(ici.fpc) then
-- pragma translate_on
              v.setrepl :=  lru_set(rl.lru(conv_integer(ici.fpc(OFFSET_HIGH downto OFFSET_LOW))), lock(0 to ISETS-1));
-- pragma translate_off
            end if;
-- pragma translate_on
          when lrr =>
            v.setrepl := (others => '0');
            if ICLOCK_BIT = 1 then
              if lock(0) = '1' then v.setrepl(0) := '1';
              else
                v.setrepl(0) := icramo.itramout(0).lrr xor icramo.itramout(1).lrr;
              end if;
            else
              v.setrepl(0) := icramo.itramout(0).lrr xor icramo.itramout(1).lrr;
            end if;
            if v.setrepl(0) = '0' then v.lrr := not icramo.itramout(0).lrr;
            else v.lrr := icramo.itramout(0).lrr; end if;
          end case;  
        end if;  
        if (ICLOCK_BIT = 1) then
          if (hit and lock(set)) = '1' then v.lock := '1';
          else v.lock := '0'; end if;
        end if;
      end if;
    when "01" =>		-- streaming: update cache and send data to IU
      rdatasel := memory;
      taddr(TAG_HIGH downto LINE_LOW) := r.waddress(TAG_HIGH downto LINE_LOW);
      branch := (ici.fbranch and r.overrun) or
		      (ici.rbranch and (not r.overrun));
      v.underrun := r.underrun or 
        (write and ((ici.nullify or not eholdn) and (mcio.ready and not (r.overrun and not r.underrun))));
      v.overrun := (r.overrun or (eholdn and not ici.nullify)) and 
		    not (write or r.underrun);
      if mcio.ready = '1' then
--        mds := not (v.overrun and not r.underrun);
        mds := not (r.overrun and not r.underrun);
--        v.req := r.burst; 
        v.burst := v.req and not nnlastline;
      end if;
      if mcio.grant = '1' then 
        v.req := mcio.burst and r.burst and 
	         (not (nnlastline and mcio.ready)) and (mcio.burst or (not branch)) and
		 not (v.underrun and not cacheon);
        v.burst := v.req and not nnlastline;
      end if;
      v.underrun := (v.underrun or branch) and not v.overrun;
      v.holdn := not (v.overrun or v.underrun);
      if (mcio.ready = '1') and (r.req = '0') then --(v.burst = '0') then
        v.underrun := '0'; v.overrun := '0';
        if (mcio.ics(0) and not r.flush2) = '1' then
	  v.istate := "10"; v.holdn := '0';
	else
          v.istate := "00"; v.flush := r.flush2; v.holdn := '1';
	  if r.overrun = '1' then taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
	  else taddr := ici.rpc(TAG_HIGH downto LINE_LOW); end if;
	end if;
      end if;
    when "10" => 		-- return to main
      taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
      v.istate := "00"; v.flush := r.flush2;
    when others => v.istate := "00";
    end case;

    if mcio.retry = '1' then v.req := '1'; end if;

-- Generate new valid bits write strobe

    vmaskraw := decode(r.waddress(LINE_HIGH downto LINE_LOW));
    twrite := write;
    if cacheon = '0' then
      twrite := '0'; vmask := (others => '0');
    elsif (mcio.ics = "01") then
      twrite := twrite and r.hit;
      vmask := icramo.itramout(set).valid or vmaskraw;
    else
      if r.hit = '1' then vmask := r.valid or vmaskraw;
      else vmask := vmaskraw; end if;
    end if; 
    if (mcio.mexc or not mcio.cache) = '1' then 
      twrite := '0'; dwrite := '0';
    else dwrite := twrite; end if;
    if twrite = '1' then
      v.valid := vmask; v.hit := '1';
      if (ISETS > 1) and (ICREPLACE = lru) then vl.write := '1'; end if;
    end if;

    if (ISETS > 1) and (ICREPLACE = lru) and (rl.write = '1') then
      vl.lru(conv_integer(rl.waddr)) :=
	  lru_calc(rl.lru(conv_integer(rl.waddr)), conv_integer(rl.set));
    end if;

-- cache write signals
    
    if ISETS > 1 then setrepl := r.setrepl; else setrepl := (others => '0'); end if;
-- pragma translate_off
    if not is_x(setrepl) then
-- pragma translate_on
      if twrite = '1' then ctwrite(conv_integer(setrepl)) := '1'; end if;
      if dwrite = '1' then cdwrite(conv_integer(setrepl)) := '1'; end if;
-- pragma translate_off
    end if;
-- pragma translate_on
    
-- diagnostic cache access

    if diagen = '1' then
     if (ISETS /= 1) then 
       v.diagset := dco.icdiag.addr(SETBITS -1 + TAG_LOW downto TAG_LOW);
     end if;
   end if;
     
    if (ISETS /= 1) then 
-- pragma translate_off
      if not is_x(r.diagset) then
-- pragma translate_on
        rdiagset := conv_integer(r.diagset);
-- pragma translate_off
      end if;
-- pragma translate_on
-- pragma translate_off
      if not is_x(v.diagset) then
-- pragma translate_on
        vdiagset := conv_integer(v.diagset);
-- pragma translate_off
      end if;
-- pragma translate_on
    end if;

    diagdata := icramo.idramout(rdiagset).data;
    if diagen = '1' then -- diagnostic access
      taddr(OFFSET_HIGH downto LINE_LOW) := dco.icdiag.addr(OFFSET_HIGH downto LINE_LOW);
      wtag(TAG_HIGH downto TAG_LOW) := dci.maddress(TAG_HIGH downto TAG_LOW);
      wlrr := dci.maddress(ICTAG_LRRPOS);
      wlock := dci.maddress(ICTAG_LOCKPOS);
      if dco.icdiag.tag = '1' then
	twrite := not dco.icdiag.read; dwrite := '0';
        ctwrite := (others => '0'); cdwrite := (others => '0');
	ctwrite(vdiagset) := not dco.icdiag.read;
        diagdata := (others => '0');
        diagdata(TAG_HIGH downto TAG_LOW) := icramo.itramout(rdiagset).tag(ITAG_BITS - ILINE_SIZE - 1 downto 0);
        diagdata(ILINE_SIZE -1 downto 0) := icramo.itramout(rdiagset).valid;
        diagdata(ICTAG_LRRPOS) := icramo.itramout(rdiagset).lrr;
        diagdata(ICTAG_LOCKPOS) := icramo.itramout(rdiagset).lock;
      else
	dwrite := not dco.icdiag.read; twrite := '0';
        cdwrite := (others => '0'); cdwrite(vdiagset) := not dco.icdiag.read;
        ctwrite := (others => '0');
      end if;
      vmask := dci.maddress(ILINE_SIZE -1 downto 0);
      v.diagrdy := '1';
    end if;

-- select data to return on read access

    case rdatasel is
    when memory => rdata := mcio.data;
    when others => rdata := icramo.idramout(set).data;
    end case;

-- cache flush

    if (ici.flush or dco.icdiag.flush) = '1' then
      v.flush := '1'; v.flush2 := '1'; v.faddr := (others => '0');
    end if;

    if r.flush2 = '1' then
      twrite := '1'; ctwrite := (others => '1'); vmask := (others => '0');
      v.faddr := r.faddr +1; taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;
      wlrr := '0'; wlock := '0'; wtag := (others => '0');
      if (r.faddr(IOFFSET_BITS -1) and not v.faddr(IOFFSET_BITS -1)) = '1' then
	v.flush2 := '0';
      end if;
    end if;

-- reset

    if rst = '0' then 
      v.istate := "00"; v.req := '0'; v.burst := '0'; v.holdn := '1';
      v.flush := '0'; v.flush2 := '0'; v.overrun := '0'; v.underrun := '0';
      v.rndcnt := (others => '0'); v.lrr := '0'; v.setrepl := (others => '0');
      v.diagset := (others => '0'); v.lock := '0';
    end if;

    if (not rst or r.flush) = '1' then  
      vl.lru := (others => (others => '0'));
    end if;
    
-- Drive signals

    c  <= v;	   -- register inputs
    cl <= vl;  -- lru register inputs

    -- tag ram inputs
    icrami.itramin.valid    <= vmask;
    icrami.itramin.tag      <= wtag;
    icrami.itramin.lrr      <= wlrr;
    icrami.itramin.lock     <= wlock;
    icrami.itramin.enable   <= enable;
    icrami.itramin.write    <= ctwrite;
    icrami.itramin.flush    <= r.flush2;

    -- data ram inputs
    icrami.idramin.enable   <= enable;
    icrami.idramin.address  <= taddr(OFFSET_HIGH downto LINE_LOW);
    icrami.idramin.data     <= ddatain;
    icrami.idramin.write    <= cdwrite; 
    
    -- memory controller inputs
    mcii.address(31 downto 2)  <= r.waddress(31 downto 2);
    mcii.address(1 downto 0)  <= "00";
    mcii.su       <= r.su;
    mcii.burst    <= r.burst;
    mcii.req      <= r.req;
    mcii.flush    <= r.flush;

    -- IU data cache inputs
    ico.data      <= rdata;
    ico.exception <= mcio.mexc or error;
    ico.hold      <= r.holdn;
    ico.mds       <= mds;
    ico.flush     <= r.flush;
    ico.diagdata  <= diagdata;
    ico.diagrdy   <= r.diagrdy;

  end process;

-- Local registers


  regs1 : process(clk)
  begin if rising_edge(clk) then r <= c; end if; end process;

  regs2gen : if (ISETS > 1) and (ICREPLACE = lru) generate
    regs2 : process(clk)
    begin if rising_edge(clk) then rl <= cl; end if; end process;
  end generate;


-- pragma translate_off
  chk : process
  begin
    assert not ((ISETS > 2) and (ICREPLACE = lrr)) report
	"Wrong instruction cache configuration detected: LRR replacement requires 2 sets"
    severity failure;
    wait;
  end process;
-- pragma translate_on
      
end ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -