Выходные контакты FPGA выводят неправильное состояние
Я пишу контроллер LCD для FPGA, и у меня действительно странная (по крайней мере для меня) проблема. Конечный автомат, который должен выводить необходимые биты на экран, ведет себя неправильно и возвращает выходные контакты в "старое" состояние, в то время как он явно перешел в более поздние состояния.
Вот соответствующие части состояния машины:
PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO clk_divider; -- clk_divider is a generic positive.
BEGIN
IF (clk'EVENT AND clk = '1') THEN
count := count + 1;
IF (count = clk_divider) THEN
EAUX <= NOT EAUX;
count := 0;
END IF;
END IF;
END PROCESS;
....
PROCESS (EAUX)
BEGIN
IF (EAUX'EVENT AND EAUX = '1') THEN
pr_state <= nx_state;
END IF;
END PROCESS;
....
PROCESS (pr_state)
BEGIN
CASE pr_state IS
WHEN EntryMode => --6=1,7=Cursor increment/decrement, 8=Display shift on/off
RSs <='0';
DB(7 DOWNTO 0) := "00000110";
nx_state <= WriteData;
WHEN WriteData => --Write data to LCD:
RSs <='1';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
i := i + 1;
IF (i < chars) THEN
nx_state <= WriteData;
ELSE
i := 0;
nx_state <= ReturnHome;
END IF;
WHEN ReturnHome => --Return cursor
RSs <='0';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
nx_state <= WriteData;
END CASE;
END PROCESS;
Где биты в переменной DB назначены сигналу DBOUT:
DBOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) -- In entity
SHARED VARIABLE DB : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; -- In Architecture
DBOUT <= DB;
DBOUT выводится (в.ucf-файл) как:
NET "DBOUT(0)" LOC = P10;
NET "DBOUT(1)" LOC = P11;
NET "DBOUT(2)" LOC = P12;
NET "DBOUT(3)" LOC = P13;
NET "DBOUT(4)" LOC = P15;
NET "DBOUT(5)" LOC = P16;
NET "DBOUT(6)" LOC = P18;
NET "DBOUT(7)" LOC = P19;
Используя осциллограф на выводах, я вижу, что он явно застрял, выводя биты "EntryMode" и "RS" установлен на низкий уровень, в то время как YLED (внутренний светодиод на ПЛИС) включен (он выключен во всех других состояниях).). Действительно странная вещь (а это заняло очень много времени) состоит в том, что если я изменю биты EntryMode из
"00000110"
в
"00000100"
он успешно передает состояние и выводит правильные биты. Это может быть верно и для других изменений, но мне не очень хочется тестировать это слишком много. Любая помощь или советы будут высоко оценены!
ОБНОВЛЕНИЕ: после популярного запроса я явно установил YLED на низкое значение во всех ранних состояниях и переключил (назад) БД, чтобы он стал сигналом. В результате я вообще не могу достичь более поздних состояний или, по крайней мере, остаться в них (даже когда играю с магическими битами, что, я думаю, хорошо), поскольку YLED остается включенным только на долю секунды после загрузки ПЛИС.
1 ответ
Полный пример, включая теорию, конечный автомат и код VHDL, приведен на страницах 279-290 книги "Конечные автоматы в аппаратном обеспечении: теория и проектирование...", Волней Педрони, MIT Press, декабрь 2013 г.