From aac89ca1f0c0a52a89265a928e7ee3f1529cb7ad Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 10 May 2016 00:27:31 -0700 Subject: [PATCH] Add PLIC --- src/main/scala/Configs.scala | 24 +++++++++++++++++++++++- src/main/scala/RocketChip.scala | 20 ++++++++++++++++++-- src/main/scala/TestBench.scala | 20 ++++++++++++++++---- src/main/scala/Testing.scala | 6 ++---- uncore | 2 +- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 5874c9ff..d3199ccc 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -27,10 +27,11 @@ class DefaultConfig extends Config ( lazy val internalIOAddrMap: AddrMap = { val entries = collection.mutable.ArrayBuffer[AddrMapEntry]() entries += AddrMapEntry("debug", MemSize(1<<12, 1<<12, MemAttr(0))) - entries += AddrMapEntry("bootrom", MemSize(1<<13, 1<<12, MemAttr(AddrMapProt.RX))) + entries += AddrMapEntry("bootrom", MemSize(1<<12, 1<<12, MemAttr(AddrMapProt.RX))) entries += AddrMapEntry("rtc", MemSize(1<<12, 1<<12, MemAttr(AddrMapProt.RW))) for (i <- 0 until site(NTiles)) entries += AddrMapEntry(s"prci$i", MemSize(1<<12, 1<<12, MemAttr(AddrMapProt.RW))) + entries += AddrMapEntry("plic", MemSize(1<<22, 1<<22, MemAttr(AddrMapProt.RW))) new AddrMap(entries) } lazy val (globalAddrMap, globalAddrHashMap) = { @@ -54,12 +55,19 @@ class DefaultConfig extends Config ( } def makeConfigString() = { val addrMap = globalAddrHashMap + val plicAddr = addrMap(s"io:int:plic").start + val plicInfo = site(PLICKey) val xLen = site(XLen) val res = new StringBuilder res append "platform {\n" res append " vendor ucb;\n" res append " arch rocket;\n" res append "};\n" + res append "plic {\n" + res append s" priority 0x${plicAddr.toString(16)};\n" + res append s" pending 0x${(plicAddr + plicInfo.pendingBase).toString(16)};\n" + res append s" ndevs ${plicInfo.nDevices};\n" + res append "};\n" res append "rtc {\n" res append s" addr 0x${addrMap("io:int:rtc").start.toString(16)};\n" res append "};\n" @@ -79,6 +87,18 @@ class DefaultConfig extends Config ( res append s" isa $isa;\n" res append s" timecmp 0x${timecmpAddr.toString(16)};\n" res append s" ipi 0x${prciAddr.toString(16)};\n" + res append s" plic {\n" + res append s" m {\n" + res append s" ie 0x${(plicAddr + plicInfo.enableAddr(i, 'M')).toString(16)};\n" + res append s" thresh 0x${(plicAddr + plicInfo.threshAddr(i, 'M')).toString(16)};\n" + res append s" claim 0x${(plicAddr + plicInfo.claimAddr(i, 'M')).toString(16)};\n" + res append s" };\n" + res append s" s {\n" + res append s" ie 0x${(plicAddr + plicInfo.enableAddr(i, 'S')).toString(16)};\n" + res append s" thresh 0x${(plicAddr + plicInfo.threshAddr(i, 'S')).toString(16)};\n" + res append s" claim 0x${(plicAddr + plicInfo.claimAddr(i, 'S')).toString(16)};\n" + res append s" };\n" + res append s" };\n" res append " };\n" res append " };\n" } @@ -194,6 +214,8 @@ class DefaultConfig extends Config ( else TestGeneration.addSuites(env.map(rv64ufNoDiv)) true } + case NExtInterrupts => 2 + case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), site(NExtInterrupts)) case FDivSqrt => true case SFMALatency => 2 case DFMALatency => 3 diff --git a/src/main/scala/RocketChip.scala b/src/main/scala/RocketChip.scala index 3c87007b..30e66045 100644 --- a/src/main/scala/RocketChip.scala +++ b/src/main/scala/RocketChip.scala @@ -29,6 +29,10 @@ case object BuildTiles extends Field[Seq[(Bool, Parameters) => Tile]] case object ConfigString extends Field[Array[Byte]] /** Number of L1 clients besides the CPU cores */ case object ExtraL1Clients extends Field[Int] +/** Number of external interrupt sources */ +case object NExtInterrupts extends Field[Int] +/** Interrupt controller configuration */ +case object PLICKey extends Field[PLICConfig] case object UseStreamLoopback extends Field[Boolean] case object StreamLoopbackSize extends Field[Int] @@ -74,6 +78,7 @@ class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p) class TopIO(implicit p: Parameters) extends BasicTopIO()(p) { val mem = Vec(nMemChannels, new NastiIO) val mmio = new NastiIO + val interrupts = Vec(p(NExtInterrupts), Bool()).asInput } object TopUtils { @@ -134,6 +139,7 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters { uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten io.host <> uncore.io.host + uncore.io.interrupts <> io.interrupts io.mmio <> uncore.io.mmio io.mem.zip(uncore.io.mem).foreach { case (outer, inner) => @@ -159,6 +165,7 @@ class Uncore(implicit val p: Parameters) extends Module val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip val prci = Vec(nTiles, new PRCITileIO).asOutput val mmio = new NastiIO + val interrupts = Vec(p(NExtInterrupts), Bool()).asInput } val htif = Module(new Htif(CSRs.mreset)) // One HTIF module per chip @@ -202,6 +209,15 @@ class Uncore(implicit val p: Parameters) extends Module require(rtc.size <= rtcAddr.region.size) rtc.io.tl <> mmioNetwork.io.out(rtcAddr.port) + val plic = Module(new PLIC(p(PLICKey))) + val plicAddr = ioAddrHashMap("int:plic") + plic.io.tl <> mmioNetwork.io.out(plicAddr.port) + for (i <- 0 until io.interrupts.size) { + val gateway = Module(new LevelGateway) + gateway.io.interrupt := io.interrupts(i) + plic.io.devices(i) <> gateway.io.plic + } + for (i <- 0 until nTiles) { val prci = Module(new PRCI) val prciAddr = ioAddrHashMap(s"int:prci$i") @@ -209,8 +225,8 @@ class Uncore(implicit val p: Parameters) extends Module prci.io.id := UInt(i) prci.io.interrupts.mtip := rtc.io.irqs(i) - prci.io.interrupts.meip := Bool(false) - prci.io.interrupts.seip := Bool(false) + prci.io.interrupts.meip := plic.io.harts(plic.cfg.context(i, 'M')) + prci.io.interrupts.seip := plic.io.harts(plic.cfg.context(i, 'S')) prci.io.interrupts.debug := Bool(false) io.prci(i) := prci.io.tile diff --git a/src/main/scala/TestBench.scala b/src/main/scala/TestBench.scala index e8e872b2..54a658e9 100644 --- a/src/main/scala/TestBench.scala +++ b/src/main/scala/TestBench.scala @@ -3,12 +3,12 @@ package rocketchip import Chisel._ +import cde.Parameters object TestBenchGeneration extends FileSystemUtilities { def generateVerilogFragment( - topModuleName: String, configClassName: String, - nMemChannel: Int) = { - + topModuleName: String, configClassName: String, p: Parameters) = { + val nMemChannel = p(NMemoryChannels) // YUNSUP: // I originally wrote this using a 2d wire array, but of course Synopsys' // DirectC implementation totally chokes on it when the 2d array is @@ -199,6 +199,10 @@ object TestBenchGeneration extends FileSystemUtilities { .io_mem_${i}_b_bits_id (b_id_delay_$i), .io_mem_${i}_b_bits_user (1'b0), +""" } mkString + + val interrupts = (0 until p(NExtInterrupts)) map { i => s""" + .io_interrupts_$i (1'b0), """ } mkString val instantiation = s""" @@ -213,6 +217,8 @@ object TestBenchGeneration extends FileSystemUtilities { $nasti_connections + $interrupts + `ifndef FPGA .io_host_clk(htif_clk), .io_host_clk_edge(), @@ -293,7 +299,8 @@ object TestBenchGeneration extends FileSystemUtilities { } def generateCPPFragment( - topModuleName: String, configClassName: String, nMemChannel: Int) { + topModuleName: String, configClassName: String, p: Parameters) = { + val nMemChannel = p(NMemoryChannels) val assigns = (0 until nMemChannel).map { i => s""" mem_ar_valid[$i] = &tile.Top__io_mem_${i}_ar_valid; @@ -330,8 +337,13 @@ object TestBenchGeneration extends FileSystemUtilities { """ }.mkString + val interrupts = (0 until p(NExtInterrupts)) map { i => s""" + tile.Top__io_interrupts_$i = LIT<1>(0); +""" } mkString + val f = createOutputFile(s"$topModuleName.$configClassName.tb.cpp") f.write(assigns) + f.write(interrupts) f.close } } diff --git a/src/main/scala/Testing.scala b/src/main/scala/Testing.scala index 3ecc50e8..9c2c343a 100644 --- a/src/main/scala/Testing.scala +++ b/src/main/scala/Testing.scala @@ -184,11 +184,9 @@ object TestGenerator extends App with FileSystemUtilities { TestGeneration.generateMakefrag(topModuleName, configClassName) TestBenchGeneration.generateVerilogFragment( - topModuleName, configClassName, - paramsFromConfig(NMemoryChannels)) + topModuleName, configClassName, paramsFromConfig) TestBenchGeneration.generateCPPFragment( - topModuleName, configClassName, - paramsFromConfig(NMemoryChannels)) + topModuleName, configClassName, paramsFromConfig) val pdFile = createOutputFile(s"$topModuleName.$configClassName.prm") pdFile.write(ParameterDump.getDump) diff --git a/uncore b/uncore index 143ce453..36d6a151 160000 --- a/uncore +++ b/uncore @@ -1 +1 @@ -Subproject commit 143ce453a489ffae7dc3f65db2d50a7dc5d18b7f +Subproject commit 36d6a15155c38af0878806bd55fc5ff31811a47c