New Horizons

Welcome to my blog

My name is Sven Andersson and I
work as a consultant in embedded
system design, implemented in ASIC
and FPGA.
In my spare time I write this blog
and I hope it will inspire others to
learn more about this fantastic field.
I live in Stockholm Sweden and have
my own company


You are welcome to contact me
and ask questions or make comments
about my blog.


New Horizons
What's new
Starting a blog
Writing a blog
Using an RSS reader

Zynq Design From Scratch
Started February 2014
1 Introduction
Changes and updates
2 Zynq-7000 All Programmable SoC
3 ZedBoard and other boards
4 Computer platform and VirtualBox
5 Installing Ubuntu
6 Fixing Ubuntu
7 Installing Vivado
8 Starting Vivado
9 Using Vivado
10 Lab 1. Create a Zynq project
11 Lab 1. Build a hardware platform
12 Lab 1. Create a software application
13 Lab 1. Connect to ZedBoard
14 Lab 1. Run a software application
15 Lab 1. Benchmarking ARM Cortex-A9
16 Lab 2. Adding a GPIO peripheral
17 Lab 2. Create a custom HDL module
18 Lab 2. Connect package pins and implement
19 Lab 2. Create a software application and configure the PL
20 Lab 2. Debugging a software application
21 Running Linux from SD card
22 Installing PetaLinux
23 Booting PetaLinux
24 Connect to ZedBoad via ethernet
25 Rebuilding the PetaLinux kernel image
26 Running a DHCP server on the host
27 Running a TFTP server on the host
28 PetaLinux boot via U-boot
29 PetaLinux application development
30 Fixing the host computer
31 Running NFS servers
32 VirtualBox seamless mode
33 Mounting guest file system using sshfs
34 PetaLinux. Setting up a web server
35 PetaLinux. Using cgi scripts
36 PetaLinux. Web enabled application
37 Convert from VirtualBox to VMware
38 Running Linaro Ubuntu on ZedBoard
39 Running Android on ZedBoard
40 Lab2. Booting from SD card and SPI flash
41 Lab2. PetaLinux board bringup
42 Lab2. Writing userspace IO device driver
43 Lab2. Hardware debugging
44 MicroZed quick start
45 Installing Vivado 2014.1
46 Lab3. Adding push buttons to our Zynq system
47 Lab3. Adding an interrupt service routine
48 Installing Ubuntu 14.04
49 Installing Vivado and Petalinux 2014.2
50 Using Vivado 2014.2
51 Upgrading to Ubuntu 14.04
52 Using Petalinux 2014.2
53 Booting from SD card and SPI flash
54 Booting Petalinux 2014.2 from SD card
55 Booting Petalinux 2014.2 from SPI flash
56 Installing Vivado 2014.3

Chipotle Verification System

EE Times Retrospective Series
It all started more than 40 years ago
My first job as an electrical engineer
The Memory (R)evolution
The Microprocessor (R)evolution

Four soft-core processors
Started January 2012
Table of contents
OpenRISC 1200
Nios II

Using the Spartan-6 LX9 MicroBoard
Started August 2011
Table of contents
Problems, fixes and solutions

FPGA Design From Scratch
Started December 2006
Table of contents
Acronyms and abbreviations

Actel FPGA design
Designing with an Actel FPGA. Part 1
Designing with an Actel FPGA. Part 2
Designing with an Actel FPGA. Part 3
Designing with an Actel FPGA. Part 4
Designing with an Actel FPGA. Part 5

A hardware designer's best friend
Zoo Design Platform

Installing Cobra Command Tool
A processor benchmark

Porting a Unix program to Mac OS X
Fixing a HyperTerminal in Mac OS X
A dream come true

Stockholm by bike

The New York City Marathon

Kittelfjall Lappland

Tour skating in Sweden and around the world
Wild skating
Tour day
Safety equipment
A look at the equipment you need
Skate maintenance
Books, photos, films and videos
Weather forecasts

38000 feet above see level
A trip to Spain
Florida the sunshine state

Photo Albums
Seaside Florida
Ronda Spain
Sevilla Spain
Cordoba Spain
Alhambra Spain
KittelfjÀll Lapland
Landsort Art Walk
Skating on thin ice

100 Power Tips for FPGA Designers

Adventures in ASIC
Computer History Museum
Design & Reuse
d9 Tech Blog
EDA Cafe
EDA DesignLine
Eli's tech Blog
FPGA Arcade
FPGA Central
FPGA developer
FPGA Journal
FPGA World
Lesley Shannon Courses
Mac 2 Ubuntu
Programmable Logic DesignLine
World of ASIC

If you want to be updated on this weblog Enter your email here:

rss feed

Saturday, June 09, 2007
FPGA design from scratch. Part 31
Adding a 16x2 character LCD display

To write the
"Hello world" program we need a place to display the greeting. We will add an LCD display. We are going to use the General Purpose IO interface to drive the LCD display. In the IP catalog we  open the General Purpose IO entry and choose the OPB General Purpose IO and select Add IP from the menu. For more information about adding a new IP block see Part 17.

Set address range

We will select a 4k address range and click Generate Addresses to define the Base Address and the High Address for the IP block.

Connecting ports

We will make GPIO_IO an external port. All other ports are left unconnected.

The easy way to add a new block

Probably the easiest way to add a new peripheral is to edit the ETC_system.mhs file. This file will be read when we start XPS and the information will be displayed in the System Assembly window. To add a new GPIO block we can copy one of the existing GPIO block and edit the information to fit our new block. Like this:

BEGIN opb_gpio
 PORT GPIO_IO = fpga_0_LEDs_4Bit_GPIO_IO

Copy, paste and edit.

BEGIN opb_gpio

The next time we start Xilinx Platform Studio the LCD_16x2_GPIO_IO block will be added.

Configure the IP block

Before we can configure the IP block we need to know more about the LCD display on the ML403 evaluation board. Let's read the
ML403 User Guide. Here is what it has to say about the LCD display:

The ML403 board has a 16-character x 2-line LCD (Lumex LCM-S01602DTR/M) on the board to display text information. Potentiometer R1 adjusts the contrast of the LCD. The data interface  to the LCD is connected to the FPGA to support 4-bit mode only. A level translator chip is used to shift the voltage level between the FPGA and the LCD.

Spartan-3A Starter Kit Board User Guide gives us some more information about the LCD display (see chapter 5), but observe that this is not the same implementation as used on the ML403 board. To find out more about the LCD implementation on the ML403 board we take a look at the schematics.

(Courtesy of Xilinx)
The LCD driver

The LCD driver used on the ML403 board is a
Samsung S6A0069 dot matrix LCD driver & controller LSI device. It can display 1 or 2 lines with a 5x8 or a 5x11 dots matrix. It can be set to use an 8 bit or 4 bit data bus. On the ML403 board the bus is 4 bits.

RS RW Operation
L L Instruction write operation (MPU writes instruction code into IR)
L H Read Busy Flag (DB7) and address counter
H L Data write operation (MPU writes data into DR)
H H Data read operation (MPU reads data from DR) 

LCD display timing

The LCD display is a practical way to display a variety of information using standard ASCII characters and even allows you to create some of your own. However, these displays are not fast. This design scrolls the display at 0.5 second intervals and that really is the practical limit for clarity. This low performance rate also relates to the signals used for communication. Compared with a Virtex-4 operating at 100MHz, the display can appear extremely slow. This is where MicroBlaze can be used to efficiently implement timing delays as well as control the actual content of the display.

4-bit write operation

This timing diagram shows a single write operation being performed. The diagram is approximately to scale showing the minimum times allowed for setup, hold and enable pulse  length relative to a 50MHz clock (20ns period). The data D[7:4], Register Select (RS) and write control (RW) must be set up at least 40ns before the enable E goes High. Enable must be High  or at least 230ns which is almost 12 clock cycles at 50MHz. In our write only system, the R/W signal can be tied Low permanently.

8-bit write operation

After initial display communication is established, all data transfers are 8-bit ASCII character codes, data bytes or 8-bit addresses. Each 8-bit transfer obviously has to be decomposed into two 4-bit transfers which must be spaced by at least 1μs. Following an 8-bit write operation, there must be an interval of at least 40μs before the next communication. This delay must be increased to 1.64ms following a clear display command.

Programming sequence

Here are all the steps needed to send an 8 bit instruction to the LCD driver in 4 bit mode:
  1. Keep LCD_RW low (write mode)
  2. Set LCD_RS high (data mode)
  3. Put data bits 7:4 on the bus (LCD_D7:LCD_D4)
  4. Wait 100ns
  5. Set LCD_E high
  6. Wait 300ns
  7. Set LCD_E low
  8. Wait 1500ns
  9. Put data bits 3:0 on the bus (LCD_D7:LCD_D4)
  10. Wait 100ns
  11. Set LCD_E high
  12.  Wait 300ns
  13. Set LCD_E low
  14. Wait 60us
Display setup

Before the display can be used for the first time, there is an initialisation sequence which must be followed to allow communication to take place. These sequences are ideally suited to an processor such as MicroBlaze. Besides the relative complexity of the sequence, the process is only executed once and then the processor is available to perform other tasks including the control on the display itself.

More reading

Signal wiring on the ML403 board

 Signal Name
 Description GP IO pin
 FPGA Pin Location
Read/Write Enable Pulse
0: Disabled
1: Read/Write operation enabled
LCD_RS Register Select
0:Instruction register during write
1:Data for read or write operation

LCD_RW  Read/Write Control
0:Write, LCD accepts data
1:Read, LCD presents data

LCD_DB7 Data Bus bit 7
LCD_DB6 Data Bus bit 6
LCD_DB5 Data Bus bit 5
LCD_DB4  Data Bus bit 4

It looks like we need seven General Purpose IO pins to control the LCD display. The rest is software. We will set the GPIO Data Bus Width to 7 and leave everything else untouched.

Adding constraints

The following constraints will be added to the constraints file .../ETC/xps/data/ETC_system.ucf

#### Module LCD_16x2 constraints

NET "LCD_16x2_GPIO_IO_pin<0>" LOC="AE13" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<1>" LOC="AC17" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<2>" LOC="AB17" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<3>" LOC="AF12" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<4>" LOC="AE12" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<5>" LOC="AC10" | IOSTANDARD = LVCMOS33 | TIG ;
NET "LCD_16x2_GPIO_IO_pin<6>" LOC="AB10" | IOSTANDARD = LVCMOS33 | TIG ;

Generate Netlist

After adding the new IP block we have to rerun netlist generation Hardware->Generate Netlist. The netlist generation generates a number of warnings but finish successfully.

   /home/svenand/root/projects/ETC/xps/ETC_system.mhs line 306 - floating

WARNING:Xst:2211 - "/home/svenand/root/projects/ETC/xps/hdl/ETC_system.vhd" line 2217: Instantiating black box module <IOBUF>.

Xst:387 - The KEEP property attached to the net <microblaze_0/microblaze_0/Performance.Decode_I/of_PipeRun_Prefetch> may hinder timing optimization.

   You may achieve better results by removing this property

Generate Bitstream

Next step is to generate a new bitstream Hardware->Generate Bitstream. The bitstream generation generates a number of warnings but finish successfully.

WARNING:NgdBuild:440 - FF primitive
   FIFO_I/BU520' has unconnected output pin
WARNING:NgdBuild:478 - clock net debug_module/bscan_drck1 with clock driver
   debug_module/debug_module/BUFG_DRCK1 drives no clock pins

WARNING:PhysDesignRules:372 - Gated clock. Clock net
   DCM_ADV.DCM_ADV_INST/cd/CLK<1> is sourced by a combinatorial pin. This is not
   good design practice. Use the CE pin to control the loading of data into the

Can someone explain the meaning of these warnings to me.

Top  Next  Previous

Posted at 10:25 by

October 14, 2008   07:24 PM PDT

Does anybody know where i can find a sample implementation for for the LCD using a Xilinx ML403 board using a PowerPc instead of a Microblace processor?

Some code snippets would be very usefull.

Dipak Gupta
August 11, 2008   07:26 AM PDT
hi m trying to connect as u suggest the steps and i give the pin location in UCF what u had give but i m using ML402 Board with Video starter Kit so when i m generating the Bit stream or Netlist it is not able to verify the pic location so what is the pin location with LCD is connect on ML402
August 15, 2007   08:29 AM PDT
Thanks Torsten and Chris for explaining the warning messages.

Torsten Landschoff
August 14, 2007   11:52 PM PDT
Hi Sven,

About your warnings:

WARNING:NgdBuild:440 - FF primitive '<path>' has unconnected output pin

This warning is issued if the output value of a flip flop is not used. After all, why create a memory when the stored value is never used? Often these warnings are bogus as you will often use a generic component that provides a service you do not need. So you do not use the output, resulting in this warning.

WARNING:NgdBuild:478 - clock net debug_module/bscan_drck1 with clock driver debug_module/debug_module/BUFG_DRCK1 drives no clock pins
Never seen this warning before. From the wording it sounds like there is a clock driver (which is special as it does use a low-delay clock tree) from which the output is either unused or it is not used as a clock. As it is some debug module, I wouldn't care unless I knew what the clock should drive :)

WARNING:PhysDesignRules:372 - Gated clock. Clock net '<net>' is sourced by a combinatorial pin.
The delay of the clock distribution network in an FPGA is balanced in a way that setup and hold times are guaranteed by the design software. Now, if a clock net is driven by a combinational source, the tools can no longer check that the timing is valid. I think, this exact warning is generated with most Virtex4 based designs in EDK (I've seen it before). Ignore it or tell Xilinx. :)

Greetings, Torsten

Leave a Comment:


Homepage (optional)


Previous Entry Home Next Entry