Hello,
I share my VHDL code for put number of 4 bit on the LCD-4bit of the virtex-6.
The input is a biggest numer of 32bit.
One state machine for display and another for transmission.
------------------------------------------------------------------------------------------
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 instantiating
entity Affichage_LCD_4bit is
port(
clk, reset : in std_logic;
DataIn32bit : in std_logic_vector(31 downto 0);
SF_D : out std_logic_vector(3 downto 0);
LCD_E, LCD_RS, LCD_RW, SF_CE0 : out std_logic;
LED : out std_logic_vector(7 downto 0)
);
end Affichage_LCD_4bit;
-----------------------------------------------------------------------
-- For a clock of 50MHz--
architecture behavior of Affichage_LCD_4bit is
type display_state is (function_set, s1, entry_set, s2, set_display, s3, clr_display, s4, pause, set_addr, s5, update, s6, done);
signal cur_state : display_state := function_set;
type tx_sequence is (high_setup, high_hold, oneus, low_setup, low_hold, fortyus, done);
signal tx_state : tx_sequence := done;
signal tx_byte : std_logic_vector(7 downto 0);
signal tx_init : std_logic := '0';
signal tx_rdy : std_logic := '0';
signal i : integer range 0 to 32 := 0;
signal i2 : integer range 0 to 2000 := 28;
signal i3 : integer range 0 to 82000 := 0;
begin
LED <= tx_byte; --for diagnostic purposes
SF_CE0 <= '1'; --disable intel strataflash
LCD_RW <= '0'; --write only
--when to transmit a command/data and when not to
with cur_state select
tx_init <= '1' when function_set | entry_set | set_display | clr_display | set_addr | update,
'0' when others;
with cur_state select
LCD_RS <= '1' when s6,
'0' when others;
with cur_state select
tx_byte <= "00101000" when s1, --28 hexa
"00000110" when s2, --06 hexa
"00001100" when s3, --0C hexa
"00000001" when s4, --01 hexa
"11000000" when s5, --C0h
"0011"&DataIn32bit(i+3 downto i) when s6, -- Chiffre de 0 à 9 en ASCII
--"00111000" when s6, -- Chiffre de 0 à 9 en ASCII
"00000000" when others;
-----------------------------------------------------------------------------
--main state machine
display: process(clk, reset)
begin
if(reset='1') then
cur_state <= function_set;
elsif(clk='1' and clk'event) then
case cur_state is
when function_set =>
cur_state <= s1;
when s1 =>
if(tx_rdy = '1') then
cur_state <= entry_set;
else
cur_state <= s1;
end if;
when entry_set =>
cur_state <= s2;
when s2 =>
if(tx_rdy = '1') then
cur_state <= set_display;
else
cur_state <= s2;
end if;
when set_display =>
cur_state <= s3;
when s3 =>
if(tx_rdy = '1') then
cur_state <= clr_display;
else
cur_state <= s3;
end if;
when clr_display =>
cur_state <= s4;
when s4 =>
i3 <= 0;
if(tx_rdy = '1') then
cur_state <= pause;
else
cur_state <= s4;
end if;
when pause =>
if(i3 = 82000) then
cur_state <= set_addr;
i3 <= 0;
else
cur_state <= pause;
i3 <= i3 + 1;
end if;
when set_addr =>
cur_state <= s5;
when s5 =>
if(tx_rdy = '1') then
cur_state <= update;
else
cur_state <= s5;
end if;
when update =>
cur_state <= s6;
when s6 =>
if(tx_rdy = '1') then
if (i > 0)then
i <= i-4;
cur_state <= update;
else
cur_state <= set_addr;
i <= 28;
end if;
else
cur_state <= s6;
end if;
when done =>
cur_state <= done;
end case;
end if;
end process display;
---------------------------------------------------------------------------
with tx_state select
tx_rdy <= '1' when done,
'0' when others;
with tx_state select
LCD_E <= '0' when high_setup | oneus | low_setup | fortyus | done,
'1' when high_hold | low_hold;
with tx_state select
SF_D <= tx_byte(7 downto 4) when high_setup | high_hold | oneus,
tx_byte(3 downto 0) when low_setup | low_hold | fortyus | done;
--------------------------------------------------------------------------
--specified by datasheet
transmit : process(clk, reset, tx_init)
begin
if(reset='1') then
tx_state <= done;
elsif(clk='1' and clk'event) then
case tx_state is
when high_setup => --40ns
if(i2 = 2) then
tx_state <= high_hold;
i2 <= 0;
else
tx_state <= high_setup;
i2 <= i2 + 1;
end if;
when high_hold => --230ns
if(i2 = 12) then
tx_state <= oneus;
i2 <= 0;
else
tx_state <= high_hold;
i2 <= i2 + 1;
end if;
when oneus =>
if(i2 = 50) then
tx_state <= low_setup;
i2 <= 0;
else
tx_state <= oneus;
i2 <= i2 + 1;
end if;
when low_setup =>
if(i2 = 2) then
tx_state <= low_hold;
i2 <= 0;
else
tx_state <= low_setup;
i2 <= i2 + 1;
end if;
when low_hold =>
if(i2 = 12) then
tx_state <= fortyus;
i2 <= 0;
else
tx_state <= low_hold;
i2 <= i2 + 1;
end if;
when fortyus =>
if(i2 = 2000) then
tx_state <= done;
i2 <= 0;
else
tx_state <= fortyus;
i2 <= i2 + 1;
end if;
when done =>
if(tx_init = '1') then
tx_state <= high_setup;
i2 <= 0;
else
tx_state <= done;
i2 <= 0;
end if;
end case;
end if;
end process transmit;
-----------------------------------------------------------------------
---------------------------------------------------------------------------
end behavior;
I share my VHDL code for put number of 4 bit on the LCD-4bit of the virtex-6.
The input is a biggest numer of 32bit.
One state machine for display and another for transmission.
------------------------------------------------------------------------------------------
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 instantiating
entity Affichage_LCD_4bit is
port(
clk, reset : in std_logic;
DataIn32bit : in std_logic_vector(31 downto 0);
SF_D : out std_logic_vector(3 downto 0);
LCD_E, LCD_RS, LCD_RW, SF_CE0 : out std_logic;
LED : out std_logic_vector(7 downto 0)
);
end Affichage_LCD_4bit;
-----------------------------------------------------------------------
-- For a clock of 50MHz--
architecture behavior of Affichage_LCD_4bit is
type display_state is (function_set, s1, entry_set, s2, set_display, s3, clr_display, s4, pause, set_addr, s5, update, s6, done);
signal cur_state : display_state := function_set;
type tx_sequence is (high_setup, high_hold, oneus, low_setup, low_hold, fortyus, done);
signal tx_state : tx_sequence := done;
signal tx_byte : std_logic_vector(7 downto 0);
signal tx_init : std_logic := '0';
signal tx_rdy : std_logic := '0';
signal i : integer range 0 to 32 := 0;
signal i2 : integer range 0 to 2000 := 28;
signal i3 : integer range 0 to 82000 := 0;
begin
LED <= tx_byte; --for diagnostic purposes
SF_CE0 <= '1'; --disable intel strataflash
LCD_RW <= '0'; --write only
--when to transmit a command/data and when not to
with cur_state select
tx_init <= '1' when function_set | entry_set | set_display | clr_display | set_addr | update,
'0' when others;
with cur_state select
LCD_RS <= '1' when s6,
'0' when others;
with cur_state select
tx_byte <= "00101000" when s1, --28 hexa
"00000110" when s2, --06 hexa
"00001100" when s3, --0C hexa
"00000001" when s4, --01 hexa
"11000000" when s5, --C0h
"0011"&DataIn32bit(i+3 downto i) when s6, -- Chiffre de 0 à 9 en ASCII
--"00111000" when s6, -- Chiffre de 0 à 9 en ASCII
"00000000" when others;
-----------------------------------------------------------------------------
--main state machine
display: process(clk, reset)
begin
if(reset='1') then
cur_state <= function_set;
elsif(clk='1' and clk'event) then
case cur_state is
when function_set =>
cur_state <= s1;
when s1 =>
if(tx_rdy = '1') then
cur_state <= entry_set;
else
cur_state <= s1;
end if;
when entry_set =>
cur_state <= s2;
when s2 =>
if(tx_rdy = '1') then
cur_state <= set_display;
else
cur_state <= s2;
end if;
when set_display =>
cur_state <= s3;
when s3 =>
if(tx_rdy = '1') then
cur_state <= clr_display;
else
cur_state <= s3;
end if;
when clr_display =>
cur_state <= s4;
when s4 =>
i3 <= 0;
if(tx_rdy = '1') then
cur_state <= pause;
else
cur_state <= s4;
end if;
when pause =>
if(i3 = 82000) then
cur_state <= set_addr;
i3 <= 0;
else
cur_state <= pause;
i3 <= i3 + 1;
end if;
when set_addr =>
cur_state <= s5;
when s5 =>
if(tx_rdy = '1') then
cur_state <= update;
else
cur_state <= s5;
end if;
when update =>
cur_state <= s6;
when s6 =>
if(tx_rdy = '1') then
if (i > 0)then
i <= i-4;
cur_state <= update;
else
cur_state <= set_addr;
i <= 28;
end if;
else
cur_state <= s6;
end if;
when done =>
cur_state <= done;
end case;
end if;
end process display;
---------------------------------------------------------------------------
with tx_state select
tx_rdy <= '1' when done,
'0' when others;
with tx_state select
LCD_E <= '0' when high_setup | oneus | low_setup | fortyus | done,
'1' when high_hold | low_hold;
with tx_state select
SF_D <= tx_byte(7 downto 4) when high_setup | high_hold | oneus,
tx_byte(3 downto 0) when low_setup | low_hold | fortyus | done;
--------------------------------------------------------------------------
--specified by datasheet
transmit : process(clk, reset, tx_init)
begin
if(reset='1') then
tx_state <= done;
elsif(clk='1' and clk'event) then
case tx_state is
when high_setup => --40ns
if(i2 = 2) then
tx_state <= high_hold;
i2 <= 0;
else
tx_state <= high_setup;
i2 <= i2 + 1;
end if;
when high_hold => --230ns
if(i2 = 12) then
tx_state <= oneus;
i2 <= 0;
else
tx_state <= high_hold;
i2 <= i2 + 1;
end if;
when oneus =>
if(i2 = 50) then
tx_state <= low_setup;
i2 <= 0;
else
tx_state <= oneus;
i2 <= i2 + 1;
end if;
when low_setup =>
if(i2 = 2) then
tx_state <= low_hold;
i2 <= 0;
else
tx_state <= low_setup;
i2 <= i2 + 1;
end if;
when low_hold =>
if(i2 = 12) then
tx_state <= fortyus;
i2 <= 0;
else
tx_state <= low_hold;
i2 <= i2 + 1;
end if;
when fortyus =>
if(i2 = 2000) then
tx_state <= done;
i2 <= 0;
else
tx_state <= fortyus;
i2 <= i2 + 1;
end if;
when done =>
if(tx_init = '1') then
tx_state <= high_setup;
i2 <= 0;
else
tx_state <= done;
i2 <= 0;
end if;
end case;
end if;
end process transmit;
-----------------------------------------------------------------------
---------------------------------------------------------------------------
end behavior;
Last edited: