OpenCores
URL https://opencores.org/ocsvn/wb_lcd/wb_lcd/trunk

Subversion Repositories wb_lcd

[/] [wb_lcd/] [trunk/] [verilog/] [wb_lcd_ramless/] [rtl/] [lcd_display.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jvillar
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  lcd_display.v                                               ////
4
////                                                              ////
5
////  This file is part of:                                       ////
6
////  WISHBONE/MEM MAPPED CONTROLLER FOR LCD CHARACTER DISPLAYS   ////
7
////  http://www.opencores.org/projects/wb_lcd/                   ////
8
////                                                              ////
9
////  Description                                                 ////
10
////   - Memory mapped main controller.                           ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   - nothing really                                           ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////   - José Ignacio Villar, jose@dte.us.es , jvillar@gmail.com  ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19
////                                                              ////
20
//// Copyright (C) 2009 José Ignacio Villar - jvillar@gmail.com   ////
21
////                                                              ////
22
//// This source file may be used and distributed without         ////
23
//// restriction provided that this copyright statement is not    ////
24
//// removed from the file and that any derivative work contains  ////
25
//// the original copyright notice and the associated disclaimer. ////
26
////                                                              ////
27
//// This source file is free software; you can redistribute it   ////
28
//// and/or modify it under the terms of the GNU Lesser General   ////
29
//// Public License as published by the Free Software Foundation; ////
30
//// either version 3 of the License, or (at your option) any     ////
31
//// later version.                                               ////
32
////                                                              ////
33
//// This source is distributed in the hope that it will be       ////
34
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
35
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
36
//// PURPOSE.  See the GNU Lesser General Public License for more ////
37
//// details.                                                     ////
38
////                                                              ////
39
//// You should have received a copy of the GNU Lesser General    ////
40
//// Public License along with this source; if not, download it   ////
41
//// from http://www.gnu.org/licenses/lgpl.txt                    ////
42
////                                                              ////
43
//////////////////////////////////////////////////////////////////////
44
 
45
`include "lcd_defines.v"
46
 
47
module lcd (
48
        input clk,
49
        input reset,
50
 
51
        input [`DAT_WIDTH-1:0] dat,
52
        input [`ADDR_WIDTH-1:0] addr,
53
        input we,
54
 
55
        output busy,
56
        output [3:0] SF_D,
57
        output LCD_E,
58
        output LCD_RS,
59
        output LCD_RW
60
        );
61
 
62
//
63
// TX sub FSM
64
//
65
parameter tx_state_high_setup   = 3'b000;
66
parameter tx_state_high_hold    = 3'b001;
67
parameter tx_state_oneus        = 3'b010;
68
parameter tx_state_low_setup    = 3'b011;
69
parameter tx_state_low_hold     = 3'b100;
70
parameter tx_state_fortyus      = 3'b101;
71
parameter tx_state_done         = 3'b110;
72
 
73
reg     [2:0]    tx_state = tx_state_done; // Current tx fsm state
74
reg     [7:0]    tx_byte; // transmitting byte
75
wire            tx_init; // init transmission
76
reg             tx_done = 0;
77
 
78
 
79
//
80
// MAIN FSM
81
//
82
parameter display_state_init            = 5'b00000;
83
parameter init_state_fifteenms          = 5'b00001;
84
parameter init_state_one                = 5'b00010;
85
parameter init_state_two                = 5'b00011;
86
parameter init_state_three              = 5'b00100;
87
parameter init_state_four               = 5'b00101;
88
parameter init_state_five               = 5'b00110;
89
parameter init_state_six                = 5'b00111;
90
parameter init_state_seven              = 5'b01000;
91
parameter init_state_eight              = 5'b01001;
92
parameter display_state_function_set    = 5'b11000;
93
parameter display_state_entry_set       = 5'b11001;
94
parameter display_state_set_display     = 5'b11010;
95
parameter display_state_clr_display     = 5'b11011;
96
parameter display_state_pause_setup     = 5'b10000;
97
parameter display_state_pause           = 5'b10001;
98
parameter display_state_set_addr        = 5'b11100;
99
parameter display_state_char_write      = 5'b11101;
100
parameter display_state_done            = 5'b10010;
101
 
102
reg [4:0] display_state = display_state_init; // current main fsm state
103
 
104
 
105
 
106
 
107
//
108
// RAM Interface
109
//
110
assign busy = (display_state != display_state_done);
111
 
112
reg [`DAT_WIDTH-1:0] wr_dat;
113
reg [`ADDR_WIDTH-1:0] wr_addr;
114
 
115
///
116
/// FSM and councurrent assignments definitions for LCD driving
117
/// 
118
reg [3:0] SF_D0 = 4'b0000;
119
reg [3:0] SF_D1 = 4'b0000;
120
reg       LCD_E0 = 1'b0;
121
reg       LCD_E1 = 1'b0;
122
wire      output_selector;
123
 
124
assign output_selector = display_state[4];
125
 
126
assign SF_D = (output_selector == 1'b1) ?       SF_D0 : //transmit
127
                                                SF_D1;  //initialize
128
 
129
assign LCD_E = (output_selector == 1'b1) ?      LCD_E0 ://transmit
130
                                                LCD_E1; //initialize
131
 
132
assign LCD_RW = 1'b0; // write only
133
 
134
//when to transmit a command/data and when not to
135
assign tx_init = !tx_done & display_state[4] & display_state[3];
136
 
137
// register select
138
assign LCD_RS = (display_state == display_state_function_set) ? 1'b0 :
139
                (display_state == display_state_entry_set)    ? 1'b0 :
140
                (display_state == display_state_set_display)  ? 1'b0 :
141
                (display_state == display_state_clr_display)  ? 1'b0 :
142
                (display_state == display_state_set_addr)     ? 1'b0 :
143
                                                                1'b1;
144
 
145
 
146
reg  [`INIT_DELAY_COUNTER_WIDTH-1:0] main_delay_value = 0;
147
reg  [`INIT_DELAY_COUNTER_WIDTH-1:0] tx_delay_value = 0;
148
 
149
wire delay_done;
150
 
151
reg main_delay_load = 0;
152
reg tx_delay_load = 0;
153
 
154
 
155
 
156
delay_counter  #(
157
        .counter_width(`INIT_DELAY_COUNTER_WIDTH)
158
) delay_counter (
159
        .clk   ( clk ),
160
        .reset ( reset ),
161
        .count ( (main_delay_load) ? main_delay_value : tx_delay_value),
162
        .load  ( main_delay_load | tx_delay_load ),
163
        .done  ( delay_done )
164
);
165
 
166
 
167
 
168
 
169
// main (display) state machine
170
always @(posedge clk, posedge reset)
171
begin
172
        if(reset==1'b1) begin
173
                display_state <= display_state_init;
174
                main_delay_load <= 0;
175
                main_delay_value <= 0;
176
        end else begin
177
                main_delay_load <= 0;
178
                main_delay_value <= 0;
179
 
180
                case (display_state)
181
                        //refer to intialize state machine below
182
                        display_state_init:
183
                        begin
184
                                tx_byte <= 8'b00000000;
185
                                display_state <= init_state_fifteenms;
186
                                main_delay_load <= 1'b1;
187
                                main_delay_value <= 750000;
188
                        end
189
 
190
                        init_state_fifteenms:
191
                        begin
192
                                main_delay_load <= 1'b0;
193
                                if(delay_done) begin
194
                                        display_state <= init_state_one;
195
                                        main_delay_load <= 1'b1;
196
                                        main_delay_value <= 11;
197
                                end
198
                        end
199
 
200
                        init_state_one:
201
                        begin
202
                                main_delay_load <= 1'b0;
203
                                SF_D1 <= 4'b0011;
204
                                LCD_E1 <= 1'b1;
205
                                if(delay_done) begin
206
                                        display_state <= init_state_two;
207
                                        main_delay_load <= 1'b1;
208
                                        main_delay_value <= 205000;
209
                                end
210
                        end
211
 
212
                        init_state_two:
213
                        begin
214
                                main_delay_load <= 1'b0;
215
                                LCD_E1 <= 1'b0;
216
                                if(delay_done) begin
217
                                        display_state <= init_state_three;
218
                                        main_delay_load <= 1'b1;
219
                                        main_delay_value <= 11;
220
                                end
221
                        end
222
 
223
                        init_state_three:
224
                        begin
225
                                main_delay_load <= 1'b0;
226
                                SF_D1 <= 4'b0011;
227
                                LCD_E1 <= 1'b1;
228
                                if(delay_done) begin
229
                                        display_state <= init_state_four;
230
                                        main_delay_load <= 1'b1;
231
                                        main_delay_value <= 5000;
232
                                end
233
                        end
234
 
235
                        init_state_four:
236
                        begin
237
                                main_delay_load <= 1'b0;
238
                                LCD_E1 <= 1'b0;
239
                                if(delay_done) begin
240
                                        display_state <= init_state_five;
241
                                        main_delay_load <= 1'b1;
242
                                        main_delay_value <= 11;
243
                                end
244
                        end
245
 
246
                        init_state_five:
247
                        begin
248
                                main_delay_load <= 1'b0;
249
                                SF_D1 <= 4'b0011;
250
                                LCD_E1 <= 1'b1;
251
                                if(delay_done) begin
252
                                        display_state <= init_state_six;
253
                                        main_delay_load <= 1'b1;
254
                                        main_delay_value <= 2000;
255
                                end
256
                        end
257
 
258
                        init_state_six:
259
                        begin
260
                                main_delay_load <= 1'b0;
261
                                LCD_E1 <= 1'b0;
262
                                if(delay_done) begin
263
                                        display_state <= init_state_seven;
264
                                        main_delay_load <= 1'b1;
265
                                        main_delay_value <= 11;
266
                                end
267
                        end
268
 
269
                        init_state_seven:
270
                        begin
271
                                main_delay_load <= 1'b0;
272
                                SF_D1 <= 4'b0010;
273
                                LCD_E1 <= 1'b1;
274
                                if(delay_done) begin
275
                                        display_state <= init_state_eight;
276
                                        main_delay_load <= 1'b1;
277
                                        main_delay_value <= 2000;
278
                                end
279
                        end
280
 
281
                        init_state_eight:
282
                        begin
283
                                main_delay_load <= 1'b0;
284
                                LCD_E1 <= 1'b0;
285
                                if(delay_done) begin
286
                                        display_state <= display_state_function_set;
287
                                end
288
                        end
289
 
290
                        //every other state but pause uses the transmit state machine
291
                        display_state_function_set:
292
                        begin
293
                                tx_byte <= 8'b00101000;
294
                                if(tx_done)
295
                                        display_state <= display_state_entry_set;
296
                        end
297
 
298
                        display_state_entry_set:
299
                        begin
300
                                tx_byte <= 8'b00000110;
301
                                if(tx_done)
302
                                        display_state <= display_state_set_display;
303
                        end
304
 
305
                        display_state_set_display:
306
                        begin
307
                                tx_byte <= 8'b00001100;
308
                                if(tx_done)
309
                                        display_state <= display_state_clr_display;
310
                        end
311
 
312
                        display_state_clr_display:
313
                        begin
314
                                tx_byte <= 8'b00000001;
315
                                if(tx_done) begin
316
                                        display_state <= display_state_pause_setup;
317
                                        main_delay_load <= 1;
318
                                        main_delay_value <= 82000;
319
                                end
320
                        end
321
 
322
                        display_state_pause_setup:
323
                        begin
324
                                display_state <= display_state_pause;
325
                        end
326
 
327
                        display_state_pause:
328
                        begin
329
                                tx_byte <= 8'b00000000;
330
                                if(delay_done)
331
                                        display_state <= display_state_done;
332
                        end
333
 
334
                        display_state_done:
335
                        begin
336
                                tx_byte <= 8'b00000000;
337
                                if (we) begin
338
                                        display_state <= display_state_set_addr;
339
                                        wr_addr <= addr;
340
                                        wr_dat <= dat;
341
                                end else
342
                                        display_state <= display_state_done;
343
                        end
344
 
345
                        display_state_set_addr:
346
                        begin
347
                                tx_byte <= { 1'b1 , wr_addr};
348
                                if(tx_done) begin
349
                                        display_state <= display_state_char_write;
350
                                end
351
                        end
352
 
353
                        display_state_char_write:
354
                        begin
355
                                tx_byte <= wr_dat;
356
                                if(tx_done)
357
                                        display_state <= display_state_done;
358
 
359
                        end
360
 
361
                endcase
362
        end
363
end
364
 
365
 
366
// transmit (tx) state machine, specified by datasheet
367
always @(posedge clk, posedge reset)
368
begin
369
        if(reset==1'b1)
370
                tx_state <= tx_state_done;
371
        else
372
        begin
373
                case (tx_state)
374
                        tx_state_high_setup: // 40 ns
375
                        begin
376
                                LCD_E0 <= 1'b0;
377
                                SF_D0 <= tx_byte[7 : 4];
378
                                tx_delay_load <= 1'b0;
379
                                if(delay_done) begin
380
                                        tx_state <= tx_state_high_hold;
381
                                        tx_delay_load <= 1'b1;
382
                                        tx_delay_value <= 12;
383
                                end
384
                        end
385
 
386
                        tx_state_high_hold: // 230 ns
387
                        begin
388
                                LCD_E0 <= 1'b1;
389
                                SF_D0 <= tx_byte[7 : 4];
390
                                tx_delay_load <= 1'b0;
391
                                if(delay_done) begin
392
                                        tx_state <= tx_state_oneus;
393
                                        tx_delay_load <= 1'b1;
394
                                        tx_delay_value <= 50;
395
                                end
396
                        end
397
 
398
                        tx_state_oneus:
399
                        begin
400
                                LCD_E0 <= 1'b0;
401
                                tx_delay_load <= 1'b0;
402
                                if(delay_done) begin
403
                                        tx_state <= tx_state_low_setup;
404
                                        tx_delay_load <= 1'b1;
405
                                        tx_delay_value <= 2;
406
                                end
407
                        end
408
 
409
                        tx_state_low_setup: // 40 ns
410
                        begin
411
                                LCD_E0 <= 1'b0;
412
                                SF_D0 <= tx_byte[3 : 0];
413
                                tx_delay_load <= 1'b0;
414
                                if(delay_done) begin
415
                                        tx_state <= tx_state_low_hold;
416
                                        tx_delay_load <= 1'b1;
417
                                        tx_delay_value <= 12;
418
                                end
419
                        end
420
 
421
                        tx_state_low_hold: // 230 ns
422
                        begin
423
                                LCD_E0 <= 1'b1;
424
                                SF_D0 <= tx_byte[3 : 0];
425
                                tx_delay_load <= 1'b0;
426
                                if(delay_done) begin
427
                                        tx_state <= tx_state_fortyus;
428
                                        tx_delay_load <= 1'b1;
429
                                        tx_delay_value <= 2000;
430
                                end
431
                        end
432
 
433
                        tx_state_fortyus:
434
                        begin
435
                                LCD_E0 <= 1'b0;
436
                                tx_delay_load <= 1'b0;
437
                                if(delay_done) begin
438
                                        tx_state <= tx_state_done;
439
                                        tx_done <= 1'b1;
440
                                end
441
                        end
442
 
443
                        tx_state_done:
444
                        begin
445
                                LCD_E0 <= 1'b0;
446
                                tx_done <= 1'b0;
447
                                tx_delay_load <= 1'b0;
448
                                if(tx_init == 1'b1) begin
449
                                        tx_state <= tx_state_high_setup;
450
                                        tx_delay_load <= 1'b1;
451
                                        tx_delay_value <= 2;
452
                                end
453
                        end
454
                endcase
455
        end
456
end
457
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.