📄 sdmctrl.vhd
字号:
if r.trfc = "000" then v.sdstate := sidle; end if; when rd1 => v.casn := '1'; v.sdstate := rd7; if lineburst and (sdi.htrans = "11") then if sdi.rhaddr(4 downto 2) = "111" then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; end if; end if; when rd7 => v.casn := '1'; if r.cfg.casdel = '1' then v.sdstate := rd2; if lineburst and (sdi.htrans = "11") then if sdi.rhaddr(4 downto 2) = "110" then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; end if; end if; else v.sdstate := rd3; if sdi.htrans /= "11" then if (r.trfc(2 downto 1) = "00") then v.rasn := '0'; v.sdwen := '0'; end if; elsif lineburst then if sdi.rhaddr(4 downto 2) = "110" then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; end if; end if; end if; when rd2 => v.casn := '1'; v.sdstate := rd3; if sdi.htrans /= "11" then v.rasn := '0'; v.sdwen := '0'; elsif lineburst then if sdi.rhaddr(4 downto 2) = "101" then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; end if; end if; if v.sdwen = '0' then v.dqm := (others => '1'); end if; when rd3 => v.sdstate := rd4; v.hready := '1'; v.casn := '1'; if r.sdwen = '0' then v.rasn := '1'; v.sdwen := '1'; v.sdcsn := "11"; v.dqm := (others => '1'); elsif lineburst and (sdi.htrans = "11") and (r.casn = '1') then if sdi.rhaddr(4 downto 2) = ("10" & not r.cfg.casdel) then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; end if; end if; when rd4 => v.hready := '1'; v.casn := '1'; if (sdi.htrans /= "11") or (r.sdcsn = "11") or ((sdi.rhaddr(5 downto 2) = "1111") and (r.cfg.command = "10")) -- exit on refresh 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; elsif lineburst then if (sdi.rhaddr(4 downto 2) = lline) and (r.casn = '1') then v.address(9 downto 5) := r.address(9 downto 5) + 1; v.address(4 downto 2) := "000"; v.casn := '0'; 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'); v.casn := '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 if (sdi.idle = '1') then v.busy := '1'; v.sdcsn := (others => '0'); v.rasn := '0'; v.sdwen := '0'; v.address(12) := '1'; v.cmstate := active; end if; when "10" => -- auto-refresh v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0'; v.cmstate := active; when "11" => if (sdi.idle = '1') then v.busy := '1'; v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0'; v.sdwen := '0'; v.cmstate := active; if lineburst then v.address(15 downto 2) := "000010001" & r.cfg.casdel & "0011"; else v.address(15 downto 2) := "000010001" & r.cfg.casdel & "0111"; end if; end if; 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 => if r.trfc = "000" then v.cmstate := midle; end if; end case;-- sdram init case r.istate is when iidle => if (sdi.idle and sdi.enable) = '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 sdi.enable = '0' then v.istate := iidle; end if; end case; if (sdi.hready and sdi.hsel ) = '1' then if sdi.htrans(1) = '0' then v.hready := '1'; end if; 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 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;-- APB register access if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then case apbi.paddr(3 downto 2) is when "01" => if pageburst = 2 then v.cfg.pageburst := apbi.pwdata(17); end if; if sdi.enable = '1' then v.cfg.command := apbi.pwdata(20 downto 19); end if; v.cfg.csize := apbi.pwdata(22 downto 21); v.cfg.bsize := apbi.pwdata(25 downto 23); v.cfg.casdel := apbi.pwdata(26); v.cfg.trfc := apbi.pwdata(29 downto 27); v.cfg.trp := apbi.pwdata(30); v.cfg.renable := apbi.pwdata(31); when "10" => v.cfg.refresh := apbi.pwdata(26 downto 12); v.refresh := (others => '0'); when others => end case; end if; regsd := (others => '0'); case apbi.paddr(3 downto 2) is when "01" => 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 not lineburst then regsd(17) := '1'; end if; when others => regsd(26 downto 12) := r.cfg.refresh; end case; apbo.prdata <= regsd;-- synchronise with sram/prom controller if fast = 0 then if (r.sdstate < wr4) or (v.hsel = '1') then v.busy := '1';end if; else if (r.sdstate < wr4) or (r.startsd = '1') then v.busy := '1';end if; end if; v.busy := v.busy or r.bdelay; busy := v.busy or r.busy; v.aload := r.busy and not v.busy; aload := v.aload;-- generate memory address sdmo.address <= v.address;-- 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"; v.cfg.renable := '0'; v.cfg.trp := '1'; v.dqm := (others => '1'); v.sdwen := '1'; v.rasn := '1'; v.casn := '1'; v.hready := '1'; v.startsd := '0'; if (pageburst = 2) then v.cfg.pageburst := '0'; end if; end if; ri <= v; sdmo.bdrive <= v.bdrive; sdo.sdcke <= (others => '1'); sdo.sdcsn <= r.sdcsn; sdo.sdwen <= r.sdwen; sdo.dqm <= r.dqm; sdo.rasn <= r.rasn; sdo.casn <= r.casn; sdmo.busy <= busy; sdmo.aload <= aload; sdmo.hready <= r.hready; sdmo.hresp <= hresp; sdmo.hsel <= r.hsel; sdmo.bsel <= r.bsel; end process; regs : process(clk,rst) begin if rising_edge(clk) then r <= ri; if rst = '0' then r.icnt <= (others => '0'); end if; end if; if rst = '0' then r.bdrive <= '0'; r.sdcsn <= (others => '1'); end if; end process;end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -