VIDEO
CONTROLLER
The bit-mapped video controller, based on ideas from
[1], displays all 32 KB of external SRAM at 576
× 455 resolution, monochrome.
It
runs autonomously from the CPU, and so is not a peripheral
on the on-chip bus. It uses DMA to fetch video data,
which consumes about 10% of memory bandwidth.
A
video signal is a series of frames; each frame is
a series of lines, and each line is a series of pixels.
The video controller fetches 16-pixel words of video
memory, shifts the pixels out serially, and uses horizontal
and vertical sync pulses to format the pixels into
frames and lines for the monitor.
Generating
VGA-compatible horizontal and vertical sync timings,
VGA shifts pixels out at 24 MHz, twice the system
clock rate, shifting one out when CLK is high and
a second when it is low. The horizontal and vertical
sync pulses are advanced a few clocks (lines) to center
the display in the frame (see Table 5).
| Port
PIX15:0
REQ
RESET
ACK
CLK
R1,R0
G1,G0
B1,B0
NHSYNC
NVSYNC
|
Description
next 16-bit pixel word
request DMA of next word
reset DMA address counter
DMA acknowledge input
system clock
2-bit red intensity
2-bit green intensity
2-bit blue intensity
active-low horizontal sync
active-low vertical sync
|
Quantity
two-pixel clock
one-pixel half-clockvisible pixels/line
visible clocks/line
horizontal sync "on" clock
horizontal sync "off" clock
line total clocks
line time
visible lines/frame
vertical sync "on" line
vertical sync "off" line
frame total lines
frame time
|
Value
83.3 ns
41.7 ns
576
288
308
353
381
31.8 ms
455
486
488
528
16.8 ms
|
Tables 5 & 6The
12-MHz clock and 24-MHz pixel shift frequency
determines the pixels per line
and lines per frame, as well as the horizontal
and vertical counter values for sync and blanking
events. |
The
VGA ports are described in Table 6. The first five
ports request new pixel data via the DMA controller.
The rest are the VGA video outputs. The red, green,
and blue intensities R1, R0, G1, G0, B1, and B0 drive
resistor-based 2-bit D/A converters, providing up
to 64 colors (4 × 4 × 4). However, at this resolution,
with 32 KB of RAM, you can only support a monochrome
(1-bit/pixel) display. So, each pixel bit drives all
six outputs, drawing black or white pixels.
To
generate horizontal and vertical syncs and a video
blanking signal, you need a 9-bit horizontal cycle
counter and a 10-bit vertical line counter.
After
288 clocks, its time to blank the video. Assert
horizontal sync after 308 clocks, deassert it after
353, and reset the counter and re-enable video after
381 clocks (one line).
In
the vertical direction, the VGA controller must blank
video after 455 lines, assert vertical sync after
486 lines, deassert it after 488 lines, and reset
the counter, re-enable video, and reset the video
DMA address counter after 528 lines.
The
simplest way to build each counter is with a Xilinx
library binary counter, such as a CC16RE. But because
I had just about filled the FPGA, and because theyre
cool, I designed a more compact 10-bit linear feedback
shift register (LFSR) counter. This uses a 10-bit
serial shift register which has an input that is the
XOR of certain shift register output taps.
An
n-bit LFSR repeats every 2n-1 cycles, but you can
make an arbitrary m-cycle counter by complementing
the LFSR input bit, thereby short-circuiting the full
sequence when a particular bit pattern is recognized.
My LFSR counter design program can be downloaded from
the Circuit Cellar web site.
Referring
to Figure 7, note the video controller contains two
LFSR counters, H and V. Each has four comparators
to compare the LFSR bit patterns to the count patterns
output by my program.
| Figure 7As
you can see, the video controller contains
two LFSR counters that each have four comparators
for comparing the LFSR bit patterns to the
count patterns that are output by the program
that I wrote. |
Each
of the J-K flip-flops HENN, NHSYNC, VEN, and NVSYNC
are set on reaching one counter value and reset on
reaching another.
NHSYNC
is asserted low during clocks 308353, and NVSYNC
during lines 486488. HEN is the pipelined horizontal
video enable, and VEN is the vertical video enable.
When both are true, you fetch and shift out video
data.
In
the video datapath, each clock shifts out two
bits of video data. Every eight clocks, WORD goes
true, and it requests a new 16-bit word of video data
from memory. REQ is asserted, registering a pending
DMA transfer with the CPU.
Five
or fewer clocks later, the CPU performs the DMA load,
asserting ACK. The video data word is latched in the
PIXELS staging register. On the eighth clock, this
word is loaded into the PMUX 8 × 2 parallel-load serial-out
shift register.
Two
bits shift out of PMUX during each clock, and feed
a 21 mux that drives the 1-bit pixel each half
clock.