Initial commit.
[sifive-blocks.git] / src / main / scala / devices / spi / SPIBundle.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.spi
3
4 import Chisel._
5
6 abstract class SPIBundle(val c: SPIConfigBase) extends Bundle {
7 override def cloneType: SPIBundle.this.type =
8 this.getClass.getConstructors.head.newInstance(c).asInstanceOf[this.type]
9 }
10
11 class SPIDataIO extends Bundle {
12 val i = Bool(INPUT)
13 val o = Bool(OUTPUT)
14 val oe = Bool(OUTPUT)
15 }
16
17 class SPIPortIO(c: SPIConfigBase) extends SPIBundle(c) {
18 val sck = Bool(OUTPUT)
19 val dq = Vec(4, new SPIDataIO)
20 val cs = Vec(c.csWidth, Bool(OUTPUT))
21 }
22
23 trait HasSPIProtocol {
24 val proto = Bits(width = SPIProtocol.width)
25 }
26 trait HasSPIEndian {
27 val endian = Bits(width = SPIEndian.width)
28 }
29 class SPIFormat(c: SPIConfigBase) extends SPIBundle(c)
30 with HasSPIProtocol
31 with HasSPIEndian {
32 val iodir = Bits(width = SPIDirection.width)
33 }
34
35 trait HasSPILength extends SPIBundle {
36 val len = UInt(width = c.lengthBits)
37 }
38
39 class SPIClocking(c: SPIConfigBase) extends SPIBundle(c) {
40 val div = UInt(width = c.divisorBits)
41 val pol = Bool()
42 val pha = Bool()
43 }
44
45 class SPIChipSelect(c: SPIConfigBase) extends SPIBundle(c) {
46 val id = UInt(width = c.csIdBits)
47 val dflt = Vec(c.csWidth, Bool())
48
49 def toggle(en: Bool): Vec[Bool] = {
50 val mask = en << id
51 val out = Cat(dflt.reverse) ^ mask
52 Vec.tabulate(c.csWidth)(out(_))
53 }
54 }
55
56 trait HasSPICSMode {
57 val mode = Bits(width = SPICSMode.width)
58 }
59
60 class SPIDelay(c: SPIConfigBase) extends SPIBundle(c) {
61 val cssck = UInt(width = c.delayBits)
62 val sckcs = UInt(width = c.delayBits)
63 val intercs = UInt(width = c.delayBits)
64 val interxfr = UInt(width = c.delayBits)
65 }
66
67 class SPIWatermark(c: SPIConfigBase) extends SPIBundle(c) {
68 val tx = UInt(width = c.txDepthBits)
69 val rx = UInt(width = c.rxDepthBits)
70 }
71
72 class SPIControl(c: SPIConfigBase) extends SPIBundle(c) {
73 val fmt = new SPIFormat(c) with HasSPILength
74 val sck = new SPIClocking(c)
75 val cs = new SPIChipSelect(c) with HasSPICSMode
76 val dla = new SPIDelay(c)
77 val wm = new SPIWatermark(c)
78 }
79
80 object SPIControl {
81 def init(c: SPIConfigBase): SPIControl = {
82 val ctrl = Wire(new SPIControl(c))
83 ctrl.fmt.proto := SPIProtocol.Single
84 ctrl.fmt.iodir := SPIDirection.Rx
85 ctrl.fmt.endian := SPIEndian.MSB
86 ctrl.fmt.len := UInt(math.min(c.frameBits, 8))
87 ctrl.sck.div := UInt(3)
88 ctrl.sck.pol := Bool(false)
89 ctrl.sck.pha := Bool(false)
90 ctrl.cs.id := UInt(0)
91 ctrl.cs.dflt.foreach { _ := Bool(true) }
92 ctrl.cs.mode := SPICSMode.Auto
93 ctrl.dla.cssck := UInt(1)
94 ctrl.dla.sckcs := UInt(1)
95 ctrl.dla.intercs := UInt(1)
96 ctrl.dla.interxfr := UInt(0)
97 ctrl.wm.tx := UInt(0)
98 ctrl.wm.rx := UInt(0)
99 ctrl
100 }
101 }
102
103 class SPIInterrupts extends Bundle {
104 val txwm = Bool()
105 val rxwm = Bool()
106 }