Appendix C1 – module BankSelect
// ********************************************************************
// This module assigns a memory bank to the camera and the monitor
// When the camera reaches the end of a frame, it is switched to
// the next frame and the next time the monitor gets to the end of
// a frame, it is switched to the next frame. Since the monitor
runs
// faster than the camera, it will display the same bank for multiple
// frames.
module bankselect (clk, cameraFrame, monitorFrame, cameraBank, monitorBank) ;
input cameraFrame ; // Goes high when camera has finished a frame
input monitorFrame ; // Goes high when monitor has finished a frame
input clk ;
output [1:0] cameraBank ; // Bank address used by the camera to store
a frame
output [1:0] monitorBank ;// Bank address used by the monitor
reg [1:0] cameraBank ;
reg [1:0] monitorBank ;
reg [1:0] previousCameraBank ; // Monitor uses the previous camera
frame
reg nextCameraBank ; // Control signal that loads cameraBank with
next value
reg nextMonitorBank ; // Control signal that loads monitorBank
with next value
// State register and state assignments
reg [1:0] state, nextState;
parameter cameraWait = 0, cameraDone = 1,
monitorWait = 2, monitorDone = 3;
// Note that the state machine has no reset - it is self starting
// Note that we do not use delayed assignment when using previousCameraBank
// If we change the value in the first if statement, we want to use
the new
// value in the second if. (Currently this never happens because
nextCameraBank
// and nextMonitorBank are never asserted at the same time.)
always @(posedge clk) begin
state <= nextState;
if (nextCameraBank) begin
previousCameraBank = cameraBank; // Save current camera bank
cameraBank <= cameraBank + 1; // Move to next bank
end
if (nextMonitorBank)
monitorBank = previousCameraBank; // Move to next bank
end
always @(state or cameraFrame or monitorFrame) begin
// Default values for outputs
nextMonitorBank = 0;
nextCameraBank = 0;
nextState = state; // Stay in the same state by default
case (state)
// Wait for camera to get to the end of a frame
// We don't come to this state until cameraFrame is turned off
cameraWait: begin
if (cameraFrame) begin
nextState = cameraDone;
nextCameraBank = 1; // Go to the
next camera bank
end
end
// Camera is at the end of a frame
cameraDone: begin
if (!cameraFrame) nextState = monitorWait;
else if (monitorFrame) begin
nextState = monitorDone;
nextMonitorBank = 1;
end
end
// Camera has started a new frame but we are still waiting for
the monitor
// to finish so we can move it along
monitorWait: begin
if (monitorFrame) begin
nextState = cameraWait; // we know cameraFrame =
0
nextMonitorBank = 1;
end
end
// Both the camera and monitor have finished their frames and
have
// moved to the next bank.
// We need to wait for the camera to deassert cameraFrame
monitorDone: begin
if (!cameraFrame) nextState = cameraWait;
end
endcase
end
endmodule
Appendix C2 – module Blank
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma, //
Gary Look, and Michael Dougherty)
//
// FILE: blank.v
//
// DESCRIPTION: Asserts the blank signal outside of the monitor
image region
//
// ********************************************************************
module BLANK (HCNT, VCNT, NBLANK) ;
input [9:0] HCNT ;
input [9:0] VCNT ;
output NBLANK ;
assign NBLANK = ((HCNT > 0 && HCNT < 512 ) && (VCNT < 481));
endmodule
Appendix C3 – BlankPixel
// ********************************************************************
module BlankPixel (DataIn, blank, DataOut) ;
input [7:0] DataIn ;
input blank ;
output [7:0] DataOut ;
// This passes the data from input to output, setting it to
// zero if blank is asserted
assign DataOut = (blank ? 0 : DataIn);
endmodule
Appendix C4 – module Camera_Test
// ********************************************************************
// This module takes pixel values from the FIFO and writes the top
left
// 256x256 pixels into the VGA memory space. We throw away the pixels
// outside this 256x256 area
// Memory asserts BUSY when it can't do the write - we repeat the write
// until BUSY is not asserted
module camera_test (Clk, Empty, Fst, Busy, addr_low, addr_high, Write, RE, frameEnd);
input Clk ;
input Empty ;
input Fst ; // frame start signal
from the camera
input Busy ; // busy signal from memory
output [7:0] addr_low ; // address to memory
output [7:0] addr_high;
output Write ; // write signal to memory
output RE ; // Read signal to FIFO - move to the
next entry
output frameEnd ; // Signals that we've reached the end of the
frame
reg [8:0] hcnt, next_hcnt; //horizontal pixel counter
reg [8:0] vcnt, next_vcnt; //vertical line counter
reg Write, RE;
parameter LINESIZE = 351; // Length of a line from the camera
assign addr_low = {hcnt[7:0]};
assign addr_high = {vcnt[7:0]};
wire inImage;
assign inImage = hcnt < 256 && vcnt < 256;
assign frameEnd = (vcnt == 256); // End of frame when we get to the 256th row
always @ (posedge Clk) begin
if (Fst) begin // We reset everything on Fst
hcnt <= 0;
vcnt <= 0;
end else begin
hcnt <= next_hcnt;
vcnt <= next_vcnt;
end
end
always @ (hcnt or vcnt or inImage or Fst or Busy or Empty) begin
Write = 0; // Default values
RE = 0;
next_hcnt = hcnt;
next_vcnt = vcnt;
if (!Fst) begin // frame reset signal
// If the FIFO has something, and we are in the image, write to memory
if(!Empty && inImage) Write = 1;
// If we had a pixel and memory was not busy, or we were not in the
image, go on to next pixel
if (!Empty && (!Busy ||
!(inImage))) begin
RE = 1;
next_hcnt = hcnt + 1;
if(hcnt >= LINESIZE) begin // if we are at the end of
the line
next_hcnt = 0; // on to
next row
next_vcnt = vcnt + 1;
end
end
end
end
endmodule
Appendix C5 – module Coords (BusIFace)
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma, //
Gary Look, and Michael Dougherty)
//
// FILE: coords.v
//
// DESCRIPTION: Sets the FINX, FINY, MOTX, and MOTY registers
when new
//
data is available from the bus interface.
//
//*********************************************************************
module COORDS (CLK, RESET, DONE, BYTEX_A, BYTEX_BH, BYTEX_BL, BYTEY_A, BYTEY_BL, BYTEY_BH, FINX, FINY, MOTX, MOTY) ;
input CLK;
input RESET;
input DONE;
input [7:0] BYTEX_A;
input BYTEX_BH;
input BYTEX_BL;
input [7:0] BYTEY_A;
input BYTEY_BH;
input BYTEY_BL;
output [8:0] FINX;
output [8:0] FINY;
output [8:0] MOTX;
output [8:0] MOTY;
reg [8:0] FINX;
reg [8:0] FINY;
reg [8:0] MOTX;
reg [8:0] MOTY;
always@(posedge CLK)
begin
if(RESET)
begin
FINX = 9'b0_1000_0000;
FINY = 9'b0_1000_0000;
MOTX = 9'b0_1000_0000;
MOTY = 9'b0_1000_0000;
end
else if(DONE)
begin
// checks the high order bit the last tranmitted byte to determine
// whether this is touch screen coordinates or motor coordinates
if(BYTEX_BH && BYTEY_BH)
begin
FINX = {BYTEX_BL,BYTEX_A};
FINY = {BYTEY_BL,BYTEY_A};
end
else
begin
MOTX = {BYTEX_BL,BYTEX_A};
MOTY = {BYTEY_BL,BYTEY_A};
end
end
end
endmodule
Appendix C6 – module NbusControl (BusIFace)
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma,
//
Gary Look, and Michael Dougherty)
//
// FILE: NBuscontrol.v
//
// DESCRIPTION: Finite Stage Machine for the bus interface.
Control
//
when data is shifted in, and asserts Done when the
//
data is ready
//
//*********************************************************************
module NBuscontrol (Strobe,CLK, RST,state,SHData,Done) ;
input CLK ;
input RST;
input Strobe;
output SHData ; // Shift next nibble into data register
output Done;
output[4:0] state;
reg SHData ;
reg Done;
// FSM states
parameter IDLE = 0, // waiting for first nibble
Data1 = 1, // got first nibble, waiting for second
Data2 = 2, // got second nibble, waiting for third
Data3 = 3, // got third nibble, waiting for fourth
Data4 = 4, // got fourth nibble, waiting for fifth
Data5 = 5, // got fifth nibble, waiting for sixth
Data6 = 6, // got sixth nibble, waiting for seventh
Data7 = 7, // got seventh nibble, waiting for eigth
Data8 = 8, // got eigth nibble; waiting for ninth
Data9 = 9, // ...
Data10 = 10,
Data11 = 11,
Data12 = 12,
Data13 = 13,
Data14 = 14,
Data15 = 15,
Data16 = 16; // got sixtheenth nibble. all done
reg [4:0] state;
reg [4:0] nextState;
//reg prstrobe;
//reg reading;
always @(posedge CLK) begin
if (RST) begin
state <= IDLE;
// reading = 0;
end else begin
state <= nextState;
end
// if (prstrobe == 0 && Strobe == 1)
// reading = 1;
// else
// reading = 0;
// prstrobe = Strobe;
end
always @(state or Strobe ) begin
// default behavior
Done=0;
nextState = state; // Stay in the same state by
default
SHData = 0;
case (state)
IDLE: // This is the IDLE
state
begin
if(Strobe)
begin
SHData=1;
//the first nibble
nextState=Data1;
end
end
Data16:
begin
nextState=IDLE;
Done = 1;
end
default: // increment next state and shift if we get a
Strobe signal
begin
if(Strobe)begin
SHData=1;
nextState=nextState+1;
end
end
endcase
end
endmodule
Appendix C7 – module NDataReg (BusIFace)
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma,
//
Gary Look, and Michael Dougherty)
//
// FILE: NDataReg.v
//
// DESCRIPTION: Shifts in data from FPGA 1
//
//*********************************************************************
module NDataReg (CLK,DataBus,SHData,FirstByteData,SecondByteData,ThirdByteData,FourthByteData)
;
input CLK ;
input [1:0] DataBus ;
input SHData ;
output [7:0] FirstByteData ;
output [7:0] SecondByteData ;
output [7:0] ThirdByteData ;
output [7:0] FourthByteData ;
reg [31:0] ByteData ;
// Data gets shifted to the right as it gets in, so the first byte is
at 'right' end of ByteData
assign FourthByteData = ByteData[31:24];
assign ThirdByteData = ByteData[23:16];
assign SecondByteData = ByteData[15:8];
assign FirstByteData = ByteData[7:0];
// Shift right as low order nibbles come first
always @(posedge CLK) begin
//Low order is sent first....
if (SHData) ByteData = { DataBus, ByteData[31:2] };
end
endmodule
Appendix C8 – module SyncGen
// ********************************************************************
// This module defines when the horizontal sync and vertical sync are
// asserted. By asserting these syncs in the middle of the blank
// region, we are in effect centering the image displayed on the screen
// The horizontal count goes to 759
// The vertical count goes to 527
module syncgen (hcnt, vcnt, hsync, vsync) ;
input [9:0] hcnt ;
input [9:1] vcnt ; // Bit 0 is a don't care, so we have to leave it
out
output hsync ;
output vsync ;
// There is a vile bug in the synthesis tools which throws away
// individual bits in busses attached to pins that are not used.
// Xilinx says the bug is being fixed but for now we have to work around
it
assign hsync = !((hcnt>=582)&&(hcnt<=674)); // These are
magic numbers!
//assign vsync = !(vcnt>=490)&&(vcnt<=491);
assign vsync = !(vcnt==245); // A hack to avoid the synthesis
bug
endmodule
Appendix C9 – module Target
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma,
//
Gary Look, and Michael Dougherty)
//
// FILE: target.v
//
// DESCRIPTION: Asserts the white signal to draw the motor coordinate
//
crosshairs and the touch coordinate crosshairs.
//
//*********************************************************************
module TARGET (WHITE, MOTX, MOTY, FINX, FINY, HCNT, VCNT) ;
output WHITE ;
input [8:0] MOTX ;
input [8:0] MOTY ;
input [8:0] FINX ;
input [8:0] FINY ;
input [8:0] HCNT ;
input [8:0] VCNT ;
assign WHITE = cross(MOTX, MOTY, FINX, FINY, HCNT, VCNT);
// compares touch and motor coordinates to HCNT and VCNT
function cross;
input [8:0] MOTX;
input [8:0] MOTY;
input [8:0] FINX;
input [8:0] FINY;
input [8:0] HCNT;
input [8:0] VCNT;
if(FINX == HCNT || FINY == VCNT)
cross = 1'b1;
else if((MOTX == (HCNT + 8) || MOTX == (HCNT - 8)) &&
(MOTY < VCNT + 9) && (MOTY > VCNT - 9))
cross = 1'b1;
else if((MOTY == (VCNT + 8) || MOTY == (VCNT - 8)) &&
(MOTX < HCNT + 9) && (MOTX > HCNT - 9))
cross = 1'b1;
else if((FINX == (HCNT + 15) || FINX == (HCNT - 15)) &&
(FINY < VCNT + 16) && (FINY > VCNT - 16))
cross = 1'b1;
else if((FINY == (VCNT + 15) || FINY == (VCNT - 15)) &&
(FINX < HCNT + 16) && (FINX > HCNT - 16))
cross = 1'b1;
// if motor coordinates and touch coordinates are approximatly
equal, an X is draw in the upper
// right portion of the screen, indicating that the platform
is read to fire at the target.
else if(HCNT > 479 && VCNT < 32)
begin
if(VCNT[4:0] == 0 || VCNT[4:0] == 31 || HCNT[4:0] == 0 || HCNT[4:0]
== 31)
cross = 1'b1;
else if((FINX[8:3] == MOTX[8:3]) && (FINY[8:3] == MOTY[8:3]))
begin
if(HCNT[4:0] == VCNT[4:0] || (HCNT[4:0] == (32 - VCNT[4:0])))
cross = 1'b1;
else
cross = 1'b0;
end
end
else
cross = 1'b0;
endfunction
endmodule
Appendix C10 – module Whmux
//*********************************************************************
//
// PROJECT: Sieg Defense Platform (CSE
477, Spring 2000, Gene Ma,
//
Gary Look, and Michael Dougherty)
//
// FILE: whmux.v
//
// DESCRIPTION: If white is asserted, outputs 1111_1111, or the
color
//
white. If white is not asserted, outputs PIXIN
//
//*********************************************************************
module WHMUX (WHITE, PIXIN, PIXOUT) ;
input WHITE ;
input [7:0] PIXIN;
output [7:0] PIXOUT;
assign PIXOUT = wht(WHITE, PIXIN);
function [7:0] wht;
input WHITE;
input [7:0] PIXIN;
if(WHITE)
wht = 8'b1111_1111;
else
wht = PIXIN;
endfunction
endmodule