Я новичок в FPGA, и мне нужна помощь, если это возможно.
Я хотел бы реализовать схему последовательного управления с восемью светодиодами с помощью Quartus.
Я буду осуществлять внешнее управление через GPIO. Например, GPIO [1] будет сбросом, а GPIO [0] будет сигнал.
Когда я изменяю сигнал GPIO [0] (с «0» на «1» и наоборот), цепь должна переключиться на следующее из трех состояний, определяемых следующим образом:
A) Светодиод [0: 1] периодически мигает с периодом 2 секунд (горит в течение 1 секунды), а светодиод [3: 7] остается выключенным.
B) Светодиод [3: 4] периодически мигает в течение 6 секунд (оставаясь включенным в течение 3 секунд), в то время как Светодиод [0: 2] и [5: 7] остаются выключенными.
C) Светодиод [6: 7] периодически мигает с периодом 12 секунд (горит в течение 6 секунд), в то время как Светодиод [0: 5] остается выключенным.
Итак, я написал этот VHDL-код.
library IEEE;
use IEEE.std_logic_1164.all;
USE ieee.std_logic_arith.all ;
USE ieee.std_logic_unsigned.all ;
library altera_mf;
use altera_mf.altera_mf_components.all;
entity exone is
--//=======================================================
--// PORT declarations
--//=======================================================
PORT (
-- //////////// CLOCK //////////
CLOCK_50 : IN STD_LOGIC;
LED :OUT STD_LOGIC_VECTOR(7 downto 0);
GPIO_2 : INOUT STD_LOGIC_VECTOR(1 downto 0)
);
end exone ;
architecture rtl of exone is
signal led_s : STD_LOGIC_VECTOR(7 downto 0 );
signal inp : STD_LOGIC ;
signal state : integer := 3 ;
signal rst, clk : STD_LOGIC ;
signal cnt1: STD_LOGIC_VECTOR( 19 downto 0);
signal cnt2: STD_LOGIC_VECTOR( 19 downto 0);
begin
clk <= CLOCK_50 ;
inp <= GPIO_2(0);
rst <= GPIO_2(1);
process (clk, rst, inp) -- CYCLE
begin
if rst='1' then
cnt1<=(others=>'0');
cnt2<=(others=>'0');
led_s<=(others=>'0');
elsif (clk'event and clk = '1') then
cnt1 <= cnt1 + 1;
if (cnt1=1000000) then
cnt2 <= cnt2+1;
cnt1 <= (others=>'0');
end if;
if inp = '1' and state = 3 then
state <= 1 ;
if (cnt2=0) then
led_s <= "11000000";
elsif (cnt2=50) then
led_s <= "00000000";
elsif (cnt2=100) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if ;
elsif inp = '0' then
if (cnt2=0) then
led_s <= "00011000";
elsif (cnt2=150) then
led_s <= "00000000";
elsif (cnt2=300) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if;
else
state <= 3 ;
if (cnt2=0) then
led_s <= "00000011";
elsif (cnt2=300) then
led_s <= "00000000";
elsif (cnt2=600) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if ;
end if;
end if;
end process ;
LED <= led_s ;
END rtl ;
Это самое простое решение, которое я мог себе представить. Дело в том, что часть
if inp = '1' and state = 3 then
state <= 1 ;
if (cnt2=0) then
led_s <= "11000000";
elsif (cnt2=50) then
led_s <= "00000000";
elsif (cnt2=100) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if ;
elsif inp = '0' then
if (cnt2=0) then
led_s <= "00011000";
elsif (cnt2=150) then
led_s <= "00000000";
elsif (cnt2=300) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if;
else
state <= 3 ;
if (cnt2=0) then
led_s <= "00000011";
elsif (cnt2=300) then
led_s <= "00000000";
elsif (cnt2=600) then
cnt2<=(others=>'0');
else
led_s <= led_s;
end if ;
Кажется, не так хорошо работает. Я пытался найти то, что не так в течение многих часов, но все равно не повезло.
Итак, мой вопрос:
Есть ли лучшие способы проверить изменения inp , а также пометить состояния?
Я считаю, что код, который я написал, является мусором и слишком велик для того, чего я хочу достичь.