Initial commit.
[freedom-sifive.git] / src / main / scala / unleashed / u500vc707devkit / Top.scala
1 // See LICENSE for license details.
2 package sifive.freedom.unleashed.u500vc707devkit
3
4 import Chisel._
5 import config._
6 import util._
7 import junctions._
8 import diplomacy._
9 import uncore.tilelink._
10 import uncore.devices._
11 import uncore.util._
12 import uncore.converters._
13 import rocket._
14 import coreplex._
15 import rocketchip._
16
17 import sifive.blocks.devices.xilinxvc707mig._
18 import sifive.blocks.devices.xilinxvc707pciex1._
19 import sifive.blocks.devices.gpio.{GPIOConfig, PeripheryGPIO, PeripheryGPIOBundle, PeripheryGPIOModule}
20 import sifive.blocks.devices.spi.{SPIConfig, PeripherySPI, PeripherySPIBundle, PeripherySPIModule}
21 import sifive.blocks.devices.uart._
22 import sifive.blocks.util.ResetCatchAndSync
23
24 trait PeripheryConfigs {
25 val uartConfigs = List(UARTConfig(address = BigInt(0x54000000L)))
26 val spiConfigs = List(SPIConfig(rAddress = BigInt(0x54001000L)))
27 val gpioConfig = GPIOConfig(address = BigInt(0x54002000L), width = 4)
28 }
29
30 class U500VC707DevKitSystem(implicit p: Parameters) extends BaseTop
31 with PeripheryConfigs
32 with PeripheryBootROM
33 with PeripheryDebug
34 with PeripheryCounter
35 with PeripheryUART
36 with PeripherySPI
37 with PeripheryGPIO
38 with PeripheryXilinxVC707MIG
39 with PeripheryXilinxVC707PCIeX1
40 with HardwiredResetVector
41 with RocketPlexMaster {
42 override lazy val module = new U500VC707DevKitSystemModule(this, () => new U500VC707DevKitSystemBundle(this))
43
44 // scalastyle:off method.length
45 ConfigStringOutput.contents = Some {
46 """platform {
47 | vendor ucb;
48 | arch spike;
49 |};
50 |plic {
51 | interface "plic";
52 | ndevs 9;
53 | priority { mem { 0x0c000000 0x0c00ffff; }; };
54 | pending { mem { 0x0c001000 0x0c00107f; }; };
55 | 0 {
56 | 0 {
57 | m {
58 | ie { mem { 0x0c002000 0x0c00207f; }; };
59 | ctl { mem { 0x0c200000 0x0c200007; }; };
60 | };
61 | s {
62 | ie { mem { 0x0c002080 0x0c0020ff; }; };
63 | ctl { mem { 0x0c201000 0x0c201007; }; };
64 | };
65 | };
66 | };
67 |};
68 |pcie {
69 | interface "xilinx-pcie-rv";
70 | bus {
71 | mem { 0x60000000 0x7fffffff; } { 0x200000000 0x3ffffffff; };
72 | bus { 1 63; };
73 | };
74 | bridge {
75 | mem { 0x50000000 0x53ffffff; };
76 | bus 0;
77 | irq 6;
78 | };
79 |};
80 |leds {
81 | interface "gpio";
82 | ngpio 4;
83 | mem { 0x54002000 0x54002003; };
84 |};
85 |rtc {
86 | addr 0x200bff8;
87 |};
88 |ram {
89 | 0 {
90 | addr 0x80000000;
91 | size 0x10000000;
92 | };
93 |};
94 |uart {
95 | addr 0x54000000;
96 |};
97 |core {
98 | 0 {
99 | 0 {
100 | isa rv64ima;
101 | timecmp 0x02004000;
102 | ipi 0x02000000;
103 | };
104 | };
105 |};
106 |\u0000""".stripMargin
107 }
108 // scalastyle:on method.length
109 }
110
111 class U500VC707DevKitSystemBundle[+L <: U500VC707DevKitSystem](_outer: L) extends BaseTopBundle(_outer)
112 with PeripheryConfigs
113 with PeripheryBootROMBundle
114 with PeripheryDebugBundle
115 with PeripheryCounterBundle
116 with PeripheryUARTBundle
117 with PeripherySPIBundle
118 with PeripheryGPIOBundle
119 with PeripheryXilinxVC707MIGBundle
120 with PeripheryXilinxVC707PCIeX1Bundle
121 with HardwiredResetVectorBundle
122 with RocketPlexMasterBundle
123
124 class U500VC707DevKitSystemModule[+L <: U500VC707DevKitSystem, +B <: U500VC707DevKitSystemBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io)
125 with PeripheryConfigs
126 with PeripheryBootROMModule
127 with PeripheryDebugModule
128 with PeripheryCounterModule
129 with PeripheryUARTModule
130 with PeripherySPIModule
131 with PeripheryGPIOModule
132 with PeripheryXilinxVC707MIGModule
133 with PeripheryXilinxVC707PCIeX1Module
134 with HardwiredResetVectorModule
135 with RocketPlexMasterModule
136
137 /////
138
139 class ResetDone extends Module {
140 //unused - in future io.resetdone can set rocketchip STOP_COND/PRINTF_COND
141 val io = new Bundle{
142 val reset = Bool(INPUT)
143 val resetdone = Bool(OUTPUT)
144 }
145 val resetdonereg = Reg(init = Bool(false))
146 val resetff = Reg(init = Bool(false))
147 resetff := io.reset;
148 resetdonereg := Mux( ((!io.reset)&&resetff), UInt("b1"), resetdonereg)
149 io.resetdone := resetdonereg
150 }
151
152 /////
153
154 class U500VC707DevKitIO(implicit val p: Parameters) extends Bundle
155 with PeripheryConfigs
156 with PeripheryUARTBundle
157 with PeripherySPIBundle
158 with PeripheryGPIOBundle
159 {
160 val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip)
161 val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip)
162 //MIG
163 val xilinxvc707mig = new XilinxVC707MIGPads
164 //PCIe
165 val xilinxvc707pcie = new XilinxVC707PCIeX1Pads
166 //Clocks
167 val sys_clk_n = Bool(INPUT)
168 val sys_clk_p = Bool(INPUT)
169 val pcie_refclk_p = Bool(INPUT)
170 val pcie_refclk_n = Bool(INPUT)
171 //Reset
172 val sys_reset = Bool(INPUT)
173 //Misc outputs used in system.v
174 val core_reset = Bool(OUTPUT)
175 val core_clock = Clock(OUTPUT)
176 }
177
178 /////
179
180 class U500VC707DevKitTop(implicit val p: Parameters) extends Module {
181
182 // ------------------------------------------------------------
183 // Instantiate U500 VC707 Dev Kit system (sys)
184 // ------------------------------------------------------------
185 val sys = Module(LazyModule(new U500VC707DevKitSystem).module)
186 val io = new U500VC707DevKitIO
187
188 // ------------------------------------------------------------
189 // Clock and Reset
190 // ------------------------------------------------------------
191 val mig_mmcm_locked = Wire(Bool())
192 val mig_sys_reset = Wire(Bool())
193 val init_calib_complete = Wire(Bool())
194 val mmcm_lock_pcie = Wire(Bool())
195 val do_reset = Wire(Bool())
196 val mig_clock = Wire(Clock())
197 val mig_resetn = Wire(Bool())
198 val top_resetn = Wire(Bool())
199 val pcie_dat_reset = Wire(Bool())
200 val pcie_dat_resetn = Wire(Bool())
201 val pcie_cfg_reset = Wire(Bool())
202 val pcie_cfg_resetn = Wire(Bool())
203 val pcie_dat_clock = Wire(Clock())
204 val pcie_cfg_clock = Wire(Clock())
205 val top_clock = Wire(Clock())
206 val top_reset = Wire(Bool())
207 val mig_reset = Wire(Bool())
208
209 do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset
210 mig_resetn := !mig_reset
211 top_resetn := !top_reset
212 pcie_dat_resetn := !pcie_dat_reset
213 pcie_cfg_resetn := !pcie_cfg_reset
214 // For now, run the CPU synchronous to the PCIe data bus
215 top_clock := pcie_dat_clock
216 val safe_reset = Module(new vc707reset)
217 safe_reset.io.areset := do_reset
218 safe_reset.io.clock1 := mig_clock
219 mig_reset := safe_reset.io.reset1
220 safe_reset.io.clock2 := pcie_dat_clock
221 pcie_dat_reset := safe_reset.io.reset2
222 safe_reset.io.clock3 := pcie_cfg_clock
223 pcie_cfg_reset := safe_reset.io.reset3
224 safe_reset.io.clock4 := top_clock
225 top_reset := safe_reset.io.reset4
226
227 sys.clock := top_clock
228 sys.reset := top_reset
229
230 // ------------------------------------------------------------
231 // UART
232 // ------------------------------------------------------------
233 io.uarts <> sys.io.uarts
234
235 // ------------------------------------------------------------
236 // SPI
237 // ------------------------------------------------------------
238 io.spis <> sys.io.spis
239
240 // ------------------------------------------------------------
241 // GPIO
242 // ------------------------------------------------------------
243 io.gpio <> sys.io.gpio
244
245 // ------------------------------------------------------------
246 // MIG
247 // ------------------------------------------------------------
248 sys.io.xilinxvc707mig.sys_clk_p := io.sys_clk_p
249 sys.io.xilinxvc707mig.sys_clk_n := io.sys_clk_n
250 mig_clock := sys.io.xilinxvc707mig.ui_clk
251 mig_sys_reset := sys.io.xilinxvc707mig.ui_clk_sync_rst
252 mig_mmcm_locked := sys.io.xilinxvc707mig.mmcm_locked
253 sys.io.xilinxvc707mig.aresetn := mig_resetn
254 init_calib_complete := sys.io.xilinxvc707mig.init_calib_complete
255 sys.io.xilinxvc707mig.sys_rst := io.sys_reset
256 //the below bundle assignment is dangerous and relies on matching signal names
257 // io.xilinxvc707 is of type XilinxVC707MIGPads
258 // sys.io.xilinxvc707mig is of type XilinxVC707MIGIO
259 io.xilinxvc707mig <> sys.io.xilinxvc707mig
260
261 // ------------------------------------------------------------
262 // PCIe
263 // ------------------------------------------------------------
264 sys.io.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn
265 pcie_dat_clock := sys.io.xilinxvc707pcie.axi_aclk_out
266 pcie_cfg_clock := sys.io.xilinxvc707pcie.axi_ctl_aclk_out
267 mmcm_lock_pcie := sys.io.xilinxvc707pcie.mmcm_lock
268 sys.io.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn
269 sys.io.xilinxvc707pcie.REFCLK_rxp := io.pcie_refclk_p
270 sys.io.xilinxvc707pcie.REFCLK_rxn := io.pcie_refclk_n
271 //another dangerous bundle assignment which relies on matching signal names
272 // io.xilinxvc707pcie is of type XilinxVC707PCIeX1Pads
273 // sys.io.xilinxvc707pcie is of type XilinxVC707PCIeX1IO
274 io.xilinxvc707pcie <> sys.io.xilinxvc707pcie
275
276 // ------------------------------------------------------------
277 // Debug
278 // ------------------------------------------------------------
279 if (p(IncludeJtagDTM)) {
280 sys.io.jtag.get <> io.jtag.get
281 //Override TRST to reset this logic IFF the core is in reset.
282 // This will require 3 ticks of TCK before the debug logic
283 // comes out of reset, but JTAG needs 5 ticks anyway.
284 // This means that the "real" TRST is never actually used.
285 sys.io.jtag.get.TRST := ResetCatchAndSync(sys.io.jtag.get.TCK, top_reset)
286 }else{
287 // SimDTM; only for simulation use
288 sys.io.debug.get := io.debug.get
289 // test_mode_clk shouldn't be used for simulation
290 //sys.io.test_mode_clk := Bool(false).asClock
291 }
292
293 // ------------------------------------------------------------
294 // Misc outputs used in system.v
295 // ------------------------------------------------------------
296 io.core_clock := top_clock
297 io.core_reset := top_reset
298
299 }