forked from SpinalHDL/VexRiscv
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Keypad.scala
81 lines (64 loc) · 1.68 KB
/
Keypad.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package vexriscv.demo
import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba3.apb._
import spinal.lib.bus.misc._
case class Keypad() extends Bundle with IMasterSlave {
val cols = Bits(4 bits)
val rows = Bits(4 bits)
override def asMaster(): Unit = {
in(rows)
out(cols)
}
}
case class KeypadCtrl() extends Component {
val io = new Bundle {
val keypad = master(Keypad())
val keys = out Bits(16 bits)
}
val cols = Reg(Bits(4 bits)) init B"1110"
io.keypad.cols := cols
val column = Reg(UInt(2 bits)) init 0
val keys = Reg(Bits(16 bits)) init 0
io.keys := keys
for(i <- 0 until 4) {
keys(i*4 + column) := !io.keypad.rows(i)
}
val prescaler = Reg(UInt(12 bits))
prescaler := prescaler + 1
when (prescaler === 1000) {
column := column + 1
cols := cols.rotateLeft(1)
prescaler := 0
}
def driveFrom(busCtrl : BusSlaveFactory, baseAddress : Int = 0) () = new Area {
busCtrl.read(io.keys,baseAddress)
}
}
class KeypadTest extends Component {
val io = new Bundle {
val keypad= master(Keypad())
val leds = out Bits(16 bits)
}
val keypadCtrl = new KeypadCtrl()
keypadCtrl.io.keypad <> io.keypad
io.leds := keypadCtrl.io.keys
}
object KeypadTest {
def main(args: Array[String]): Unit = {
SpinalVerilog(new KeypadTest)
}
}
/*
* Keys -> 0x00 Read register to read the keys
**/
case class Apb3KeypadCtrl() extends Component {
val io = new Bundle {
val apb = slave(Apb3(Apb3Config(addressWidth = 8, dataWidth = 32)))
val keypad = master(Keypad())
}
val busCtrl = Apb3SlaveFactory(io.apb)
val keypadCtrl = KeypadCtrl()
io.keypad <> keypadCtrl.io.keypad
keypadCtrl.driveFrom(busCtrl)()
}