The final lab project will be designing an interface from the serial output of the PC to an LCD (liquid crystal display). In this laboratory assignment you will design a simple LCD controller using three 22V10 PALs and behavioral Verilog. In the next, and final, lab you will add the serial line input. You are now familiar with two very powerful tools: ActiveHDL and behavioral Verilog, and you will employ them both extensively in order to complete this assignment.
You should work with your partner on this assignment. You
should fully design and simulate this circuit before you try to construct
it. You should do as much as you can before attending lab session. This lab
assignment is definitely more challenging than the previous ones, and you may
not be able to finish within the first lab session. However, you will have an
extra week this time to complete the assignment.
Your goal is to design a circuit which can write an arbitrary ASCII character code entered on your prototyping switches to an LCD display. (In the next lab, the character will be come from a serial input.) Three PALs will be required to control the LCD: an 8-bit tri-state driver, an LCD command “decoder,” and a main controller PAL that directs them. Only the main controller should be sequential. The tri-state driver and command decoder should be very simple and merely implement combinational logic.
The LCD which you will be using has many advanced functions (see the datasheet for a complete explanation), but you will only be concerned with the following two:
The pin layout of the LCD follows:
Pin |
Name |
Function |
1 |
GND |
0 V |
2 |
Vdd |
5 V |
3 |
Vo |
1 V |
4 |
RS |
High: Data input Low: Instruction input |
5 |
R/W |
High: Read from LCD Low: Write to LCD |
6 |
E |
Enable the LCD |
7 |
DB0 |
Data bus |
8 |
DB1 |
|
9 |
DB2 |
|
10 |
DB3 |
|
11 |
DB4 |
|
12 |
DB5 |
|
13 |
DB6 |
|
14 |
DB7 |
Pins 1-3 are power supply connections and will be explained later. Pins 4-14 are signals that you must supply. R/W specifies whether you are reading or writing the display: Since you will only be writing to the display, the R/W signal will always be 0. RS is used to determine whether you are sending a command or ASCII data to the display. E (enable) is used to provide a strobe that causes the operation to be executed. The enable E is really clock signal for the LCD that you must generate: the LCD commits a new character or command on the negative edge of E. The data pins contain either an ASCII character code or a command code depending upon the value of RS. You will need to multiplex this data bus between an instruction source and a data source using tri-state drivers in the PAL.
The following is a table with the codes for the 5 commands that you need to execute for this assignment. The first four should be executed in sequence on reset. The last command is used to write a character to the display. You can look at the documentation if you would like to try out other commands.
Operation |
RS |
DB[7:0] |
Clear Display |
0 |
0000 0001 |
Function Set |
0 |
0011 0011 |
Display On |
0 |
0000 1100 |
Entry Mode Set |
0 |
0000 0110 |
Write Character |
1 |
DDDD DDDD |
Your “main controller” PAL will contain a finite state machine that (a) sends the four command sequence to the LCD on reset, and (b) writes characters to the LCD when the input “write” is asserted indicating that a new character is available. This controller FSM will sequence through the commands, asserting the appropriate command or data on the data bus and generating the enable E and RS signals.
It will be immediately apparent that one PAL is too small for this. The data bus and control signals E and RS are 10 outputs just by themselves. Thus you will need partition the state machine so that the 8-bit command value is generated by a 2nd PAL that is controlled by the FSM. This “command decoder” PAL will expand a tightly encoded command code from your main controller into the 8-bit wide command code that the LCD expects. The controller PAL must also control the multiplexing of the command and data onto the databus. We will do this using tri-state drivers: either the command PAL will drive the databus, or the 3rd “data” PAL will drive the databus.
Finally, you will need to set the contrast for the LCD screen. For this, we have to apply a specific voltage at the Vo pin. We can do so with the voltage divider circuit shown in the figure below. It will generate a voltage Vo of approximately 1/(1+4) of Vdd or 20% of 5V (1V). In your kit should be a 3.9K ohm resistor and a 1K ohm resistor. You can determine the resistance value of a resistor by the color coded bands on the resistor (see explanation of how the color coded system works and an automated calculator).
The following Verilog implements an 8-bit tri-state driver which will serve your purposes for this assignment. You are encouraged to use an intuitive pin assignment. The provided file tri_driver.ctl will do just fine. Note how “turning off” the output of a pin is expressed in Verilog: rather than assigning 0 or 1 to the output, we assign a z, which stands for “not driven”.
module
tri_driver (en, from, to);
input en;
input [7:0] from;
output [7:0] to;
assign to = (en) ? from : 8'bzzzzzzzz;
endmodule
The following is a do-nothing stub which you will need to complete for the command decoder. Again, a sane pin assignment is highly recommended (use lcd_cmd.ctl). Remember that, since you will wire the outputs of the 8-bit tri-state driver together with the outputs of this PAL, you will need to be able to also “turn off” this chip’s output when data is being driven to the databus..
module
lcd_cmd (RS, cmdIndex, lcdCMD);
input
RS;
// Used to tristate the LCD CMD
input [1:0] cmdIndex; // Index of the command
output [7:0] lcdCMD; // LCD command
/* YOUR CODE HERE */
endmodule
Here is another stub module which you will need to complete. Note: Before you start writing this module, draw a complete, correct state diagram for its finite state machine. You will be asked to turn in the state diagram, and it definitely pays to carefully think about the exact timing of your finite state machine in this traditional manner before beginning to write the code for it. Pay particular attention to the timing of the RS and EN signals and use the lcd test fixture to make sure you’ve got it right.
You will need to write your own pin assignment file for this chip, unless, of course, you prefer the nearly random pin assignments of the synthesis tool.
module
lcd_control (clk, reset, write, EN, RS, CMD);
input clk, reset;
input write; // Write a character to the
LCD
output EN, RS; // Enable, RS signals of LCD
output [1:0] CMD; // Index for current LCD command
/* reg [??:??] state; */
/* YOUR DECLARATIONS ETC. GO HERE */
always @(posedge clk) begin
/* YOUR REGISTER CODE GOES HERE */
end
always @(state or . . . ) begin
/* YOUR STATE MACHINE CODE GOES HERE */
end
endmodule
You must verify your final circuit design before actually programming your PALs and wiring it. Use the LCD test fixture lcd_tf.v to simulate the precise timing behavior of the LCD entirely within ActiveHDL. Now that you are beginning to understand behavioral Verilog, you might want to read and understand the behavior of the test fixture if that of the LCD itself is not clear to you. Note that this test fixture is not like some of those that you’ve worked with in the past. It does not exhaustively test your design for all possible (or any) inputs. It merely simulates an LCD and writes characters to the ActiveHDL console when properly used, so you will be responsible for anticipating, handling, and verifying all of the interesting “boundary conditions” for your design.
After successful simulation of your design, program your PALs, and wire up the full circuit. Be prepared to reprogram a chip for a bug fix, and wire accordingly. In other words, try to wire as neatly as possible, and try to do so such that your chips may be extracted from the circuit without significant rewiring. Consider ways in which you might be able to use fewer wires for the LCD’s data bus. You are encouraged to use the wire packages in your kits, but you may cut and strip your own wire from scratch if you wish.
Full credit completion of this assignment will include all of the following by the given due date: