807 lines
36 KiB
VHDL
807 lines
36 KiB
VHDL
----------------------------------------------------------------------
|
|
---- ----
|
|
---- This file is part of the 'Firebee' project. ----
|
|
---- http://acp.atari.org ----
|
|
---- ----
|
|
---- Description: ----
|
|
---- This design unit provides the DDR controller of the 'Firebee'----
|
|
---- computer. It is optimized for the use of an Altera Cyclone ----
|
|
---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ----
|
|
---- tion of the Firebee configware originally provided by Fredi ----
|
|
---- Ashwanden and Wolfgang Förster. This release is in compa- ----
|
|
---- rision to the first edition completely written in VHDL. ----
|
|
---- ----
|
|
---- Author(s): ----
|
|
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
|
---- ----
|
|
----------------------------------------------------------------------
|
|
---- ----
|
|
---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ----
|
|
---- ----
|
|
---- This source file is free software; you can redistribute it ----
|
|
---- and/or modify it under the terms of the GNU General Public ----
|
|
---- License as published by the Free Software Foundation; either ----
|
|
---- version 2 of the License, or (at your option) any later ----
|
|
---- version. ----
|
|
---- ----
|
|
---- This program is distributed in the hope that it will be ----
|
|
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
|
|
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
|
|
---- PURPOSE. See the GNU General Public License for more ----
|
|
---- details. ----
|
|
---- ----
|
|
---- You should have received a copy of the GNU General Public ----
|
|
---- License along with this program; if not, write to the Free ----
|
|
---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ----
|
|
---- Boston, MA 02110-1301, USA. ----
|
|
---- ----
|
|
----------------------------------------------------------------------
|
|
--
|
|
-- Revision History
|
|
--
|
|
-- Revision 2K12B 20120801 WF
|
|
-- Initial Release of the second edition.
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity DDR_CTRL_V1 is
|
|
port(
|
|
CLK_MAIN : in std_logic;
|
|
DDR_SYNC_66M : in std_logic;
|
|
FB_ADR : in std_logic_vector(31 downto 0);
|
|
FB_CS1n : in std_logic;
|
|
FB_OEn : in std_logic;
|
|
FB_SIZE0 : in std_logic;
|
|
FB_SIZE1 : in std_logic;
|
|
FB_ALE : in std_logic;
|
|
FB_WRn : in std_logic;
|
|
FIFO_CLR : in std_logic;
|
|
VIDEO_RAM_CTR : in std_logic_vector(15 downto 0);
|
|
BLITTER_ADR : in std_logic_vector(31 downto 0);
|
|
BLITTER_SIG : in std_logic;
|
|
BLITTER_WR : in std_logic;
|
|
DDRCLK0 : in std_logic;
|
|
CLK_33M : in std_logic;
|
|
FIFO_MW : in std_logic_vector(8 downto 0);
|
|
VA : out std_logic_vector(12 downto 0);
|
|
VWEn : out std_logic;
|
|
VRASn : out std_logic;
|
|
VCSn : out std_logic;
|
|
VCKE : out std_logic;
|
|
VCASn : out std_logic;
|
|
FB_LE : out std_logic_vector(3 downto 0);
|
|
FB_VDOE : out std_logic_vector(3 downto 0);
|
|
SR_FIFO_WRE : out std_logic;
|
|
SR_DDR_FB : out std_logic;
|
|
SR_DDR_WR : out std_logic;
|
|
SR_DDRWR_D_SEL : out std_logic;
|
|
SR_VDMP : out std_logic_vector(7 downto 0);
|
|
VIDEO_DDR_TA : out std_logic;
|
|
SR_BLITTER_DACK : out std_logic;
|
|
BA : out std_logic_vector(1 downto 0);
|
|
DDRWR_D_SEL1 : out std_logic;
|
|
VDM_SEL : out std_logic_vector(3 downto 0);
|
|
DATA_IN : in std_logic_vector(31 downto 0);
|
|
DATA_OUT : out std_logic_vector(31 downto 16);
|
|
DATA_EN_H : out std_logic;
|
|
DATA_EN_L : out std_logic
|
|
);
|
|
end entity DDR_CTRL_V1;
|
|
|
|
architecture BEHAVIOUR of DDR_CTRL_V1 is
|
|
-- FIFO WATER MARK:
|
|
constant FIFO_LWM : std_logic_vector(8 downto 0) := "000000000";
|
|
constant FIFO_MWM : std_logic_vector(8 downto 0) := "011001000"; -- 200.
|
|
constant FIFO_HWM : std_logic_vector(8 downto 0) := "111110100"; -- 500.
|
|
|
|
type ACCESS_WIDTH_TYPE is (LONG, WORD, BYTE);
|
|
type DDR_ACCESS_TYPE is (CPU, FIFO, BLITTER, NONE);
|
|
type FB_REGDDR_TYPE is (FR_WAIT, FR_S0, FR_S1, FR_S2, FR_S3);
|
|
type DDR_SM_TYPE is (DS_T1, DS_T2A, DS_T2B, DS_T3, DS_N5, DS_N6, DS_N7, DS_N8, -- Start (normal 8 cycles total = 60ns).
|
|
DS_C2, DS_C3, DS_C4, DS_C5, DS_C6, DS_C7, -- Configuration.
|
|
DS_T4R, DS_T5R, -- Read CPU or BLITTER.
|
|
DS_T4W, DS_T5W, DS_T6W, DS_T7W, DS_T8W, DS_T9W, -- Write CPU or BLITTER.
|
|
DS_T4F, DS_T5F, DS_T6F, DS_T7F, DS_T8F, DS_T9F, DS_T10F, -- Read FIFO.
|
|
DS_CB6, DS_CB8, -- Close FIFO bank.
|
|
DS_R2, DS_R3, DS_R4, DS_R5, DS_R6); -- Refresh: 10 x 7.5ns = 75ns.
|
|
|
|
signal ACCESS_WIDTH : ACCESS_WIDTH_TYPE;
|
|
signal FB_REGDDR : FB_REGDDR_TYPE;
|
|
signal FB_REGDDR_NEXT : FB_REGDDR_TYPE;
|
|
signal DDR_ACCESS : DDR_ACCESS_TYPE;
|
|
signal DDR_STATE : DDR_SM_TYPE;
|
|
signal DDR_NEXT_STATE : DDR_SM_TYPE;
|
|
signal VCS_In : std_logic;
|
|
signal VCKE_I : std_logic;
|
|
signal BYTE_SEL : std_logic_vector(3 downto 0);
|
|
signal SR_FIFO_WRE_I : std_logic;
|
|
signal VCAS : std_logic;
|
|
signal VRAS : std_logic;
|
|
signal VWE : std_logic;
|
|
signal MCS : std_logic_vector(1 downto 0);
|
|
signal BUS_CYC : std_logic;
|
|
signal BUS_CYC_END : std_logic;
|
|
signal BLITTER_REQ : std_logic;
|
|
signal BLITTER_ROW_ADR : std_logic_vector(12 downto 0);
|
|
signal BLITTER_BA : std_logic_vector(1 downto 0);
|
|
signal BLITTER_COL_ADR : std_logic_vector(9 downto 0);
|
|
signal CPU_DDR_SYNC : std_logic;
|
|
signal CPU_ROW_ADR : std_logic_vector(12 downto 0);
|
|
signal CPU_BA : std_logic_vector(1 downto 0);
|
|
signal CPU_COL_ADR : std_logic_vector(9 downto 0);
|
|
signal CPU_REQ : std_logic;
|
|
signal DDR_SEL : std_logic;
|
|
signal DDR_CS : std_logic;
|
|
signal DDR_CONFIG : std_logic;
|
|
signal FIFO_REQ : std_logic;
|
|
signal FIFO_ROW_ADR : std_logic_vector(12 downto 0);
|
|
signal FIFO_BA : std_logic_vector(1 downto 0);
|
|
signal FIFO_COL_ADR : unsigned(9 downto 0);
|
|
signal FIFO_ACTIVE : std_logic;
|
|
signal FIFO_CLR_SYNC : std_logic;
|
|
signal VDM_SEL_I : std_logic_vector(3 downto 0);
|
|
signal CLEAR_FIFO_CNT : std_logic;
|
|
signal STOP : std_logic;
|
|
signal FIFO_BANK_OK : std_logic;
|
|
signal DDR_REFRESH_ON : std_logic;
|
|
signal DDR_REFRESH_CNT : unsigned(10 downto 0);
|
|
signal DDR_REFRESH_REQ : std_logic;
|
|
signal DDR_REFRESH_SIG : unsigned(3 downto 0);
|
|
signal REFRESH_TIME : std_logic;
|
|
signal VIDEO_BASE_L_D : std_logic_vector(7 downto 0);
|
|
signal VIDEO_BASE_L : std_logic;
|
|
signal VIDEO_BASE_M_D : std_logic_vector(7 downto 0);
|
|
signal VIDEO_BASE_M : std_logic;
|
|
signal VIDEO_BASE_H_D : std_logic_vector(7 downto 0);
|
|
signal VIDEO_BASE_H : std_logic;
|
|
signal VIDEO_BASE_X_D : std_logic_vector(2 downto 0);
|
|
signal VIDEO_ADR_CNT : unsigned(22 downto 0);
|
|
signal VIDEO_CNT_L : std_logic;
|
|
signal VIDEO_CNT_M : std_logic;
|
|
signal VIDEO_CNT_H : std_logic;
|
|
signal VIDEO_BASE_ADR : std_logic_vector(22 downto 0);
|
|
signal VIDEO_ACT_ADR : std_logic_vector(26 downto 0);
|
|
signal FB_ADR_I : std_logic_vector(32 downto 0);
|
|
|
|
|
|
signal VA_S : std_logic_vector(12 downto 0);
|
|
signal VA_P : std_logic_vector(12 downto 0);
|
|
signal BA_S : std_logic_vector(1 downto 0) ;
|
|
signal BA_P : std_logic_vector(1 downto 0);
|
|
signal TSIZ : std_logic_vector(1 downto 0);
|
|
begin
|
|
TSIZ <= FB_SIZE1 & FB_SIZE0;
|
|
with TSIZ select
|
|
ACCESS_WIDTH <= LONG when "11",
|
|
WORD when "00",
|
|
BYTE when others;
|
|
|
|
-- Byte selectors:
|
|
BYTE_SEL(0) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else
|
|
'1' when FB_ADR(1 downto 0) = "00" else '0'; -- Byte 0.
|
|
|
|
BYTE_SEL(1) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else
|
|
'1' when ACCESS_WIDTH = BYTE and FB_ADR(1) = '0' else -- High word.
|
|
'1' when FB_ADR(1 downto 0) = "01" else '0'; -- Byte 1.
|
|
|
|
BYTE_SEL(2) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else
|
|
'1' when FB_ADR(1 downto 0) = "10" else '0'; -- Byte 2.
|
|
|
|
BYTE_SEL(3) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else
|
|
'1' when ACCESS_WIDTH = BYTE and FB_ADR(1) = '1' else -- Low word.
|
|
'1' when FB_ADR(1 downto 0) = "11" else '0'; -- Byte 3.
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
------------------------------------ CPU READ (REG DDR => CPU) AND WRITE (CPU => REG DDR) ---------------------------------------------------------------------
|
|
FBCTRL_REG: process
|
|
begin
|
|
wait until CLK_MAIN = '1' and CLK_MAIN' event;
|
|
FB_REGDDR <= FB_REGDDR_NEXT;
|
|
end process FBCTRL_REG;
|
|
|
|
FBCTRL_DEC: process(FB_REGDDR, BUS_CYC, DDR_SEL, ACCESS_WIDTH, FB_WRn, DDR_CS)
|
|
begin
|
|
case FB_REGDDR is
|
|
when FR_WAIT =>
|
|
if BUS_CYC = '1' then
|
|
FB_REGDDR_NEXT <= FR_S0;
|
|
elsif DDR_SEL = '1' and ACCESS_WIDTH = LONG and FB_WRn = '0' then
|
|
FB_REGDDR_NEXT <= FR_S0;
|
|
else
|
|
FB_REGDDR_NEXT <= FR_WAIT;
|
|
end if;
|
|
when FR_S0 =>
|
|
if DDR_CS = '1' and ACCESS_WIDTH = LONG then
|
|
FB_REGDDR_NEXT <= FR_S1;
|
|
else
|
|
FB_REGDDR_NEXT <= FR_WAIT;
|
|
end if;
|
|
when FR_S1 =>
|
|
if DDR_CS = '1' then
|
|
FB_REGDDR_NEXT <= FR_S2;
|
|
else
|
|
FB_REGDDR_NEXT <= FR_WAIT;
|
|
end if;
|
|
when FR_S2 =>
|
|
if DDR_CS = '1' and BUS_CYC = '0' and ACCESS_WIDTH = LONG and FB_WRn = '0' then -- Eventually wait during long word access.
|
|
FB_REGDDR_NEXT <= FR_S2;
|
|
elsif DDR_CS = '1' then
|
|
FB_REGDDR_NEXT <= FR_S3;
|
|
else
|
|
FB_REGDDR_NEXT <= FR_WAIT;
|
|
end if;
|
|
when FR_S3 =>
|
|
FB_REGDDR_NEXT <= FR_WAIT;
|
|
end case;
|
|
end process FBCTRL_DEC;
|
|
|
|
-- Coldfire CPU access:
|
|
FB_LE(0) <= not FB_WRn when FB_REGDDR = FR_WAIT else
|
|
not FB_WRn when FB_REGDDR = FR_S0 and DDR_CS = '1' else '0';
|
|
FB_LE(1) <= not FB_WRn when FB_REGDDR = FR_S1 and DDR_CS = '1' else '0';
|
|
FB_LE(2) <= not FB_WRn when FB_REGDDR = FR_S2 and DDR_CS = '1' else '0';
|
|
FB_LE(3) <= not FB_WRn when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0';
|
|
|
|
-- Video data access:
|
|
VIDEO_DDR_TA <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' else
|
|
'1' when FB_REGDDR = FR_S1 and DDR_CS = '1' else
|
|
'1' when FB_REGDDR = FR_S2 and FB_REGDDR_NEXT = FR_S3 else
|
|
'1' when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0';
|
|
|
|
-- FB_VDOE # VIDEO_OE.
|
|
-- Write access for video data:
|
|
FB_VDOE(0) <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and ACCESS_WIDTH = LONG else
|
|
'1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and ACCESS_WIDTH /= LONG and CLK_MAIN = '0' else '0';
|
|
FB_VDOE(1) <= '1' when FB_REGDDR = FR_S1 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' else '0';
|
|
FB_VDOE(2) <= '1' when FB_REGDDR = FR_S2 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' else '0';
|
|
FB_VDOE(3) <= '1' when FB_REGDDR = FR_S3 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and CLK_MAIN = '0' else '0';
|
|
|
|
BUS_CYC_END <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and ACCESS_WIDTH /= LONG else
|
|
'1' when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0';
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
------------------------------------------------------ DDR State Machine --------------------------------------------------------------------------------------
|
|
DDR_STATE_REG: process
|
|
begin
|
|
wait until DDRCLK0 = '1' and DDRCLK0' event;
|
|
DDR_STATE <= DDR_NEXT_STATE;
|
|
end process DDR_STATE_REG;
|
|
|
|
DDR_STATE_DEC: process(DDR_STATE, DDR_REFRESH_REQ, CPU_DDR_SYNC, DDR_CONFIG, FB_WRn, DDR_ACCESS, BLITTER_WR, FIFO_REQ, FIFO_BANK_OK,
|
|
FIFO_MW, CPU_REQ, VIDEO_ADR_CNT, DDR_SEL, FB_SIZE1, FB_SIZE0, DATA_IN, FIFO_BA, DDR_REFRESH_SIG)
|
|
begin
|
|
case DDR_STATE is
|
|
when DS_T1 =>
|
|
if DDR_REFRESH_REQ = '1' then
|
|
DDR_NEXT_STATE <= DS_R2;
|
|
elsif CPU_DDR_SYNC = '1' and DDR_CONFIG = '1' then -- Synchronous start.
|
|
DDR_NEXT_STATE <= DS_C2;
|
|
elsif CPU_DDR_SYNC = '1' and CPU_REQ = '1' then -- Synchronous start.
|
|
DDR_NEXT_STATE <= DS_T2B;
|
|
elsif CPU_DDR_SYNC = '1' then
|
|
DDR_NEXT_STATE <= DS_T2A;
|
|
else
|
|
DDR_NEXT_STATE <= DS_T1; -- Synchronize.
|
|
end if;
|
|
when DS_T2A => -- Fast access, in this case page is always not ok.
|
|
DDR_NEXT_STATE <= DS_T3;
|
|
when DS_T2B =>
|
|
DDR_NEXT_STATE <= DS_T3;
|
|
when DS_T3 =>
|
|
if DDR_ACCESS = CPU and FB_WRn = '0' then
|
|
DDR_NEXT_STATE <= DS_T4W;
|
|
elsif DDR_ACCESS = BLITTER and BLITTER_WR = '1' then
|
|
DDR_NEXT_STATE <= DS_T4W;
|
|
elsif DDR_ACCESS = CPU then -- CPU?
|
|
DDR_NEXT_STATE <= DS_T4R;
|
|
elsif DDR_ACCESS = FIFO then -- FIFO?
|
|
DDR_NEXT_STATE <= DS_T4F;
|
|
elsif DDR_ACCESS = BLITTER then
|
|
DDR_NEXT_STATE <= DS_T4R;
|
|
else
|
|
DDR_NEXT_STATE <= DS_N8;
|
|
end if;
|
|
-- Read:
|
|
when DS_T4R =>
|
|
DDR_NEXT_STATE <= DS_T5R;
|
|
when DS_T5R =>
|
|
if FIFO_REQ = '1' and FIFO_BANK_OK = '1' then -- Insert FIFO read, when bank ok.
|
|
DDR_NEXT_STATE <= DS_T6F;
|
|
else
|
|
DDR_NEXT_STATE <= DS_CB6;
|
|
end if;
|
|
-- Write:
|
|
when DS_T4W =>
|
|
DDR_NEXT_STATE <= DS_T5W;
|
|
when DS_T5W =>
|
|
DDR_NEXT_STATE <= DS_T6W;
|
|
when DS_T6W =>
|
|
DDR_NEXT_STATE <= DS_T7W;
|
|
when DS_T7W =>
|
|
DDR_NEXT_STATE <= DS_T8W;
|
|
when DS_T8W =>
|
|
DDR_NEXT_STATE <= DS_T9W;
|
|
when DS_T9W =>
|
|
if FIFO_REQ = '1' and FIFO_BANK_OK = '1' then
|
|
DDR_NEXT_STATE <= DS_T6F;
|
|
else
|
|
DDR_NEXT_STATE <= DS_CB6;
|
|
end if;
|
|
-- FIFO read:
|
|
when DS_T4F =>
|
|
DDR_NEXT_STATE <= DS_T5F;
|
|
when DS_T5F =>
|
|
if FIFO_REQ = '1' then
|
|
DDR_NEXT_STATE <= DS_T6F;
|
|
else
|
|
DDR_NEXT_STATE <= DS_CB6; -- Leave open.
|
|
end if;
|
|
when DS_T6F =>
|
|
DDR_NEXT_STATE <= DS_T7F;
|
|
when DS_T7F =>
|
|
if CPU_REQ = '1' and FIFO_MW > FIFO_LWM then
|
|
DDR_NEXT_STATE <= DS_CB8; -- Close bank.
|
|
elsif FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then -- New page?
|
|
DDR_NEXT_STATE <= DS_CB8; -- Close bank.
|
|
elsif FIFO_REQ = '1' then
|
|
DDR_NEXT_STATE <= DS_T8F;
|
|
else
|
|
DDR_NEXT_STATE <= DS_CB8; -- Close bank.
|
|
end if;
|
|
when DS_T8F =>
|
|
if FIFO_MW < FIFO_LWM then -- Emergency?
|
|
DDR_NEXT_STATE <= DS_T5F; -- Yes!
|
|
else
|
|
DDR_NEXT_STATE <= DS_T9F;
|
|
end if;
|
|
when DS_T9F =>
|
|
if FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then -- New page?
|
|
DDR_NEXT_STATE <= DS_CB6; -- Close bank.
|
|
elsif FIFO_REQ = '1' then
|
|
DDR_NEXT_STATE <= DS_T10F;
|
|
else
|
|
DDR_NEXT_STATE <= DS_CB6; -- Close bank.
|
|
end if;
|
|
when DS_T10F =>
|
|
if DDR_SEL = '1' and (FB_WRn = '1' or (FB_SIZE0 and FB_SIZE1) = '0') and DATA_IN(13 downto 12) /= FIFO_BA then
|
|
DDR_NEXT_STATE <= DS_T3;
|
|
else
|
|
DDR_NEXT_STATE <= DS_T7F;
|
|
end if;
|
|
-- Configuration cycles:
|
|
when DS_C2 =>
|
|
DDR_NEXT_STATE <= DS_C3;
|
|
when DS_C3 =>
|
|
DDR_NEXT_STATE <= DS_C4;
|
|
when DS_C4 =>
|
|
if CPU_REQ = '1' then
|
|
DDR_NEXT_STATE <= DS_C5;
|
|
else
|
|
DDR_NEXT_STATE <= DS_T1;
|
|
end if;
|
|
when DS_C5 =>
|
|
DDR_NEXT_STATE <= DS_C6;
|
|
when DS_C6 =>
|
|
DDR_NEXT_STATE <= DS_C7;
|
|
when DS_C7 =>
|
|
DDR_NEXT_STATE <= DS_N8;
|
|
-- Close FIFO bank.
|
|
when DS_CB6 =>
|
|
DDR_NEXT_STATE <= DS_N7;
|
|
when DS_CB8 =>
|
|
DDR_NEXT_STATE <= DS_T1;
|
|
-- Refresh 70ns = ten cycles.
|
|
when DS_R2 =>
|
|
if DDR_REFRESH_SIG = x"9" then -- One cycle delay to close all banks.
|
|
DDR_NEXT_STATE <= DS_R4;
|
|
else
|
|
DDR_NEXT_STATE <= DS_R3;
|
|
end if;
|
|
when DS_R3 =>
|
|
DDR_NEXT_STATE <= DS_R4;
|
|
when DS_R4 =>
|
|
DDR_NEXT_STATE <= DS_R5;
|
|
when DS_R5 =>
|
|
DDR_NEXT_STATE <= DS_R6;
|
|
when DS_R6 =>
|
|
DDR_NEXT_STATE <= DS_N5;
|
|
-- Loop:
|
|
when DS_N5 =>
|
|
DDR_NEXT_STATE <= DS_N6;
|
|
when DS_N6 =>
|
|
DDR_NEXT_STATE <= DS_N7;
|
|
when DS_N7 =>
|
|
DDR_NEXT_STATE <= DS_N8;
|
|
when DS_N8 =>
|
|
DDR_NEXT_STATE <= DS_T1;
|
|
end case;
|
|
end process DDR_STATE_DEC;
|
|
|
|
P_CLK0: process
|
|
begin
|
|
wait until DDRCLK0 = '1' and DDRCLK0' event;
|
|
-- Default assignments;
|
|
DDR_ACCESS <= NONE;
|
|
SR_FIFO_WRE_I <= '0';
|
|
SR_VDMP <= x"00";
|
|
SR_DDR_WR <= '0';
|
|
SR_DDRWR_D_SEL <= '0';
|
|
|
|
MCS <= MCS(0) & CLK_MAIN;
|
|
BLITTER_REQ <= BLITTER_SIG and not DDR_CONFIG and VCKE_I and not VCS_In;
|
|
FIFO_CLR_SYNC <= FIFO_CLR;
|
|
CLEAR_FIFO_CNT <= FIFO_CLR_SYNC or not FIFO_ACTIVE;
|
|
STOP <= FIFO_CLR_SYNC or CLEAR_FIFO_CNT;
|
|
|
|
if FIFO_MW < FIFO_MWM then
|
|
FIFO_REQ <= '1';
|
|
elsif FIFO_MW < FIFO_HWM and FIFO_REQ = '1' then
|
|
FIFO_REQ <= '1';
|
|
elsif FIFO_ACTIVE = '1' and CLEAR_FIFO_CNT = '0' and STOP = '0' and DDR_CONFIG = '0' and VCKE_I = '1' and VCS_In = '0' then
|
|
FIFO_REQ <= '1';
|
|
else
|
|
FIFO_REQ <= '1';
|
|
end if;
|
|
|
|
if CLEAR_FIFO_CNT = '1' then
|
|
VIDEO_ADR_CNT <= unsigned(VIDEO_BASE_ADR);
|
|
elsif SR_FIFO_WRE_I = '1' then
|
|
VIDEO_ADR_CNT <= VIDEO_ADR_CNT + 1;
|
|
end if;
|
|
|
|
if MCS = "10" and VCKE_I = '1' and VCS_In = '0' then
|
|
CPU_DDR_SYNC <= '1';
|
|
else
|
|
CPU_DDR_SYNC <= '0';
|
|
end if;
|
|
|
|
if DDR_REFRESH_SIG /= x"0" and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' and REFRESH_TIME = '1' then
|
|
DDR_REFRESH_REQ <= '1';
|
|
else
|
|
DDR_REFRESH_REQ <= '0';
|
|
end if;
|
|
|
|
if DDR_REFRESH_CNT = "00000000000" and CLK_MAIN = '0' then
|
|
REFRESH_TIME <= '1';
|
|
else
|
|
REFRESH_TIME <= '0';
|
|
end if;
|
|
|
|
if REFRESH_TIME = '1' and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' then
|
|
DDR_REFRESH_SIG <= x"9";
|
|
elsif DDR_STATE = DS_R6 and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' then
|
|
DDR_REFRESH_SIG <= DDR_REFRESH_SIG - 1;
|
|
else
|
|
DDR_REFRESH_SIG <= x"0";
|
|
end if;
|
|
|
|
if BUS_CYC_END = '1' then
|
|
BUS_CYC <= '0';
|
|
elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and CPU_REQ = '1' then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_T2B then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA then
|
|
BUS_CYC <= '1';
|
|
elsif DDR_STATE = DS_C3 then
|
|
BUS_CYC <= CPU_REQ;
|
|
end if;
|
|
|
|
if DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and CPU_REQ = '1' then
|
|
VA_S <= CPU_ROW_ADR;
|
|
BA_S <= CPU_BA;
|
|
DDR_ACCESS <= CPU;
|
|
elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and FIFO_REQ = '1' then
|
|
VA_P <= FIFO_ROW_ADR;
|
|
BA_P <= FIFO_BA;
|
|
DDR_ACCESS <= FIFO;
|
|
elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and BLITTER_REQ = '0' then
|
|
VA_P <= BLITTER_ROW_ADR;
|
|
BA_P <= BLITTER_BA;
|
|
DDR_ACCESS <= BLITTER;
|
|
elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' then
|
|
VA_S(10) <= '1';
|
|
DDR_ACCESS <= CPU;
|
|
elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') then
|
|
VA_S(10) <= '1';
|
|
DDR_ACCESS <= CPU;
|
|
elsif DDR_STATE = DS_T2A then
|
|
-- ?? mfro
|
|
VA_S(10) <= not (FIFO_ACTIVE and FIFO_REQ);
|
|
DDR_ACCESS <= FIFO;
|
|
FIFO_BANK_OK <= FIFO_ACTIVE and FIFO_REQ;
|
|
-- ?? mfro BLITTER_AC <= BLITTER_ACTIVE and BLITTER_REQ;
|
|
elsif DDR_STATE = DS_T2B then
|
|
FIFO_BANK_OK <= '0';
|
|
elsif DDR_STATE = DS_T3 then
|
|
VA_S(10) <= VA_S(10);
|
|
if (FB_WRn = '0' and DDR_ACCESS = CPU) or (BLITTER_WR = '1' and DDR_ACCESS = BLITTER) then
|
|
VA_S(9 downto 0) <= CPU_COL_ADR;
|
|
BA_S <= CPU_BA;
|
|
elsif FIFO_ACTIVE = '1' then
|
|
VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR);
|
|
BA_S <= FIFO_BA;
|
|
elsif DDR_ACCESS = BLITTER then
|
|
VA_S(9 downto 0) <= BLITTER_COL_ADR;
|
|
BA_S <= BLITTER_BA;
|
|
end if;
|
|
elsif DDR_STATE = DS_T4R then
|
|
-- mfro SR_DDR_FB <= CPU_AC;
|
|
-- mfro SR_BLITTER_DACK <= BLITTER_AC;
|
|
elsif DDR_STATE = DS_T5R and FIFO_REQ = '1' and FIFO_BANK_OK = '1' then
|
|
VA_S(10) <= '0';
|
|
VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR);
|
|
BA_S <= FIFO_BA;
|
|
elsif DDR_STATE = DS_T5R then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T4W then
|
|
VA_S(10) <= VA_S(10);
|
|
-- mfro SR_BLITTER_DACK <= BLITTER_AC;
|
|
elsif DDR_STATE = DS_T5W then
|
|
VA_S(10) <= VA_S(10);
|
|
if DDR_ACCESS = CPU then
|
|
VA_S(9 downto 0) <= CPU_COL_ADR;
|
|
BA_S <= CPU_BA;
|
|
elsif DDR_ACCESS = BLITTER then
|
|
VA_S(9 downto 0) <= BLITTER_COL_ADR;
|
|
BA_S <= BLITTER_BA;
|
|
end if;
|
|
if DDR_ACCESS = BLITTER and FB_SIZE1 = '1' and FB_SIZE0 = '1' then
|
|
SR_VDMP <= BYTE_SEL & x"F";
|
|
elsif DDR_ACCESS = BLITTER then
|
|
SR_VDMP <= BYTE_SEL & x"0";
|
|
else
|
|
SR_VDMP <= BYTE_SEL & x"0";
|
|
end if;
|
|
elsif DDR_STATE = DS_T6W then
|
|
SR_DDR_WR <= '1';
|
|
SR_DDRWR_D_SEL <= '1';
|
|
if DDR_ACCESS = BLITTER or (FB_SIZE1 = '1' and FB_SIZE0 = '1') then
|
|
SR_VDMP <= x"FF";
|
|
else
|
|
SR_VDMP <= x"00";
|
|
end if;
|
|
elsif DDR_STATE = DS_T7W then
|
|
SR_DDR_WR <= '1';
|
|
SR_DDRWR_D_SEL <= '1';
|
|
elsif DDR_STATE = DS_T9W and FIFO_REQ = '1' and FIFO_BANK_OK = '1' then
|
|
VA_S(10) <= '0';
|
|
VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR);
|
|
BA_S <= FIFO_BA;
|
|
elsif DDR_STATE = DS_T9W then
|
|
VA_S(10) <= '0';
|
|
elsif DDR_STATE = DS_T4F then
|
|
SR_FIFO_WRE_I <= '1';
|
|
elsif DDR_STATE = DS_T5F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T5F and FIFO_REQ = '1' then
|
|
VA_S(10) <= '0';
|
|
VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100");
|
|
BA_S <= FIFO_BA;
|
|
elsif DDR_STATE = DS_T5F then
|
|
VA_S(10) <= '0';
|
|
elsif DDR_STATE = DS_T6F then
|
|
SR_FIFO_WRE_I <= '1';
|
|
elsif DDR_STATE = DS_T7F and CPU_REQ = '1' and FIFO_MW > FIFO_LWM then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T7F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T7F and FIFO_REQ = '1' then
|
|
VA_S(10) <= '0';
|
|
VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100");
|
|
BA_S <= FIFO_BA;
|
|
elsif DDR_STATE = DS_T7F then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T9F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T9F and FIFO_REQ = '1' then
|
|
VA_P(10) <= '0';
|
|
VA_P(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100");
|
|
BA_P <= FIFO_BA;
|
|
elsif DDR_STATE = DS_T9F then
|
|
VA_S(10) <= '1';
|
|
elsif DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA then
|
|
VA_S(10) <= '1';
|
|
DDR_ACCESS <= CPU;
|
|
elsif DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA then
|
|
VA_S(10) <= '1';
|
|
DDR_ACCESS <= CPU;
|
|
elsif DDR_STATE = DS_T10F then
|
|
SR_FIFO_WRE_I <= '1';
|
|
elsif DDR_STATE = DS_C6 then
|
|
VA_S <= DATA_IN(12 downto 0);
|
|
BA_S <= DATA_IN(14 downto 13);
|
|
elsif DDR_STATE = DS_CB6 then
|
|
FIFO_BANK_OK <= '0';
|
|
elsif DDR_STATE = DS_CB8 then
|
|
FIFO_BANK_OK <= '0';
|
|
elsif DDR_STATE = DS_R2 then
|
|
FIFO_BANK_OK <= '0';
|
|
else
|
|
end if;
|
|
end process P_CLK0;
|
|
|
|
DDR_SEL <= '1' when FB_ALE = '1' and DATA_IN(31 downto 30) = "01" else '0';
|
|
|
|
P_DDR_CS: process
|
|
begin
|
|
wait until CLK_MAIN = '1' and CLK_MAIN' event;
|
|
if FB_ALE = '1' then
|
|
DDR_CS <= DDR_SEL;
|
|
end if;
|
|
end process P_DDR_CS;
|
|
|
|
P_CPU_REQ: process
|
|
begin
|
|
wait until DDR_SYNC_66M = '1' and DDR_SYNC_66M' event;
|
|
if DDR_SEL = '1' and FB_WRn = '1' and DDR_CONFIG = '0' then
|
|
CPU_REQ <= '1';
|
|
elsif DDR_SEL = '1' and FB_SIZE1 = '0' and FB_SIZE1 = '0' and DDR_CONFIG = '0' then -- Start when not config and not long word access.
|
|
CPU_REQ <= '1';
|
|
elsif DDR_SEL = '1' and FB_SIZE1 = '0' and FB_SIZE1 = '1' and DDR_CONFIG = '0' then -- Start when not config and not long word access.
|
|
CPU_REQ <= '1';
|
|
elsif DDR_SEL = '1' and FB_SIZE1 = '1' and FB_SIZE1 = '0' and DDR_CONFIG = '0' then -- Start when not config and not long word access.
|
|
CPU_REQ <= '1';
|
|
elsif DDR_SEL = '1' and DDR_CONFIG = '1' then -- Config, start immediately.
|
|
CPU_REQ <= '1';
|
|
elsif FB_REGDDR = FR_S1 and FB_WRn = '0' then -- Long word write later.
|
|
CPU_REQ <= '1';
|
|
elsif FB_REGDDR /= FR_S1 and FB_REGDDR /= FR_S3 and BUS_CYC_END = '0' and BUS_CYC = '0' then -- Halt, bus cycle in progress or ready.
|
|
CPU_REQ <= '0';
|
|
end if;
|
|
end process P_CPU_REQ;
|
|
|
|
P_REFRESH: process
|
|
-- Refresh: Always 8 at a time every 7.8us.
|
|
-- 7.8us x 8 = 62.4us = 2059 -> 2048 @ 33MHz.
|
|
begin
|
|
wait until CLK_33M = '1' and CLK_33M' event;
|
|
DDR_REFRESH_CNT <= DDR_REFRESH_CNT + 1; -- Count 0 to 2047.
|
|
end process P_REFRESH;
|
|
|
|
SR_FIFO_WRE <= SR_FIFO_WRE_I;
|
|
|
|
VA <= DATA_IN(26 downto 14) when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else
|
|
DATA_IN(26 downto 14) when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else
|
|
VA_P when DDR_STATE = DS_T2A else
|
|
DATA_IN(26 downto 14) when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else
|
|
DATA_IN(26 downto 14) when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else
|
|
VA_P when DDR_STATE = DS_T10F else
|
|
"0010000000000" when DDR_STATE = DS_R2 and DDR_REFRESH_SIG = x"9" else VA_S;
|
|
|
|
BA <= DATA_IN(13 downto 12) when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else
|
|
DATA_IN(13 downto 12) when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else
|
|
BA_P when DDR_STATE = DS_T2A else
|
|
DATA_IN(13 downto 12) when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else
|
|
DATA_IN(13 downto 12) when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else
|
|
BA_P when DDR_STATE = DS_T10F else BA_S;
|
|
|
|
VRAS <= '1' when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else
|
|
'1' when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else
|
|
'1' when DDR_STATE = DS_T2A and DDR_ACCESS = FIFO and FIFO_REQ = '1' else
|
|
'1' when DDR_STATE = DS_T2A and DDR_ACCESS = BLITTER and BLITTER_REQ = '1' else
|
|
'1' when DDR_STATE = DS_T2B else
|
|
'1' when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else
|
|
'1' when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else
|
|
DATA_IN(18) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else
|
|
'1' when DDR_STATE = DS_CB6 else
|
|
'1' when DDR_STATE = DS_CB8 else
|
|
'1' when DDR_STATE = DS_R2 else '0';
|
|
|
|
VCAS <= '1' when DDR_STATE = DS_T4R else
|
|
'1' when DDR_STATE = DS_T6W else
|
|
'1' when DDR_STATE = DS_T4F else
|
|
'1' when DDR_STATE = DS_T6F else
|
|
'1' when DDR_STATE = DS_T8F else
|
|
'1' when DDR_STATE = DS_T10F and VRAS = '0' else
|
|
DATA_IN(17) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else
|
|
'1' when DDR_STATE = DS_R2 and DDR_REFRESH_SIG /= x"9" else '0';
|
|
|
|
VWE <= '1' when DDR_STATE = DS_T6W else
|
|
DATA_IN(16) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else
|
|
'1' when DDR_STATE = DS_CB6 else
|
|
'1' when DDR_STATE = DS_CB8 else
|
|
'1' when DDR_STATE = DS_R2 and DDR_REFRESH_SIG = x"9" else '0';
|
|
|
|
-- DDR controller:
|
|
-- VIDEO RAM CONTROL REGISTER (is in VIDEO_MUX_CTR)
|
|
-- $F0000400: BIT 0: VCKE; 1: not nVCS ;2:REFRESH ON , (0=FIFO and CNT CLEAR);
|
|
-- 3: CONFIG; 8: FIFO_ACTIVE;
|
|
VCKE <= VCKE_I;
|
|
VCKE_I <= VIDEO_RAM_CTR(0);
|
|
VCSn <= VCS_In;
|
|
VCS_In <= not VIDEO_RAM_CTR(1);
|
|
DDR_REFRESH_ON <= VIDEO_RAM_CTR(2);
|
|
DDR_CONFIG <= VIDEO_RAM_CTR(3);
|
|
FIFO_ACTIVE <= VIDEO_RAM_CTR(8);
|
|
|
|
CPU_ROW_ADR <= FB_ADR(26 downto 14);
|
|
CPU_BA <= FB_ADR(13 downto 12);
|
|
CPU_COL_ADR <= FB_ADR(11 downto 2);
|
|
VRASn <= not VRAS;
|
|
VCASn <= not VCAS;
|
|
VWEn <= not VWE;
|
|
|
|
DDRWR_D_SEL1 <= '1' when DDR_ACCESS = BLITTER else '0';
|
|
|
|
BLITTER_ROW_ADR <= BLITTER_ADR(26 downto 14);
|
|
BLITTER_BA <= BLITTER_ADR(13 downto 12);
|
|
BLITTER_COL_ADR <= BLITTER_ADR(11 downto 2);
|
|
|
|
FIFO_ROW_ADR <= std_logic_vector(VIDEO_ADR_CNT(22 downto 10));
|
|
FIFO_BA <= std_logic_vector(VIDEO_ADR_CNT(9 downto 8));
|
|
FIFO_COL_ADR <= VIDEO_ADR_CNT(7 downto 0) & "00";
|
|
|
|
VIDEO_BASE_ADR(22 downto 20) <= VIDEO_BASE_X_D;
|
|
VIDEO_BASE_ADR(19 downto 12) <= VIDEO_BASE_H_D;
|
|
VIDEO_BASE_ADR(11 downto 4) <= VIDEO_BASE_M_D;
|
|
VIDEO_BASE_ADR(3 downto 0) <= VIDEO_BASE_L_D(7 downto 4);
|
|
|
|
VDM_SEL <= VDM_SEL_I;
|
|
VDM_SEL_I <= VIDEO_BASE_L_D(3 downto 0);
|
|
|
|
-- Current video address:
|
|
VIDEO_ACT_ADR(26 downto 4) <= std_logic_vector(VIDEO_ADR_CNT - unsigned(FIFO_MW));
|
|
VIDEO_ACT_ADR(3 downto 0) <= VDM_SEL_I;
|
|
|
|
P_VIDEO_REGS: process
|
|
-- Video registers.
|
|
begin
|
|
wait until CLK_MAIN = '1' and CLK_MAIN' event;
|
|
if VIDEO_BASE_L = '1' and FB_WRn = '0' and BYTE_SEL(1) = '1' then
|
|
VIDEO_BASE_L_D <= DATA_IN(23 downto 16); -- 16 byte boarders.
|
|
end if;
|
|
|
|
if VIDEO_BASE_M = '1' and FB_WRn = '0' and BYTE_SEL(3) = '1' then
|
|
VIDEO_BASE_M_D <= DATA_IN(23 downto 16);
|
|
end if;
|
|
|
|
if VIDEO_BASE_H = '1' and FB_WRn = '0' and BYTE_SEL(1) = '1' then
|
|
VIDEO_BASE_H_D <= DATA_IN(23 downto 16);
|
|
end if;
|
|
|
|
if VIDEO_BASE_H = '1' and FB_WRn = '0' and BYTE_SEL(0) = '1' then
|
|
VIDEO_BASE_X_D <= DATA_IN(26 downto 24);
|
|
end if;
|
|
end process P_VIDEO_REGS;
|
|
|
|
FB_ADR_I <= FB_ADR & '0';
|
|
|
|
VIDEO_BASE_L <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"820D" else '0'; -- x"FF820D".
|
|
VIDEO_BASE_M <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8204" else '0'; -- x"FF8203".
|
|
VIDEO_BASE_H <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8202" else '0'; -- x"FF8201".
|
|
|
|
VIDEO_CNT_L <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8208" else '0'; -- x"FF8209".
|
|
VIDEO_CNT_M <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8206" else '0'; -- x"FF8207".
|
|
VIDEO_CNT_H <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8204" else '0'; -- x"FF8205".
|
|
|
|
DATA_OUT(31 downto 24) <= "00000" & VIDEO_BASE_X_D when VIDEO_BASE_H = '1' else
|
|
"00000" & VIDEO_ACT_ADR(26 downto 24) when VIDEO_CNT_H = '1' else (others => '0');
|
|
|
|
DATA_EN_H <= (VIDEO_BASE_H or VIDEO_CNT_H) and not FB_OEn;
|
|
|
|
DATA_OUT(23 downto 16) <= VIDEO_BASE_L_D when VIDEO_BASE_L = '1' else
|
|
VIDEO_BASE_M_D when VIDEO_BASE_M = '1' else
|
|
VIDEO_BASE_H_D when VIDEO_BASE_H = '1' else
|
|
VIDEO_ACT_ADR(7 downto 0) when VIDEO_CNT_L = '1' else
|
|
VIDEO_ACT_ADR(15 downto 8) when VIDEO_CNT_M = '1' else
|
|
VIDEO_ACT_ADR(23 downto 16) when VIDEO_CNT_H = '1' else (others => '0');
|
|
|
|
DATA_EN_L <= (VIDEO_BASE_L or VIDEO_BASE_M or VIDEO_BASE_H or VIDEO_CNT_L or VIDEO_CNT_M or VIDEO_CNT_H) and not FB_OEn;
|
|
end architecture BEHAVIOUR;
|
|
-- VA : Video DDR address multiplexed.
|
|
-- VA_P : latched VA, wenn FIFO_AC, BLITTER_AC.
|
|
-- VA_S : latch for default VA.
|
|
-- BA : Video DDR bank address multiplexed.
|
|
-- BA_P : latched BA, wenn FIFO_AC, BLITTER_AC.
|
|
-- BA_S : latch for default BA.
|
|
--
|
|
--FB_SIZE ersetzen. |