我正在为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”位并且“RS”设置为低,而YLED(FPGA上的内部LED)打开(它在关闭时)所有其他国家)。真正奇怪的是(这需要很长时间才能找到)是如果我从
更改EntryMode位"00000110"
到
"00000100"
它成功通过状态并输出正确的位。对于其他变化也可能是这样,但我真的不想测试太多。任何帮助或提示将受到高度赞赏!
更新: 在流行的请求之后,我明确地将YLED置于所有早期状态的低位,并切换(返回)DB作为信号。结果是我根本无法达到后来的状态,或者至少留在它们中(即使在摆弄魔术位时,我认为这是一件好事)因为YLED在启动后只能保持一秒钟FPGA。
答案 0 :(得分:0)
有一个完整的例子,包括理论,状态机和VHDL代码,在第292-290页中,有关状态机器在硬件:理论和设计......&#34;,由Volnei Pedroni,麻省理工学院按,2013年12月。