SNES 컨트롤러로 ACT를 사용하기 위해 저렴한 FPGA (ep2c5t144 Altera Cyclone II 미니 보드)와 SNES를 인터페이스하려고합니다. 지금까지는 켜고 끄는 것처럼 보입니다 ... 현재 문제는 켜져있는 상태에서 약 1 초 동안 작동하지만 재설정 될 때까지는 멈추지 않는 것 같습니다.VHDL - SNES FPGA를 사용하는 컨트롤러 포트를 통한 인터페이스
로직 문제에 대한 코드를 오랫동안 보았으므로 FPGA 사용의 이상한 기이인지 궁금해하기 시작했지만 이미 정의되지 않은 상태에 대한 테스트를 시도했습니다. , 그리고 그 문제가 해결되지 않았습니다. 나는 아래의 SNES 코드와 문제점을 보여주는 값싼 로직 분석기의 출력을 게시 할 것이다. 경고, 코드는 꽤 지저분한 ... 특히 그것을 수정하려고 주위에 물건을 변화와 함께. 어떤 아이디어라도 많이 감사하겠습니다!
사전 도움을 주셔서 감사합니다. 로직 분석기에서
문제점 :
When a request works - State transitions occur as expected
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity snes_controller is
generic (
hp : integer := 300
);
port (
clk : in std_logic;
latch : in std_logic;
data : out std_logic := '0';
clock : in std_logic;
enable : in std_logic;
btn_B : in std_logic;
btn_Y : in std_logic;
btn_select : in std_logic;
btn_start : in std_logic;
btn_up : in std_logic;
btn_down : in std_logic;
btn_left : in std_logic;
btn_right : in std_logic;
btn_A : in std_logic;
btn_X : in std_logic;
btn_L : in std_logic;
btn_R : in std_logic;
helpA : out std_logic := '0';
helpB : out std_logic := '0';
helpC : out std_logic := '0';
helpD : out std_logic := '0';
helpE : out std_logic := '0'
);
end entity;
architecture Behav of snes_controller is
signal buttons : unsigned(16 downto 0) := "10000000000000000";
type state_type is (s_idle, s_latching_1, s_latching_2, s_working);
signal state : state_type := s_idle;
type cycle_type is (c_high, c_low);
signal cycle : cycle_type := c_high;
begin
process (clk)
variable i : integer range 0 to 16;
variable count : integer range 0 to hp;
begin
if(rising_edge(clk)) then
data <= not buttons(i);
if(state = s_latching_1 or state = s_latching_2 or state = s_working) then
if(count < hp) then
count := count+1;
else
count := 0;
if(state = s_latching_1) then
if(latch = '1') then
state <= s_latching_2;
buttons(0) <= btn_B;
buttons(1) <= btn_Y;
buttons(2) <= btn_select;
buttons(3) <= btn_start;
buttons(4) <= btn_up;
buttons(5) <= btn_down;
buttons(6) <= btn_left;
buttons(7) <= btn_right;
buttons(8) <= btn_A;
buttons(9) <= btn_X;
buttons(10) <= btn_L;
buttons(11) <= btn_R;
else
state <= s_idle;
end if;
elsif(state = s_latching_2) then
state <= s_working;
i := 0;
cycle <= c_high;
elsif(state = s_working) then
if(latch = '1') then
state <= s_idle;
helpD <= '1';
elsif(cycle = c_low) then
cycle <= c_high;
if(i < 16) then
i := i+1;
else
state <= s_idle;
helpD <= '0';
helpE <= '0';
end if;
else
cycle <= c_low;
end if;
end if;
end if;
elsif(state = s_idle) then
if(latch = '1') then
state <= s_latching_1;
count := 0;
i := 0;
end if;
else
helpE <= '1';
state <= s_idle;
count := 0;
i := 0;
end if;
end if;
end process;
process(state)
begin
if(state = s_idle) then
helpA <= '0';
helpB <= '0';
elsif(state = s_latching_1) then
helpA <= '1';
helpB <= '0';
elsif(state = s_latching_2) then
helpA <= '0';
helpB <= '1';
elsif(state = s_working) then
helpA <= '1';
helpB <= '1';
else
helpA <= clk;
helpB <= not clk;
end if;
if(cycle = c_low) then
helpC <= '0';
elsif(cycle = c_high) then
helpC <= '1';
end if;
end process;
end Behav;
귀하의 질문은 귀하가 귀하의 코드를 시뮬레이트하지 않았지만 벤치에서 디버깅하려고한다는 것을 나타냅니다. 테스트 벤치를 작성하고 코드를 먼저 시뮬레이트하는 것이 훨씬 좋은 생각입니다. 테스트 벤치에서 직접 자극을 생성하면 완벽하게 제어 할 수 있습니다. 시뮬레이션을 재현 할 수 있습니다. 디버깅을 돕기 위해 설계의 어느 곳에서나 쉽게 프로브 할 수 있습니다. 디자인의 동작을 자동으로 확인할 수 있습니다 (수동 검사도 오류가 발생하기 쉽습니다). Stack Overflow의 컨텍스트에서 테스트 벤치를 가지고 있었기 때문에 다른 사람이 실수를 재현하기 위해 시뮬레이션을 실행할 수있었습니다. –
@MatthewTaylor이 경우 테스트 벤치는 입력의 비동기를 정확하게 시뮬레이트하는 경우에만 작동합니다. 나는 Oron 항구에 의한 답이 맞을 것이라고 확신한다. 싱크로 나이저가 없으면 FSM이 잠길 수 있습니다. – JHBonarius