<< INTRODUCTION >>
<< OVERVIEW >>
<< AUDIO >>
<< GAMEPLAY >>
<< VIDEO >>
<< IMPROVEMENTS >>
<< ZBT RAMS >>
<< TIPS AND TRICKS >>
<< NES INPUT FSM >>
<< TOOLS >>
The video subsystem is responsible for displaying the game content to the screen. The subsystem takes input from the game logic subsystem and uses it to generate the images displayed to the user. This system displays 24-bit color 640x480 VGA video at 60 frames per second. Figure X below shows a general schematic of the video subsystem.
Figure 10. Video Subsystem Schematic
The system implements a page-buffering scheme using the two ZBT SRAMs included in the lab kit. Page-buffering simply means that while the contents of one RAM are being displayed to the screen, the other RAM is being filled with the contents of the next screen. This results in smoother video performance, greatly reducing the visibility of any glitches that may occur. The video subsystem is comprised of five modules: the SRAMs, the ram_select/sel_clock unit, a bank of sprite ROMs, the screen_store unit, and the screen_draw unit. These modules are discussed in greater detail in the sections that follow.
The ZBT SRAMs included in the lab kit are 512Kx36 SRAMs. The RAMs serve as the page buffers for the video system. Each RAM contains a snapshot of the screen at a given instant. In particular, the RAMs are addressed using a linear combination of the screen coordinate values (x and y) for a given pixel, and contains a 24-bit value representing the color of that particular pixel. For more detail about interfacing with the ZBT RAMs, please see Appendix A.
ram_select and sel_clock
These modules implement the buffer switching for the page-buffering mechanism for the iGamePlay system. Ram_select interfaces between the drawing systems (screen_draw and screen_store) and the RAMs. When the input sel is high, the ram_select module assigns RAM0 to the screen_draw system and RAM1 to the screen_store unit. When sel switches values, the RAMs flip. Thus, while screen_store is writing data to one RAM, screen_draw can display the data from the other RAM.
Sel is controlled by the sel_clock module. Sel_clock also takes in the vblank signal from screen_draw and the fin signal from screen_store. When the screen_store unit finishes writing data into a RAM, it asserts the fin signal. If this signal is asserted while vblank is low, sel_clock inverts the value of the sel output and asserts the capture signal. This causes the ram_select unit to flip the RAMs. When the capture signal is asserted, the screen_store unit begins storing another screen image to the RAM. It is important that sel_clock only trigger a page flip while vblank is low. This ensures that the transition occurs while the screen is being blanked, preventing viewers from seeing the refresh.
In order to display complicated characters more easily, the video subsystem uses an array of ROMs containing sprite images. Just like the ZBT RAMs, these ROMs are addressed by pixel coordinates and contain the color of the corresponding pixel. If the current position on the screen falls within a displayed sprite, the screen_store system indexes the appropriate ROM and selects the value stored at the current location to store in the page buffer. The iGamePlay system uses sprites for players, enemies, missiles, and for the title screens.
The screen_draw unit generates the control signals necessary to drive the VGA monitor. These signals include the vertical and horizontal sync and blank signals. Additionally, the screen_draw unit reads the color value of the current pixel from memory and presents it to the ADV7125 chip. This chip performs the digital to analog conversion necessary to display the data on the VGA monitor.
Since the screen_draw unit functions as a continuous signal generator, the unit is implemented as several separate Verilog always blocks. Since these blocks execute in parallel, this guarantees that the control signals remain appropriately in sync.
Displaying VGA video starts by generating a pixel clock. Every time the pixel clock pulses high, the current data presented to the ADV7125 will be latched in and converted. A complete line of pixels is preceded by a horizontal sync pulse. Similarly, a complete frame of lines is preceded by a vertical sync pulse. All sync pulses are surrounded by a blanking interval. These intervals are know as the front and back porches. The exact duration and timing of these pulses great depends on the resolution and refresh rate of the monitor in use. For a table of the timing parameters used in the iGamePlay system and the Verilog code for the screen_draw module, please see Appendix B.
The screen_store unit is the most complicated unit in the video subsystem. This unit takes input from the game control system. Using this input, the screen_store unit determines what color needs to be displayed at each pixel on the screen and stores these values to the ZBT page buffer.
The basic structure of the screen_store unit is as follows. The unit waits in an IDLE state until the sel_clock unit asserts the capture signal. Starting from the upper left corner of the screen, screen_store examines the input to determine if the current pixel is contained within a sprite to be displayed on the screen. If so, the unit uses the current pixel’s coordinates to address the appropriate sprite ROM and retrieve the pixel’s color value. This value is then written into the ZBT page buffer. If no sprite is present at the current location, the unit writes the background color into the ZBT page buffer and examines the next pixel on the same line. Once the line is completed, the unit moves on to the next line until the entire screen has been stored to the ZBT RAM. The unit then asserts the fin signal, and waits until the sel_clock unit re-asserts the capture signal.