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

📄 dcache.vhd

📁 sparc org, vhdl rtl code
💻 VHD
📖 第 1 页 / 共 3 页
字号:
          if maddress(1) = '1' then 
	    rdata(15 downto 0) := mcdo.data(15 downto 0);
	    if signed = '1' then rdata(31 downto 15) := (others => mcdo.data(15)); end if;
	  else
	    rdata(15 downto 0) := mcdo.data(31 downto 16);
	    if signed = '1' then rdata(31 downto 15) := (others => mcdo.data(31)); end if;
	  end if;
        when others => 			-- single and double word read
	  rdata := mcdo.data;
        end case;
        else
        rdata := (others => '0');
	for i in 0 to DSETS-1 loop
          case size is
          when "00" => 			-- byte read
            case maddrlow is
	    when "00" => 
	      rdatav(i)(7 downto 0) := dcramov.ddramout(i).data(31 downto 24);
	      if signed = '1' then rdatav(i)(31 downto 8) := (others => dcramov.ddramout(i).data(31)); end if;
	    when "01" => 
	      rdatav(i)(7 downto 0) := dcramov.ddramout(i).data(23 downto 16);
	      if signed = '1' then rdatav(i)(31 downto 8) := (others => dcramov.ddramout(i).data(23)); end if;
	    when "10" => 
	      rdatav(i)(7 downto 0) := dcramov.ddramout(i).data(15 downto 8);
	      if signed = '1' then rdatav(i)(31 downto 8) := (others => dcramov.ddramout(i).data(15)); end if;
	    when others => 
	      rdatav(i)(7 downto 0) := dcramov.ddramout(i).data(7 downto 0);
	      if signed = '1' then rdatav(i)(31 downto 8) := (others => dcramov.ddramout(i).data(7)); end if;
            end case;
          when "01" => 			-- half-word read
            if maddress(1) = '1' then 
	      rdatav(i)(15 downto 0) := dcramov.ddramout(i).data(15 downto 0);
	      if signed = '1' then rdatav(i)(31 downto 15) := (others => dcramov.ddramout(i).data(15)); end if;
	    else
	      rdatav(i)(15 downto 0) := dcramov.ddramout(i).data(31 downto 16);
	      if signed = '1' then rdatav(i)(31 downto 15) := (others => dcramov.ddramout(i).data(31)); end if;
	    end if;
          when others => 			-- single and double word read
	    rdatav(i) := dcramov.ddramout(i).data;
          end case;
          if validrawv(i) = '1' then rdata := rdata or rdatav(i); end if;
        end loop;
        end if;
      else
        if rdatasel = ddata then align_data := dcramov.ddramout(set).data;
        else align_data := mcdo.data; end if;
        case size is
        when "00" => 			-- byte read
          case maddrlow is
	  when "00" => 
	    rdata(7 downto 0) := align_data(31 downto 24);
	    if signed = '1' then rdata(31 downto 8) := (others => align_data(31)); end if;
	  when "01" => 
	    rdata(7 downto 0) := align_data(23 downto 16);
	    if signed = '1' then rdata(31 downto 8) := (others => align_data(23)); end if;
	  when "10" => 
	    rdata(7 downto 0) := align_data(15 downto 8);
	    if signed = '1' then rdata(31 downto 8) := (others => align_data(15)); end if;
	  when others => 
	    rdata(7 downto 0) := align_data(7 downto 0);
	    if signed = '1' then rdata(31 downto 8) := (others => align_data(7)); end if;
          end case;
        when "01" => 			-- half-word read
          if maddress(1) = '1' then 
	    rdata(15 downto 0) := align_data(15 downto 0);
	    if signed = '1' then rdata(31 downto 15) := (others => align_data(15)); end if;
	  else
	    rdata(15 downto 0) := align_data(31 downto 16);
	    if signed = '1' then rdata(31 downto 15) := (others => align_data(31)); end if;
	  end if;
        when others => 			-- single and double word read
	  rdata := align_data;
        end case;
      end if;
    end case;

-- select which data to update the data cache with

    if DWRITE_FAST then
      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.ddramout(i).data(23 downto 0);
          when "01" =>
	    ddatainv(i) := dcramov.ddramout(i).data(31 downto 24) & edata(7 downto 0) & 
		     dcramov.ddramout(i).data(15 downto 0);
          when "10" =>
	    ddatainv(i) := dcramov.ddramout(i).data(31 downto 16) & edata(7 downto 0) & 
		     dcramov.ddramout(i).data(7 downto 0);
          when others =>
	    ddatainv(i) := dcramov.ddramout(i).data(31 downto 8) & edata(7 downto 0); 
          end case;
        when "01" =>
          if maddress(1) = '0' then
            ddatainv(i) := edata(15 downto 0) & dcramov.ddramout(i).data(15 downto 0);
          else
            ddatainv(i) := dcramov.ddramout(i).data(31 downto 16) & edata(15 downto 0);
          end if;
        when others => 
          ddatainv(i) := edata;
        end case;

      end loop;
      ddatain := ddatainv(set);

    else
      case size is		-- merge data during partial write
      when "00" =>
        case maddrlow is
        when "00" =>
	  ddatain := edata(7 downto 0) & dcramov.ddramout(set).data(23 downto 0);
        when "01" =>
	  ddatain := dcramov.ddramout(set).data(31 downto 24) & edata(7 downto 0) & 
		     dcramov.ddramout(set).data(15 downto 0);
        when "10" =>
	  ddatain := dcramov.ddramout(set).data(31 downto 16) & edata(7 downto 0) & 
		     dcramov.ddramout(set).data(7 downto 0);
        when others =>
	  ddatain := dcramov.ddramout(set).data(31 downto 8) & edata(7 downto 0); 
        end case;
      when "01" =>
        if maddress(1) = '0' then
          ddatain := edata(15 downto 0) & dcramov.ddramout(set).data(15 downto 0);
        else
          ddatain := dcramov.ddramout(set).data(31 downto 16) & edata(15 downto 0);
        end if;
      when others => 
        ddatain := edata;
      end case;

    end if;

-- handle double load with pipeline hold

    if (r.dstate = "000") and (r.nomds = '1') then
      rdata := r.wb.data2; mexc := r.mexc;
    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 := vmaskraw;
    if r.hit = '1' then vmask := r.valid or vmaskraw; end if;
    if r.dstate = "000" then 
--      vmask := dcramov.dtramout(set).valid or vmaskraw;
      vmask := ivalid or vmaskraw;

    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 (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 DEBUG_UNIT and (dci.dsuen = '1') then
        vmask := dci.maddress(DLINE_SIZE - 1 downto 0);
      else
        vmask := dci.edata(DLINE_SIZE - 1 downto 0);
        newtag(TAG_HIGH downto TAG_LOW) := dci.edata(TAG_HIGH downto TAG_LOW);
        for i in 0 to 1 loop wlrr(i)  := dci.edata(DCTAG_LRRPOS); end loop;
        for i in 0 to DSETS-1 loop wlock(i) := dci.edata(DCTAG_LOCKPOS); end loop;
      end if;
    end if;

-- cache flush

    if (dci.flush or flush or mcdo.dflush) = '1' then
      v.flush := '1'; v.faddr := (others => '0');
    end if;

    if r.flush = '1' then
      twrite := '1'; vmask := (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;
    end if;

-- AHB snoop handling (2), bypass write data on read/write contention

    if DSNOOP then
-- pragma translate_off
      if not is_x(setrepl) then
-- pragma translate_on
        if tdiagwrite = '1' then snoopset2 := ddset; 
	else snoopset2 := conv_integer(setrepl); end if;
-- pragma translate_off
      end if;
-- pragma translate_on
      if DSNOOP_FAST then
        vh.taddr := taddr(OFFSET_HIGH downto OFFSET_LOW);
        vh.set := std_logic_vector(conv_unsigned(set, SETBITS));
	if twrite = '1' then 
-- pragma translate_off
          if not is_x(taddr(OFFSET_HIGH downto OFFSET_LOW)) then
-- pragma translate_on
	    vh.hit(conv_integer(taddr(OFFSET_HIGH downto OFFSET_LOW)))(snoopset2) := '0';
-- pragma translate_off
          end if;
-- pragma translate_on
	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'; end if;
	  else
            if (snoopwe = '1') and (conv_integer(setrepl) = snoopset) 
            then twrite := '0'; end if; -- avoid write/write contention
	  end if;
	end if;
      end if;
    end if;

-- update cache with memory data during read miss

    if read = '1' then ddatain := mcdo.data; 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 = '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.flush or (not rst)) = '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.rndcnt := (others => '0'); v.setrepl := (others => '0');
      v.dsuset := (others => '0');
      v.lrr := '0'; v.lock := '0';
    end if;


-- Drive signals

    c <= v; cs <= vs;	ch <= vh; -- register inputs
    cl <= vl;

    
    -- tag ram inputs
    dcrami.dtramin.valid    <= vmask;
    dcrami.dtramin.tag      <= newtag(TAG_HIGH downto TAG_LOW);
    dcrami.dtramin.lrr      <= wlrr;
    dcrami.dtramin.lock     <= wlock;
    dcrami.dtramin.enable   <= enable;
    dcrami.dtramin.write    <= ctwrite;
    dcrami.dtramin.flush    <= r.flush;
    dcrami.dtraminsn.enable <= vs.snoop or rs.snoop;
    dcrami.dtraminsn.write  <= csnoopwe;
    dcrami.dtraminsn.address<= snoopaddr;
    dcrami.dtraminsn.tag    <= rs.addr(TAG_HIGH downto TAG_LOW);
    
    -- data ram inputs
    dcrami.ddramin.enable   <= enable;
    dcrami.ddramin.address  <= taddr;
    dcrami.ddramin.data     <= ddatain;
    dcrami.ddramin.write    <= cdwrite;
    dcrami.ldramin.address  <= laddr(LOCAL_RAM_BITS+1 downto 2);
    dcrami.ldramin.enable   <= lramcs or lramwr;
    dcrami.ldramin.read     <= r.lramrd or lramrd;
    dcrami.ldramin.write    <= lramwr;

    -- 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 or dci.lock;
    mcdi.req      <= r.req;
    mcdi.flush    <= r.flush;

    -- diagnostic instruction cache access
    dco.icdiag.flush  <= iflush or mcdo.iflush;
    dco.icdiag.read   <= read;
    dco.icdiag.tag    <= not r.asi(0);
    dco.icdiag.addr   <= r.xaddress;
    dco.icdiag.enable <= r.icenable;
    dco.dsudata       <= dsudata;	-- debug unit
 
    -- IU data cache inputs
    dco.data  <= rdata;
    dco.mexc  <= mexc;
    dco.hold  <= r.holdn;
    dco.mds   <= mds;
    dco.werr  <= mcdo.werr;
    
  end process;

-- Local registers

    reg1 : process(clk)
    begin if rising_edge(clk ) then r <= c; end if; end process;
    sn2 : if DSNOOP generate
      reg2 : process(clk)
      begin if rising_edge(clk ) then rs <= cs; end if; end process;
    end generate;
    sn3 : if DSNOOP_FAST generate
      reg3 : process(clk)
      begin if rising_edge(clk ) then rh <= ch; end if; end process;
    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;   

    
-- 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_on

end ;

⌨️ 快捷键说明

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