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

📄 smc_mctrl.vhd

📁 ahb sdram interface.arm cpu series,include controller
💻 VHD
📖 第 1 页 / 共 3 页
字号:
    if r.area(io) = '1' then      rws := r.mcfg1.iows; wws := r.mcfg1.iows;      if r.mcfg1.ioen = '0' then addrerr := '1'; end if;    end if;-- generate data buffer enables    bdrive := (others => '1');    case r.busw is    when "00" => if BUS8EN then bdrive := "0001"; end if;    when "01" => if BUS16EN then bdrive := "0011"; end if;    when others =>    end case;-- generate chip select and output enable    rams := '0' & decode(adec);    case srbanks is    when 0 => rams := "00000";    when 1 => rams := "00001";    when 2 => rams := "000" & (rams(3 downto 2) or rams(1 downto 0));    when others =>      if RAMSEL5 and (haddr(sdrasel) = '1') then rams := "10000"; end if;    end case;    iosn := '1'; ramsn := (others => '1'); romsn := (others => '1');    if area(rom) = '1' then      romsn := (not haddr(romasel)) & haddr(romasel);    end if;    if area(ram) = '1' then ramsn := not rams; end if;    if area(io) = '1' then iosn := '0'; end if;-- generate write strobe    wrn := "0000";    case r.busw is    when "00" =>      if BUS8EN then wrn := "1110"; end if;    when "01" =>      if BUS16EN then	if (r.size = "00") and (r.brmw = '0') then	  wrn := "11" & (not r.address(0)) & r.address(0);        else wrn := "1100"; end if;      end if;    when "10" | "11" =>      case r.size is      when "00" =>        case r.address(1 downto 0) is        when "00" => wrn := "1110";        when "01" => wrn := "1101";        when "10" => wrn := "1011";        when others => wrn := "0111";        end case;      when "01" =>        wrn := not r.address(1) & not r.address(1) & r.address(1) & r.address(1);      when others => null;      end case;    when others => null;    end case;    if (r.mcfg2.rmw = '1') and (r.area(ram) = '1') then wrn := not bdrive; end if;    if (((ahbsi.hready and ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1') or (((sdmo.aload and r.hsel) = '1') and SDRAMEN))    then      v.area := area;      v.address  := haddr;       if (busw = "00") and (hwrite = '0') and (area(io) = '0') and BUS8EN      then v.address(1 downto 0) := "00"; end if;      if (busw = "01") and (hwrite = '0') and (area(io) = '0') and BUS16EN      then v.address(1 downto 0) := "00"; end if;      if (brmw = '1') then	v.read := '1';      else v.read := not hwrite; end if;      v.busw := busw; v.brmw := brmw;    end if;-- Select read data depending on bus width    if BUS8EN and (r.busw = "00") then      memdata := r.readdata(23 downto 0) & r.data(31 downto 24);    elsif BUS16EN and (r.busw = "01") then      memdata := r.readdata(15 downto 0) & r.data(31 downto 16);    else      memdata := r.data;    end if;    bwdata := memdata;-- Merge data during byte write    writedata := ahbsi.hwdata;    if ((r.brmw and r.busw(1)) = '1')    then      case r.address(1 downto 0) is      when "00" =>	writedata(15 downto 0) := bwdata(15 downto 0);	if r.size = "00" then	  writedata(23 downto 16) := bwdata(23 downto 16);	end if;      when "01" =>	writedata(31 downto 24) := bwdata(31 downto 24);	writedata(15 downto 0) := bwdata(15 downto 0);      when "10" =>	writedata(31 downto 16) := bwdata(31 downto 16);	if r.size = "00" then	  writedata(7 downto 0) := bwdata(7 downto 0);	end if;      when  others =>	writedata(31 downto 8) := bwdata(31 downto 8);      end case;    end if;    if (r.brmw = '1') and (r.busw = "01") and BUS16EN then      if (r.address(0) = '0') then        writedata(23 downto 16) :=  r.data(23 downto 16);      else        writedata(31 downto 24) :=  r.data(31 downto 24);      end if;    end if;-- save read data during 8/16 bit reads    if BUS8EN and (r.ready8 = '1') and (r.busw = "00") then      v.readdata := v.readdata(23 downto 0) & r.data(31 downto 24);    elsif BUS16EN and (r.ready8 = '1') and (r.busw = "01") then      v.readdata := v.readdata(15 downto 0) & r.data(31 downto 16);    end if;-- Ram, rom, IO access FSM    if r.read = '1' then wsnew := rws; else wsnew := wws; end if;    case r.bstate is    when idle =>      v.ws := wsnew;      if r.bdrive(0) = '1' 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.srhsel = '1') and ((sdmo.busy = '0') or not SDRAMEN)      then        if WPROTEN then wprothitx := wpo.wprothit; end if;	if (wprothitx or addrerr) = '1' then	  v.hresp := HRESP_ERROR; v.bstate := berr; v.bdrive := (others => '1');	elsif r.read = '0' then	  if (r.busw = "00") and (r.area(io) = '0') and BUS8EN then	    v.bstate := bwrite8;	  elsif (r.busw = "01") and (r.area(io) = '0') and BUS16EN then	    v.bstate := bwrite16;   	  else v.bstate := bwrite; end if;	  v.wrn := wrn; v.writen := '0'; v.bdrive := not bdrive;	else	  if r.oen = '1' then v.ramoen := r.ramsn; v.oen := '0';	  else	    if (r.busw = "00") and (r.area(io) = '0') and BUS8EN then v.bstate := bread8;	    elsif (r.busw = "01") and (r.area(io) = '0') and BUS16EN then v.bstate := bread16;	    else v.bstate := bread; end if;	  end if;	end if;      end if;    when berr =>      v.bstate := idle; ready := '1';      v.hresp := HRESP_ERROR;      v.ramsn := (others => '1'); v.romsn := (others => '1');      v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11"; v.bdrive := (others => '1');    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(hindex) = '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.read := not r.hwrite;	  if r.brmw = '0' then  	    v.ramsn := (others => '1'); v.romsn := (others => '1');	  else	    v.echeck := '1';	  end if;	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 => '1'); v.bstate := idle;      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') and (bready = '1') 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(hindex) = '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');	    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;      else	v.bstate := idle;      end if;    when bwrite8 =>      if BUS8EN then        if (r.ws = "0000") and (r.ready8 = '0') and (bready = '1') then	  v.ready8 := '1'; v.wrn := (others => '1'); v.writen := '1';        end if;        if (r.ws = "0000") and (bready = '1') 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 => '1'); v.bstate := idle;        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 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;      else	v.bstate := idle;      end if;    when bread16 =>      if BUS16EN then        if (r.ws = "0000") and (bready = '1') 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(hindex) = '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');	    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 (bready = '1') 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;      else	v.bstate := idle;      end if;    when bwrite16 =>      if BUS16EN then        if (r.ws = "0000") and (bready = '1') 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 => '1'); v.bstate := idle;        end if;        if (r.ws = "0000") and (bready = '1') 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;      else	v.bstate := idle;      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(hindex) = '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 => '1'); v.wrn := (others => '1');        v.writen := '1'; v.hsel := '0'; ready := ahbsi.hsel(hindex); v.srhsel := '0';      elsif srhsel = '1' then        v.romsn := romsn; v.ramsn(4 downto 0) := ramsn(4 downto 0); v.iosn := iosn & '1';        if v.read = '1' then v.ramoen(4 downto 0) := ramsn(4 downto 0); 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; v.bdrive := (others => '1');

⌨️ 快捷键说明

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