用于 LCD 初始化的 VHDL 状态机
我正在尝试实现 Spartan 3AN LCD 的初始化。我对此很陌生,所以非常欢迎每一个建议。
我的代码如下:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:31:49 11/04/2011
-- Design Name:
-- Module Name: LCD - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity LCD is
Port ( clk : in STD_LOGIC;
LCD_DB : out STD_LOGIC_VECTOR (7 downto 0);
LCD_E : out STD_LOGIC;
LCD_RS : out STD_LOGIC;
LCD_RW : out STD_LOGIC);
end LCD;
architecture Behavioral of LCD is
-- CAUTION!!! When using 4-bit mode, FPGA must drive the LCD_DB<3:0> signals HIGH ( = '1' )
-- MAQUINA DE ESTADOS INICIALIZACION
type initialization_state is (A, B, C, D, E, F, G, H, I, done);
signal iCurrentState: initialization_state := A;
signal iNextState: initialization_state := A;
signal cycleCounter: integer := 0;
-- MAQUINA DE ESTADOS
begin
initializationLCD:
process (clk) begin
if (clk'event and clk = '1') then
case iCurrentState is
when A =>
if (cycleCounter = 750000) then
iCurrentState <= B;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when B =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000001";
if (cycleCounter = 50000) then
iCurrentState <= C;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when C =>
if (cycleCounter = 50000) then
iCurrentState <= D;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when D =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000010";
if (cycleCounter = 50000) then
iCurrentState <= E;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when E =>
if (cycleCounter = 50000) then
iCurrentState <= F;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when F =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000100";
if (cycleCounter = 12) then
iCurrentState <= G;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when G =>
if (cycleCounter = 50000) then
iCurrentState <= H;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when H =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00001000";
if (cycleCounter = 12) then
iCurrentState <= I;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when I =>
if (cycleCounter = 50000) then
iCurrentState <= done;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when others =>
iCurrentState <= done;
end case;
end if;
end process;
end Behavioral;
那么有2个问题:
这段代码可以吗?我知道我还有很多代码要做,但我只是想看看我是否做得很好,是什么让我想到问题 2
我用 ISim 进行模拟(顺便说一句,我使用的是 Xilinx 12.3)并且状态永远不会改变是A,我的代码缺少什么吗?或者也许我以错误的方式进行模拟,您能告诉我如何模拟它吗?
非常感谢 !
I'm trying to implement the initialization of a LCD of the Spartan 3AN. I'm very new to this so every advise is very welcome.
My code is as follows:
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:31:49 11/04/2011
-- Design Name:
-- Module Name: LCD - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity LCD is
Port ( clk : in STD_LOGIC;
LCD_DB : out STD_LOGIC_VECTOR (7 downto 0);
LCD_E : out STD_LOGIC;
LCD_RS : out STD_LOGIC;
LCD_RW : out STD_LOGIC);
end LCD;
architecture Behavioral of LCD is
-- CAUTION!!! When using 4-bit mode, FPGA must drive the LCD_DB<3:0> signals HIGH ( = '1' )
-- MAQUINA DE ESTADOS INICIALIZACION
type initialization_state is (A, B, C, D, E, F, G, H, I, done);
signal iCurrentState: initialization_state := A;
signal iNextState: initialization_state := A;
signal cycleCounter: integer := 0;
-- MAQUINA DE ESTADOS
begin
initializationLCD:
process (clk) begin
if (clk'event and clk = '1') then
case iCurrentState is
when A =>
if (cycleCounter = 750000) then
iCurrentState <= B;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when B =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000001";
if (cycleCounter = 50000) then
iCurrentState <= C;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when C =>
if (cycleCounter = 50000) then
iCurrentState <= D;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when D =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000010";
if (cycleCounter = 50000) then
iCurrentState <= E;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when E =>
if (cycleCounter = 50000) then
iCurrentState <= F;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when F =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00000100";
if (cycleCounter = 12) then
iCurrentState <= G;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when G =>
if (cycleCounter = 50000) then
iCurrentState <= H;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when H =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_DB <= "00001000";
if (cycleCounter = 12) then
iCurrentState <= I;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when I =>
if (cycleCounter = 50000) then
iCurrentState <= done;
cycleCounter <= 0;
else
cycleCounter <= cycleCounter + 1;
end if;
when others =>
iCurrentState <= done;
end case;
end if;
end process;
end Behavioral;
So there are 2 questions:
Is this code fine? I know I have much more code to do but I just want to see if I'm doing well, what takes me to question 2
I simulated with ISim (BTW I'm on Xilinx 12.3) and the state never changes always is A, is my code missing something? or maybe I'm simulating this the wrong way, can you tell me how to simulate it?
Thanks so much !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我看到的一些东西,有些是风格,有些不是:
std_logic_arith
和std_logic_unsigned
库 - 它们不是 IEEE 标准,并且确实会伤害初学者,因为它剥夺了 VHDL 提供的许多强类型。请改用numeric_std
。互联网搜索可以告诉您更多信息。rising_edge()
是时钟检查的首选,因为它还处理 L->H 状态(这在 FPGA/ASIC 中永远不会发生,但无论如何......iNextState
似乎未使用。LCD
输出。要么向 FSM 添加重置,要么需要重新考虑设置输出的方式(参见 Mealy 与 Moore 风格的 FSM)。initialization_state
的枚举,您可能希望为它们提供更有意义的名称和/或评论它们在每个状态下应该执行的操作。否则,快速查看似乎没问题。正如其他人指出的,750K 时钟是一个长的模拟,如果没有看到驱动时钟的测试平台代码,我们不知道它是否会工作。我建议将 750K 和所有其他值切换为常数,您可以将其更改为非常小的值以进行测试。
A few things I see, some are style, some are not:
std_logic_arith
andstd_logic_unsigned
libraries - they are not IEEE standard, and can really hurt beginners because it takes away a lot of the strong types the VHDL provides. Usenumeric_std
instead. An internet search can tell you more.rising_edge()
is preferred for clock checking because it also handles the L->H state (which in an FPGA/ASIC never happens, but anyway...)iNextState
which seems to be unused.LCD
outputs are set on startup. Either add a reset to the FSM, or you need to re-think the way the outputs are set (cf. Mealy vs Moore style FSMs).initialization_state
you might want to give them more meaningful names and/or comment on what they're supposed to be doing at each state.Otherwise, a quick look seems fine. As others noted, 750K clocks is a long simulation, and without seeing the testbench code that drives the clock, we have no idea if it will work. I'd recommend switching the 750K and all the others into constants that you can change to very small values for testing purposes.