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