83e6664b2819c5bdcb4912e87b2c869134fc8002
[sifive-blocks.git] / src / main / scala / devices / spi / SPIPeriphery.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.spi
3
4 import Chisel._
5 import config.Field
6 import diplomacy.{LazyModule,LazyMultiIOModuleImp}
7 import rocketchip.HasSystemNetworks
8 import uncore.tilelink2.{TLFragmenter,TLWidthWidget}
9 import util.HeterogeneousBag
10
11 case object PeripherySPIKey extends Field[Seq[SPIParams]]
12
13 trait HasPeripherySPI extends HasSystemNetworks {
14 val spiParams = p(PeripherySPIKey)
15 val spis = spiParams map { params =>
16 val spi = LazyModule(new TLSPI(peripheryBusBytes, params))
17 spi.rnode := TLFragmenter(peripheryBusBytes, cacheBlockBytes)(peripheryBus.node)
18 intBus.intnode := spi.intnode
19 spi
20 }
21 }
22
23 trait HasPeripherySPIBundle {
24 val spis: HeterogeneousBag[SPIPortIO]
25
26 def SPItoGPIOPins(syncStages: Int = 0): Seq[SPIPinsIO] = spis.map { s =>
27 val pins = Module(new SPIGPIOPort(s.c, syncStages))
28 pins.io.spi <> s
29 pins.io.pins
30 }
31 }
32
33 trait HasPeripherySPIModuleImp extends LazyMultiIOModuleImp with HasPeripherySPIBundle {
34 val outer: HasPeripherySPI
35 val spis = IO(HeterogeneousBag(outer.spiParams.map(new SPIPortIO(_))))
36
37 (spis zip outer.spis).foreach { case (io, device) =>
38 io <> device.module.io.port
39 }
40 }
41
42 case object PeripherySPIFlashKey extends Field[Seq[SPIFlashParams]]
43
44 trait HasPeripherySPIFlash extends HasSystemNetworks {
45 val spiFlashParams = p(PeripherySPIFlashKey)
46 val qspi = spiFlashParams map { params =>
47 val qspi = LazyModule(new TLSPIFlash(peripheryBusBytes, params))
48 qspi.rnode := TLFragmenter(peripheryBusBytes, cacheBlockBytes)(peripheryBus.node)
49 qspi.fnode := TLFragmenter(1, cacheBlockBytes)(TLWidthWidget(peripheryBusBytes)(peripheryBus.node))
50 intBus.intnode := qspi.intnode
51 qspi
52 }
53 }
54
55 trait HasPeripherySPIFlashBundle {
56 val qspi: HeterogeneousBag[SPIPortIO]
57
58 // It is important for SPIFlash that the syncStages is agreed upon, because
59 // internally it needs to realign the input data to the output SCK.
60 // Therefore, we rely on the syncStages parameter.
61 def SPIFlashtoGPIOPins(syncStages: Int = 0): Seq[SPIPinsIO] = qspi.map { s =>
62 val pins = Module(new SPIGPIOPort(s.c, syncStages))
63 pins.io.spi <> s
64 pins.io.pins
65 }
66 }
67
68 trait HasPeripherySPIFlashModuleImp extends LazyMultiIOModuleImp with HasPeripherySPIFlashBundle {
69 val outer: HasPeripherySPIFlash
70 val qspi = IO(HeterogeneousBag(outer.spiFlashParams.map(new SPIPortIO(_))))
71
72 (qspi zip outer.qspi) foreach { case (io, device) =>
73 io <> device.module.io.port
74 }
75 }
76