forked from wgwozdz/Spartan_LCD
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlcd.v
53 lines (48 loc) · 2.18 KB
/
lcd.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module lcd (
input clk,
output reg lcd_rs,
output reg lcd_rw,
output reg lcd_e,
output reg [7:4] lcd_d,
output [4:0] mem_addr,
input [7:0] mem_bus
);
parameter n = 24;
parameter j = 17; // Initialization is slow, runs at clk/2^(j+2) ~95Hz
parameter k = 11; // Writing/seeking is fast, clk/2^(k_2) ~6KHz
parameter noop = 6'b010000; // Allows LCD to drive lcd_d, can be safely written any time
reg [n:0] count = 0;
reg [5:0] lcd_state = noop;
reg init = 1; // Start in initialization on power on
reg row = 0; // Writing to top or or bottom row
assign mem_addr = {row, count[k+6:k+3]};
initial count[j+7:j+2] = 11;
always @ (posedge clk) begin
count <= count + 1;
if (init) begin // initalization
case (count[j+7:j+2])
1: lcd_state <= 6'b000010; // function set
2: lcd_state <= 6'b000010;
3: lcd_state <= 6'b001000;
4: lcd_state <= 6'b000000; // display on/off control
5: lcd_state <= 6'b001100;
6: lcd_state <= 6'b000000; // display clear
7: lcd_state <= 6'b000001;
8: lcd_state <= 6'b000000; // entry mode set
9: lcd_state <= 6'b000110;
10: begin init <= ~init; count <= 0; end
endcase
// Write lcd_state to the LCD and turn lcd_e high for the middle half of each lcd_state
{lcd_e,lcd_rs,lcd_rw,lcd_d[7:4]} <= {^count[j+1:j+0] & ~lcd_rw,lcd_state};
end else begin // Continuously update screen from memory
case (count[k+7:k+2])
32: lcd_state <= {3'b001,~row,2'b00}; // Move cursor to begining of next line
33: lcd_state <= 6'b000000;
34: begin count <= 0; row <= ~row; end // Restart and switch which row is being written
default: lcd_state <= {2'b10, ~count[k+2] ? mem_bus[7:4] : mem_bus[3:0]}; // Pull characters from bus
endcase
// Write lcd_state to the LCD and turn lcd_e high for the middle half of each lcd_state
{lcd_e,lcd_rs,lcd_rw,lcd_d[7:4]} <= {^count[k+1:k+0] & ~lcd_rw,lcd_state};
end
end
endmodule