📄 ddrctrl.vhd
字号:
case v.ddrcfg.memCmd is when "01" => -- Precharge all v.cmdbufferdata := CMD_PRE; v.adrbufferdata(10) := '1'; v.pre_chg := (others => '0'); v.memCmdDone := '1'; v.mainstate := c2; when "10" => -- AutoRefresh -- All banks have to be precharged before AR if v.pre_chg = "00000000" then v.cmdbufferdata := CMD_AR; v.memCmdDone := '1'; v.mainstate := c2; v.refreshDone := '1'; else -- Run Precharge, and let AR begin when finished v.cmdbufferdata := CMD_PRE; v.adrbufferdata(10) := '1'; v.pre_chg := (others => '0'); v.mainstate := idle; end if; when "11" => -- LMR -- All banks have to be precharged before LMR if v.pre_chg = "00000000" then v.cmdbufferdata := CMD_LMR; v.adrbufferdata := v.lmradr; v.memCmdDone := '1'; v.mainstate := c2; else v.cmdbufferdata := CMD_PRE; v.adrbufferdata(10) := '1'; v.pre_chg := (others => '0'); v.mainstate := idle; end if; when others => null; end case; v.loadcmdbuffer := '1'; end if; when c2 => if v.ddrcfg.memCmd = "00" then v.refreshDone := '0'; v.mainstate := idle; end if; when others => v.mainstate := init; end case; -- Reset if rst = '0' then -- Main controller v.mainstate := init; v.loadcmdbuffer := '0'; v.cmdbufferdata := CMD_NOP; v.adrbufferdata := (others => '0'); v.use_ahb := 0; v.use_bl := 4; v.use_cas := "00"; v.use_buf := (others => '1'); v.burstlength := 8; v.rw_cmd_done := (others => (others => '1')); v.lmradr := (others => '0'); v.memCmdDone := '0'; v.lockAHB := "00"; v.pre_row := (others => (others => '0')); v.pre_chg := (others => '0'); v.pre_bankadr := (0,0); v.sync2_adr := (others =>(others => '0')); -- For init statemachine v.initstate := idle; v.doMemInit := '0'; v.memInitDone := '0'; v.initDelay := 0; v.cs := "11"; -- For address calculator v.coladdress := (others => (others => '0')); v.tmpcoladdress := (others => (others => '0')); v.rowaddress := (others => (others => '0')); v.addressrange := 0; v.tmpcolbits := 0; v.colbits := 0; v.rowbits := 0; v.bankselect := ("11","11"); v.intbankbits := ("00","00"); -- For refresh timer statemachine v.timerstate := t2; v.doRefresh := '0'; v.refreshDone := '0'; v.refreshTime := 0; v.maxRefreshTime := 0; v.idlecnt := 0; v.refreshcnt := DELAY_200us; -- For DDRCFG register v.apbstate := idle; v.apb_cmd_done := '0'; v.ready := '0'; v.ddrcfg := (ddrcfg_reset(31),ddrcfg_reset(30 downto 29),ddrcfg_reset(28 downto 27), ddrcfg_reset(26 downto 25),ddrcfg_reset(24),ddrcfg_reset(23 downto 22), ddrcfg_reset(21 downto 20),'0'); end if; -- Set output signals mainri <= v; fromMain.hssi.bl <= v.use_bl; fromMain.hssi.ml <= fromAHB(mainr.use_ahb).burst_dm(conv_integer(mainr.use_buf)); fromMain.hssi.cas <= v.use_cas; fromMain.hssi.buf <= v.use_buf; fromMain.hssi.ahb <= v.use_ahb; fromMain.hssi.cs <= v.cs; fromMain.hssi.cmd <= v.cmdbufferdata; fromMain.hssi.cmd_valid <= v.loadcmdbuffer; fromMain.hssi.adr <= v.adrbufferdata; fromMain.ahbctrlsi(0).burstlength <= v.burstlength; fromMain.ahbctrlsi(1).burstlength <= v.burstlength; fromMain.ahbctrlsi(0).r_predict <= v.ddrcfg.r_predict(0); fromMain.ahbctrlsi(1).r_predict <= v.ddrcfg.r_predict(1); fromMain.ahbctrlsi(0).w_prot <= v.ddrcfg.w_prot(0); fromMain.ahbctrlsi(1).w_prot <= v.ddrcfg.w_prot(1); fromMain.ahbctrlsi(0).locked <= v.lockAHB(0); fromMain.ahbctrlsi(1).locked <= v.lockAHB(1); fromMain.ahbctrlsi(0).asramsi.raddress <= v.sync2_adr(0); fromMain.ahbctrlsi(1).asramsi.raddress <= v.sync2_adr(1); fromMain.apbctrlsi.apb_cmd_done <= v.apb_cmd_done; fromMain.apbctrlsi.ready <= v.ready; end process; --Main clocked register mainclk : process(clk0) begin if rising_edge(clk0) then mainr <= mainri; -- Register to sync between different clock domains fromAPB2Main.ddrcfg_reg <= fromAPB.ddrcfg_reg; -- Makes signals from main to AHB, ABP, HS registerd fromMain2AHB <= fromMain.ahbctrlsi; fromMain2APB <= fromMain.apbctrlsi; fromMain2HS <= fromMain.hssi; end if; end process; -- Sync of incoming data valid signals from AHB -- Either if separate clock domains or if syncram_2p -- doesn't support write through (write first) a1rt : if ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0 generate regip1 : process(clk0) begin if rising_edge(clk0) then fromAHB2Main(0).rw_cmd_valid <= fromAHB(0).rw_cmd_valid; fromAHB2Main(0).w_data_valid <= fromAHB(0).w_data_valid; end if; end process; end generate; arf : if not (ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0) generate fromAHB2Main(0).rw_cmd_valid <= fromAHB(0).rw_cmd_valid; fromAHB2Main(0).w_data_valid <= fromAHB(0).w_data_valid; end generate; a2rt : if ahb2sepclk = 1 or syncram_2p_write_through(tech) = 0 generate regip2 : process(clk0) begin if rising_edge(clk0) then fromAHB2Main(1).rw_cmd_valid <= fromAHB(1).rw_cmd_valid; fromAHB2Main(1).w_data_valid <= fromAHB(1).w_data_valid; end if; end process; end generate; a2rf : if not (ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0) generate fromAHB2Main(1).rw_cmd_valid <= fromAHB(1).rw_cmd_valid; fromAHB2Main(1).w_data_valid <= fromAHB(1).w_data_valid; end generate; --------------------------------------------------------------------------------- High speed interface (Physical layer towards memory)------------------------------------------------------------------------------- D0 : hs generic map( tech => tech, dqsize => dqsize, dmsize => dmsize, strobesize => strobesize, clkperiod => clkperiod) port map( rst => rst, clk0 => clk0, clk90 => clk90, clk180 => clk180, clk270 => clk270, hclk => pclk, hssi => toHS, hsso => fromHS); A0 : ahb_slv generic map( hindex => hindex1, haddr => haddr1, hmask => hmask1, sepclk => ahb1sepclk, dqsize => dqsize, dmsize => dmsize, tech => tech) port map ( rst => rst, hclk => hclk1, clk0 => clk0, csi => toAHB(0), cso => fromAHB(0)); B1: if numahb = 2 generate A1 : ahb_slv generic map( hindex => hindex2, haddr => haddr2, hmask => hmask2, sepclk => ahb2sepclk, dqsize => dqsize, dmsize => dmsize) port map ( rst => rst, hclk => hclk2, clk0 => clk0, csi => toAHB(1), cso => fromAHB(1)); end generate; B2 : if numahb /= 2 generate fromAHB(1).rw_cmd_valid <= (others => '1'); end generate;--------------------------------------------------------------------------------- Mapping signals -- Signals to HS toHS.bl <= fromMain.hssi.bl; toHS.ml <= fromMain.hssi.ml; toHS.cas <= fromMain.hssi.cas; toHS.buf <= fromMain.hssi.buf; toHS.ahb <= fromMain.hssi.ahb; toHS.cs <= fromMain.hssi.cs; toHS.adr <= fromMain.hssi.adr; toHS.cmd <= fromMain.hssi.cmd; toHS.cmd_valid <= fromMain.hssi.cmd_valid; toHS.dsramso(0) <= fromAHB(0).dsramso; toHS.dsramso(1) <= fromAHB(1).dsramso; toHS.ddso <= ddso; -- Signals to AHB ctrl 1 toAHB(0).ahbsi <= ahb1si; toAHB(0).asramsi <= fromMain.ahbctrlsi(0).asramsi; toAHB(0).dsramsi <= fromHS.dsramsi(0); toAHB(0).burstlength <= fromMain2AHB(0).burstlength; toAHB(0).r_predict <= fromMain2AHB(0).r_predict; toAHB(0).w_prot <= fromMain2AHB(0).w_prot; toAHB(0).locked <= fromMain2AHB(0).locked; toAHB(0).rw_cmd_done <= fromHS.cmdDone(0); -- Signals to AHB ctrl 2 toAHB(1).ahbsi <= ahb2si; toAHB(1).asramsi <= fromMain.ahbctrlsi(1).asramsi; toAHB(1).dsramsi <= fromHS.dsramsi(1); toAHB(1).burstlength <= fromMain2AHB(1).burstlength; toAHB(1).r_predict <= fromMain2AHB(1).r_predict; toAHB(1).w_prot <= fromMain2AHB(1).w_prot; toAHB(1).locked <= fromMain2AHB(1).locked; toAHB(1).rw_cmd_done <= fromHS.cmdDone(1); -- Ouput signals ahb1so <= fromAHB(0).ahbso; ahb2so <= fromAHB(1).ahbso; ddsi <= fromHS.ddsi; end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -