Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Spartan 3E LCD verilog code problem

Status
Not open for further replies.

arishsu

Member level 3
Joined
Sep 10, 2013
Messages
66
Helped
6
Reputation
12
Reaction score
6
Trophy points
8
Location
India
Activity points
422
I tried to run this code on the fpga, but it is showing some garbage characters.
I got this code from the web. Please help me to correct the code.
Code:
module test_lcd(clk,sf_e,rs,rw,a,b,c,d,e);

input clk;//50Mhz onboard clk
output reg sf_e;//1 lcd access (0 strataFlash access)
output reg e;//enable(1)
output reg rs;//Register select(1 data bits for R/W)
output reg rw;//Read/Write, 1/0
output reg a;//1st data bits (to form a nibble)
output reg b;//2nd data bits (to form a nibble)
output reg c;//3rd data bits (to form a nibble)
output reg d;//4th data bits (to form a nibble)

reg[26:0] count=0;//27-bit count. 0 to 128M-1, over 2 secs
reg[5:0] code;//6-bit different signals to give out
reg refresh;//refresh lcd rate @ about 25Hz

always@(posedge clk)
begin
  count <= count+1;
  case (count[26:21]) //as top 6 bits change
 //power on init can be carried out before this loop to avoid the flickers
  0: code <= 6'h03;//power on init sequence
  1: code <= 6'h03;//this is needed atleast once
  2: code <= 6'h03;//when LCD is powered on
  3: code <= 6'h03;//it flickers existing char display
//table 5-3 function set
//send 00 and upper nibble 0010, then 00 and lower nibble 10xx
  4: code <= 6'h02;//function set, upper nibble 0010
  5: code <= 6'h08;//lower nibble 1000(10xx)
  
//table 5-3, entry mode
//send 00 and upper nibble 0000, then 00 and lower nibble 01 I/D S
//last 2 bit of the lower nibble I/D bit(increment 1 decrement 0)
  6: code <= 6'h00;//see table, upper nibble 0000, then lower nibble
  7: code <= 6'h06;//0110 incr, shift disabled

//table 5-3,display on/off
//send 00 and upper nibble 0000, then 00 and lower nibble 1DCB
//D:1, show char represented by code in DDR, 0, don't but code remains
//B:1, show cursor, 0, don't
//C:1, cursor blinks (if shown), 0, dont blink (if shown)
  8: code <= 6'h00;//display on/off, upper nibble 0000
  9: code <= 6'h0C;//lower nibble 1100(1 D C B)
  
//table 5-3 clear display, 00 and upper nibble 0000, then 00 and lower nibble 0001
  10: code <= 6'h00;//clear display, 00 and upper nibble 0000
  11: code <= 6'h01;//then 00 and lower nibble 0001
  
//charecters are then given out. cursor will advance to the right
//table 5-3, write data to DD RAM (or CG RAM)
//fig 5-4, 'H,' send 10 and upper nibble 0100, then 10 and lower nibble 1000
  12: code <= 6'h24;//'H' higher nibble
  13: code <= 6'h28;//'H'lower nibble
  14: code <= 6'h26;//e
  15: code <= 6'h25;
  16: code <= 6'h26;//l
  17: code <= 6'h2C;
  18: code <= 6'h26;//l
  19: code <= 6'h2C;
  20: code <= 6'h26;//o
  21: code <= 6'h2F;
  22: code <= 6'h22;//,
  23: code <= 6'h2C;
  
//table 5-3, set DDR address
//position the cursor on to the start of the 2nd line
//send 00 and upper nibble 1???, ??? is the highest 3 bit of the DDR
//address to move the cursor to, then 00 and lower 4 bits of the address
//so ??? is 100 and then 0000 for h40
  24: code <= 6'b001100;//position cursor to 2nd line upper nibble
  25: code <= 6'b000000;//lower nibble: h0

//charecters are then given out. cursor will advance to the right
  26: code <= 6'h25;//W
  27: code <= 6'h27;
  28: code <= 6'h26;//o
  29: code <= 6'h2F;
  30: code <= 6'h27;//r
  31: code <= 6'h22;
  32: code <= 6'h26;//l
  33: code <= 6'h2C;
  34: code <= 6'h26;//d
  35: code <= 6'h24;
  36: code <= 6'h22;//!
  37: code <= 6'h21;
  
//Table 5-3, Read Busy Flag and address
//send 01 BF (Busy Flag) xxx, then, 01xxxx
//idling
  default: code <=6'h10;//the rest unused time
  endcase
  
//refresh (enable) LCD when bit 20 of the count is 1
//it flips when counted up to 2M, and flips again after another 2M
  refresh <=count[20];//flip rate about 25(50MHz/2^21=2M)
  sf_e <= 1;
  {e,rs,rw,a,b,c,d} <= {refresh, code};
  
end //always
endmodule

And this is the ucf file.

Code:
NET "clk" LOC = "C9" | IOSTANDARD = LVCMOS33 ;
NET "sf_e" LOC = "D16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "e" LOC = "M18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "rs" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "rw" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
# The LCD four-bit data interface is shared with the StrataFlash.
NET "a" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "b" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "c" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "d" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 

hi, if you can tell me what to be displayed ,then i can help you.
 
Last edited by a moderator:

Anything. A simple hello world program for example.
 

module lcd(clk,sf_ce0, lcd_rs, lcd_rw,
lcd_e, lcd_4, lcd_5, lcd_6, lcd_7);
parameter k = 18;
input clk; // synthesis attribute PERIOD clk "50 MHz"
// synthesis attribute PERIOD clk "50 MHz"
reg [k+8:0] count=0;
output reg sf_ce0; // high for full LCD access
reg lcd_busy=1;
reg lcd_stb;
reg [5:0] lcd_code;
reg [6:0] lcd_stuff;
output reg lcd_rs;
output reg lcd_rw;
output reg lcd_7;
output reg lcd_6;
output reg lcd_5;
output reg lcd_4;
output reg lcd_e;
reg [127:0] input1,input2;
initial
begin
input1 = " hello ";
input2 = " everyone ";
end
always @ (posedge clk) begin
count <= count + 1;
sf_ce0 <= 1;
case (count[k+8:k+2])
0: lcd_code = 6'h03; // power-on initialization
1: lcd_code = 6'h03;
2: lcd_code = 6'h03;
3: lcd_code = 6'h02;
4: lcd_code = 6'h02; // function set
5: lcd_code = 6'h08;
6: lcd_code = 6'h00; // entry mode set
7: lcd_code = 6'h06;
8: lcd_code = 6'h00; // display on/off control
9: lcd_code = 6'h0C;
10: lcd_code = 6'h00; // display clear
11: lcd_code = 6'h01;



12: lcd_code = {2'b10,input1[127:124]};
13: lcd_code = {2'b10,input1[123:120]};

14: lcd_code = {2'b10,input1[119:116]};
15: lcd_code = {2'b10,input1[115:112]};

16: lcd_code = {2'b10,input1[111:108]};
17: lcd_code = {2'b10,input1[107:104]};

18: lcd_code = {2'b10,input1[103:100]};
19: lcd_code = {2'b10,input1[99:96]};

20: lcd_code = {2'b10,input1[95:92]};
21: lcd_code = {2'b10,input1[91:88]};

22: lcd_code = {2'b10,input1[87:84]};
23: lcd_code = {2'b10,input1[83:80]};

24: lcd_code = {2'b10,input1[79:76]};
25: lcd_code = {2'b10,input1[75:72]};

26: lcd_code = {2'b10,input1[71:68]};
27: lcd_code = {2'b10,input1[67:64]};

28: lcd_code = {2'b10,input1[63:60]};
29: lcd_code = {2'b10,input1[59:56]};

30: lcd_code ={2'b10,input1[55:52]};
31: lcd_code = {2'b10,input1[51:48]};

32: lcd_code = {2'b10,input1[47:44]};
33: lcd_code = {2'b10,input1[43:40]};

34: lcd_code = {2'b10,input1[39:36]};
35: lcd_code = {2'b10,input1[35:32]};

36: lcd_code = {2'b10,input1[31:28]};
37: lcd_code = {2'b10,input1[27:24]};

38: lcd_code = {2'b10,input1[23:20]};
39: lcd_code = {2'b10,input1[19:16]};

40: lcd_code = {2'b10,input1[15:12]};
41: lcd_code = {2'b10,input1[11:08]};

42: lcd_code = {2'b10,input1[07:04]};
43: lcd_code = {2'b10,input1[03:00]};

44: lcd_code = 6'h0c;
45: lcd_code = 6'h00;

46: lcd_code = {2'b10,input2[127:124]};
47: lcd_code = {2'b10,input2[123:120]};

48: lcd_code = {2'b10,input2[119:116]};
49: lcd_code = {2'b10,input2[115:112]};

50: lcd_code = {2'b10,input2[111:108]};
51: lcd_code = {2'b10,input2[107:104]};

52: lcd_code = {2'b10,input2[103:100]};
53: lcd_code = {2'b10,input2[99:96]};

54: lcd_code = {2'b10,input2[95:92]};
55: lcd_code = {2'b10,input2[91:88]};

56: lcd_code = {2'b10,input2[87:84]};
57: lcd_code = {2'b10,input2[83:80]};

58: lcd_code = {2'b10,input2[79:76]};
59: lcd_code = {2'b10,input2[75:72]};

60: lcd_code = {2'b10,input2[71:68]};
61: lcd_code = {2'b10,input2[67:64]};

62: lcd_code = {2'b10,input2[63:60]};
63: lcd_code = {2'b10,input2[59:56]};

64: lcd_code ={2'b10,input2[55:52]};
65: lcd_code = {2'b10,input2[51:48]};

66: lcd_code = {2'b10,input2[47:44]};
67: lcd_code = {2'b10,input2[43:40]};

68: lcd_code = {2'b10,input2[39:36]};
69: lcd_code = {2'b10,input2[35:32]};

70: lcd_code = {2'b10,input2[31:28]};
71: lcd_code = {2'b10,input2[27:24]};

72: lcd_code = {2'b10,input2[23:20]};
73: lcd_code = {2'b10,input2[19:16]};

74: lcd_code = {2'b10,input2[15:12]};
75: lcd_code = {2'b10,input2[11:08]};

76: lcd_code = {2'b10,input2[07:04]};
77: lcd_code = {2'b10,input2[03:00]};
default: lcd_code = 6'h10;
endcase
//if (lcd_rw) // comment-out for repeating display
// lcd_busy <= 0; // comment-out for repeating display
lcd_stb <= ^count[k+1:k+0] & ~lcd_rw & lcd_busy; // clkrate / 2^(k+2)
lcd_stuff <= {lcd_stb,lcd_code};
{lcd_e,lcd_rs,lcd_rw,lcd_7,lcd_6,lcd_5,lcd_4} <= lcd_stuff;
end
endmodule

- - - Updated - - -

//ucf file
NET "lcd_e" LOC = "M18" ;
NET "lcd_rs" LOC = "L18" ;
NET "lcd_rw" LOC = "L17" ;

NET "lcd_4" LOC = "R15";
NET "lcd_5" LOC = "R16" ;
NET "lcd_6" LOC = "P17";
NET "lcd_7" LOC = "M15" ;

NET "clk" LOC = "C9";
NET "sf_ce0" LOC = "D16";

- - - Updated - - -

@arishu
try this code.
 
hi Gs65,

Have you implemented your code in fpga ?

I doubt it will work.
 

I have modified the code which was working and displayed here.
Right now I don't have the kit. ..it will work
 

hi Gs65,

Have you implemented your code in fpga ?

I doubt it will work.
This is a case of the blind (Gs65) leading the blind (arishsu).

Store the bytes to send in a array and use a simple sequencer to address the array and output a value to the LCD. That gets rid of the huge ugly ridiculous case statement.

This is also a glitch generator: ^count[k+1:k+0] This combinational output relies on the adjacent bits of the output count being routed with exactly the same amount of delay to avoid a low going pulse during the 01-10 transition.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top