--================================================================
-- LCD state machine controlling the DisplayTech 162B controller
--================================================================
Library IEEE;
use ieee.std_logic_1164.all;
entity LCD_test is
generic(
clk_e : integer := 100e6/1000 --- Amount of bits for the enable signal
);
port(
CLK100MHZ, reset : in std_logic;
RS,RW : out std_logic; -- RS: register select RW: Register Write
E : buffer std_logic; -- Enable signal for the LCD
data : out std_logic_vector(7 downto 0) -- Data sent to the LCD
);
end entity;
architecture arch of LCD_test is
type state is (functionset1, functionset2,functionset3,functionset4, display_off, clear, entry_mode,display_on, write_data, returnhome);
signal old_state, new_state: state;
begin
RW <= '0'; -- Read: 1, Write: 0
--=================================================
-- Generating a 500Hz enable signal (E)
--=================================================
process(CLK100MHZ,reset)
variable cnt : integer;
begin
if reset = '1' then
cnt := 0;
elsif rising_edge(CLK100MHZ) then
cnt := cnt + 1;
E <= '0';
if cnt = clk_e then
cnt := 0;
E <= '1'; --- Creates a clocksignal
end if; -- Creation of E
end if; -- Reset
end process;
--======================================================
-- State register controlling the transisions
--=====================================================
process(CLK100MHZ, reset)
begin
if reset = '1' then
old_state <= functionset1;
elsif E = '1' then --- Find alternative to rising_edge due to mitigate the risk of asycnhronous designs during synthesis
old_state <= new_state;
end if;
end process;
--==================================================
-- State machine controlling the display
--==================================================
process(old_state)
begin
case old_state is
when functionset1 =>
RS <= '0';
data <= "00111000"; -- 8-bit interface, 1-line, 5x8 Font
new_state <= functionset2;
when functionset2 =>
RS <= '0';
data <= "00111000"; -- 8-bit interface, 1-line, 5x8 Font
new_state <= functionset3;
when functionset3 =>
RS <= '0';
data <= "00111000"; -- 8-bit interface, 1-line, 5x8 Font
new_state <= functionset4;
when functionset4 =>
RS <= '0';
data <= "00111000"; -- 8-bit interface, 1-line, 5x8 Font
new_state <= display_off;
when display_off =>
RS <= '0';
data <= "00001000"; -- Display OFF, Cursor OFF, Blink OFF
new_state <= clear;
when clear =>
RS <= '0';
data <= "00000001"; -- Clear Diplay
new_state <= entry_mode;
when entry_mode =>
RS <= '0';
data <= "00000111"; -- Increment and shift the display to the right
new_state <= display_on;
when display_on =>
RS <= '0';
data <= "00001100"; -- Display ON, Cursor OFF, Blink OFF
new_state <= write_data;
when write_data =>
RS <= '0';
data <= "10000101"; -- Letter X
new_state <= returnhome;
when returnhome =>
RS <= '0';
data <= "10000000";-- Returns to display again
new_state <= write_data;
end case;
end process;
end arch;
I was supposed to be synchronous as the FSM is a two process FSM design but they removed the rising_edge(CLK100MHZ) from the synchronous part of the FSM, which they didn't do a good job of explaining why they did that and the comment one the E ='1' line indicates they don't understand the difference between asynchronous and synchronous design.Your"state machine controlling the display" is completely asynchronous. You need to make the process sensitive to clock.
I noticed this too. The OP's code makes 'E' active only when cnt equals clk_e and disables it otherwise.The asynchronous state machine will step through more than one state per E pulse.
The timing of the enable signal is inappropriate to drive a LCD display. You have 10 ns pulse width, but at least several 100 ns are required. Review the display data sheet.
process(CLK100MHZ,reset)
variable cnt : integer;
begin
if reset = '1' then
cnt := 0;
elsif rising_edge(CLK100MHZ) then
If (cnt = clk_e-1) then
cnt := 0;
else
cnt := cnt + 1;
end if;
if (cnt = clk_e-1) or (cnt < E_width-1) then --where E_width is the number of clk100MHZ pulses that makes up the duration that 'E' needs to be high, example if E_width = 5 then E will be high for 50ns with your 10ns CLK100MHZ clock.
E <= '1'; -- makes E active
else
E <= '0'; -- makes E inactive
end if; -- Creation of E
end if; -- Reset
end process;
Yes it's supposed to be synchronous.I was supposed to be synchronous as the FSM is a two process FSM design but they removed the rising_edge(CLK100MHZ) from the synchronous part of the FSM, which they didn't do a good job of explaining why they did that and the comment one the E ='1' line indicates they don't understand the difference between asynchronous and synchronous design.
--================================================================
-- LCD state machine controlling the LCD controller
--================================================================
Library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity LCD is
port(
CLK100MHZ, reset : in std_logic;
RS,RW : out std_logic; -- RS: register select RW: Register Write
E : out std_logic; -- Enable signal for the LCD
data : out std_logic_vector(7 downto 0) -- Data sent to the LCD
);
end entity;
architecture arch of LCD is
type state is (initialization, write_data, returnhome, enable);
signal old_state, new_state: state;
signal delay : std_logic_vector(20 downto 0); --- counter handling the delay
constant delay_15ms : integer := 1500000; --- Delay of power on
constant delay_4ms : integer := 410000; --- Delay of first function set cmd
constant delay_100us : integer := 10000; --- Delay of second function set command
constant delay_5000ns : integer := 500; --- Enable cycle time
constant delay_1000ns : integer := 100; --- Enable pulse width
constant delay_200ns : integer := 20; --- Set up time for E
signal commands : std_logic_vector(2 downto 0); --- Steps through the initialization commands
begin
process(CLK100MHZ, reset)
begin
if reset = '1' then
delay <= (others => '0');
commands <= (others => '0');
E <= '1';
RS <= '0';
RW <= '0';
data <= (others => '0');
old_state <= initialization;
new_state <= initialization;
elsif rising_edge(CLK100MHZ) then
delay <= delay + 1;
E <= '1';
case old_state is
when initialization =>
RS <= '0';
RW <= '0';
if(delay >= delay_15ms) AND (commands = "000") then --- Power up delay
delay <= (others => '0');
commands <= commands + 1;
data <= "00110000"; -- Function set command
old_state <= enable;
new_state <= initialization;
elsif (delay >= delay_4ms) AND(commands = "001") then
delay <= (others => '0');
commands <= commands + 1;
data <= "00110000"; -- Function set command
old_state <= enable;
new_state <= initialization;
elsif (delay >= delay_100us) AND(commands = "010") then
delay <= (others => '0');
commands <= commands + 1;
data <= "00110000"; -- Function set command
old_state <= enable;
new_state <= initialization;
elsif (commands = "011") then --- function set for interface
delay <= (others => '0');
commands <= commands + 1;
data <= "00110100"; -- 8-bit interface, 1-line, 5x10 Font
old_state <= enable;
new_state <= initialization;
elsif (commands = "100") then --- Display off
delay <= (others => '0');
commands <= commands + 1;
data <= "00001000"; -- Display OFF command
old_state <= enable;
new_state <= initialization;
elsif (commands = "101") then --- Clear Display
delay <= (others => '0');
commands <= commands + 1;
data <= "00000001"; -- 8-bit interface, 1-line, 5x8 Font
old_state <= enable;
new_state <= initialization;
elsif (commands = "110") then --- Entry Mode Set
delay <= (others => '0');
commands <= commands + 1;
data <= "00000111"; -- Increment and shift to the left
old_state <= enable;
new_state <= initialization;
elsif (commands = "111") then --- Display ON
delay <= (others => '0');
commands <= commands + 1;
data <= "00001111"; -- Display ON, Cursor ON, Blink ON
old_state <= enable;
new_state <= write_data;
end if;
when write_data =>
delay <= (others => '0');
RW <= '0';
RS <= '1';
data <= "10000101"; -- Letter X
old_state <= enable;
new_state <= returnhome;
when returnhome =>
delay <= (others => '0');
RW <= '0';
RS <= '0';
data <= "00000010";-- Returns to address "00H" to display again
old_state <= enable;
new_state <= write_data;
when enable =>
if delay < delay_5000ns then
if (delay >= delay_200ns) AND (delay <= delay_1000ns) then
E <= '0';
end if;
else
delay <= (others => '0');
RW <= '0';
old_state <= new_state;
end if;
end case;
end if;
end process;
end arch;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?