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

📄 dcache.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
	    v.holdn := '1'; v.dstate := 0;
	  else
	    v.dstate := 3; v.wexc := '1'; v.mds := '0';
	    v.holdn := '0'; error := '0';
	  end if;
        end if;
      end if;
    when 1 => 		-- read miss, wait for memory data
      v.req := '1'; v.holdn := '0'; rdatasel := memory;
      v.burst := r.burst and not r.xaddress(2);
      if mcdo.ready = '1' then
         v.mds := r.nomds; v.req := v.burst; v.burst := '0'; v.dstate := 2; 
      end if;
    when 2 =>		-- read miss, update cache and send data to IU
      rdatasel := memory;
      if (mcdo.dcs = "01") then
	twrite := r.cachable and r.hit;
      elsif (mcdo.dcs(1) = '1') then
	twrite := r.cachable;
      end if; 
      dwrite := twrite;
      if (size = "11") and (r.xaddress(2) = '0') then
	v.xaddress(2) := '1';
        if mcdo.ready = '1' then 	-- true on 0-ws burst read
          v.dstate := 2;
        else
	  v.dstate := 1; v.req := '1'; v.nomds := not ico.hold;
	end if;
      else
	if (dci.enaddr = '1') and (mcdo.dcs /= "00") then
	  v.dstate := 3; v.holdn := '0';
	else
	  v.dstate := 0;
	end if;
      end if;
    when 3 =>		-- return from read miss with load pending
      taddr := dci.maddress(TAG_HIGH downto LINE_LOW);
      v.dstate := 0;
    when 4 => 		-- second part of double store cycle
      v.dstate := 0; v.wb.data2 := eaddress;
      if (mcdo.dcs /= "00") and (r.hit = '1') then  -- write hit
	twrite := '1'; dwrite := twrite;
      end if;
    when 5 =>		-- icache diag access
      rdatasel := icache; v.icenable := '1'; v.holdn := '0';
      if  ((ico.diagrdy and (not read)) or not r.mds) = '1' then
	v.dstate := 3; v.icenable := '0';
      elsif ico.diagrdy = '1' then
        v.mds := not read; v.icenable := read;
      end if;
    when others => null;
    end case;

-- select data to return on read access
-- align if byte/half word read from cache or memory.

    rdata := (others => '0');
    align_data := (others => '0');
    case rdatasel is
    when dtag	=> rdata(TAG_HIGH downto TAG_LOW) := dcramo.dtramout.tag;
                   rdata(DLINE_SIZE -1 downto 0) := dcramo.dtramout.valid;
                   rdata(31) := dcramo.dtramout.parity;
    when icache => rdata := ico.diagdata;
    when ddata | memory =>
      if rdatasel = ddata then align_data := dcramo.ddramout.data;
      else align_data := mcdo.data; end if;
      case size is
      when "00" => 			-- byte read
        case maddress(1 downto 0) 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 case;

-- select which data to update the data cache with

    if read = '1' then
      ddatain := mcdo.data;	-- load full word from memory
    else
      case size is		-- merge data during partial write
      when "00" =>
        case maddress(1 downto 0) is
	when "00" =>
	  ddatain := eaddress(7 downto 0) & dcramo.ddramout.data(23 downto 0);
	when "01" =>
	  ddatain := dcramo.ddramout.data(31 downto 24) & eaddress(7 downto 0) & 
		     dcramo.ddramout.data(15 downto 0);
	when "10" =>
	  ddatain := dcramo.ddramout.data(31 downto 16) & eaddress(7 downto 0) & 
		     dcramo.ddramout.data(7 downto 0);
	when others =>
	  ddatain := dcramo.ddramout.data(31 downto 8) & eaddress(7 downto 0); 
	end case;
      when "01" =>
        if maddress(1) = '0' then
          ddatain := eaddress(15 downto 0) & dcramo.ddramout.data(15 downto 0);
	else
          ddatain := dcramo.ddramout.data(31 downto 16) & eaddress(15 downto 0);
	end if;
      when others => 
 	ddatain := eaddress;
      end case;
    end if;

-- Generate new valid bits

    vmaskraw := decode(r.xaddress(LINE_HIGH downto LINE_LOW));

    case mcdo.dcs is
    when "00"	  => vmask := (others => '0');
    when "01"     => vmask := dcramo.dtramout.valid or vmaskraw;
    when others   => 
      if hit = '1' then vmask := dcramo.dtramout.valid or vmaskraw;
      else vmask := vmaskraw; end if;
    end case;

    if mcdo.mexc = '1' then 
      vmask := vmask and not vmaskraw; dwrite := '0';
    end if;

    if tdiagwrite = '1' then -- diagnostic tag write
      vmask  := eaddress(DLINE_SIZE - 1 downto 0);
    end if;

    if (r.dstate /= 0) and (twrite = '1') then 
      taddr(OFFSET_HIGH downto LINE_LOW) := r.xaddress(OFFSET_HIGH downto LINE_LOW);
    end if;

    v.lineaddr := taddr(LINE_HIGH downto LINE_LOW);

-- cache flush

    if (dci.flush or flush) = '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; 
      maddress(TAG_HIGH downto TAG_LOW) := (others => '0');
      taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;
      taddr(OFFSET_LOW-1 downto LINE_LOW) := (others => '0');
      if (r.faddr(DOFFSET_BITS -1) and not v.faddr(DOFFSET_BITS -1)) = '1' then
	v.flush := '0';
      end if;
    end if;

-- parity generation

    v.taddrpar := '0';
    if DTAGPAR then
      v.taddrpar := xorv(taddr(OFFSET_HIGH downto OFFSET_LOW)) and DTAGAPAR;
    end if;

    v.daddrpar := '0';
    if DDATPAR then
      v.daddrpar := xorv(taddr(OFFSET_HIGH downto LINE_LOW)) and DDATAPAR;
    end if;

    tparin := '0'; v.dparerr2 := '0';
    if DTAGPAR then
      tparin := xorv(vmask & maddress(TAG_HIGH downto TAG_LOW));
      if (r.flush and DTAGAPAR) = '1' then
        tparin := xorv(r.faddr & tparin);
      else
        tparin := xorv(v.taddrpar & tparin);
      end if; 
--      if tdiagwrite = '1' then tparin := tparin xor maddress(31); end if;
      if tdiagwrite = '1' then tparin := tparin xor dci.maddress(31); end if;
      v.dparerr2 := r.dparerr;
    end if;

    dparin := '0'; v.tparerr2 := '0';
    if DDATPAR then
      dparin := xorv(v.daddrpar & ddatain); v.tparerr2 := r.tparerr;
--      if ddiagwrite = '1' then dparin := dparin xor maddress(31); end if;
      if ddiagwrite = '1' then dparin := dparin xor dci.maddress(31); end if;
    end if;

-- reset

    if rst = '0' then 
      v.dstate := 0; v.stpend  := '0'; v.req := '0'; v.burst := '0';
      v.read := '0'; v.flush := '0'; v.werr := '0';
    end if;

-- Drive signals

    c <= v;	-- register inputs

    -- tag ram inputs
    dcrami.dtramin.valid    <= vmask;
    dcrami.dtramin.tag      <= maddress(TAG_HIGH downto TAG_LOW);
    dcrami.dtramin.enable   <= enable;
    dcrami.dtramin.write    <= twrite;
    dcrami.dtramin.parity   <= tparin;

    -- data ram inputs
    dcrami.ddramin.enable   <= enable;
    dcrami.ddramin.address  <= taddr(OFFSET_HIGH downto LINE_LOW) ;
    dcrami.ddramin.data     <= ddatain;
    dcrami.ddramin.write    <= dwrite;
    dcrami.ddramin.parity   <= dparin;

    -- memory controller inputs
    mcdi.address  <= r.wb.addr;
    if (r.burst and mcdo.ready) = '1' then
      mcdi.data     <= r.wb.data2;
    else
      mcdi.data     <= r.wb.data1;
    end if;
    mcdi.asi      <= r.wb.asi;
    mcdi.burst    <= r.burst;
    mcdi.size     <= r.wb.size;
    mcdi.read     <= r.wb.read;
    mcdi.req      <= r.req;
    mcdi.tparerr  <= r.tparerr and not r.tparerr2;
    mcdi.dparerr  <= r.dparerr and not r.dparerr2;
    mcdi.flush    <= r.flush;

    -- diagnostic instruction cache

   dco.icdiag.flush   <= iflush;
   dco.icdiag.read   <= read;
   dco.icdiag.tag    <= not asi(0);
   dco.icdiag.addr   <= r.xaddress;
   dco.icdiag.enable <= r.icenable;
 
    -- IU data cache inputs
    dco.data  <= rdata;
    dco.mexc  <= (mcdo.mexc and not r.stpend) or r.wexc or error;
    dco.wexc  <= r.wexc or werr;
    dco.hold  <= r.holdn;
    dco.mds   <= r.mds;

  end process;

-- Local registers

  dlat : process(clk)
  begin
    if clk'event and (clk='1') then
      r <= c;
    end if;
  end process;

end ;

⌨️ 快捷键说明

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