0

我正在为 FPGA 编写 LCD 控制器,但遇到了一个非常奇怪的问题(至少对我而言)。应该将所需位输出到屏幕的状态机行为不端,并使输出引脚“卡”在旧状态,而它显然已经转移到后来的状态。

下面是状态机的相关部分:

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”位并且“RSs”设置为低,而 YLED(FPGA 上的内部 LED)打开(它在所有其他状态下都关闭)。真正奇怪的是(这需要很长时间才能找到)如果我将 EntryMode 位从

"00000110"

"00000100"

它成功通过状态并输出正确的位。其他更改也可能如此,但我真的不想进行太多测试。任何帮助或提示将不胜感激!

更新:在受欢迎的请求之后,我在所有早期状态中明确地将 YLED 设置为低电平,并切换(返回)DB 作为信号。结果是我根本无法达到后面的状态,或者至少停留在它们中(即使在摆弄魔法位时,我认为这是一件好事),因为 YLED 在启动后只停留一瞬间FPGA。

4

1 回答 1

0

有一个完整的示例,包括理论、状态机和 VHDL 代码,位于“硬件中的有限状态机:理论与设计...”的第 279-290 页,作者 Volnei Pedroni,麻省理工学院出版社,2013 年 12 月。

于 2015-12-11T21:43:34.087 回答