353 lines
11 KiB
Plaintext
353 lines
11 KiB
Plaintext
TITLE "DDR_CTR_BLITTER";
|
||
|
||
-- CREATED BY FREDI ASCHWANDEN
|
||
|
||
INCLUDE "lpm_bustri_BYT.inc";
|
||
|
||
|
||
-- {{ALTERA_PARAMETERS_BEGIN}} DO NOT REMOVE THIS LINE!
|
||
-- {{ALTERA_PARAMETERS_END}} DO NOT REMOVE THIS LINE!
|
||
|
||
SUBDESIGN DDR_CTR_BLITTER
|
||
(
|
||
-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
|
||
FB_ADR[31..0] : INPUT;
|
||
nFB_CS1 : INPUT;
|
||
nFB_CS2 : INPUT;
|
||
nFB_CS3 : INPUT;
|
||
nFB_OE : INPUT;
|
||
FB_SIZE0 : INPUT;
|
||
FB_SIZE1 : INPUT;
|
||
nRSTO : INPUT;
|
||
MAIN_CLK : INPUT;
|
||
FIFO_FULL : INPUT;
|
||
FB_ALE : INPUT;
|
||
nFB_WR : INPUT;
|
||
DDR_SYNC_66M : INPUT;
|
||
VSYNC : INPUT;
|
||
BLITTER_ON : INPUT;
|
||
VIDEO_RAM_CTR[15..0] : INPUT;
|
||
VDVZ[127..0] : INPUT;
|
||
DDRCLK[3..0] : INPUT;
|
||
BA0 : OUTPUT;
|
||
BA1 : OUTPUT;
|
||
VA[12..0] : OUTPUT;
|
||
nVWE : OUTPUT;
|
||
nVRAS : OUTPUT;
|
||
nVCS : OUTPUT;
|
||
VCKE : OUTPUT;
|
||
nVCAS : OUTPUT;
|
||
FIFO_WRE : OUTPUT;
|
||
FB_LE[3..0] : OUTPUT;
|
||
FB_VDOE[3..0] : OUTPUT;
|
||
START_CYC_RDWR : OUTPUT;
|
||
DDR_WR : OUTPUT;
|
||
CLEAR_FIFO_CNT : OUTPUT;
|
||
BLITTER_RUN : OUTPUT;
|
||
BLITTER_DOUT[127..0] : OUTPUT;
|
||
BLITTER_LE[3..0] : OUTPUT;
|
||
BLITTER_RDE : OUTPUT;
|
||
DDRWR_D_SEL[1..0] : OUTPUT;
|
||
VDMP[7..0] : OUTPUT;
|
||
FB_AD[31..0] : BIDIR;
|
||
-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
|
||
)
|
||
|
||
VARIABLE
|
||
FB_REGDDR :MACHINE WITH STATES(FR_WAIT,FR_S0,FR_S1,FR_S2,FR_S3);
|
||
DDR_SM :MACHINE WITH STATES(DS_T1,DS_T2,DS_T3,DS_T4,DS_T5,DS_T6,DS_T7,DS_T8,DS_LS);
|
||
LINE :NODE;
|
||
FB_B[3..0] :NODE;
|
||
VCAS :NODE;
|
||
VRAS :NODE;
|
||
VWE :NODE;
|
||
VA[12..0] :NODE;
|
||
BA0 :NODE;
|
||
BA1 :NODE;
|
||
DDR_WR :DFF;
|
||
DDR_SEL :NODE;
|
||
DDR_CONFIG :NODE;
|
||
DDRWR_D_SEL[1..0] :DFF;
|
||
CPU_ROW_ADR[12..0] :NODE;
|
||
CPU_BA0 :NODE;
|
||
CPU_BA1 :NODE;
|
||
CPU_COL_ADR[9..0] :NODE;
|
||
CPU_SIG :NODE;
|
||
CPU_REQ :DFF;
|
||
BLITTER_SIG :NODE;
|
||
BLITTER_REQ :DFF;
|
||
BLITTER_RUN :DFF;
|
||
BLITTER_WR :DFF;
|
||
BLITTER_ROW_ADR[12..0] :NODE;
|
||
BLITTER_BA0 :NODE;
|
||
BLITTER_BA1 :NODE;
|
||
BLITTER_COL_ADR[9..0] :NODE;
|
||
FIFO_SIG :NODE;
|
||
FIFO_REQ :DFF;
|
||
FIFO_ROW_ADR[12..0] :NODE;
|
||
FIFO_BA0 :NODE;
|
||
FIFO_BA1 :NODE;
|
||
FIFO_COL_ADR[9..0] :NODE;
|
||
FIFO_WRE :DFF;
|
||
FIFO_ACTIVE :NODE;
|
||
CLEAR_FIFO_CNT :DFF;
|
||
STOP :DFF;
|
||
DDR_REFRESH_ON :NODE;
|
||
VIDEO_BASE_L_D[3..0] :DFFE;
|
||
VIDEO_BASE_L :NODE;
|
||
VIDEO_BASE_M_D[7..0] :DFFE;
|
||
VIDEO_BASE_M :NODE;
|
||
VIDEO_BASE_H_D[7..0] :DFFE;
|
||
VIDEO_BASE_H :NODE;
|
||
VIDEO_BASE_X_D[7..0] :DFFE;
|
||
VIDEO_ADR_CNT[27..0] :DFFE;
|
||
VIDEO_CNT_L :NODE;
|
||
VIDEO_CNT_M :NODE;
|
||
VIDEO_CNT_H :NODE;
|
||
VIDEO_BASE_ADR[27..0] :NODE;
|
||
|
||
BEGIN
|
||
LINE = FB_SIZE0 & FB_SIZE1;
|
||
-- BYT SELECT
|
||
FB_B0 = FB_ADR[1..0]==0; -- ADR==0
|
||
FB_B1 = FB_ADR[1..0]==1 -- ADR==1
|
||
# FB_SIZE1 & !FB_SIZE0 & !FB_ADR1 -- HIGH WORD
|
||
# FB_SIZE1 & FB_SIZE0 # !FB_SIZE1 & !FB_SIZE0; -- LONG UND LINE
|
||
FB_B2 = FB_ADR[1..0]==2 -- ADR==2
|
||
# FB_SIZE1 & FB_SIZE0 # !FB_SIZE1 & !FB_SIZE0; -- LONG UND LINE
|
||
FB_B3 = FB_ADR[1..0]==3 -- ADR==3
|
||
# FB_SIZE1 & !FB_SIZE0 & FB_ADR1 -- LOW WORD
|
||
# FB_SIZE1 & FB_SIZE0 # !FB_SIZE1 & !FB_SIZE0; -- LONG UND LINE
|
||
-- CPU READ (REG DDR => CPU) AND WRITE (CPU => REG DDR) --------------------------------------------------
|
||
FB_REGDDR.CLK = MAIN_CLK;
|
||
CASE FB_REGDDR IS
|
||
WHEN FR_WAIT =>
|
||
IF DDR_SEL THEN
|
||
FB_REGDDR = FR_S0;
|
||
ELSE
|
||
FB_REGDDR = FR_WAIT;
|
||
END IF;
|
||
WHEN FR_S0 =>
|
||
FB_VDOE0 = !nFB_OE & !DDR_CONFIG;
|
||
FB_LE0 = !nFB_WR;
|
||
IF LINE THEN
|
||
FB_REGDDR = FR_S1;
|
||
ELSE
|
||
FB_REGDDR = FR_WAIT;
|
||
END IF;
|
||
WHEN FR_S1 =>
|
||
FB_VDOE1 = !nFB_OE & !DDR_CONFIG;
|
||
FB_LE1 = !nFB_WR;
|
||
FB_REGDDR = FR_S2;
|
||
WHEN FR_S2 =>
|
||
FB_VDOE2 = !nFB_OE & !DDR_CONFIG;
|
||
FB_LE2 = !nFB_WR;
|
||
FB_REGDDR = FR_S3;
|
||
WHEN FR_S3 =>
|
||
FB_VDOE3 = !nFB_OE & !DDR_CONFIG;
|
||
FB_LE3 = !nFB_WR;
|
||
FB_REGDDR = FR_WAIT;
|
||
END CASE;
|
||
-- DDR STEUERUNG -----------------------------------------------------
|
||
-- VIDEO RAM CONTROL REGISTER (IST IN VIDEO_MUX_CTR) $F0000400: BIT 0=VCKE,1=!nVCS,2=FIFO_ACTIVE,3=FIFO UND CNT CLEAR,15..11=VIDEO RAM BASE
|
||
VCKE = VIDEO_RAM_CTR0;
|
||
nVCS = !VIDEO_RAM_CTR1;
|
||
FIFO_ACTIVE = VIDEO_RAM_CTR2;
|
||
DDR_CONFIG = VIDEO_RAM_CTR3;
|
||
DDR_REFRESH_ON = VIDEO_RAM_CTR4;
|
||
--------------------------------
|
||
CPU_ROW_ADR[] = FB_ADR[26..14];
|
||
CPU_BA1 = FB_ADR13;
|
||
CPU_BA0 = FB_ADR12;
|
||
CPU_COL_ADR[] = FB_ADR[11..2];
|
||
nVRAS = !VRAS;
|
||
nVCAS = !VCAS;
|
||
nVWE = !VWE;
|
||
DDR_WR.CLK = DDRCLK0;
|
||
-- SELECT LOGIC
|
||
DDR_SEL = FB_ALE & FB_AD[31..29]==B"011";
|
||
-- WENN READ ODER WRITE B,W,L DDR SOFORT ANFORDERN, BEI WRITE LINE SP<53>TER
|
||
CPU_SIG = DDR_SEL & nFB_WR & !DDR_CONFIG -- READ SOFORT LOS
|
||
# FR_S0 & !nFB_WR -- WRITE SP<53>TER AUCH CONFIG
|
||
# FR_S3 & !nFB_WR & LINE & !DDR_CONFIG; -- LINE WRITE
|
||
CPU_REQ = CPU_SIG;
|
||
CPU_REQ.CLK = DDR_SYNC_66M;
|
||
DDR_D_SEL[].CLK = DDRCLK3;
|
||
-- DDR STATE MACHINE -----------------------------------------------
|
||
DDR_SM.CLK = DDRCLK0;
|
||
CASE DDR_SM IS
|
||
WHEN DS_T1 =>
|
||
IF MAIN_CLK THEN
|
||
DDR_WR = DDR_WR; -- WRITE HALTEN (VON T4)
|
||
DDR_SM = DS_T2;
|
||
ELSE
|
||
DDR_SM = DS_LS; -- SYNCHRONISIEREN
|
||
END IF;
|
||
WHEN DS_T2 =>
|
||
IF !DDR_CONFIG THEN
|
||
VRAS = CPU_SIG # BLITTER_SIG # FIFO_SIG # DDR_REFRESH_ON;
|
||
VA[] = CPU_SIG & CPU_ROW_ADR[]
|
||
# BLITTER_SIG & BLITTER_ROW_ADR[]
|
||
# FIFO_SIG & FIFO_ROW_ADR[];
|
||
BA0 = CPU_SIG & CPU_BA0
|
||
# BLITTER_SIG & BLITTER_BA0
|
||
# FIFO_SIG & FIFO_BA0;
|
||
BA1 = CPU_SIG & CPU_BA1
|
||
# BLITTER_SIG & BLITTER_BA1
|
||
# FIFO_SIG & FIFO_BA1;
|
||
VCAS = !CPU_SIG & !BLITTER_SIG & !FIFO_SIG & DDR_REFRESH_ON; -- AUTO REFRESH WENN SONST NICHTS
|
||
BLITTER_REQ = BLITTER_SIG;
|
||
FIFO_REQ = FIFO_SIG;
|
||
END IF;
|
||
IF MAIN_CLK THEN
|
||
DDR_SM = DS_T3;
|
||
ELSE
|
||
DDR_SM = DS_LS;
|
||
END IF;
|
||
WHEN DS_T3 =>
|
||
IF DDR_CONFIG & CPU_REQ THEN
|
||
VRAS = FB_AD18;
|
||
VCAS = FB_AD17;
|
||
VWE = FB_AD16;
|
||
BA1 = FB_AD14;
|
||
BA0 = FB_AD13;
|
||
VA[] = FB_AD[12..0];
|
||
END IF;
|
||
IF !CPU_REQ & !BLITTER_REQ & !FIFO_REQ # DDR_CONFIG THEN
|
||
DDR_SM = DS_LS;
|
||
ELSE
|
||
BLITTER_REQ = BLITTER_SIG;
|
||
FIFO_REQ = FIFO_SIG;
|
||
DDR_SM = DS_T4;
|
||
END IF;
|
||
WHEN DS_T4 =>
|
||
FIFO_REQ = FIFO_SIG;
|
||
VCAS = VCC;
|
||
VWE = !nFB_WR & CPU_REQ # BLITTER_WR & BLITTER_REQ;
|
||
VA[9..0] = CPU_REQ & CPU_COL_ADR[]
|
||
# BLITTER_REQ & BLITTER_COL_ADR[]
|
||
# FIFO_REQ & FIFO_COL_ADR[];
|
||
VA10 = VCC; -- AUTO PRECHARGE
|
||
BA0 = CPU_REQ & CPU_BA0
|
||
# BLITTER_REQ & BLITTER_BA0
|
||
# FIFO_REQ & FIFO_BA0;
|
||
BA1 = CPU_REQ & CPU_BA1
|
||
# BLITTER_REQ & BLITTER_BA1
|
||
# FIFO_REQ & FIFO_BA1;
|
||
DDR_WR = !nFB_WR & CPU_REQ # BLITTER_WR & BLITTER_REQ;
|
||
FIFO_REQ = FIFO_SIG;
|
||
IF FIFO_REQ & FIFO_COL_ADR[]!= H"3FF" THEN -- GLEICHE PAGE?
|
||
DDR_SM = DS_T5; -- JA->
|
||
ELSE
|
||
DDR_SM = DS_T1; -- SONST NEUE PAGE AUFMACHEN
|
||
END IF;
|
||
WHEN DS_T5 =>
|
||
FIFO_REQ = FIFO_SIG;
|
||
DDR_SM = DS_T6;
|
||
WHEN DS_T6 =>
|
||
IF CPU_SIG THEN -- SOFORT UMSCHALTEN WENN CPU REQ
|
||
VRAS = VCC;
|
||
VA[] = CPU_ROW_ADR[];
|
||
BA1 = CPU_BA1;
|
||
BA0 = CPU_BA0;
|
||
DDR_SM = DS_T3;
|
||
ELSE
|
||
FIFO_REQ = FIFO_SIG;
|
||
VCAS = VCC;
|
||
VA[9..0] = FIFO_COL_ADR[];
|
||
VA10 = VCC; -- AUTO PRECHARGE
|
||
BA0 = FIFO_BA0;
|
||
BA1 = FIFO_BA1;
|
||
FIFO_WRE = FIFO_REQ; -- ODER FIFO LATCH IN 5 CYC 133
|
||
IF FIFO_REQ & FIFO_COL_ADR[]!= H"3FF" THEN -- GLEICHE PAGE?
|
||
DDR_SM = DS_T5; -- JA->
|
||
ELSE
|
||
DDR_SM = DS_T1; -- SONST NEUE PAGE AUFMACHEN
|
||
END IF;
|
||
END IF;
|
||
WHEN DS_LS =>
|
||
IF !MAIN_CLK THEN -- LEERSTATE UND SYNC
|
||
DDR_SM = DS_T1;
|
||
ELSE
|
||
DDR_SM = DS_LS;
|
||
END IF;
|
||
END CASE;
|
||
------------------------------------------------------------------------------
|
||
-- FIFO ---------------------------------
|
||
FIFO_SIG = FIFO_ACTIVE & !FIFO_FULL & !BLITTER_SIG & !CPU_SIG;
|
||
FIFO_REQ.CLK = DDR_SYNC_66M;
|
||
FIFO_ROW_ADR[] = VIDEO_ADR_CNT[24..12];
|
||
FIFO_BA1 = VIDEO_ADR_CNT11;
|
||
FIFO_BA0 = VIDEO_ADR_CNT10;
|
||
FIFO_COL_ADR[] = VIDEO_ADR_CNT[9..0];
|
||
-- Z<>HLER R<>CKSETZEN WENN VSYNC ----------------
|
||
CLEAR_FIFO_CNT.CLK = DDRCLK0;
|
||
CLEAR_FIFO_CNT = VSYNC # !FIFO_ACTIVE;
|
||
STOP.CLK = DDRCLK0;
|
||
STOP = VSYNC # CLEAR_FIFO_CNT;
|
||
VIDEO_ADR_CNT[].CLK = DDRCLK0;
|
||
VIDEO_ADR_CNT[] = CLEAR_FIFO_CNT & VIDEO_BASE_ADR[] -- SET
|
||
# !CLEAR_FIFO_CNT & (VIDEO_ADR_CNT[]+1); -- NEXT 16 BYTS
|
||
VIDEO_ADR_CNT[].ENA = CLEAR_FIFO_CNT # FIFO_WRE;
|
||
FIFO_WRE.CLK = DDRCLK0;
|
||
---------------------------------------------------------------
|
||
-- BLITTER BUS IST 128 BIT BREIT ------
|
||
BLITTER_SIG = GND & !CPU_SIG;
|
||
BLITTER_REQ.CLK = DDR_SYNC_66M;
|
||
BLITTER_RUN.CLK = DDRCLK0;
|
||
BLITTER_RUN = GND;
|
||
BLITTER_WR.CLK = DDRCLK0;
|
||
BLITTER_WR = GND;
|
||
DDRWR_D_SEL1 = BLITTER_WR;
|
||
BLITTER_ROW_ADR[] = H"0";
|
||
BLITTER_BA1 = GND;
|
||
BLITTER_BA0 = GND;
|
||
BLITTER_COL_ADR[] = H"0";
|
||
BLITTER_DOUT[] = H"0";
|
||
BLITTER_LE[] = H"0";
|
||
-----------------------------------------------------------
|
||
-- VIDEO REGISTER -----------------------
|
||
---------------------------------------------------------------------------------------------------------------------
|
||
VIDEO_BASE_L_D[].CLK = MAIN_CLK;
|
||
VIDEO_BASE_L = !nFB_CS1 & FB_ADR[15..1]==H"4106"; -- 820D/2
|
||
VIDEO_BASE_L_D[] = FB_AD[23..20]; -- SORRY, NUR 16 BYT GRENZEN
|
||
VIDEO_BASE_L_D[].ENA = !nFB_WR & VIDEO_BASE_L & FB_B1;
|
||
|
||
VIDEO_BASE_M_D[].CLK = MAIN_CLK;
|
||
VIDEO_BASE_M = !nFB_CS1 & FB_ADR[15..1]==H"4101"; -- 8203/2
|
||
VIDEO_BASE_M_D[] = FB_AD[23..16];
|
||
VIDEO_BASE_M_D[].ENA = !nFB_WR & VIDEO_BASE_M & FB_B3;
|
||
|
||
VIDEO_BASE_H_D[].CLK = MAIN_CLK;
|
||
VIDEO_BASE_H = !nFB_CS1 & FB_ADR[15..1]==H"4100"; -- 8200-1/2
|
||
VIDEO_BASE_H_D[] = FB_AD[23..16];
|
||
VIDEO_BASE_H_D[].ENA = !nFB_WR & VIDEO_BASE_H & FB_B1;
|
||
VIDEO_BASE_X_D[].CLK = MAIN_CLK;
|
||
VIDEO_BASE_X_D[] = FB_AD[31..24];
|
||
VIDEO_BASE_X_D[].ENA = !nFB_WR & VIDEO_BASE_H & FB_B0;
|
||
|
||
VIDEO_CNT_L = !nFB_CS1 & FB_ADR[15..1]==H"4104"; -- 8209/2
|
||
VIDEO_CNT_M = !nFB_CS1 & FB_ADR[15..1]==H"4103"; -- 8207/2
|
||
VIDEO_CNT_H = !nFB_CS1 & FB_ADR[15..1]==H"4102"; -- 8205/2
|
||
|
||
FB_AD[31..24] = lpm_bustri_BYT(
|
||
VIDEO_BASE_H & VIDEO_BASE_X_D[]
|
||
# VIDEO_CNT_H & VIDEO_ADR_CNT[27..20]
|
||
,(VIDEO_BASE_H # VIDEO_CNT_H) & !nFB_OE);
|
||
|
||
FB_AD[23..16] = lpm_bustri_BYT(
|
||
VIDEO_BASE_L & (VIDEO_BASE_L_D[],B"0000")
|
||
# VIDEO_BASE_M & VIDEO_BASE_M_D[]
|
||
# VIDEO_BASE_H & VIDEO_BASE_H_D[]
|
||
# VIDEO_CNT_L & (VIDEO_ADR_CNT[3..0],B"0000")
|
||
# VIDEO_CNT_M & VIDEO_ADR_CNT[11..4]
|
||
# VIDEO_CNT_H & VIDEO_ADR_CNT[19..12]
|
||
,(VIDEO_BASE_L # VIDEO_BASE_M # VIDEO_BASE_H # VIDEO_CNT_L # VIDEO_CNT_M # VIDEO_CNT_H) & !nFB_OE);
|
||
|
||
VIDEO_BASE_ADR[27..20] = VIDEO_BASE_X_D[];
|
||
VIDEO_BASE_ADR[19..12] = VIDEO_BASE_H_D[];
|
||
VIDEO_BASE_ADR[11..4] = VIDEO_BASE_M_D[];
|
||
VIDEO_BASE_ADR[3..0] = VIDEO_BASE_L_D[];
|
||
END;
|
||
|