Professional Documents
Culture Documents
****}
--{ FileName............: Lcd_controller_main.vhd
--{ Project.............: FPGA
--{-----------------------------------------------------------------------------}
--{
--{ Notes: has some design flaws
--{
--{
--{ Physical 'Testbench' for LCD_CONTROLLER
--{ Output signals on prototyping board:
--{
J4-6 260 ns cycle signal
--{
J4-8 1 ms cycle signal
(1 kHz)
--{
J4-10 0.2 ms cycle signal (5 kHz)
--{-----------------------------------------------------------------------------}
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--{-----------------------------------------------------------------------------}
--{
Xilinx primitives libraries used
--{-----------------------------------------------------------------------------}
library UNISIM;
use UNISIM.VComponents.all;
entity LCD_CONTROLLER_MAIN is
port(
CLK_SMT
: in std_logic;
PUSH_RESET: in
PUSH
: in
std_logic;
std_logic_vector(2 downto 1);
LCD_DB
LCD_E
LCD_RS
PIEZO
: out std_logic;
CLK_TIMING_IN_NS : natural;
cycle time (in ns)
CLK_TIMING_OUT_NS: natural
cycle time (in ns)
);
port(
CLK_IN : in std_logic;
CLK_OUT: out std_logic
);
end component;
-- Input clock
-- Input clock
-- Input clock
-- Output clock
component LCD_CONTROLLER is
port(
RST
: in std_logic;
CLK
: in std_logic;
ns cycle time)
START
: in std_logic;
RS
: in std_logic;
select
DATA
: in std_logic_vector (7 downto 0);
E_PORT
: out std_logic;
port
RS_PORT
: out std_logic;
select port
DATA_PORT : out std_logic_vector (7 downto 0);
READY
: out std_logic
);
end component;
-- Reset
-- Clock (>= 250
-- Start flag
-- Register
-- Data
-- Enable signal
-- Register
-- Data port
-- Ready flag
ttextlength
tline
tinitlength
tinitdata
is
is
is
is
range 16 downto 0;
array(ttextlength) of std_logic_vector (7 downto 0);
range 8 downto 0;
array(tinitlength) of std_logic_vector (7 downto 0);
constant init_data
: tinitdata := (x"38",
x"0E", x"01", x"80", x"00");
constant line1
: tline
:= (x"20",
x"4C", x"49", x"53",
x"4D",
x"20", x"20", x"20", x"00");
constant line2
: tline
:= (x"45",
x"65", x"65", x"72",
x"69",
x"2E", x"56", x"2E", x"00");
constant line3
: tline
:= (x"42",
x"6E", x"20", x"31",
x"20",
x"73", x"65", x"64", x"00");
constant line4
: tline
:= (x"42",
x"6E", x"20", x"32",
x"20",
x"73", x"65", x"64", x"00");
signal state
main state amchine
signal text_index
: tstate_main;
-- Current state
: ttextlength;
-- Index counter
signal init_index
: tinitlength;
-- Index counter
signal clk
: std_logic;
master clock
signal rst
: std_logic;
signal start
: std_logic;
for writing to LCD
signal ready
: std_logic;
(ready for writing to LCD)
signal rs
: std_logic;
LCD
signal data
: std_logic_vector (7 downto 0);
to LCD
-- Buffered
-- LCD clock
-- Timing signal
signal push1_p
PUSH1 button
signal push1_d
PUSH1 button
signal push2_p
PUSH2 button
signal push2_d
PUSH2 button
-- Debouncing
: std_logic;
-- Debounced
-- Debouncing
: std_logic;
-- Debounced
begin
CLK_250NS_I : CLOCK_DIV
generic map (
CLK_TIMING_IN_NS => 13,
CLK_TIMING_OUT_NS => 260
)
port map (
CLK_IN => clk,
CLK_OUT => clk_out
)
;
CLK_1MS_I : CLOCK_DIV
generic map (
CLK_TIMING_IN_NS => 13,
CLK_TIMING_OUT_NS => 1000000
)
port map (
CLK_IN => clk,
CLK_OUT => clk_1ms
)
;
CLK_02MS_I : CLOCK_DIV
generic map (
CLK_TIMING_IN_NS => 13,
CLK_TIMING_OUT_NS => 200000
)
port map (
CLK_IN => clk,
CLK_OUT => clk_02ms
-- Reset signal
-- Start flag
-- Ready flag
-- RS data for
-- Data to write
-- Timing signal
)
;
UUT : LCD_CONTROLLER
port map (
RST
=> rst,
CLK
=> clk_out,
START
=> start,
RS
=> rs,
DATA
=> data,
E_PORT
=> LCD_E,
RS_PORT
=> LCD_RS,
DATA_PORT => LCD_DB,
READY
=> ready
)
;
--{-----------------------------------------------------------------------------}
--{ Descript: Clock buffering
--{-----------------------------------------------------------------------------}
BUFGDLL_INST1: BUFGDLL
port map (
I => CLK_SMT,
O => clk
)
;
--{-----------------------------------------------------------------------------}
--{ Params : <clk_1ms> Clock
--{ Descript: Debounce the input. This is done by checking the
--{
input for a number of cycles and when all of them are
--{
equal the output changes.
--{-----------------------------------------------------------------------------}
process (clk_1ms)
begin
if (rising_edge(clk_1ms)) then
push1_p(0) <= not(PUSH(1));
push1_p(1) <= push1_p(0);
push1_p(2) <= push1_p(1);
push1_p(3) <= push1_p(2);
if (push1_p = "1111") then
push1_d <= '1';
else
if (push1_p = "0000") then
push1_d <= '0';
end if;
end if;
end if;
end process;
process (clk_1ms)
begin
if (rising_edge(clk_1ms)) then
push2_p(0) <= not(PUSH(2));
Start LCD
Start LCD
Start LCD
state
<= press4;
text_index <= ttextlength'HIGH;
end if;
when press4 => if (ready = '1') then
-- Wait for LCD
ready to accept command
data
<= line4(text_index);
text_index <= text_index - 1;
start
<= '1';
-- Start LCD
sequence
rs
<= '1';
state
<= press5;
end if;
when press5 => if (ready = '0') then
-- Wait for LCD
sequence started
start <= '0';
-- Make sure
sequence not automatically restarted
if (text_index = 0) then
-- Did we just
send the last text line 1 data?
state <= press6;
else
state <= press4;
end if;
end if;
when press6 => if (push2_d = '1') then
state <= press6;
else
state <= wait1;
end if;
when others
end case;
end if;
end if;
end process;
rst <= not
P1_LIO_A09
P1_LIO_A13
P1_LIO_A15
PUSH_RESET;
<= clk_out;
<= clk_1ms;
<= clk_02ms;