EE/CS 52 Digital Oscilloscope Documentation Julian Panetta TA: Gabe Cohn Table of Contents
• User’s manual • Functional Specification • Block Diagram • Protoboard Schematic • Board Layout • Timing Diagrams
o VRAM Timing Specifications Read, Write, Refresh, Data Transfer
o LCD Timing Specifications LCD Signals
o SRAM Read, Write
o Rom Read
• Memory Map • Pin Assignment • Quartus Design
o Top Level Design o Analog Control Block o LCD/VRAM Control Block o LCD Signal Generator o Keypad Debouncer o Clock Divider
• VHDL o VRAM Controller State Machine
State machine diagram vram_controller_lut.vhd
o split.vhd, combine.vhd, combine_16_16.vhd • Software
o Drivers/Initialization start.s keypad.s, display.s, interrupts.s constants.s
o OS stubfuncs.c interfac.h
JulianPanetta EE/CS52 Page1TA:GabeCohn
Digital Oscilloscope User’s Manual
Introduction
This digital oscilloscope is an easy-to-use instrument for visualizing analog input signals. In fact, such great care has been taken to ensure ease of use that the user’s task of finding and attaching an analog voltage signal source has been removed entirely. Simply attach the oscilloscope to a computer, open up your $2500+ copy of Quartus, program the FPGA design into it, and you’re ready to view the beautiful, noise-free built-in simulated signal. Even better, there is no need to try to figure out how switch to another input signal because this oscilloscope has been specialized to display only this signal! Hardware
The hardware devices you use to interact with and monitor the oscilloscope are described on the next page.
JulianPanetta EE/CS52 Page2TA:GabeCohn
Device Name Device Type Description Keypad 4*4 Array of 16
keys Of the 16 keys, only 5 are used:
Display LCD Panel A “high” quality LCD to display the
oscilloscope’s output. Status LED LED A shiny red LED that lights when system
has booted to let you know that initialization has completed successfully and the scope interface should be running.
User Interface
Once programmed, the system boots into Normal mode with a 100ns sampling
rate and a positive slope mid-level (2.480V) trigger with no delay. x- and y-axes are displayed behind the trace, and a menu in the upper right-hand corner—demonstrated in the screenshot above—lets you change all of the scope’s settings and enter different sampling modes. To hide and show the menu, press the <Menu> key.
Up
MenuLeft Right
Down
Menu
JulianPanetta EE/CS52 Page3TA:GabeCohn
You can change from one highlighted menu item to the next using the <Up> and <Down> keys. To alter the highlighted configuration setting, the user presses the <Left> and <Right> keys to select a value.
The configurable settings and their values are as follows:
Menu Title Options and Description Mode Normal Scope waits for a trigger after completing each
retrace. Automatic Scope waits for a trigger after each retrace, but
retriggers automatically without a trigger event after a delay.
One-Shot Scope triggers only once, continuing to display the last trace captured.
Scale Scale Axes Display x and y axes along with trace. Scale Grid Display x-y grid along with the trace. Scale Off Display the trace only.
Sweep Items are time quantities that specify the sweep rate, or the time between successive samples options: 100ns, 200ns, 500ns, 1us, 2us, 5us, 10us, 20us, 50us, 100us, 200us, 500us, 1ms, 2ms, 5ms, 10ms, 20ms
Level 128 voltage quantities are given as choices for the trigger voltage level. The levels are equally spaced from 0V to 5V.
Slope Slope + Scope is triggered on a positive slope (rising edge)
Slope - Scope is triggered on a negative slope (falling edge)
Delay Time quantities ranging between 0ms and 1ms specify the time between the trigger and the start of the trace.
Limitations
If for some reason you have decided to go through the effort of finding a voltage source you want to measure, you will find that the oscilloscope has no connector to which you can attach the signal. The oscilloscope is compatible only with the built-in demonstration trace.
JulianPanetta EE/CS52 Page1TA:GabeCohn
Digital Oscilloscope Functional Specification Description: The system is an interactive digital oscilloscope displaying on a 640 x 200
LCD panel. The signal is input via an analog line in, which runs through an analog to digital converter. There is a keypad to change the operation parameters. The system must be connected to a computer to program the FPGA, but can be disconnected once booted.
Inputs: Input is received through a keypad, a serial connection, and an analog input
signal.
Input Name Input Type Description Keypad 4*4 Array of 16
keys Of the 16 keys, only 5 are used by the OS:
Serial RS-232 Port Allows communication with the NIOS using
GERMS. Downloading of sample data to the oscilloscope from the computer is not yet implemented.
Analog Analog Line In Analog signal line whose voltage variation with time the scope measures. This portion of the oscilloscope is not yet implemented.
Outputs: Output is implemented with a display, a serial connection, and a LED.
Output Name Output Type Description Display LCD Panel A 640 x 200 graphics panel used to display the
analog input and to present an operation and configuration menu to the user.
Serial RS-232 Port Allows sampled data to be uploaded to a
Up
MenuLeft Right
Down
JulianPanetta EE/CS52 Page2TA:GabeCohn
computer via a serial connection. This feature is not yet implemented.
Status LED LED LED lights when system has booted to inform user that the software initialization has completed successfully and the OS should be running.
User Interface: By default, the system boots into Normal mode with a 100ns sampling rate
and a positive slope mid-level (2.480V) trigger with no delay. x- and y-axes are displayed behind the trace, and a menu in the upper right-hand corner lets the user change all of the scope’s settings and enter different sampling modes. The user can press the menu key to toggle the menu’s visibility.
The user changes from one highlighted menu item to the next using the up and
down keys. To alter the highlighted configuration setting, the user presses the left and right keys to select a value.
Serial transfers will be implemented with “silent linking.” The computer will
send a request to transmit data or a request to receive data, and the oscilloscope will comply without asking the user to confirm. A status message for the transfer will be displayed in the lower left-hand corner.
The menu options are as follows:
Menu Title Options and Description Mode Normal Scope waits for a trigger after completing each retrace.
Automatic Scope waits for a trigger after each retrace, but retriggers automatically without a trigger event after a delay.
One-Shot Scope triggers only once, continuing to display the last trace captured.
Scale Scale Axes Display x and y axes along with trace. Scale Grid Display x-y grid along with the trace. Scale Off Display the trace only.
Sweep Items are time quantities that specify the sweep rate, or the time between successive samples options: 100ns, 200ns, 500ns, 1us, 2us, 5us, 10us, 20us, 50us, 100us, 200us, 500us, 1ms, 2ms, 5ms, 10ms, 20ms
Level 128 voltage quantities are given as choices for the trigger voltage level. The levels are equally spaced from 0V to 5V.
Slope Slope + Scope is triggered on a positive slope (rising edge) Slope - Scope is triggered on a negative slope (falling edge)
Delay Time quantities ranging between 0ms and 1ms specify the time between the trigger and the start of the trace.
JulianPanetta EE/CS52 Page3TA:GabeCohn
Error Handling: If a key not mapped to an interface action in the current mode of operation is pressed, then no operation occurs. No other errors are anticipated for the current implementation.
Once analog and serial input is implemented, the following error handling will apply:
If a buffer overflow occurs on the signal input queue, “Signal Buffer Overflow” is displayed in the lower left-hand corner, and no further input is accepted. If a serial overflow occurs, “Serial Buffer Overflow” is displayed. If an error with framing, parity, a break, or some other serial error occurs, the messages “Framing Error”, “Parity Error”, “Break Error”, and “Serial Error” are displayed respectively.
Algorithms: A FFT may be implemented in the future for data analysis purposes. Currently
no FFT is used. A look up table is used to validate the user’s keypresses. Data Structures: A circular queue will be used to buffer serial input in case bytes are received
faster than the NIOS can respond. A FIFO will also be used to buffer the signal input from the analog to digital converter/analog control block.
Limitations: There is currently no analog or serial input.
FPGA
NIOS CPU
Keypad
Debouncer
UART
VRAM/LCD
Controller
Analog
FIFO
Analog
Control Block
Interrupt
Controller
Chip Select
Logic
PIOs
Reset Logic
Clock Logic
Serial ADC
Buffers
Address
Control
Data
VRAM LCD
Keypad
SRAM ROMBu
ffe
rs
EE/CS 52 Digital Oscilloscope Block Diagram
1
1
2
2
3
3
4
4
5
5
6
6
D D
C C
B B
A A
Title
Number RevisionSize
B
Date: 11/19/2008 Sheet of File: C:\Documents and Settings\.. \protoboard.schdocDrawn By:
A012
A111
A210
A39
A48
A57
A66
A75
A827
A926
A1023
A1125
A124
A1328
A1429
A153
A162
A1730
CE22
OE24
DQ1 13
DQ2 14
DQ3 15
DQ4 17
DQ5 18
DQ6 19
DQ7 20
DQ8 21
A181
WE31
Am29F040-120
512k * 8 Bit ROM
A010
A19
A28
A37
A46
A55
A64
A73
A825
A924
A1021
A1123
A122
CS20
WE27 OE22
D0 11
D1 12
D2 13
D3 15
D4 16
D5 17
D6 18
D7 19
A1326
A141
W24257A
1K
R3Res1
1K
R4Res1
VCC3.3 1
VCC3.3 2
IO58 3
IO59 4
IO60 5
IO61 6
IO62 7
IO63 8
IO65 9
IO66 10
GND 11
IO67 12
IO68 13
IO69 14
IO70 15
IO71 16
IO72 17
IO73 18
IO74 19
GND 20
IN77 21
GND 22
GND 24
GND 26
GND 28
IN81 23
nSTATUS 25
CONFDONE 27
IO89 29
IO90 30
IO91 31
IO92 32
IO93 33
IO94 34
IO96 35
IO97 36
GND 37
IO98 38
IO99 39
IO100 40
IO101 41
IO102 42
IO103 43
IO104 44
IO106 45
VCC5 46
VCC5 47
VCC5 50
GND 48
CLK1 49
J?
APEX_J3
A0A1A2A3
A4A5A6A7A8A9A10A11
A12A13A14A15A16A17A18
A0A1A2A3A4A5A6A7A8A9A10A11A12A13A14A15A16A17A18
A0A1A2A3A4A5A6A7A8A9A10A11A12A13A14
D0D1D2D3D4D5D6D7
D0D1D2D3D4D5D6D7
D0D1D2D3D4D5D6D7
GND 1
IO34 2
IO37 3
IO38 4
IO40 5
IO41 6
IO42 7
NC5 8
NC6 9
GND 10
IO44 11
IO45 12
IO46 13
IO49 14
IO50 15
IO51 16
NC7 17
NC8 18
GND 19
GND 20
APEX_J5
VCC3.3 1
VCC3.3 2
TDO 3
xTDO 4
TMS 5
TCK 6
TDI 7
xTDI 8
GND 9
GND 10
nWS 11
nRS 12
nCS 13
CS 14
DEVCLRn 15
DCLK 16
CLK2 17
nCE 18
DEVOE 19
LOCK 20
J?
APEX_J10
Top Right of the Adapter Board
Top Left of the Adapter Board
EE52 Digital Oscilloscope Protoboard
1.0
10K
R2Res2
10K
R1Res2
MR1
VCC 2
GND3
PFI4
PFO 5
WDI6
RST 7WDO 8
MAX706SCSA
VCC
S1
SW-PB
VCC
WDI, WDO, and PFO are left floating as allowed by datasheet.
SRAM
ROM
Reset Circuitry
IO61 IO72 IO93 IO134 IO145 IO156 NC17 NC28 GND9 IO1710 IO1811 IO1912 IO2013 IO2114 IO2215 NC316 NC417 nCONFIG18 GND19 GND20J?
APEX_J4
2 15Rx
U2A
145406
143 Tx
U2B
145406
RARY
DY
DA
15Rx4
U1A
145406
143 Tx
U1B
145406
RARY
DY
DA
VCC3.31 VCC3.32 IO2053 IO2044 IO2035 IO2026 IO2017 IO2008 IO1989 IO19710 GND11 IO19612 IO19513 IO19414 IO19315 IO19216 IO19117 IO19018 IO18819 TRST20 nCEO21 IN18422 GND23 IN18124 INITDONE25 RDYnBSY26 CLKUSR27 U5OE228 U5DIR229 IO17530 IO17431 DATA132 IO17133 IO17034 DATA235 IO16736 IO16637 GND38 IO16539 IO16440 DATA341 DATA442 DATA543 DATA044 DATA645 DATA746 U5DIR147 U5OE148 GND49 GND50J?
APEX_J2
IO1591 IO1552 IO1523 IO1514 IO1445 IO1406 IO1397 IO1358 uIO1629 IO13410 IO12311 IO12212 IO12013 IO11714 IO11615 IO11516 IO11317 VCC518 VCC519 VCC520
APEX_J9
100K
R5Res3
1
2
3
4
5
6
7
8
9
J?
D Connector 9
TX 1
RX 1
TX 2
RX 2
R1OUTR2OUT
T1IN
T2IN
DS?
LED1
43 Ohm
R10
A0 17A1 16A2 15A3 14A4 11A5 10A6 9A7 13
RAS 8CAS 18
DT/OE 4WB/WE 7
W/IO05 W/IO16 W/IO219 W/IO320
SO02 SO13 SO222 SO323
SOE21
SC1U?
41264
VR
AM
dat
a bu
s is o
n U
4.1
VR
AM A
ddre
ss B
us o
n U
4.2
Only one VRAM chip is used, so SOE is lowW/IO0W/IO1W/IO2W/IO3
Buf
fer 5
.1 is
Dis
abled
Row 0 SelectRow 1 SelectRow 2 SelectRow 3 Select
Column 0 DataColumn 1 DataColumn 2 DataColumn 3 Data
LCD SenseStart Frame (DI)
YSCL/LP
AC Drive Signal (FR)
XSC
L
ECL
LAT / Y Shift Clock
Display Enable
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18
Display ConnectorHeader 10X2A
D0
D1
D2
D3
VEE (-12V)
VDD (5V)
Julian Panetta
KEYPAD4X4
Keypad debouncing is done in the FPGA
1234
1112131415Keypad Conn1Header 10X2A
1 2 3 4
11 12 13 14 15
Keypad Conn2Header 10X2A
Pull columns low when no key is pressed.
4.6K
R8
4.6K
R7
4.6K
R6
4.6K
R9
Colu
mn
0
Colu
mn
1
Colu
mn
2
Colu
mn
3
Row 0
Row 1
Row 2
Row 3
Buf
fer 5
.2 is
Dis
able
d
VR
AM
Ctl
Lin
es o
n B
uffe
r 9.2
OE/
WE
and
LC
D C
tl L
ines
on
Buff
er 9
.1D
ata
on B
uffe
r 6.1
Add
ress
and
CS
on B
uffe
r 6.2
Add
ress
Lin
es o
n B
uffe
r 7.
1 an
d 7.
2
Key
pad
Col
on
Buf
fer 1
0.2
LED
& K
eypa
d R
ow on
Buf
fer 1
0.1
Seri
al R
X o
n Buf
fer 8
.1Se
rial
TX
on
Buf
fer 8
.2
Apex Board
DB-9
SRAM
ROM
Keypad Conn
Display Connector
VRA
M
Power
Conn. Reset
ResetKey
LED
RS-232
Capacitors
PowerConn.
JTAGPowerJack
Timing Diagrams
o VRAM Timing Specifications Read, Write, Refresh, Data Transfer
o LCD Timing Specifications (1180F, 1190) LCD Signals
o SRAM Read, Write
o Rom Read
Page
2V
RA
M T
imin
g S
pec
ific
atio
ns
DES
CR
IPT
ION
SYM
BO
LM
INM
AX
Col
umn
addr
ess
hold
tim
e af
ter R
AS
low
t AR
80ns
Col
umn
addr
ess
setu
p tim
et A
SC
0ns
Row
add
ress
set
up ti
me
t AS
R0n
s
Acce
ss ti
me
from
CAS
t CA
C60
ns
Col
umn
addr
ess
hold
tim
et C
AH
20ns
CAS
pul
se w
idth
t CA
S60
ns
DT
low
hol
d tim
e af
ter R
AS lo
wt C
DH
40ns
CAS
bef
ore
RAS
refre
sh h
old
time
t CH
R25
ns
CAS
pre
char
ge ti
me
(pag
e cy
cle
only
)t C
P50
ns
CAS
pre
char
ge ti
me
(non
page
cyc
le)
t CP
N25
ns
CAS
hig
h to
RAS
low
pre
char
ge ti
me
t CR
P10
ns
CAS
hol
d tim
et C
SH
120n
s
CAS
bef
ore
RAS
refre
sh s
etup
tim
et C
SR
10ns
CAS
to W
E de
lay
t CW
D10
0ns
Writ
e co
mm
and
to C
AS le
ad ti
me
t CW
L40
ns
Dat
a-in
hol
d tim
et D
H35
ns
DT
high
hol
d tim
et D
HH
20ns
Dat
a-in
hol
d tim
e af
ter R
AS lo
wt D
HR
95ns
DT
high
set
up ti
me
t DH
S0
Page
3V
RA
M T
imin
g S
pec
ific
atio
ns
con
tin
ued
...
DES
CR
IPT
ION
SYM
BO
LM
INM
AX
DT
low
set
up ti
me
t DLS
0
Dat
a-in
set
up ti
me
t DS
0
DT
high
to C
AS h
igh
dela
yt D
TC
10ns
DT
high
hol
d tim
e af
ter R
AS h
igh
t DT
H20
ns
DT
high
to R
AS h
igh
dela
yt D
TR
10ns
OE
pul
se w
idth
t OE
35ns
Acce
ss ti
me
from
OE
t OE
A30
ns
OE
to d
ata-
in s
etup
del
ayt O
ED
35ns
OE
hol
d tim
e af
ter W
E lo
wt O
EH
30ns
OE
to R
AS in
activ
e se
tup
time
t OE
S10
ns
Out
put d
isab
le ti
me
from
OE
hig
ht O
EZ
030
ns
Out
put d
isab
le ti
me
from
CAS
hig
ht O
FF0
30ns
Pag
e cy
cle
time
t PC
120n
s
Acce
ss ti
me
from
RAS
t RA
C12
0ns
Row
add
ress
hol
d tim
et R
AH
15ns
RAS
pul
se w
idth
t RA
S12
0ns
1000
0ns
Ran
dom
read
or w
rite
cycl
e tim
et R
C22
0ns
RAS
to C
AS d
elay
tim
et R
CD
25ns
60ns
Rea
d co
mm
and
hold
tim
e af
ter C
AS
high
t RC
H0
Page
4V
RA
M T
imin
g S
pec
ific
atio
ns
con
tin
ued
...
DES
CR
IPT
ION
SYM
BO
LM
INM
AX
Rea
d co
mm
and
setu
p tim
et R
CS
0
DT
low
hol
d tim
e af
ter R
AS lo
w (s
eria
l po
rt ac
tive)
t RD
H10
0ns
Ref
resh
inte
rval
t RE
F4n
s
RAS
pre
char
ge ti
me
t RP
90ns
RAS
hig
h to
CAS
low
pre
char
ge ti
me
t RP
C0
Rea
d co
mm
and
hold
afte
r RAS
hig
ht R
RH
20ns
RAS
hol
d tim
et R
SH
60ns
Rea
d-w
rite/
read
-mod
ify-w
rite
cycl
e tim
et R
WC
300n
s
RAS
to W
E de
lay
t RW
D16
0ns
to b
e de
fined
t
Writ
e co
mm
and
to R
AS le
ad ti
me
t RW
L40
ns
SC
pul
se w
idth
t SC
H10
ns
Ser
ial o
utpu
t acc
ess
time
from
SC
t SC
A40
ns
Ser
ial c
lock
cyc
le ti
me
t SC
C40
ns50
000n
s
SC
pre
char
ge ti
me
t SC
L10
ns
SC
hig
h to
DT
high
del
ayt S
DD
10ns
SC
low
hol
d tim
e af
ter D
T hi
ght S
DH
10ns
Ser
ial o
utpu
t acc
ess
time
from
SO
Et S
OA
35ns
SO
E p
ulse
wid
tht S
OE
15ns
Page
5V
RA
M T
imin
g S
pec
ific
atio
ns
con
tin
ued
...
DES
CR
IPT
ION
SYM
BO
LM
INM
AX
Ser
ial o
utpu
t hol
d tim
e af
ter S
C h
igh
t SO
H10
ns
SO
E lo
w to
ser
ial o
utpu
t set
up d
elay
t SO
O5n
s
SO
E p
rech
arge
tim
et S
OP
15ns
Ser
ial o
utpu
t dis
able
tim
e fro
m S
OE
high
t SO
Z0
30ns
Ris
e an
d fa
ll tra
nsiti
on ti
me
t T3n
s50
ns
Writ
e-pe
r-bi
t hol
d tim
et W
BH
20ns
Writ
e-pe
r-bi
t set
up ti
me
t WB
S0
Writ
e co
mm
and
hold
tim
et W
CH
35ns
Writ
e co
mm
and
hold
tim
e af
ter R
AS lo
wt W
CR
95ns
Writ
e co
mm
and
setu
p tim
et W
CS
0
Writ
e bi
t sel
ectio
n ho
ld ti
me
t WH
20ns
Writ
e co
mm
and
puls
e w
idth
t WP
35ns
Writ
e bi
t sel
ectio
n se
tup
time
t WS
0
Actu
al R
AS to
CAS
del
ayt R
CD
_Act
ual
100
100
Page
1vr
am_r
ead
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\v
ram
_rea
d.td
ml
0ns
50ns
100n
s15
0ns
200n
s25
0ns
300n
s35
0ns
400n
s45
0ns
500n
s
clk
O20
MH
z
RA
SO
CA
SO
Ad
dre
ss
O[1
5..0
]
WB
/WE
O
DT
/OE
O
Wi/IO
iO
Ro
wC
olu
mn
Re
ad
Da
ta
t CP
N
t CR
P
t AS
Rt R
AH
t AS
Ct C
AH
t RC
S
t DH
St D
HH
t CA
S
t CS
H
t RS
H
t RA
St R
P
t RC
t RR
H
t RC
H
t AR
t OE
t OE
Z
t OF
F
t OE
S
t RC
D_
Ac
tua
l
t RA
C
t CA
C
t OE
A
Page
1vr
am_w
rite
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\v
ram
_writ
e.td
ml
-50n
s0n
s50
ns10
0ns
150n
s20
0ns
250n
s30
0ns
350n
s40
0ns
450n
s
clk
O20
MH
z
RA
SO
CA
SO
Ad
dre
ss
O[1
5..0
]
WB
/WE
O
DT
/OE
O
Wi/IO
iO
Ro
wC
olu
mn
Wri
te M
as
k V
alid
Inp
ut
Da
ta V
alid
t CP
N
t CR
P
t AS
Rt R
AH
t AS
Ct C
AH
t DH
St D
HH
t CA
S
t CS
H
t RS
H
t RA
St R
P
t RC
t AR
t RC
D_
Ac
tua
l
t WB
S
t WH
t WS
t DS
t DH
t DH
R
t WC
St W
BH
t WP
t WC
R
t RW
L
t WC
H
t CW
L
Page
1vr
am_r
efre
sh
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\v
ram
_ref
resh
.tdm
l
0ns
50ns
100n
s15
0ns
200n
s25
0ns
300n
s35
0ns
400n
s45
0ns
500n
s
clk
O20
MH
z
RA
SO
CA
SO
Wi/IO
iO
t RA
S
t RP
t RC
t CS
Rt C
HR
t RP
C
Page
1VR
AM
Dat
a Tr
ansf
er
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trato
r\Des
ktop
\vra
m_d
t.tdm
l~
0ns
50
ns
10
0ns
15
0ns
20
0ns
25
0ns
30
0ns
35
0ns
40
0ns
45
0ns
50
0ns
clk
O20
MH
z
RAS
O
CAS
O
Addr
ess
I[7
..0]
WB /
WE
O
DT/
OE
O
Wi/IO
iO
SC
O3.
3333
33M
Hz
SO
O
Row
Col
umn
Old
Dat
aN
ew D
ata
t CP
N
t CR
P
t AS
Rt R
AH
t AS
Ct C
AH
t DLS
t RD
H
t CA
S
t CS
H
t RS
H
t RA
St R
P
t RC
t AR
t RC
D_A
ctua
l
t CD
H
t SD
D
t DT
R
t DT
C
t DT
H
t SD
H
t SO
H
t SC
A
t SO
H
t SC
A
Page
21
18
0F
SYM
BO
LD
EFIN
ITIO
ND
ESC
RIP
TIO
NM
INM
AX
NO
TES
t CLC
shift
clo
ck c
ycle
166
t WC
LHS
hift
cloc
k "H
" wid
th63
t WC
LLS
hift
cloc
k "L
" wid
th63
t DS
Dat
a se
tup
time
50
t DH
Dat
a ho
ld ti
me
30
t WE
CH
Ena
ble
cloc
k "H
" wid
th10
0
t WE
CL
Ena
ble
cloc
k "L
" wid
th10
0
t ED
SE
nabl
e da
ta s
etup
tim
e50
t ED
HE
nabl
e da
ta h
old
time
20
t ED
RE
nabl
e cl
ock
dela
y tim
e-1
0
t EC
SE
nabl
e cl
ock
setu
p tim
e70
t WLP
HLa
tch
puls
e "H
" wid
th11
0
t WLP
LLa
tch
puls
e "L
" wid
th22
0
t LTLa
tch
timin
g10
0
t LHLa
tch
hold
tim
e0
t LDS
Latc
h pu
lse
data
set
up
time
140
t LDH
Latc
h pu
lse
data
hol
d tim
e50
t DFR
Per
mis
sibl
e fra
me
sign
al
dela
y-5
0050
0
Page
31
18
0F
con
tin
ued
...
SYM
BO
LD
EFIN
ITIO
ND
ESC
RIP
TIO
NM
INM
AX
NO
TES
t PD
Ena
ble
outp
ut d
elay
2015
0
Page
41
19
0
SYM
BO
LD
EFIN
ITIO
ND
ESC
RIP
TIO
NM
INM
AX
NO
TES
t CY
LLa
tch
puls
e cy
cle
time
to b
e de
fined
400
t WLT
HLa
tch
puls
e "H
" wid
thto
be
defin
ed18
0
t WLL
Latc
h pu
lse
"L" w
idth
to b
e de
fined
180
t CY
CS
hift
cloc
k cy
cle
time
to b
e de
fined
400
t WC
LHS
hift
cloc
k "H
" tim
eto
be
defin
ed11
0
t WC
LLS
hift
cloc
k "L
" tim
eto
be
defin
ed24
0
t DS
Dat
a se
tup
time
to b
e de
fined
70
t DH
Dat
a ho
ld ti
me
to b
e de
fined
30
t ST
Dat
a sh
ift ti
min
gto
be
defin
ed0
t ST
HD
ata
shift
hol
d tim
eto
be
defin
ed12
5
t DFR
Per
mis
sibl
e fra
me
sign
al
dela
yto
be
defin
ed-5
0050
0
t pDD
ata
outp
ut d
elay
tim
eto
be
defin
ed30
170
Page
1L
CD
Tim
ing
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\L
CD
_Tim
ing_
Long
.tdm
l
0ns
200n
s40
0ns
600n
s80
0ns
1us
1.2us
clk
O20
MH
z
FR
O
LP
/YS
CL
/LA
TO
EC
LO
XS
CL
O3.
3333
33M
Hz
Da
taI
[3..
0]
DI
O
DT
_N
OW
O
Ne
w fr
am
e d
ata
t EC
St W
EC
H
t CL
C
t DS
t DH
t WC
LH
t WC
LL
t LD
St L
DH
t DF
R
t WL
PH
t ED
R
t LT
t DS
t DH
t WL
TH
t LH
Page
1S
RA
M
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\fr
om_w
indo
ws\
Tim
ing
Dia
gram
s\S
RA
M R
ead.
tdm
l
-50n
s0p
s50
ns10
0ns
150n
s20
0ns
250n
s30
0ns
clk
O20
MH
z
Ad
dre
ss
O[1
5..0
]
CS
O
RD
O
Da
taO
[15.
.0]
da
ta_
req
uir
em
en
t
TO
HT
AA
Page
1S
RA
M W
rite
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\fr
om_w
indo
ws\
Tim
ing
Dia
gram
s\S
RA
M W
rite.
tdm
l
-20n
s0n
s20
ns40
ns60
ns80
ns10
0ns
120n
s
clk
O20
MH
z
Ad
dre
ss
O[1
5..0
]
CS
O
OE
O
WE
O
Da
ta In
O[1
5..0
]
Page
1R
OM
Rea
d
C:\D
ocum
ents
and
Set
tings
\Adm
inis
trat
or\D
eskt
op\fr
om_w
indo
ws\
Tim
ing
Dia
gram
s\R
OM
Rea
d.td
ml
-100
ns0n
s10
0ns
200n
s30
0ns
400n
s50
0ns
clk
O20
MH
z
Ad
dre
ss
O[1
5..0
]
CE
O
WE
O
OE
O
Da
taO
[15.
.0]
t AC
C (1
20
ns
)
Memory Map
Digital Oscilloscope APEX20K Pin Assignments
To Location General Function Special FunctionCLOCK PIN_27 Dedicated Clock CLK1RESET PIN_142 Row I/O nRSU4OE1 PIN_187 Column I/OU4OE2 PIN_206 Column I/OU6OE1 PIN_57 Column I/OU6OE2 PIN_84 Column I/OU6DIR2 PIN_85 Column I/OU7DIR1 PIN_87 Column I/OU7DIR2 PIN_108 Row I/OU7OE1 PIN_88 Column I/OU7OE2 PIN_107 Row I/OU8DIR1 PIN_2 Row I/OU8DIR2 PIN_31 Row I/OU8OE1 PIN_5 Row I/OU8OE2 PIN_30 Row I/OU9DIR1 PIN_32 Row I/OU9DIR2 PIN_55 Column I/OU9OE1 PIN_33 Row I/OU9OE2 PIN_54 Column I/OU10OE1 PIN_112 Row I/OU10OE2 PIN_158 Column I/Oaddr[0] PIN 71 Col mn I/Oaddr[0] PIN_71 Column I/Oaddr[1] PIN_72 Column I/Oaddr[2] PIN_73 Column I/Oaddr[3] PIN_74 Column I/Oaddr[4] PIN_89 Column I/Oaddr[5] PIN_90 Column I/Oaddr[6] PIN_91 Column I/Oaddr[7] PIN_92 Column I/Oaddr[8] PIN_93 Column I/Oaddr[9] PIN_94 Column I/Oaddr[10] PIN_96 Column I/Oaddr[11] PIN_97 Column I/Oaddr[12] PIN_98 Column I/Oaddr[13] PIN_99 Column I/Oaddr[14] PIN_100 Column I/Oaddr[15] PIN_101 Column I/Oaddr[16] PIN_102 Column I/Oaddr[17] PIN_103 Column I/Oaddr[18] PIN_104 Column I/Odata[0] PIN_58 Column I/Odata[1] PIN_59 Column I/Odata[2] PIN_60 Column I/Odata[3] PIN_61 Column I/Odata[4] PIN_62 Column I/Odata[5] PIN_63 Column I/Odata[6] PIN_65 Column I/O
Digital Oscilloscope APEX20K Pin Assignments
data[7] PIN_66 Column I/OnCS_RAM PIN_37 Row I/OnCS_ROM PIN_34 Row I/OnRD PIN_67 Column I/OnWR PIN_68 Column I/OU6DIR1 PIN_56 Column I/OTX1 PIN_17 Row I/ORX2 PIN_7 Row I/Okeypad_rowPIN_120 Row I/Okeypad_rowPIN_122 Row I/Okeypad_rowPIN_123 Row I/Okeypad_rowPIN_134 Row I/Okeypad_col PIN_140 Row I/Okeypad_col PIN_144 Row I/Okeypad_col PIN_151 Row I/Okeypad_col PIN_152 Row I/OU10DIR1 PIN_111 Row I/OU10DIR2 PIN_161 Column I/OSTATUS_LE PIN_117 Row I/OU4DIR1 PIN_179 Column I/OU4DIR2 PIN_207 Column I/Ovaddr[0] PIN_44 Row I/Oaddr[1] PIN 204 Col mn I/Ovaddr[1] PIN_204 Column I/O
vaddr[2] PIN_203 Column I/Ovaddr[3] PIN_202 Column I/Ovaddr[4] PIN_201 Column I/Ovaddr[5] PIN_200 Column I/Ovaddr[6] PIN_198 Column I/Ovaddr[7] PIN_197 Column I/Ovdata[0] PIN_193 Column I/Ovdata[1] PIN_194 Column I/Ovdata[2] PIN_195 Column I/Ovdata[3] PIN_196 Column I/OnRAS PIN_45 Row I/OnCAS PIN_46 Row I/OnDTOE PIN_49 Row I/OnWBWE PIN_50 Row I/OVRAM_SC PIN_51 Row I/ODI PIN_38 Row I/ODisplayEnabPIN_40 Row I/OFR PIN_41 Row I/OLP PIN_113 Row I/OECL PIN_115 Row I/OYSCL PIN_42 Row I/O
Quartus Design • Top Level Design • Analog Control Block • LCD/VRAM Control Block • LCD Signal Generator • Keypad Debouncer • Clock Divider
Date: November , 2008 oscilloscope.bdf Project: oscilloscope
Page 1 of 1 Revision:
Buffer Enables:
Wait Counter Left Floating
Buffer Directions (GND = input, VCC = output)
Enabled: Buffers 4, 6, 7, 8, 9, 10
Variable: Buffer 6.1 (Data bus), 4.1 (VRAM data bus)
The analog input hardware is not constructed,
so take the input to be a constant zero.
IInterrupt line for keypad input
Control line for the status LED.
8.2 (Serial out), 9.1 (OE,WE,LCD Control lines)
RAM and ROM Chip Select Lines
Output: Buffers 6.2 (Address/CS lines), 7 (Address)
4.2 (VRAM address)
Input: Buffers 8.1 (Serial in), 10.2 (Keypad column)
9.2 (VRAM control), 10 (LED, Keypad row)
System Clock (20MHz)
System Clock (20MHz)
System Reset
Input lines for reading undebounced row
of keypress data from the keypad
Serial input data line for NIOS terminal
VRAM Ctl/ Bus, LCD Signal Lines
Drive high to power LCD
Bringing this line high turns on the LED.
8-bit Input from the ADC
Keypad row enable lines
Debounce keypresses (with key repeat),
and interrupt the NIOS when one is debounced.
When requested, sample data from the ADC at a specified sample rate.
Store ADC samples until software
can read and process them.
Generate signals to control the VRAM and
the LCD, and provide an interface between
the Avalon bus and the VRAM's bus.
Debounced key data
VCCRX2 INPUT
VCCRESET INPUT
VCCCLOCK INPUT
VCCkeypad_col[3..0] INPUT
U4OE1OUTPUT
U4OE2OUTPUT
TX1OUTPUT
U6OE1OUTPUT
U6OE2OUTPUT
U7OE1OUTPUT
U7OE2OUTPUT
U8OE1OUTPUT
U8OE2OUTPUT
U9OE1OUTPUT
U9OE2OUTPUT
U8DIR1OUTPUT
U6DIR2OUTPUT
U7DIR1OUTPUT
U7DIR2OUTPUT
U8DIR2OUTPUT
U9DIR1OUTPUT
nCS_ROMOUTPUT
nCS_RAMOUTPUT
nRDOUTPUT
nWROUTPUT
addr[18..0]OUTPUT
U6DIR1OUTPUT
keypad_row[1]OUTPUT
keypad_row[2]OUTPUT
keypad_row[3]OUTPUT
keypad_row[0]OUTPUT
STATUS_LEDOUTPUT
U10OE1OUTPUT
U10OE2OUTPUT
U10DIR2OUTPUT
U10DIR1OUTPUT
vaddr[7..0]OUTPUT
nCASOUTPUT
nRASOUTPUT
nWBWEOUTPUT
nDTOEOUTPUT
U4DIR1OUTPUT
U4DIR2OUTPUT
VRAM_SCOUTPUT
U9DIR2OUTPUT
ECLOUTPUT
LPOUTPUT
YSCLOUTPUT
FROUTPUT
DIOUTPUT
DisplayEnableOUTPUT
VCCdata[7..0]BIDIR
VCCvdata[3..0]BIDIR
GND
VCC
GND
clk
col[3..0]
row0
row1
row2
row3
key_data[5..0]
key_ready
key_debouncer
inst13
08
lpm_constant7
inst6
clk
reset_n
in_port_to_the_analog_fifo_data_in_pio[7..0]
in_port_to_the_analog_fifo_empty_pio
in_port_to_the_analog_fifo_full_pio
in_port_to_the_key_ready_pio
in_port_to_the_keydata_pio[5..0]
WaitRequest_from_the_vram_0
rxd_to_the_uart_0
out_port_from_the_LED_pio
out_port_from_the_analog_control_reset_pio
out_port_from_the_analog_control_settings_data_pio[15..0]
out_port_from_the_analog_control_settings_selector_pio[2..0]
out_port_from_the_analog_fifo_read_req_pio
nCS_to_the_ram_0
nCS_to_the_rom_0
nCS_to_the_vram_0
nRS_to_the_vram_0
rom_0_ROMAm29F040B_wait_counter_eq_1
tri_state_bridge_0_address[18..0]
tri_state_bridge_0_readn
tri_state_bridge_0_writen
txd_from_the_uart_0
tri_state_bridge_0_data[7..0]
NIOS
inst
8 bits x 16 words
data[7..0]
wrreq
rdreq
clock
sclr
q[7..0]
full
empty
lpm_fifo0
inst15
ADDR[18..0]
nWR
nRD
nCS
nRS
clk
vdata[3..0]
vaddr[7..0]
nCAS
nRAS
nWBWE
nDTOE
DisplayEnable
XSCL
ECL
YSCL
LP
DI
FR
WaitReq
DATA
LCD_VRAM_Block
inst8
CLK
SETTING_DATA[15..0]
SETTING_SELECTOR[2..0]
ADC_DATA[7..0]
ANALOG_RESET
SAMPLE_CLK
SAMPLE_REQ
SAMPLE_DATA[7..0]
analog
inst16
Date: November , 2008 analog.bdf Project: oscilloscope
Page 1 of 1 Revision:
b = signal level
a = trigger level
has_trigger
in the low 16 bits of the clock divider input
Put the sample rate clock divider value
(Must be on the same clock as the trigger, not the sample clock!)
Only reset trigger delay counter on
first trigger event since reset
Stop sampling after 640 samples are taken
until a reset occurs (regardless of new trigger events)
Sample 640 samples
Delay until the specified number of
sample clocks have passed.
Trigger sets has_trigger until it is cleared by ANALOG_RESET
system clock. It must therefore be multiplied by 2.
period, not the 50ns period of our 20MHz
Sample rate input is a multiplier of a 100ns
Glen George's trigger
state machine. Triggers
Latch in sample rate.
Latch in trigger delay.
Texas Instrument's TLC5510 ADC
returns 255 for the lowest voltage and
agb <==> signal < trigger
aeb <==> signal == trigger
Latch in trigger delay.
Latch in trigger level.
Trigger level is 7-bit, while the ADC output is 8-bit. Multiply
level by 2 to distribute levels
evenly throughout 8-bit domain
Only the low 7 bits are needed for trigger level/slope
on a specified slope event.
zero <==> + slope
nonzero <==> - slope
Latch in trigger slope
2: Set trigger delay
3: Set trigger level
4: Set trigger slope
1: Set sample rate
Analog Control Block
0 for the highest; so input must be inverted.
Samples data from the ADC at a specified rate after a set delay
following a trigger event (defined by a configurable level and slope)
System clock (20MHz)
Value to be used for the selected setting.
Index of the setting to be altered
Incoming data from the ADC
Signal to reset the triggering mechanism
and all the counters use for delay/sampling.
('1' == Reset, '0' == Don't Reset)
The settings are altered by first selecting the desired setting by placing
a 3-bit identifier on the selector line:
1 == Sample rate, 2 == Trigger delay, 3 == Trigger level, 4 == Trigger slope
Then the value for that setting is placed on the SETTING_DATA line.
Once the setting is made, the setting can be deselected by writing the identifier 0
Create a sample clock based on the selected
sampling rate.
or by selecting another setting to change.
This control block interacts with the FIFO, storing sample data on SAMPLE_CLK's rising edge by
requesting that the FIFO latch in data from the SAMPlE_DATA output using its SAMPLE_REQ line.
VCCSETTING_DATA[15..0] INPUT
VCCADC_DATA[7..0] INPUT
VCCCLK INPUT
VCCANALOG_RESET INPUT
VCCSETTING_SELECTOR[2..0] INPUT
SAMPLE_CLKOUTPUT
SAMPLE_REQOUTPUT
SAMPLE_DATA[7..0]OUTPUT
TS
TEQ
TLT
clk
Reset
TrigEvent
scoptrig_explicit
inst
8 8
lpm_inv0
inst4
DFFdata[7..0]
clock
enableq[7..0]
lpm_dff2
inst5
DFFdata[15..0]
clock
enableq[15..0]
lpm_dff3
inst7
LOGICAL left shift
data[7..0]
distance
result[7..0]lpm_clshift1
inst8
LOGICAL left shift
data[15..0]
distance
result[15..0]lpm_clshift2
inst10
a[15..0] low[7..0]
high[7..0]
split
inst11
compare
datab[]=0
dataa[7..0]aneb
lpm_compare7
inst12
DFFdata
clock
enableq
lpm_dff4
inst14
1
lpm_constant3
inst15
1
lpm_constant3
inst16
clk_in
scale_factor[31..0]
clk_out
clock_divider
inst17
unsigned compare
dataa[7..0]
datab[7..0]
aeb
agb
lpm_compare8
inst18
1
lpm_constant3
inst22
compare
dataa[15..0]
datab[15..0]aeb
lpm_compare10
inst25
a[15..0]
b[15..0]
c[31..0]
combine_16_16
inst28
016
lpm_constant5
inst29
DFFdata[15..0]
clock
enableq[15..0]
lpm_dff3
inst6
unsigned compare
dataa[15..0]
datab[15..0]
aeb
ageb
alb
lpm_compare9
inst20
AN
D2
inst
3
1
lpm
_con
stan
t6inst
13
NOT
inst30
up counterclock
cnt_en
aclr
q[15..0]
lpm_counter5
inst19
616
lpm_constant4
inst26
up countersclr
clock
cnt_en
aclr
q[15..0]
lpm_counter6
inst24
DFFdata
clock
aclr
q
lpm_dff7
inst9
DFFdata
clock
enable
aclr
q
lpm_dff5
inst21
AND3
inst33
DFFdata[7..0]
clock q[7..0]
lpm_dff6
inst27
NOT
inst2
data[2..0]
eq1
eq2
eq3
eq4
lpm_decode1
inst1
Date: November , 2008 LCD_VRAM_Block.bdf Project: oscilloscope
Page 1 of 1 Revision:
LCD/VRAM Block
State machine implementing VRAM cycles.
Collection of counters that implement pulses to be sent to the LCD
and computes the address of the row the VRAM needs to transfer
into its serial shift register.
Avalon Bus Ctl Line (Wait Request)
VRAM / LCD Rest
VRAM Chip Select
System Clock (20 MHz)
(Display enabled when no reset is occuring)
VRAM Control Lines:
LCD Control Lines:
Implements reads, writes, data transfers, and refreshes
Generates the signals needed to drive the LCD using
for the VRAM using a finite state machine implemented in VHDL.
a block design file with counters and comparators.
VCCnWR INPUT
VCCnRD INPUT
VCCnCS INPUT
VCCclk INPUT
VCCnRS INPUT
VCCADDR[18..0] INPUT
XSCLOUTPUT
ECLOUTPUT
LPOUTPUT
DIOUTPUT
FROUTPUT
nCASOUTPUT
nRASOUTPUT
nWBWEOUTPUT
nDTOEOUTPUT
vdata[3..0]OUTPUT
vaddr[7..0]OUTPUT
YSCLOUTPUT
DisplayEnableOUTPUT
WaitReqOUTPUT
VCCDATABIDIRaddr[18..0]
nWR
nRD
clk
nCS
DT_SOON
DT_NOW
nRS
DT_ROW[7..0]
vaddr[7..0]
nCAS
nRAS
nWBWE
nDTOE
WR
data[7..0]
vdata[3..0]
vram_controller_lut
inst
nRS
clk
XSCL
ECL
DT_SOON
DT_NOW
LP
DI
FR
RADDR[7..0]
lcd_signal_generator
inst1
Date: November , 2008 lcd_signal_generator.bdf Project: oscilloscope
Page 1 of 1 Revision:
Toggle FR on falling
edge of DI
LCD Signal Generator
Generates the timing signals to be sent to the LCD
and the row address used during a VRAM Data Transfer
XSCL has a period of 6 clocks XSCL is high for 3 clocks and
low for 3 clocks.
ECL has a period of 96 clocks
DT has a period of 960 clocks
LP has a period of 1920 clocks
(Occurs once every 16 XSCLs)
(Occurs once every 10 ECLs)
(Occurs once every 20 ECLs)
DI has a period of 192000 clocks
(Occurs once very 100 LPs)
There are 200 rows to transfer to the LCD in total.
Move to the next row each LP (so the inverted LP signal is used as a clock)
ECL is high for clocks 2 to
9 at the start of its period.
design implements.
See the LCD timing diagram for the timings that this
DT_SOON is high from clock 950 in one
period to clock 8 in the next.
To make rows of VRAM correspond to physical rows on the LCD
Transfer rows in the order 0, 100, 1, 101, etc.
Make sure all signals change on system clock edges
and prevent glitching with flip-flops.
DT_NOW is high for clocks
3 to7 at its period beginning
at the start of its period
LP is high from clocks 6 to 13
DI is high for clocks 12 to 17
at the start of its period
Asynchronous clear is used because the clock
Event will never occur upon reset.
(this is a very conservative interval.)
Row
incr
emen
t "cl
ock"
Row increment "clock"
System clock (20MHz)
Must be made active highSignal to clear (reset) components
Inputs:
nRS - Active low reset signal
clk - System clock, assumed to be 20MHz
VCCnRS INPUT
VCCclk INPUT
XSCLOUTPUT
ECLOUTPUT
LPOUTPUT
DIOUTPUT
FROUTPUT
RADDR[7..0]OUTPUT
DT_SOONOUTPUT
DT_NOWOUTPUT
up countermodulus 96sclr
clock q[6..0]
ECLCounter
inst
up countermodulus 960sclr
clock q[9..0]
DTCounter
inst2
up countermodulus 1920sclr
clock q[10..0]
LPCounter
inst3
up countermodulus 192000sclr
clock q[17..0]
DICounter
inst4
NOT
inst6 unsigned compare
datab[]=3
dataa[2..0]alb
XSCLCompare
inst7
AND2
inst10
AND2
inst18
AND2
inst21
NOT
inst36N
OT
inst
37
RowCounter[7..0] ROW_ADDR[7..0]
Row_Decoder
inst1
up countermodulus 200clock
aclr
q[7..0]
RowCounter
inst5
AND2
inst22
OR2
inst23
up countermodulus 6sclr
clock q[2..0]
XSCLCounter
inst12
unsigned compare
datab[]=2
dataa[6..0]ageb
ECLCompareLow
inst31
unsigned compare
datab[]=10
dataa[6..0]alb
ECLCompareHigh
inst32
unsigned compare
datab[]=950
dataa[9..0]ageb
SOONCompareLow
inst33
unsigned compare
datab[]=8
dataa[9..0]alb
SOONCompareHigh
inst35
unsigned compare
datab[]=5
dataa[9..0]ageb
NOWCompareLow
inst41
unsigned compare
datab[]=8
dataa[9..0]alb
NOWCompareHigh
inst42
unsigned compare
datab[]=6
dataa[10..0]ageb
LPCompareLow
inst43
unsigned compare
datab[]=14
dataa[10..0]alb
LPCompareHigh
inst44
unsigned compare
datab[]=12
dataa[17..0]ageb
DICompareLow
inst45
unsigned compare
datab[]=18
dataa[17..0]alb
DICompareHigh
inst46
DFFdata
clock q
LCDSignalFlipFlop
inst47
DFFdata
clock q
LCDSignalFlipFlop
inst48
DFFdata
clock q
LCDSignalFlipFlop
inst49
DFFdata
clock q
LCDSignalFlipFlop
inst50
DFFdata
clock q
LCDSignalFlipFlop
inst51
DFFdata
clock q
LCDSignalFlipFlop
inst52
DFFdata
clock q
LCDSignalFlipFlop
inst53
TFFclock
aclr
q
FRToggle
inst54
DFFdata[7..0]
clock q[7..0]
RowAddressFlipFlop
inst55
Date: November , 2008 key_debouncer.bdf Project: oscilloscope
Page 1 of 1 Revision:
Poll the current keypad row
once each millisecond.
notDebouncing: row multiplexing counter increments only when we are not debouncing
(when there is no kepress read from the current row)
debounce_counter only counts when we are debouncing a
key (when the row data read is not zero). The counter resets
every time a value is read that differs from the last read.
Key is debounced after 20ms have passed without
the row nibble changing. Key will repeat after being
held for 300ms, since the counter reduces(mod 300)
Divide clock by 20000 so that
it cycles every 1 ms
Detect changes in the row nibble,
which will reset the debouncing counter
The the 6-bit key output, key_data[5..0], is encoded as follows:
Bits 5 - 4 -- the index of the row from which the presses were read
Bits 0 - 3 -- nibble representing the pressed keys in the row (1 = pressed)
This design file implements a keypad debouncer.
The implementation debounces a keypress for 20ms
and repeats a key every subsequent 300ms if the
user continues to hold it.
The debouncer supports multiple keypresses
on a single row, but does not respond to
simultaneous kepresses occuring on different
rows. In this case, the first row with a keypress
encountered during row multiplexing is the only
one from which keypresses are debounced.
Row select lines
Select keypad row corresponding to given 2-bit address
Are any keys being held?
When a key is debounced, key_ready will pulse
high for 1ms, and the encoded presses can be
read from key_data[6..0].
This debouncer assumes that the clock runs
at 20MHz. If it doesn't, the debounce and key
repeat times will differ from the stated values.
Prevent key_ready from glitching when it
changes due to combinational logic since it
needs to be used as an interrupt line.
VCCclk INPUT
VCCcol[3..0] INPUT
row0OUTPUT
row1OUTPUT
row2OUTPUT
row3OUTPUT
key_readyOUTPUT
key_data[5..0]OUTPUT
data[1..0]
eq0
eq1
eq2
eq3
lpm_decode0
inst
up counterclock
cnt_enq[1..0]
lpm_counter1
inst7
DFFdata[3..0]
clock q[3..0]
lpm_dff0
inst10
compare
dataa[3..0]
datab[3..0]aneb
lpm_compare1
inst1
compare
datab[]=0
dataa[3..0]aeb
lpm_compare2
inst5
NOT
inst11
a[1..0]
b[3..0]
c[5..0]
combine
inst3
DFFdata
clock q
lpm_dff1
inst8
2000032
lpm_constant1
inst4
up countermodulus 300sclr
clock
cnt_en
q[8..0]
lpm_counter3
inst6
compare
datab[]=20
dataa[8..0]aeb
lpm_compare3
inst12
NOT
inst13
clk_in
scale_factor[31..0]
clk_out
clock_divider
inst2
Date: November , 2008 clock_divider.bdf Project: oscilloscope
Page 1 of 1 Revision:
Divide scale_factor by two to determine the number
many counts it should be low.
of counts the divided clock should be high, and how
Clock Divider
Divides clk_in by scale_factor, generating a new clock on clk_out.
counts, so that an entire output clock cycle
occurs in scale_factor counts.
values, so we count up to (scale_factor / 2) - 1
We want (scale_factor / 2) distinct counter
Make counter reduce mod (scale_factor / 2) - 1
Toggle clock output every (scale_factor / 2)
integer). A scale_factor of 1 is not allowed, as it will cause an
overflow in the computation of (scale_factor / 2) - 1.
occur in (scale_factor - 1) ticks (rounds down to nearest even
Known issues: if scale_factor is odd, the divided clock cycle will
VCCclk_in INPUT
VCCscale_factor[31..0] INPUT
clk_outOUTPUT
TFFdata
clock q
lpm_tff0
inst51
lpm_constant0
inst3LOGICAL right shift
data[31..0]
distance
result[31..0]lpm_clshift0
inst2
1
A
B
A-B
dataa[31..0]
result[31..0]
lpm_add_sub0
inst6
up countersclr
clockq[31..0]
lpm_counter4
inst unsigned compare
dataa[31..0]
datab[31..0]ageb
lpm_compare5
inst4
VHDL
• VRAM Controller State Machine o State machine diagram o vram_controller_lut.vhd
• Miscellaneous Helper Blocks o split.vhd o combine.vhd o combine_16_16.vhd
READ_ONEAssert Row AddrnDT HighnCAS highnWE High
IDLEWR High
READ_TWOnRAS low
READ_THREEAssert Col Addr
READ_FOURnCAS lownOE low
READ_FIVETransfer DataWR low
READ_SIXnRAS highnCAS highnOE highWR high
nRD low,
DT_SOO
N low
VRAM Read Cycle
WRITE_ONEAssert Row AddrAssert Write MasknCAS highnWB lownDT high
WRITE_TWOnRAS low
WRITE_THREEAssert Input DataAssert Col Addr
WRITE_FOURnCAS low
WRITE_FIVEWAIT
WRITE_SIXnRAS highnCAS highnWB highWR low
VRAM Write Cycle
nWR
low,
DT_S
OON
low
REFRESH_ONEnCAS low
REFRESH_TWOnRAS low
REFRESH_THREEnCAS high
REFRESH_FOURWAIT
REFRESH_FIVEnRAS high
VRAM Refresh Cycle
DT_SOON lownCS high
VRAM Data Transfer Cycle
DT_NOW high
Actions executed upon state entry.
DT ONEAssert Row AddrnDT LownCAS highDT_TWO
nRAS low
DT_THREEAssert Col Addr
DT_FOURnCAS low
DT_FIVEnDT high
DT_SIXnRAS highnCAS high
vram_controller_lut.vhd Page 1
------------------------------------------------------------------------------------ Oscilloscope VRAM Controller---- This VHDL file implements a controller for the NEC uPD41264-12 VRAM chip.-- The controller is implemeted using a state machine whose transitions are-- a function of the input lines. Output signals change upon transition to-- a new state, and their values are looked up in a table indexed by current-- state number.---- The controller uses a wait request line to halt the NIOS cpu until it is-- able to complete a read or write, since a refresh cycle or data transfer-- cycle could delay read/write cycles an amount unpredictable to the Avalon-- Tristate Bus.---- See the state diagram for a visual overview of the state machine.-- Inputs and outputs are enumerated and described in the port section below.---- Revision History:-- 10/23/08 Julian Panetta Initial Revision-- 11/16/08 Julian Panetta Reformatted to fit within 80 chracters wide----------------------------------------------------------------------------------
Library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;
entity vram_controller_lut is port ( -- 16-bit address input (row & column addresses) with 3 disregarded -- most significant bits so it interfaces with 19-bit shared Avalon bus addr : in std_logic_vector(18 downto 0); -- 8-bit data bus (data / writemask nibbles) data : inout std_logic_vector(7 downto 0);
-- Write enable nWR : in std_logic;
-- Output enable nRD : in std_logic;
-- System clock (Assumed to be 20MHz) clk : in std_logic;
-- Chip select nCS : in std_logic;
-- Data transfer needs to occur before a new cycle can be completed. -- ('1' == true, '0' == false) DT_SOON : in std_logic;
-- Data transfer needs to occur NOW -- ('1' == true, '0' == false) DT_NOW : in std_logic;
-- reset state machine to known, IDLE state nRS : in std_logic;
-- Row address to be used for the data transfer cycle. -- (The data transfer column is always 0.) DT_ROW : in std_logic_vector(7 downto 0);
vram_controller_lut.vhd Page 2
-- 4-bit data bus to VRAM vdata : inout std_logic_vector(3 downto 0);
-- 8-bit address bus out to VRAM vaddr : out std_logic_vector(7 downto 0);
-- CAS signal to VRAM nCAS : out std_logic;
-- RAS signal to VRAM nRAS : out std_logic;
-- nWB/nWE signal to VRAM nWBWE : out std_logic;
-- nDT/nOE signal to VRAM nDTOE : out std_logic;
-- Wait request signal for NIOS WR : out std_logic );end vram_controller_lut;
architecture Moore_machine of vram_controller_lut is constant IDLE : integer range 0 to 23 := 0; -- VRAM Read Cycle States constant READ_ONE : integer range 0 to 23 := 1; constant READ_TWO : integer range 0 to 23 := 2; constant READ_THREE : integer range 0 to 23 := 3; constant READ_FOUR : integer range 0 to 23 := 4; constant READ_FIVE : integer range 0 to 23 := 5; constant READ_SIX : integer range 0 to 23 := 6; -- VRAM Write Cycle States constant WRITE_ONE : integer range 0 to 23 := 7; constant WRITE_TWO : integer range 0 to 23 := 8; constant WRITE_THREE : integer range 0 to 23 := 9; constant WRITE_FOUR : integer range 0 to 23 := 10; constant WRITE_FIVE : integer range 0 to 23 := 11; constant WRITE_SIX : integer range 0 to 23 := 12; -- VRAM Refresh Cycle States constant REFRESH_ONE : integer range 0 to 23 := 13; constant REFRESH_TWO : integer range 0 to 23 := 14; constant REFRESH_THREE : integer range 0 to 23 := 15; constant REFRESH_FOUR : integer range 0 to 23 := 16; constant REFRESH_FIVE : integer range 0 to 23 := 17; -- VRAM Data Transfer Cycle States constant DTRAN_ONE : integer range 0 to 23 := 18; constant DTRAN_TWO : integer range 0 to 23 := 19; constant DTRAN_THREE : integer range 0 to 23 := 20; constant DTRAN_FOUR : integer range 0 to 23 := 21; constant DTRAN_FIVE : integer range 0 to 23 := 22; constant DTRAN_SIX : integer range 0 to 23 := 23;
-- LUT for control line ouputs. 0 => nRAS, 1 => nCAS, 2 => nWBWE, 3 => nDTOE, 4 => WR type TABLE is array(0 to 23) of std_logic_vector(4 downto 0); constant OUTPUT_BITS : TABLE := ( -- IDLE control line values "11111",
-- READ_* control line values "11111", "11110", "11110", "10100", "00100", "11111",
vram_controller_lut.vhd Page 3
-- WRITE_* control line values "11011", "11010", "11010", "11000", "11000", "01111",
-- REFRESH_* control line values "11101", "11100", "11100", "11100", "11111",
-- DTRAN_* control line values "10111", "10110", "10110", "10100", "11100", "11111"); signal CurrentState : integer range 0 to 23; -- current state signal NextState : integer range 0 to 23; -- next statebegin -- Compute the next state (function of current state and inputs) using -- concurrent statements NextState <= -- Transitions to IDLE IDLE when (nRS = '0') else IDLE when (CurrentState = READ_SIX or CurrentState = WRITE_SIX or CurrentState = REFRESH_FIVE or CurrentState = DTRAN_SIX)
-- Idle State transitions else READ_ONE when (CurrentState = IDLE and nRD = '0' and DT_SOON = '0' and nCS = '0') else WRITE_ONE when (CurrentState = IDLE and nWR = '0' and DT_SOON = '0' and nCS = '0') else REFRESH_ONE when (CurrentState = IDLE and nCS = '1' and DT_SOON = '0') else DTRAN_ONE when (CurrentState = IDLE and DT_NOW = '1') else IDLE when (CurrentState = IDLE) -- Movement Within Cycles else CurrentState + 1;
-- Upon transition into the new state, update the contol line values -- using the output lookup table. output_computation : process (CurrentState) begin -- Look up and set control line values for the current state nRAS <= OUTPUT_BITS(CurrentState)(0); nCAS <= OUTPUT_BITS(CurrentState)(1); nWBWE <= OUTPUT_BITS(CurrentState)(2); nDTOE <= OUTPUT_BITS(CurrentState)(3); WR <= OUTPUT_BITS(CurrentState)(4);
-- VRAM address line access -- Assert row address for the first and second read and write states. if (CurrentState = READ_ONE or CurrentState = WRITE_ONE or CurrentState = READ_TWO or CurrentState = WRITE_TWO) then vaddr <= addr(15 downto 8); else -- Assert col address for the third/fourth read and write states. if (CurrentState = READ_THREE or CurrentState = READ_FOUR or CurrentState = WRITE_THREE or CurrentState = WRITE_FOUR) then vaddr <= addr(7 downto 0); else -- Assert DT row address for the first and second DT states. if (CurrentState = DTRAN_ONE or CurrentState = DTRAN_TWO) then vaddr <= DT_ROW; else -- Output zero addess in all other states. vaddr <= "00000000"; end if; end if; end if;
vram_controller_lut.vhd Page 4
-- VRAM data bus access -- Transfer VRAM data to Avalon Bus for the fifth read state. if (CurrentState = READ_FIVE) then data <= "0000" & vdata; else -- Assert write mask for the first and second write state. if (CurrentState = WRITE_ONE or CurrentState = WRITE_TWO) then vdata <= data(7 downto 4); else -- Assert graphics nibble for the third and fourth write state. if (CurrentState = WRITE_THREE or CurrentState = WRITE_FOUR) then vdata <= data(3 downto 0); else -- In all other states, the Avalon data bus and the VRAM -- data bus should be high impedance. vdata <= "ZZZZ"; data <= "ZZZZZZZZ"; end if; end if; end if;
end process output_computation; -- Make actual transition to the new state on rising clock edge make_transition : process (clk) begin if clk = '1' then -- Only change on the rising clock edge CurrentState <= NextState; -- Transition to the new state end if; end process;
end Moore_machine;
Date: November , 2008 split.vhd Project: oscilloscope
Page 1 of 1 Revision:
---------------------------------------------------------------------------------- Split---- Splits the 16-bit input bits read from port a evenly into the 8 LSBs (placed-- on "low" ouptut line) and the 8 MSBs (placed on "high" output line).---- Revision History:-- 09/05/08 Julian Panetta Initial Revision------------------------------------------------------------------------------Library ieee;use ieee.std_logic_1164.all;
entity split isport (
a : in std_logic_vector(15 downto 0);low : out std_logic_vector(7 downto 0);high : out std_logic_vector(7 downto 0)
);end split;
architecture dataflow of split isbegin
low <= a(7 downto 0);high <= a(15 downto 8);
end dataflow;
Date: November , 2008 combine.vhd Project: oscilloscope
Page 1 of 1 Revision:
---------------------------------------------------------------------------------- Combine---- (For use with computing debounced keypress output)-- Concatenates 2-bit row address read from port a with 4-bit column data read-- from port b into a 6-bit output placed on port c. The row address is placed-- in the MSBs of the output and the column address is placed in the LSBs.--------------------------------------------------------------------------------Library ieee;use ieee.std_logic_1164.all;
entity combine isport (
a : in std_logic_vector(1 downto 0);b : in std_logic_vector(3 downto 0);c : out std_logic_vector(5 downto 0)
);end combine;
architecture dataflow of combine isbegin
c <= a & b;end dataflow;
Date: November , 2008 combine_16_16.vhd Project: oscilloscope
Page 1 of 1 Revision:
--------------------------------------------------------------------------------- Combine 16_16---- Concatenates two 16-bit inputs (read from ports a and b) into a 32-bit-- output value placed on port c. the value of port a is placed in the most-- significant bits of c, and b's value is placed in the least significant-- bits. ---- Revision History:-- 09/05/08 Julian Panetta Initial Revision-----------------------------------------------------------------------------Library ieee;use ieee.std_logic_1164.all;
entity combine_16_16 isport (
a : in std_logic_vector(15 downto 0);b : in std_logic_vector(15 downto 0);c : out std_logic_vector(31 downto 0)
);end combine_16_16;
architecture dataflow of combine_16_16 isbegin
c <= a & b;end dataflow;
Software • Drivers/Initialization (NIOS Assembly)
o start.s Initializes hardware and calls oscilloscope operating system main
loop. Global symbols: _start
o keypad.s Interrupt-driven driver for the keypad Global symbols: install_key_handler, getkey, key_available
o display.s Code for drawing on and clearing the LCD Global symbols: plot_pixel, clear_display
o interrupts.s Code for initializing interrupts Global symbols: init_interrupts
o constants.s Include file holding constants used throughout the NIOS assembly
files listed above. • OS (C)
o stubfuncs.c Functions emulating hardware not yet implemented Global symbols: set_sample_rate, set_trigger, set_delay,
start_sample, sample_done o interfac.h
Include file holding constants used throughout the oscilloscope operating system.
start.s Page 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; File: start.s; Description:; Code run when the NIOS resets. Performs hardware initialization and then; branches to Glen George's oscilloscope code.;; Input: Keypresses from the user, analog signal input (not implemented); Output: Output displayed ;; Known Bugs: None; Revision History:; 11/04/08 Julian Panetta Initial Revision; 11/17/08 Julian Panetta Added more extensive documentation;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.include "excalibur.s".include "constants.s"
.text
.global _start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void _start(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Code located at the NIOS' reset location. Initializes hardware and then; runs the oscilloscope OS.; Operation:; - Installs the keypad handler, initialize_interrupts, and forces interrupts; to be enabled.; - Turns on the status LED.; - Branches to the oscilloscope's main loop from which the NIOs should never; return.;; Arguments: None; Return Values: None;; Inputs: Keypresses read from keypad; Outputs: User interface displayed on LCD;; Registers Destroyed: None (Registers SAVED, no supervisor/caller anyway).; Shared Variables: None;; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_start: SAVE %sp, 0 ; No stack space is needed
_BSR install_key_handler NOP _BSR init_interrupts NOP
; Turn on interrupts ; According to the NIOS Programmer's Manual, interrupts should be enabled ; by default and need only be enabled if explicitly disabled previously. ; However, I have found the interrupts don't function if they aren't ; enabled as done by the following two lines. These lines were copied ; verbatim from the Programmer's Manual. PFX 9 WRCTL %g0
; Turn on the LED to indicate the system has booted MOVI %l1, LED_ON
start.s Page 2
MOVIA %l0, na_LED_pio PFX np_piodata ST [%l0], %l1 _BSR main ; Run Glen's oscilloscope code NOP
; This line should never be reached. RESTRET
keypad.s Page 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; File: keypad.s; Description:; Routines to allow Glen George's oscilloscope software interface with; the debounced keypad.; Input: Debounced keypresses from the user (ISR run when keypress made).; Output: None.;; Known Bugs: None; Revision History:; 09/06/08 Julian Panetta Initial Revision; 11/17/08 Julian Panetta Added documentation and replaced; magic numbers with constants.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.include "excalibur.s".include "constants.s"
.datakey_ready: .4byte falsekey_data: .4byte KEY_ILLEGAL
.text
.global install_key_handler
.global getkey
.global key_available
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void install_key_handler(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Installs and initializes the isr that is run when a key is debounced.; Operation:; - Intalls ISR.; - Clears key_ready and key_data variables.; - Clears edge capture register so previous keypresses aren't detected.
; Arguments: None; Return Values: None;; Outputs: None; Registers Destroyed: None (Registers SAVED/RESTORED);; Shared Variables:; key_ready -- (Cleared) Boolean value recording the occurance of a keypress; key_data -- (Cleared) Byte recording the value of the keypress;; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;install_key_handler: SAVE %sp, 0 ; no stack space is needed
MOVIA %o0, na_key_ready_pio_irq ; select key_ready interrupt MOVIA %o1, key_handler@h ; load ISR address MOVIA %o2, 0 ; context (ignored)
BSR nr_installuserisr ; install our keypad isr NOP ; Initialize key_ready and key_data words to zero MOVIA %l2, false
MOVIA %l1, key_ready ST [%l1], %l2 ; No key is ready initially
keypad.s Page 2
MOVIA %l2, KEY_ILLEGAL ; (Not needed as false == KEY_ILLEGAL) MOVIA %l1, key_data ; No valid key is encoded initially ST [%l1], %l2
; Clear the edge capture register to ensure a keypress made ; before loading the code doesn't result in an interrupt. MOVIA %l1, na_key_ready_pio MOVI %l0, false PFX np_pioedgecapture ST [%l1], %l0
RESTRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void key_handler(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; ISR that is run when a key is pressed. Simply records the presence of a key; and resets the interrupt event.; Operation:; - Clears the edge capture register so the event doesn't fire until a new; keypress is made.; - Sets key_ready and stores debounced key data in key_data.;; Arguments: None; Return Values: None;; Inputs: Keys pressed by the user trigger this handler; Outputs: None;; Registers Destroyed: None (Registers SAVED/RESTORED); Shared Variables:; key_ready -- (Set) Boolean value recording the occurance of a keypress; key_data -- (Stored) Byte recording the value of the keypress;; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;key_handler: SAVE %sp, 0 ; no stack space is needed ; clear the edge capture register MOVIA %l1, na_key_ready_pio MOVI %l0, 0 PFX np_pioedgecapture ST [%l1], %l0
MOVIA %l0, key_ready MOVI %r0, true ST8S [%l0], %r0, 0 ; Indicate a debounced key was received MOVIA %l0, na_keydata_pio PFX np_piodata LD %l1, [%l0]
MOVIA %l0, key_data ST [%l0], %l1
RESTORE TRET %o7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; unsigned char key_available(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Returns 0x01 if a key press is ready for reading and 0x00 if not.
keypad.s Page 3
; Operation:; - Reads key_ready and extracts bit 1 as the return value.;; Arguments: None; Return Values: None;; Inputs: None; Outputs: None;; Registers Destroyed: None (Registers SAVED/RESTORED); Shared Variables:; key_ready -- (Read) Boolean value recording the occurance of a keypress;; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;key_available: SAVE %sp, 0 ; No stack space is needed MOVIA %o1, key_ready LD %o0, [%o1] MOVI %o1, true
AND %o0, %o1 ; Check if a keypress is ready RESTRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; int getkey(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Waits until a valid keypress is made (if one hasn't been already) and then; returns that keypress' code.; Operation:; - Waits until a a keypress has been made.; - Performs a lookup to see if that key is valid.; - Returns the key if it is valid, otherwise waits for another keypress.;; Arguments: None; Return Values: None;; Inputs: Valid keys pressed by the user are returned by this routine.; Outputs: None;; Registers Destroyed: None (Registers SAVED/RESTORED); Shared Variables: None; key_ready -- (Read) Boolean value recording the occurance of a keypress; key_data -- (Read) Byte recording the value of the keypress;; Data Structures/Algorithms: Look up table is used to validate keypresses;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;getkey: SAVE %sp, 0 ; no stack space is needed
MOVIA %l0, key_ready MOVIA %l3, key_data MOVI %l2, truewait: LD %l1, [%l0] AND %l1, %l2 ; Check key is ready
IFS cc_z BR wait ; wait until a key is ready NOP
MOVI %l1, false ST [%l0], %l1 ; clear key_ready
keypad.s Page 4
LD %i0, [%l3] ; get key_data EXT8D %i0, %l1 ; put key_data in low byte of return value
MOVIA %l4, valid_keysvalidate_loop: LD %l5, [%l4]
CMP %i0, %l5 IFS cc_eq ; valid key? BR valid ; return it. NOP
CMPI %l5, KEY_ILLEGAL IFS cc_eq ; invalid key? BR wait ; wait for a valid one. NOP BR validate_loop ; not sure yet! ADDI %l4, 1 ; move to the next key entry
valid: RESTRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; valid_keys:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Constant table of valid keypress values terminated by KEY_ILLEGAL.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;valid_keys: .word KEY_UP .word KEY_DOWN .word KEY_LEFT .word KEY_RIGHT .word KEY_MENU .word KEY_ILLEGAL ; KEY_ILLEGAL Terminates the list of valid keys
display.s Page 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; File: display.s; Description:; Routines to set individual pixels on the LCD and clear the entire LCD.; Input: None.; Output: Pixels displayed on LCD.;; Known Bugs: None; Revision History:; 11/04/08 Julian Panetta Initial Revision;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.include "excalibur.s".include "constants.s"
.text
.global plot_pixel
.global clear_display
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void plot_pixel(unsigned int x, unsigned int y, int p);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Sets the pixel at the passed (x, y) to the value p.; The origin of the screen coordinate system is the upper left corner. ; Operation:; - Computes the VRAM address of the nibble holding the desired pixel.; - Adds this offset to the VRAM base address to compute the absolute address.; - Creates a bit mask for the VRAM write so that only the desired pixel of; the nibble is modified.; - Sets the write data to all 1's for p == PIXEL_BLACK and all 0's for; p == PIXEL_WHITE. This ensures the selected pixel is set to the correct; value, regardless of which of the four pixels it is.; - Sends these computed write mask and data nibbles to the VRAM;; Arguments (After execution of SAVE):; %i0 = x coordinate of desired pixel; %i1 = y coordinate of desired pixel; %i2 = p = color to paint specified pixel;; Return Values: None;; Outputs: Pixel at (x, y) painted with color p.; (Corresponding bit in VRAM is set) ;; Registers Destroyed: None (Registers SAVED/RESTORED); Stack depth: 0;; Shared Variables: None;; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;plot_pixel: SAVE %sp, 0 ; no stack space is required
; Load VRAM base address MOVIA %l0, na_vram_0
; Compute offset from VRAM base address: ; Offset = (VRAM_row << 8) + VRAM_column ; = (y << 8) + (x >> 2)
LSLI %i1, 8 ; move y coordinate into the row portion of offset ADD %l0, %i1
display.s Page 2
MOV %l1, %i0 ; Get a copy of the x coordinate LSRI %l1, 2 ; get the nibble in which the pixel appears ADD %l0, %l1 ; Add in the column portion of the nibble offset
MOVI %l2, 3 AND %i0, %l2 ; get the x offset within that nibble
BGEN %l1, 7 ; set the leftmost pixel enable bit LSR %l1, %i0 ; shift the pixel enable bit into the 'x' location ; within the write mask
; If the color, p, is PIXEL_WHITE, set all the bits in the graphics nibble ; to '0' (to clear the pixel). Otherwise, set all the bits in the graphics ; nibble to '1' (blacken the pixel). Assuming the PIXEL_WHITE value is 0 ; and the PIXEL_BLACK value is 0x0F, p can simbly be ORed into the data ; byte. OR %l1, %i2
FILL8 %r0, %l1 ; Fill all bytes of this word with the computed ; graphics byte so ST8D will read it in all cases
ST8D [%l0], %r0
RESTRET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void clear_display(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Sets all the LCD pixels to white.; Operation:; Iterates over the portions of VRAM mapped to pixels on the LCD, and paints; them all white 16 pixels (4 nibbles) at a time.;; Arguments: None; Return Values: None
; Outputs: All pixels on the LCD are painted white.; (All bits in VRAM that are displayed on the LCD are set to '0');; Registers Destroyed: None; Stack depth: 0; Shared Variables: None; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;clear_display: SAVE %sp, 0 ; no stack space is required
; Load VRAM base address MOVIA %l0, na_vram_0 MOVIA %l3, CLEAR_PATTERN ; Load pattern to clear 4 graphics nibbles
MOVIA %l1, SIZE_Y ; loop over all LCD rows MOVIA %l4, ROW_ADVANCE ; Ammount added to address to advance rowrow_loop: MOVIA %l2, LCD_NIBBLES_WIDE ; loop over all the nibbles in the row col_loop: ST [%l0], %l3 ; Clear 4 nibbles (16 pixels) of the LCD
SUBI %l2, NIBBLES_PER_WRITE ; Subtract nibbles cleared from remaining IFS cc_nz BR col_loop ; Continue until there are none remaining
display.s Page 3
ADDI %l0, COLUMN_ADVANCE ; Move to the next set of 4 nibbles
SUBI %l1, ROWS_PER_LOOP ; Subtract rows cleared from rows remaining IFS cc_nz BR row_loop ; Continue until there are no rows remaining ADD %l0, %l4 ; Advance to the start of the next row
RESTRET
interrupts.s Page 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; File: interrupts.s; Description:; Routine to enable interrupts for the NIOS CPU.; The only interrupts acknowledged are from the keypad, so; only the na_key_ready_pio's interrupt need be enabled.; Input: None.; Output: None.;; Known Bugs: None;; Revision History:; 09/06/08 Julian Panetta Initial Revision;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.include "excalibur.s"
.text
.global init_interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; void init_interrupts(void);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Description:; Enables all the interrupts to be acknowledged by the NIOS.; This should only be called AFTER the ISRs to handle these interrupts have; already been installed.; Operation:; - Sets the key_ready pio's interrupt mask bit to '1' so that the debounced; key bit line can interrupt the NIOS' operation.;; Arguments: None; Return Values: None; Outputs: None; Registers Destroyed: None (Registers SAVED/RESTORED); Stack depth: 0; Shared Variables: None; Data Structures/Algorithms: None;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;init_interrupts: SAVE %sp, 0 ; No stack space is needed
MOVIA %l0, na_key_ready_pio MOVI %l1, 1 STP [%l0, np_piointerruptmask], %l1
RESTRET
constants.s Page 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; File: constants.s; Description:; Defines constants used by the keypad and display hardware drivers.; Also defines global software constants and constants related to the status; LED.;; Revision History:; 11/17/08 Julian Panetta Initial Revision;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Global Constants;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.equ true, 1 ; Boolean true value.equ false, 0 ; Boolean false value
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Status LED Constants;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.equ LED_ON, 1 ; Value to write to LED PIO to turn on Status LED.equ LED_OFF, 0 ; Value to write to LED PIO to turn off Status LED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Display Constants;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.equ PIXEL_BLACK, 0X0F ; Pixel color passed to draw black pixels..equ PIXEL_WHITE, 0X00 ; Pixel color passed to draw white pixels..equ CLEAR_PATTERN, 0xF0F0F0F0 ; Word value that will clear 16 bits of VRAM
; VRAM/LCD Properties.equ SIZE_X, 640 ; X resolution of the LCD.equ SIZE_Y, 200 ; Y resolution of the LCD.equ LCD_NIBBLES_WIDE, (SIZE_X / 4); Number of nibbles in VRAM per LCD row.equ VRAM_WIDTH, 256 ; Number of nibbles in VRAM per VRAM row
; Constants used for clearing the LCD efficiently.equ NIBBLES_PER_WRITE, 4 ; Number of nibbles cleared per write.equ COLUMN_ADVANCE, NIBBLES_PER_WRITE ; Number of nibbles to skip over to ; advance to the next column.equ ROWS_PER_LOOP, 1 ; Number of rows cleared per iteration.equ ROW_ADVANCE, (VRAM_WIDTH - LCD_NIBBLES_WIDE) ; Number of nibbles to skip ; to advance to the next row
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Keypad Constants;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;.equ KEY_UP, 0x02 ; <Up>.equ KEY_DOWN, 0x22 ; <Down>.equ KEY_LEFT, 0x11 ; <Left>.equ KEY_RIGHT, 0x14 ; <Right>.equ KEY_MENU, 0x12 ; <Menu>.equ KEY_ILLEGAL, 0x00 ; Illegal Key
stubfncs.c Page 1
/****************************************************************************//* *//* STUBFNCS *//* Oscilloscope Stub Functions *//* Digital Oscilloscope Project *//* EE/CS 52 *//* *//****************************************************************************/
/* This file contains stub functions for the hardware interfacing code for the Digital Oscilloscope project. The file is meant to allow linking of the main code without necessarily having all of the low-level functions or hardware working. The functions included are: key_available - check if a key is available getkey - get a key clear_display - clear the display plot_pixel - plot a pixel set_sample_rate - set the sample rate set_trigger - set the trigger level and slope set_delay - set the trigger delay start_sample - start sampling sample_done - sampling status
The local functions included are: none
The locally global variable definitions included are: none
Revision History 3/8/94 Glen George Initial revision. 3/13/94 Glen George Updated comments. 3/13/94 Glen George Changed set_sample_rate to return SIZE_X. 5/9/06 Glen George Updated start_sample stub to match the new specification. 11/4/08 Julian Panetta Altered stub functions to implement test analog sample. Also removed stub functions for keypad/display which have real implmeentations.*/
/* library include files */ /* none */
/* local include files */#include "interfac.h"#include "scopedef.h"
/* Variables used to store state of analog hardware simulator */static long int sample_rate;static int sample_level, sample_slope;static long int sample_delay;static int is_sampling;
/* Buffer to store simulated analog input data */static char sample_data[SIZE_X];
/* sampling parameter functions */
int set_sample_rate(long int rate)
stubfncs.c Page 2
{ sample_rate = rate; return SIZE_X;}
void set_trigger(int level, int slope){ sample_level = level; sample_slope = slope; return;}
void set_delay(long int delay){ sample_delay = delay; return;}
/* sampling functions */
void start_sample(int auto_trigger){ get_test_sample(sample_rate, SIZE_X, sample_data); is_sampling = 1;}
unsigned char far *sample_done(){ /* Only return NULL once per sample */ if (!is_sampling) return NULL; else { is_sampling = 0; return sample_data; }}
interfac.h Page 1
/****************************************************************************//* *//* INTERFAC.H *//* Interface Definitions *//* Include File *//* Digital Oscilloscope Project *//* EE/CS 52 *//* *//****************************************************************************/
/* This file contains the constants for interfacing between the C code and the assembly code/hardware for the Digital Oscilloscope project. This is a sample interface file to allow compilation of the .c files.
Revision History: 3/8/94 Glen George Initial revision. 3/13/94 Glen George Updated comments. 3/17/97 Glen George Added constant MAX_SAMPLE_SIZE and removed KEY_UNUSED. 11/04/08 Julian Panetta Updated to match constants of my hardware drivers.*/
#ifndef __INTERFAC_H__ #define __INTERFAC_H__
/* library include files */ /* none */
/* local include files */ /* none */
/* constants */
/* keypad constants */#define KEY_MENU 0x12 /* <Menu> */#define KEY_UP 0x02 /* <Up> */#define KEY_DOWN 0x22 /* <Down> */#define KEY_LEFT 0x11 /* <Left> */#define KEY_RIGHT 0x14 /* <Right> */#define KEY_ILLEGAL 0 /* illegal key */
/* display constants */#define SIZE_X 640 /* size in the x dimension */#define SIZE_Y 200 /* size in the y dimension */#define PIXEL_WHITE 0 /* pixel off */#define PIXEL_BLACK 0xF /* pixel on */
/* scope parameters */#define MIN_DELAY 0 /* minimum trigger delay */#define MAX_DELAY 50000 /* maximum trigger delay */#define MIN_LEVEL 0 /* minimum trigger level (in mV) */#define MAX_LEVEL 5000 /* maximum trigger level (in mV) */
/* sampling parameters */#define MAX_SAMPLE_SIZE 2400 /* maximum size of a sample (in samples) */
#endif