Skip to content

Latest commit

 

History

History
157 lines (103 loc) · 8.27 KB

modules.md

File metadata and controls

157 lines (103 loc) · 8.27 KB

Display Controller Modules

The display controller consists of six core modules. This document describes the interfaces for the three you interact with: display_clocks, display_timings and dvi_generator. The other three modules are used internally by dvi_generator. You can see the modules being put to use in the demos and test benches.

The design aims to be as generic as possible but does make use of Xilinx Series 7 specific features, such as SerDes. If you want advice on adapting this design to other FPGAs, then take a look at porting.

See README for more documentation.

Contents

Architecture

TMDS Encoding on FPGA for DVI or HDMI

  1. Display Clocks - synthesizes the pixel and SerDes clocks, for example, 74.25 and 371.25 MHz for 720p
  2. Display Timings - generates the display sync signals and active pixel position
  3. Colour Data - the colour of a pixel, taken from a bitmap, sprite, test card etc.
  4. DVI Generator
    1. TMDS Encoder - encodes 8-bit red, green, and blue pixel data into 10-bit TMDS values
    2. 10:1 Serializer - converts parallel 10-bit TMDS value into serial form
  5. Differential Signal Output - converts TMDS data into differential form for output via two FPGA pins

Analogue VGA and BML DVI Pmod

  1. Display Clocks - synthesizes the pixel clock, for example, 40 MHz for 800x600
  2. Display Timings - generates the display sync signals and active pixel position
  3. Colour Data - the colour of a pixel, taken from a bitmap, sprite, test card etc.
  4. Parallel Colour Output - external hardware converts this to analogue VGA or TMDS DVI as appropriate

Display Clocks

Timing is everything when it comes to working with screens: everything marches in step with the pixel clock. Pixel clocks are typically in the range 25-165 MHz for SD and HD resolutions; for example, 1280x720p60 uses a pixel clock of 74.25 MHz. If our pixel clock deviates by more than 0.5%, it'll be out of Vesa spec and will likely fail to display. This module generates a high-quality pixel clock using the mixed-mode clock manager (MMCM). When doing our own TMDS SerDes, we also need a 5x pixel clock, which this module also generates. (display_clocks.v)

Display parameters includes appropriate parameters for four standard pixel clocks, and you can see examples in the demos.

Inputs

  • i_clk - input clock
  • i_rst - reset (active high)

The IN_PERIOD parameter (below) must match the frequency of the input clock.

Outputs

  • o_clk_1x - pixel clock
  • o_clk_5x - 5x clock for 10:1 DDR SerDes
  • o_locked - clock locked? (active high)

You shouldn't use the clocks until the locked signal is high. You can safely ignore the o_clk_5x output if you're not doing TMDS encoding on the FPGA.

Parameters

  • MULT_MASTER - multiplication for both output clocks
  • DIV_MASTER - division for both output clocks
  • DIV_5X - division for 5x (SerDes) clock
  • DIV_1X - division for pixel clock
  • IN_PERIOD - period of input clock in nanoseconds (ns)

The IN_PERIOD needs to match the input clock i_clk frequency. For example, a 100 MHz clock has a 10 ns period, so IN_PERIOD would be 10.

The output clocks are calculated as follows:

o_clk_1x = (i_clk * MULT_MASTER / DIV_MASTER) / DIV_1X
o_clk_5x = (i_clk * MULT_MASTER / DIV_MASTER) / DIV_5X

For example, 720p60:

 74.25 MHz = (100 MHz * 37.125 / 5) / 10
371.25 MHz = (100 MHz * 37.125 / 5) /  2

Display Timings

The display timings module turns timing parameters into appropriately timed sync pulses and provides the current screen coordinates. Accurate timings depend on an accurate pixel clock. (display_timings.v)

Inputs

  • i_pix_clk - pixel clock
  • i_rst - reset (active high)

The pixel clock must be suitable for the timings given in the parameters (see display clocks, above).

Outputs

  • o_hs - horizontal sync
  • o_vs - vertical sync
  • o_de - display enable: high during active video
  • o_frame - high for one tick at the start of each frame
  • o_sx [15:0] - horizontal screen position (signed)
  • o_sy [15:0] - vertical screen position (signed)

The current beam position is given by (o_sx,o_sy). o_sx and o_sy are signed 16-bit values.

When display enable (o_de) is high, these values provide the active drawing pixel and are always positive. During the blanking interval, one or both of o_sx and o_sy will be negative, which allows you to prepare for drawing. For example, if you have a two-cycle latency to retrieve a pixel's colour you can request the data for the first pixel of a line when o_sx == -2.

The screen coordinate diagram, above, shows a 1280x720p60 frame. At the start of the frame o_sx == -370 and o_sy == -30. Active drawing starts at o_sx == 0 and o_sy == 0 with the final coordinates being o_sx == 1279 and o_sy == 719. See drawing coordinates for details on all supported resolutions.

Horizontal and vertical sync may be active high or low depending on the display mode; this is controlled using the H_POL and V_POL parameters (below).

Parameters

  • H_RES - active horizontal resolution in pixels
  • V_RES - active vertical resolution in lines
  • H_FP - horizontal front porch length in pixels
  • H_SYNC - horizontal sync length in pixels
  • H_BP - horizontal back porch length in pixels
  • V_FP - vertical front porch length in lines
  • V_SYNC - vertical sync length in lines
  • V_BP - vertical back porch length in lines
  • H_POL - horizontal sync polarity (0:negative, 1:positive)
  • V_POL - vertical sync polarity (0:negative, 1:positive)

Display parameters includes appropriate timing parameters for four standard resolutions. You can also see examples of the parameters in the demos.

DVI Generator

The DVI generator has many inputs but is straightforward to use. You hook it up to the display clocks and display timings then add your pixel colour data. (dvi_generator.v)

DVI generator instantiates two other modules to do the actual work: one for TMDS encoding and the other for 10:1 serialization. The TMDS encoder has a Python model to aid with development and testing.

Inputs

  • i_pix_clk - pixel clock (display clocks provides this)
  • i_pix_clk_5x - 5x pixel clock for DDR serialization (display clocks provides this)
  • i_rst - reset (active high)
  • i_de - display enable (display timings provides this)
  • i_data_ch0 [7:0] - 8-bit blue colour data (TMDS channel 0)
  • i_data_ch1 [7:0] - 8-bit green colour data (TMDS channel 1)
  • i_data_ch2 [7:0] - 8-bit red colour data (TMDS channel 2)
  • i_ctrl_ch0 [1:0] - channel 0 control data; set to {v_sync, h_sync} from display timings
  • i_ctrl_ch1 [1:0] - channel 1 control data; set to 2'b00
  • i_ctrl_ch2 [1:0] - channel 2 control data; set to 2'b00

Outputs

The output is the four TMDS encoded serial channels ready for output as differential signals:

  • o_tmds_ch0_serial - channel 0 - serial TMDS
  • o_tmds_ch1_serial - channel 1 - serial TMDS
  • o_tmds_ch2_serial - channel 2 - serial TMDS
  • o_tmds_chc_serial - channel clock - serial TMDS

You can use these signals with OBUFDS, for example:

OBUFDS #(.IOSTANDARD("TMDS_33"))
    tmds_buf_ch0 (.I(tmds_ch0_serial), .O(hdmi_tx_p[0]), .OB(hdmi_tx_n[0]));

Where hdmi_tx_p[0] and hdmi_tx_n[0] are the differential output pins for TMDS channel 0.

You can see an example of this in the DVI TMDS demo.