Writing Characters to LCD Display on Xilinx® Spartan® -3A FPGA board

Author: Aditya Joshi aditya.joshi@mathworks.com

Overview: The Spartan® 3A starter kit board comes with a 2-line by 16-character liquid crystal display (LCD) [1], which offers a practical way to display information. The FPGA can use both 8-bit and 4-bit data interface to control the LCD. Both ASCII and custom characters can be used for displaying information. In this tutorial, we discuss a way to display the word “HOLA” on the LCD using the eight bit data interface. For complete details on how the LCD display configuration and commands, please refer to the Spartan® 3A User Guide. Design Overflow: 1. Design and simulate the top level model in Simulink® and Stateflow®. 2. Use the Simulink® HDL Coder to produce VHDL code. 3. Synthesize and implement the VHDL code in Xilinx® ISE. 4. Deploy the .bit file produced using iMPACT® in Xilinx® ISE v9.2. Background: All the clock cycles are measured relative to the 50 MHz on board clock (LOC E12). The character codes to be displayed on the screen are stored in the Display Data Ram (DD-RAM). There are special addresses to store these characters: 0x00 to 0x0F (upper line) and 0x40 to 0x4F (lower line). We use the following commands to the DD RAM
1.

Set DD RAM Address: To initialize the address counter before reading/writing.

Here is the chart for determining the ASII code addresses of the stored characters (Please see the reference for details [1]): . 2. The CG ROM contains certain pre-defined characters that can be displayed on the LCD. This could correspond to one of the LCD character sets in the CG ROM.This command has the general form: LCD_RS LCD_RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 1 A6 A5 A4 A3 A2 A1 A0 ‘A’ in A6-A0 stands for address-bit. Write Data to DD RAM: The general form of this command is: LCD_RS LCD_RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 1 0 D7 D6 D5 D4 D3 D2 D1 D0 ‘D’ in D7-D0 stands for the data-bit to be written to the DD RAM address. A6-A0 can be either ‘0’ or ‘1’ and refer to one of the valid DD RAM addresses.

These are used to print to the LCD screen using the 4-bit data interface. These are: 1. Value: 0x00 Execution Time: 15 ms = 750000 cycles . Waiting: Wait for display to get ready after power-on. which has a totally different process. For example. we can combine both the upper and lower nibbles. the command ‘Write Data to DD RAM’ for the character ‘I’ can be sent as: 1001001001 (2 control bits (LCD_RS + LCD_RW) + 8 data bits) Before writing to the LCD display.Please note that the character sets are described in terms of “Upper Data Nibble” and “Lower Data Nibble”. Since we are using the 8-bit interface. a set of commands must be issued to configure the LCD for the data write operation.

2 ms = 210000 cycles 5. the characters to be displayed can be transferred: 1. Clear Display: Value used: 0x01 Execution Time: 4. 3. Set Display On: Turn the display on. cursor off and cursor position off.2. Please refer to the user manual for details. the character font and the data length (in bits) Value used*: 0x3C Execution Time: 8.2 ms = 210000 cycles .2 ms = 210000 cycles Once the LCD is configured for writing. Value used: 0x06 Execution Time: 4.2 ms = 210000 cycles 4. Char_o: Value: 0x4F Execution Time: 4. Char_h: Value: 0x48 Execution Time: 4.4 ms = 420000 cycles * Please note that some of the value used can be changed by setting the DB0 and DB1. Entry Mode Set: This is a powerful command! It can be used to set the direction in which the cursor moves and to specify whether to shift the display or not. Value used: 0x0C Execution Time: 4.2 ms = 210000 cycles 2. Function Set: This is used to set the number of display lines.

.2 ms = 210000 cycles After writing the characters. it is good to wait for additional 4. Char_l: Value: 0x4C Execution Time: 4. Char_a: Value: 0x41 Execution Time: 4. It is also important to remember switching the values of the control signals. Data for Read/ Write Read/ Write Control 0: Write data to LCD 1: Read data from LCD LCD_RS Y14 LCD_RW W13 *Please refer to the user manual [1] for details.3.2 ms (210000 cycles) before exiting the program.2 ms = 210000 cycles 4. Here is a description of the three LCD control signals: Signal Name LCD_E FPGA Pin AB4 Description Read/ Write enable Values: 0: Disabled 1: Enabled for Read/ Write Register Select Values: 0: Instruction Register during write operation Busy flash during read operation* 1.

4 m Function_set LCD_Data=0x3C T < 20 ns T < 20 ns T > 8.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 T=4.2 ms LCD_Data=0x3C LCD_E=1 LCD_RS=0 LCD_RW=0 .4 ms Initialize3 20 ns<T<8. LCD_E=1 LCD_RS=0 LCD_RW=0 T > 8.4 ms Initialize4 Function_set 20 ns<T<4.4 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_E=1 LCD_RS=0 LCD_RW=0 Function_set T=8.Implementation: The entire write process can be represented in terms of state diagrams: Waiting LCD_E=0 LCD_RS=0 LCD_RW=0 T > 15 ms T < 20 ns LCD_E=1 LCD_RS=0 LCD_RW=0 Initialize1 20 ns<T<8.4 ms LCD_E=1 LCD_RS=0 LCD_RW=0 Function_set LCD_Data=0x3C LCD_E=1 LCD_RS=0 LCD_RW=0 T < 20 ns LCD_E=1 LCD_RS=0 LCD_RW=0 T > 8.4 ms LCD_E=0 LCD_RS=0 LCD_RW=0 T=8.4 ms LCD_Data=0x3C T > 8.

2 ms LCD_E=1 LCD_RS=0 LCD_RW=0 T > 4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_Data=0x48 T=4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_Data=0x0C T=4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_Data=0x01 T=4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_Data=0x06 T=4.2 ms Char_h T < 20 ns LCD_E=1 LCD_RS=1 LCD_RW=0 20 ns<T<4.2 ms LCD_E=1 LCD_RS=0 LCD_RW=0 T > 4.T > 4.2 ms LCD_E=1 LCD_RS=1 LCD_RW=0 .2 ms Set_display T < 20 ns LCD_E=1 LCD_RS=0 LCD_RW=0 20 ns<T<4.2 ms Clear_display T < 20 ns LCD_E=1 LCD_RS=0 LCD_RW=0 20 ns<T<4.2 ms Entry_set T < 20 ns LCD_E=1 LCD_RS=0 LCD_RW=0 20 ns<T<4.2 ms LCD_E=1 LCD_RS=0 LCD_RW=0 T > 4.

2 ms Char_l T < 20 ns LCD_E=1 LCD_RS=1 LCD_RW=0 20 ns<T<4.2 ms LCD_E=0 LCD_RS=1 LCD_RW=0 LCD_Data=0x00 .2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 T > 4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 T=4.2 ms Done T<4.2 ms LCD_E=1 LCD_RS=1 LCD_RW=0 Char_o T < 20 ns LCD_E=1 LCD_RS=1 LCD_RW=0 20 ns<T<4.2 ms LCD_E=0 LCD_RS=0 LCD_RW=0 LCD_Data=0x4C T=4.2 ms LCD_E=1 LCD_RS=1 LCD_RW=0 LCD_Data=0x41 T > 4.2 ms Char_a T<4.2 ms LCD_E=1 LCD_RS=1 LCD_RW=0 T > 4.2 ms LCD_Data=0x4F T=4.T > 4.

T2. T3 and T4. The attached zip file contains the model ‘lcd_hola_sim. 20 ns.4 ms. Figure 1: Simulation in Simulink .mdl’ which is the most direct implementation of the above flow diagram. When the model is run.2 ms and 8. The values of T1. LCD_RW. the corresponding values of the LCD_E. have been scaled down to reduce simulation time. 4. LCD_RS and LCD_DATA can be visualized in the scope block.We use Stateflow® in Simulink® to model the states and the state transitions. which correspond to 15 ms.

To generate the HDL code. We use an Embedded MATLAB Function for this conversion. Since Spartan® 3A will only work with fixed-point data types.mdl’. Replace the scope with output ports.A note on Data types: The default data type in Simulink® is ‘double’ which is 64-bit precision floating-point. The output ‘LCD_DATA’ has to be converted to binary values to work on the FPGA. Figure 2: HDL Code Generation in Simulink . Remove the ‘clock’ and the ‘scope’ in ‘lcd_hola_sim. please follow these steps: 1. all ‘double’ and ‘single’ data-types should be converted to equivalent fixed-point types. 2.

8).real(to_integer(c(n . 8). This is because this block produces a temporary variable of type ‘real’. to: VARIABLE argin_t_0 : integer.mdl’ is obtained after applying the above modifications. Here are the steps: 1. some additional changes need to be made to the generated VHDL file that corresponds to the binary convertor embedded MATLAB function block ‘uint2bin’. . 2. Change the following lines (Line #72 and 73): argin_t_0 := real(to_integer(argin_t)) . Click on Tools->HDL Coder->Generate HDL to generate the VHDL code. The generated code should now be ready to be synthesized on Xilinx® ISE.The model ‘lcd_hola. width).1))). 3. Before the code can be used for synthesis in Xilinx® ISE. which must be changed to ‘integer’. Change the following (Line # 55) : VARIABLE argin_t_0 : real. Remove the following function (Line # 39): -.to_integer(c(n .1)).TMW_TO_UNSIGNED FUNCTION tmw_to_unsigned(arg: real.2. to: argin_t_0 := to_integer(argin_t) . The attached zip file contains the project built using Xilinx® ISE v9. END FUNCTION. width: integer) RETURN unsigned IS BEGIN RETURN to_unsigned(integer(arg). argin_t := tmw_to_unsigned(argin_t_0. argin_t := to_unsigned(argin_t_0.

ise”. Open the project: “lcd_eight_hola_spartan. Following are the most straightforward way to synthesize. build and deploy the project to the FPGA board (Please refer to the ISE in depth tutorial for complete details [2]): 1. Double click on “Synthesize-XST” .Working in Xilinx® ISE: This section is for those not familiar with Xilinx® ISE.

Configure the device: . Implement Design: 3.2.

4. Program the board: ISE should prompt this: Right Click: .

Spartan 3A Starter Kit Board User Guide. ISE In-depth Tutorial. 2.LCD display should print “HOLA”. References: 1. Xilinx®. Please ensure that the “Clock enable” switch is “HIGH” as specified in the constraint file (constraints. . Xilinx®.ucf).

Sign up to vote on this title
UsefulNot useful