Initial commit.
[sifive-blocks.git] / src / main / scala / devices / mockaon / MockAON.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.mockaon
3
4 import Chisel._
5 import config._
6 import regmapper._
7 import uncore.tilelink2._
8 import rocketchip.PeripheryBusConfig
9
10 import sifive.blocks.util.GenericTimer
11
12 case class MockAONConfig(
13 address: BigInt = BigInt(0x10000000),
14 nBackupRegs: Int = 16) {
15 def size: Int = 0x1000
16 def regBytes: Int = 4
17 def wdogOffset: Int = 0
18 def rtcOffset: Int = 0x40
19 def backupRegOffset: Int = 0x80
20 def pmuOffset: Int = 0x100
21 }
22
23 trait HasMockAONParameters {
24 val params: (MockAONConfig, Parameters)
25 val c = params._1
26 implicit val p = params._2
27 }
28
29 class MockAONPMUIO extends Bundle {
30 val vddpaden = Bool(OUTPUT)
31 val dwakeup = Bool(INPUT)
32 }
33
34 class MockAONMOffRstIO extends Bundle {
35 val hfclkrst = Bool(OUTPUT)
36 val corerst = Bool(OUTPUT)
37 }
38
39 trait MockAONBundle extends Bundle with HasMockAONParameters {
40
41 // Output of the Power Management Sequencer
42 val moff = new MockAONMOffRstIO ()
43
44 // This goes out to wrapper
45 // to be combined to create aon_rst.
46 val wdog_rst = Bool(OUTPUT)
47
48 // This goes out to wrapper
49 // and comes back as our clk
50 val lfclk = Clock(OUTPUT)
51
52 val pmu = new MockAONPMUIO
53
54 val lfextclk = Clock(INPUT)
55
56 val resetCauses = new ResetCauses().asInput
57 }
58
59 trait MockAONModule extends Module with HasRegMap with HasMockAONParameters {
60 val io: MockAONBundle
61
62 // the expectation here is that Chisel's implicit reset is aonrst,
63 // which is asynchronous, so don't use synchronous-reset registers.
64
65 val rtc = Module(new RTC)
66
67 val pmu = Module(new PMU(new DevKitPMUConfig))
68 io.moff <> pmu.io.control
69 io.pmu.vddpaden := pmu.io.control.vddpaden
70 pmu.io.wakeup.dwakeup := io.pmu.dwakeup
71 pmu.io.wakeup.awakeup := Bool(false)
72 pmu.io.wakeup.rtc := rtc.io.ip(0)
73 pmu.io.resetCauses := io.resetCauses
74 val pmuRegMap = {
75 val regs = pmu.io.regs.wakeupProgram ++ pmu.io.regs.sleepProgram ++
76 Seq(pmu.io.regs.ie, pmu.io.regs.cause, pmu.io.regs.sleep, pmu.io.regs.key)
77 for ((r, i) <- regs.zipWithIndex)
78 yield (c.pmuOffset + c.regBytes*i) -> Seq(r.toRegField())
79 }
80 interrupts(1) := rtc.io.ip(0)
81
82 val wdog = Module(new WatchdogTimer)
83 io.wdog_rst := wdog.io.rst
84 wdog.io.corerst := pmu.io.control.corerst
85 interrupts(0) := wdog.io.ip(0)
86
87 // If there are multiple lfclks to choose from, we can mux them here.
88 io.lfclk := io.lfextclk
89
90 val backupRegs = Seq.fill(c.nBackupRegs)(Reg(UInt(width = c.regBytes * 8)))
91 val backupRegMap =
92 for ((reg, i) <- backupRegs.zipWithIndex)
93 yield (c.backupRegOffset + c.regBytes*i) -> Seq(RegField(reg.getWidth, RegReadFn(reg), RegWriteFn(reg)))
94
95 regmap((backupRegMap ++
96 GenericTimer.timerRegMap(wdog, c.wdogOffset, c.regBytes) ++
97 GenericTimer.timerRegMap(rtc, c.rtcOffset, c.regBytes) ++
98 pmuRegMap):_*)
99
100 }
101
102 class MockAON(c: MockAONConfig)(implicit val p: Parameters)
103 extends TLRegisterRouter(c.address, interrupts = 2, size = c.size, beatBytes = p(PeripheryBusConfig).beatBytes, concurrency = 1)(
104 new TLRegBundle((c, p), _) with MockAONBundle)(
105 new TLRegModule((c, p), _, _) with MockAONModule)