Lab 6 DSD

Download as pdf or txt
Download as pdf or txt
You are on page 1of 12

Digital System Design

CPE – 344
Lab 6

Name Rohaid Ahmed Mirza

Registration Number FA19-BCE-006

Class BCE – 7A

Instructor’s Name Sir Bilal Qasim


In lab:
Main Code:
module PmodCLP( data,
btnr,
CLK,
JA,
JB
);

input btnr; // use BTNR as reset


input
input CLK; // 100 MHz
clock input
input [7:0]data;
//lcd input signals
//signal on connector JA
output [7:0] JA; //output bus,
used for data transfer (DB)
// signal on connector JB
//JB[4]register selection pin (RS)
//JB[5]selects between read/write modes (RW)
//JB[6]enable signal for starting the data read/write (E)
output [6:4] JB;
wire [7:0] JA;
wire [6:4] JB;

//LCD control state machine


parameter [3:0] stFunctionSet = 0, //
Initialization states
stDisplayCtrlSet = 1,
stDisplayClear = 2,
stPowerOn_Delay = 3,
// Delay states
stFunctionSet_Delay = 4,
stDisplayCtrlSet_Delay = 5,
stDisplayClear_Delay = 6,
stInitDne = 7,
// Display characters and perform standard operations
stActWr = 8,
stCharDelay = 9;
// Write delay for operations

/* These constants are used to initialize the LCD pannel.

-- FunctionSet:
Bit 0 and 1 are arbitrary
Bit 2: Displays font
type(0=5x8, 1=5x11)
Bit 3: Numbers of
display lines (0=1, 1=2)
Bit 4: Data length (0=4
bit, 1=8 bit)
Bit 5-7 are set
-- DisplayCtrlSet:
Bit 0: Blinking cursor
control (0=off, 1=on)
Bit 1: Cursor (0=off,
1=on)
Bit 2: Display (0=off,
1=on)
Bit 3-7 are set
-- DisplayClear:
Bit 1-7 are set */

reg [6:0] clkCount = 7'b0000000;


reg [20:0] count = 21'b000000000000000000000; // 21 bit count
variable for timing delays
wire delayOK;
// High when count has reached the right delay
time
reg oneUSClk;
// Signal is treated as a 1 MHz clock
reg [3:0] stCur = stPowerOn_Delay; //
LCD control state machine
reg [3:0] stNext;
wire writeDone;
// Command set finish

reg [9:0] LCD_CMDS[0:23];


reg [4:0] lcd_cmd_ptr;
initial begin
LCD_CMDS[0] = {2'b00, 8'h3C};// 0, Function Set
LCD_CMDS[1] = {2'b00, 8'h0C}; // 1, Display ON, Cursor
OFF, Blink OFF
LCD_CMDS[2] = {2'b00, 8'h01}; // 2, Clear Display
LCD_CMDS[3] = {2'b00, 8'h02}; // 3, Return Home
LCD_CMDS[4] = {2'b10, 8'h52}; // 4, R
LCD_CMDS[5] = {2'b10, 8'h6F}; // 5, o
LCD_CMDS[6] = {2'b10, 8'h68}; // 6, h
LCD_CMDS[7] = {2'b10, 8'h61}; // 7, a
LCD_CMDS[8] = {2'b10, 8'h69}; // 8, i
LCD_CMDS[9] = {2'b10, 8'h64}; // 9, d
LCD_CMDS[10] = {2'b10, 8'h20}; // 10, blank
LCD_CMDS[11] = {2'b10, 8'h41}; // 11, A
LCD_CMDS[12] = {2'b10, 8'h68}; // 12, h
LCD_CMDS[13] = {2'b10, 8'h6D}; // 13, m
LCD_CMDS[14] = {2'b10, 8'h65}; // 14, e
LCD_CMDS[15] = {2'b10, 8'h64}; // 15, d
LCD_CMDS[16] = {2'b10, 8'h20}; // 16, blank
LCD_CMDS[17] = {2'b10, 8'h4D}; // 17, M
LCD_CMDS[18] = {2'b10, 8'h69}; // 18, i
LCD_CMDS[19] = {2'b10, 8'h72}; // 19, r
LCD_CMDS[20] = {2'b10, 8'h7A}; // 20, z
LCD_CMDS[21] = {2'b10, 8'h61}; // 21, a
LCD_CMDS[22] = {2'b00, 8'h18}; // 22, Shift left

end

// This process counts to 100, and then resets. It is used to


divide the clock signal.
// This makes oneUSClock peak aprox. once every 1microsecond
always @(posedge CLK) begin

if(clkCount == 7'b1100100) begin


clkCount <= 7'b0000000;
oneUSClk <= ~oneUSClk;
end
else begin
clkCount <= clkCount + 1'b1;
end

end

// This process increments the count variable unless delayOK = 1.


always @(posedge oneUSClk) begin

if(delayOK == 1'b1) begin


count <= 21'b000000000000000000000;
end
else begin
count <= count + 1'b1;
end

end

// Determines when count has gotten to the right number,


depending on the state.
assign delayOK = (
((stCur == stPowerOn_Delay) && (count ==
21'b111101000010010000000)) || // 2000000 ->
20 ms
((stCur == stFunctionSet_Delay) && (count ==
21'b000000000111110100000)) || // 4000 -> 40 us
((stCur == stDisplayCtrlSet_Delay) && (count ==
21'b000000000111110100000)) || // 4000 -> 40 us
((stCur == stDisplayClear_Delay) && (count ==
21'b000100111000100000000)) || // 160000 -> 1.6 ms
((stCur == stCharDelay) && (count ==
21'b000111111011110100000)) // 260000
-> 2.6 ms - Max Delay for character writes and shifts
) ? 1'b1 : 1'b0;

// writeDone goes high when all commands have been run


assign writeDone = (lcd_cmd_ptr == 5'd21) ? 1'b1 : 1'b0;

// Increments the pointer so the statemachine goes through the


commands
always @(posedge oneUSClk) begin
if((stNext == stInitDne || stNext == stDisplayCtrlSet
|| stNext == stDisplayClear) && writeDone == 1'b0) begin
lcd_cmd_ptr <= lcd_cmd_ptr + 1'b1;
end
else if(stCur == stPowerOn_Delay || stNext ==
stPowerOn_Delay) begin
lcd_cmd_ptr <= 5'b00000;
end
else begin
lcd_cmd_ptr <= lcd_cmd_ptr;
end
end

// This process runs the LCD state machine


always @(posedge oneUSClk) begin
if(btnr == 1'b1) begin
stCur <= stPowerOn_Delay;
end
else begin
stCur <= stNext; LCD_CMDS[7] = {2'b10,
data};
end
end

// This process generates the sequence of outputs needed to


initialize and write to the LCD screen
always @(stCur or delayOK or writeDone or lcd_cmd_ptr) begin
case (stCur)
// Delays the state machine for 20ms which is
needed for proper startup.
stPowerOn_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stFunctionSet;
end
else begin
stNext <= stPowerOn_Delay;
end
end

// This issues the function set to the LCD as


follows
// 8 bit data length, 1 lines, font is 5x8.
stFunctionSet : begin
stNext <= stFunctionSet_Delay;
end

// Gives the proper delay of 37us between the


function set and
// the display control set.
stFunctionSet_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stDisplayCtrlSet;
end
else begin
stNext <= stFunctionSet_Delay;
end
end

// Issuse the display control set as follows


// Display ON, Cursor OFF, Blinking Cursor OFF.
stDisplayCtrlSet : begin
stNext <= stDisplayCtrlSet_Delay;
end

// Gives the proper delay of 37us between the


display control set
// and the Display Clear command.
stDisplayCtrlSet_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stDisplayClear;
end
else begin
stNext <=
stDisplayCtrlSet_Delay;
end
end

// Issues the display clear command.


stDisplayClear : begin
stNext <= stDisplayClear_Delay;
end

// Gives the proper delay of 1.52ms between the


clear command
// and the state where you are clear to do
normal operations.
stDisplayClear_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stInitDne;
end
else begin
stNext <= stDisplayClear_Delay;
end
end

// State for normal operations for displaying


characters, changing the
// Cursor position etc.
stInitDne : begin
stNext <= stActWr;
end

// stActWr
stActWr : begin
stNext <= stCharDelay;
end

// Provides a max delay between instructions.


stCharDelay : begin
if(delayOK == 1'b1) begin
stNext <= stInitDne;
end
else begin
stNext <= stCharDelay;
end
end

default : stNext <= stPowerOn_Delay;

endcase
end

// Assign outputs
assign JB[4] = LCD_CMDS[lcd_cmd_ptr][9];
assign JB[5] = LCD_CMDS[lcd_cmd_ptr][8];
assign JA = LCD_CMDS[lcd_cmd_ptr][7:0];
assign JB[6] = (stCur == stFunctionSet || stCur ==
stDisplayCtrlSet || stCur == stDisplayClear || stCur == stActWr) ? 1'b1
: 1'b0;

endmodule

Post lab:
Main Code:
module PmodCLP( data,
btnr,
CLK,
JA,
JB
);

input btnr; // use BTNR as reset


input
input CLK; // 100
MHz clock input
input [7:0]data;
//lcd input signals
//signal on connector JA
output [7:0] JA; //output bus,
used for data transfer (DB)
// signal on connector JB
//JB[4]register selection pin (RS)
//JB[5]selects between read/write modes (RW)
//JB[6]enable signal for starting the data read/write (E)
output [6:4] JB;
wire [7:0] JA;
wire [6:4] JB;

//LCD control state machine


parameter [3:0] stFunctionSet = 0, //
Initialization states
stDisplayCtrlSet = 1,
stDisplayClear = 2,
stPowerOn_Delay = 3,
// Delay states
stFunctionSet_Delay = 4,
stDisplayCtrlSet_Delay = 5,
stDisplayClear_Delay = 6,
stInitDne = 7,
// Display characters and perform standard operations
stActWr = 8,
stCharDelay = 9;
// Write delay for operations

/* These constants are used to initialize the LCD pannel.

-- FunctionSet:
Bit 0 and 1 are arbitrary
Bit 2: Displays font
type(0=5x8, 1=5x11)
Bit 3: Numbers of
display lines (0=1, 1=2)
Bit 4: Data length (0=4
bit, 1=8 bit)
Bit 5-7 are set
-- DisplayCtrlSet:
Bit 0: Blinking cursor
control (0=off, 1=on)
Bit 1: Cursor (0=off,
1=on)
Bit 2: Display (0=off,
1=on)
Bit 3-7 are set
-- DisplayClear:
Bit 1-7 are set */

reg [6:0] clkCount = 7'b0000000;


reg [20:0] count = 21'b000000000000000000000; // 21 bit count
variable for timing delays
wire delayOK;
// High when count has reached the right delay
time
reg oneUSClk;
// Signal is treated as a 1 MHz clock
reg [3:0] stCur = stPowerOn_Delay; //
LCD control state machine
reg [3:0] stNext;
wire writeDone;
// Command set finish

reg [9:0] LCD_CMDS[0:35];


reg [4:0] lcd_cmd_ptr;
initial begin
LCD_CMDS[0] = {2'b00, 8'h3C};// 0, Function Set
LCD_CMDS[1] = {2'b00, 8'h0C}; // 1, Display ON, Cursor
OFF, Blink OFF
LCD_CMDS[2] = {2'b00, 8'h01}; // 2, Clear Display
LCD_CMDS[3] = {2'b00, 8'h02}; // 3, Return Home
LCD_CMDS[4] = {2'b10, 8'h52}; // 4, R
LCD_CMDS[5] = {2'b10, 8'h6F}; // 5, o
LCD_CMDS[6] = {2'b10, 8'h68}; // 6, h
LCD_CMDS[7] = {2'b10, 8'h61}; // 7, a
LCD_CMDS[8] = {2'b10, 8'h69}; // 8, i
LCD_CMDS[9] = {2'b10, 8'h64}; // 9, d
LCD_CMDS[10] = {2'b10, 8'h20}; // 10, blank
LCD_CMDS[11] = {2'b10, 8'h41}; // 11, A
LCD_CMDS[12] = {2'b10, 8'h68}; // 12, h
LCD_CMDS[13] = {2'b10, 8'h6D}; // 13, m
LCD_CMDS[14] = {2'b10, 8'h65}; // 14, e
LCD_CMDS[15] = {2'b10, 8'h64}; // 15, d
LCD_CMDS[16] = {2'b10, 8'h20}; // 16, blank
LCD_CMDS[17] = {2'b10, 8'h4D}; // 17, M
LCD_CMDS[18] = {2'b10, 8'h69}; // 18, i
LCD_CMDS[19] = {2'b10, 8'h72}; // 19, r
LCD_CMDS[20] = {2'b10, 8'h7A}; // 20, z
LCD_CMDS[21] = {2'b10, 8'h61}; // 21, a
LCD_CMDS[22] = {2'b10, 8'hC0}; // 21, next line
LCD_CMDS[23] = {2'b10, 8'h46}; // 21, F
LCD_CMDS[24] = {2'b10, 8'h41}; // 21, A
LCD_CMDS[25] = {2'b10, 8'h31}; // 21, 1
LCD_CMDS[26] = {2'b10, 8'h39}; // 21, 9
LCD_CMDS[27] = {2'b10, 8'hB0}; // 21, -
LCD_CMDS[28] = {2'b10, 8'h42}; // 21, B
LCD_CMDS[29] = {2'b10, 8'h43}; // 21, C
LCD_CMDS[30] = {2'b10, 8'h45}; // 21, E
LCD_CMDS[31] = {2'b10, 8'hB0}; // 21, -
LCD_CMDS[32] = {2'b10, 8'h30}; // 21, 0
LCD_CMDS[33] = {2'b10, 8'h30}; // 21, 0
LCD_CMDS[34] = {2'b10, 8'h36}; // 21, 6
LCD_CMDS[35] = {2'b00, 8'h18}; // 22, Shift left
end

// This process counts to 100, and then resets. It is used to


divide the clock signal.
// This makes oneUSClock peak aprox. once every 1microsecond
always @(posedge CLK) begin

if(clkCount == 7'b1100100) begin


clkCount <= 7'b0000000;
oneUSClk <= ~oneUSClk;
end
else begin
clkCount <= clkCount + 1'b1;
end

end

// This process increments the count variable unless delayOK = 1.


always @(posedge oneUSClk) begin

if(delayOK == 1'b1) begin


count <= 21'b000000000000000000000;
end
else begin
count <= count + 1'b1;
end

end

// Determines when count has gotten to the right number,


depending on the state.
assign delayOK = (
((stCur == stPowerOn_Delay) && (count ==
21'b111101000010010000000)) || // 2000000 ->
20 ms
((stCur == stFunctionSet_Delay) && (count ==
21'b000000000111110100000)) || // 4000 -> 40 us
((stCur == stDisplayCtrlSet_Delay) && (count ==
21'b000000000111110100000)) || // 4000 -> 40 us
((stCur == stDisplayClear_Delay) && (count ==
21'b000100111000100000000)) || // 160000 -> 1.6 ms
((stCur == stCharDelay) && (count ==
21'b000111111011110100000)) // 260000
-> 2.6 ms - Max Delay for character writes and shifts
) ? 1'b1 : 1'b0;

// writeDone goes high when all commands have been run


assign writeDone = (lcd_cmd_ptr == 5'd21) ? 1'b1 : 1'b0;

// Increments the pointer so the statemachine goes through the


commands
always @(posedge oneUSClk) begin
if((stNext == stInitDne || stNext == stDisplayCtrlSet
|| stNext == stDisplayClear) && writeDone == 1'b0) begin
lcd_cmd_ptr <= lcd_cmd_ptr + 1'b1;
end
else if(stCur == stPowerOn_Delay || stNext ==
stPowerOn_Delay) begin
lcd_cmd_ptr <= 5'b00000;
end
else begin
lcd_cmd_ptr <= lcd_cmd_ptr;
end
end

// This process runs the LCD state machine


always @(posedge oneUSClk) begin
if(btnr == 1'b1) begin
stCur <= stPowerOn_Delay;
end
else begin
stCur <= stNext; LCD_CMDS[7] = {2'b10,
data};
end
end

// This process generates the sequence of outputs needed to


initialize and write to the LCD screen
always @(stCur or delayOK or writeDone or lcd_cmd_ptr) begin
case (stCur)
// Delays the state machine for 20ms which is
needed for proper startup.
stPowerOn_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stFunctionSet;
end
else begin
stNext <= stPowerOn_Delay;
end
end

// This issues the function set to the LCD as


follows
// 8 bit data length, 1 lines, font is 5x8.
stFunctionSet : begin
stNext <= stFunctionSet_Delay;
end

// Gives the proper delay of 37us between the


function set and
// the display control set.
stFunctionSet_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stDisplayCtrlSet;
end
else begin
stNext <= stFunctionSet_Delay;
end
end

// Issuse the display control set as follows


// Display ON, Cursor OFF, Blinking Cursor OFF.
stDisplayCtrlSet : begin
stNext <= stDisplayCtrlSet_Delay;
end

// Gives the proper delay of 37us between the


display control set
// and the Display Clear command.
stDisplayCtrlSet_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stDisplayClear;
end
else begin
stNext <=
stDisplayCtrlSet_Delay;
end
end

// Issues the display clear command.


stDisplayClear : begin
stNext <= stDisplayClear_Delay;
end

// Gives the proper delay of 1.52ms between the


clear command
// and the state where you are clear to do
normal operations.
stDisplayClear_Delay : begin
if(delayOK == 1'b1) begin
stNext <= stInitDne;
end
else begin
stNext <= stDisplayClear_Delay;
end
end

// State for normal operations for displaying


characters, changing the
// Cursor position etc.
stInitDne : begin
stNext <= stActWr;
end
// stActWr
stActWr : begin
stNext <= stCharDelay;
end

// Provides a max delay between instructions.


stCharDelay : begin
if(delayOK == 1'b1) begin
stNext <= stInitDne;
end
else begin
stNext <= stCharDelay;
end
end

default : stNext <= stPowerOn_Delay;

endcase
end

// Assign outputs
assign JB[4] = LCD_CMDS[lcd_cmd_ptr][9];
assign JB[5] = LCD_CMDS[lcd_cmd_ptr][8];
assign JA = LCD_CMDS[lcd_cmd_ptr][7:0];
assign JB[6] = (stCur == stFunctionSet || stCur ==
stDisplayCtrlSet || stCur == stDisplayClear || stCur == stActWr) ? 1'b1
: 1'b0;

endmodule

Conclusion:
In this lab, we learnt to interface pmod lcd with FPGA and display text.

You might also like