Written by Fabio Andres

 

 

In this manual you are going to understand how the SNES Controller Works, and how we can acquire through a simple Finite State Machine (FSM), all the buttons states from the SNES controller using the de0-nano SOC (you can use any FPGA borad, and implement this manual).

It is important to make clear that this manual is based on "SNES timing diagram"(Design Methodology) by Thomas D.

 

Required Materials:

  1. Any FPGA board (Though for this manual we are going to use the DE0-NANO-SOC)
  2. SNES Controller (10 USD on Ebay)

 

Brief Explanation:

  • Let's start by looking at the SNES Controller Pinout:

 

 

As you can see The SNES has two gamepad ports which each have 5 wires. Two are the power supply wires: brown (ground) and white (5v). Two of the three remaining wires are used by the SNES to output clock and timing information: yellow (data latch), and orange (data clock) y el Puerto restante es el rojo (DATA).

 

  • The SNES sends a 12 us positive impulse on the data latch wire (yellow). This data latch indicates the SNES will start sending 16 data clock periods to the gamepad on the clock wire (orange) which are used by the gamepads to indicate what buttons are pressed. Each of the 16 data clock periods represent a different button, and the SNES will expect the output signal to toggle on those data clock periods which indicates a button on the gamepad is pressed.

There are 12 buttons on the SNES gamepad, but the SNES sends 16 data clocks periods. Only the first 12 data clock periods are used, the following 4 are ignored by the SNES. The protocol was first designed for the NES console which had less buttons. Nintendo added new buttons on the SNES but didn't change the communication protocol as it could support more buttons. Potentially, this protocol could support up to 16 different buttons.

 

 

  •  Once the logical procedure is understood, the following step is to put this into a FSM Diagram to make it more understandable.

 

  • The previous FSM diagram is composed by 5 different states which are necessary to get the buttons status from SNES controller:
    • IDLE: this state set up the delay in 12 microseconds and, if the signal start is high, go to the next state.
    • STATE1: in this state the LATCH  signal is high, and stay in this status as long as the delay is greater than zero, when have passed 12 microseconds, the FSM go to the next state.
    • STATE2: in this state the LATCH signal  goes from high state to low state and the clock signal hold in high state as long as the delay is greater than zero, when have passed 6 microseconds, the FSM go to the next state.
    • STATE3: in this state all the signals hold in low state (the clock signal goes from high state to low state) From now on whenever a flank is down it takes a button and it is stored in the buttons_temp vector [14: 0] (always@ negedge clk_snes) if the module have saved all the 16 buttons state, the FSM go to the next state, else , the FSM returns to the state 2 and save a new botton state.
    • STATE4: in this state the clock signal hold in high state as long as the delay is greather than zero, when have passed 12 microseconds the FSM go to the next state.
    • FINISH: in this state the finish signal hold in high state and the bottons state are sent to the output of the module and the FSM goes to the IDLE state. 

 

  • The above description can be represented by the following graph through time:

 

  •  Now it is time to see the Verilog Code, for this logic.
    • Verilog Module pinout:
      module SNES_FSM(
      				input clk_50,
      				input start,
      				input data_in_snes,
      				output reg [11:0]buttons_snes,
      				output finish,
      				output idle,
      				output latch_snes,
      				output clk_snes
      				);
    • States and control signal declaration:
      							  //LATCH______CLOCK_____FINISH____IDLE______STATE
      localparam   IDLE  =  10'b0_____________1_________0________1______000001;
      localparam   STATE1=  10'b1_____________1_________0________0______000010;
      localparam   STATE2=  10'b0_____________1_________0________0______000100;
      localparam   STATE3=  10'b0_____________0_________0________0______001000;
      localparam   STATE4=  10'b0_____________1_________0________0______010000;
      localparam   FINISH=  10'b0_____________1_________1________0______100000;
      							//numero de clocks del relog base de 50 Mhz
      localparam   TIME6u	= 10'd300;
      localparam   TIME12u	= 10'd600;
      
      
      reg [9:0]state=IDLE;
      reg [9:0]delay=TIME12u;
      reg [3:0]num_clks=4'd0;
      reg [14:0]buttons_temp=15'd0;
      wire pre_finish=(state[9:0]==STATE4)?1'b1:0;
      assign latch_snes=state[9];
      assign clk_snes=state[8];
      assign finish=state[7];
      assign idle=state[6];
      
      
    • Main FSM:
      always@(posedge clk_50)
      begin
      	case(state[9:0])
      	IDLE  :begin
      				state[9:0]<=IDLE;
      				delay[9:0]<=TIME12u;
      				num_clks[3:0]<=4'd0;
      				if(start==1)
      				begin
      					state[9:0]<=STATE1;
      				end
      			 end
         STATE1:begin
      				state[9:0]<=STATE1;
      				delay[9:0]<=delay[9:0]-1'b1;
      				num_clks[3:0]<=4'd1;
      				if(delay[9:0]==10'd0)
      				begin
      					delay[9:0]<=TIME6u;
      					state[9:0]<=STATE2;
      				end
      			 end
      	STATE2:begin
      				state[9:0]<=STATE2;
      				delay[9:0]<=delay[9:0]-1'b1;
      				num_clks[3:0]<=num_clks[3:0];
      				if(delay[9:0]==10'd0)
      				begin
      					delay[9:0]<=TIME6u;
      					state[9:0]<=STATE3;
      				end
      			 end
         STATE3:begin
      				state[9:0]<=STATE3;
      				delay[9:0]<=delay[9:0]-1'b1;
      				num_clks[3:0]<=num_clks[3:0];
      				if(delay[9:0]==10'd0)
      				begin
      					num_clks[3:0]<=num_clks[3:0]+1'b1;
      					if(num_clks[3:0]<4'd15)
      					begin	
      						delay[9:0]<=TIME6u;
      						state[9:0]<=STATE2;
      					end
      					else
      					begin
      						delay[9:0]<=TIME12u;
      						state[9:0]<=STATE4;
      					end
      				end
      			 end
         STATE4:begin
      				state[9:0]<=STATE4;
      				delay[9:0]<d=delay[9:0]-1'b1;
      				num_clks[3:0]<=4'd0;
      				if(delay[9:0]==10'd0)
      				begin
      					state[9:0]<=FINISH;
      				end
      			 end
         FINISH:begin
      				state[9:0]<=IDLE;
      				delay[9:0]<=10'd0;
      				num_clks[3:0]<=4'd0;
      			 end
      	default:begin
      				state[9:0]<=IDLE;
      				delay[9:0]<=10'd0;
      				num_clks[3:0]<=4'd0;
      			 end
      	endcase
      end
    • shift register to save button states:
      always@(negedge clk_snes)
      begin							
      	buttons_temp[14:0]<={data_in_snes,buttons_temp[14:1]};
      end
    • When FSM has acquired all the buttons, sends them to the output of the module:
      always@(posedge pre_finish)
      begin
      	buttons_snes[11:0]<=buttons_temp[11:0];
      end

 

  •  Once we have taken a look at the FSM diagram and the Verilog description, we can simulate using ModelSim to verify that the designed FSM works properly, and we meet the timing specifications.

 

 

 

 

  • ENJOY!

 

 

 

 

 

Attachments:
Download this file (DE0_NANO_SOC_SNES_control.qar)DE0_NANO_SOC_SNES_control.qar[ ]12 kB
Download this file (SNES_FSM.v)SNES_FSM.v[ ]2 kB
Powered by OrdaSoft!
  Written By Peter Gomez Este contenido esta orientado a los programadores que tienen problema con la conectividad("SGC PmmC") de su pantalla uOled-128-g1/g2…
Written by Sherneyko Plata Rangel   Pynq-z2: Hello world   In this tutorial we will implement a simple test of the inputs/outputs available on…
Objetivos Requerimientos Procedimiento Descripción de Hardware. Qsys. Nios II. UCOS II. Secuencia de Sprite. Sintesis de Audio. Descargas Glosario Otros Resultados. Ejemplo de Sprites.     Objetivos: Diseñar una plantilla general para el diseño de…
Written by Holguer A. Becerra           Requerimientos: DE0-NANO USB-UART(solo para parte 3) Python 2.7 ó superior.   Objetivos: Dar una introducción a los conceptos de Multitasking, Scheduling y…
Written by Holguer A. Becerra             Based on Gregory Estrade's Work.   I have ported the PC Engine System on the DE0-NANO back in 2014, why…
      Arduino tools are generally nice tools for quick prototyping and improvized projects, and the Seeeduino Xiao…
Written by: Holguer A Becerra         En esta practica vamos a construir nuestro primer juego retro  usando un sincronizador de Video VGA…
Written by: Andrea Paola Pabón Ortega & Daniel Enrique Mejia Rueda Revision by: Ing Holguer A. Becerra   DESCRIPCIÓN DEL PROYECTO: El  RTAWD DE0NANO…
  Written by Holguer Andres   Requires: DE0-NANO. 4.3 Inch 480x272 Screen.( WQVGA ) ?️       Parte HW: Descargue la siguiente plantilla( DE0_NANO_TFT_PSP.zip) y descomprimala en una ruta sin espacios y…
Escrito por Guillermo Acevedo   Diseño   En esta practica desarrollaremos un filtro FIR en hardware, para este caso en especifico, realizaremos un filtro…
 Written By Juan David Delgado   FILTRO FIR (FILTRO DE RESPUESTA FINITA AL IMPULSO)     Son conocidos como filtros digitales no recursivos debido a…
XISCKER: Reduced and Complex Instruction Set Computing Key Educational Resources A Configurable Platform for the Emulation of Different Computer Architectures An introduction to Computer Architectures through digital design description for FPGA devices   Computer Architecture embraces all three…
Escrito por: Alix Angarita   En el manual a continuación se explica un método de debug adicional que es muy interesante debido a…
By: Fabio Hernández   INTRODUCCIÓN:   El presente documento pretende mostrar la manera de generar software para una imagen de Linux implementada en la…
Summary Written by Fabio Hernandez   HARD PROCESSOR SYSTEM (HPS)     ------------------------------------------------------------------------------------------------------------------------------------------------   Introducción   Tenemos  2 nuclos de procesamiento ARM cortex-A9, cada uno son su propio cache  se…
Escrito por Jesus Lopez         INTRODUCCIÓN   El acceso directo a memoria (DMA, del inglés direct memory access) permite a cierto tipo de componentes de una computadora acceder a…
    Written by  Sebastian Baquero       Objetivos  Introducción a los conceptos de Multitasking, Scheduling y Context Switching.  Ampliación de los conceptos a cerca de el…