Sunday, 24 January 2016

Numato Mimas V2 - Controlling a 16x2 LCD display using VHDL

In the previous post we discussed how to control a Numato Labs LCD Expansion module using the Mimas V2 FPGA Development board.  The post is available below for those that are interested:

Mimas V2 FPGA - Controlling a 16x2 LCD Display

This post discusses the same subject but goes into more detail and relies on VHDL code instead of Verilog.

There are a great many 16x2 LCD displays available to electronic design engineers.  Nearly all of them are controlled by the Hitachi HD44780 control IC which is built into the display module.  The wikipedia entry on the control system is here:

Wikipedia Entry on HD44780

The datasheet for the HD44780 is here:

HD44780 datasheet

The pins used on LCD display have been standardised to make it simple for engineers to use these displays in their electronic circuits.  The nuances of controlling a display are quite complex and beyond the scope of what I'm prepared to discuss here.  The displays are controlled by sending signals from a microcontroller which implements a state machine in order to send data to be displayed to the display and read back from the display.


If people are interested in exactly how to control an LCD display with switches then here is a tutorial for you:

HD44780 Tutorial

In order to use an FPGA to achieve control of a display we need to implement a similar state machine.  This has been written many times before and a particular good paper explaining the implementation of the state machine is here:

FPGA State machine paper

Luckily we don't have to write our own state machine as I found a really good implementation of one at OpenCores.  OpenCores is an excellent FPGA design and development resource and if anyone is serious about learning and using FPGA technology then they should check it out!

http://opencores.org/

In order to use the site you will have to register but that's no hardship as registration is simple and free!

The project we are interested in is here:

http://opencores.org/project,16x2_lcd_controller

Download the project files and extract them to somewhere sensible on your Hard disk and then load up Xilinx WebISE and lets get started!

We need to create a new project - use the settings shown in the picture below:


They are all correct for the Numato Labs Mimas V2 Development board.  Click OK when ready.

Next right click on the Hierarchy window in the main project window of WebISE and choose 'add Copy of Source' - then navigate to the folder(s) where the OpenCores project is located and find and then add the file:

lcd16x2_ctrl.vhd


Click 'OK' when asked to confirm adding the file to the project.

Then repeat the process to add lcd16x2_ctrl_demo.vhd 


Click 'OK' when asked to confirm adding the file to the project.

The repeat the process on more time to add the UCF file called 'pin_locations.ucf'


The main project window should now look like this:


What needs to be done now is to update the UCF file with the appropriate connections for the Mimas V2 Development board.  Load up the UCF file in the internal text editor in WebISE:


Delete all of the text present and replace it with the code below:

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# This file is a .ucf for 16x2 LCD Expansion Modules on Mimas V2 modified by ALEX!          #
# To use it in your project :                                                               #
# * Remove or comment the lines corresponding to unused pins                                #
# * Rename the used signals according to the your project                                   #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

   # Clock 100 MHz
       NET "Clk"             LOC = V10 | IOSTANDARD = LVCMOS33 | Period = 100 MHz;
  
###########################################################################################################
#                                               16x2 LCD Expansion Module                                 # 
###########################################################################################################
###########################################################################################################
#                                            Expansion Connector's HEADER P6                           #
###########################################################################################################
# Clock 100 MHz
     NET "clk"             LOC = V10 | IOSTANDARD = LVCMOS33 | Period = 100 MHz;

     NET "lcd_e"           LOC = T4  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # Enable PIN of LCD
     NET "lcd_rs"          LOC = V7  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # Register Select PIN of LCD
     NET "lcd_rw"          LOC = U7  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # Read/Write PIN of LCD
    
  # Four bits LCD Data
     NET "lcd_db<7>"       LOC = R3  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # PIN 14 on LCD
     NET "lcd_db<6>"       LOC = V5  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # PIN 13 on LCD
     NET "lcd_db<5>"       LOC = U5  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # PIN 12 on LCD
     NET "lcd_db<4>"       LOC = V4  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST; # PIN 11 on LCD

Then save the project - always a good idea.  Now its time to 'compile' the code!  Implement a top module by clicking on the green arrrow:


Now generate a bitstream file:



Once that is complete generate a 'Bit File' and then upload that to the Mimas V2 Development board via your preferred method - by Python Script or by using the supplied uploader.  I use the uploader.


Ensure you have a power supply connected to the Vext input of the Expansion PCB (which is capable of supplying at least 7 Volts.  Then plug the expansion header into the P6 header socket.  When you connect it up you should be presented with the following image:


Cool beans!

At this point I should probably explain some of the code and how it works.  We added three files to the project in order to get things working.

  • lcd16x2_ctrl.vhd - The state machine for controlling the LCD display
  • pin_locations.UCF - The UCF file which tells the compiler
  • lcd16x2_ctrl_demo.vhd - a file to demonstrate the display in operation.

The code was written by a very clever German gentleman named Daniel Drescher and full credit goes to him for an excellent implementation of an VHDL Hitachi HD44780 display driver.

I'm not going to go into much detail about the lcd16x2_ctrl.vhd file except to say that it provides the method for controlling the pins on the display to go about getting the response required whether reading whether the display has correctly displayed something or writing data to the display.  Most people are only interested in write operation however the read operation can be useful for fault finding.

The file pin_locations.ucf tell Xilinx WebISE which pins on the FPGA are going to be used.  In the example above we used the pins associated with the P6 connector.  If another connector is needed then refer to the Mimas V2 instruction manual and schematic and update this file as necessary.

The 16x2_ctrl_demo.vhd file is the file of most interest.  It allows the designer to set the data to be sent and displayed on the 16x2 screen.

library ieee;
use ieee.std_logic_1164.all;

-------------------------------------------------------------------------------

entity lcd16x2_ctrl_demo is
  port (
    clk    : in  std_logic;
    lcd_e  : out std_logic;
    lcd_rs : out std_logic;
    lcd_rw : out std_logic;
    lcd_db : out std_logic_vector(7 downto 4));

end entity lcd16x2_ctrl_demo;

-------------------------------------------------------------------------------

The above lines of code tell the compiler to include some standard vhdl libraries and then implements an entity statement - tells the compiler the pin names we are going to use and what type of pin they are either input or output.  The pin names point towards their function.

clk - The free running clock to assist with the timings to control the display
lcd_e - the LCD enable pin
lcd_rs - the LCD register select pin
lcd_rw - the LCD read/write register pin
lcd_db - 4 pins used to control the data pins on the LCD display in 4 bit operation

-------------------------------------------------------------------------------

architecture behavior of lcd16x2_ctrl_demo is

  -- 
  signal timer : natural range 0 to 100000000 := 0;
  signal switch_lines : std_logic := '0';
  signal line1 : std_logic_vector(127 downto 0);
  signal line2 : std_logic_vector(127 downto 0);
  

  -- component generics
  constant CLK_PERIOD_NS : positive := 10;  -- 100 Mhz

  -- component ports
  signal rst          : std_logic;
  signal line1_buffer : std_logic_vector(127 downto 0);
  signal line2_buffer : std_logic_vector(127 downto 0);

The above lines are from the architecture statement.  It defines the behaviour of the FPGA. In this case it will drive the 16x2 LCD display.  It does this by implementing some internal signals (variables).  

The Signal timer is a timer which counts from zero to ten million.  This will be used to ensure that the timings for the reading and writing to the display are correct,

The signal switch lines is a variable to tell the FPGA to swap the top and bottom lines on the 16x2 LCD display.

The signals line1 and line2 are logic vectors to send the characters to be displayed to the 16x2 LCD display.

Next a constant clock period is set at 100 MHz or ten nano seconds and the clock is positive edge triggered.

Finally some further signals are created including a reset signal and some logic buffers for the characters to be sent to the 16x2 Display.

-------------------------------------------------------------------------------

begin  -- architecture behavior

  -- component instantiation
  DUT : entity work.lcd16x2_ctrl
    generic map (
      CLK_PERIOD_NS => CLK_PERIOD_NS)
    port map (
      clk          => clk,
      rst          => rst,
      lcd_e        => lcd_e,
      lcd_rs       => lcd_rs,
      lcd_rw       => lcd_rw,
      lcd_db       => lcd_db,
      line1_buffer => line1_buffer,
      line2_buffer => line2_buffer);

  rst <= '0';

The above lines begin the actual architecture statement.  The method of controlling the display is instantiated from the code written in lcd16x2_ctrl.vhd.  The clock period is set to match and the pins are mapped to ensure data is passed correctly between the two files.  Finally the reset pin is set low to ensure the display is ready to receive data.

-------------------------------------------------------------------------------

-- see the display's datasheet for the character map
  line1(127 downto 120) <= X"20"; 
  line1(119 downto 112) <= X"20";
  line1(111 downto 104) <= X"48";  -- H
  line1(103 downto 96)  <= X"65";  -- e
  line1(95 downto 88)   <= X"6c";  -- l
  line1(87 downto 80)   <= X"6c";  -- l
  line1(79 downto 72)   <= X"6f";  -- o
  line1(71 downto 64)   <= X"20";
  line1(63 downto 56)   <= X"57";  -- W
  line1(55 downto 48)   <= X"6f";  -- o
  line1(47 downto 40)   <= X"72";  -- r
  line1(39 downto 32)   <= X"6c";  -- l
  line1(31 downto 24)   <= X"64";  -- d
  line1(23 downto 16)   <= X"21";  -- !
  line1(15 downto 8)    <= X"20";
  line1(7 downto 0)     <= X"20";

  line2(127 downto 120) <= X"30";
  line2(119 downto 112) <= X"31";
  line2(111 downto 104) <= X"32";
  line2(103 downto 96)  <= X"33";
  line2(95 downto 88)   <= X"34";
  line2(87 downto 80)   <= X"35";
  line2(79 downto 72)   <= X"36";
  line2(71 downto 64)   <= X"37";
  line2(63 downto 56)   <= X"38";
  line2(55 downto 48)   <= X"39";
  line2(47 downto 40)   <= X"3a";
  line2(39 downto 32)   <= X"3b";
  line2(31 downto 24)   <= X"3c";
  line2(23 downto 16)   <= X"3d";
  line2(15 downto 8)    <= X"3e";
  line2(7 downto 0)     <= X"3f";

  line1_buffer <= line2 when switch_lines = '1' else line1;
  line2_buffer <= line1 when switch_lines = '1' else line2;

The above lines actually are the characters that will be sent to the display.  The more observant will notice that the values used are hexadecimal values for ascii characters.  If it was required to change the characters displayed on screen we would need to change these hexadecimal values to whatever we wanted.  

-------------------------------------------------------------------------------

-- switch lines every second
  process(clk)
  begin
    if rising_edge(clk) then
      if timer = 0 then
        timer <= 100000000;
        switch_lines <= not switch_lines;
      else
        timer <= timer - 1;
      end if;
    end if;
      
  end process;
end architecture behavior;

The above lines is the actual process the display will follow.  If the clock is positive and the timer is at zero then the timer is set to a hundred million.  This equates to one second as 100,000,000 counts of a 100 MHz clock is one second.  The characters on the top and bottom lines are swapped.  Then the timer is decremented and the process ends.  

If we wanted to change the characters being displayed we need to change the section shown here:

-- see the display's datasheet for the character map
  line1(127 downto 120) <= X"20"; 
  line1(119 downto 112) <= X"20";
  line1(111 downto 104) <= X"48";  -- H
  line1(103 downto 96)  <= X"65";  -- e
  line1(95 downto 88)   <= X"6c";  -- l
  line1(87 downto 80)   <= X"6c";  -- l
  line1(79 downto 72)   <= X"6f";  -- o
  line1(71 downto 64)   <= X"20";
  line1(63 downto 56)   <= X"57";  -- W
  line1(55 downto 48)   <= X"6f";  -- o
  line1(47 downto 40)   <= X"72";  -- r
  line1(39 downto 32)   <= X"6c";  -- l
  line1(31 downto 24)   <= X"64";  -- d
  line1(23 downto 16)   <= X"21";  -- !
  line1(15 downto 8)    <= X"20";
  line1(7 downto 0)     <= X"20";

  line2(127 downto 120) <= X"30";
  line2(119 downto 112) <= X"31";
  line2(111 downto 104) <= X"32";
  line2(103 downto 96)  <= X"33";
  line2(95 downto 88)   <= X"34";
  line2(87 downto 80)   <= X"35";
  line2(79 downto 72)   <= X"36";
  line2(71 downto 64)   <= X"37";
  line2(63 downto 56)   <= X"38";
  line2(55 downto 48)   <= X"39";
  line2(47 downto 40)   <= X"3a";
  line2(39 downto 32)   <= X"3b";
  line2(31 downto 24)   <= X"3c";
  line2(23 downto 16)   <= X"3d";
  line2(15 downto 8)    <= X"3e";
  line2(7 downto 0)     <= X"3f";

It really helps to have an ascii character map with the hexadecimal values:


Just for fun, I changed the code to this:

-- see the display's datasheet for the character map
  line1(127 downto 120) <= X"4E";  -- N
  line1(119 downto 112) <= X"75";  -- u
  line1(111 downto 104) <= X"6D";  -- m
  line1(103 downto 96)  <= X"61";  -- a
  line1(95 downto 88)   <= X"74";  -- t
  line1(87 downto 80)   <= X"6F";  -- o
  line1(79 downto 72)   <= X"20";  -- space 
  line1(71 downto 64)   <= X"4C";  -- L
  line1(63 downto 56)   <= X"61";  -- a
  line1(55 downto 48)   <= X"62";  -- b
  line1(47 downto 40)   <= X"73";  -- s
  line1(39 downto 32)   <= X"20";  -- space
  line1(31 downto 24)   <= X"46";  -- F
  line1(23 downto 16)   <= X"50";  -- P
  line1(15 downto 8)    <= X"47";  -- G
  line1(7 downto 0)     <= X"41";  -- A

  line2(127 downto 120) <= X"56";  -- V
  line2(119 downto 112) <= X"48";  -- H
  line2(111 downto 104) <= X"44";  -- D
  line2(103 downto 96)  <= X"4C";  -- L
  line2(95 downto 88)   <= X"20";  -- space
  line2(87 downto 80)   <= X"4C";  -- L
  line2(79 downto 72)   <= X"43";  -- C
  line2(71 downto 64)   <= X"44";  -- D
  line2(63 downto 56)   <= X"20";  -- space
  line2(55 downto 48)   <= X"45";  -- E
  line2(47 downto 40)   <= X"78";  -- x
  line2(39 downto 32)   <= X"61";  -- a
  line2(31 downto 24)   <= X"6D";  -- m
  line2(23 downto 16)   <= X"70";  -- p
  line2(15 downto 8)    <= X"6C";  -- l
  line2(7 downto 0)     <= X"65";  -- e

I then recompiled and uploaded the new bitstream file to the FPGA development board.  Here is a quick video showing what happened:



Well that's all for now.  Hope this helps people out!  Here is the code if people need it:


Cheers - Langster!

Monday, 18 January 2016

Numato Mimas V2 controlling a 16x2 LCD display

A blog reader has asked me to write a tutorial about controlling a 16x2 LCD display using the Mimas V2 FPGA development board from Numato Labs.

The display itself could be any 16x2 LCD display but I bought one especially from Numato labs as it makes it more simple to connect to the Mimas V2 FPGA development board.

Here is a picture of the display:

16x2 LCD displays with onboard 5V regulator
In order to use the LCD display with a Mimas or Elbert V2 Development board an external 7 to 9 Vdc power supply is required.  The manual for the display is provided on Numato's website:

LCD Expansion Module User Manual

The manual provides information on the LCD display has been constructed and how it should be used and connected to an FGPA development board such as the Elbert V2 or Mimas V2 FPGA development boards.  The pin connections are below:

16x2 Expansion LCD Pin Connections
The schematic Diagram is also provided in the manual but for completeness it is present below:

The display has been physically designed to connect to one of the spare input header sockets on the Elbert or Mimas V2 FPGA development boards.  It could be connected to any FPGA development board or Micro-controller however as long as the pin connections are known.

LCD Display Connected to the P6 Header socket on the Mimas V2
There is some example code available for testing and learning how to use the LCD display available from Numato's website.  It provides an example project to get users started.

LCD Display16x2 Example project

Download the example project and uncompress it to a folder of your choice.

The project has been written in verilog which I'm not too familiar with.  I am slowly learning VHDL for when I use FPGAS however verilog is similar and I know the code works as intended.  If we load the project up in Xilinx WebISE we are presented with the following:

The first thing required is to change the project settings to relate to the FPGA device on the Mimas V2 development board.  At the moment it is set for use with an Elbert V2 development board.  Right click on the project hierachy box and select "Design Properties":

Then change all of the information in the windows that opens to match the picture below:

Mimas V2 Design Properties for LCD Example project
Next we need to update the UCF file for the one relating to the Mimas V2 FPGA development board. At the moment its written to reflect the pin connections on the Elbert V2 board.  We need to change it to reflect the Mimas V2 board (which is what we are using for this example).

Right click on the UCF file and remove it from the project:


Click on 'Yes' when the confirmation window is displayed.

Now right click on the project hierachy box and select "Add Source"and then navigate to the UCF folder where the project was unzipped on your hard disk.  Select the UCF file called MimasV2.ucf and click 'Open' and then click 'Ok' on the confirmation windows that appear.


Now double click on the newly added UCF file to open in for editing in Xilinx WebISE:

Here is where things get interesting.  I looked at the pin labels on P6 of the Mimas V2 Development board and the pin labels on the LCD expansion PCB.  I found that Row 1 of the Development board is connected to Row 2 of the LCD expansion PCB and that Row 2 of the Development board was connected to Row 1 of the LCD Expansion PCB.  Because these are reversed the supplied UCF file is unfortunately not correct.  I verified this with a multimeter (and a lot of patience) and re-wrote the UCF file to create the correct connections:

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# This file is a .ucf for 16x2 LCD Expansion Modules on Mimas V2 modified by ALEX!          #
# To use it in your project :                                                               #
# * Remove or comment the lines corresponding to unused pins                                #
# * Rename the used signals according to the your project                                   #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

   # Clock 100 MHz
       NET "Clk"             LOC = V10 | IOSTANDARD = LVCMOS33 | Period = 100 MHz;
  
####################################################################################################################################################
#                                               16x2 LCD Expansion Module                                                                          #
####################################################################################################################################################
####################################################################################################################################################
#                                            Expansion Connector's HEADER P6                                                                   #
####################################################################################################################################################
     NET "en"               LOC = T4  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # Enable PIN of LCD
     NET "rs"               LOC = V7  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # Register Select PIN of LCD
     NET "rw"               LOC = U7  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # Read/Write PIN of LCD
    
  # Four bits LCD Data
     NET "LCD_out[3]"       LOC = R3  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # PIN 14 on LCD
     NET "LCD_out[2]"       LOC = V5  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # PIN 13 on LCD
     NET "LCD_out[1]"       LOC = U5  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # PIN 12 on LCD
     NET "LCD_out[0]"       LOC = V4  | IOSTANDARD = LVCMOS33  | DRIVE = 8  | SLEW = FAST;                 # PIN 11 on LCD  

# P6 Connections

# pin 1 (U7) is connected to pin 2 on header which is RW (pin 5) on LCD  
# pin 2 (V7) is connected to pin 1 on header which is RS (pin 4) on LCD
# pin 3 (T4) is connected to pin 4 on header which is EN (pin 6) on LCD
# pin 4 (V4) is connected to pin 3 on header which is D0 (pin 11) on LCD
# pin 5 (U5) is connected to pin 6 on header which is D1 (pin 12) on LCD
# pin 6 (V5) is connected to pin 5 on header which is D2(pin 13) on LCD
# pin 7 (R3) is connected to pin 8 on header which is D3(pin 14) on LCD
# pin 8 (T3) is connected to pin 7 on header which is not connected LCD
# pin 9 (GND) is connected to pin 10 on header which is (GND ) on LCD
# pin 10 (GND) is connected to pin 9 on header which is (GND ) on LCD
# pin 11 (+3v3) is connected to pin 12 on header 
# pin 12 (+3v3) is connected to pin 11 on header 

####################################################################################################################################################

Copy and paste the above code into the UCF text editor and save the project.

Now it's time to compile the project and generate a bit file ready to upload to the Mimas V2 Development board. Click on the green Arrow in the middle of the screen to compile the project:

Once that is complete generate a 'Bit File' and then upload that to the Mimas V2 Development board via your preferred method - by Python Script or by using the supplied uploader.  I use the uploader.


Ensure you have a power supply connected to the Vext input of the Expansion PCB (which is capable of supplying at least 7 Volts.  When you connect it up you should be presented with the following images:



I know they are upside down but it does prove the display is working!

If you wish to change the message that is displayed on the LCD then the following lines of code will be of interest:

// Shift the display right.
assign memory[19]={2'b00,8'h1C}; 

// Character that should be displayed on the LCD.
assign memory[20]={2'b10,"W"};
assign memory[21]={2'b10,"E"};
assign memory[22]={2'b10,"L"};
assign memory[23]={2'b10,"C"};
assign memory[24]={2'b10,"O"};
assign memory[25]={2'b10,"M"};
assign memory[26]={2'b10,"E"};
assign memory[27]={2'b10," "};
assign memory[28]={2'b10,"T"};
assign memory[29]={2'b10,"O"};

// Shift to second Line of LCD
assign memory[30]={2'b00,8'h40};

// Space that should appear on LCD.                              
assign memory[31]={2'b10," "};

// Shift the display right 
assign memory[32]={2'b00,8'h1C};                              

// Character that should be displayed on the LCD.  
assign memory[33]={2'b10,"N"};
assign memory[34]={2'b10,"U"};
assign memory[35]={2'b10,"M"};
assign memory[36]={2'b10,"A"};
assign memory[37]={2'b10,"T"};
assign memory[38]={2'b10,"O"};
assign memory[39]={2'b10," "};

assign memory[40]={2'b10,"L"};
assign memory[41]={2'b10,"A"};
assign memory[42]={2'b10,"B"};

The first line shifts the display right by three characters.  As the display has availability for 16 characters in each line this places the first character to be displayed at position 4 on the first line.

The next ten lines assign the memory register with characters to be displayed.  If you wanted to these can be changed to whichever ascii character required.  Change the characters in the quotation marks but remember that a space must be " " and not "".  Using "" causes three horizontal lines to be displayed.  I changed the code to that displayed below:

// Shift the display right.
assign  memory[19]={2'b00,8'h1C}; 

// Character that should be displayed on the LCD.
assign  memory[20]={2'b10,"V"};
assign  memory[21]={2'b10,"E"};
assign  memory[22]={2'b10,"R"};
assign  memory[23]={2'b10,"I"};
assign  memory[24]={2'b10,"L"};
assign  memory[25]={2'b10,"O"};
assign  memory[26]={2'b10,"G"};
assign  memory[27]={2'b10," "};
assign  memory[28]={2'b10,"I"};
assign  memory[29]={2'b10,"S"};

// Shift to second Line of LCD
assign  memory[30]={2'b00,8'h40};

// Space that should appear on LCD.                              
assign  memory[31]={2'b10," "};

// Shift the display right 
assign  memory[32]={2'b00,8'h1C};                              

// Character that should be displayed on the LCD.   
assign  memory[33]={2'b10,"H"};
assign  memory[34]={2'b10,"A"};
assign  memory[35]={2'b10,"R"};
assign  memory[36]={2'b10,"D"};
assign  memory[37]={2'b10," "};
assign  memory[38]={2'b10,"T"};
assign  memory[39]={2'b10,"O"};

assign  memory[40]={2'b10,"U"};
assign  memory[41]={2'b10,"S"};
assign  memory[42]={2'b10,"E"};

I then re-compiled the code and re-uploaded it to the Mimas V2 Development board.  Here is what I got:



In order to reduce the number of spaces at the beginning the lines:

assign  memory[19]={2'b00,8'h1C}; 
assign  memory[32]={2'b00,8'h1C};     

must be changed to suit the requirements.  The section 2'b00 section sets the RS and RW registers to zero.  Setting the RS register to zero means the display is being sent a command by the FPGA. The RW pin is 0 when sending information to the display and 1 when displaying items on the display.  I am not sure what the h1C part of the code performs.

I have found that by changing the line to

assign  memory[19]={2'b00,8'h1B}; 

moves the text starting position to the first block on the display.  I also increased the amount of memory present in the register by changing this line from 43 to 44:

// Specify the depth of block memory where the data and command are to be saved.
parameter Length=44;

That allowed me to obtain the following result:


That's all for now.  I will investigate further as to how this code works.

Take care - Langster