พื้นหลัง
นี่เป็นโครงการส่วนบุคคล มันเกี่ยวกับการเชื่อมต่อ FPGA กับ N64 ค่าไบต์ที่ FPGA ได้รับจะถูกส่งผ่าน UART ไปยังคอมพิวเตอร์ของฉัน มันใช้งานได้ดีจริง ๆ ! ในบางครั้งน่าเสียดายที่อุปกรณ์จะล้มเหลวจากนั้นกู้คืน ผ่านการดีบักฉันจัดการเพื่อค้นหาปัญหา แต่ฉันนิ่งงันวิธีการแก้ไขเพราะฉันไม่สามารถ VHDL
ฉันเล่นกับ VHDL มาสองสามวันแล้วและฉันอาจไม่สามารถแก้ไขปัญหานี้ได้
ปัญหา
ฉันมีออสซิลโลสโคปวัดสัญญาณ N64 ลงใน FPGA และช่องอื่น ๆ เชื่อมต่อกับเอาท์พุทของ FPGA ฉันยังมีพินดิจิตอลที่บันทึกค่าตัวนับ
โดยพื้นฐานแล้ว N64 จะส่งบิตข้อมูล 9 ชุดรวมถึงบิต STOP ตัวนับนับจำนวนข้อมูลที่ได้รับและเมื่อฉันไปถึง 9 บิต FPGA จะเริ่มส่งสัญญาณผ่าน UART
นี่คือพฤติกรรมที่ถูกต้อง:
FPGA เป็นรูปคลื่นสีฟ้าและรูปคลื่นสีส้มเป็นอินพุตของ N64 ในช่วงระยะเวลาของการรับสัญญาณ FPGA ของฉัน "echos" เป็นสัญญาณของอินพุตสำหรับการดีบัก หลังจาก FPGA นับเป็น 9 จะเริ่มส่งข้อมูลผ่าน UART โปรดสังเกตว่าหมุดดิจิตอลนับเป็น 9 และเอาต์พุต FPGA จะเป็น LOW ทันทีหลังจาก N64 เสร็จสิ้น
นี่คือตัวอย่างของความล้มเหลว:
โปรดสังเกตว่าตัวนับข้ามบิต 2 และ 7! FPGA ถึงจุดสิ้นสุดรอการเริ่มต้นบิตถัดไปจาก N64 แต่ไม่มีอะไร ดังนั้น FPGA จึงหมดเวลาและกู้คืน
นี่คือ VHDL สำหรับโมดูลรับ N64 มันมีตัวนับ: 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;
ดังนั้นความคิดใด ๆ เคล็ดลับการแก้จุดบกพร่อง? เคล็ดลับในการเข้ารหัส จำกัด เครื่องจักรของรัฐ?
ในระหว่างนี้ฉันจะเล่นต่อไปเรื่อย ๆ (ในที่สุดฉันจะได้) ช่วยฉันแลกเปลี่ยน Stack คุณเป็นความหวังเดียวของฉัน!
แก้ไข
การค้นพบเพิ่มเติมในการแก้ไขจุดบกพร่องของฉันรัฐจะกระโดดจาก waitForStart กลับไปที่ waitForStop ฉันให้ค่าแต่ละรัฐด้วย waitForStart เท่ากับ '5' และ waitForStop เท่ากับ '4' ดูภาพด้านล่าง: