Initial commit.
[freedom-sifive.git] / src / main / scala / everywhere / e300artydevkit / Top.scala
1 // See LICENSE for license details.
2 package sifive.freedom.everywhere.e300artydevkit
3
4 import Chisel._
5 import config._
6 import diplomacy._
7 import coreplex._
8 import rocketchip._
9 import uncore.devices.DebugBusIO
10 import sifive.blocks.devices.gpio.{GPIOConfig, PeripheryGPIO, PeripheryGPIOBundle, PeripheryGPIOModule, GPIOPin, GPIOPinToIOF, GPIOPinIOFCtrl, GPIOInputPinCtrl, JTAGPinsIO, JTAGGPIOPort}
11 import sifive.blocks.devices.mockaon.{MockAONConfig, PeripheryMockAON, PeripheryMockAONBundle, PeripheryMockAONModule, MockAONWrapperPadsIO}
12 import sifive.blocks.devices.pwm.{PWMConfig, PeripheryPWM, PeripheryPWMBundle, PeripheryPWMModule, PWMGPIOPort}
13 import sifive.blocks.devices.spi.{SPIConfig, PeripherySPI, PeripherySPIBundle, PeripherySPIModule, SPIFlashConfig, PeripherySPIFlash, PeripherySPIFlashBundle, PeripherySPIFlashModule, SPIPinsIO, SPIGPIOPort}
14 import sifive.blocks.devices.uart.{UARTConfig, PeripheryUART, PeripheryUARTBundle, PeripheryUARTModule, UARTGPIOPort}
15 import sifive.blocks.util.ResetCatchAndSync
16 import util._
17
18 // Coreplex and Periphery
19
20 trait E300ArtyDevKitPeripheryConfigs {
21 val mockAONConfig = MockAONConfig(address = 0x10000000)
22 val gpioConfig = GPIOConfig(address = 0x10012000, width = 32)
23 val pwmConfigs = List(
24 PWMConfig(address = 0x10015000, cmpWidth = 8),
25 PWMConfig(address = 0x10025000, cmpWidth = 16),
26 PWMConfig(address = 0x10035000, cmpWidth = 16))
27 val spiConfigs = List(
28 SPIConfig(csWidth = 4, rAddress = 0x10024000, sampleDelay = 3),
29 SPIConfig(csWidth = 1, rAddress = 0x10034000, sampleDelay = 3))
30 val spiFlashConfig = SPIFlashConfig(
31 fAddress = 0x20000000, rAddress = 0x10014000, sampleDelay = 3)
32 val uartConfigs = List(
33 UARTConfig(address = 0x10013000),
34 UARTConfig(address = 0x10023000))
35 }
36
37 // This custom E300ArtyDevKit coreplex has no port into the L2 and no memory subsystem
38
39 class E300ArtyDevKitCoreplex(implicit p: Parameters) extends BareCoreplex
40 with CoreplexNetwork
41 with CoreplexRISCVPlatform
42 with RocketTiles {
43 override lazy val module = new E300ArtyDevKitCoreplexModule(this, () => new E300ArtyDevKitCoreplexBundle(this))
44 }
45
46 class E300ArtyDevKitCoreplexBundle[+L <: E300ArtyDevKitCoreplex](_outer: L) extends BareCoreplexBundle(_outer)
47 with CoreplexNetworkBundle
48 with CoreplexRISCVPlatformBundle
49 with RocketTilesBundle
50
51 class E300ArtyDevKitCoreplexModule[+L <: E300ArtyDevKitCoreplex, +B <: E300ArtyDevKitCoreplexBundle[L]](_outer: L, _io: () => B)
52 extends BareCoreplexModule(_outer, _io)
53 with CoreplexNetworkModule
54 with CoreplexRISCVPlatformModule
55 with RocketTilesModule
56
57 class E300ArtyDevKitSystem(implicit p: Parameters) extends BaseTop
58 with E300ArtyDevKitPeripheryConfigs
59 with PeripheryBootROM
60 with PeripheryDebug
61 with PeripheryMockAON
62 with PeripheryUART
63 with PeripherySPIFlash
64 with PeripherySPI
65 with PeripheryGPIO
66 with PeripheryPWM
67 with HardwiredResetVector {
68 override lazy val module = new E300ArtyDevKitSystemModule(this, () => new E300ArtyDevKitSystemBundle(this))
69
70 val coreplex = LazyModule(new E300ArtyDevKitCoreplex)
71 socBus.node := coreplex.mmio
72 coreplex.mmioInt := intBus.intnode
73 }
74
75 class E300ArtyDevKitSystemBundle[+L <: E300ArtyDevKitSystem](_outer: L) extends BaseTopBundle(_outer)
76 with E300ArtyDevKitPeripheryConfigs
77 with PeripheryBootROMBundle
78 with PeripheryDebugBundle
79 with PeripheryUARTBundle
80 with PeripherySPIBundle
81 with PeripheryGPIOBundle
82 with PeripherySPIFlashBundle
83 with PeripheryMockAONBundle
84 with PeripheryPWMBundle
85 with HardwiredResetVectorBundle
86
87 class E300ArtyDevKitSystemModule[+L <: E300ArtyDevKitSystem, +B <: E300ArtyDevKitSystemBundle[L]](_outer: L, _io: () => B)
88 extends BaseTopModule(_outer, _io)
89 with E300ArtyDevKitPeripheryConfigs
90 with PeripheryBootROMModule
91 with PeripheryDebugModule
92 with PeripheryUARTModule
93 with PeripherySPIModule
94 with PeripheryGPIOModule
95 with PeripherySPIFlashModule
96 with PeripheryMockAONModule
97 with PeripheryPWMModule
98 with HardwiredResetVectorModule
99
100 // Top
101
102 class E300ArtyDevKitTopIO(implicit val p: Parameters) extends Bundle with E300ArtyDevKitPeripheryConfigs {
103 val pads = new Bundle {
104 val jtag = new JTAGPinsIO
105 val gpio = Vec(gpioConfig.width, new GPIOPin)
106 val qspi = new SPIPinsIO(spiFlashConfig)
107 val aon = new MockAONWrapperPadsIO()
108 }
109 }
110
111 class E300ArtyDevKitTop(implicit val p: Parameters) extends Module with E300ArtyDevKitPeripheryConfigs {
112 val sys = Module(LazyModule(new E300ArtyDevKitSystem).module)
113 val io = new E300ArtyDevKitTopIO
114
115 // This needs to be de-asserted synchronously to the coreClk.
116 val async_corerst = sys.io.aon.rsts.corerst
117 sys.reset := ResetCatchAndSync(clock, async_corerst, 20)
118
119 // ------------------------------------------------------------
120 // Check for unsupported RCT Connections
121 // ------------------------------------------------------------
122
123 require (p(NExtTopInterrupts) == 0, "No Top-level interrupts supported");
124
125 // ------------------------------------------------------------
126 // Build GPIO Pin Mux
127 // ------------------------------------------------------------
128
129 // Pin Mux for UART, SPI, PWM
130 // First convert the System outputs into "IOF" using the respective *GPIOPort
131 // converters.
132 val sys_uarts = sys.io.uarts
133 val sys_pwms = sys.io.pwms
134 val sys_spis = sys.io.spis
135
136 val uart_pins = uartConfigs.map { c => Module (new UARTGPIOPort) }
137 val pwm_pins = pwmConfigs.map { c => Module (new PWMGPIOPort(c.bc)) }
138 val spi_pins = spiConfigs.map { c => Module (new SPIGPIOPort(c)) }
139
140 (uart_pins zip sys_uarts) map {case (p, r) => p.io.uart <> r}
141 (pwm_pins zip sys_pwms) map {case (p, r) => p.io.pwm <> r}
142 (spi_pins zip sys_spis) map {case (p, r) => p.io.spi <> r}
143
144 // ------------------------------------------------------------
145 // Default Pin connections before attaching pinmux
146
147 for (iof_0 <- sys.io.gpio.iof_0) {
148 iof_0.o := GPIOPinIOFCtrl()
149 }
150
151 for (iof_1 <- sys.io.gpio.iof_1) {
152 iof_1.o := GPIOPinIOFCtrl()
153 }
154
155 // ------------------------------------------------------------
156 // TODO: Make this mapping more programmatic.
157
158 val iof_0 = sys.io.gpio.iof_0
159 val iof_1 = sys.io.gpio.iof_1
160
161 // SPI1 (0 is the dedicated)
162 GPIOPinToIOF(spi_pins(0).io.pins.cs(0), iof_0(2))
163 GPIOPinToIOF(spi_pins(0).io.pins.dq(0), iof_0(3))
164 GPIOPinToIOF(spi_pins(0).io.pins.dq(1), iof_0(4))
165 GPIOPinToIOF(spi_pins(0).io.pins.sck, iof_0(5))
166 GPIOPinToIOF(spi_pins(0).io.pins.dq(2), iof_0(6))
167 GPIOPinToIOF(spi_pins(0).io.pins.dq(3), iof_0(7))
168 GPIOPinToIOF(spi_pins(0).io.pins.cs(1), iof_0(8))
169 GPIOPinToIOF(spi_pins(0).io.pins.cs(2), iof_0(9))
170 GPIOPinToIOF(spi_pins(0).io.pins.cs(3), iof_0(10))
171
172 // SPI2
173 GPIOPinToIOF(spi_pins(1).io.pins.cs(0), iof_0(26))
174 GPIOPinToIOF(spi_pins(1).io.pins.dq(0), iof_0(27))
175 GPIOPinToIOF(spi_pins(1).io.pins.dq(1), iof_0(28))
176 GPIOPinToIOF(spi_pins(1).io.pins.sck, iof_0(29))
177 GPIOPinToIOF(spi_pins(1).io.pins.dq(2), iof_0(30))
178 GPIOPinToIOF(spi_pins(1).io.pins.dq(3), iof_0(31))
179
180 // UART0
181 GPIOPinToIOF(uart_pins(0).io.pins.rxd, iof_0(16))
182 GPIOPinToIOF(uart_pins(0).io.pins.txd, iof_0(17))
183
184 // UART1
185 GPIOPinToIOF(uart_pins(1).io.pins.rxd, iof_0(24))
186 GPIOPinToIOF(uart_pins(1).io.pins.txd, iof_0(25))
187
188 //PWM
189 GPIOPinToIOF(pwm_pins(0).io.pins.pwm(0), iof_1(0) )
190 GPIOPinToIOF(pwm_pins(0).io.pins.pwm(1), iof_1(1) )
191 GPIOPinToIOF(pwm_pins(0).io.pins.pwm(2), iof_1(2) )
192 GPIOPinToIOF(pwm_pins(0).io.pins.pwm(3), iof_1(3) )
193
194 GPIOPinToIOF(pwm_pins(1).io.pins.pwm(1), iof_1(19))
195 GPIOPinToIOF(pwm_pins(1).io.pins.pwm(0), iof_1(20))
196 GPIOPinToIOF(pwm_pins(1).io.pins.pwm(2), iof_1(21))
197 GPIOPinToIOF(pwm_pins(1).io.pins.pwm(3), iof_1(22))
198
199 GPIOPinToIOF(pwm_pins(2).io.pins.pwm(0), iof_1(10))
200 GPIOPinToIOF(pwm_pins(2).io.pins.pwm(1), iof_1(11))
201 GPIOPinToIOF(pwm_pins(2).io.pins.pwm(2), iof_1(12))
202 GPIOPinToIOF(pwm_pins(2).io.pins.pwm(3), iof_1(13))
203
204 // ------------------------------------------------------------
205 // Drive actual Pads
206 // ------------------------------------------------------------
207
208 // Result of Pin Mux
209 io.pads.gpio <> sys.io.gpio.pins
210
211 val dedicated_spi_pins = Module (new SPIGPIOPort(spiFlashConfig, syncStages=3, driveStrength=Bool(true)))
212 dedicated_spi_pins.clock := sys.clock
213 dedicated_spi_pins.reset := sys.reset
214 io.pads.qspi <> dedicated_spi_pins.io.pins
215 dedicated_spi_pins.io.spi <> sys.io.qspi
216
217 // JTAG Debug Interface
218
219 val jtag_pins = Module (new JTAGGPIOPort(true))
220 io.pads.jtag <> jtag_pins.io.pins
221 sys.io.jtag.get <> jtag_pins.io.jtag
222 // Override TRST to reset this logic IFF the core is in reset.
223 // This will require 3 ticks of TCK before the debug logic
224 // comes out of reset, but JTAG needs 5 ticks anyway.
225 // This means that the "real" TRST is never actually used in this design.
226 sys.io.jtag.get.TRST := ResetCatchAndSync(sys.io.jtag.get.TCK, async_corerst)
227
228 // AON Pads
229 io.pads.aon <> sys.io.aon.pads
230 }