module lcd(reset,clk,flag,incode1,incode2,rs,rw,en,lcd_out);
input clk,reset; //40ns
input [7:0] incode1,incode2;
input flag;
output rs,rw,en;
output [7:0] lcd_out;
reg [7:0] lcd_out;
reg rs,rw,en;
reg [3:0] state;
reg [19:0] num;
reg [4:0] addr;
parameter idle=4'b0000,s0=4'b0001,s1=4'b0011,
s2=4'b0010,s3=4'b0110,s4=4'b0111,
s5=4'b0101,s6=4'b0100,s7=4'b1100,
s8=4'b1101,s9=4'b1111,s10=4'b1110;
function [7:0] romout;
input [3:0] addr;
case(addr)
0: romout=8'h20; //blank
1: romout=8'h69;//i
2: romout=8'h73;//s
3: romout=8'h20; //blank
4: romout=8'h6F;//o
5: romout=8'h70;//p
6: romout=8'h65;//e
7: romout=8'h6E;//n
8: romout=8'h21;//!
9: romout=8'h73;//s
10: romout=8'h68;//h
11: romout=8'h6F;//o
12: romout=8'h72;//r
13: romout=8'h74;//t
default:romout=8'h21;//!
endcase
endfunction
//reg flag;
//reg [7:0] incode1,incode2;
[email=always@(posedge]always@(posedge[/email] clk or posedge reset)
begin
// flag<=1'b0;incode1<=8'h31;incode2<=8'h32;
if(reset) begin num<=0;addr<=0;state<=idle;end
else begin
case(state)
idle: begin
num<=num+20'b1;addr<=0;
rs<=0;rw<=0;en<=1;
if(num<500000) begin num<=0;state<=s0;end
end
s0: begin
num<=num+20'b1;
if(num<3) begin rs<=0;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h38;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s1;end
end
s1: begin
num<=num+20'b1;
if(num<3) begin rs<=0;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h01;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s2;end
end
s2: begin
num<=num+20'b1;
if(num<3) begin rs<=0;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h0c;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s3;end
end
s3: begin
num<=num+20'b1;
if(num<3) begin rs<=0;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h06;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s4;end
end
s4: begin //write the address
num<=num+20'b1;
if(num<3) begin rs<=0;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h82;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s5;end
end
s5: begin //write R
num<=num+20'b1;
if(num<3) begin rs<=1;rw<=0;en<=1;end
else if(num<6) lcd_out<=8'h52;
else if(num<30) en<=0;
else if(num<31) begin num<=0;state<=s6;end
end
s6: begin //write the number of 10
num<=num+20'b1;
if(num<3) begin rs<=1;rw<=0;en<=1;end
else if(num<6) begin lcd_out<=incode1; end
else if(num<30) en<=0;
else if(num<31) begin num<=0; state<=s7;end
end
s7: begin //write the number of 1
num<=num+20'b1;
if(num<3) begin rs<=1;rw<=0;en<=1;end
else if(num<6) begin lcd_out<=incode2; end
else if(num<30) en<=0;
else if(num<31) begin num<=0; state<=s8;end
end
s8: begin //write data
num<=num+20'b1;
if(num<3) begin rs<=1;rw<=0;en<=1;end
else if(num<6) begin lcd_out<=romout(addr);end
else if(num<30) en<=0;
else if(num<31) begin num<=0; addr<=addr+4'b1;
if(flag) begin if(addr==8) state<=s9;end
else begin if(addr==3) addr<=4'd9;
else if(addr==14) state<=s9;
end
end
end
s9: begin //write A
num<=num+20'b1;
if(num==600) begin num<=0;state<=idle;end
end
default :state<=idle;
endcase
end
end
endmodule