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

📄 mctrl.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
          regsd := (others => '-');
	end if;
      when "1000" => 
	if WPROTEN then
	  regsd := wpr.wprot2.enable & wpr.wprot2.ablock & 
		   wpr.wprot2.addr & wpr.wprot2.mask;
	else
          regsd := (others => '-');
	end if;
      when others => regsd := (others => '-');
      end case;
      if (r.read and r.ready2) = '1' then
        v.rstate := idle;
      elsif r.read = '0' then
        v.rstate := rwrite; 
	v.ready := '1';
	if (r.address(5 downto 2) = "0110") and (peo.irl = "0000") then 
	  v.pwd := '1';
     	end if;
      end if;
    when rwrite =>
      v.rstate := idle;
      case r.address(5 downto 2) is
      when "0000" => 
        v.mcfg1.romrws      :=  r.writedata(3 downto 0); 
        v.mcfg1.romwws      :=  r.writedata(7 downto 4);
        v.mcfg1.romwidth    :=  r.writedata(9 downto 8);
        v.mcfg1.romedac     :=  r.writedata(10);
        v.mcfg1.romwrite    :=  r.writedata(11);
        v.mcfg1.romleadin   :=  r.writedata(12);
        v.mcfg1.romleadout  :=  r.writedata(13);
        v.mcfg1.rombanksz   :=  r.writedata(17 downto 14);
        v.mcfg1.extlatch    :=  r.writedata(18);
        v.mcfg1.ioen        :=  r.writedata(19);
        v.mcfg1.iows        :=  r.writedata(23 downto 20);
        v.mcfg1.ioleadin    :=  r.writedata(24);
        v.mcfg1.ioleadout   :=  r.writedata(25);
        v.mcfg1.iordy       :=  r.writedata(26);
        v.mcfg1.iowidth     :=  r.writedata(28 downto 27);
      when "0001" => 
        v.mcfg2.ramrws      := r.writedata(1 downto 0);
        v.mcfg2.ramwws      := r.writedata(3 downto 2);
        v.mcfg2.ramwidth    := r.writedata(5 downto 4);
        v.mcfg2.ramedac     := r.writedata(6);
        v.mcfg2.ramleadin   := r.writedata(7);
        v.mcfg2.ramleadout  := r.writedata(8);
        v.mcfg2.rambanksz   := r.writedata(12 downto 9);
      when "0010" => 
	v.edacctrl.wcheckbits := r.writedata(6 downto 0);
	v.edacctrl.wbypass    := r.writedata(7);
      when "0011" => v.failaddr := r.writedata;
      when "0100" => 
	v.memstat.lock    := r.writedata(10);
	v.memstat.mulerr  := r.writedata(9);
	v.memstat.newerr  := r.writedata(8);
	v.memstat.read    := r.writedata(7);
	v.memstat.asi     := r.writedata(6 downto 3);
	v.memstat.errtype := r.writedata(2 downto 0);
      when "0101" => 
        v.cctrl.ib  := r.writedata(16);
        v.cctrl.ite := r.writedata(13 downto 12);
        v.cctrl.ide := r.writedata(11 downto 10);
        v.cctrl.dte := r.writedata(9 downto 8);
        v.cctrl.dde := r.writedata(7 downto 6);
        v.cctrl.dfrz  := r.writedata(5);
        v.cctrl.ifrz  := r.writedata(4);
        v.cctrl.dcs := r.writedata(3 downto 2);
        v.cctrl.ics := r.writedata(1 downto 0);
      when "0111" => 
        wprot1.enable := r.writedata(31);
	wprot1.ablock := r.writedata(30);
	wprot1.addr := r.writedata(29 downto 15);
	wprot1.mask := r.writedata(14 downto 0);
      when "1000" => 
        wprot2.enable := r.writedata(31);
	wprot2.ablock := r.writedata(30);
	wprot2.addr := r.writedata(29 downto 15);
	wprot2.mask := r.writedata(14 downto 0);
      when others => null;
      end case;
    when eregs =>
      v.regen := '1'; regsd := pbo.data;
      if r.read  = '1' then
	if r.ready2 = '1' then 
	  v.rstate := idle; v.regen := '0';
	end if;
      else
        v.rstate := ewrite; v.ready := '1';
      end if;
    when ewrite =>
      v.rstate := idle;
    end case;

-- select appropriate data during reads

    case r.area is
    when rom | ram => 
      if r.checkedac = '1' then dataout := edata.data;
      else
	if busw(1) = '1' then dataout := r.data;
	else dataout := r.readdata(23 downto 0) & r.data(31 downto 24); end if;
      end if;
    when io => dataout := r.data;
    when regs => dataout := regsd;
    when others => dataout := (others => '-');
    end case;

-- Merge (corrected) data during byte write

    if r.checkedac = '1' then memdata := edata.data; 
    elsif busw(1) = '0' then memdata := r.readdata(23 downto 0) & r.data(31 downto 24);
    else memdata := r.data; end if;

    case r.busstate is
    when bw2 =>		-- write back the merged word
	case r.ba is
	when "00" => 
	  v.writedata(15 downto 0) := memdata(15 downto 0);
	  if r.size(0) = '0' then 
	    v.writedata(23 downto 16) := memdata(23 downto 16);
	  end if;
	when "01" => 
	  v.writedata(31 downto 24) := memdata(31 downto 24);
	  v.writedata(15 downto 0) := memdata(15 downto 0);
	when "10" => 
	  v.writedata(31 downto 16) := memdata(31 downto 16);
	  if r.size(0) = '0' then 
	    v.writedata(7 downto 0) := memdata(7 downto 0);
	  end if;
	when  others => 
	  v.writedata(31 downto 8) := memdata(31 downto 8);
	end case;
    when others => null;
    end case;

-- update memory status and failing address register if an error occured

    failaddr := (others => '-');
    merror := edata.merror and r.checkedac2;
    cerror := edata.error and r.checkedac2;
    bexc := r.ready and (not r.bexcn);
    if (merror or r.mexc or cerror or bexc) = '1' then
      failaddr := r.address2;
      if r.mexc = '1' then
 	failaddr := r.address;
	if r.werr = '1' then merrtype := ERR_WP;
	else merrtype := ERR_ILLA; end if;
      elsif bexc = '1' then
 	merrtype := ERR_BEXC; v.werr := not r.read;
      elsif merror = '1' then
 	merrtype := ERR_UEDAC; 
	if (r.busstate = bw2) then v.werr := '1'; end if;
      else
 	merrtype := ERR_CEDAC; v.cerror := '1';
      end if;
      if r.memstat.lock = '0' then
        v.memstat.read := r.read; v.memstat.asi := r.asi; 
        v.memstat.errtype := merrtype; v.failaddr := failaddr;
        v.memstat.lock := merror or r.mexc;
      end if;
      v.memstat.newerr := '1'; v.memstat.mulerr := r.memstat.newerr;
    end if;

-- load checkbits into edac test cotrol register during edac test reads

    if (r.master = data) and 
       ((r.read and r.edacctrl.wbypass and r.checkedac2) = '1') then
      if busw = "00" then
        v.edacctrl.wcheckbits := r.data(30 downto 24);
      else
        v.edacctrl.wcheckbits := r.cb;
      end if;
    end if;

-- generate appropriate data ready and error signals

    case v.master is
    when inst => v.iready := v.ready;
    when data => v.dready := v.ready and not v.pwd;
    when dma  => v.mready := v.ready and DMAEN;
    when others => null;
    end case;

    case r.master is
    when inst => imerror := merror;
    when data => dmerror := (merror and r.read) or r.werr;
    when dma  => mmerror := ((merror and r.read) or r.werr) and DMAEN;
    when others => null;
    end case;

    v.imexc := r.iready and r.mexc;
    v.dmexc := (r.dready and (r.mexc or not r.bexcn) and r.read) or
	((not r.bexcn) and (not r.read) and v.dready);
    v.mmexc := ((r.mready and (r.mexc or not r.bexcn) and r.read) or
	((not r.bexcn) and (not r.read) and v.mready)) and DMAEN;

-- release iu if irl /= 0 

    if (r.pwd = '1') and peo.irl /= "0000" then 
      v.dready := not r.dready;
    end if;
    -- delay release of r.pwd one clock
    if r.dready = '1' then v.pwd := '0'; end if; 

-- suppress ready signal and EDAC error during byte writes (data access only)

    case r.busstate is
    when bw1 | bw2 => v.dready := v.werr; dmerror := '0';
    when others => null;
    end case;
    if v.busstate = bw1 then v.dready := '0'; end if;

-- generate chip select and output enable

    rams := decode(adec);
    v.ramsn := "1111";
    v.ramoen := "1111";
    v.iosn := '1';
    romsn := '1';
    v.oen := '1';
    bwidth := "00";

    if csen = '1' then
      case v.area is
      when rom =>
	romsn := v.mexc; v.oen := v.mexc or not v.read; 
	bwidth := r.mcfg1.romwidth;
      when ram =>
        bwidth := r.mcfg2.ramwidth;
	if v.mexc = '0' then
          v.ramsn := not rams;
          if (v.read = '1') then v.ramoen := v.ramsn; end if;
	end if;
      when io =>
	v.iosn := '0'; v.oen := not v.read; bwidth := r.mcfg1.iowidth;
      when others => null;
      end case;
    end if;

    v.romsn(0) := romsn or v.address(28);
    v.romsn(1) := romsn or not v.address(28);

    case bwidth is
    when "00" => v.bdrive := "000" & bdrive;
    when "01" => v.bdrive := "00" & bdrive & bdrive;
    when others => v.bdrive := (others => bdrive);
    end case;

-- generate appropriate write strobe

    if r.wren = '1' then 
      wrn <= r.ramsn; writen <= r.romsn(0) and r.romsn(1) and r.iosn;
    else
      wrn <= "1111"; writen <= '1';
    end if;

-- generate memory address

    if RAWADDR and (r.mcfg1.extlatch = '1') then
      memo.address <= v.address(27 downto 0);
    else
      memo.address <= r.address(27 downto 0);
    end if;

-- use d(15:0) as input ports (only usefull in 8-bit mode)

    pbi.pioh 	<= r.data(15 downto 0);

-- reset

    if rst = '0' then
      v.bstate := idle; v.busstate := idle; v.rstate := idle; 
      v.master := inst; v.read := '1'; v.ajam := '0'; v.pwd := '0';
      v.memstat.lock := '0';
      v.memstat.mulerr := '0';
      v.memstat.newerr := '0';
      v.mcfg1.romrws         := "1111";
      v.mcfg1.romwws         := "1111";
      v.mcfg1.romwidth       := mctrli.romwidth;
      v.mcfg1.romedac        := mctrli.romedac;
      v.mcfg1.romwrite       := '0';
      v.mcfg1.romleadin      := '1';
      v.mcfg1.romleadout     := '1';
      v.mcfg1.rombanksz      := "0000";
      v.mcfg1.extlatch       := '0';
      v.mcfg1.ioen           := '0';
      v.cctrl.ib             := '0';
      v.cctrl.dcs            := "00";
      v.cctrl.ics            := "00";
      v.edacctrl.wbypass     := '0';
      wprot1.enable          := '0';
      wprot2.enable          := '0';
    end if;

-- drive various register inputs and external outputs

    ri <= v;

    wpv.wprot1		<= wprot1;
    wpv.wprot2		<= wprot2;
    pbi.read 		<= mcdi.read;
    mctrlo.cerror 	<= r.cerror;
    mcio.data    	<= dataout;
    mcio.ics  		<= r.cctrl.ics;
    mcio.burst 		<= r.cctrl.ib;
    mcio.mexc   	<= r.imexc or imerror;
    mcio.ready   	<= r.iready;
    mcdo.data    	<= dataout;
    mcdo.dcs  		<= r.cctrl.dcs;
    mcdo.mexc   	<= r.dmexc or dmerror;
    mcdo.ready   	<= r.dready;
    mcmo.data    	<= dataout;
    mcmo.mexc   	<= r.mmexc or mmerror;
    mcmo.ready   	<= r.mready;
    memo.ramsn    	<= r.ramsn;
    memo.ramoen     	<= r.ramoen;
    memo.romsn    	<= r.romsn;
    memo.oen  		<= r.oen;
    memo.iosn  		<= r.iosn;
    memo.read  		<= r.read;
    memo.bdrive  	<= r.bdrive;
    memo.data		<= r.writedata;
    memo.checkbits 	<= cbout;
    pbi.address 	<= r.address(7 downto 2);
    pbi.data 		<= r.writedata;
    pbi.enable 		<= r.regen;


  end process;

  fregs : process(clk)
  begin
    if clk'event and (clk = '0') then
      memo.wrn <= wrn;
      memo.writen <= writen;
    end if;
  end process;

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

  wpreggen : if WPROTEN generate 
    wpregs : process(clk)
    begin
      if clk'event and (clk = '1') then
        wpr <= wpv;
      end if;
    end process;
  end generate;

end;

⌨️ 快捷键说明

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