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

📄 iu.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
  memory_stage : process(me, wr, sregs, sregsin, sysi, dco)
  variable op    : std_logic_vector(1 downto 0);
  variable op3   : std_logic_vector(5 downto 0);
  variable ctrl  : pipeline_control_type;
  variable nullify : std_logic;
  variable iflush : std_logic;
  variable write_cwp : std_logic;
  variable cwp   : std_logic_vector(NWINLOG2-1 downto 0);

  begin

-- common initialisation

    op    := me.ctrl.inst(31 downto 30);
    op3   := me.ctrl.inst(24 downto 19);
    ctrl := me.ctrl;
    ctrl.annul := ctrl.annul or wr.annul_all;
    nullify := ctrl.annul;
    iflush := '0';
    cwp := me.cwp; write_cwp := me.write_cwp;

-- external interrupt handling

    -- use sregsin.pil and sregsin.et since a WRPSR should affect ET and PIL
    -- without delay (SPARC V8 ISP, p.183)
    if ((ctrl.annul or ctrl.trap) = '0') and ((sregsin.et and ctrl.pv) = '1') then
      if (sysi.irl = "1111") or (sysi.irl > sregsin.pil) then
	ctrl.trap := '1'; ctrl.tt := "01" & sysi.irl;
        if op = LDST then nullify := '1'; end if;
      end if;
    end if;


    if ((ctrl.annul or ctrl.trap) /= '1') then
      case op is
      when FMT3 =>
        case op3 is
	when WRPSR =>
	  if me.result(4 downto NWINLOG2) /= CWPFILL then
	    ctrl.trap := '1'; ctrl.tt := IINST_TT;
	  else
	    cwp := me.result(NWINLOG2-1 downto 0); write_cwp := '1';
	  end if;
	when JMPL | RETT =>
	  if me.addr_misal = '1' then ctrl.trap := '1'; ctrl.tt := UNALA_TT; end if;
        when TADDCCTV | TSUBCCTV =>
	  if me.icc(1) = '1' then ctrl.trap := '1'; ctrl.tt := TAG_TT; end if;
	when FLUSH => iflush := '1';
        when others => null;
        end case;
      when LDST =>
        if ctrl.cnt = "00" then
          case op3 is
	  when LDD | ISTD | LDDA | STDA =>
	    if me.result(2 downto 0) /= "000" then
	      ctrl.trap := '1'; ctrl.tt := UNALA_TT; nullify := '1';
	    end if;
 	  when LD | LDA | ST | STA | SWAP =>
	    if me.result(1 downto 0) /= "00" then
	      ctrl.trap := '1'; ctrl.tt := UNALA_TT; nullify := '1';
	    end if;
          when LDUH | LDUHA | LDSH | LDSHA | STH | STHA =>
	    if me.result(0) /= '0' then
	      ctrl.trap := '1'; ctrl.tt := UNALA_TT; nullify := '1';
	    end if;
          when others => null;
          end case;
	end if;
      when others => null;
      end case;
    end if;

    if (me.memory_load or not dco.mds) = '1' then
      wrin.result <= dco.data;
    else 
      wrin.result <= me.result;    -- data load bus
    end if;

    if ((ctrl.annul or ctrl.trap) /= '1') and (me.write_y = '1') then
      wrin.y <= me.y;
    else
      wrin.y <= wr.y;
    end if;

    wrin.cwp <= cwp; wrin.write_cwp <= write_cwp;
    wrin.ctrl <= ctrl;
    ici.flush <= iflush;
    dci.flush <= iflush;
    dci.nullify <= nullify;
    dci.maddress <= me.result;

  end process;

-------------------------------------------------------------------------------
-- write stage
-------------------------------------------------------------------------------

  write_stage : process(rst, wr, sregs, de, ex, me)
  variable op     : std_logic_vector(1 downto 0);
  variable op3    : std_logic_vector(5 downto 0);
  variable rd_address : std_logic_vector(RABITS-1 downto 0);
  variable write_reg : std_logic;
  variable annul_all : std_logic;
  variable cwp : std_logic_vector(NWINLOG2-1 downto 0);
  variable icc : std_logic_vector(3 downto 0);
  variable tt     : std_logic_vector(7 downto 0);
  variable tba    : std_logic_vector(19 downto 0);
  variable wim    : std_logic_vector(NWINDOWS-1 downto 0);
  variable pil    : std_logic_vector(3 downto 0);
  variable ec, ef, ps, s, et : std_logic;
  variable exception : std_logic;
  variable trapping : std_logic;
  variable save_pc : std_logic;
  variable error : std_logic;
  variable intack : std_logic;
  variable tpcsel    : std_logic_vector(1 downto 0);
  variable trap_address : std_logic_vector(31 downto PCLOW);    --  trap address


  begin

-- common initialisation

    op    := wr.ctrl.inst(31 downto 30);
    op3   := wr.ctrl.inst(24 downto 19);

    rd_address := wr.ctrl.rd;
    write_reg := '0';

    annul_all := '0'; exception := '0';
    trapping := wr.trapping; tpcsel := "00";
    save_pc := '0'; error := wr.error; intack := '0';
    trap_address(31 downto 4) := sregs.tba & sregs.tt; 
    trap_address(3 downto PCLOW) := (others => '0');

-- special registers write handling

    icc := sregs.icc; cwp := sregs.cwp; ef := sregs.ef; ec := sregs.ec;
    pil := sregs.pil; s := sregs.s; ps := sregs.ps; et := sregs.et; 
    tba := sregs.tba; tt := sregs.tt; wim := sregs.wim;

    if (wr.ctrl.annul or wr.ctrl.trap) /= '1' then
      if wr.write_cwp = '1' then
        cwp := wr.cwp;
      end if;
      write_reg := wr.write_reg;
      case op is
      when FMT3 =>
        case op3 is
        when WRPSR =>
          cwp := wr.result(NWINLOG2-1 downto 0);
          icc := wr.result(23 downto 20);
          ec  := wr.result(13);
          ef  := wr.result(12);
          pil := wr.result(11 downto 8);
          s   := wr.result(7);
          ps  := wr.result(6);
          et  := wr.result(5);
        when WRWIM =>
          wim := wr.result(NWINDOWS-1 downto 0);
        when WRTBR =>
          tba := wr.result(31 downto 12);
        when RETT =>
          s := ps;
          et := '1';
        when others => null;
        end case;
      when others => null;
      end case;
      if wr.write_icc = '1' then
        icc := wr.icc;
      end if;
    end if;

-- trap handling

    if (((wr.ctrl.trap and not wr.ctrl.annul) or wr.mexc or trapping) = '1') then
      if trapping = '0' then			-- first trap cycle
        if et = '0' then 
	  error := HALTONERROR;
	end if;
        annul_all := '1'; trapping := '1'; ps := s; s := '1';
	if wr.wexc = '1' then tt := "00" & DSEX_TT;
	elsif wr.mexc = '1' then tt := "00" & DAEX_TT;
	elsif wr.ctrl.tt = TICC_TT then tt := '1' & wr.result(6 downto 0);
        else tt := "00" & wr.ctrl.tt; end if;
        write_reg := '1'; save_pc := '1';
-- pragma translate_off
        if not is_x(cwp) then
-- pragma translate_on
	  rd_address := (others => '0');
	  rd_address (NWINLOG2 + 3 downto 0) := cwp & "0001";
-- pragma translate_off
	end if;
-- pragma translate_on

        if ((not me.ctrl.annul) and me.ctrl.pv) = '1' then tpcsel := "00";
        elsif ((not ex.ctrl.annul) and ex.ctrl.pv) = '1' then tpcsel := "01";
        elsif ((not de.annul) and de.pv) = '1' then tpcsel := "10";
        else tpcsel := "11"; end if;
      else					-- second trap cycle
        if error = '1' then
	  annul_all := '1'; trapping := '1';
	else
          trapping := '0'; annul_all := '1';
	  if sregs.tt(5 downto 4) = "01" then intack := '1'; end if;
          write_reg := '1'; save_pc := '1';
-- pragma translate_off
          if not is_x(cwp) then
-- pragma translate_on
	    rd_address := (others => '0');
	    rd_address (NWINLOG2 + 3 downto 0) := cwp & "0010";
-- pragma translate_off
	  end if;
-- pragma translate_on
-- pragma translate_off
        if not is_x(cwp) then
-- pragma translate_on
	  if (not CWPOPT) and (cwp = CWPMIN) then cwp := CWPMAX;
	  else cwp := cwp - 1; end if;
-- pragma translate_off
	end if;
-- pragma translate_on
	end if;
	exception := '1'; et := '0';
      end if;
      if ((not sregs.et) and (not HALTONERROR)) = '1' then 
	trap_address(11 downto 4) := (others => '0');
      end if;
    end if;

-- pragma translate_off
    if DEBUGPORT then
      debug.tt <= tt;
      debug.trap <= trapping;
    end if;
-- pragma translate_on

-- reset handling

    if Rst = '0' then
      et := '0'; s := '1'; annul_all := '1';
      trapping := '0'; save_pc := '0'; exception := '0'; error := '0';
    end if;

    if save_pc = '1' then
      case wr.tpcsel is
      when "00" => rfi.wrdata <= wr.ctrl.pc(31 downto 2) & "00";
      when "01" => rfi.wrdata <= me.ctrl.pc(31 downto 2) & "00";
      when "10" => rfi.wrdata <= ex.ctrl.pc(31 downto 2) & "00";
      when others => rfi.wrdata <= de.pc(31 downto 2) & "00";
      end case;
    else
      rfi.wrdata <= wr.result;
    end if;

    syso.error <= not wr.error;
    syso.intack <= wr.intack;
    syso.irqvec <= sregs.tt(3 downto 0);
    wr.annul_all <= annul_all;
    wrin.trapping <= trapping;
    wrin.tpcsel <= tpcsel;
    wrin.error <= error;
    wrin.intack <= intack;
    sregsin.cwp <= cwp;
    sregsin.icc <= icc;
    sregsin.ec  <= ec;
    sregsin.ef  <= ef;
    sregsin.pil <= pil;
    sregsin.s   <= s;
    sregsin.ps  <= ps;
    sregsin.et  <= et;
    sregsin.wim <= wim;
    sregsin.tba <= tba;
    sregsin.tt  <= tt;
    rfi.wraddr <= rd_address;
    rfi.wren <= write_reg;
    fecomb.exception <= exception;
    fecomb.trap_address <= trap_address;

  end process;

-- missed instruction and data registers

  instmux : process(dein, ico, de, fecomb)
  begin
    if (ico.mds and fecomb.hold_pc) = '1' then
      dein.inst <= de.inst;
      dein.mexc <= de.mexc;
    else
      dein.inst <= ico.data;
      dein.mexc <= ico.exception;
    end if;
  end process;

  ir0: if GATEDCLK generate  -- use generate to make sure no gates are placed
    iregs : process (iclk)   -- on the clock line during synthesis
    begin
      if iclk'event and (iclk = '1') then
        de.inst <= dein.inst;
        de.mexc <= dein.mexc;
      end if;
    end process;
    dregs : process(dclk)
    begin
      if dclk'event and dclk = '1' then
        wr.result <= wrin.result;
	wr.mexc <= dco.mexc;
	wr.wexc <= dco.wexc;
      end if;
    end process;
  end generate;

  ir1: if not GATEDCLK generate
    iregs : process (clk)
    begin
      if clk'event and (clk = '1') then
        if (holdn or (not ico.mds)) = '1' then
          de.inst <= dein.inst;
          de.mexc <= dein.mexc;
        end if;
      end if;
    end process;
    dregs : process(clk)
    begin
      if clk'event and clk = '1' then
        if (holdn or (not dco.mds)) = '1' then
	  wr.mexc <= dco.mexc;
	  wr.wexc <= dco.wexc;
          wr.result <= wrin.result;
        end if;
      end if;
    end process;
  end generate;

-- normal registers

  pregs : process (clk)
  begin
    if clk'event and (clk = '1') then
      if (holdn = '1') or GATEDCLK then

-- fetch stage
      fe <= fein;
-- decode stage
      de.annul <= dein.annul;
      de.cnt <= dein.cnt;
      de.mulcnt <= dein.mulcnt;
      de.cwp <= dein.cwp;
      de.pv <= dein.pv;
      de.pc <= dein.pc;

-- execute stage
      ex.ctrl <= exin.ctrl;
      ex.write_reg <= exin.write_reg;
      ex.ctrl.rd <= exin.ctrl.rd;
      ex.write_cwp <= exin.write_cwp;
      ex.cwp <= exin.cwp;
      ex.write_y <= exin.write_y;
      ex.rst_mey <= exin.rst_mey;
      ex.write_icc <= exin.write_icc;
      ex.rs1data <= exin.rs1data;
      ex.rs2data <= exin.rs2data;
      ex.alu_cin <= exin.alu_cin;
      ex.aluop <= exin.aluop;
      ex.alusel <= exin.alusel;
      ex.aluadd <= exin.aluadd;
      ex.mulstep <= exin.mulstep;
      ex.mulinsn <= exin.mulinsn;
      ex.ycarry <= exin.ycarry;
      ex.ymsb <= exin.ymsb;
      dci.write <= dciin.write;
      dci.asi <= dciin.asi;
      dci.enaddr <= dciin.enaddr;
      dci.read <= dciin.read;
      dci.lock <= dciin.lock;

-- memory stage
      me.result <= mein.result;
      me.y <= mein.y;
      me.ctrl <= mein.ctrl;
      dci.size <= mein.ld_size;
      me.memory_load <= mein.memory_load;
      dci.signed <= mein.signed;
      me.write_reg <= ex.write_reg;
      me.ctrl.rd <= ex.ctrl.rd;
      me.write_cwp <= ex.write_cwp;
      me.cwp <= ex.cwp;
      me.write_y <= ex.write_y;
      me.write_icc <= ex.write_icc;
      me.icc <= mein.icc;
      me.addr_misal <= mein.addr_misal;

-- write stage
      wr.y <= wrin.y;
      wr.ctrl <= wrin.ctrl;
      wr.write_reg <= me.write_reg;
      wr.ctrl.rd <= me.ctrl.rd;
      wr.write_cwp <= wrin.write_cwp;
      wr.cwp <= wrin.cwp;
      wr.write_icc <= me.write_icc;
      wr.icc <= me.icc;
      wr.tpcsel <= wrin.tpcsel;
      wr.trapping <= wrin.trapping;
      wr.error <= wrin.error;
      wr.intack <= wrin.intack;

-- special registers
      sregs.cwp <= sregsin.cwp;
      sregs.icc <= sregsin.icc;
      sregs.tt  <= sregsin.tt;
      sregs.tba <= sregsin.tba;
      sregs.wim  <= sregsin.wim;
      sregs.ec  <= sregsin.ec;
      sregs.ef  <= sregsin.ef;
      sregs.et  <= sregsin.et;
      sregs.ps  <= sregsin.ps;
      sregs.s   <= sregsin.s;
      sregs.pil <= sregsin.pil;
      end if;
    end if;

  end process;
  
  ldbpr0 : if LDDELAY = 1 generate
    lb : process(clk)
    begin
      if clk'event and (clk = '1') then
        if (holdn = '1') or GATEDCLK then
	  ex.ldbp1 <= exin.ldbp1;
	  ex.ldbp2 <= exin.ldbp2;
        end if;
      end if;
    end process;
  end generate;

    
-- debugging support

-- pragma translate_off
  debug0 : if DEBUGPORT generate

    debug.clk    <= clk;
    debug.rst    <= rst;
    debug.holdn  <= holdn;
    debug.ex     <= ex.ctrl;
    debug.me     <= me.ctrl;
    debug.wr     <= wr.ctrl;

  end generate;
-- pragma translate_on

end;

⌨️ 快捷键说明

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