
input clk,rst;
input [1:0] test_mode;
input [15:0] lcd_data_in;
output RS,RW,cont,en;
output [7:0] lcd_data_out;
wire en_out;
reg RS,RW;
reg[3:0] count;
reg[7:0] lcd_data_out;
reg[3:0] state;
wire clk_out,clk_en,cont;
reg en_tmp;
parameter Warmup = 4'b0000,
Funcset = 4'b0001,
Dspoff = 4'b0011,
Clsdsp = 4'b0010,
Modeset = 4'b0110,
Dspon = 4'b0111,
Setaddr1 = 4'b0101,
Indata1 = 4'b0100,
Setaddr2 = 4'b1101,
Indata2 = 4'b1100,
Idle = 4'b1000;
clkdiv U1(clk,clk_out);
assign cont = 1'b0;
always @(posedge clk or negedge rst)
if(~rst)
en_tmp<=1'b0;
else
en_tmp<=clk_out;
assign en= ~clk_out & en_tmp;
assign clk_en = ~en_tmp & clk_out;
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
count<=0;
state<=Warmup;
end
else
begin
case(state)
Warmup:
begin
if(clk_en)
begin if(count==4'b0111)
begin state<=Funcset;
count<=0;
end
else
begin state<=Warmup; count<=count+4'b0001;
end
end
end
Funcset:
begin
if(clk_en)
begin if(count==4'b1111)
begin
state<=Dspoff;
count<=0;
end
else
begin
state<=Funcset; count<=count+4'b0001;
end
end
end
Dspoff:
state<=Clsdsp;
Clsdsp:
begin
if(clk_en)
begin
if(count==4'b0101)
begin
state<=Modeset;
count<=0;
end
else
begin
state<=Clsdsp;
count<=count+4'b0001;
end
end
end
Modeset: begin
if(clk_en) state<=Dspon;
end
Dspon:
begin
if(clk_en)
begin
if(count==4'b0100)
begin
state<=Setaddr1;
count<=0;
end
else
begin
state<=Dspon; count<=count+4'b0001;
end
end
end
Setaddr1: begin if(clk_en) state<=Indata1;
end
Indata1:
begin
if(clk_en)
begin
if(count==4'b1110)
begin
state<=Setaddr2;
count<=0;
end
else
begin
state<=Indata1; count<=count+4'b0001;
end
end
end
Setaddr2:
begin if(clk_en) state<=Indata2;
end
Indata2:
begin
if(clk_en)
begin
if(count==4'b1111)
begin
state<=Setaddr1;
count<=0;
end
else
begin
state<=Indata2; count<=count+4'b0001;
end
end
end
default:state<=Warmup;
endcase
end
end
always @(state or count)
begin
case(state)
Warmup: begin
RS<=0;
RW<=0; lcd_data_out<=8'b00000000;
end
Funcset:lcd_data_out<=8'b00111000;
Dspoff: lcd_data_out<=8'b00001000;
Clsdsp: lcd_data_out<=8'b00000001;
Modeset:lcd_data_out<=8'b00000110;
Dspon: lcd_data_out<=8'b00001100;
Setaddr1:begin
RS<=0;
RW<=0; lcd_data_out<=8'b10000000;
end
Indata1:begin
RS<=1;
RW<=0;
case(count) 4'b0000:lcd_data_out<=8'b00100000; 4'b0001:lcd_data_out<=8'b01010011; 4'b0010:lcd_data_out<=8'b01000011;
4'b0011:lcd_data_out<=8'b01001111; 4'b0100:lcd_data_out<=8'b01010000;
4'b0101:lcd_data_out<=8'b01000101;
4'b0110:lcd_data_out<=8'b00111010;
4'b0111:begin case(test_mode) 2'b00:lcd_data_out<=8'b00110000; 2'b01:lcd_data_out<=8'b00110000; 2'b10:lcd_data_out<=8'b00110010; 2'b11:lcd_data_out<=8'b00110000; default: lcd_data_out<=8'b00111100; endcase
end
4'b1000:begin case(test_mode) 2'b00:lcd_data_out<=8'b00110000; 2'b01:lcd_data_out<=8'b00101101; 2'b10:lcd_data_out<=8'b00110000; 2'b11:lcd_data_out<=8'b00101110; default: lcd_data_out<=8'b00100000; endcase
end
4'b1001:case(test_mode) 2'b00:lcd_data_out<=8'b00110000; 2'b01:lcd_data_out<=8'b00110010; 2'b10:lcd_data_out<=8'b00101101; 2'b11:lcd_data_out<=8'b00110010;
default: lcd_data_out<=8'b00100000; endcase
4'b1010:case(test_mode) 2'b00:lcd_data_out<=8'b00110000; 2'b01:lcd_data_out<=8'b00110000; 2'b10:lcd_data_out<=8'b00110010; 2'b11:lcd_data_out<=8'b00101101; default: lcd_data_out<=8'b00100000; endcase
4'b1011:case(test_mode) 2'b00:lcd_data_out<=8'b01101101; 2'b01:lcd_data_out<=8'b01101101; 2'b10:lcd_data_out<=8'b00110000; 2'b11:lcd_data_out<=8'b00110010; default: lcd_data_out<=8'b00100000; endcase
4'b1100:case(test_mode) 2'b00:lcd_data_out<=8'b01000001; 2'b01:lcd_data_out<=8'b01000001; 2'b10:lcd_data_out<=8'b00110000; 2'b11:lcd_data_out<=8'b00101110; default: lcd_data_out<=8'b00100000; endcase
4'b1101:case(test_mode) 2'b00:lcd_data_out<=8'b00100000; 2'b01:lcd_data_out<=8'b00100000; 2'b10:lcd_data_out<=8'b01101101; 2'b11:lcd_data_out<=8'b00110000; default: lcd_data_out<=8'b00100000; endcase
4'b1110:case(test_mode) 2'b00:lcd_data_out<=8'b00100000; 2'b01:lcd_data_out<=8'b00100000; 2'b10:lcd_data_out<=8'b01000001; 2'b11:lcd_data_out<=8'b01000001; default: lcd_data_out<=8'b00100000; endcase
default:lcd_data_out<=8'b00100000; endcase
end
Setaddr2:begin
RS<=0;
RW<=0; lcd_data_out<=8'b11000000;
end
Indata2:begin
RS<=1;
RW<=0;
case(count) 4'b0000:lcd_data_out<=8'b00100000; 4'b0001:lcd_data_out<=8'b01001001; 4'b0010:lcd_data_out<=8'b01101111; 4'b0011:lcd_data_out<=8'b01110101; 4'b0100:lcd_data_out<=8'b01110100;
4'b0101:lcd_data_out<=8'b00111101;
4'b0110:begin
if(test_mode[1] & test_mode[0])
lcd_data_out<={4'b0011,lcd_data_in[15:12]};
else if(~test_mode[1] & test_mode[0]) lcd_data_out<={4'b0011,lcd_data_in[11:8]};
else lcd_data_out<=8'b00100000;
end
4'b0111: lcd_data_out<={4'b0011,lcd_data_in[11:8]};
4'b1000:
begin if(~test_mode[1] & test_mode[0]) lcd_data_out<=8'b00101110;
else lcd_data_out<={4'b0011,lcd_data_in[7:4]};
end 4'b1001:lcd_data_out<={4'b0011,lcd_data_in[3:0]};
4'b1010:lcd_data_out<=8'b01101101;
4'b1011:lcd_data_out<=8'b01000001;
default:lcd_data_out<=8'b00100000;
endcase
end
default:lcd_data_out<=8'bzzzzzzzz;
endcase
end
endmodule
module clkdiv(clk_in,clk_out);
input clk_in;
output clk_out;
reg clk_out;
reg[15:0] count;
always@(posedge clk_in)
begin
if(count==15'b111111111111111)
begin
clk_out<=~clk_out;
count<=0;
end
else
count<=count+15'b0000_0000_0000_001;
end
endmodule
