Video Signal Generation

The Timing and the Signals

The questions below are due on Wednesday October 02, 2024; 11:59:00 PM.
 
You are not logged in.

Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

In this problem you'll develop all of the necessary signals to run a 720p video generation pipeline.

As discussed in lecture 7, video is generally conveyed by the repeated drawing of image frames. This method of video transfer is as old as motion pictures and optical illusions (think simplistic flipbooks from before the twentieth century). Since we can't send these frames all at once, we instead send them serially (as we do almost all digital information to one degree or another) using an established "raster" pattern which involves starting the transmission in the upper left of a frame of video and then going left-to-right, before reaching the end of the line and jumping back to the beginning of the next line. Then data is again sent left-to-right until the end of the line is reached. This is repeated until the bottom right corner of the frame has been sent. At this point, the process starts all over again to send the next frame (remember we have to send lots of frames to give the illusion of video).

A single frame is both sent and drawn in a raster pattern, where the first pixel sent is the upper left and following pixels are sent in a left-to-right-then-reset pattern going all the way down the screen ending with the lower right pixel.

While the image part of the frame is the primary thing we care about, in a modern video-transfer system, that's actually only about ~75% of the data sent. A full frame of video contains not just the "active drawing" region, but also regions at the end of every line drawn (known as horizontal blanking and horizontal sync periods), as well as full lines at the end of every frame (known as vertical blanking and vertical sync periods). These regions of signals are extremely important since they are used to calibrate and synchronize the receiver so that it knows how to properly render the image data from the active drawing region.

The regions of a frame of video are shown below. Note that a significant portion of it is not the active draw region that you actually see (what you think of when you think of "video")

The general regions of a frame of video (applies to all timings and resolutions).

The regions of a frame are as follows:

  • Active Draw: The parts of a frame that are actually video data to be shown.
  • Horizontal Front Porch After drawing each line of video data, the system should go into a rest period known as the "front porch." No video data is conveyed here. This is sometimes also called a "blanking" period.
  • Horizontal Synch Width: After the silence of the front porch, a "burst" of signal of a known pattern is sent.
  • Horizontal Back Porch: After the sync signal, another period of silence ends a given line of data. This is known as the "back porch," and is also sometimes referred to as a blanking period. This is the last thing to do on a line. When this is complete, a new line should begin.
  • Vertical Front Porch: After completing the lines of active video, the system enters a frame sync period. These may appear "shorter" than their horizontal counterparts, but that's misleading since the timing refers to full lines, so they are quite long in duration. The vertical front porch is a period of relative silence with no video data.
  • Vertical Sync Width: The duration of a sync signal towards the end of the frame.
  • Vertical Back Porch: The final rest period at the end of a frame of video. When this is completed, the next frame will begin to be drawn.

Each frame is comprised of a two-dimensional field of pixels and each pixel has a certain amount of information associated with it. In the active drawing region, the pixels will convey information about the color to be drawn at that particular spot. In the non-active drawing regions, the pixels can contain calibrations and sync info as well as audio, control signals, copyright protection crap, and other non-video information supplemental to a media stream.

By convention, computer graphics almost always use a coordinate system where the origin is in the top left of the screen with the "x" dimension (more commonly known as "horizontal count") growing left to right and the "y" dimension (more commonly known as "vertical count") growing top to bottom. Do not stray from this. Any graphics library you use that deviates from this is an abomination. The upper-left origin orientation is nice because it lines up with how graphical systems actually transfer data (top-left to bottom-right)

The size of the frames drawn (in pixels) can vary wildy based on the standard being used. The "better" the video, generally, the larger the frame in terms of pixel dimensions. A general list of many resolutions is found here for reference. For this lab and class we'll be targeting 60 Hz 720p video. The measurements/dimensions of a 720p frame of data are as follows:

The contents of a frame of 720p video. Note there are regions that need to be sent that don't get drawn and they are as important as the video itself to make things work. A single frame of 720p has 1.2375 million pixels of information in it, each pixel being comprised of 24 bits.

The particular timing dimensions are listed again below with 720p numbers:

  • Active Draw Width: 1280 The number of pixels that are video data on a given line (that is drawn). Note not all lines have video data in them (see ones that are in the vertical sync regions).

  • Horizontal Front Porch: 110 After drawing each line of video data, the system should go into a rest period known as the "front porch." No video data is conveyed here. This is sometimes also called a "blanking" period.

  • Horizontal Synch Width: 40 After the silence of the front porch, a "burst" of signal of a known pattern is sent.

  • Horizontal Back Porch: 220 After the sync signal, another period of silence ends a given line of data. This is known as the "back porch," and is also sometimes referred to as a blanking period. This is the last thing to do on a line. When this is complete, a new line should begin.

  • Active Draw Height: 720 The number of lines with video content in them.

  • Vertical Front Porch: 5 After completing the lins of active video (0 through 719), the system enters a frame sync period. These may appear "shorter" than their horizontal counterparts, but that's misleading since the timing refers to full lines (and each line is 1650 pixels), so they are quite long in duration). The vetical front porch is a period of relative silence with no video data.

  • Vertical Sync Width: 5 The duration of a sync signal towards the end of the frame.

  • Vertical Back Porch: 20 The final rest period at the end of a frame of video. When this is completed (when vertical count is 749 and the horizontal count is 1649), the next frame will begin.

Note the entire frame of 720p is 1650 pixels by 750 pixels in size. the "720p" only refers to the height of the active drawing region frame. With this type of video in mind, and knowing how many frames per second we need to send (60) we can do some math to figure out how fast we need to send our pixels. Each frame of 720p video has 1.2375 million pixels. At 60 frames per second that means we need to send 74.25 million pixels per second to keep up. This number is important. It will be our "pixel clock" and we'll use a clock management tile on our FPGA to turn our 100 MHz reference clock into 74.25 MHz.

Given this clock signal and given the dimensions of a frame of video, we have enough information to generate the raster pattern signals that adhere to the 720p timing specification for raster drawing. We want to therefore generate a list of signals that could be used to generate and process video by other modules downstream. This list of signals is:

  • hcount_out: The current horizontal count on the screen.
  • vcount_out: The current vertical count on the screen.
  • vs_out: The vertical sync signal, high when in the vertical sync region
  • hs_out: The horizontal sync signal, high when in the horizontal sync region
  • ad_out: The active drawing indicator, low when in blanking or sync period, high when actively drawing.
  • nf_out: Single cycle indicator of a new frame (see below)
  • fc_out: Current frame with a rolling second-long window (ranges from 0 to 59 inclusive)

Generate your video signals!

Because the scale of the signal pattern in a 720p frame of video is extremely large compared to the clock period, we need write this module in such a way that it does not have hard-coded dimensions. Instead we'll set all important values to be parameters that can be overwritten, but which default to the 720p standard if otherwise ignored. This will allow us to test and verify in simulation that the basic mechanics of its logic are sound without needing to run painfully long simulations.

Write the video_sig_gen module using this code skeleton so that it generates all the signals needed.

A few other notes:

To make video and other higher-level logic (like game mechanics) more convenient to write, we'd also like a rolling frame counter fc_out that runs from 0 to parameter FPS-1, and a single-cycle new frame indicator signal nf_out to be generated. In order to give any processing logic plenty of time to prep before the drawing period of the next frame, we want to switch to a new frame into the pure blanking period at (1280,720) in 720p (which should be scaled based on the appropriate parameters in the module)1

Roll the frame over at (1280,720) in 720p.

Try not to overthink this system. Other than a few counters, it really doesn't need a state machine since its output at any point in time is solely dictated on what the current hcount and vcount values are. You are welcome to make the output signals like vertical sync be combinationally specified off of the hcount and vcount.

When rst_in is asserted, the system should not be transferring active video. When rst_in is deasserted, the system must start with an hcount and vcount of (0,0) and all appropriate signals on the following rising clock edge. See the image below.

Simplified reset.

All signals must be clock-cycle correct. In other words, the ad_out should not be 1 when hcount_out is 1280 (with default parameters), for example. The timing is very particular!

Utilize the specified parameters for the dimensions. Do not hard-code any numbers like 1280, instead use their corresponding parameter since those parameters will be modified for testing. This is important since for testing below we will overwrite those parameters to allow us to test in a reasonable amount of time.

For debugging, we encourage you to write a simple testbench and set some shorter parameters to verify that the signals look good. This system doesn't really need any inputs (other than a quick fire to reset)...so you really just need to let it run and watch all the output signals and make sure they're going low and high with the right periodicity.

Some checkers below are placed here to ensure you're getting proper signal creation. Make sure you pass them.

Code Skeleton
  No file selected

Here's another test you should make sure to pass with some different parameters.

Code Skeleton
  No file selected

OK you're making your video signals (check). Now we need to figure out how to encode our pixel information for HDMI. Continue on to Part 1 of that journey here..


 
Footnotes

1A (good) argument could be made that we should fire at (1280,719). We'll change it to that for 2025, but for now, let's just keep it at 1280,720, etc... so people aren't chasing a moving set of standards. (click to return to text)