------------------------------------------------------------------------------- -- Title : LCD Driver for the clock -- Project : ------------------------------------------------------------------------------- -- File : lcddriver.vhd -- Author : -- Company : -- Created : 2008-10-07 -- Last update: 2008-10-08 -- Platform : -- Standard : VHDL'87 ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- -- Copyright (c) 2008 ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2008-10-07 1.0 Fador Created ------------------------------------------------------------------------------- library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; entity lcddriver is generic ( data_width_g : integer := 8; clk_rate_g : integer := 50000000 ); port ( lcddata_r : inout std_logic_vector(data_width_g-1 downto 0); -- lcddata lcdE_out_r : out std_logic; -- Enable lcdRW_out_r : out std_logic; -- read/write lcdRS_out_r : out std_logic; -- RS lcdready_r : out std_logic; -- is block ready clk : in std_logic; rst_n : in std_logic; data_in : in std_logic_vector(data_width_g-1 downto 0); -- e_in_r : in std_logic; rw_in : in std_logic; rs_in : in std_logic; data_ready_in : in std_logic); end lcddriver; architecture rtl of lcddriver is signal lcdready : std_logic; signal slow_clk_r : integer; signal clk_limit_r : integer; type statetype is (idle,init, datain, finish, initbusy, waitbusy, endbusy); signal state : statetype; begin -- rtl main: process (clk, rst_n) begin -- process main if rst_n = '0' then -- asynchronous reset (active low) lcdready <= '1'; -- LCD is ready when we start lcdready_r <= '1'; state <= idle; slow_clk_r <= 0; lcddata_r <= "00000000"; clk_limit_r <= clk_rate_g/1000; -- every 1ms lcdRS_out_r <= '0'; lcdRW_out_r <= '0'; elsif clk'event and clk = '1' then -- rising clock edge slow_clk_r <= slow_clk_r +1; if slow_clk_r = clk_limit_r then slow_clk_r <= 0; case state is when idle => if data_ready_in = '1' then state <= init; lcdready <= '0'; end if; when init => lcdE_out_r <= '1'; state <= datain; when datain => lcddata_r <= data_in; lcdRS_out_r <= rs_in; lcdRW_out_r <= rw_in; state <= finish; when finish => lcdE_out_r <= '0'; lcddata_r <= "ZZZZZZZZ"; state <= initbusy; when initbusy => lcdE_out_r <= '1'; lcdRW_out_r <= '1'; lcdRS_out_r <= '0'; state <= waitbusy; -- wait until LCD is ready when waitbusy => if lcddata_r(7) = '0' then state <= endbusy; lcdRW_out_r <= '0'; else lcdE_out_r <= '0'; state <= initbusy; end if; when endbusy => if data_ready_in = '0' then lcdready <= '1'; state <= idle; end if; end case; end if; -- Slow clock end if; lcdready_r <= lcdready; end process main; end rtl;