Lý lịch
Đây là một dự án cá nhân; liên quan đến việc kết nối một FPGA với N64, các giá trị byte mà FPGA nhận được sau đó được gửi qua UART tới máy tính của tôi. Nó thực sự hoạt động khá tốt! Không may vào thời điểm ngẫu nhiên, thiết bị sẽ bị lỗi, sau đó phục hồi. Thông qua việc gỡ lỗi, tôi đã tìm ra được vấn đề, tuy nhiên tôi vẫn chưa biết cách khắc phục vì tôi không đủ năng lực với VHDL.
Tôi đã chơi với VHDL vài ngày nay và tôi có thể không thể giải quyết vấn đề này.
Vấn đề
Tôi có một máy hiện sóng đo tín hiệu N64 vào FPGA và kênh khác kết nối với đầu ra của FPGA. Tôi cũng có chân kỹ thuật số ghi lại giá trị truy cập.
Về cơ bản, N64 gửi 9 bit dữ liệu, bao gồm một bit STOP. Bộ đếm đếm các bit dữ liệu nhận được và khi tôi đạt 9 bit, thì FPGA bắt đầu truyền qua UART.
Đây là hành vi đúng:
FPGA là dạng sóng màu xanh và dạng sóng màu cam là đầu vào của N64. Trong thời gian nhận, FPGA của tôi "vang" tín hiệu của đầu vào cho mục đích gỡ lỗi. Sau khi FPGA đếm đến 9, nó bắt đầu truyền dữ liệu qua UART. Lưu ý rằng các chân kỹ thuật số được đếm đến 9 và đầu ra FPGA trở nên THẤP ngay sau khi N64 kết thúc.
Đây là một ví dụ về một thất bại:
Lưu ý rằng bộ đếm bỏ qua bit 2 và 7! Các FPGA đến cuối cùng, chờ bit bắt đầu tiếp theo từ N64 nhưng không có gì. Vì vậy, thời gian ra và phục hồi.
Đây là VHDL cho mô đun nhận N64. Nó chứa bộ đếm: 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;
Vậy, có ý kiến gì không? Mẹo gỡ lỗi? Lời khuyên về mã hóa máy nhà nước hữu hạn?
Trong khi đó, tôi sẽ tiếp tục chơi với nó (cuối cùng tôi sẽ có nó)! Giúp tôi trao đổi Stack, bạn là hy vọng duy nhất của tôi!
Biên tập
Một khám phá thêm trong quá trình sửa lỗi của tôi, các trạng thái sẽ chuyển từ WaitForStart trở lại WaitForStop. Tôi đã cho mỗi trạng thái một giá trị với WaitForStart bằng '5' và WaitForStop bằng '4'. Xem hình ảnh dưới đây: