Background
Este es un proyecto personal; Con respecto a la conexión de un FPGA a un N64, los valores de bytes que recibe el FPGA se envían a través de UART a mi computadora. En realidad funciona bastante bien! En momentos aleatorios, desafortunadamente, el dispositivo fallará y luego se recuperará. A través de la depuración, me las arreglé para encontrar el problema, sin embargo, no sé cómo solucionarlo porque soy bastante incompetente con VHDL.
He estado jugando con la VHDL por un par de días y puedo ser incapaz de resolver esto.
El problema
Tengo un osciloscopio que mide la señal N64 en el FPGA, y el otro canal se conecta a la salida del FPGA. También tengo pines digitales grabando el valor del contador.
Esencialmente, el N64 envía 9 bits de datos, incluido un bit STOP. El contador cuenta los bits de datos recibidos y cuando llego a 9 bits, el FPGA comienza a transmitir a través de UART.
Aquí está el comportamiento correcto:
ElFPGAeslaformadeondaazulylaformadeondanaranjaeslaentradadelN64.Durantelarecepción,miFPGA"hace eco" de la señal de la entrada para fines de depuración. Después de que el FPGA cuente hasta 9, comienza a transmitir los datos a través de UART. Observe que los pines digitales cuentan hasta 9 y la salida FPGA se BAJA inmediatamente después de que se termina el N64.
Aquí hay un ejemplo de un error:
¡Notequeelcontadorsaltalosbits2y7!ElFPGAllegaalfinal,esperandoelsiguientebitdeiniciodelN64peronada.AsíqueelFPGAseapagayserecupera.
EsteeselVHDLparaelmóduloderecepciónN64.Contieneelcontador:s_bitCount.
libraryIEEE;useIEEE.STD_LOGIC_1164.all;useIEEE.STD_LOGIC_UNSIGNED.ALL;entityN64RXisport(N64RXD:inSTD_LOGIC;--Datainputclk25:inSTD_LOGIC;clr:inSTD_LOGIC;tdre:inSTD_LOGIC;--detectswhenUARTisreadytransmit:outSTD_LOGIC;--SignaltoUARTtotransmitsel:outSTD_LOGIC;echoSig:outSTD_LOGIC;bitcount:outSTD_LOGIC_VECTOR(3downto0);data:outSTD_LOGIC_VECTOR(3downto0)--Thesignificantnibble);endN64RX;--}}EndofautomaticallymaintainedsectionarchitectureN64RXofN64RXistypestate_typeis(start,delay2us,sigSample,waitForStop,waitForStart,timeout,count9bits,sendToUART);signalstate:state_type;signals_sel,s_echoSig,s_timeoutDetect:STD_LOGIC;signals_baudCount:STD_LOGIC_VECTOR(6downto0);--Countingvariableforbaudrateindelaysignals_bitCount:STD_LOGIC_VECTOR(3downto0);--Countingvariablefornumberofbitsrecievedsignals_data:STD_LOGIC_VECTOR(8downto0);--Signalfordataconstantdelay:STD_LOGIC_VECTOR(6downto0):="0110010"; --Provided 25MHz, 50 cycles is 2us
constant delayLong : STD_LOGIC_VECTOR(6 downto 0) := "1100100";
begin
n64RX: process(clk25, N64RXD, clr, tdre)
begin
if clr = '1' then
s_timeoutDetect <= '0';
s_echoSig <= '1';
s_sel <= '0';
state <= start;
s_data <= "000000000";
transmit <= '0';
s_bitCount <= "0000";
s_baudCount <= "0000000";
elsif (clk25'event and clk25 = '1') then --on rising edge of clock input
case state is
when start =>
--s_timeoutDetect <= '0';
s_sel <= '0';
transmit <= '0'; --Don't request UART to transfer
s_data <= "000000000";
s_bitCount <= X"0";
if N64RXD = '1' then
state <= start;
elsif N64RXD = '0' then --if Start bit detected
state <= delay2us;
end if;
when delay2us => --wait two microseconds to sample
--s_timeoutDetect <= '0';
s_sel <= '1';
s_echoSig <= '0';
if s_baudCount >= delay then
state <= sigSample;
else
s_baudCount <= s_baudCount + 1;
state <= delay2us;
end if;
when sigSample =>
--s_timeoutDetect <= '1';
s_echoSig <= N64RXD;
s_bitCount <= s_bitCount + 1;
s_baudcount <= "0000000";
s_data <= s_data(7 downto 0) & N64RXD;
state <= waitForStop;
when waitForStop =>
s_echoSig <= N64RXD;
if N64RXD = '0' then
state <= waitForStop;
elsif N64RXD = '1' then
state <= waitForStart;
end if;
when waitForStart =>
s_echoSig <= '1';
s_baudCount <= s_baudCount + 1;
if N64RXD = '0' then
s_baudCount <= "0000000";
state <= delay2us;
elsif N64RXD = '1' then
if s_baudCount >= delayLong then
state <= timeout;
elsif s_bitCount >= X"9" then
state <= count9bits;
else
state <= waitForStart;
end if;
end if;
when count9bits =>
s_sel <= '0';
if tdre = '0' then
state <= count9bits;
elsif tdre = '1' then
state <= sendToUART;
end if;
when sendToUART =>
transmit <= '1';
if tdre = '0' then
state <= start;
else
state <= sendToUART;
end if;
when timeout =>
--s_timeoutDetect <= '1';
state <= start;
end case;
end if;
end process n64RX;
--timeoutDetect <= s_timeoutDetect;
bitcount <= s_bitCount;
echoSig <= s_echoSig;
sel <= s_sel;
data <= s_data(4 downto 1);
end N64RX;
Entonces, ¿alguna idea? Consejos de depuración? ¿Consejos para codificar máquinas de estados finitos?
¡Mientras tanto, seguiré jugando con él (lo tendré eventualmente)! ¡Ayúdame a Stack Exchange, eres mi única esperanza!
Editar
Un descubrimiento adicional en mi depuración, los estados pasarán de waitForStart a waitForStop. Le di a cada estado un valor con waitForStart igual a '5' y waitForStop igual a '4'. Vea la imagen de abajo: