module testingLCD(SW,LEDR,LCD_DATA, LCD_EN, LCD_RW, LCD_ON, LCD_BLON);
input [17:0] SW;
inout [7:0] LCD_DATA;
output [17:0] LEDR;
output LCD_EN;
output LCD_ON;
output LCD_BLON;
output LCD_RW;
reg[7:0] data;
reg rw;
reg en;
assign LCD_ON= 1'b1;
assign LCD_BLON = 1'b1;
assign LEDR = SW;
always@(SW)
begin
if (SW[17]==1'b1)
begin
rw = 1'b1;
en = 1'b1;
data <= LCD_DISPLAY(0);
end
end
function [7:0] LCD_DISPLAY;
input [3:0] value;
begin
if(value==0)
LCD_DISPLAY = 7'b01010000; //print words P
end
endfunction
assign LCD_DATA = data;
assign LCD_EN = en;
assign LCD_RW = rw;
endmodule
module top(
// Outputs
DATA_BUS, LCD_E, LCD_RS,
// Inputs
clk_12Mhz, reset
);
input clk_12Mhz; // To LCD of LCD.v
input reset; // To LCD of LCD.v, ...
output [7:0] DATA_BUS; // From LCD of LCD.v
output LCD_E; // From LCD of LCD.v
output LCD_RS; // From LCD of LCD.v
wire CLK_10HZ;
wire [15:0] count;
wire [18:0] bcd_count;
//BCD to ASCII
wire [7:0] B5 = {4'h3, bcd_count[3:0]};
wire [7:0] B4 = {4'h3, bcd_count[7:4]};
wire [7:0] B3 = {4'h3, bcd_count[11:8]};
wire [7:0] B2 = {4'h3, bcd_count[15:12]};
wire [7:0] B1 = {4'h3, 1'b0, bcd_count[18:16]};
LCD LCD(// Outputs
.LCD_RS (LCD_RS),
.LCD_E (LCD_E),
.CLK_10HZ (CLK_10HZ),
.LCD_RW (),
.DATA_BUS (DATA_BUS[7:0]),
// Inputs
.reset (reset),
.clk_12Mhz (clk_12Mhz),
.C1L1 (" "),
.C2L1 (" "),
.C3L1 ("C"),
.C4L1 ("O"),
.C5L1 ("U"),
.C6L1 ("N"),
.C7L1 ("T"),
.C8L1 ("E"),
.C9L1 ("R"),
.C10L1 ("-"),
.C11L1 ("T"),
.C12L1 ("E"),
.C13L1 ("S"),
.C14L1 ("T"),
.C15L1 (" "),
.C16L1 (" "),
.C1L2 (" "),
.C2L2 (" "),
.C3L2 (" "),
.C4L2 (" "),
.C5L2 (" "),
.C6L2 (" "),
.C7L2 (B1),
.C8L2 (B2),
.C9L2 (B3),
.C10L2 (B4),
.C11L2 (B5),
.C12L2 (" "),
.C13L2 (" "),
.C14L2 (" "),
.C15L2 (" "),
.C16L2 (" "));
counter counter(// Outputs
.count (count[15:0]),
// Inputs
.reset (reset),
.clk (clk_12Mhz),
.clk_en (CLK_10HZ));
binbcd16 binbcd16(// Outputs
.P (bcd_count[18:0]),
// Inputs
.B (count[15:0]));
endmodule // top
module binbcd16(B,P);
input [15:0] B;
output [18:0] P;
reg [18:0] P;
reg [35:0] z;
integer i;
always @(B) begin
for(i = 0; i <= 35; i = i+1)
z[i] = 0;
z[18:3] = B;
for(i = 0; i <= 12; i = i+1) begin
if(z[19:16] > 4)
z[19:16] = z[19:16] + 3;
if(z[23:20] > 4)
z[23:20] = z[23:20] + 3;
if(z[27:24] > 4)
z[27:24] = z[27:24] + 3;
if(z[31:28] > 4)
z[31:28] = z[31:28] + 3;
if(z[35:32] > 4)
z[35:32] = z[35:32] + 3;
z[35:1] = z[34:0];
end
P = z[35:16];
end
endmodule
module counter(
// Outputs
count,
// Inputs
reset, clk,
clk_en
);
input reset,clk;
input clk_en;
output [15:0] count;
reg [15:0] count;
always @(posedge clk or posedge reset)
if (reset) count <= 0;
else if (clk_en) count <= count + 1;
endmodule // counter
module LCD(
// Outputs
LCD_RS, LCD_E, CLK_10HZ, LCD_RW, DATA_BUS,
// Inputs
reset, clk_12Mhz, C1L1, C2L1, C3L1, C4L1, C5L1, C6L1, C7L1, C8L1, C9L1,
C10L1, C11L1, C12L1, C13L1, C14L1, C15L1, C16L1, C1L2, C2L2, C3L2, C4L2,
C5L2, C6L2, C7L2, C8L2, C9L2, C10L2, C11L2, C12L2, C13L2, C14L2, C15L2,
C16L2
);
input reset, clk_12Mhz;
output LCD_RS;
output LCD_E;
output CLK_10HZ;
output LCD_RW;
input [7:0] C1L1,C2L1,C3L1,C4L1,C5L1,C6L1,C7L1,C8L1,C9L1;
input [7:0] C10L1,C11L1,C12L1,C13L1,C14L1,C15L1,C16L1;
input [7:0] C1L2,C2L2,C3L2,C4L2,C5L2,C6L2,C7L2,C8L2,C9L2;
input [7:0] C10L2,C11L2,C12L2,C13L2,C14L2,C15L2,C16L2;
output [7:0] DATA_BUS;
reg LCD_RS;
reg LCD_E;
reg CLK_400HZ;
reg LCD_RW;
parameter RESET1 = 0,
RESET2 = 1,
RESET3 = 2,
FUNC_SET = 3,
MODE_SET = 4,
DISPLAY_ON = 5,
WRITE_CHAR1 = 6,
WRITE_CHAR2 = 7,
WRITE_CHAR3 = 8,
WRITE_CHAR4 = 9,
WRITE_CHAR5 = 10,
WRITE_CHAR6 = 11,
WRITE_CHAR7 = 12,
WRITE_CHAR8 = 13,
WRITE_CHAR9 = 14,
WRITE_CHAR10 = 15,
WRITE_CHAR11 = 16,
WRITE_CHAR12 = 17,
WRITE_CHAR13 = 18,
WRITE_CHAR14 = 19,
WRITE_CHAR15 = 20,
WRITE_CHAR16 = 21,
RETURN_HOME = 22,
TOGGLE_E = 23,
HOLD = 24,
DISPLAY_OFF = 25,
DISPLAY_CLEAR = 26; // these are the states
reg [4:0] state, next_command;
reg [7:0] DATA_BUS;
reg [15:0] CLK_COUNT_400HZ;
reg [7:0] CLK_COUNT_10HZ;
reg CLK_10HZ,LINE;
always @(posedge clk_12Mhz or posedge reset) begin
if (reset) begin
CLK_COUNT_400HZ <= 'h0000;
CLK_400HZ <= 1'b0;
end else begin
if (CLK_COUNT_400HZ == 'h7530) begin
CLK_COUNT_400HZ <= 'h0000;
CLK_400HZ <= 1'b1;
end else begin
CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
CLK_400HZ <= 1'b0;
end
end
end
// GENERATE 1 SEC CLOCK SIGNAL FOR SECOND COUNT PROCESS
always @(posedge clk_12Mhz or posedge reset) begin
if (reset) begin
CLK_COUNT_10HZ <= 8'h00;
CLK_10HZ <= 1'b0;
end else begin
CLK_10HZ <= CLK_400HZ & (CLK_COUNT_10HZ == 19);
if (CLK_400HZ)
if (CLK_COUNT_10HZ == 19)
CLK_COUNT_10HZ <= 8'h00;
else
CLK_COUNT_10HZ <= CLK_COUNT_10HZ + 1;
end
end
always @(posedge clk_12Mhz or posedge reset) begin
if (reset) begin
state <= RESET1;
DATA_BUS <= 8'h38;
next_command <= RESET2;
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
end else if (CLK_400HZ) begin
// SEND TIME TO LCD
case (state)
// Set Function to 8-bit transfer and 2 line display with 5x8 Font size
// see Hitachi HD44780 family data sheet for LCD command and timing details
RESET1 : begin
LINE <= 1'b1;
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h38;
state <= TOGGLE_E;
next_command <= RESET2;
end
RESET2 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h38;
state <= TOGGLE_E;
next_command <= RESET3;
end
RESET3 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h38;
state <= TOGGLE_E;
next_command <= FUNC_SET;
end
// EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
FUNC_SET : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h38;
state <= TOGGLE_E;
next_command <= DISPLAY_OFF;
end
// Turn off Display and Turn off cursor
DISPLAY_OFF : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h08;
state <= TOGGLE_E;
next_command <= DISPLAY_CLEAR;
end
// Turn on Display and Turn off cursor
DISPLAY_CLEAR : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h01;
state <= TOGGLE_E;
next_command <= DISPLAY_ON;
end
// Turn on Display and Turn off cursor
DISPLAY_ON : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h0C;
state <= TOGGLE_E;
next_command <= MODE_SET;
end
// Set write mode to auto increment address and move cursor to the right
MODE_SET : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW <= 1'b0;
DATA_BUS <= 8'h06;
state <= TOGGLE_E;
next_command <= WRITE_CHAR1;
end
// Write ASCII hex character in first LCD character location
WRITE_CHAR1 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C1L1;
else
DATA_BUS <= C1L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR2;
end
// Write ASCII hex character in second LCD character location
WRITE_CHAR2 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <=C2L1;
else
DATA_BUS <= C2L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR3;
end
// Write ASCII hex character in third LCD character location
WRITE_CHAR3 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C3L1 ;
else
DATA_BUS <= C3L2 ;
state <= TOGGLE_E;
next_command <= WRITE_CHAR4;
end
// Write ASCII hex character in fourth LCD character location
WRITE_CHAR4 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C4L1;
else
DATA_BUS <= C4L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR5;
end
// Write ASCII hex character in fifth LCD character location
WRITE_CHAR5 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C5L1;
else
DATA_BUS <= C5L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR6;
end
// Write ASCII hex character in sixth LCD character location
WRITE_CHAR6 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C6L1 ;
else
DATA_BUS <= C6L2 ;
state <= TOGGLE_E;
next_command <= WRITE_CHAR7;
end
// Write ASCII hex character in seventh LCD character location
WRITE_CHAR7 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C7L1;
else
DATA_BUS <= C7L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR8;
end
// Write ASCII hex character in eighth LCD character location
WRITE_CHAR8 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <= C8L1;
else
DATA_BUS <= C8L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR9;
end
WRITE_CHAR9 : begin
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW <= 1'b0;
if (LINE == 1'b0)
DATA_BUS <=C9L1;
else
DATA_BUS <= C9L2;
state <= TOGGLE_E;
next_command <= WRITE_CHAR10;
end
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?