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

📄 dcache.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 3 页
字号:
        tdiagwrite := not dci.eenaddr and dci.enaddr and dci.write;        twrite := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := dtag;       when ASI_DDATA =>        ddiagwrite := not dci.eenaddr and dci.enaddr and dci.write;        dwrite := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := dddata;       when ASI_UDATA | ASI_SDATA  =>         lramwr := not dci.eenaddr and dci.enaddr and dci.write;--       when ASI_UINST | ASI_SINST =>              when others =>      end case;    end if;        rdatav := (others => (others => '0'));    align_data := (others => '0'); align_datav := (others => (others => '0'));    maddrlow := maddress(1 downto 0); -- stupid Synopsys VSS bug ...    case rdatasel is    when dddata =>       rdatav := dcramov.data;      if dci.dsuen = '1' then set := conv_integer(r.dsuset);      else set := ddset; end if;     when dtag =>       rdatav := dcramov.tag;       if dci.dsuen = '1' then set := conv_integer(r.dsuset);      else set := ddset; end if;     when icache =>       rdatav(0) := ico.diagdata; set := 0;    when ddata | memory =>        if rdatasel = memory then	  rdatav(0) := mcdo.data; set := 0; --FIXME        else	  for i in 0 to DSETS-1 loop rdatav(i) := dcramov.data(i); end loop;        end if;    when sysr =>       set := 0;      case dci.maddress(3 downto 2) is      when "00" | "01" =>        rdatav(0)(23) := r.cctrl.dsnoop;        rdatav(0)(16 downto 14) := r.cctrl.burst & ico.flush & r.flush;        rdatav(0)(5 downto 0) :=             r.cctrl.dfrz & r.cctrl.ifrz & r.cctrl.dcs & r.cctrl.ics;      when "10" =>	rdatav(0) := ico.cfg;      when others =>	rdatav(0) := cache_cfg(drepl, dsets, dlinesize, dsetsize, dsetlock, 		dsnoop, dlram, dlramsize, dlramstart, 0);      end case;    end case;-- select which data to update the data cache with      for i in 0 to DSETS-1 loop        case size is		-- merge data during partial write        when "00" =>          case maddrlow is          when "00" =>	    ddatainv(i) := edata(7 downto 0) & dcramov.data(i)(23 downto 0);          when "01" =>	    ddatainv(i) := dcramov.data(i)(31 downto 24) & edata(7 downto 0) & 		     dcramov.data(i)(15 downto 0);          when "10" =>	    ddatainv(i) := dcramov.data(i)(31 downto 16) & edata(7 downto 0) & 		     dcramov.data(i)(7 downto 0);          when others =>	    ddatainv(i) := dcramov.data(i)(31 downto 8) & edata(7 downto 0);           end case;        when "01" =>          if maddress(1) = '0' then            ddatainv(i) := edata(15 downto 0) & dcramov.data(i)(15 downto 0);          else            ddatainv(i) := dcramov.data(i)(31 downto 16) & edata(15 downto 0);          end if;        when others =>           ddatainv(i) := edata;        end case;      end loop;--      ddatain := ddatainv(set);-- handle double load with pipeline hold    if (r.dstate = "000") and (r.nomds = '1') then      rdatav(0) := r.wb.data2; mexc := r.mexc; set := 0; --FIXME    end if;-- Handle AHB retry. Re-generate bus request and burst    if mcdo.retry = '1' then      v.req := '1';      v.burst := r.wb.size(0) and r.wb.size(1) and not r.wb.addr(2);    end if;-- Generate new valid bits    vmaskdbl := decode(maddress(LINE_HIGH downto LINE_LOW+1));    if (size = "11") and (read = '0') then       for i in 0 to (dlinesize - 1) loop vmaskraw(i) := vmaskdbl(i/2); end loop;    else      vmaskraw := decode(maddress(LINE_HIGH downto LINE_LOW));    end if;    vmask := (others => vmaskraw);    if r.hit = '1' then       for i in 0 to DSETS-1 loop vmask(i) := r.valid(i) or vmaskraw; end loop;    end if;    if r.dstate = "000" then --      vmask := dcramov.dtramout(set).valid or vmaskraw;      for i in 0 to DSETS-1 loop        vmask(i) := dcramov.tag(i)(dlinesize-1 downto 0) or vmaskraw;      end loop;    else      for i in 0 to DSETS-1 loop tag(i)(dlinesize-1 downto 0) := vmask(i); end loop;    end if;    if (mcdo.mexc or r.flush) = '1' then twrite := '0'; dwrite := '0'; end if;    if twrite = '1' then      v.valid := vmask;      if (DSETS>1) and (drepl = lru) and (tdiagwrite = '0') then        vl.write := '1'; vl.set := setrepl;      end if;    end if;    if (DSETS>1) and (drepl = 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;    if tdiagwrite = '1' then -- diagnostic tag write      if (dsu = 1) and (dci.dsuen = '1') then        vmask := (others => dci.maddress(dlinesize - 1 downto 0));      else        vmask := (others => dci.edata(dlinesize - 1 downto 0));        newtag(TAG_HIGH downto TAG_LOW) := dci.edata(TAG_HIGH downto TAG_LOW);        for i in 0 to 3 loop wlrr(i)  := dci.edata(CTAG_LRRPOS); end loop;        for i in 0 to DSETS-1 loop wlock(i) := dci.edata(CTAG_LOCKPOS); end loop;      end if;    end if;-- cache flush    if ((dci.flush or flush) = '1') and (dcen /= 0) then      v.flush := '1'; v.faddr := (others => '0');    end if;    if (r.flush = '1') and (dcen /= 0) then      twrite := '1'; vmask := (others => (others => '0'));       v.faddr := r.faddr +1; newtag(TAG_HIGH downto TAG_LOW) := (others => '0');      taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;      wlrr := (others => '0');      if (r.faddr(DOFFSET_BITS -1) and not v.faddr(DOFFSET_BITS -1)) = '1' then	v.flush := '0';      end if;      if DSNOOP = 2 then        vh.hit(conv_integer(taddr(OFFSET_HIGH downto OFFSET_LOW))) := (others => '0');      end if;    end if;-- AHB snoop handling (2), bypass write data on read/write contention    if DSNOOP /= 0 then      if tdiagwrite = '1' then snoopset2 := ddset;       else snoopset2 := conv_integer(setrepl); end if;      if DSNOOP = 2 then        vh.taddr := taddr(OFFSET_HIGH downto OFFSET_LOW);        vh.set := conv_std_logic_vector(set, SETBITS);	if (twrite = '1') and (r.dstate /= "000") then	  vh.hit(conv_integer(taddr(OFFSET_HIGH downto OFFSET_LOW)))(snoopset2) := '0';          	end if;      else        if rs.addr(OFFSET_HIGH  downto OFFSET_LOW) = 	  taddr(OFFSET_HIGH  downto OFFSET_LOW) 	then 	  if twrite = '0' then             if snoopwe = '1' then              vs.writebp(snoopset) := '1';              if DEST_RW then enable(snoopset) := '0'; end if;            end if;	  else            if (snoopwe = '1') and (conv_integer(setrepl) = snoopset) then  -- avoid write/write contention              twrite := '0';              if DEST_RW then enable(snoopset) := '0'; end if;            end if; 	  end if;	end if;      end if;      if (r.dstate = "001") and ((rbphit and rs.snoop) = '1') then v.hit := '0'; end if;      if DEST_RW then        -- disable snoop read enable on write/read contention        if taddr(OFFSET_HIGH downto OFFSET_LOW) = ahbsi.haddr(OFFSET_HIGH  downto OFFSET_LOW) then          for i in 0 to DSETS-1 loop            if (twrite and senable(i)) = '1' then senable(i) := '0'; end if;          end loop;        end if;      end if;    end if;-- update cache with memory data during read miss    if read = '1' then      for i in 0 to DSETS-1 loop ddatainv(i) := mcdo.data; end loop;    end if;-- cache write signals    if twrite = '1' then      if tdiagwrite = '1' then ctwrite(ddset) := '1';      else ctwrite(conv_integer(setrepl)) := '1'; end if;    end if;    if dwrite = '1' then      if ddiagwrite = '1' then cdwrite(ddset) := '1';      else cdwrite(conv_integer(setrepl)) := '1'; end if;    end if;          csnoopwe := (others => '0');     if ((snoopwe and not mcdo.scanen) = '1') then csnoopwe(snoopset) := '1'; end if;     if (r.flush and twrite) = '1' then   -- flush        ctwrite := (others => '1'); wlrr := (others => '0'); wlock := (others => '0');     end if;     if r.flush2 = '1' then      vl.lru := (others => (others => '0'));    end if;-- reset    if rst = '0' then       v.dstate := "000"; v.stpend  := '0'; v.req := '0'; v.burst := '0';      v.read := '0'; v.flush := '0'; v.nomds := '0'; v.holdn := '1';      v.rndcnt := (others => '0'); v.setrepl := (others => '0');      v.dsuset := (others => '0'); v.flush2 := '1';      v.lrr := '0'; v.lock := '0'; v.ilramen := '0';      v.cctrl.dcs := "00"; v.cctrl.ics := "00";      v.cctrl.burst := '0'; v.cctrl.dsnoop := '0';     end if;    if dsnoop = 0 then v.cctrl.dsnoop := '0'; end if;-- Drive signals    c <= v; cs <= vs;	ch <= vh; -- register inputs    cl <= vl;        -- tag ram inputs    senable := senable and not scanen; enable := enable and not scanen;    if mcdo.scanen = '1' then ctwrite := (others => '0'); end if;    for i in 0 to DSETS-1 loop      tag(i)(dlinesize-1 downto 0) := vmask(i);      tag(i)(TAG_HIGH downto TAG_LOW) := newtag(TAG_HIGH downto TAG_LOW);      tag(i)(CTAG_LRRPOS) := wlrr(i);      tag(i)(CTAG_LOCKPOS) := wlock(i);    end loop;    dcrami.tag <= tag;    dcrami.tenable   <= enable;    dcrami.twrite    <= ctwrite;    dcrami.flush    <= r.flush;    dcrami.senable <= senable;--vs.snoop or rs.snoop;    dcrami.swrite  <= csnoopwe;    dcrami.saddress(19 downto (OFFSET_HIGH - OFFSET_LOW +1)) <=     	zero32(19 downto (OFFSET_HIGH - OFFSET_LOW +1));    dcrami.saddress(OFFSET_HIGH - OFFSET_LOW downto 0) <= snoopaddr;    dcrami.stag(31 downto (TAG_HIGH - TAG_LOW +1)) <=    	zero32(31 downto (TAG_HIGH - TAG_LOW +1));    dcrami.stag(TAG_HIGH - TAG_LOW downto 0) <= rs.addr(TAG_HIGH downto TAG_LOW);    dcrami.tdiag <= mcdo.testen & "000";    dcrami.ddiag <= mcdo.testen & "000";    -- data ram inputs    dcrami.denable   <= enable;    dcrami.address(19 downto (OFFSET_HIGH - LINE_LOW + 1)) <= zero32(19 downto (OFFSET_HIGH - LINE_LOW + 1));    dcrami.address(OFFSET_HIGH - LINE_LOW downto 0) <= taddr;    dcrami.data <= ddatainv;    dcrami.dwrite    <= cdwrite;    dcrami.ldramin.address(23 downto 2) <= laddr(23 downto 2);    dcrami.ldramin.enable <= (lramcs or lramwr) and not mcdo.scanen;    dcrami.ldramin.read   <= rlramrd;    dcrami.ldramin.write  <= lramwr;    dcrami.dpar <= (others => (others => '0'));    dcrami.tpar <= (others => (others => '0'));    dcrami.ctx <= (others => (others => '0'));    dcrami.ptag <= (others => (others => '0'));    dcrami.tpwrite <= (others => '0');    -- memory controller inputs    mcdi.address  <= r.wb.addr;    mcdi.data     <= r.wb.data1;    mcdi.burst    <= r.burst;    mcdi.size     <= r.wb.size;    mcdi.read     <= r.wb.read;    mcdi.asi      <= r.wb.asi;    mcdi.lock     <= r.wb.lock;    mcdi.req      <= r.req;    mcdi.cache    <= orv(r.cctrl.dcs);    -- diagnostic instruction cache access    dco.icdiag.flush  <= iflush;    dco.icdiag.read   <= read;    dco.icdiag.tag    <= not r.asi(0);    dco.icdiag.addr   <= r.xaddress;    dco.icdiag.enable <= r.icenable;    dco.icdiag.ilramen <= r.ilramen;        dco.icdiag.cctrl <= r.cctrl;    dco.icdiag.scanen  <= mcdo.scanen;    dco.icdiag.pflush <= '0';    dco.icdiag.ctx <= '0';    dco.icdiag.ilock <= (others => '0');    dco.icdiag.pflushaddr <= (others => '0');     -- IU data cache inputs    dco.data <= rdatav;    dco.mexc <= mexc;    dco.set  <= conv_std_logic_vector(set, 2);    dco.hold <= r.holdn;    dco.mds  <= mds;    dco.werr <= mcdo.werr;    dco.idle <= sidle and not r.stpend;    dco.scanen <= mcdo.scanen;    dco.testen <= mcdo.testen;  end process;-- Local registers    reg1 : process(clk)    begin      if rising_edge(clk) then	r <= c;	if rst = '0' then r.wb.lock <= '0'; end if;	--sync reset for wb.lock  must be generated here to make	--gate level simulations possible with some synthesis tools      end if;     end process;    sn2 : if DSNOOP /= 0 generate      reg2 : process(sclk)      begin if rising_edge(sclk ) then rs <= cs; end if; end process;    end generate;    nosn2 : if DSNOOP = 0 generate      rs.snoop <= '0'; rs.writebp <= (others => '0');      rs.addr <= (others => '0'); rs.readbpx <= (others => '0');    end generate;    sn3 : if DSNOOP = 2 generate      reg3 : process(sclk)      begin if rising_edge(sclk ) then rh <= ch; end if; end process;    end generate;    nosn3 : if DSNOOP /= 2 generate      rh.hit <=  (others => (others => '0')); rh.taddr <=  (others => '0');      rh.set <=  (others => '0');    end generate;    reg2 : if (DSETS>1) and (drepl = lru) generate      reg2 : process(clk)      begin if rising_edge(clk ) then rl <= cl; end if; end process;    end generate;       noreg2 : if (DSETS = 1) or (drepl /= lru) generate      rl.write <= '0'; rl.waddr <= (others => '0');      rl.set <= (others => '0'); rl.lru <= (others => (others => '0'));    end generate;       -- pragma translate_off  chk : process  begin    assert not ((DSETS > 2) and (drepl = lrr)) report	"Wrong data cache configuration detected: LRR replacement requires 2 sets"    severity failure;    wait;  end process;-- pragma translate_onend ;

⌨️ 快捷键说明

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