Lab 3
Lab 3
Lab 3
1
1 Introduction
In this lab you will interface a PS/2 keyboard (standard PC keyboard) with the XSB board.
Scan codes will be received from the keyboard and displayed the scan codes in hex format on
the XSB digit LEDs.
The PS/2 interface is used to connect other devices than keyboards. In this text we refer to the
“PS/2 Keyboard Interface”, but the PS/2 interface is a general serial interface and the
keyboard is just a device that uses the PS/2 interface.
The FPGA/keyboard interface is shown in figure 1. When the FPGA “reads” the Data or
Clock inputs both PS2Data_out and PS2Clk_out are kept low which puts the tri-state buffers
in high impedance mode. When the FPGA "writes" a logic 0 on an output, the corresponding
x_out (x = PS2Data or PS2Clk) signal is set high which pulls the line low. When “writing”
logic 1 the FPGA simply sets the x_out signal low.
+5V
Xilinx FPGA
PS2Data_out
0
Data
Keyboard
PS2Data
Clock
PS2Clk_out
PS2Clk
In this lab you will not write data to the keyboard, the FPGA will only “sniff” the data sent by
the keyboard. So there is no need to implement the tristate buffers illustrated in figure 1.
Note: The lab setup up is a hack! Don’t try this at home . The Spartan IIE FPGA on XSB
board is not 5V tolerant, that is the FPGA can be destroyed if the input buffer are fed with 5V.
In order to interface a keyboard we really should use some kind of voltage level conversion.
2
But since this is a last minute hack we power the keyboard with 3.3V. This will probably
violate the PS/2 specification but for the particular keyboards we have in the lab it does work.
Clock
Data Start Data0 Data1 Data2 Data3 Data4 Data5 Data6 Data7 Parity Stop
The keyboard may initiate a transfer if the Clock line is high. The host (FPGA in this case)
may force the Clock low in order to prevent the keyboard from sending data – the host may
inhibit communication. Note that the keyboard generates the clock. Data is valid at least 5 us
(t in figure 3) before the falling edge of the clock. The clock period is (T in figure 3) is 60 to
100 us.
T
Datax
One of the keyboards in the lab was tested with a logic analyzer as shown in Figure 4.
Data is sent in bit serially. The first bit is always a start bit, logic 0. Then 8 bits are sent with
the least significant bit first. The data is padded with a parity bit (odd parity). The parity bit is
set if there is an even number of 1' s in the data bits and reset (logic 0) if there is an odd
number of 1' s in the data bits. The number of 1’s in the data bits plus the parity bit always
adds up to an odd number (odd parity.) This is used for error detection. A stop bit (logic 1)
indicates the end of the data stream.
3
2.3 The keyboard scan-codes
The keyboard sends packets of data, scan codes, to the host indicating which key has been
pressed. When a key is pressed or held down a make code is transmitted. When a key is
released a break code is transmitted. Every key is assigned a unique make and break code so
that the host can determine exactly what has happened.
There are three different scan code sets, but all PC keyboards use Scan Code Set 2. A sample
of this scan code set is listed in table 1. Please refer to the lab homepage for the full scan code
set.
4
Following we will partition this problem into more manageable pieces. We will partition the
design into a data path and a control path. A block diagram of the complete design is shown in
figure 5. Please note that the suggested implementation may not be optimal. There are many
ways to implement the desired functionality. This is just one example.
All flip-flops in the design are clocked with a 20 MHz clock and the rising edge is the active
edge. Three types of positive edge-triggered D-flip-flops are shown in Figure 5.
The PS2Data and PS2Clk signals are sampled with FDP flip-flops. The PS2Data is fed
into a shift register. When 8 data bits (scan code) and one parity bit has been shifted into the
shift register the scan code is written to a synchronous FIFO. When the FIFO is not empty the
output is read in intervals of approximately 1 second. The FIFO output is connected to two
identical ROMs. The ROMs decode the scan code data so that a character “0” – “F” is
displayed on each digit LED.
A short description of each module in the data and control path follows.
The shift register is an 8 bit serial in parallel out (SIPO) shift register with a shift enable input.
5
3.1.2 FIFO
The FIFO stores a maximum of 256 bytes. The data input and outputs are 8 bits wide. The
FIFO is initialized synchronously by setting sinit high. When wr_en is set high data is
written to the FIFO and when rd_en is set high data is read from the FIFO. Two flags,
empty and full indicate the status of the FIFO. The FIFO will be created with the Xilinx
Core Generator tool.
Start Core Generator with the command coregen. In the dialog box that appears; chose to
create a new project. The New Project dialog appears:
6
Double-
click here!
Complete the dialog as indicated in the figure above. Leave “Handshaking Options” to the
default values. Click “Generate” to generate the FIFO core. Next click “Data Sheet…” and
read the specifications for the FIFO. Next exit the Core Generator.
fifo.edn EDIF implementation netlist for the core. Describes how the core is
to be implemented. Used as input to the Xilinx implementation
tools.
7
fifo.vho VHDL Template file. The components in this file can be used to
instantiate a core.
fifo.vhd VHDL wrapper file. Used to instantiate the core during simulation.
The figure below illustrates how the two files are used in the design flow. The synthesis tool
will read the FIFO netlist to in order to make an area and timing estimate of the core. The
output from the synthesis tool is an EDIF net list where the core is instantiated. But this netlist
contains no information about how the FIFO is implemented. Instead there will be two
separate netlists that are input to the implementation tool. You may see it as the two netlists
will be “merged” together in the implementation tool.
.VHO VHDL
Core Generator Instantiation Emacs
VHDL
EDIF Netlist
Xilinx CoreLib
Simulation model
NC VHDL
Simulator
EDIF Netlist
The parity checker is a combinational unit that outputs a ‘1’ if there is no parity error; else it
outputs a ‘0’.
3.1.4 ROM
The ROM converts four bits of the scan code so that a digit “0” – “F” is displayed on the digit
LEDs. You must (for educational reasons) model the ROMs as function calls. You have been
8
provided with a skeleton for this function in the package smd152_pkg (see file
smd152_pkg.vhd)
9
3.2 Control path components
3.2.1 “One-shot” component
The one-shot component should output a pulse for one clock cycle when it detects that the
PS2Clk has transitioned from high to low. See timing diagram below.
Clock
PS2Clk
Pulse
The pulsed output will be used to enable the shift register. As previously mentioned
PS2Data is valid on the falling edge of PS2Clk. However we do not want enable the shift
register every falling edge of PS2Clk. The pulse is passed through a Finite State Machine
(FSM) that may suppress the pulse.
The receiver FSM controls that the PS/2 data is read correctly. An ASM chart for the FSM is
shown below. When the FSM powers up or is reset it enters the Idle state. When
PS2ClkPulse and PSData are set a start bit has been detected and the FSM enters the
state SO. The FSM stays in this state until PS2ClkPulse is high again. When this happens
the Shift_en is set high in the same clock cycle and the next clock cycle the FSM enters
the state, S0. The Shift_en signal enables the shift register and shifts in PS/2 data bits.
States S1 to S7 are identical to S0. The state Parity is also identical to S0. When the FSM
enters the StopBit state the shift register contains the scan code and the parity bit. The
FSM stays in the StopBit state until another pulse is detected on PS2ClkPulse. When
the pulse is detected, a stop bit is detected and the parity is correct the FifoWrite signal is
set and the FSM returns to the Idle state. If a stop bit is not detected or the parity is incorrect
the FSM enters the Idle state without enabling the FifoWrite signal.
10
Idle Parity
0 0
PS2ClkPulse PS2ClkPulse
1 1
1 Shift_en
PS2Data
0
Stop
S0 Bit
0
0 PS2ClkPulse
PS2ClkPulse
1
1
0
Shift_en PS2Data
S1 to S7 same
as S0 0
ParityOK
FifoWrite
The FSM does not check if the FIFO is full before writing to it. Practically this means that
some scan codes may be lost.
Since states S0 to S7 and Parity are identical the number of states can be reduced. For
instance a counter could have been used to keep track of how many bits that have been shifted
in to the shift register. You can choose how to implement the FSM – using “many” states or
fewer states and a counter.
3.2.3 Timer
The timer controls the update rate of the digit LEDs and consequently at what rate the FIFO
data is read. Design a timer that updates the digits LEDs at a rate of approximately 0.5 - 1 Hz.
Note that you should not read from the FIFO while it is empty.
11
The output from the timer enables read from FIFO. The output from timer delayed by one
clock cycle is used to enable the output registers for the digit LEDs. The FIFO data output is
valid one clock cycle after the read signal is activated.
As you will notice simulating one second takes a loooong time. In order to speed up
simulation you can modify the timer so the update rate is shorter. But remember to change the
code before you synthesize your design!
To save some time: As an example, use the following procedure to create a new file and entity
for the ShiftReg component:
The input/output registers and the ROM should be implemented in a process found at the end
of the architecture. There is a skeleton for a function, Bin2LED(), in smd152_pkg.vhd.
FYI, the LEDs are attached to a shared peripheral bus on the XSB board. Memory, Ethernet
controller, USB etc. must be tristated if a stable signal is desired to the LEDs. The ports and
signal assignment is given in this lab.
3.4 Simulation
You may use the following commands to compile your code:
ncvhdl fifo.vhd
ncvhdl smd152_pkg.vhd
ncvhdl OneShot.vhd
ncvhdl ParityChecker.vhd
ncvhdl ReceiverFSM.vhd
ncvhdl ShiftReg.vhd
ncvhdl Timer.vhd
ncvhdl Spartan.vhd
ncvhdl Spartan_tb.vhd
To elaborate use:
12
ncelab work.Spartan_tb:sim
To simulate use:
You have been provided with a test bench. The test bench only apply stimuli, it does not
check if the result is correct! You should study the test bench and perhaps extend it.
3.5 Synthesis
Use the same device as you have used in the first lab – Xilinx Spartan IIe, XC2S300E, speed
grade 6, package PQ208. Constrain the clock frequency to 20 MHz. See figure below. You
may ignore the input/output constraints for this lab.
Device tab
VHDL tab
Add all the VHDL files and the generated FIFO edif netlist to the Synplify project, see Figure
13 below.
13
Figure 13 Files (VHDL and edif) added to Synplify
3.6 Implementation
After you have completed the synthesis process start the Xilinx implementation tools. From
the Synplify Pro menu select: Options Xilinx Start ISE Project Navigator.
The commands should be similar to the commands used in lab1, that is, add the netlist for the
fifo (fifo.edn) and the constraint file Spartan.ucf when you implement your design.
Select project Add Copy of Source… and navigate to the files. The source tree should
look like the figure below.
Then select Spartan.edn in the Sources in Project: window. Then right-click Implement
Design according to the figure below and select Properties…
14
Select
Spartan
Right-click
Implement design,
select Properties
Figure 15 Xilinx ISE
This will bring up the Process Properties window. Select the Place & Route tab and set the
“Place and Route Effort Level” to “High” and click OK.
Now press the Play button! (Right-click Implement design and select Run.) Finally, right-
click Generate Programming file and select Run.
15