Full-HD (1080p) VGA core in mSpectrum

The first VGA core designed for mSpectrum back in 2008 focussed on lower resolution screens like 1024x768 and 1280x1024. Screens running these resolutions get hard to find. New screens run natively at 1680x1050, 1920x1080 or even 1920x1200.

Using the native resolution of a screen yields the nicest results, so I redesigned the VGA core with timing optimization in mind and to see if I would be able to run the Spartan 3E device at the required speeds:

ResolutionRefreshStandardRequired pixel clock
1024x76860 HzXGA65 MHz
1024x76870 HzVESA75 MHz
1680x105060 HzVESA146 MHz
1920x108060 HzVESA172 MHz

Core parameters

I arranged that the timing information can be specified using generics. Generics help to easily change between display modes. The timing parameters are equivalent to the configuration of X servers on linux in the early days.

Other parameters are MAGX and MAGY for stretching the Spectrum image on the screen. DIV and MUL are the DCM parameters: fVGA = 50MHz * MUL / DIV.

Timing parameters for 1680x1050:

vga_timing_inst: vga_timing
  generic map (
    -- 1680x1050@60 VESA 146 Mhz
    MAGX => 6, MAGY => 5, DIV => 11, MUL => 32, 
    PAL => 1680, HFP => 102, HPW => 180, HBP => 282, 
    LAF => 1050, VFP => 1,   VPW => 3,   VBP => 26

Timing parameters for 1920x1080:

vga_timing_inst: vga_timing
  generic map (
    -- 1920x1080@60 VESA 172 Mhz
    MAGX => 7, MAGY => 5, DIV => 9, MUL => 31, 
    PAL => 1920, HFP => 119, HPW => 207, HBP => 326, 
    LAF => 1080, VFP => 1,   VPW => 3,   VBP => 32

Timing closure

The new synthesized VGA core meets the timing requirements even for the full-HD resolution when used as a stand-alone unit. The VGA core runs at 172MHz which comes really close to the limits of the Spartan-3E.

When used within the entire mSpectrum design, timing requirements succeed up till the 1680x1050 resolution. The mSpectrum system and Z80 core run at 56 MHz, the VGA core runs at 146 MHz.

With the 1920x1080 resolution timing fails. However the timing score is still low (975 with the default strategy) and the the design runs fine on the xc3s1200 as can be seen on the pictures below.

SmartXplorer shows that the score can be brought down to 668 with the MapUseIOReg strategy

Strategy Timing score Luts Slice registers RunTime
MapUseIOReg 668 3,424 (19%) 1,004 (5%) 0h 3m 44s
MapTimingExtraEffort 857 3,424 (19%) 1,040 (5%) 0h 3m 19s
MapPhysSynthesis 857 3,424 (19%) 1,040 (5%) 0h 3m 29s
ParHighEffort1 975 3,424 (19%) 1,040 (5%) 0h 3m 25s
ParHighEffort2 975 3,424 (19%) 1,040 (5%) 0h 3m 25s
MapTiming1 5401 3,424 (19%) 1,040 (5%) 0h 3m 15s
MapTiming2 1703 3,424 (19%) 1,040 (5%) 0h 4m 4s


Pictures of the VGA core in action with mSpectrum at full HD resolution

mSpectrum running the 128K ZX Spectrum on a full-HD screen in the native resolution of 1920x1080 at 60Hz. The Spectrum screen is streched to fill most of the screen (magX = 7, magY = 5).

Close-up of the screen showing the VGA signal details

Load menu of the mSpectrum.

mSpectrum loading the game Fairlight at 56MHz, 16 times the original speed of the ZX Spectrum.