FPGA DE2-115 + LCD

Status
Not open for further replies.

Oscar99haha

Newbie
Joined
Jul 13, 2022
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
29
Hi everyone, im so new to this Verilog FPGA DE2-115 Altera. Could anyone shows me the way in displaying the LCD with simple "Hello World" using verilog? i've been trying for myself for the past 2 weeks and is really struggling me. Thank you so much
 

If you've been struggling for 2 weeks, then you must have written some Verilog. Post the code you've written that doesn't work and an explanation how the code doesn't behave as you expect.

We won't do the work for you but can point out what you need to change in work you've already done.
 

Code:
module testingLCD(SW,LEDR,LCD_DATA, LCD_EN, LCD_RW, LCD_ON, LCD_BLON);

input [17:0] SW;
inout [7:0] LCD_DATA;
output [17:0] LEDR;
output LCD_EN;
output LCD_ON;
output LCD_BLON;
output LCD_RW;

reg[7:0] data;
reg rw;
reg en;

assign LCD_ON= 1'b1;
assign LCD_BLON = 1'b1;

assign LEDR = SW;


always@(SW)
begin
if (SW[17]==1'b1)
begin
rw = 1'b1;
en = 1'b1;
data <= LCD_DISPLAY(0);
end
end

function [7:0] LCD_DISPLAY;
input [3:0] value;
begin
if(value==0)
LCD_DISPLAY = 7'b01010000; //print words P
end
endfunction
assign LCD_DATA = data;
assign LCD_EN = en;
assign LCD_RW = rw;

endmodule


so in my code here, i was trying to print a word P on my LCD display when i put high on my SW17. but it wont work out anyway. Could you help me to point out my problem?

[moderator action: added code tags]
 
Last edited by a moderator:

Without knowing what any of your signals are (because you haven't told us or put any comments in your code or shown us a schematic) all we can do is guess.

Is LCD_BLON a blanking signal? Which you've asserted?

I'm not really a verilog guy, but it looks to me like data gets assigned 00101000 when SW occurs. So, what does that mean?

Have you simulated this? Have you looked at signals with a scope?
 

I do not code any HDL language, but from all perspectives the above code seems is not even close to do anything. First of all, you did not mention what LCD controller you are using at the actual device, so we should assume as being an Hitashi compatile one. Secondly, being the case, the default setup on this controller is data bus handled only with the upper nibble D4-D7, not the whole byte D0-D7 as you did.; In addition, prior to issuing any character it is expected to issue init commands in order to select for example the 'font' size, cursor positioning, etc...Moreover, you are doind nothing with the control signals, as for example the EN is set to 1 and left to this level forever.
 


Hi,

I see no clock at all.
I see signals set to 1 but never to 0.

But I´m not experienced with HDL.

Klaus
 

I have this sample code to display counter on LCD module HD44780 same as your FPGA board has!
You just need to add tie hi ouput pin for LCD_ON. LCDBLON should not be used as per user manual for DE2-115
Code:
module top(
   // Outputs
   DATA_BUS, LCD_E, LCD_RS,
   // Inputs
   clk_12Mhz, reset
   );
   input                clk_12Mhz;              // To LCD of LCD.v
   input                reset;                  // To LCD of LCD.v, ...

   output [7:0]         DATA_BUS;               // From LCD of LCD.v
   output               LCD_E;                  // From LCD of LCD.v
   output               LCD_RS;                 // From LCD of LCD.v

   wire                 CLK_10HZ;
   wire [15:0]          count;
   wire [18:0]          bcd_count;

   //BCD to ASCII
   wire [7:0] B5 = {4'h3, bcd_count[3:0]};
   wire [7:0] B4 = {4'h3, bcd_count[7:4]};
   wire [7:0] B3 = {4'h3, bcd_count[11:8]};
   wire [7:0] B2 = {4'h3, bcd_count[15:12]};
   wire [7:0] B1 = {4'h3, 1'b0, bcd_count[18:16]};

   LCD LCD(// Outputs
           .LCD_RS                      (LCD_RS),
           .LCD_E                       (LCD_E),
           .CLK_10HZ                    (CLK_10HZ),
           .LCD_RW                      (),
           .DATA_BUS                    (DATA_BUS[7:0]),
           // Inputs
           .reset                       (reset),
           .clk_12Mhz                   (clk_12Mhz),
           .C1L1                        (" "),
           .C2L1                        (" "),
           .C3L1                        ("C"),
           .C4L1                        ("O"),
           .C5L1                        ("U"),
           .C6L1                        ("N"),
           .C7L1                        ("T"),
           .C8L1                        ("E"),
           .C9L1                        ("R"),
           .C10L1                       ("-"),
           .C11L1                       ("T"),
           .C12L1                       ("E"),
           .C13L1                       ("S"),
           .C14L1                       ("T"),
           .C15L1                       (" "),
           .C16L1                       (" "),
           .C1L2                        (" "),
           .C2L2                        (" "),
           .C3L2                        (" "),
           .C4L2                        (" "),
           .C5L2                        (" "),
           .C6L2                        (" "),
           .C7L2                        (B1),
           .C8L2                        (B2),
           .C9L2                        (B3),
           .C10L2                       (B4),
           .C11L2                       (B5),
           .C12L2                       (" "),
           .C13L2                       (" "),
           .C14L2                       (" "),
           .C15L2                       (" "),
           .C16L2                       (" "));

   counter counter(// Outputs
                   .count               (count[15:0]),
                   // Inputs
                   .reset               (reset),
                   .clk                 (clk_12Mhz),
                   .clk_en              (CLK_10HZ));

   binbcd16 binbcd16(// Outputs
                     .P                 (bcd_count[18:0]),
                     // Inputs
                     .B                 (count[15:0]));
endmodule // top

Hope this helps!
--- Updated ---

Rest of the code...
Code:
module binbcd16(B,P);
   input [15:0] B;
   output [18:0] P;
   reg [18:0]    P;
   reg [35:0]    z;
   integer       i;
   always @(B) begin
      for(i = 0; i <= 35; i = i+1)
        z[i] = 0;
      z[18:3] = B;
      for(i = 0; i <= 12; i = i+1) begin
         if(z[19:16] > 4)  
           z[19:16] = z[19:16] + 3;
         if(z[23:20] > 4)    
           z[23:20] = z[23:20] + 3;
         if(z[27:24] > 4)    
           z[27:24] = z[27:24] + 3;
         if(z[31:28] > 4)    
           z[31:28] = z[31:28] + 3;
         if(z[35:32] > 4)    
           z[35:32] = z[35:32] + 3;
         z[35:1] = z[34:0];
      end    
      P = z[35:16];  
   end
endmodule

module counter(
   // Outputs
   count,
   // Inputs
   reset, clk,
   clk_en              
   );

   input reset,clk;
   input clk_en;
   output [15:0] count;
   reg [15:0] count;
   always @(posedge clk or posedge reset)
     if (reset) count <= 0;
     else if (clk_en) count <= count + 1;
endmodule // counter
--- Updated ---

Rest of the code continue....
Code:
module LCD(
   // Outputs
   LCD_RS, LCD_E, CLK_10HZ, LCD_RW, DATA_BUS,
   // Inputs
   reset, clk_12Mhz, C1L1, C2L1, C3L1, C4L1, C5L1, C6L1, C7L1, C8L1, C9L1,
   C10L1, C11L1, C12L1, C13L1, C14L1, C15L1, C16L1, C1L2, C2L2, C3L2, C4L2,
   C5L2, C6L2, C7L2, C8L2, C9L2, C10L2, C11L2, C12L2, C13L2, C14L2, C15L2,
   C16L2
   );
   input reset, clk_12Mhz;
   output LCD_RS;
   output LCD_E;
   output CLK_10HZ;
   output LCD_RW;
   input [7:0] C1L1,C2L1,C3L1,C4L1,C5L1,C6L1,C7L1,C8L1,C9L1;
   input [7:0] C10L1,C11L1,C12L1,C13L1,C14L1,C15L1,C16L1;
   input [7:0] C1L2,C2L2,C3L2,C4L2,C5L2,C6L2,C7L2,C8L2,C9L2;
   input [7:0] C10L2,C11L2,C12L2,C13L2,C14L2,C15L2,C16L2;
   output [7:0] DATA_BUS;
   reg LCD_RS;
   reg LCD_E;
   reg CLK_400HZ;
   reg LCD_RW;

   parameter RESET1 = 0,
     RESET2 = 1,
     RESET3 = 2,
     FUNC_SET = 3,
     MODE_SET = 4,
     DISPLAY_ON = 5,
     WRITE_CHAR1 = 6,
     WRITE_CHAR2 = 7,
     WRITE_CHAR3 = 8,
     WRITE_CHAR4 = 9,
     WRITE_CHAR5 = 10,
     WRITE_CHAR6 = 11,
     WRITE_CHAR7 = 12,
     WRITE_CHAR8 = 13,
     WRITE_CHAR9 = 14,
     WRITE_CHAR10 = 15,
     WRITE_CHAR11 = 16,
     WRITE_CHAR12 = 17,
     WRITE_CHAR13 = 18,
     WRITE_CHAR14 = 19,
     WRITE_CHAR15 = 20,
     WRITE_CHAR16 = 21,
     RETURN_HOME = 22,
     TOGGLE_E = 23,
     HOLD = 24,
     DISPLAY_OFF = 25,
     DISPLAY_CLEAR = 26; // these are the states
   reg [4:0] state, next_command;
   reg [7:0] DATA_BUS;
   reg [15:0] CLK_COUNT_400HZ;
   reg [7:0]  CLK_COUNT_10HZ;
   reg        CLK_10HZ,LINE;
   always @(posedge clk_12Mhz or posedge reset) begin
      if (reset) begin
         CLK_COUNT_400HZ <= 'h0000;
         CLK_400HZ <= 1'b0;
      end else begin
         if (CLK_COUNT_400HZ == 'h7530) begin
            CLK_COUNT_400HZ <= 'h0000;
            CLK_400HZ <= 1'b1;
         end else begin
            CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
            CLK_400HZ <= 1'b0;
         end
      end
   end

   // GENERATE 1 SEC CLOCK SIGNAL FOR SECOND COUNT PROCESS
   always @(posedge clk_12Mhz or posedge reset) begin
      if (reset) begin
         CLK_COUNT_10HZ <= 8'h00;
         CLK_10HZ <= 1'b0;
      end else begin
         CLK_10HZ <= CLK_400HZ & (CLK_COUNT_10HZ == 19);
         if (CLK_400HZ)
           if (CLK_COUNT_10HZ == 19)
             CLK_COUNT_10HZ <= 8'h00;
           else
             CLK_COUNT_10HZ <= CLK_COUNT_10HZ + 1;
      end
   end
--- Updated ---

Rest of the code continue ....
Code:
   always @(posedge clk_12Mhz or posedge reset) begin
      if (reset) begin
         state <= RESET1;
         DATA_BUS <= 8'h38;
         next_command <= RESET2;
         LCD_E <= 1'b1;
         LCD_RS <= 1'b0;
         LCD_RW <= 1'b0;
      end else if (CLK_400HZ) begin
         // SEND TIME TO LCD          
         case (state)
           // Set Function to 8-bit transfer and 2 line display with 5x8 Font size
           // see Hitachi HD44780 family data sheet for LCD command and timing details
           RESET1 : begin
              LINE   <= 1'b1;
              LCD_E  <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h38;
              state <= TOGGLE_E;
              next_command <= RESET2;
           end
           RESET2 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h38;
              state <= TOGGLE_E;
              next_command <= RESET3;
           end
           RESET3 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h38;
              state <= TOGGLE_E;
              next_command <= FUNC_SET;
           end
           // EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
           FUNC_SET : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;                      
              DATA_BUS <= 8'h38;
              state <= TOGGLE_E;
              next_command <= DISPLAY_OFF;
           end
           // Turn off Display and Turn off cursor
           DISPLAY_OFF : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h08;
              state <= TOGGLE_E;
              next_command <= DISPLAY_CLEAR;
           end
           // Turn on Display and Turn off cursor
           DISPLAY_CLEAR : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h01;
              state <= TOGGLE_E;
              next_command <= DISPLAY_ON;
           end
           // Turn on Display and Turn off cursor
           DISPLAY_ON : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
             LCD_RW <= 1'b0;
              DATA_BUS <= 8'h0C;
              state <= TOGGLE_E;
              next_command <= MODE_SET;
           end
           // Set write mode to auto increment address and move cursor to the right
           MODE_SET : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b0;
              LCD_RW <= 1'b0;
              DATA_BUS <= 8'h06;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR1;
           end
           // Write ASCII hex character in first LCD character location
           WRITE_CHAR1 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C1L1;
              else
                DATA_BUS <= C1L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR2;
           end
           // Write ASCII hex character in second LCD character location
           WRITE_CHAR2 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <=C2L1;
              else
                DATA_BUS <= C2L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR3;
           end
           // Write ASCII hex character in third LCD character location
           WRITE_CHAR3 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C3L1 ;
              else
                DATA_BUS <= C3L2 ;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR4;
           end
           // Write ASCII hex character in fourth LCD character location
           WRITE_CHAR4 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C4L1;
              else
                DATA_BUS <= C4L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR5;
           end
           // Write ASCII hex character in fifth LCD character location
           WRITE_CHAR5 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C5L1;
              else
                DATA_BUS <= C5L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR6;
           end
           // Write ASCII hex character in sixth LCD character location
           WRITE_CHAR6 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C6L1 ;
              else
                DATA_BUS <= C6L2 ;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR7;
           end
           // Write ASCII hex character in seventh LCD character location
           WRITE_CHAR7 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C7L1;
              else
                DATA_BUS <= C7L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR8;
           end
           // Write ASCII hex character in eighth LCD character location
           WRITE_CHAR8 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <= C8L1;
              else
                DATA_BUS <= C8L2;
              state <= TOGGLE_E;
              next_command <= WRITE_CHAR9;
           end
          WRITE_CHAR9 : begin
              LCD_E <= 1'b1;
              LCD_RS <= 1'b1;
              LCD_RW <= 1'b0;
              if (LINE == 1'b0)
                DATA_BUS <=C9L1;
              else
                DATA_BUS <= C9L2;
              state <= TOGGLE_E;                      
              next_command <= WRITE_CHAR10;
           end
--- Updated ---

Can't past the code here so attaching it......
 

Attachments

  • top.rar
    2.6 KB · Views: 233
Last edited:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…