バックグラウンド
これは個人的なプロジェクトです。FPGAをN64に接続すると、FPGAが受信したバイト値はUARTを介してコンピューターに送信されます。それは実際にはかなりうまく機能します!不幸にも不定期に、デバイスは失敗し、その後回復します。デバッグによって問題を見つけることができましたが、VHDLにはかなりの能力がないため、修正方法に困惑しています。
私は2日間VHDLをいじっていて、これを解決できないかもしれません。
問題
FPGAへのN64信号を測定するオシロスコープがあり、他のチャネルはFPGAの出力に接続しています。カウンター値を記録するデジタルピンもあります。
基本的に、N64はSTOPビットを含む9つのデータビットを送信します。カウンターは受信したデータビットをカウントし、9ビットに達すると、FPGAはUARTを介して送信を開始します。
正しい動作は次のとおりです。

FPGAは青色の波形で、オレンジ色の波形はN64の入力です。受信中、私のFPGAはデバッグの目的で入力の信号を "エコー"します。FPGAが9までカウントした後、UARTを介してデータの送信を開始します。N64が終了した直後にデジタルピンが9にカウントされ、FPGA出力がLOWになることに注意してください。
失敗の例を次に示します。

カウンターがビット2と7をスキップすることに注意してください!FPGAは最後まで到達し、N64からの次の開始ビットを待ちますが、何もしません。したがって、FPGAはタイムアウトして回復します。
これは、N64受信モジュールのVHDLです。次のカウンターが含まれています:s_bitCount。
library IEEE;
use IEEE.STD_LOGIC_1164.all;   
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity N64RX is
     port(
         N64RXD : in STD_LOGIC;                    --Data input
         clk25 : in STD_LOGIC;
         clr : in STD_LOGIC; 
         tdre : in STD_LOGIC;                      --detects when UART is ready
         transmit : out STD_LOGIC;                 --Signal to UART to transmit  
         sel : out STD_LOGIC; 
         echoSig : out STD_LOGIC;
         bitcount : out STD_LOGIC_VECTOR(3 downto 0);
         data : out STD_LOGIC_VECTOR(3 downto 0)   --The significant nibble
         );
end N64RX;
--}} End of automatically maintained section
architecture N64RX of N64RX is 
type state_type is (start, delay2us, sigSample, waitForStop, waitForStart, timeout, count9bits, sendToUART);
signal state: state_type;
signal s_sel, s_echoSig, s_timeoutDetect : STD_LOGIC;
signal s_baudCount : STD_LOGIC_VECTOR(6 downto 0);  --Counting variable for baud rate in delay
signal s_bitCount : STD_LOGIC_VECTOR(3 downto 0);  --Counting variable for number of bits recieved 
signal s_data : STD_LOGIC_VECTOR(8 downto 0);   --Signal for data
constant delay : STD_LOGIC_VECTOR(6 downto 0) := "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;
それで、何かアイデアはありますか?デバッグのヒント?有限状態機械のコーディングのヒントは?
その間、私はそれをいじり続けます(最終的にはそれを持ちます)。スタック交換を手伝ってください、あなたは私の唯一の希望です!
編集する
デバッグのさらなる発見として、状態はwaitForStartからwaitForStopに戻ります。各状態に、waitForStartが「5」、waitForStopが「4」の値を指定しました。下の画像をご覧ください。
