Verilog LCD Controller Module
Hi guys,
Thought of presenting you some interesting stuff. A Verilog character LCD Module…. Okey. You know it’s kinda cool to display characters on your FPGA board’s LCD display rather than always lighting LED s to demonstrate your program output. But using these LCDs aren’t easy as using a DOS prompt (CLI) to show a message using a high level software development language. It takes a fair amount of time to figure out how these things work. So it’s much easy, if you have a sample code. Even though this code is written for a Spartan 3E 1600E FPGA board’s character LCD (16×2), you can customize this code easily for any other LCD because the code is quite simple and clear. Having the code alone doesn’t make any sense to you, you should first understand how these character LCDs work. Also it is very important for you to understand about how to write a Verilog LCD module from the beginning. So then the process of editing this sample code becomes very easy. So please follow the steps.
Module Specs :
Originally written for : Spartan 3E 1600E FPGA development board (but easily configurable with any other board).
LCD Display Controller : Sitronix ST7066U
FPGA to LCD Controller interface type : 8 bit interface
LCD Display size : 16×2
link : Download Verilog Character LCD Driver Module
If you are new to the topic please follow the rest of the article.
So OK, How to start writing a Verilog character LCD controller Module?
First, you should thoroughly read your FPGA board’s manual’s chapter for “Character LCD Screen”. Seriously… But when you start to read it, you might feel that it is a mess at the beginning. So please note down the following points before reading it.
LCD Display basically has 2 components
The dumb display: which display the characters according to the signals received from the LCD Display Controller.
LCD Display Controller: This is like the brain of the LCD Display. It writes the characters to the display, it can clear all the characters out, it can shift the displaying characters, it can move the cursor of the display, etc.
So, now, here, what is important is that the connections of the display controller with the FPGA. There must be a diagram on your board manual regarding these connections. Use that diagram and following explanation to understand how the display controller is connected with the FPGA.
You also might see an Intel StrataFlash chip in the same diagram, if you have that in your board. (StrataFlash explained later)
OK now lets see what are the important pins connected to FPGA from the display controller. Those can be named as LCD_E, LCD_RS, LCD_RW, Bit 1, Bit 2, Bit 3,…. Bit 7 (only for a 8 bit interface with the FPGA, if the FPGA has a 4 bit interface only up to Bit 3 is there). Initially let me just remind you, what FPGA is doing with these pins. It is simply driving these LCD Controller’s pins to 1 s or 0 s. Depending on what pins are changed by the FPGA (to 1 or 0), the LCD controller interprets it as an instruction and do the changes in the dumb LCD display accordingly. See the bellow diagram extracted from the user guide of Spartan 3E to identify the connections, there are whole a lot of them, but some are not essential to know of.
LCD Controller and the FPGA Connections for Spartan 3E 1600E
Please see the descriptions of important pins of the LCD Display bellow….
- Register Select (RS) pin of LCD Controller: Commonly labeled as LCD_RS or LCD_D/i. Ok, now if FPGA changes this pin to 0 (LCD_RS=0), the controller interprets this as, “Okey, now what I’m receiving from the Bit pins (Bit 0, Bit 1…. Bit 7) is an instruction”. So as long as the LCD_RS pin is 0, LCD Controller is in the instruction execution mode. At this time assume that the FPGA is driving Bit 7, Bit 6, …. Bit 0 pins as like 0 0 0 0 0 0 0 1. This instruction means to clear the display. So the display controller will delete all the existing characters on the display. Please follow the “Instruction Set” table in your FPGA board’s User Guide. Then you will be clear about what I’m telling. One very important point to note here is that, these instructions takes some time to execute. LCD displays are just like any other I/O devices, has the drawback of being slow compared to the FPGA’s working clock speed (50 MHz, 100MHz, or more, etc). So can’t help it
, you have to retain the values of the pins (I mean LCD_RS pin (which is 0 at this time) and Bit 0 to Bit 7 pins) unchanged until the instruction is fully executed. if your oscillator is 50MHz, you have to wait like 250,000 clock cycles (always remember that this whole system works according to the clock cycles [positive edge triggered, AKA posedge CLK] of the oscillator, so there is no actual wait time because loop is constantly running, so what we are doing here is that constantly assigning previously assigned values for respected pins in each clock cycle until the clock count exceeds 250,000 cycles). So now that is only for the “Clear Display” instruction. Different commands takes different times periods to execute. If you don’t give enough time for these commands to execute, simply the LCD Controller will not complete the command execution. The time periods that you need for each command to execute is mentioned in the your FPGA board’s manual (user guide). You will see how the delays are applied in the sample code provided (simply we use counters for delays, simulation type delay’s won’t work here)… OK Now, when LCD Controller’s LCD_RS = 1: Guess what? The bits transferred from the pins from Bit 0 to Bit 7 are accepted as Data by the LCD Display Controller and stored in the DD RAM. This DD RAM is the thing which is storing all the data that are displayed on the LCD screen. Once again to get these data and store them in the DD RAM takes time. So it is necessary to retain the pin values for the required amount of time. - Read/Write (R/W) pin. This pin is very important. Let’s call this LCD_RW. When LCD_RW is = 0, What the LCD Display Controller understands is “Ok, now the FPGA is only writing (or transferring) data or instructions ‘to’ the DDRAM, FPGA does not read data from the Display (simply DDRAM)”. So accordingly when LCD_RW = 1, FPGA can read data from the display (or DD RAM). Usually we don’t want to read from the DD RAM. So we must make sure to keep the LCD_RW always 0.
- Enable pin. Usually shown as LCD_E. As the name implies this works as the switch between FPGA and LCD Controller. when LCD_E = 0, no input is taken into the Controller. To execute a command or transfer data LCD_E pin has to be 1. Why do you need this LCD_E pin? Can’t it be set as 1 always? NO, LCD_E pin is used to break one instruction execution from another (or one data byte transfer from another). If you enable LCD_E always, for example you might see repeatedly characters are appearing on the display or the display may be always blank because of the execution of the command to clear the display.
OK now, remember that above mentioned 3 pins are the most important and you have to control their values systematically for the operations to take place correctly. Moving on, following pins are used to transfer instructions (if LCD_RS = 0) or data (if LCD_RS = 1) to the LCD Display Controller. Also if you want to read data from the display to FPGA, these pins will work as the carriers.
- Bit 0 pin [SF_D8] or [LCD_D8] (Not used in 4-bit operation), What is 4 Bit operation? (= 4 bit interface), Explained later.
- Bit 1 pin [SF_D9] or [LCD_D9] (Not used in 4-bit operation)
- Bit 2 pin [SF_D10] or [LCD_D10](Not used in 4-bit operation)
- Bit 3 pin [SF_D11] or [LCD_D11](Not used in 4-bit operation)
- Bit 4 pin [SF_D12] or [LCD_D12]
- Bit 5 pin [SF_D13] or [LCD_D13]
- Bit 6 pin [SF_D14] or [LCD_D14]
- Bit 7 pin [SF_D15] or [LCD_D15]
Now when you take your LCD Display Controller, there are different products by different vendors. For example Spartan 3E board’s LCD Display Controller is Sitronix ST7066U. But its functionality is equivalent to the Hitachi HD44780, SMOS SED1278, Samsung S6A0069X or KS0066U, etc. So likewise, most probably your FPGA development kit might have a similar controller. Specially Hitachi HD4478. It is like the industry standard for Character LCD Displays. The code provided with this blog post was written by reading the data sheet for Sitronix ST7066U. Obviously it provides much more details about the LCD Display Controller and it is easy to understand. So I recommend you to follow the data sheet for your LCD Display Controller too (you don’t have to read the whole thing, just there are important 5 or 6 pages). Your FPGA board’s manual has all information regarding its LCD Character Display, but it may be little unclear sometimes, that’s why I recommended direct LCD Display’s datasheet.
I mentioned in the above paragraph that, you can write the Verilog LCD module by reading the LCD Controller’s data sheet. then how come the FPGA’s manual be important?
Well that is the thing which provides you information about how the FPGA is connected with the LCD controller. Frankly saying from the FPGA’s manual you can find whether its FPGA has a 4 bit connection interface (has pins from Bit 0 to Bit 3 other than the common pins like LCD_E, LCD_RS, etc) with the LCD Display controller or whether it is having a 8 bit interface (has pins from Bit 0 to Bit 7 other than the common pins like LCD_E, LCD_RS, etc). You know, that LCD Controller always (as far as I know) has 8 pins (as described earlier, for Bit 0 to Bit 7 thing) to transfer data or instructions, but the FPGA may or may not have 8 pins dedicated for the display controller. Most of the small scale FPGAs has 4 pins.
So if the FPGA is connected to LCD Controller through 4 pins, how to transfer data or instructions from FPGA to LCD Controller? (note that data block or an instruction block is always 8 bits when dealing with LCDs). Simply the solution is dividing the 8 bit data segment into two, 4 bit data segments and transfer them sequentially. Upper nibble (Bit 7 to Bit 4) transferred first (remember that you have to keep this signals for sometime for the LCD Controller to understand it) and then there is some hold time in between the first nibble and the lower nibble, then finally the lower nibble (Bit 3 to Bit 0) is transferred (this nibble has a holding time too).
Refer this paragraph only if you have Intel StrataFlash on your board. Ok now if you have it, you will see that, StrataFlash’s pins are shared with the LCD Display’s data lines (or instruction lines, Bit 0 to Bit 7). It’s ok that StrataFlash shares the connections, you don’t have to worry about it when you are only using LCD Display. I mean values inside the StrataFlash may change, but it won’t harm your operations with the LCD. But if you want, you can disable the StrataFlash (I recommend you to do this). There is a pin named SF_CEO on the StrataFlash. If you make it to 1, StrataFlash is disabled. This pin is important when you use both the LCD and the StrataFlash. Otherwise you can constantly drive this as 1. Refer your manual for more info.
OK now lets see other important components that we need in this whole LCD operation.
- DD RAM : As mentioned earlier DD RAM is the place where the LCD Controller stores its characters. Why controller need such a thing? Because Controller can refer only to a one character location at a time. When you store it in the DD RAM, it is displayed directly and controller don’t have to worry about it. By the way this DD RAMs are having 80 memory locations. That means 40 memory locations per a line. So what does (16×2) LCD means? here you can only display 16 characters per line at a time. There are 2 lines like that for a (16×2) Display. If you want to read the other characters (characters from memory location 17th to 40th and 57th to 80th), you have to shift the display using a special command (it is like LCD_E = 1, LCD_RW = 0, LCD_RS = 0 and Bit 0 to Bit 7 holds the instruction you want to send, refer the manual for the command…..it will be like 0 0 0 1 1 0 X X). (X refers to don’t care term). BTW if you have a 4 line display (20×4), all the characters you write, can be displayed without shifting the display.
Addressing on DD RAM
- CG ROM : Ok now there is a thing called CG ROM (Character Generator ROM). What it holds is a set of character symbols (EX: It has the ASCII character set and the Japanese characters) arranged in a matrix structure (refer manual for the character matrix). So each character has a row index and a column index. Remember we stored data in the DD RAM? The data that we received via Bit 0 to Bit 7 pins. Ok now you will see what is the actual meaning of that 8 bit block. That 8 bit block actually holds the address of the CG ROM’s character location. That 8 bit block’s upper nibble (Bit 7 to Bit 4) provides you the column index of the CG ROM’s required character location and the lower nibble (Bit 3 to Bit 0) holds the row index.
- CG RAM : Now what does CG RAM do? You know in CG ROM, the existing characters are fixed (hard coded, obviously because it is just a ROM). So you can only use the characters that are included in the CG ROM. What if you want to have your own characters drawn by you? This facility is provided for you by the CGRAM. There are 8 memory locations that you can use to store your own characters. But the method of drawing a character on the CGRAM is out of scope on this article. Please refer the LCD Controller manual to do that.
CGROM (+CGRAM) character Map
This article is still under development. Users are welcome to inform me about the mistakes, areas that are unclear, and what need to be added ? etc etc

this is a very informative article on verilog, i enjoyed reading it very much and want to give it a try, keep up the good work!!!