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

Subversion Repositories wb_lcd

[/] [wb_lcd/] [trunk/] [verilog/] [wb_lcd/] [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
        input  repaint,
56
        output busy,
57
        output [3:0] SF_D,
58
        output LCD_E,
59
        output LCD_RS,
60
        output LCD_RW
61
        );
62
 
63
//
64
// TX sub FSM
65
//
66
parameter tx_state_high_setup   = 3'b000;
67
parameter tx_state_high_hold    = 3'b001;
68
parameter tx_state_oneus        = 3'b010;
69
parameter tx_state_low_setup    = 3'b011;
70
parameter tx_state_low_hold     = 3'b100;
71
parameter tx_state_fortyus      = 3'b101;
72
parameter tx_state_done         = 3'b110;
73
 
74
reg     [2:0]    tx_state = tx_state_done; // Current tx fsm state
75
reg     [7:0]    tx_byte; // transmitting byte
76
wire            tx_init; // init transmission
77
reg  tx_done = 0;
78
 
79
 
80
//
81
// MAIN FSM
82
//
83
parameter display_state_init            = 5'b00000;
84
parameter init_state_fifteenms          = 5'b00001;
85
parameter init_state_one                = 5'b00010;
86
parameter init_state_two                = 5'b00011;
87
parameter init_state_three              = 5'b00100;
88
parameter init_state_four               = 5'b00101;
89
parameter init_state_five               = 5'b00110;
90
parameter init_state_six                = 5'b00111;
91
parameter init_state_seven              = 5'b01000;
92
parameter init_state_eight              = 5'b01001;
93
parameter display_state_function_set    = 5'b11000;
94
parameter display_state_entry_set       = 5'b11001;
95
parameter display_state_set_display     = 5'b11010;
96
parameter display_state_clr_display     = 5'b11011;
97
parameter display_state_pause_setup     = 5'b10000;
98
parameter display_state_pause           = 5'b10001;
99
parameter display_state_set_addr1       = 5'b11100;
100
parameter display_state_char_write1     = 5'b11101;
101
parameter display_state_set_addr2       = 5'b11110;
102
parameter display_state_char_write2     = 5'b11111;
103
parameter display_state_done            = 5'b10010;
104
 
105
reg [4:0] display_state = display_state_init; // current main fsm state
106
integer pos = `MEM_LOW1; // current drawing position
107
 
108
 
109
 
110
 
111
//
112
// RAM Interface
113
//
114
reg     [`DAT_WIDTH-1:0] ram [0:`MEM_LENGTH-1];    // memory contents
115
assign busy = (display_state != display_state_done);
116
 
117
always @(posedge clk)
118
        if (we)
119
                ram[addr] <= dat;
120
 
121
///
122
/// FSM and councurrent assignments definitions for LCD driving
123
/// 
124
reg [3:0] SF_D0 = 4'b0000;
125
reg [3:0] SF_D1 = 4'b0000;
126
reg       LCD_E0 = 1'b0;
127
reg       LCD_E1 = 1'b0;
128
wire      output_selector;
129
 
130
assign output_selector = display_state[4];
131
 
132
assign SF_D = (output_selector == 1'b1) ?       SF_D0 : //transmit
133
                                                SF_D1;  //initialize
134
 
135
assign LCD_E = (output_selector == 1'b1) ?      LCD_E0 ://transmit
136
                                                LCD_E1; //initialize
137
 
138
assign LCD_RW = 1'b0; // write only
139
 
140
//when to transmit a command/data and when not to
141
assign tx_init = !tx_done & display_state[4] & display_state[3];
142
 
143
// register select
144
assign LCD_RS = (display_state == display_state_function_set) ? 1'b0 :
145
                (display_state == display_state_entry_set)    ? 1'b0 :
146
                (display_state == display_state_set_display)  ? 1'b0 :
147
                (display_state == display_state_clr_display)  ? 1'b0 :
148
                (display_state == display_state_set_addr1)    ? 1'b0 :
149
                (display_state == display_state_set_addr2)    ? 1'b0 :
150
                                                                1'b1;
151
 
152
 
153
reg  [`INIT_DELAY_COUNTER_WIDTH-1:0] main_delay_value = 0;
154
reg  [`INIT_DELAY_COUNTER_WIDTH-1:0] tx_delay_value = 0;
155
 
156
wire delay_done;
157
 
158
reg main_delay_load = 0;
159
reg tx_delay_load = 0;
160
 
161
 
162
 
163
delay_counter  #(
164
        .counter_width(`INIT_DELAY_COUNTER_WIDTH)
165
) delay_counter (
166
        .clk   ( clk ),
167
        .reset ( reset ),
168
        .count ( (main_delay_load) ? main_delay_value : tx_delay_value),
169
        .load  ( main_delay_load | tx_delay_load ),
170
        .done  ( delay_done )
171
);
172
 
173
 
174
 
175
 
176
// main (display) state machine
177
always @(posedge clk, posedge reset)
178
begin
179
        if(reset==1'b1) begin
180
                display_state <= display_state_init;
181
                main_delay_load <= 0;
182
                main_delay_value <= 0;
183
        end else begin
184
                main_delay_load <= 0;
185
                main_delay_value <= 0;
186
 
187
                case (display_state)
188
                        //refer to intialize state machine below
189
                        display_state_init:
190
                        begin
191
                                tx_byte <= 8'b00000000;
192
                                display_state <= init_state_fifteenms;
193
                                main_delay_load <= 1'b1;
194
                                main_delay_value <= 750000;
195
                        end
196
 
197
                        init_state_fifteenms:
198
                        begin
199
                                main_delay_load <= 1'b0;
200
                                if(delay_done) begin
201
                                        display_state <= init_state_one;
202
                                        main_delay_load <= 1'b1;
203
                                        main_delay_value <= 11;
204
                                end
205
                        end
206
 
207
                        init_state_one:
208
                        begin
209
                                main_delay_load <= 1'b0;
210
                                SF_D1 <= 4'b0011;
211
                                LCD_E1 <= 1'b1;
212
                                if(delay_done) begin
213
                                        display_state <= init_state_two;
214
                                        main_delay_load <= 1'b1;
215
                                        main_delay_value <= 205000;
216
                                end
217
                        end
218
 
219
                        init_state_two:
220
                        begin
221
                                main_delay_load <= 1'b0;
222
                                LCD_E1 <= 1'b0;
223
                                if(delay_done) begin
224
                                        display_state <= init_state_three;
225
                                        main_delay_load <= 1'b1;
226
                                        main_delay_value <= 11;
227
                                end
228
                        end
229
 
230
                        init_state_three:
231
                        begin
232
                                main_delay_load <= 1'b0;
233
                                SF_D1 <= 4'b0011;
234
                                LCD_E1 <= 1'b1;
235
                                if(delay_done) begin
236
                                        display_state <= init_state_four;
237
                                        main_delay_load <= 1'b1;
238
                                        main_delay_value <= 5000;
239
                                end
240
                        end
241
 
242
                        init_state_four:
243
                        begin
244
                                main_delay_load <= 1'b0;
245
                                LCD_E1 <= 1'b0;
246
                                if(delay_done) begin
247
                                        display_state <= init_state_five;
248
                                        main_delay_load <= 1'b1;
249
                                        main_delay_value <= 11;
250
                                end
251
                        end
252
 
253
                        init_state_five:
254
                        begin
255
                                main_delay_load <= 1'b0;
256
                                SF_D1 <= 4'b0011;
257
                                LCD_E1 <= 1'b1;
258
                                if(delay_done) begin
259
                                        display_state <= init_state_six;
260
                                        main_delay_load <= 1'b1;
261
                                        main_delay_value <= 2000;
262
                                end
263
                        end
264
 
265
                        init_state_six:
266
                        begin
267
                                main_delay_load <= 1'b0;
268
                                LCD_E1 <= 1'b0;
269
                                if(delay_done) begin
270
                                        display_state <= init_state_seven;
271
                                        main_delay_load <= 1'b1;
272
                                        main_delay_value <= 11;
273
                                end
274
                        end
275
 
276
                        init_state_seven:
277
                        begin
278
                                main_delay_load <= 1'b0;
279
                                SF_D1 <= 4'b0010;
280
                                LCD_E1 <= 1'b1;
281
                                if(delay_done) begin
282
                                        display_state <= init_state_eight;
283
                                        main_delay_load <= 1'b1;
284
                                        main_delay_value <= 2000;
285
                                end
286
                        end
287
 
288
                        init_state_eight:
289
                        begin
290
                                main_delay_load <= 1'b0;
291
                                LCD_E1 <= 1'b0;
292
                                if(delay_done) begin
293
                                        display_state <= display_state_function_set;
294
                                end
295
                        end
296
 
297
                        //every other state but pause uses the transmit state machine
298
                        display_state_function_set:
299
                        begin
300
                                tx_byte <= 8'b00101000;
301
                                if(tx_done)
302
                                        display_state <= display_state_entry_set;
303
                        end
304
 
305
                        display_state_entry_set:
306
                        begin
307
                                tx_byte <= 8'b00000110;
308
                                if(tx_done)
309
                                        display_state <= display_state_set_display;
310
                        end
311
 
312
                        display_state_set_display:
313
                        begin
314
                                tx_byte <= 8'b00001100;
315
                                if(tx_done)
316
                                        display_state <= display_state_clr_display;
317
                        end
318
 
319
                        display_state_clr_display:
320
                        begin
321
                                tx_byte <= 8'b00000001;
322
                                if(tx_done) begin
323
                                        display_state <= display_state_pause_setup;
324
                                        main_delay_load <= 1;
325
                                        main_delay_value <= 82000;
326
                                end
327
                        end
328
 
329
                        display_state_pause_setup:
330
                        begin
331
                                display_state <= display_state_pause;
332
                        end
333
 
334
                        display_state_pause:
335
                        begin
336
                                tx_byte <= 8'b00000000;
337
                                if(delay_done)
338
                                        display_state <= display_state_set_addr1;
339
                        end
340
 
341
                        display_state_set_addr1:
342
                        begin
343
                                tx_byte <= 8'b10000000;
344
                                if(tx_done) begin
345
                                        display_state <= display_state_char_write1;
346
                                        pos <= `MEM_LOW1;
347
                                end
348
                        end
349
 
350
                        display_state_char_write1:
351
                        begin
352
                                tx_byte <= ram[pos] & 8'b11111111;
353
                                if(tx_done)
354
                                        if(pos == `MEM_HIGH1)
355
                                                display_state <= display_state_set_addr2;
356
                                        else
357
                                                pos <= pos + 1;
358
                        end
359
 
360
                        display_state_set_addr2:
361
                        begin
362
                                tx_byte <= 8'b11000000;
363
                                if(tx_done) begin
364
                                        display_state <= display_state_char_write2;
365
                                        pos <= `MEM_LOW2;
366
                                end
367
                        end
368
 
369
                        display_state_char_write2:
370
                        begin
371
                                tx_byte <= ram[pos] & 8'b11111111;
372
                                if(tx_done)
373
                                        if(pos == `MEM_HIGH2) begin
374
                                                display_state <= display_state_done;
375
                                        end else
376
                                                pos <= pos + 1;
377
                        end
378
 
379
                        display_state_done:
380
                        begin
381
                                tx_byte <= 8'b00000000;
382
                                if(repaint)
383
                                        display_state <= display_state_function_set;
384
                                else
385
                                        display_state <= display_state_done;
386
                        end
387
                endcase
388
        end
389
end
390
 
391
 
392
// transmit (tx) state machine, specified by datasheet
393
always @(posedge clk, posedge reset)
394
begin
395
        if(reset==1'b1)
396
                tx_state <= tx_state_done;
397
        else
398
        begin
399
                case (tx_state)
400
                        tx_state_high_setup: // 40 ns
401
                        begin
402
                                LCD_E0 <= 1'b0;
403
                                SF_D0 <= tx_byte[7 : 4];
404
                                tx_delay_load <= 1'b0;
405
                                if(delay_done) begin
406
                                        tx_state <= tx_state_high_hold;
407
                                        tx_delay_load <= 1'b1;
408
                                        tx_delay_value <= 12;
409
                                end
410
                        end
411
 
412
                        tx_state_high_hold: // 230 ns
413
                        begin
414
                                LCD_E0 <= 1'b1;
415
                                SF_D0 <= tx_byte[7 : 4];
416
                                tx_delay_load <= 1'b0;
417
                                if(delay_done) begin
418
                                        tx_state <= tx_state_oneus;
419
                                        tx_delay_load <= 1'b1;
420
                                        tx_delay_value <= 50;
421
                                end
422
                        end
423
 
424
                        tx_state_oneus:
425
                        begin
426
                                LCD_E0 <= 1'b0;
427
                                tx_delay_load <= 1'b0;
428
                                if(delay_done) begin
429
                                        tx_state <= tx_state_low_setup;
430
                                        tx_delay_load <= 1'b1;
431
                                        tx_delay_value <= 2;
432
                                end
433
                        end
434
 
435
                        tx_state_low_setup: // 40 ns
436
                        begin
437
                                LCD_E0 <= 1'b0;
438
                                SF_D0 <= tx_byte[3 : 0];
439
                                tx_delay_load <= 1'b0;
440
                                if(delay_done) begin
441
                                        tx_state <= tx_state_low_hold;
442
                                        tx_delay_load <= 1'b1;
443
                                        tx_delay_value <= 12;
444
                                end
445
                        end
446
 
447
                        tx_state_low_hold: // 230 ns
448
                        begin
449
                                LCD_E0 <= 1'b1;
450
                                SF_D0 <= tx_byte[3 : 0];
451
                                tx_delay_load <= 1'b0;
452
                                if(delay_done) begin
453
                                        tx_state <= tx_state_fortyus;
454
                                        tx_delay_load <= 1'b1;
455
                                        tx_delay_value <= 2000;
456
                                end
457
                        end
458
 
459
                        tx_state_fortyus:
460
                        begin
461
                                LCD_E0 <= 1'b0;
462
                                tx_delay_load <= 1'b0;
463
                                if(delay_done) begin
464
                                        tx_state <= tx_state_done;
465
                                        tx_done <= 1'b1;
466
                                end
467
                        end
468
 
469
                        tx_state_done:
470
                        begin
471
                                LCD_E0 <= 1'b0;
472
                                tx_done <= 1'b0;
473
                                tx_delay_load <= 1'b0;
474
                                if(tx_init == 1'b1) begin
475
                                        tx_state <= tx_state_high_setup;
476
                                        tx_delay_load <= 1'b1;
477
                                        tx_delay_value <= 2;
478
                                end
479
                        end
480
                endcase
481
        end
482
end
483
endmodule

powered by: WebSVN 2.1.0

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