sdctrl.vhd

来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 544 行 · 第 1/2 页

VHD
544
字号
        if WPROTEN and (r.wprothit = '1') then	  v.hresp := HRESP_ERROR; v.hready := '1'; 	  v.sdstate := wr1; v.sdwen := '1'; v.bdrive := '1'; v.casn := '1';	end if;      else v.sdstate := rd1; end if;    when wr1 =>      v.address(14 downto 2) := r.haddr(13 downto 12) & '0' & r.haddr(11 downto 2);      if (((r.burst and r.hready) = '1') and (r.htrans = "11"))      and not (WPROTEN and (r.wprothit = '1'))      then 	v.hready := ahbsi.htrans(0) and ahbsi.htrans(1) and r.hready;      else        v.sdstate := wr2; v.bdrive := '1'; v.casn := '1'; v.sdwen := '1';	v.dqm := (others => '1');      end if;    when wr2 =>      v.rasn := '0'; v.sdwen := '0'; v.sdstate := wr3;    when wr3 =>      v.sdcsn := "11"; v.rasn := '1'; v.sdwen := '1';       if (r.cfg.trp = '1') then v.sdstate := wr4;      else v.sdstate := sidle; end if;    when wr4 =>      v.sdstate := sidle;    when rd1 =>      v.casn := '1';      if SDINVCLK then        if r.cfg.casdel = '1' then v.sdstate := rd2;        else          v.sdstate := rd3;          if ahbsi.htrans /= "11" then v.rasn := '0'; v.sdwen := '0'; end if;        end if;      else v.sdstate := rd7; end if;    when rd7 =>      if r.cfg.casdel = '1' then v.sdstate := rd2;      else        v.sdstate := rd3;        if ahbsi.htrans /= "11" then v.rasn := '0'; v.sdwen := '0'; end if;      end if;    when rd2 =>      v.sdstate := rd3;      if ahbsi.htrans /= "11" then v.rasn := '0'; v.sdwen := '0'; end if;      if v.sdwen = '0' then v.dqm := (others => '1'); end if;    when rd3 =>      v.sdstate := rd4; v.hready := '1';      if r.sdwen = '0' then	v.rasn := '1'; v.sdwen := '1'; v.sdcsn := "11"; v.dqm := (others => '1');      end if;    when rd4 =>      v.hready := '1';      if ahbsi.htrans /= "11" or (r.sdcsn = "11") then        v.hready := '0'; v.dqm := (others => '1');        if (r.sdcsn /= "11") then	  v.rasn := '0'; v.sdwen := '0'; v.sdstate := rd5;	else          if r.cfg.trp = '1' then v.sdstate := rd6; 	  else v.sdstate := sidle; end if;        end if;      end if;    when rd5 =>      if r.cfg.trp = '1' then 	v.sdstate := rd6;       else v.sdstate := sidle; end if;      v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1'; v.dqm := (others => '1');    when rd6 =>      v.sdstate := sidle; v.dqm := (others => '1');      v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1';    when others =>	v.sdstate := sidle;    end case;-- sdram commands    case r.cmstate is    when midle =>      if r.sdstate = sidle then        case r.cfg.command is        when "01" => -- precharge	    v.sdcsn := (others => '0'); v.rasn := '0'; v.sdwen := '0';	    v.address(12) := '1'; v.cmstate := active;        when "10" => -- auto-refresh	  v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0';          v.cmstate := active;        when "11" =>	    v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0'; 	    v.sdwen := '0'; v.cmstate := active;	    v.address(15 downto 2) := "000010001" & r.cfg.casdel & "0111";        when others => null;        end case;      end if;    when active =>      v.sdcsn := (others => '1'); v.rasn := '1'; v.casn := '1';       v.sdwen := '1'; v.cfg.command := "00";      v.cmstate := leadout; v.trfc := r.cfg.trfc;    when leadout =>      v.trfc := r.trfc - 1;      if r.trfc = "000" then v.cmstate := midle; end if;    end case;-- sdram init    case r.istate is    when iidle =>      if r.cfg.renable = '1' then        v.cfg.command := "01"; v.istate := pre;      end if;    when pre =>      if r.cfg.command = "00" then        v.cfg.command := "10"; v.istate := ref; v.icnt := "111";       end if;    when ref =>      if r.cfg.command = "00" then        v.cfg.command := "10"; v.icnt := r.icnt - 1;	if r.icnt = "000" then v.istate := lmode; v.cfg.command := "11"; end if;       end if;    when lmode =>      if r.cfg.command = "00" then        v.istate := finish;      end if;    when others =>      if r.cfg.renable = '0' then        v.istate := iidle;      end if;    end case;    if (ahbsi.hready and ahbsi.hsel(hindex) ) = '1' then      if ahbsi.htrans(1) = '0' then v.hready := '1'; end if;    end if;    if (r.hsel and r.hio and not r.hready) = '1' then v.hready := '1'; end if;-- second part of main fsm    case r.mstate is    when active =>      if v.hready = '1' then	v.mstate := midle;      end if;    when others => null;    end case;-- sdram refresh counter-- pragma translate_off    if not is_x(r.cfg.refresh) then-- pragma translate_on      if (r.cfg.renable = '1') and (r.istate = finish) then 	v.refresh := r.refresh - 1;        if (v.refresh(14) and not r.refresh(14))  = '1' then 	  v.refresh := r.cfg.refresh;	  v.cfg.command := "10";	end if;      end if;-- pragma translate_off    end if;-- pragma translate_on-- AHB register access    if (r.hsel and r.hio and r.hwrite and r.htrans(1)) = '1' then      v.cfg.command   :=  ahbsi.hwdata(20 downto 19);       v.cfg.csize     :=  ahbsi.hwdata(22 downto 21);       v.cfg.bsize     :=  ahbsi.hwdata(25 downto 23);       v.cfg.casdel    :=  ahbsi.hwdata(26);       v.cfg.trfc      :=  ahbsi.hwdata(29 downto 27);       v.cfg.trp       :=  ahbsi.hwdata(30);       v.cfg.renable   :=  ahbsi.hwdata(31);       v.cfg.refresh   :=  ahbsi.hwdata(14 downto 0);       v.refresh       :=  (others => '0');    end if;    regsd := (others => '0');    regsd(31 downto 19) := r.cfg.renable & r.cfg.trp & r.cfg.trfc &	 r.cfg.casdel & r.cfg.bsize & r.cfg.csize & r.cfg.command;     if BUS64 then regsd(15) := '1'; end if;    regsd(14 downto 0) := r.cfg.refresh;     if (r.hsel and r.hio) = '1' then dout := regsd;    else       if BUS64 and r.bsel = '1' then dout := r.hrdata(63 downto 32);      else dout := r.hrdata(31 downto 0); end if;    end if;    v.nbdrive := not v.bdrive;     if oepol = 1 then bdrive := r.nbdrive; vbdrive := (others => v.nbdrive);    else bdrive := r.bdrive; vbdrive := (others => v.bdrive);end if;     -- reset    if rst = '0' then      v.sdstate	      := sidle;       v.mstate	      := midle;       v.istate	      := iidle;       v.cmstate	      := midle;       v.hsel	      := '0';      v.cfg.command   := "00";      v.cfg.csize     := "10";      v.cfg.bsize     := "000";      v.cfg.casdel    :=  '1';      v.cfg.trfc      := "111";      if pwron = 1 then v.cfg.renable :=  '1';      else v.cfg.renable :=  '0'; end if;      v.cfg.trp       :=  '1';      v.dqm	      := (others => '1');      v.sdwen	      := '1';      v.rasn	      := '1';      v.casn	      := '1';      v.hready	      := '1';      v.bsel	      := '0';      v.startsd       := '0';    end if;    ri <= v;     ribdrive <= vbdrive;         sdo.address  <= r.address;    sdo.bdrive   <= bdrive;    sdo.vbdrive  <= rbdrive;     sdo.sdcsn    <= r.sdcsn;    sdo.sdwen    <= r.sdwen;    sdo.dqm      <= r.dqm;    sdo.rasn     <= r.rasn;    sdo.casn     <= r.casn;    sdo.data     <= r.hwdata;    ahbso.hready  <= r.hready;    ahbso.hresp   <= r.hresp;    ahbso.hrdata  <= dout;    ahbso.hcache  <= not r.hio;  end process;  sdo.sdcke     <= (others => '1');  ahbso.hconfig <= hconfig;  ahbso.hirq    <= (others => '0');  ahbso.hindex  <= hindex;  regs : process(clk,rst)  begin     if rising_edge(clk) then      r <= ri; rbdrive <= ribdrive;      if rst = '0' then        r.icnt <= (others => '0');      end if;     end if;    if rst = '0' then      r.sdcsn  <= (others => '1');      r.bdrive <= '1'; r.nbdrive <= '0';      if oepol = 0 then rbdrive <= (others => '1');      else rbdrive <= (others => '0'); end if;    end if;  end process;-- pragma translate_off  bootmsg : report_version   generic map ("sdctrl" & tost(hindex) & 	": PC133 SDRAM controller rev " & tost(REVISION));-- pragma translate_onend;

⌨️ 快捷键说明

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