Beruflich Dokumente
Kultur Dokumente
Introduction
The LCD (Liquid Crystal Display) in question is included with the Spartan-3E Starter Board Kit
sold by both Digilent. LCD’s in general offer a cheap and convenient way to deliver information
from electronic devices. Indeed, it is that very convenience that has led to the LCD’s near
ubiquity in today’s electronic world.
A detailed description of the operation of an LCD is far beyond the scope of this document;
however, it is yet worthwhile to understand the general operation of an LCD device. Essentially,
what a traditional black & white LCD does is to selectively toggle what are termed pixels in the
display to allow or block light from passing. These pixels are abstractly considered to be the
points that compose the display; of course, in our particular case the pixels themselves are clearly
visible and are perfect squares. In any case, to generate something like the letter ‘I’, the LCD
would merely toggle the pixels in a straight vertical line.
This lab will assume the completion or understanding of the material in labs 1, 2, 3 and 5. There
are two fundamental sections for this lab. These consist of:
1. The implementation of hardware to control the onboard LCD.
2. A simulation of the hardware to verify functionality.
The enterprising reader may idly consider the fact that it is easier to simply program the board
than verify the hardware design in software first. Unfortunately, that is only true of very small
projects, as projects become larger, so do the problems with no seeming source or solution.
Repeatedly programming the board in trial and error fashion will only waste time.
LCD Controller: Sitronix ST7066U
Relevant Pins
There are two possible interfaces to the LCD controller, one 8 bits wide and another 4 bits wide.
The designers of the Spartan-3E chose to use the four bit interface and share it with the onboard
Intel StrataFlash storage device to minimize pin count. This will slightly complicate the
procedure of initializing and writing to the display. The following pin definitions will be used in
the “ucf” constraints file (manual pg. 43). LCD_RW will be pulled low, as this application will
not be reading data from the display. Driving LCD_E low causes the LCD to ignore all inputs. A
high LCD_RS specifies a data write operation, whereas a low LCD_RS specifies a command.
Note that the period of the 50MHz onboard clock is 20ns. The time between corresponding
nibbles is 1us, which is equivalent to 50 clock cycles. The time between successive commands is
40us, which corresponds to 2000 clock cycles. The delay after a Clear Display command is
1.64ms, rather than the usual 40us and corresponds to 82000 clock cycles. Setup time (time for
the outputs to stabilize) is 40ns, which is 2 clock cycles, the hold time (time to assert the LCD_E
pin) is 230ns, which translates to roughly 12 clock cycles, and the fall time (time to allow the
outputs to stabilize) is 10ns, which translates to roughly 1 clock cycle.
The following is the LCD command set.
Initialization
1. Wait 15 ms or longer, although the display is generally ready when the FPGA finishes configuration. The
15 ms interval is 750,000 clock cycles at 50 MHz.
Configuration
1. Issue a Function Set command, 0x28, to configure the display for operation on the
Spartan-3E Starter Kit board.
2. Issue an Entry Mode Set command, 0x06, to set the display to automatically increment
the address pointer.
3. Issue a Display On/Off command, 0x0C, to turn the display on and disables the cursor
and blinking.
4. Finally, issue a Clear Display command. Allow at least 1.64 ms (82,000 clock cycles)
after issuing this command.
The third and last step involves the actual process of writing data to the DD-RAM.
Display
Objective
To use the S3E Starter Board’s LCD to display “FPGA”, and learn more about digital logic
design in the process.
Proces s
Implementation
This project requires 3 state machines. One for the power on initialization sequence, one to
transmit commands and data to the LCD and lastly, one to start the power on initialization
sequence, then configure and write to the LCD.
Note that one will have to make sure that the state machines are synchronized properly, that is,
that main state machine remains in the “INIT” state until the initialization state machine is in the
“DONE” state, and that subsequent command states not change until the data is fully transferred
by the transmission state machine.
Figure 4 shows the main state machine that controls the initialization sequence and the
transmission state machines. Note that each and every command implicitly requires the
transmission state machine.
Figure 5 is the initialization sequence state machine. It is only activated when the main state
machine asserts “init”. Make certain that there is a way to notify the main state machine that the
initialization is over and the four bit interface is established.
This is the last state machine, and potentially the most troublesome. The main state machine will
set the values of LCD_RS and the values of the high and low nibbles of an LCD command. This
state machine will simply verify the strict timing constraints given above for an LCD command,
otherwise it would be totally unnecessary. Again, a command will only be transferred once
tx_init is asserted by the main state machine.
Figure 7 shows a simulation of a properly working implementation of LCD controller hardware.
This simulation demonstrates the way the disparate state machines work together. As the
initialization sequence finishes, the command states of the main state machine begin.
NOTE: ISE Simulator may cause a memory error due to lack of recources. The waveforms
shown are from MODELSIM XE
The following simulation waveforms show exactly what happens with all three state machines
when the initialization sequence ends, and the states of the function_set command.
--Written by Rahul Vora
--for the University of New Mexico
--rhlvora@gmail.com
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity lcd is
port(
clk, reset : in bit;
SF_D : out bit_vector(3 downto 0);
LCD_E, LCD_RS, LCD_RW, SF_CE0 : out bit;
LED : out bit_vector(7 downto 0) );
end lcd;
type init_sequence is (idle, fifteenms, one, two, three, four, five, six, seven, eight, done);
signal init_state : init_sequence := idle;
signal init_init, init_done : bit := '0';
type display_state is (init, function_set, entry_set, set_display, clr_display, pause, set_addr, char_f, char_p, char_g,
char_a, done);
signal cur_state : display_state := init;
begin
LED <= tx_byte; --for diagnostic purposes
--The following "with" statements simplify the process of adding and removing states.
--every other state but pause uses the transmit state machine
when function_set =>
if(i2 = 2000) then
cur_state <= entry_set;
else
cur_state <= function_set;
end if;
end case;
end if;
end process display;
--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
LCD_E0 <= '0';
SF_D0 <= tx_byte(7 downto 4);
if(i2 = 2) then
tx_state <= high_hold;
i2 <= 0;
else
tx_state <= high_setup;
i2 <= i2 + 1;
end if;
end case;
end if;
end process transmit;
--specified by datasheet
power_on_initialize: process(clk, reset, init_init) --power on initialization sequence
begin
if(reset='1') then
init_state <= idle;
init_done <= '0';
elsif(clk='1' and clk'event) then
case init_state is
when idle =>
init_done <= '0';
if(init_init = '1') then
init_state <= fifteenms;
i <= 0;
else
init_state <= idle;
i <= i + 1;
end if;
This tutorial was written by Rahul Vora. Rahul is an engineering student in the department of
Electrical and Computer Engineering at the University of New Mexico. He can be reached at
rvora@unm.edu.
This tutorial was updated and edited by Brian Zufelt. Brian is an engineering student in the
department of Electrical and Computer Engineering at the University of New Mexico.