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

📄 mctrl.vhd

📁 不可多的的内存控制代码,是VHDL开发的珍贵参考资料!
💻 VHD
📖 第 1 页 / 共 2 页
字号:
    case r.bstate is    when idle =>      v.ws := wsnew;       if r.bdrive(0) = '0' then         if r.busw(1) = '1' then v.writedata := writedata;	else	  v.writedata(31 downto 16) := writedata(31 downto 16);	  v.writedata8 := writedata(15 downto 0);	end if;      end if;      if r.hsel = '1' then	wprothitx := wpo.wprothit and not r.read;	if (wprothitx or addrerr) = '1' then	  v.hresp := HRESP_ERROR; v.bstate := berr;	elsif r.read = '0' then 	  if (r.busw = "00") and (r.area /= io) and BUS8EN then 	    v.bstate := bwrite8;	  elsif (r.busw = "01") and (r.area /= io) and BUS16EN then 	    v.bstate := bwrite16;   	  else v.bstate := bwrite; end if;	  v.wrn := wrn; v.writen := '0'; v.bdrive := bdrive;	else 	  if r.oen = '1' then v.ramoen := r.ramsn; v.oen := '0';	  else	    if (r.busw = "00") and (r.area /= io) and BUS8EN then v.bstate := bread8;	    elsif (r.busw = "01") and (r.area /= io) and BUS16EN then v.bstate := bread16;	    else v.bstate := bread; end if;	  end if;	end if;      end if;    when berr =>      v.bstate := idle; v.hsel := '0'; ready := '1';      v.hresp := HRESP_ERROR;      v.ramsn := (others => '1'); v.romsn := (others => '1'); v.psel(0) := '1';      v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";    when bread =>       if ((r.ws = "0000") and (r.ready = '0') and (bready = '1'))      then 	if r.brmw = '0' then	  ready := '1'; v.address := ahbsi.haddr; v.echeck := '1';	end if;        if (((ahbsi.hsel = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or (r.hburst = HBURST_SINGLE))        then	  if r.brmw = '0' then  	    v.ramsn := (others => '1'); v.romsn := (others => '1'); 	    v.hsel := '0'; v.psel(0) := '1';	  else v.echeck := '1'; end if;  	  v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";   	  v.bstate := idle; v.read := not r.hwrite;	end if;      end if;      if r.ready = '1' then	v.ws := rws;      else	if r.ws /= "0000" then v.ws := r.ws - 1; end if;      end if;    when bwrite =>      if (r.ws = "0000") and (bready = '1') then	ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';	v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";	v.bdrive := (others => '0'); v.bstate := idle; v.hsel := '0';	v.psel(0) := '1';      end if;      if r.ws /= "0000" then v.ws := r.ws - 1; end if;    when bread8 =>       if BUS8EN then        if (r.ws = "0000") and (r.ready8 = '0') then	  v.ready8 := '1'; v.ws := rws; 	  v.address(1 downto 0) := r.address(1 downto 0) + 1;          if (r.address(1 downto 0) = "11") then	    ready := '1'; v.address := ahbsi.haddr; v.echeck := '1';            if (((ahbsi.hsel = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or 	        (r.hburst = HBURST_SINGLE))            then  	      v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";   	      v.bstate := idle;  	      v.ramsn := (others => '1'); v.romsn := (others => '1'); v.hsel := '0';	      v.psel(0) := '1';	    end if;          end if;        end if;        if (r.ready8 = '1') then v.ws := rws;        elsif r.ws /= "0000" then v.ws := r.ws - 1; end if;      end if;    when bwrite8 =>      if BUS8EN then        if (r.ws = "0000") and (r.ready8 = '0') then 	  v.ready8 := '1'; v.wrn := (others => '1'); v.writen := '1';        end if;        if (r.ws = "0000") and            ((r.address(1 downto 0) = "11") or             ((r.address(1 downto 0) = "01") and (r.size = "01")) or	    (r.size = "00"))         then	  ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';	  v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";	  v.bdrive := (others => '0'); v.bstate := idle; v.hsel := '0';	  v.psel(0) := '1';        end if;        if (r.ready8 = '1') then	  v.address(1 downto 0) := r.address(1 downto 0) + 1; v.ws := rws; --	  v.writedata(31 downto 8) := r.writedata(23 downto 0);	  v.writedata(31 downto 16) := r.writedata(23 downto 16) & r.writedata8(15 downto 8);	  v.writedata8(15 downto 8) := r.writedata8(7 downto 0);	  v.bstate := idle;         end if;        if r.ws /= "0000" then v.ws := r.ws - 1; end if;      end if;    when bread16 =>       if BUS16EN then        if (r.ws = "0000") and ((r.address(1) or r.brmw) = '1') and 	   (r.ready8 = '0')         then	  if r.brmw = '0' then	    ready := '1'; v.address := ahbsi.haddr; v.echeck := '1';	  end if;          if (((ahbsi.hsel = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or 	      (r.hburst = HBURST_SINGLE))          then	    if r.brmw = '0' then  	      v.ramsn := (others => '1'); v.romsn := (others => '1'); v.hsel := '0';	      v.psel(0) := '1';	    end if;  	    v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";   	    v.bstate := idle; v.read := not r.hwrite;	  end if;        end if;        if (r.ws = "0000") and (r.ready8 = '0') then 	  v.ready8 := '1'; v.ws := rws; 	  if r.brmw = '0' then v.address(1) := not r.address(1); end if;        end if;        if r.ws /= "0000" then v.ws := r.ws - 1; end if;      end if;    when bwrite16 =>      if BUS16EN then        if (r.ws = "0000") and            ((r.address(1 downto 0) = "10") or (r.size(1) = '0'))         then	  ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';	  v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";	  v.bdrive := (others => '0'); v.bstate := idle; v.hsel := '0';	  v.psel(0) := '1';        end if;        if (r.ws = "0000") and (r.ready8 = '0') then 	  v.ready8 := '1'; v.wrn := (others => '1'); v.writen := '1';        end if;        if (r.ready8 = '1') then	  v.address(1) := not r.address(1); v.ws := rws; 	  v.writedata(31 downto 16) := r.writedata8(15 downto 0);	  v.bstate := idle;         end if;        if r.ws /= "0000" then v.ws := r.ws - 1; end if;      end if;    when others =>    end case;-- if BUSY or IDLE cycle seen, or if de-selected, return to idle state    if (ahbsi.hready = '1') then      if ((ahbsi.hsel = '0') or (ahbsi.htrans = HTRANS_BUSY) or 	(ahbsi.htrans = HTRANS_IDLE))      then        v.bstate := idle;        v.ramsn := (others => '1'); v.romsn := (others => '1');        v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";        v.bdrive := (others => '0'); v.wrn := (others => '1');        v.writen := '1'; v.hsel := '0'; ready := ahbsi.hsel;	v.psel(0) := '1';      elsif ahbsi.hsel = '1' then        v.romsn := romsn; v.ramsn := ramsn; v.iosn := iosn & '1'; v.hsel := '1';        v.psel(0) := psel;        if v.read = '1' then v.ramoen := ramsn; v.oen := leadin; end if;      end if;    end if;-- error checking and reporting    noerror := '1';    if ((r.echeck and r.mcfg1.bexcen and not r.bexcn) = '1') then      noerror := '0'; v.bstate := berr; v.hresp := HRESP_ERROR;    end if;-- APB register access    case apbi.paddr(3 downto 2) is    when "00" =>       regsd(28 downto 0) := r.mcfg1.iowidth & 	r.mcfg1.brdyen & r.mcfg1.bexcen & "0" & r.mcfg1.iows & r.mcfg1.ioen &	r.mcfg1.extlatch & 	"000000" & r.mcfg1.romwrite & 	'0' & r.mcfg1.romwidth & r.mcfg1.romwws & r.mcfg1.romrws;    when "01" =>       regsd(12 downto 0) := r.mcfg2.rambanksz & "00" & r.mcfg2.rmw &	r.mcfg2.ramwidth & r.mcfg2.ramwws & r.mcfg2.ramrws;    when others => regsd := (others => '0');    end case;    apbo.prdata <= regsd;    if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then      case apbi.paddr(5 downto 2) is      when "0000" =>         v.mcfg1.romrws      :=  apbi.pwdata(3 downto 0);         v.mcfg1.romwws      :=  apbi.pwdata(7 downto 4);        v.mcfg1.romwidth    :=  apbi.pwdata(9 downto 8);        v.mcfg1.romwrite    :=  apbi.pwdata(11);        v.mcfg1.extlatch    :=  apbi.pwdata(18);        v.mcfg1.ioen        :=  apbi.pwdata(19);        v.mcfg1.iows        :=  apbi.pwdata(23 downto 20);        v.mcfg1.bexcen      :=  apbi.pwdata(25);        v.mcfg1.brdyen      :=  apbi.pwdata(26);        v.mcfg1.iowidth     :=  apbi.pwdata(28 downto 27);      when "0001" =>         v.mcfg2.ramrws      := apbi.pwdata(1 downto 0);        v.mcfg2.ramwws      := apbi.pwdata(3 downto 2);        v.mcfg2.ramwidth    := apbi.pwdata(5 downto 4);        v.mcfg2.rmw         := apbi.pwdata(6);        v.mcfg2.rambanksz   := apbi.pwdata(12 downto 9);      when others => null;      end case;    end if;-- select appropriate data during reads    case r.area is    when rom | ram =>       dataout := memdata;      if (r.area = rom) and (BOOTOPT /= memory) then	if (r.psel(0) = '0') then v.readdata := promdata; end if;        if r.psel(1) = '0' then dataout := r.readdata; end if;      end if;    when others =>      if BUS8EN and (r.busw = "00") then        dataout := r.data(31 downto 24) & r.data(31 downto 24) 		 & r.data(31 downto 24) & r.data(31 downto 24);      elsif BUS16EN and (r.busw = "01") then        dataout := r.data(31 downto 16) & r.data(31 downto 16);       else dataout := r.data; end if;    end case;    v.ready := ready;-- 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 I/O ports (only usefull in 8/16-bit mode)    if BUS8EN or BUS16EN then       mctrlo.pioh <= r.data(15 downto 0);      if (r.mcfg1.romwidth(1) or r.mcfg1.iowidth(1) or r.mcfg2.ramwidth(1)) = '0' then        v.writedata(15 downto 0) := r.writedata(15 downto 0);        if pioo.wrio = '1' then 	  v.writedata(15 downto 0) := pioo.piol(31 downto 16);        end if;        v.wrn(3 downto 2) := "11";	v.bdrive(3 downto 2) := not pioo.piodir(17 downto 16);      end if;    else mctrlo.pioh <= (others => '0'); end if;-- reset    if rst.syncrst = '0' then      v.bstate 	 	   := idle;       v.read 		   := '1';       v.wrn                := "1111";      v.writen		   := '1';       v.mcfg1.romwrite     := '0';      v.mcfg1.extlatch     := '0';      v.mcfg1.ioen         := '0';      v.mcfg1.brdyen       := '0';      v.mcfg1.bexcen       := '0';      v.hsel		   := '0';      if ((BOOTOPT = memory) or ((BOOTOPT = dual) and (pioo.io8lsb(4) = '0')))       then        v.mcfg1.romrws     := "1111";        v.mcfg1.romwws     := "1111";        v.mcfg1.romwidth   := pioo.io8lsb(1 downto 0);      else	v.mcfg2.ramrws	   := std_logic_vector(BRAMRWS(1 downto 0));	v.mcfg2.ramwws	   := std_logic_vector(BRAMWWS(1 downto 0));        v.mcfg1.romrws     := "0001";        v.mcfg1.romwws     := "0001";        v.mcfg1.romwidth   := "11";      end if;    end if;-- pragma translate_off    for i in dataout'range loop --'      if is_x(dataout(i)) then dataout(i) := '1'; end if;    end loop;-- pragma translate_on-- drive various register inputs and external outputs    ri <= v;     memo.ramsn    	<= r.ramsn;    memo.ramoen     	<= r.ramoen;    memo.romsn       	<= r.romsn;    memo.oen  		<= r.oen;    memo.iosn  		<= r.iosn(0);    memo.read  		<= r.read;    memo.wrn 		<= r.wrn;     memo.writen 	<= r.writen;    memo.bdrive  	<= (not r.bdrive) and memi.wrn;    memo.data		<= r.writedata;    ahbso.hrdata <= dataout;    ahbso.hready <= r.ready and noerror;    ahbso.hresp  <= r.hresp;    ahbso.hsplit <= (others => '0');  end process;  stdregs : process(clk,rst)  begin     if rising_edge(clk) then r <= ri; end if;    if rst.rawrst = '0' then      r.ramsn <= (others => '1'); r.romsn <= (others => '1');      r.oen <= '1'; r.bdrive <= (others => '0');      r.iosn <= "11"; r.ramoen <= (others => '1');    end if;  end process;-- optional boot-prom promgen : if (BOOTOPT /= memory) generate    bprom0 : bprom port map      (clk => clk, cs => r.psel(0), addr => r.address, data => promdata);  end generate;end;

⌨️ 快捷键说明

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