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ÄTER CPU_SIG = DDR_SEL & nFB_WR & !DDR_CONFIG -- READ SOFORT LOS # FR_S0 & !nFB_WR -- WRITE SPÄ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;