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

📄 mmu_dcache.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 4 页
字号:
        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;-- handle double load with pipeline hold    if (r.dstate = idle) 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 (DLINE_SIZE - 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 = idle then       for i in 0 to DSETS-1 loop        vmask(i) := dcramov.tag(i)(dlinesize-1 downto 0) or vmaskraw;      end loop;    end if;    if (mcdo.mexc or r.flush) = '1' then twrite := '0'; dwrite := '0'; end if;    if twrite = '1' then      if tagclear = '1' then vmask := (others => (others => '0')); end if;      v.valid := vmask;      if (DSETS>1) and (DCREPLACE = lru) and (tdiagwrite = '0') then        vl.write := '1'; vl.set := setrepl;      end if;    end if;    if (DSETS>1) and (DCREPLACE = 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);        newptag(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;    -- mmureg write    if mmuregw = '1' then      case mmudiagaddr is        when CNR_CTRL =>          v.mmctrl1.e      := mmuwdata(MMCTRL_E);          v.mmctrl1.nf     := mmuwdata(MMCTRL_NF);          v.mmctrl1.pso    := mmuwdata(MMCTRL_PSO);          v.mmctrl1.tlbdis := mmuwdata(MMCTRL_TLBDIS);          --custom           -- Note: before tlb disable tlb flush is required !!!          when CNR_CTXP =>          v.mmctrl1.ctxp := mmuwdata(MMCTXP_U downto MMCTXP_D);        when CNR_CTX =>          v.mmctrl1.ctx  := mmuwdata(MMCTXNR_U downto MMCTXNR_D);        when CNR_F => null;        when CNR_FADDR => null;        when others => null;      end case;    end if;            -- cache flush    --if (dci.flush or flush or mcdo.dflush) = '1' then    if (dci.flush or flush ) = '1' then      v.flush := '1'; v.faddr := (others => '0'); v.pflush := pflush;      v.pflushr := '1';      v.pflushaddr := pflushaddr;      v.pflushtyp := pflushtyp;    end if;        if r.flush = '1' then            twrite := '1'; vmask := (others=>(others => '0')); v.faddr := r.faddr +1;       newtag(TAG_HIGH downto TAG_LOW) := (others => '0');      newptag(TAG_HIGH downto TAG_LOW) := (others => '0');      taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;      wlrr := (others => '0'); v.lrr := '0';       if (r.faddr(DOFFSET_BITS -1) and not v.faddr(DOFFSET_BITS -1)) = '1' then	v.flush := '0';      end if;            if DSNOOP2 = 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 DSNOOP2 /= 0 then      if tdiagwrite = '1' then snoopset2 := ddset;       else snoopset2 := conv_integer(setrepl); end if;      if DSNOOP2 = 2 then        vh.taddr := taddr(OFFSET_HIGH downto OFFSET_LOW);        vh.set := conv_std_logic_vector(set, SETBITS);	if (twrite = '1') and (r.dstate /= idle) 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 = wread) 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 M_EN then    if tpwrite = '1' then      if tdiagwrite = '1' then ctpwrite(ddset) := '1';      else ctpwrite(conv_integer(setrepl)) := '1'; end if;    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');       if M_EN then         ctpwrite := (others => '1');       end if;              -- precise flush, ASI_FLUSH_PAGE & ASI_FLUSH_CTX       if false then                    --       if M_EN then        if r.pflush = '1' then          twrite := '0'; ctwrite := (others => '0');          for i in DSETS-1 downto 0 loop            wlrr(i) := dcramov.tag(i)(CTAG_LRRPOS);             wlock(i) := dcramov.tag(i)(CTAG_LOCKPOS);          end loop;          if r.pflushr = '0' then            for i in DSETS-1 downto 0 loop              pftag(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;              pftag(TAG_HIGH downto TAG_LOW) := dcramov.tag(i)(TAG_HIGH downto TAG_LOW);              if ((pftag(VA_I_U downto VA_I_D) = r.pflushaddr(VA_I_U downto VA_I_D)) or                  (r.pflushtyp = '1')) then                ctwrite(i) := '1';                wlrr(i) := '0';                wlock(i) := '0';              end if;            end loop;          else            v.faddr := r.faddr;          end if;          v.pflushr := not r.pflushr;        end if;      end if;       end if;     end if;     if r.flush2 = '1' then      vl.lru := (others => (others => '0'));    end if;        -- reset    if rst = '0' then       v.dstate := idle; 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.lrr := '0'; v.lock := '0'; v.flush2 := '1';      v.cctrl.dcs := "00"; v.cctrl.ics := "00";      v.cctrl.burst := '0'; v.cctrl.dsnoop := '0';      v.mmctrl1.e := '0'; v.mmctrl1.nf := '0'; v.mmctrl1.ctx := (others => '0');      v.mmctrl1.tlbdis := '0';      v.mmctrl1.pso := '0';      v.trans_op := '0';       v.flush_op := '0';       v.diag_op := '0';      v.pflush := '0';      v.pflushr := '0';      v.mmctrl1.bar := (others => '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 ctpwrite := (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);      ctx(i) := r.mmctrl1.ctx;      ptag(i)(TAG_HIGH downto TAG_LOW) := newptag(TAG_HIGH downto TAG_LOW);    end loop;    dcrami.tag <= tag;    dcrami.ptag <= ptag;    dcrami.ctx <= ctx;    dcrami.tenable   <= enable;    dcrami.twrite    <= ctwrite;    dcrami.tpwrite   <= ctpwrite;    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;    -- 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);    --mcdi.flush    <= r.flush;    -- diagnostic instruction cache access    dco.icdiag.flush  <= iflush;-- or mcdo.iflush;    dco.icdiag.pflush <= pflush;    dco.icdiag.pflushaddr <= pflushaddr;    dco.icdiag.pflushtyp <= pflushtyp;    dco.icdiag.read   <= read;    dco.icdiag.tag    <= (not r.asi(0));-- and (not r.asi(4));    dco.icdiag.ctx    <= r.asi(4); --ASI_ICTX "10101"    dco.icdiag.addr   <= r.xaddress;    dco.icdiag.enable <= r.icenable;    dco.icdiag.cctrl <= r.cctrl;    dco.icdiag.scanen  <= mcdo.scanen;       -- 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;        -- MMU    mmudci.trans_op <= mmudci_trans_op;        mmudci.transdata.data <= mmudci_transdata_data; --r.vaddr;    mmudci.transdata.su <= mmudci_su;    mmudci.transdata.read <= mmudci_read;    mmudci.transdata.isid <= id_dcache;    mmudci.transdata.wb_data <= dci.maddress;        mmudci.flush_op <= mmudci_flush_op;    mmudci.wb_op <= mmudci_wb_op;    mmudci.diag_op <= mmudci_diag_op;    mmudci.fsread <= mmudci_fsread;    mmudci.mmctrl1 <= r.mmctrl1;  end process;-- Local registers    reg1 : process(clk)    begin if rising_edge(clk ) then r <= c; end if; end process;      sn2 : if DSNOOP2 /= 0 generate      reg2 : process(sclk)      begin if rising_edge(sclk ) then rs <= cs; end if; end process;    end generate;      nosn2 : if DSNOOP2 = 0 generate      rs.snoop <= '0'; rs.writebp <= (others => '0');      rs.addr <= (others => '0'); rs.readbpx <= (others => '0');    end generate;      sn3 : if DSNOOP2 = 2 generate      reg3 : process(sclk)      begin if rising_edge(sclk ) then rh <= ch; end if; end process;    end generate;    sn3no : if DSNOOP2 /= 2 generate      rh.hit <= (others => (others => '0'));      rh.taddr <= (others => '0');      rh.set <= (others => '0');    end generate;    reg2 : if (DSETS>1) and (DCREPLACE = 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 (DCREPLACE = 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 + -