Copyright © 2008 Kevin Gisi
Abstract
This article will cover the basic design and Verilog implementation for a programmable logic device designed to interface with a Nintendo Entertainment Controller (NES). In this implementation, we’ll implement a design on the Altera UP2 Education Board, using the on-board seven-segment displays and VGA output. Design issues that will be covered will include timing the correct clock and latch pulses to interface appropriately with the NES controller, designing a state machine to allow for functionality related to sequential button-pushes, and interfacing with the VGA output.

- This design relies heavily on research done by Jason Rosenthal and Troy Latchman regarding the NES controller protocol.
http://users.ece.gatech.edu/~hamblen/489X/f04proj/USB_NES/protocol.htm
- This also borrows code and research created by Deshanand Singh and Aaron Egier designed to interface with the VGA output pins on the Altera UP2 board.
http://www.eecg.toronto.edu/~jayar/ece241_05F/vga_new/index.html
- Perform some sort of show when the easter-egg state is activated.
- Require that each component of the easter egg sequence be pressed within one second of each other.
- Add an additional sequence of button presses that will activate the easter-egg state that includes simultaneous button-presses.
- Implement some small type of game that can be played with the controller.
module nintendoController(clk,ctrlClock,ctrlLatch,ctrlData,buttons,easterEgg,stateDisplay,color); output [0:7] stateDisplay; parameter Left=8'b11111101; parameter Right=8'b11111110; output color; reg [0:3] color; parameter pollDelay = 555; input clk, ctrlData; output ctrlClock, ctrlLatch, easterEgg; output [0:7] buttons; reg ctrlLatch, ctrlClock; reg [0:7] buttons; reg [0:7] oldButtons; reg [0:10] counter; reg [0:7] persistance; reg [0:7] lag; initial counter = 0; initial persistance = 0; initial lag = 0; initial buttons = 8'b11111111; initial oldButtons = 8'b11111111; integer i; wire [0:3] temporaryState; reclock(clk,clock); easterEggStateMachine(buttons,persistance == 10,(lag == 255 && ~easterEgg),easterEgg,temporaryState); BCD7Seg(stateDisplay,temporaryState); always @(negedge clock) begin counter = (counter == (pollDelay + 18)) ? 0 : counter + 1; ctrlLatch = (counter == pollDelay | counter == pollDelay + 1) ? 1 : 0; ctrlClock = (counter > pollDelay + 1 && ~counter%2) ? 1 : 0; if(counter == 0) begin if(buttons == oldButtons) begin persistance = (buttons != 255) ? persistance + 1 : 0; lag = (buttons == 255) ? lag + 1 : 0; if(persistance == 10 && easterEgg) color <= (buttons == Left) ? color - 1 : (buttons == Right) ? color + 1 : color; end else begin persistance = 0; oldButtons <= buttons; end end end always @(posedge clock) for(i = 0; i < 8; i = i + 1) if((counter - pollDelay)/2 == i) buttons[i] = ctrlData; endmodule
The clock is set to a period of six microseconds to allow sampling of the data line at a time that is precisely between the negative and positive edges of the clock. This ensures that the data sampled is indeed the button desired. This does also mean that the latch and clock pulses sent to the nintendoController must be fabricated from a smaller clock, which can be seen in the always block occuring on a negative clock edge. Part of this logic mandates that the arbitrary pollDelay parameter must be an odd number. In Figure 2, “ nintendoController Waveform Test ”, the parameter was set to a smaller value of five cycles between sampling.

