User`s manual
multiplication. Essentially, they correspond to the decrements needed at the
end of each horizontal scan line. Note the use of 480, 640 (i.e
1920
4
and
1920
4
)
as opposed to the more precise 479, 639. The reason for this is that 480, 640
are multiples of sizable powers of two, reducing the bit width needed for certain
multiplications required in the solution. Moreover, the difference caused by this
slight error can be ignored, due to the continuity of the perspective transforma-
tion. Quite crucial to the ease of solving this set of equations symbolically by
hand was a good choice of basis. We were fortunate that the “natural basis” in
terms of the screen coordinates is actually a pretty good one in that sense.
The outputs of this module are synchronized on a slow clk signal. The
rationale for this is two fold:
1. Due to large number of multiplications, even with pipe-lining, it is unlikely
that we can meet timing requirements of sys clk (50 MHz).
2. It is undesirable to change the parameters mid-frame anyway, and having
a huge latency in changing these parameters may thus in fact be desirable.
5.12 pixel map (Ganesh)
The pixel map module uses the parameters pinv
i
and d
x
, d
y
, d
d
obtained in the
perspective params module to do the actual perspective transformation pixel
by pixel. At a high level, it is doing a simple loop through x and y through
[0, 639] and [0, 479] respectively, computing
pinv
1
x + pinv
2
y + pinv
3
pinv
7
x + pinv
8
y + pinv
9
,
pinv
4
x + pinv
5
y + pinv
6
pinv
7
x + pinv
8
y + pinv
9
at each x and y. It then uses the results to obtain the memory address via
addr map in the ntsc buffer, and uses another addr map to write the data
found in the ntsc buffer to the VGA buffer. When the coordinates of the in-
verse transformation are out of range, the module writes a black pixel. A state
machine is used to start the divider and keep track of the general state of the
computation. The divider used is based on the restoring division algorithm, and
was provided by the staff. There was a subtle bug in the staff-provided divider,
resulting in incomplete divisions being written out. For us, that translated into
always reading an address of 0 of the ntsc buffer, leading to a uniform color over
the whole frame. Essentially, the bug boiled down to an insufficient width for a
counter register in the divider. Tracking down the bug was pretty difficult, since
it first required verifying that our pixel map module was providing the correct
numerator and denominator. A test bench (runnable under the free software
Icarus Verilog simulator) confirmed that there was something wrong with the
divider. Another test bench then verified that the results of the division were
indeed incorrect. Finally, a close examination of the divider code resulted in the
identification of the bug. Once this bug was fixed, the module worked correctly.
Unfortunately, the divider needs a width of 79 bits, and the staff provided di-
vider is not pipe-lined. Xilinx’s IP Coregen provides pipe-lined dividers up to a
18