CPLD LCD drivare, tips på förbättringar i Verilog-koden?
Postat: 8 juli 2009, 23:02:10
Jag har skaffat ett Xilinx Coolrunner II starter kit som jag sitter och testar. Har skrivit kod som lyckas skriva ut bokstäver på LCD-displayen som följer med men eftersom jag är helt nybörjare är jag lite nyfiken ifall det går att förbättra koden på nåt smart sätt? Det här är i princip det första jag skriver i HDL...
Det den gör (eller borde göra):
0. Nollställ allt
1. Vänta 21ms, skicka "Set function"
2. Vänta 40us, skicka "Display set"
3. Vänta 40us, skicka "Display clear"
4. Vänta 1.6ms, skicka "Entry mode set"
5. Vänta 40us, skicka tecken 'A'
6. Vänta 40us, skicka tecken 'e'
7. Vänta på knapptryck...
8. Vänta 40us, skicka state-variabeln som ASCII-siffra
btn0 hoppar till steg 0. <- Rensar och skriver ut "Ae" på LCD:n
btn1 hoppar till steg 8. <- Skriver en '8' på LCD:n

Datablad på displayen: http://www.digilentinc.com/Data/Product ... m_RevA.pdf
Min kod såhär långt:
EDIT: Uppdaterat koden. Vet inte riktigt vad jag gjorde men nu blir det aldrig fel när jag trycker på knapparna. Men om nån har tips på förbättringar i mitt sätt att implementera delays eller nåt annat så skriv gärna!
Det den gör (eller borde göra):
0. Nollställ allt
1. Vänta 21ms, skicka "Set function"
2. Vänta 40us, skicka "Display set"
3. Vänta 40us, skicka "Display clear"
4. Vänta 1.6ms, skicka "Entry mode set"
5. Vänta 40us, skicka tecken 'A'
6. Vänta 40us, skicka tecken 'e'
7. Vänta på knapptryck...
8. Vänta 40us, skicka state-variabeln som ASCII-siffra
btn0 hoppar till steg 0. <- Rensar och skriver ut "Ae" på LCD:n
btn1 hoppar till steg 8. <- Skriver en '8' på LCD:n
Datablad på displayen: http://www.digilentinc.com/Data/Product ... m_RevA.pdf
Min kod såhär långt:
Kod: Markera allt
`timescale 1ns / 1ps
module t5(
input clock,
input btn0,
input btn1,
output reg [3:0] leds,
output reg lcd_rs,
output reg lcd_rw,
output reg lcd_e,
output reg [7:0] lcd_data
);
reg [15:0] cnt;
reg [3:0] state;
initial begin
state = 3'b000;
leds = 4'b1111;
lcd_e = 1'b1;
lcd_rs = 1'b0;
lcd_rw = 1'b0;
lcd_data = 8'b00000000;
cnt = 16'd0;
end
always @ (posedge clock) //1MHz clock
begin
lcd_rw <= 1'b0; //Set R/W to write
leds <= ~state; //Show state on LEDs (0=ON, 1=OFF)
lcd_e <= (cnt <= 4) ? lcd_e : 1'b0; //Keep E high 4 clocks
cnt <= cnt + 1'b1; //Increment timer (1 MHz)
//state 0000, Wait 10 counts then reset outputs
if (cnt == 16'd10 && state == 4'b0000)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b0;
lcd_data <= 8'b00000000;
lcd_e <= 1'b1;
end
//state 0001, Wait 21ms then send "Set function" to LCD
else if (cnt == 16'd21000 && state == 4'b0001)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b0;
lcd_data <= 8'b00001111;
lcd_e <= 1'b1;
end
//state 0010, Wait 40us then send "Display set" to LCD
else if (cnt == 16'd40 && state == 4'b0010)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b0;
lcd_data <= 8'b00001111;
lcd_e <= 1'b1;
end
//state 0011, Wait 40us then send "Display clear" to LCD
else if (cnt == 16'd40 && state == 4'b0011)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b0;
lcd_data <= 8'b00000001;
lcd_e <= 1'b1;
end
//state 0100, Wait 1.6ms then send "Entry mode set" to LCD
else if (cnt == 16'd1600 && state == 4'b0100)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b0;
lcd_data <= 8'b00000110;
lcd_e <= 1'b1;
end
//state 0101, Wait 40us then send char 'A' to LCD
else if (cnt == 16'd40 && state == 4'b0101)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b1;
lcd_data <= 8'b01000001;
lcd_e <= 1'b1;
end
//state 0110, Wait 40us then send char 'e' to LCD
else if (cnt == 16'd40 && state == 4'b0110)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b1;
lcd_data <= 8'b01100101;
lcd_e <= 1'b1;
end
//state 0111, Loop until button is pressed
//state 1000, Wait 40us then send state number to LCD
else if (cnt == 16'd40 && state == 4'b1000)
begin
cnt <= 16'd0;
state <= state + 1'b1;
lcd_rs <= 1'b1;
lcd_data <= {4'b0011, state};
lcd_e <= 1'b1;
end
//state 1001, Loop until button is pressed
//Reset display when btn0 is pressed
if (!btn0)
begin
state <= 4'b0000;
cnt <= 16'd0;
end
//Jump to state 1000 on btn1 press
if (!btn1)
begin
state <= 4'b1000;
cnt <= 16'd0;
end
end
endmodule