\begin{section}{Description}
\label{sec:desc}

\begin{subsection}{Input and Ouput}


\begin{figure}
\PSbox{jastr/schematics/io.ps hoffset=-20 voffset=-25 hscale=83 vscale=83}{6.5in}{8.5in}
\caption{Analog Video I/O Module}
\label{fig:iosch}
\end{figure}

\begin{subsubsection}{Analog to Digital Converter} 
\label{sec:adcdetail}

The video signal from the camera is fed directly into an AD 775 analog
to digital converter, U1 on Figure~\ref{fig:iosch}.  This chip samples
video data on the falling edge of the clock, and two and a half clock
cycles later places the value corresponding to that sample on the
outputs, which connect to the differencer.  The output enable for the
chip is asserted for half of a pixel cycle, during which the dram
stores the intensity of the pixel.  The pipeline delay associated with
the samples is ignored by the system.  The input range of the ADC as
configured here is 0 to 2.4 volts.

\end{subsubsection}



\begin{subsubsection}{Sync Generator} 

The LM1882, U4 on Figure~\ref{fig:iosch}, provides vertical and
horizontal sync pulses for both the camera and the rest of the
controller, providing information about the start and end of both
lines and frames.  The data input signals are present to turn on the
output enable bit in the chip's status register.  The chip's default
values create pules for standard NTSC when clocked at 14.31818 MHz,
except for the output enable.  To start up, the {\tt clr} and {\tt
/load} inputs must be pulsed sequentially to enable the ouput.

\end{subsubsection}

\begin{subsubsection}{Digital to Analog Converter}

The outputs from the frame differencer and bitmap overlay module
combine to produce a single stream of video data, which is converted
to analog and displayed on a greyscale monitor.  The converter
consists of two chips, a DAC0800, U2 on Figure~\ref{fig:iosch}, and an
LF357 op amp, which is necessary because the DAC0800 acts as a
variable current source rather than a variable voltage source.  R3, the
330$\Omega$ resistor across the two inputs to the op amp, is an
uncommon location for a gain control on an op amp.  The LF357 requires
that the feedback gain be within a much more restricted range than
most op amps, to prevent a pole from transforming the desired negative
feedback to unstable positive feedback.

The output of the LF357 and the CBLANK and CSYNC outputs of the LM1882
tie, through resistors, to the input of the display monitor.  This
linear network ensures that the voltage levels are within acceptable
levels for the monitor, and that the sync pulses are placed on the
output, as the digital output stream is set to all zeroes during blanking
periods.

\end{subsubsection}

\end{subsection}


\begin{subsection}{Frame Differencer}

\begin{subsubsection}{Overview}

The main cycle of the frame differencer consists of a sequence of
operations, performed on each pixel in order.  First, the DRAM's /OE
falls low to read the old pixel intensity out of DRAM; this value
is stored in a register.  The ADC then outputs the new intensity of
the same pixel, and the new and old values are fed to the
combinational circuit which calculates the absolute value of the
difference of the two values, and the result is latched into a final
register.  The nine-bit column and row counters serve as the address to
DRAM; the column counter increments after every pixel, and the row
counter increments after every row.  Figure~\ref{fig:count8-timing},
the timing diagram for the differencer, shows the evolution of the
control signals over the pixel cycles, each of which last eight clock
cycles.  Eight cycles are necessary in order to allow the address and
data busses to stabilize before they are read.

\begin{figure}
\epsfbox{golem/report/absdiff.eps}
\caption{Absolute Difference Block Diagram}
\label{fig:absdiff-block}
\end{figure}

\begin{subsubsection}{Absolute Difference Datapath}


\begin{figure}
\PSbox{jastr/schematics/diff.ps hoffset=-20 voffset=-25 hscale=83
vscale=83}{6.5in}{8.5in}
\caption{Absolute Differencer Datapath}
\label{fig:diffsch}
\end{figure}


The differencer computes the absolute value of the difference between
the current pixel's intensity and that of the same pixel of the
previous frame.  Once the two eight-bit input values are on the bus, this
is a purely combinational process.  The algorithm proceeds as follows:

\begin{enumerate}
\item Bitwise invert one of the eight-bit values.
\item Add the inverted signal to the other original eight-bit signal.
\item Use the high carry out of the adder as the select bit
	to a 16 to 8 multiplexor.  
\begin{itemize}
    \item If the carry bit is 1, then output the sum plus 1.
    \item If the carry bit is 0, then output the bitwise inversion of
the sum.
\end{itemize}
\end{enumerate} 

This combinational datapath is implemented in one 22v10, one 20v8, and
2 74LS283's.  The first 20v8, U7 on Figure~\ref{fig:diffsch},
registers the old pixel intensity and inverts it.  The two '283's, U8
and U9, add the result to the value on the data bus, which is the
output of the A2D.  This sum is fed into the 22v10, which uses the
carry output of the adder to select whether to output {\tt dsum} plus
1 or {\tt dsum} inverted.  This multiplexor is combined with a
register in U10, which latches the value until the next pixel value
arrives.

\end{subsubsection}

\begin{figure}
\epsfxsize=6.5in \epsfbox{golem/report/count8-timing.eps}
\caption{ADC and DRAM controller cycle}
The beginning of a line, followed by the first three pixels on that line.
\label{fig:count8-timing}
\end{figure}
\end{subsubsection}

\begin{subsubsection}{Controller}


\begin{figure}
\PSbox{jastr/schematics/diffctl.ps hoffset=-20 voffset=-25 hscale=83 vscale=83}{6.5in}{8.5in}
\caption{Differencer Controller}
\label{fig:diffctlsch}
\end{figure}


The differencer controller consists of three 22v10 PALs.  Two of them,
U11 and U12 on Figure~\ref{fig:diffctlsch}, are nine-bit counters which
index the current pixel position.  The other PAL, U13, is the main
controller fsm, which consists of a three-bit counter and decoding
logic to assert and deassert certain signals during the various phases
of the pixel cycle, which lasts for eight system clock periods.  (See
Figure~\ref{fig:count8-timing})  All other control signals are taken
from the LM1882 (See Figure~\ref{fig:timing-longterm}), with the
exception of the {\tt /RAS} row-address-strobe on the DRAM, which is
inverted and time-delayed from the HDRIVE in order to meet the
propagation delay timing constraint of the row-address counter and the
constraint that /RAS be low while accessing the dram.

\begin{figure}
\epsfxsize=6.5in \epsfbox{golem/report/timing-longterm.eps}
\caption{Long-Term Timing}
The beginning of a field and the first three rows of that field.
\label{fig:timing-longterm}
\end{figure}

The row and column address counters are similar, but a few differences
must be noted.  Their output enables have opposite polarity (negative
true for the row, positive true for the column) so that, while these
inputs both come from CBLANK, nevertheless only one chip drives the
bus at any point.  In addition, while the differencer stores entire
frames in the DRAM, the input is in the form of interlaced odd and
even fields; thus, the ODD/EVEN bit from the LM1882 is the low bit of
the row address.  Lastly, the counters have internal comparators which
cause the {\tt /FULL} bit to go low when the counter passes a certain
constant; for the column, this constant is 180, and for the row, it is
250.  This gives 180 columns and roughly 500 lines on the screen
(somewhat less because of sloppiness in the handling of the edge
conditions).

\end{subsubsection}

\end{subsection}


\begin{subsection}{Pong Rules Module}


The rules module keeps track of the motion of the ball, and updates it
according to information about regions of motion in the field of view
of the camera.  It implements a very simple version of the game Pong,
with rules as follows:

\begin{itemize}
\item The ball's x and y positions increment by certain values every
frame, which do not change unless the ball hits something.
\item If the ball hits the top or the bottom of the screen, it
reverses its y direction and continues as before.
\item If the ball hits a region of motion while in a ``bounce
region'', it reverses its x direction and randomizes its x and y
velocities and y direction.
\item If the ball goes off the left or right edge of the screen, the
appropriate player loses a point, and the ball is returned to the
center of the screen, where it remains motionless until hit by a
region of motion.
\end{itemize}


\begin{figure}
\epsfbox{golem/report/yencoding.eps}
\caption{Internal encoding of the ball's Y position}
\label{fig:yencoding}
\end{figure}

A clever algorithm is used to automate the bouncing of the ball.  The
internal ball x and y positions are nine-bit counters which contain
information not only about the position of the ball, but also about
its direction of motion.  The encoding for the y position is the
simpler of the two (see Figure~\ref{fig:yencoding}): if the high bit
is set, then the ball is going up, and if clear, then the ball is
going down.  The visual position of the ball is obtained by XORing the
high bit of the logical position with every other bit; the y position
is updated every cycle by adding a two-bit velocity to it.  The result
of this is that the ball moves in the appropriate direction at any
time, and when the ball hits the top or bottom of the screen, its
position simply wraps around and the high bit toggles, with the result
that the visual representation of the ball ``bounces'' from the wall
(although the logical position of the ball is still incrementing in
the same ``direction''.)

\begin{figure}
\epsfxsize=6.5in \epsfbox{golem/report/xencoding.eps}
\caption{Internal encoding of the ball's X position}
\label{fig:xencoding}
\end{figure}

The x position is somewhat more complicated, since it determines the
behavior of the ball with respect to the users.  The top three bits of
the nine-bit accumulator (which, like y, increments by a two-bit
velocity every frame) determine the behavior of the ball; thus, the
position space is logically divided into eight segments, shown in
Figure~\ref{fig:xencoding}.  Segments 1 through 3 map to the screen by
subtracting 64, while segments 5 through 7 map to the screen by a
bitwise NOT.  The ball begins in either segment 2 or segment 6 (thus,
the initial direction is random), and as it increments, it moves in
the appropriate direction on the screen, and goes through the segments
in order.  Segments 3 and 7 are ``bounce'' segments, i.e. if the ball
touches a region of movement while in either of those segments, it
will follow the ``bounce'' arrow shown by the diagram by bitwise
inverting and adding 64.  The visual result of this is a reversal of
the direction of the ball; because the segment a bounce action jumps
to is not a ``bounce'' segment, the ball will not bounce again until
it has reached the ``bounce'' segment on the other side of the screen.
If the ball passes through either bounce segment without touching a
region of motion, it will pass though into either segment 4 or segment
0, which are the ``lose'' segments.  If the ball is found to be in a
``lose'' segment, the appropriate player (determined by the segment
number) loses a point, and the ball returns to the center of the
screen.

\begin{figure}
\PSbox{jastr/schematics/pong.ps hoffset=-20 voffset=-25 hscale=83 vscale=83}{6.5in}{8.5in}
\caption{Pong Rules Module}
\label{fig:pongsch}
\end{figure}

When the ball is bounced from a region of motion, the x and y
velocities and the y direction are randomized.  The random data to
accomplish this is fed in from the low bit of the A2D output and
accumulated (via a bit-shifting process) into internal registers in
the CPLD (which performs most of the tasks of the rules module).
Special care is taken to ensure that the x velocity is never zero, for
if it ever became zero, then the ball would bounce up and down in the
same segment forever.

All that remains to be described is the method of detection of a
region of motion.  Two 20v8 PALs are programmed as
eight-bit-to-eight-bit equality comparators: one compares the ball's
screen x position with the current pixel x coordinate, and the other
compares the ball's screen y position with the current pixel y
coordinate.  (A tweak to increase sensitivity was to ground the low
bits of each compared value, effectively increasing the motion
detection area to four pixels instead of one.)  Each outputs a single
bit which is high if the values are equal.  The CPLD takes these two
bits, and a single bit of the difference stream, logically ANDs all
three, and decides that the ball has hit a region of motion if the
result is ever true over the course of a frame.  The effect is that
the ball has ``hit'' something if the difference value is greater than
a certain threshold at the screen position of the ball; if so, and if
the ball is in a ``bounce'' region, the CPLD will perform the
``bounce'' operation.

\end{subsection}


\begin{subsection}{Bitmap Overlay Module}

\begin{figure}
\epsfbox{golem/report/overlay.eps}
\caption{Block Diagram for Bitmap Overlay}
\label{fig:overlay-block}
\end{figure}

The Bitmap Overlay module takes the difference stream, the current
pixel coordinates, and the ball position as inputs, and outputs a
digital video stream which consists of the difference stream with an
image overlaid at the position of the ball.  The circuit is entirely
combinatorial; see Figure~\ref{fig:overlay-block}.

By bitwise inverting one input to each of two adders, the circuit
finds the differences between the current pixel location's and the
current ball location's x and y coordinates.  These two eight-bit
offsets form a sixteen-bit address, the high thirteen bits of which
become the low thirteen bits of the PROM address, and the low three
bits of which are used to select one of the eight bits which the PROM
outputs (using a '151 8-to-1 multiplexor).

The two high address lines on the PROM come from a slowly cycling
'393; in this way, the counter selects among four images in sequence.
The animation cycle lasts roughly half a second.

The single-bit output of this lookup table is XORed with every bit of the
difference bus, and the result is fed to the DAC; thus, where the
lookup table is zero, the output is the difference, and where it is
one, the output is the inverse of the difference, which is usually
white or very close to white.

Because this is the end of a long chain of combinational devices, the
output of the '151 is glitchy, which tends to produce lines on the
display monitor.  Adding a small (1000pF) capacitor to the output of the
multiplexor diminished these glitches enough to render them invisible,
although they are actually still present at a small magnitude.

\begin{figure}
\PSbox{jastr/schematics/bit1.ps hoffset=-20 voffset=-25 hscale=83 vscale=83}{6.5in}{8.5in}
\caption{Bitmap Overlay Offset}
\label{fig:bit1sch}
\end{figure}

\begin{figure}
\PSbox{jastr/schematics/bit2.ps hoffset=-20 voffset=-25 hscale=83 vscale=83}{6.5in}{8.5in}
\caption{Bitmap Overlay Output}
\label{fig:bit2sch}
\end{figure}

\end{subsection}

\end{section}



