├── project ├── .gitignore ├── build.properties └── plugins.sbt ├── bootrom ├── .gitignore ├── bootrom.img ├── linker.ld ├── Makefile └── bootrom.S ├── scripts ├── debug_rom │ ├── .gitignore │ ├── link.ld │ └── Makefile ├── .gitignore ├── copyright-file ├── Makefile ├── modify-copyright ├── RocketSim.cfg ├── RocketSim.py ├── RocketSim32.py ├── RocketSim64.py └── tracegen.py ├── riscv-tools.hash ├── regression └── .gitignore ├── sbt-launch.jar ├── .gitignore ├── emulator └── .gitignore ├── src ├── main │ ├── scala │ │ ├── package.scala │ │ ├── diplomacy │ │ │ ├── ClockDomain.scala │ │ │ ├── Unreachable.scala │ │ │ ├── ValName.scala │ │ │ ├── FixedClockResource.scala │ │ │ ├── Clone.scala │ │ │ ├── JSON.scala │ │ │ └── SRAM.scala │ │ ├── diplomaticobjectmodel │ │ │ ├── model │ │ │ │ ├── OMBranchPredictor.scala │ │ │ │ ├── OMFPU.scala │ │ │ │ ├── OMDevice.scala │ │ │ │ ├── OMSpecification.scala │ │ │ │ ├── OMTestHarness.scala │ │ │ │ ├── OMBase.scala │ │ │ │ ├── OMMemory.scala │ │ │ │ ├── OMRegFieldAccessType.scala │ │ │ │ ├── OMInterrupts.scala │ │ │ │ ├── OMRegFieldRdAction.scala │ │ │ │ ├── OMZeroDevice.scala │ │ │ │ ├── OMErrorDevice.scala │ │ │ │ ├── OMCLINT.scala │ │ │ │ ├── OMSRAM.scala │ │ │ │ ├── OMBusError.scala │ │ │ │ ├── OMCore.scala │ │ │ │ ├── OMBusMemory.scala │ │ │ │ ├── CustomISAExtensions.scala │ │ │ │ ├── OMRegFieldWrType.scala │ │ │ │ ├── OMPMP.scala │ │ │ │ ├── OMPerformanceMonitor.scala │ │ │ │ ├── OMPLIC.scala │ │ │ │ ├── OMCoreComplex.scala │ │ │ │ ├── OMMulDiv.scala │ │ │ │ ├── OMRocketCore.scala │ │ │ │ └── ISASpecifications.scala │ │ │ ├── HasLogicalTreeNode.scala │ │ │ └── ConstructOM.scala │ │ ├── rocket │ │ │ └── package.scala │ │ ├── groundtest │ │ │ ├── Package.scala │ │ │ ├── Generator.scala │ │ │ ├── TestHarness.scala │ │ │ ├── Status.scala │ │ │ ├── Configs.scala │ │ │ ├── GroundTestSubsystem.scala │ │ │ └── DummyPTW.scala │ │ ├── unittest │ │ │ ├── Generator.scala │ │ │ ├── package.scala │ │ │ ├── TestHarness.scala │ │ │ ├── TestGenerator.scala │ │ │ └── UnitTest.scala │ │ ├── subsystem │ │ │ ├── ResetVector.scala │ │ │ ├── RTC.scala │ │ │ ├── FrontBus.scala │ │ │ ├── SystemBus.scala │ │ │ ├── MemoryBus.scala │ │ │ └── CrossingWrapper.scala │ │ ├── interrupts │ │ │ ├── Bundles.scala │ │ │ ├── RegisterRouter.scala │ │ │ ├── NullIntSource.scala │ │ │ ├── Xbar.scala │ │ │ ├── package.scala │ │ │ └── CrossingHelper.scala │ │ ├── util │ │ │ ├── CompileOptions.scala │ │ │ ├── SeededRandom.scala │ │ │ ├── IdentityModule.scala │ │ │ ├── BlockDuringReset.scala │ │ │ ├── Crossing.scala │ │ │ ├── PSDTestMode.scala │ │ │ ├── LatencyPipe.scala │ │ │ ├── GenericParameterizedBundle.scala │ │ │ ├── HeterogeneousBag.scala │ │ │ ├── ROMGenerator.scala │ │ │ ├── ClockGate.scala │ │ │ ├── CoreMonitor.scala │ │ │ ├── CRC.scala │ │ │ ├── Frequency.scala │ │ │ ├── IDPool.scala │ │ │ ├── Repeater.scala │ │ │ ├── Broadcaster.scala │ │ │ ├── SimpleProduct.scala │ │ │ ├── DescribedSRAM.scala │ │ │ ├── LCG.scala │ │ │ ├── TraceCoreInterface.scala │ │ │ ├── Location.scala │ │ │ ├── ReduceOthers.scala │ │ │ ├── ClockDivider.scala │ │ │ ├── GeneratorUtils.scala │ │ │ ├── ResetCatchAndSync.scala │ │ │ ├── HellaQueue.scala │ │ │ └── Counters.scala │ │ ├── stage │ │ │ ├── RocketChipCli.scala │ │ │ ├── package.scala │ │ │ ├── phases │ │ │ │ ├── TransformAnnotations.scala │ │ │ │ ├── GenerateArtefacts.scala │ │ │ │ ├── GenerateROMs.scala │ │ │ │ ├── GenerateTestSuiteMakefrags.scala │ │ │ │ ├── PreElaboration.scala │ │ │ │ ├── Checks.scala │ │ │ │ └── GenerateFirrtlAnnos.scala │ │ │ ├── RocketChipOptions.scala │ │ │ └── RocketChipAnnotations.scala │ │ ├── amba │ │ │ ├── apb │ │ │ │ ├── Protocol.scala │ │ │ │ ├── Monitor.scala │ │ │ │ ├── package.scala │ │ │ │ ├── Bundles.scala │ │ │ │ ├── Test.scala │ │ │ │ ├── Xbar.scala │ │ │ │ └── Nodes.scala │ │ │ ├── axi4 │ │ │ │ ├── Monitor.scala │ │ │ │ ├── package.scala │ │ │ │ ├── Protocol.scala │ │ │ │ ├── CrossingHelper.scala │ │ │ │ └── Buffer.scala │ │ │ ├── axis │ │ │ │ ├── package.scala │ │ │ │ ├── Buffer.scala │ │ │ │ └── Nodes.scala │ │ │ ├── ahb │ │ │ │ ├── Monitor.scala │ │ │ │ ├── package.scala │ │ │ │ ├── AHBLite.scala │ │ │ │ └── Protocol.scala │ │ │ └── package.scala │ │ ├── prci │ │ │ ├── ClockBundles.scala │ │ │ ├── IOHelper.scala │ │ │ ├── package.scala │ │ │ ├── ClockDomain.scala │ │ │ ├── ClockDivider.scala │ │ │ └── ResetWrangler.scala │ │ ├── jtag │ │ │ ├── package.scala │ │ │ ├── JtagUtils.scala │ │ │ └── Utils.scala │ │ ├── tile │ │ │ ├── LookupByHartId.scala │ │ │ ├── L1Cache.scala │ │ │ └── CustomCSRs.scala │ │ ├── devices │ │ │ ├── debug │ │ │ │ ├── DebugRomContents.scala │ │ │ │ └── APB.scala │ │ │ └── tilelink │ │ │ │ ├── Deadlock.scala │ │ │ │ ├── CanHaveBuiltInDevices.scala │ │ │ │ ├── BusBlocker.scala │ │ │ │ └── ClockBlocker.scala │ │ ├── regmapper │ │ │ ├── Annotation.scala │ │ │ ├── DescribedReg.scala │ │ │ └── RegisterRouter.scala │ │ ├── system │ │ │ ├── TestHarness.scala │ │ │ ├── ExampleRocketSystem.scala │ │ │ ├── RocketChipStageGenerator.scala │ │ │ └── SimAXIMem.scala │ │ └── tilelink │ │ │ ├── package.scala │ │ │ ├── Example.scala │ │ │ ├── Map.scala │ │ │ └── CrossingHelper.scala │ └── resources │ │ ├── vsrc │ │ ├── EICG_wrapper.v │ │ ├── plusarg_reader.v │ │ ├── ClockDivider2.v │ │ ├── ClockDivider3.v │ │ └── AsyncResetReg.v │ │ └── csrc │ │ ├── SimJTAG.cc │ │ ├── verilator.h │ │ ├── SimDTM.cc │ │ └── remote_bitbang.h └── test │ └── scala │ └── generatorTests │ └── StageGeneratorSpec.scala ├── vsim ├── .gitignore └── Makefile ├── ivydependencies.json ├── .gitmodules ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── ci-tests ├── check_submodules └── wake_scala_compilation ├── macros └── src │ └── main │ └── scala │ └── ValName.scala ├── wit-manifest.json ├── LICENSE.Berkeley ├── LICENSE.jtag ├── README_TRAVIS.md └── CONTRIBUTING.md /project/.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /bootrom/.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | -------------------------------------------------------------------------------- /scripts/debug_rom/.gitignore: -------------------------------------------------------------------------------- 1 | /debug_rom 2 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.4 2 | -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | /comlog 2 | /float_fix 3 | -------------------------------------------------------------------------------- /riscv-tools.hash: -------------------------------------------------------------------------------- 1 | e2c6d1577a75f506fe992c3eb20a75174504476e 2 | -------------------------------------------------------------------------------- /regression/.gitignore: -------------------------------------------------------------------------------- 1 | /install 2 | /stamps 3 | /torture-failures 4 | -------------------------------------------------------------------------------- /sbt-launch.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josecm/rocket-chip/HEAD/sbt-launch.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | project/target 3 | *.swp 4 | *~ 5 | .addons-dont-touch 6 | /lib/ 7 | -------------------------------------------------------------------------------- /bootrom/bootrom.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josecm/rocket-chip/HEAD/bootrom/bootrom.img -------------------------------------------------------------------------------- /emulator/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | *.a 4 | *.log 5 | output/ 6 | emulator-* 7 | generated-src 8 | generated-src-debug 9 | kernel 10 | kernel.hex 11 | verilator/ 12 | -------------------------------------------------------------------------------- /src/main/scala/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips 4 | 5 | package object rocketchip { 6 | val config = chipsalliance.rocketchip.config 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/ClockDomain.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | trait HasClockDomainCrossing extends LazyScope { this: LazyModule => } 6 | -------------------------------------------------------------------------------- /vsim/.gitignore: -------------------------------------------------------------------------------- 1 | simv* 2 | csrc 3 | *.vpd 4 | *.key 5 | DVE* 6 | .vcs* 7 | timestamp 8 | *.out 9 | *.h 10 | *.log 11 | *.cmd 12 | *.daidir 13 | *.ucli 14 | *.a 15 | *.vcd 16 | generated-src 17 | output 18 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMBranchPredictor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | trait OMBranchPredictor extends OMComponent 6 | -------------------------------------------------------------------------------- /src/main/scala/rocket/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | package object rocket extends rocket.constants.ScalarOpConstants with rocket.constants.MemoryOpConstants 6 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/Unreachable.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | case object Unreachable { 6 | def apply(): Nothing = throw new AssertionError("unreachable code") 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/Package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | package object groundtest { 6 | val testRamAddr = 0x10000 7 | val timeoutCodeBits = 4 8 | val errorCodeBits = 4 9 | } 10 | -------------------------------------------------------------------------------- /scripts/copyright-file: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | d=$(dirname $0) 3 | for i in "$@"; do 4 | if [ $# -gt 1 ]; then echo "$i:"; fi 5 | git blame --date="format:%Y%m%d" -M -C -C -C "$i" | sed 's/[^(]*(\([^0-46-9]*\) \([0-9]*\).*/\2 \1/' | $d/authors | sort | uniq -c | sort -rn 6 | done 7 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/Generator.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.groundtest 4 | 5 | import firrtl.options.StageMain 6 | import freechips.rocketchip.system.RocketChipStage 7 | 8 | object Generator extends StageMain(new RocketChipStage) 9 | -------------------------------------------------------------------------------- /src/main/scala/unittest/Generator.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.unittest 4 | 5 | import firrtl.options.StageMain 6 | import freechips.rocketchip.system.RocketChipStage 7 | 8 | object Generator extends StageMain(new RocketChipStage) 9 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMFPU.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMFPU( 6 | fLen: Int, 7 | _types: Seq[String] = Seq("OMFPU", "OMComponent", "OMCompoundType") 8 | ) extends OMComponent 9 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMDevice.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | trait OMDevice extends OMComponent { 6 | def memoryRegions: Seq[OMMemoryRegion] 7 | def interrupts: Seq[OMInterrupt] 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMSpecification.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMSpecification( 6 | name: String, 7 | version: String, 8 | _types: Seq[String] = Seq("OMSpecification") 9 | ) 10 | -------------------------------------------------------------------------------- /bootrom/linker.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | ROM_BASE = 0x10000; /* ... but actually position independent */ 4 | 5 | . = ROM_BASE; 6 | .text.start : { *(.text.start) } 7 | . = ROM_BASE + 0x40; 8 | .text.hang : { *(.text.hang) } 9 | . = ROM_BASE + 0x80; 10 | .rodata.dtb : { *(.rodata.dtb) } 11 | } 12 | -------------------------------------------------------------------------------- /scripts/debug_rom/link.ld: -------------------------------------------------------------------------------- 1 | /* See LICENSE.SiFive for license details. */ 2 | OUTPUT_ARCH( "riscv" ) 3 | ENTRY( entry ) 4 | SECTIONS 5 | { 6 | .whereto 0x300 : 7 | { 8 | *(.whereto) 9 | } 10 | . = 0x800; 11 | .text : 12 | { 13 | *(.text) 14 | } 15 | _end = .; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMTestHarness.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | 6 | case class OMTestHarness( 7 | components: Seq[OMComponent], 8 | _types: Seq[String] = Seq("OMTestHarness") 9 | ) extends OMComponent 10 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMBase.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | trait OMBaseType 6 | 7 | trait OMEnum extends OMBaseType 8 | 9 | trait OMCompoundType extends OMBaseType 10 | 11 | trait OMComponent extends OMCompoundType 12 | 13 | -------------------------------------------------------------------------------- /src/main/scala/unittest/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import Chisel._ 6 | 7 | package object unittest 8 | { 9 | implicit class LazyUnitTestSeq(val seq: Seq[LazyUnitTest]) { 10 | def finished = seq.map(_.module.finished).foldLeft(Bool(true))(_ && _) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /bootrom/Makefile: -------------------------------------------------------------------------------- 1 | bootrom_img = bootrom.img 2 | 3 | GCC=riscv64-unknown-elf-gcc 4 | OBJCOPY=riscv64-unknown-elf-objcopy 5 | 6 | all: $(bootrom_img) 7 | 8 | %.img: %.bin 9 | dd if=$< of=$@ bs=128 count=1 10 | 11 | %.bin: %.elf 12 | $(OBJCOPY) -O binary $< $@ 13 | 14 | %.elf: %.S linker.ld 15 | $(GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@ 16 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/ResetVector.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import Chisel._ 6 | 7 | /** A single place for all tiles to find out the reset vector */ 8 | trait HasResetVectorWire { 9 | def resetVectorBits: Int 10 | val global_reset_vector = Wire(UInt(width = resetVectorBits)) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMMemory.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMMemory( 6 | description: String, 7 | addressWidth: Int, 8 | dataWidth: Int, 9 | depth: BigInt, 10 | writeMaskGranularity: Int, 11 | _types: Seq[String] = Seq("OMMemory") 12 | ) 13 | 14 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMRegFieldAccessType.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | sealed trait OMRegFieldAccessType extends OMEnum 6 | case object R extends OMRegFieldAccessType 7 | case object W extends OMRegFieldAccessType 8 | case object RW extends OMRegFieldAccessType 9 | 10 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/Bundles.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.interrupts 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.util._ 8 | 9 | class SyncInterrupts(params: IntEdge) extends GenericParameterizedBundle(params) 10 | { 11 | val sync = Vec(params.source.num, Bool()) 12 | } 13 | -------------------------------------------------------------------------------- /scripts/Makefile: -------------------------------------------------------------------------------- 1 | base_dir = $(abspath ..) 2 | 3 | CXXSRCS := comlog float_fix 4 | CXXFLAGS := $(CXXFLAGS) -std=c++11 -Wall 5 | 6 | OBJS := $(addsuffix .o,$(CXXSRCS)) 7 | PROGRAMS := $(CXXSRCS) 8 | 9 | all: $(PROGRAMS) 10 | 11 | %: %.o 12 | $(CXX) $< $(LDFLAGS) -o $@ 13 | 14 | %.o: $(base_dir)/csrc/%.cc 15 | $(CXX) $(CXXFLAGS) -c $< -o $@ 16 | 17 | clean: 18 | rm -f $(OBJS) $(PROGRAMS) 19 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/ValName.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | import scala.language.experimental.macros 6 | import freechips.rocketchip.macros.ValNameImpl 7 | 8 | case class ValName(name: String) 9 | 10 | object ValName 11 | { 12 | implicit def materialize(implicit x: ValNameImpl): ValName = ValName(x.name) 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMInterrupts.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMInterrupt( 6 | receiver: String, // TODO Reference 7 | numberAtReceiver: BigInt, 8 | name: String, 9 | _types: Seq[String] = Seq("OMInterrupt", "OMCompoundType") 10 | ) extends OMCompoundType 11 | 12 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMRegFieldRdAction.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | sealed trait OMRegFieldRdAction extends OMEnum 6 | case object RFRA_CLEAR extends OMRegFieldRdAction 7 | case object RFRA_SET extends OMRegFieldRdAction 8 | case object RFRA_MODIFY extends OMRegFieldRdAction 9 | 10 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMZeroDevice.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | 6 | case class OMZeroDevice( 7 | memoryRegions: Seq[OMMemoryRegion], 8 | interrupts: Seq[OMInterrupt], 9 | _types: Seq[String] = Seq("OMZeroDevice", "OMDevice", "OMComponent", "OMCompoundType") 10 | ) extends OMDevice 11 | -------------------------------------------------------------------------------- /src/main/scala/unittest/TestHarness.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.unittest 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | 8 | class TestHarness(implicit val p: Parameters) extends Module { 9 | val io = new Bundle { val success = Bool(OUTPUT) } 10 | io.success := Module(new UnitTestSuite).io.finished 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMErrorDevice.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | 6 | case class OMErrorDevice( 7 | memoryRegions: Seq[OMMemoryRegion], 8 | interrupts: Seq[OMInterrupt], 9 | _types: Seq[String] = Seq("OMErrorDevice", "OMDevice", "OMComponent", "OMCompoundType") 10 | ) extends OMDevice 11 | -------------------------------------------------------------------------------- /scripts/modify-copyright: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | d=$(dirname "$0") 3 | threshold=10 4 | 5 | for i in $(git ls-tree -r HEAD . | grep '\.\(scala\|cc\|v\)' | cut -f2); do 6 | ("$d/copyright-file" "$i" | sort -rn | awk 'NR == 1 || $1 > '$threshold' { print }' | sed 's@[^A-Z]*@// See LICENSE.@;s@$@ for license details.@;$a\\'; \ 7 | grep -v "^// See LICENSE" $i | sed '/./,$!d') > $i.tmp 8 | mv $i.tmp $i 9 | done 10 | -------------------------------------------------------------------------------- /src/main/scala/util/CompileOptions.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3.ExplicitCompileOptions.NotStrict 6 | 7 | object CompileOptions { 8 | /** Compatibility mode semantics except Module implicit reset should be inferred instead of Bool */ 9 | implicit val NotStrictInferReset = NotStrict.copy(inferModuleReset = true) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/vsrc/EICG_wrapper.v: -------------------------------------------------------------------------------- 1 | /* verilator lint_off UNOPTFLAT */ 2 | 3 | module EICG_wrapper( 4 | output out, 5 | input en, 6 | input test_en, 7 | input in 8 | ); 9 | 10 | reg en_latched /*verilator clock_enable*/; 11 | 12 | always @(*) begin 13 | if (!in) begin 14 | en_latched = en || test_en; 15 | end 16 | end 17 | 18 | assign out = en_latched && in; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMCLINT.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMCLINT( 6 | memoryRegions: Seq[OMMemoryRegion], 7 | interrupts: Seq[OMInterrupt], 8 | specifications: List[OMSpecification], 9 | _types: Seq[String] = Seq("OMCLINT", "OMDevice", "OMComponent", "OMCompoundType") 10 | ) extends OMDevice 11 | -------------------------------------------------------------------------------- /src/main/scala/stage/RocketChipCli.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage 4 | 5 | import firrtl.options.Shell 6 | 7 | trait RocketChipCli { this: Shell => 8 | 9 | parser.note("Rocket Chip Compiler Options") 10 | Seq( 11 | TopModuleAnnotation, 12 | ConfigsAnnotation, 13 | OutputBaseNameAnnotation, 14 | ) 15 | .foreach(_.addOptions(parser)) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMSRAM.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMSRAM( 6 | description: String, 7 | addressWidth: Int, 8 | dataWidth: Int, 9 | depth: BigInt, 10 | writeMaskGranularity: Int, 11 | uid: Int, 12 | rtlModule: OMRTLModule, 13 | _types: Seq[String] = Seq("OMSRAM") 14 | ) extends OMComponent 15 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMBusError.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | 6 | case class OMBusError( 7 | memoryRegions: Seq[OMMemoryRegion], 8 | interrupts: Seq[OMInterrupt], 9 | specifications: Seq[OMSpecification], 10 | _types: Seq[String] = Seq("OMBusError", "OMDevice", "OMComponent", "OMCompoundType") 11 | ) extends OMDevice 12 | -------------------------------------------------------------------------------- /src/main/scala/util/SeededRandom.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | /** Using e.g. Random.nextInt makes your hardware generation non-repoducible, 6 | * which is almost certainly undesirable. Use LCG to increment random numbers in HW, 7 | * or use this SeededRandom.fromSeed to make reproducible Scala PRNGs. 8 | */ 9 | object SeededRandom { 10 | val fromSeed = new scala.util.Random(42) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/HasLogicalTreeNode.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel 4 | 5 | 6 | import freechips.rocketchip.diplomaticobjectmodel.logicaltree._ 7 | 8 | trait HasLogicalTreeNode { 9 | def logicalTreeNode: LogicalTreeNode 10 | def addLogicalTreeNode(childLogicalTreeNode: LogicalTreeNode): Unit = LogicalModuleTree.add(logicalTreeNode, childLogicalTreeNode) 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Protocol.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import Chisel._ 6 | 7 | object APBParameters 8 | { 9 | // These are all fixed by the AHB standard: 10 | val protBits = 3 11 | 12 | def PROT_PRIVILEDGED = UInt(1, width = protBits) 13 | def PROT_NONSECURE = UInt(2, width = protBits) 14 | def PROT_INSTRUCTION = UInt(4, width = protBits) 15 | def PROT_DEFAULT = PROT_PRIVILEDGED 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/prci/ClockBundles.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | package freechips.rocketchip.prci 3 | 4 | import chisel3._ 5 | import freechips.rocketchip.util.HeterogeneousBag 6 | 7 | class ClockBundle(val params: ClockBundleParameters) extends Bundle 8 | { 9 | val clock = Clock() 10 | val reset = Reset() 11 | } 12 | 13 | class ClockGroupBundle(val params: ClockGroupBundleParameters) extends Bundle 14 | { 15 | val member = HeterogeneousBag(params.members.map(p => new ClockBundle(p))) 16 | } 17 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2") 2 | 3 | addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.1") 4 | 5 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") 6 | 7 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.9.3") 8 | 9 | addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.1") 10 | 11 | addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") 12 | 13 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") 14 | 15 | addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") 16 | -------------------------------------------------------------------------------- /ivydependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "hardfloat": { 3 | "scalaVersion": "2.12.8" 4 | }, 5 | "rocketchipMacros": { 6 | "scalaVersion": "2.12.8", 7 | "dependencies": [ 8 | "org.scala-lang:scala-reflect:2.12.8" 9 | ] 10 | }, 11 | "rocketchip": { 12 | "scalaVersion": "2.12.8", 13 | "dependencies": [ 14 | "org.json4s::json4s-jackson:3.5.3" 15 | ] 16 | }, 17 | "macrosParadise": { 18 | "scalaVersion": "2.12.8", 19 | "dependencies": [ 20 | "org.scalamacros:::paradise:2.1.0" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMCore.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | trait OMCore extends OMComponent{ 6 | def isa: OMISA 7 | def mulDiv: Option[OMMulDiv] 8 | def performanceMonitor: Option[OMPerformanceMonitor] 9 | def pmp: Option[OMPMP] 10 | def documentationName: String 11 | def hartIds: Seq[Int] 12 | def hasVectoredInterrupts: Boolean 13 | def interruptLatency: Int 14 | def nLocalInterrupts: Int 15 | def nBreakpoints: Int 16 | } 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "hardfloat"] 2 | path = hardfloat 3 | url = https://github.com/ucb-bar/berkeley-hardfloat.git 4 | [submodule "torture"] 5 | path = torture 6 | url = https://github.com/ucb-bar/riscv-torture.git 7 | [submodule "chisel3"] 8 | path = chisel3 9 | url = https://github.com/ucb-bar/chisel3.git 10 | [submodule "firrtl"] 11 | path = firrtl 12 | url = https://github.com/ucb-bar/firrtl.git 13 | [submodule "api-config-chipsalliance"] 14 | path = api-config-chipsalliance 15 | url = https://github.com/chipsalliance/api-config-chipsalliance.git 16 | -------------------------------------------------------------------------------- /src/main/scala/util/IdentityModule.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tilelink 4 | 5 | import Chisel._ 6 | 7 | class IdentityModule[T <: Data](gen: T) extends Module 8 | { 9 | val io = new Bundle { 10 | val in = gen.cloneType.flip 11 | val out = gen.cloneType 12 | } 13 | 14 | io.out := io.in 15 | } 16 | 17 | object IdentityModule 18 | { 19 | def apply[T <: Data](x: T): T = { 20 | val identity = Module(new IdentityModule(x)) 21 | identity.io.in := x 22 | identity.io.out 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /bootrom/bootrom.S: -------------------------------------------------------------------------------- 1 | #define DRAM_BASE 0x80000000 2 | 3 | .section .text.start, "ax", @progbits 4 | .globl _start 5 | _start: 6 | csrwi 0x7c1, 0 // disable chicken bits 7 | li s0, DRAM_BASE 8 | csrr a0, mhartid 9 | la a1, _dtb 10 | jr s0 11 | 12 | .section .text.hang, "ax", @progbits 13 | .globl _hang 14 | _hang: 15 | csrwi 0x7c1, 0 // disable chicken bits 16 | csrr a0, mhartid 17 | la a1, _dtb 18 | csrwi mie, 0 19 | 1: 20 | wfi 21 | j 1b 22 | 23 | .section .rodata.dtb, "a", @progbits 24 | .globl _dtb 25 | .align 5, 0 26 | _dtb: 27 | .ascii "DTB goes here" 28 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Monitor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.config.Parameters 7 | 8 | case class APBMonitorArgs(edge: APBEdgeParameters) 9 | 10 | abstract class APBMonitorBase(args: APBMonitorArgs) extends Module 11 | { 12 | val io = IO(new Bundle { 13 | val in = Input(new APBBundle(args.edge.bundle)) 14 | }) 15 | 16 | def legalize(bundle: APBBundle, edge: APBEdgeParameters, reset: Reset): Unit 17 | legalize(io.in, args.edge, reset) 18 | } 19 | -------------------------------------------------------------------------------- /scripts/RocketSim.cfg: -------------------------------------------------------------------------------- 1 | adapter_khz 10000 2 | 3 | interface remote_bitbang 4 | remote_bitbang_host localhost 5 | #$::env(REMOTE_BITBANG_HOST) 6 | remote_bitbang_port $::env(JTAG_VPI_PORT) 7 | 8 | set _CHIPNAME riscv 9 | jtag newtap $_CHIPNAME cpu -irlen 5 10 | 11 | set _TARGETNAME $_CHIPNAME.cpu 12 | target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos riscv 13 | 14 | riscv set_reset_timeout_sec 120 15 | riscv set_command_timeout_sec 120 16 | 17 | riscv set_prefer_sba $::env(JTAG_DTM_ENABLE_SBA) 18 | 19 | init 20 | halt 21 | echo "Ready for Remote Connections" 22 | -------------------------------------------------------------------------------- /src/main/scala/amba/axi4/Monitor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axi4 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.config.Parameters 7 | 8 | case class AXI4MonitorArgs(edge: AXI4EdgeParameters) 9 | 10 | abstract class AXI4MonitorBase(args: AXI4MonitorArgs) extends Module 11 | { 12 | val io = IO(new Bundle { 13 | val in = Input(new AXI4Bundle(args.edge.bundle)) 14 | }) 15 | 16 | def legalize(bundle: AXI4Bundle, edge: AXI4EdgeParameters, reset: Reset): Unit 17 | legalize(io.in, args.edge, reset) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object apb 9 | { 10 | type APBOutwardNode = OutwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] 11 | type APBInwardNode = InwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] 12 | type APBNode = SimpleNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/TestHarness.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.groundtest 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy.LazyModule 8 | import freechips.rocketchip.system.SimAXIMem 9 | 10 | class TestHarness(implicit p: Parameters) extends Module { 11 | val io = new Bundle { val success = Bool(OUTPUT) } 12 | val ldut = LazyModule(new GroundTestSubsystem) 13 | val dut = Module(ldut.module) 14 | io.success := dut.success 15 | SimAXIMem.connectMem(ldut) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMBusMemory.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | case class OMBusMemory( 6 | memoryRegions: Seq[OMMemoryRegion] = Nil, 7 | interrupts: Seq[OMInterrupt] = Nil, 8 | specifications: Seq[OMSpecification] = Nil, 9 | busProtocol: Option[OMProtocol] = None, 10 | dataECC: OMECC = OMECCIdentity, 11 | hasAtomics: Boolean = false, 12 | memories: Seq[OMSRAM], 13 | _types: Seq[String] = Seq("OMBusMemory", "OMDevice", "OMComponent", "OMCompoundType") 14 | ) extends OMDevice 15 | -------------------------------------------------------------------------------- /src/main/resources/csrc/SimJTAG.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | #include 4 | #include "remote_bitbang.h" 5 | 6 | remote_bitbang_t* jtag; 7 | extern "C" int jtag_tick 8 | ( 9 | unsigned char * jtag_TCK, 10 | unsigned char * jtag_TMS, 11 | unsigned char * jtag_TDI, 12 | unsigned char * jtag_TRSTn, 13 | unsigned char jtag_TDO 14 | ) 15 | { 16 | if (!jtag) { 17 | // TODO: Pass in real port number 18 | jtag = new remote_bitbang_t(0); 19 | } 20 | 21 | jtag->tick(jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn, jtag_TDO); 22 | 23 | return jtag->done() ? (jtag->exit_code() << 1 | 1) : 0; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/jtag/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.jtag for license details 2 | 3 | package freechips.rocketchip 4 | 5 | import scala.language.implicitConversions 6 | 7 | package object jtag { 8 | /** An implicit conversion to allow the instruction map for the TAP generator to be specified as 9 | * an Int instead of BigInt. Scala doesn't seem to want to automatically apply the built-in Int 10 | * to BigInt conversion when used as a Map key. 11 | * 12 | * This is limited to value types of Chain to limit application scope. 13 | */ 14 | implicit def instructionIntKeyToBigInt[V <: Chain](x: (Int, V)) = (BigInt(x._1), x._2) 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/ConstructOM.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel 4 | 5 | import freechips.rocketchip.diplomacy.ResourceBindingsMap 6 | import freechips.rocketchip.diplomaticobjectmodel.logicaltree._ 7 | import freechips.rocketchip.diplomaticobjectmodel.model.OMComponent 8 | import freechips.rocketchip.util.ElaborationArtefacts 9 | 10 | case object ConstructOM { 11 | def constructOM(): Unit = { 12 | val om: Seq[OMComponent] = LogicalModuleTree.bind() 13 | ElaborationArtefacts.add("objectModel.json", DiplomaticObjectModelUtils.toJson(om)) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/util/BlockDuringReset.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3._ 6 | import chisel3.util.DecoupledIO 7 | 8 | /** Blocks transactions until the cycle after reset. */ 9 | object BlockDuringReset 10 | { 11 | def apply[T <: Data](enq: DecoupledIO[T]): DecoupledIO[T] = { 12 | val out_of_reset = RegNext(true.B, false.B) 13 | val res = Wire(enq.cloneType) 14 | res.valid := enq.valid 15 | enq.ready := res.ready 16 | res.bits := enq.bits 17 | when (!out_of_reset) { 18 | res.valid := false.B 19 | enq.ready := false.B 20 | } 21 | res 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/vsrc/plusarg_reader.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | //VCS coverage exclude_file 4 | 5 | // No default parameter values are intended, nor does IEEE 1800-2012 require them (clause A.2.4 param_assignment), 6 | // but Incisive demands them. These default values should never be used. 7 | module plusarg_reader #(parameter FORMAT="borked=%d", DEFAULT=0, WIDTH=1) ( 8 | output [WIDTH-1:0] out 9 | ); 10 | 11 | `ifdef SYNTHESIS 12 | assign out = DEFAULT; 13 | `else 14 | reg [WIDTH-1:0] myplus; 15 | assign out = myplus; 16 | 17 | initial begin 18 | if (!$value$plusargs(FORMAT, myplus)) myplus = DEFAULT; 19 | end 20 | `endif 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /src/main/scala/amba/axis/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object axis 9 | { 10 | type AXISInwardNode = InwardNodeHandle[AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle] 11 | type AXISOutwardNode = OutwardNodeHandle[AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle] 12 | type AXISNode = NodeHandle[AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle, AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle] 13 | } 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | **Related issue**: 5 | 6 | 7 | **Type of change**: bug report | feature request | other enhancement 8 | 9 | 10 | **Impact**: no functional change | API addition (no impact on existing code) | API modification 11 | 12 | 13 | **Development Phase**: proposal | implementation 14 | 15 | **Release Notes** 16 | 19 | -------------------------------------------------------------------------------- /ci-tests/check_submodules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # jq filter to check that the wit-manifest contins a given commit (\1) and package (\2) 4 | filter='.[]|select(.commit == "\1")|select(.name == "\2")' 5 | 6 | # only check that all submodules have a corresponding wit package 7 | # the wit-manifest.json may have packages that are not submoduled 8 | # e.g. api-chisel3-sifive 9 | git submodule status \ 10 | | sed -r "s/[ -+U]([a-zA-Z0-9]+) ([a-zA-Z0-9\-]+) ?.*/$filter/g" \ 11 | | xargs -d '\n' -I % sh -c "jq -e '%' wit-manifest.json" 12 | 13 | if [ $? -eq 0 ]; then 14 | echo "Submodules are in sync with wit-manifest" 15 | else 16 | echo "ERROR! Submodules are out of sync with wit-manifest!" 17 | exit 1 18 | fi 19 | -------------------------------------------------------------------------------- /scripts/RocketSim.py: -------------------------------------------------------------------------------- 1 | import targets 2 | import testlib 3 | 4 | class RocketSimHart(targets.Hart): 5 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now. 6 | # to get these tests to pass. 7 | ram = 0x80000000 8 | ram_size = 0x4000 9 | instruction_hardware_breakpoint_count = 2 10 | pass 11 | 12 | class RocketSim(targets.Target): 13 | harts = [RocketSimHart()] 14 | timeout_sec = 6000 15 | server_timeout_sec = 60*60 16 | openocd_config_path = "RocketSim.cfg" 17 | 18 | def create(self): 19 | printf("STARTING A SIMULATION") 20 | printf(self.sim_cmd) 21 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False) 22 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/Status.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.groundtest 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.util.ValidMux 7 | 8 | class GroundTestStatus extends Bundle { 9 | val finished = Bool(OUTPUT) 10 | val timeout = Valid(UInt(width = 4)) 11 | val error = Valid(UInt(width = 4)) 12 | } 13 | 14 | object DebugCombiner { 15 | def apply(debugs: Seq[GroundTestStatus]): GroundTestStatus = { 16 | val out = Wire(new GroundTestStatus) 17 | out.finished := debugs.map(_.finished).reduce(_ && _) 18 | out.timeout := ValidMux(debugs.map(_.timeout)) 19 | out.error := ValidMux(debugs.map(_.error)) 20 | out 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /scripts/RocketSim32.py: -------------------------------------------------------------------------------- 1 | import targets 2 | import testlib 3 | 4 | class RocketSimHart(targets.Hart): 5 | xlen = 32 6 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now. 7 | # to get these tests to pass. 8 | ram = 0x80000000 9 | ram_size = 0x4000 10 | instruction_hardware_breakpoint_count = 2 11 | pass 12 | 13 | class RocketSim(targets.Target): 14 | harts = [RocketSimHart()] 15 | timeout_sec = 6000 16 | server_timeout_sec = 60*60 17 | openocd_config_path = "RocketSim.cfg" 18 | 19 | def create(self): 20 | print("STARTING A SIMULATION") 21 | print(self.sim_cmd) 22 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False) 23 | -------------------------------------------------------------------------------- /scripts/RocketSim64.py: -------------------------------------------------------------------------------- 1 | import targets 2 | import testlib 3 | 4 | class RocketSimHart(targets.Hart): 5 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now. 6 | # to get these tests to pass. 7 | xlen = 64 8 | ram = 0x80000000 9 | ram_size = 0x4000 10 | instruction_hardware_breakpoint_count = 2 11 | pass 12 | 13 | class RocketSim(targets.Target): 14 | harts = [RocketSimHart()] 15 | timeout_sec = 6000 16 | server_timeout_sec = 60*60 17 | openocd_config_path = "RocketSim.cfg" 18 | 19 | def create(self): 20 | print("STARTING A SIMULATION") 21 | print(self.sim_cmd) 22 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False) 23 | -------------------------------------------------------------------------------- /src/main/scala/tile/LookupByHartId.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tile 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | abstract class LookupByHartIdImpl { 9 | def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T 10 | } 11 | 12 | case class HartsWontDeduplicate(t: TileParams) extends LookupByHartIdImpl { 13 | def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T = f(t).get 14 | } 15 | 16 | case class PriorityMuxHartIdFromSeq(seq: Seq[TileParams]) extends LookupByHartIdImpl { 17 | def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T = 18 | PriorityMux(seq.collect { case t if f(t).isDefined => (t.hartId.U === hartId) -> f(t).get }) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/util/Crossing.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | import chisel3.util.{DecoupledIO, Decoupled, Irrevocable, IrrevocableIO, ReadyValidIO} 7 | 8 | class CrossingIO[T <: Data](gen: T) extends Bundle { 9 | // Enqueue clock domain 10 | val enq_clock = Clock(INPUT) 11 | val enq_reset = Bool(INPUT) // synchronously deasserted wrt. enq_clock 12 | val enq = Decoupled(gen).flip 13 | // Dequeue clock domain 14 | val deq_clock = Clock(INPUT) 15 | val deq_reset = Bool(INPUT) // synchronously deasserted wrt. deq_clock 16 | val deq = Decoupled(gen) 17 | } 18 | 19 | abstract class Crossing[T <: Data] extends Module { 20 | val io: CrossingIO[T] 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/FixedClockResource.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | class FixedClockResource(val name: String, val freqMHz: Double, val prefix: String = "soc/") 6 | { 7 | val device = new DeviceSnippet { 8 | def describe() = 9 | Description(prefix + name, Map( 10 | "#clock-cells" -> Seq(ResourceInt(0)), 11 | "clock-frequency" -> Seq(ResourceInt(freqMHz * 1000000)), 12 | "clock-output-names" -> Seq(ResourceString(name)), 13 | "compatible" -> Seq(ResourceString("fixed-clock")))) 14 | } 15 | 16 | def bind(dev: Device) { 17 | ResourceBinding { Resource(dev, "clocks").bind(ResourceReference(device.label)) } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/util/PSDTestMode.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config._ 7 | import freechips.rocketchip.diplomacy.{BundleBridgeEphemeralNode, ValName} 8 | 9 | case object IncludePSDTest extends Field[Boolean](false) 10 | case object PSDTestModeBroadcastKey extends Field( 11 | BundleBridgeEphemeralNode[PSDTestMode]()(ValName("global_psd_test_mode")) 12 | ) 13 | 14 | class PSDTestMode extends Bundle { 15 | val test_mode = Bool() 16 | val test_mode_reset = Bool() 17 | // TODO: Clocks? 18 | } 19 | 20 | trait CanHavePSDTestModeIO { 21 | implicit val p: Parameters 22 | val psd = p(IncludePSDTest).option(new PSDTestMode().asInput) 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/Clone.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | import Chisel._ 6 | import chisel3.shim.CloneModule 7 | 8 | final class CloneLazyModule private (val base: LazyModule) 9 | { 10 | // Pay special attention to the .iParams and .oParams of the node, which 11 | // indicate the parameters a stand-in master must supply. 12 | def clone[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](node: NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO])(implicit valName: ValName) = 13 | new MixedTestNode(node, this) 14 | 15 | protected[diplomacy] lazy val io = CloneModule(base.module) 16 | } 17 | 18 | object CloneLazyModule 19 | { 20 | def apply(base: LazyModule) = new CloneLazyModule(base) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/resources/csrc/verilator.h: -------------------------------------------------------------------------------- 1 | #ifndef _ROCKET_VERILATOR_H 2 | #define _ROCKET_VERILATOR_H 3 | 4 | #include "verilated_vcd_c.h" 5 | #include 6 | #include 7 | 8 | extern bool verbose; 9 | extern bool done_reset; 10 | 11 | class VerilatedVcdFILE : public VerilatedVcdFile { 12 | public: 13 | VerilatedVcdFILE(FILE* file) : file(file) {} 14 | ~VerilatedVcdFILE() {} 15 | bool open(const std::string& name) override { 16 | // file should already be open 17 | return file != NULL; 18 | } 19 | void close() override { 20 | // file should be closed elsewhere 21 | } 22 | ssize_t write(const char* bufp, ssize_t len) override { 23 | return fwrite(bufp, 1, len, file); 24 | } 25 | private: 26 | FILE* file; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/main/scala/util/LatencyPipe.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | 7 | class LatencyPipe[T <: Data](typ: T, latency: Int) extends Module { 8 | val io = new Bundle { 9 | val in = Decoupled(typ).flip 10 | val out = Decoupled(typ) 11 | } 12 | 13 | def doN[T](n: Int, func: T => T, in: T): T = 14 | (0 until n).foldLeft(in)((last, _) => func(last)) 15 | 16 | io.out <> doN(latency, (last: DecoupledIO[T]) => Queue(last, 1, pipe=true), io.in) 17 | } 18 | 19 | object LatencyPipe { 20 | def apply[T <: Data](in: DecoupledIO[T], latency: Int): DecoupledIO[T] = { 21 | val pipe = Module(new LatencyPipe(in.bits, latency)) 22 | pipe.io.in <> in 23 | pipe.io.out 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/vsrc/ClockDivider2.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes a Clock Divider by 2. 4 | * The output clock is phase-aligned to the input clock. 5 | * If you use this in synthesis, make sure your sdc 6 | * declares that you want it to do the same. 7 | * 8 | * Because Chisel does not support 9 | * blocking assignments, it is impossible 10 | * to create a deterministic divided clock. 11 | * 12 | * @param clk_out Divided Clock 13 | * @param clk_in Clock Input 14 | * 15 | */ 16 | 17 | module ClockDivider2 (output reg clk_out, input clk_in); 18 | 19 | initial clk_out = 1'b0; 20 | always @(posedge clk_in) begin 21 | clk_out = ~clk_out; // Must use =, NOT <= 22 | end 23 | 24 | endmodule // ClockDivider2 25 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/CustomISAExtensions.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | 6 | import scala.collection.mutable 7 | 8 | trait OMCustomExtensionSpecification{ 9 | def name: String 10 | def version: String 11 | def _types: Seq[String] = Seq("OMCustomExtensionSpecification", "OMSpecification") 12 | } 13 | 14 | case class Xsifivecflushdlone( 15 | full: Boolean = true, 16 | line: Boolean = true, 17 | version: String = "0.1", 18 | name: String = "Cache Flush/Power Down Instructions custom extension specification", 19 | override val _types: Seq[String] = Seq("OMXsifivecflushdlone", "OMCustomExtensionSpecification", "OMSpecification") 20 | ) extends OMCustomExtensionSpecification 21 | -------------------------------------------------------------------------------- /src/main/scala/prci/IOHelper.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | package freechips.rocketchip.prci 4 | 5 | import Chisel._ 6 | import chisel3.experimental.IO 7 | import freechips.rocketchip.diplomacy._ 8 | 9 | object IOHelper { 10 | 11 | def forNonSynchronous[T <: Data](gen: => T, xs: Seq[ClockCrossingType], prefix: String): Seq[Option[ModuleValue[T]]] = { 12 | xs.zipWithIndex.map { case (x, i) => forNonSynchronous(gen, x, prefix + s"_$i") } 13 | } 14 | 15 | def forNonSynchronous[T <: Data](gen: => T, x: ClockCrossingType, name: String): Option[ModuleValue[T]] = { 16 | x match { 17 | case SynchronousCrossing(_) => None 18 | case _ => Some(InModuleBody(IO(gen.asInput).suggestName(name))) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/prci/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import freechips.rocketchip.diplomacy._ 6 | 7 | package object prci 8 | { 9 | type ClockInwardNode = InwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] 10 | type ClockOutwardNode = OutwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] 11 | type ClockNode = NodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle, ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] 12 | def asyncMux[T](xType: ClockCrossingType, async: T, notasync: T): T = xType match { 13 | case _: AsynchronousCrossing => async 14 | case _ => notasync 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMRegFieldWrType.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | /* The following enum names come from IP-XACT */ 6 | sealed trait OMRegFieldWrType extends OMEnum 7 | case object RFWT_ONE_TO_CLEAR extends OMRegFieldWrType 8 | case object RFWT_ONE_TO_SET extends OMRegFieldWrType 9 | case object RFWT_ONE_TO_TOGGLE extends OMRegFieldWrType 10 | case object RFWT_ZERO_TO_CLEAR extends OMRegFieldWrType 11 | case object RFWT_ZERO_TO_SET extends OMRegFieldWrType 12 | case object RFWT_ZERO_TO_TOGGLE extends OMRegFieldWrType 13 | case object RFWT_CLEAR extends OMRegFieldWrType 14 | case object RFWT_SET extends OMRegFieldWrType 15 | case object RFWT_MODIFY extends OMRegFieldWrType 16 | 17 | -------------------------------------------------------------------------------- /src/main/scala/stage/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import firrtl.AnnotationSeq 6 | import firrtl.options.OptionsView 7 | 8 | package object stage { 9 | 10 | implicit object RocketChipOptionsView extends OptionsView[RocketChipOptions] { 11 | 12 | def view(annotations: AnnotationSeq): RocketChipOptions = annotations 13 | .collect { case a: RocketChipOption => a } 14 | .foldLeft(new RocketChipOptions()){ (c, x) => 15 | x match { 16 | case TopModuleAnnotation(a) => c.copy(topModule = Some(a)) 17 | case ConfigsAnnotation(a) => c.copy(configNames = Some(a)) 18 | case OutputBaseNameAnnotation(a) => c.copy(outputBaseName = Some(a)) 19 | } 20 | } 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/util/GenericParameterizedBundle.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | 7 | abstract class GenericParameterizedBundle[+T <: Object](val params: T) extends Bundle 8 | { 9 | override def cloneType = { 10 | try { 11 | this.getClass.getConstructors.head.newInstance(params).asInstanceOf[this.type] 12 | } catch { 13 | case e: java.lang.IllegalArgumentException => 14 | throw new Exception("Unable to use GenericParameterizedBundle.cloneType on " + 15 | this.getClass + ", probably because " + this.getClass + 16 | "() takes more than one argument. Consider overriding " + 17 | "cloneType() on " + this.getClass, e) 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/scala/devices/debug/DebugRomContents.scala: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by 'make publish' in debug/ directory. 2 | 3 | package freechips.rocketchip.devices.debug 4 | 5 | object DebugRomContents { 6 | 7 | def apply() : Array[Byte] = { Array ( 8 | 0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x80, 0x03, 0x6f, 0x00, 0x40, 0x04, 9 | 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, 10 | 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x34, 0x00, 11 | 0xe3, 0x08, 0x04, 0xfe, 0x13, 0x74, 0x14, 0x00, 0x63, 0x08, 0x04, 0x00, 12 | 0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, 13 | 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 14 | 0x73, 0x00, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00 15 | ).map(_.toByte) } 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/main/scala/amba/axis/Buffer.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axis 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | import freechips.rocketchip.config._ 8 | import freechips.rocketchip.util._ 9 | import freechips.rocketchip.diplomacy._ 10 | import freechips.rocketchip.tilelink._ 11 | 12 | class AXISBuffer(val params: BufferParams)(implicit p: Parameters) extends LazyModule 13 | { 14 | val node = AXISAdapterNode() 15 | lazy val module = new LazyModuleImp(this) { 16 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 17 | out :<>: params.irrevocable(in) 18 | } 19 | } 20 | } 21 | 22 | object AXISBuffer 23 | { 24 | def apply(params: BufferParams = BufferParams.default)(implicit p: Parameters) = { 25 | val buffer = LazyModule(new AXISBuffer(params)) 26 | buffer.node 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMPMP.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | import freechips.rocketchip.rocket.RocketCoreParams 6 | 7 | case class OMPMP( 8 | specifications: Seq[OMSpecification], 9 | nRegions: Int, 10 | granularity: Int, 11 | _types: Seq[String] = Seq("OMPMP", "OMComponent", "OMCompoundType") 12 | ) extends OMComponent 13 | 14 | object OMPMP { 15 | def pmp(coreParams: RocketCoreParams): Option[OMPMP] = { 16 | if (coreParams.pmpGranularity > 0 || coreParams.nPMPs > 0) { 17 | Some(OMPMP( 18 | specifications = List[OMSpecification](PrivilegedArchitectureExtensions.specVersion(MachineLevelISA, "1.10")), 19 | nRegions = coreParams.nPMPs, 20 | granularity = coreParams.pmpGranularity 21 | )) 22 | } 23 | else { 24 | None 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/scala/regmapper/Annotation.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.regmapper 4 | 5 | import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform} 6 | import chisel3.RawModule 7 | import firrtl.annotations._ 8 | import firrtl.{CircuitForm, CircuitState, LowForm, Transform} 9 | 10 | case class RegFieldDescSer( 11 | byteOffset: String, 12 | bitOffset: Int, 13 | bitWidth: Int, 14 | name: String, 15 | resetValue: BigInt, 16 | accessType: String, 17 | wrType: String, 18 | rdAction: String, 19 | desc: String, 20 | group: String, 21 | groupDesc: String, 22 | volatile: Boolean = false, 23 | hasReset: Boolean = false, 24 | enumerations: Map[BigInt, (String, String)] = Map() 25 | ) 26 | 27 | case class RegistersSer( 28 | displayName: String, 29 | deviceName: String, 30 | baseAddress: BigInt, 31 | regFields: Seq[RegFieldDescSer] 32 | ) 33 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/RegisterRouter.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.interrupts 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.regmapper._ 8 | 9 | /** Mix this trait into a RegisterRouter to be able to attach its interrupt sources to an interrupt bus */ 10 | trait HasInterruptSources { this: RegisterRouter => 11 | def nInterrupts: Int 12 | protected val intnode = IntSourceNode(IntSourcePortSimple(num = nInterrupts, resources = Seq(Resource(device, "int")))) 13 | 14 | // Externally, this helper should be used to connect the interrupts to a bus 15 | val intXing: IntOutwardCrossingHelper = this.crossOut(intnode) 16 | 17 | // Internally, this wire should be used to drive interrupt values 18 | val interrupts: ModuleValue[Vec[Bool]] = InModuleBody { if (intnode.out.isEmpty) Vec(0, Bool()) else intnode.out(0)._1 } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/NullIntSource.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.interrupts 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | 9 | /** Useful for stubbing out parts of an interrupt interface where certain devices might be missing */ 10 | class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters) extends LazyModule 11 | { 12 | val intnode = IntSourceNode(IntSourcePortSimple(num, ports, sources)) 13 | 14 | lazy val module = new LazyModuleImp(this) { 15 | intnode.out.foreach { case (o, _) => o.foreach { _ := false.B } } 16 | } 17 | } 18 | 19 | object NullIntSource { 20 | def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntNode = { 21 | val null_int_source = LazyModule(new NullIntSource(num, ports, sources)) 22 | null_int_source.intnode 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /macros/src/main/scala/ValName.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.macros 4 | 5 | import scala.language.experimental.macros 6 | import scala.reflect.macros.blackbox.Context 7 | 8 | case class ValNameImpl(name: String) 9 | 10 | object ValNameImpl 11 | { 12 | implicit def materialize: ValNameImpl = macro detail 13 | def detail(c: Context): c.Expr[ValNameImpl] = { 14 | import c.universe._ 15 | def allOwners(s: c.Symbol): Seq[c.Symbol] = 16 | if (s == `NoSymbol`) Nil else s +: allOwners(s.owner) 17 | val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm) 18 | terms.filter(t => t.isVal || t.isLazy).map(_.name.toString).find(_(0) != '$').map { s => 19 | val trim = s.replaceAll("\\s", "") 20 | c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" } 21 | }.getOrElse(c.abort(c.enclosingPosition, "Not a valid application.")) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/util/HeterogeneousBag.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | import chisel3.Record 7 | import scala.collection.immutable.ListMap 8 | 9 | final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with collection.IndexedSeq[T] { 10 | def apply(x: Int) = elts(x) 11 | def length = elts.length 12 | 13 | val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, n) }:_*) 14 | override def cloneType: this.type = (new HeterogeneousBag(elts.map(_.chiselCloneType))).asInstanceOf[this.type] 15 | 16 | // IndexedSeq has its own hashCode/equals that we must not use 17 | override def hashCode: Int = super[Record].hashCode 18 | override def equals(that: Any): Boolean = super[Record].equals(that) 19 | } 20 | 21 | object HeterogeneousBag 22 | { 23 | def fromNode[D <: Data, E](elts: Seq[(D, E)]) = new HeterogeneousBag(elts.map(_._1.cloneType)) 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/devices/debug/APB.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.devices.debug 4 | import chisel3._ 5 | import chisel3.experimental._ 6 | import freechips.rocketchip.config._ 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.regmapper._ 9 | import freechips.rocketchip.amba.apb.{APBRegisterNode} 10 | 11 | case object APBDebugRegistersKey extends Field[Map[Int, Seq[RegField]]](Map()) 12 | 13 | object APBDebugConsts { 14 | def apbDebugRegBase = 0xF00 15 | def apbDebugRegSize = 0x100 16 | } 17 | 18 | class APBDebugRegisters()(implicit p: Parameters) extends LazyModule { 19 | 20 | val node = APBRegisterNode( 21 | address = AddressSet(base=APBDebugConsts.apbDebugRegBase, mask=APBDebugConsts.apbDebugRegSize-1), 22 | beatBytes = 4, 23 | executable = false 24 | ) 25 | 26 | lazy val module = new LazyModuleImp(this){ 27 | node.regmap(p(APBDebugRegistersKey).toList:_*) 28 | 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/scala/util/ROMGenerator.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | import scala.collection.mutable.{HashMap} 7 | 8 | case class ROMConfig(name: String, depth: Int, width: Int) 9 | 10 | class BlackBoxedROM(c: ROMConfig) extends BlackBox { 11 | val io = new Bundle { 12 | val clock = Clock(INPUT) 13 | val address = UInt(INPUT, log2Ceil(c.depth)) 14 | val oe = Bool(INPUT) 15 | val me = Bool(INPUT) 16 | val q = UInt(OUTPUT, c.width) 17 | } 18 | 19 | override def desiredName: String = c.name 20 | } 21 | 22 | object ROMGenerator { 23 | private var finalized = false 24 | private val roms = HashMap[BlackBoxedROM, ROMConfig]() 25 | def apply(c: ROMConfig): BlackBoxedROM = { 26 | require(!finalized) 27 | val m = Module(new BlackBoxedROM(c)) 28 | roms(m) = c 29 | m 30 | } 31 | def lookup(m: BlackBoxedROM): ROMConfig = { 32 | finalized = true 33 | roms(m) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/amba/ahb/Monitor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.ahb 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.config.Parameters 7 | 8 | case class AHBSlaveMonitorArgs(edge: AHBEdgeParameters) 9 | 10 | abstract class AHBSlaveMonitorBase(args: AHBSlaveMonitorArgs) extends Module 11 | { 12 | val io = IO(new Bundle { 13 | val in = Input(new AHBSlaveBundle(args.edge.bundle)) 14 | }) 15 | 16 | def legalize(bundle: AHBSlaveBundle, edge: AHBEdgeParameters, reset: Reset): Unit 17 | legalize(io.in, args.edge, reset) 18 | } 19 | 20 | 21 | case class AHBMasterMonitorArgs(edge: AHBEdgeParameters) 22 | 23 | abstract class AHBMasterMonitorBase(args: AHBMasterMonitorArgs) extends Module 24 | { 25 | val io = IO(new Bundle { 26 | val in = Input(new AHBMasterBundle(args.edge.bundle)) 27 | }) 28 | 29 | def legalize(bundle: AHBMasterBundle, edge: AHBEdgeParameters, reset: Reset): Unit 30 | legalize(io.in, args.edge, reset) 31 | } 32 | -------------------------------------------------------------------------------- /src/main/scala/amba/ahb/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object ahb 9 | { 10 | type AHBSlaveOutwardNode = OutwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBSlaveBundle] 11 | type AHBSlaveInwardNode = InwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBSlaveBundle] 12 | type AHBSlaveNode = SimpleNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBSlaveBundle] 13 | type AHBMasterOutwardNode = OutwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBMasterBundle] 14 | type AHBMasterInwardNode = InwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBMasterBundle] 15 | type AHBMasterNode = SimpleNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBMasterBundle] 16 | } 17 | -------------------------------------------------------------------------------- /vsim/Makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | # Makefile for Verilog simulation w/ VCS 3 | #----------------------------------------------------------------------- 4 | # Yunsup Lee (yunsup@cs.berkeley.edu) 5 | # 6 | # This makefile will build a rtl simulator and run various tests to 7 | # verify proper functionality. 8 | # 9 | 10 | default: all 11 | 12 | base_dir = $(abspath ..) 13 | generated_dir = $(abspath ./generated-src) 14 | mem_gen = $(VLSI_MEM_GEN) 15 | sim_dir = . 16 | output_dir = $(sim_dir)/output 17 | 18 | BACKEND ?= v 19 | TB ?= TestDriver 20 | 21 | include $(base_dir)/Makefrag 22 | include $(sim_dir)/Makefrag 23 | ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),) 24 | -include $(generated_dir)/$(long_name).d 25 | endif 26 | include $(base_dir)/vsim/Makefrag-verilog 27 | 28 | all: $(simv) 29 | debug: $(simv_debug) 30 | 31 | clean: 32 | rm -rf $(junk) simv* csrc *.key DVE* *.h *.a *.daidir $(generated_dir) 33 | 34 | .PHONY: default all debug clean 35 | -------------------------------------------------------------------------------- /src/main/resources/vsrc/ClockDivider3.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes a Clock Divider by 3. 4 | * The output clock is phase-aligned to the input clock. 5 | * Do NOT use this in synthesis; the duty cycle is 2:1. 6 | * 7 | * Because Chisel does not support 8 | * blocking assignments, it is impossible 9 | * to create a deterministic divided clock. 10 | * 11 | * @param clk_out Divided Clock 12 | * @param clk_in Clock Input 13 | * 14 | */ 15 | 16 | module ClockDivider3 (output reg clk_out, input clk_in); 17 | 18 | reg delay; 19 | 20 | initial begin 21 | clk_out = 1'b0; 22 | delay = 1'b0; 23 | end 24 | 25 | always @(posedge clk_in) begin 26 | if (clk_out == 1'b0) begin 27 | clk_out = 1'b1; 28 | delay <= 1'b0; 29 | end else if (delay == 1'b1) begin 30 | clk_out = 1'b0; 31 | delay <= 1'b0; 32 | end else begin 33 | delay <= 1'b1; 34 | end 35 | end 36 | 37 | endmodule // ClockDivider3 38 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/Xbar.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.interrupts 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | 9 | class IntXbar()(implicit p: Parameters) extends LazyModule 10 | { 11 | val intnode = IntNexusNode( 12 | sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, 13 | sourceFn = { seq => 14 | IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { 15 | case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o))) 16 | }.flatten) 17 | }) 18 | 19 | lazy val module = new LazyModuleImp(this) { 20 | val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten 21 | intnode.out.foreach { case (o, _) => o := cat } 22 | } 23 | } 24 | 25 | object IntXbar { 26 | def apply(implicit p: Parameters): IntNode = { 27 | val xbar = LazyModule(new IntXbar) 28 | xbar.intnode 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ci-tests/wake_scala_compilation: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -ex 3 | 4 | echo "Installing Wake" 5 | 6 | wget https://github.com/sifive/wake/releases/download/v0.15.1/ubuntu-16.04-wake_0.15.1-1_amd64.deb 7 | sudo dpkg -i ubuntu-16.04-wake_0.15.1-1_amd64.deb 8 | 9 | 10 | echo "Installing Protobuf" 11 | 12 | mkdir protoc 13 | cd protoc 14 | wget https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/protoc-3.7.1-linux-x86_64.zip 15 | unzip protoc-3.7.1-linux-x86_64.zip 16 | export PATH=$PATH:$PWD/bin 17 | cd .. 18 | 19 | 20 | echo "Installing Wit" 21 | 22 | git clone https://github.com/sifive/wit.git --branch v0.12.0 23 | export PATH=$PATH:$PWD/wit 24 | 25 | 26 | echo "Initialize Workspace" 27 | 28 | git config --global url."https://github.com/".insteadOf 'git@github.com:' 29 | wit --repo-path $PWD/.. init workspace -a rocket-chip 30 | cd workspace/ 31 | 32 | 33 | echo "Compile Scala" 34 | 35 | export WAKE_PATH=$PATH 36 | wake --init . 37 | wake --no-tty -j1 -dv 'compileScalaModule rocketchipScalaModule | getPathResult' 38 | cd .. 39 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/TransformAnnotations.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.stage.ChiselOutputFileAnnotation 6 | import firrtl.AnnotationSeq 7 | import firrtl.options.Viewer.view 8 | import firrtl.options.{Dependency, Phase, PreservesAll} 9 | import freechips.rocketchip.stage.RocketChipOptions 10 | import freechips.rocketchip.util.HasRocketChipStageUtils 11 | 12 | /** Transforms RocketChipAnnotations into those used by other stages */ 13 | class TransformAnnotations extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 14 | 15 | override val prerequisites = Seq(Dependency[Checks]) 16 | override val dependents = Seq(Dependency[chisel3.stage.phases.AddImplicitOutputFile]) 17 | 18 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 19 | /** Construct output file annotation for emission */ 20 | new ChiselOutputFileAnnotation(view[RocketChipOptions](annotations).longName.get) +: annotations 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object interrupts 9 | { 10 | type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]] 11 | type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]] 12 | type IntNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]] 13 | 14 | implicit class IntClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal { 15 | def crossIn (n: IntInwardNode) (implicit valName: ValName) = IntInwardCrossingHelper(valName.name, x, n) 16 | def crossOut(n: IntOutwardNode)(implicit valName: ValName) = IntOutwardCrossingHelper(valName.name, x, n) 17 | def cross(n: IntInwardNode) (implicit valName: ValName) = crossIn(n) 18 | def cross(n: IntOutwardNode)(implicit valName: ValName) = crossOut(n) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/RTC.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase} 7 | import freechips.rocketchip.devices.tilelink.CanHavePeripheryCLINT 8 | 9 | trait HasRTCModuleImp extends LazyModuleImp { 10 | val outer: BaseSubsystem with CanHavePeripheryCLINT 11 | private val pbusFreq = outer.p(PeripheryBusKey).dtsFrequency.get 12 | private val rtcFreq = outer.p(DTSTimebase) 13 | private val internalPeriod: BigInt = pbusFreq / rtcFreq 14 | 15 | // check whether pbusFreq >= rtcFreq 16 | require(internalPeriod > 0) 17 | // check wehther the integer division is within 5% of the real division 18 | require((pbusFreq - rtcFreq * internalPeriod) * 100 / pbusFreq <= 5) 19 | 20 | // Use the static period to toggle the RTC 21 | val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt) 22 | 23 | outer.clintOpt.foreach { clint => 24 | clint.module.io.rtcTick := int_rtc_tick 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMPerformanceMonitor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | import freechips.rocketchip.rocket.RocketCoreParams 6 | 7 | case class OMPerformanceMonitor( 8 | specifications: List[OMSpecification], 9 | hasBasicCounters: Boolean, 10 | nAdditionalCounters: Int, 11 | _types: Seq[String] = Seq("OMPerformanceMonitor", "OMComponent", "OMCompoundType") 12 | ) extends OMComponent 13 | 14 | object PerformanceMonitor { 15 | def perfmon(coreParams: RocketCoreParams): Option[OMPerformanceMonitor] = { 16 | if (coreParams.haveBasicCounters || coreParams.nPerfCounters > 0) { 17 | Some(OMPerformanceMonitor( 18 | specifications = List[OMSpecification](PrivilegedArchitectureExtensions.specVersion(MachineLevelISA, "1.10")), 19 | hasBasicCounters = coreParams.haveBasicCounters, 20 | nAdditionalCounters = coreParams.nPerfCounters 21 | )) 22 | } 23 | else { 24 | None 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/scala/jtag/JtagUtils.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.jtag for license details. 2 | 3 | package freechips.rocketchip.jtag 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | class JTAGIdcodeBundle extends Bundle { 9 | val version = UInt(4.W) 10 | val partNumber = UInt(16.W) 11 | val mfrId = UInt(11.W) 12 | val always1 = UInt(1.W) 13 | } 14 | 15 | object JtagIdcode { 16 | /** Generates a JTAG IDCODE as a 32-bit integer, using the format in 12.1.1d. 17 | */ 18 | def apply(version: Int, partNumber: Int, mfrId: Int): BigInt = { 19 | require(version < (1 << 4), "version field must be 4 bits at most") 20 | require(partNumber < (1 << 16), "part number must be 16 bits at most") 21 | require(mfrId < (1 << 11), "manufacturer identity must be 11 bits at most") 22 | BigInt(version) << 28 | BigInt(partNumber) << 12 | BigInt(mfrId) << 1 | 1 23 | } 24 | 25 | /** A dummy manufacturer ID, not to be used per 12.2.1b since bus masters may shift this out to 26 | * determine the end of a bus. 27 | */ 28 | def dummyMfrId: Int = 0x7f 29 | } 30 | -------------------------------------------------------------------------------- /src/main/scala/devices/tilelink/Deadlock.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.devices.tilelink 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | 9 | /** Adds a /dev/null slave that does not raise ready for any incoming traffic. 10 | * !!! WARNING: This device WILL cause your bus to deadlock for as long as you 11 | * continue to send traffic to it !!! 12 | */ 13 | class TLDeadlock(params: DevNullParams, beatBytes: Int = 4)(implicit p: Parameters) 14 | extends DevNullDevice(params, minLatency = 1, // technically not true but we don't want to add extra logic to handle minLatency = 0 15 | beatBytes, new SimpleDevice("deadlock-device", Seq("sifive,deadlock0"))) 16 | { 17 | lazy val module = new LazyModuleImp(this) { 18 | val (in, _) = node.in(0) 19 | in.a.ready := Bool(false) 20 | in.b.valid := Bool(false) 21 | in.c.ready := Bool(false) 22 | in.d.valid := Bool(false) 23 | in.e.ready := Bool(false) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/amba/axi4/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object axi4 9 | { 10 | type AXI4Node = SimpleNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle] 11 | type AXI4OutwardNode = OutwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle] 12 | type AXI4InwardNode = InwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle] 13 | 14 | implicit class AXI4ClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal { 15 | def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardCrossingHelper(valName.name, x, n) 16 | def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardCrossingHelper(valName.name, x, n) 17 | def cross(n: AXI4InwardNode) (implicit valName: ValName) = crossIn(n) 18 | def cross(n: AXI4OutwardNode)(implicit valName: ValName) = crossOut(n) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/system/TestHarness.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.system 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.devices.debug.Debug 8 | import freechips.rocketchip.diplomacy.LazyModule 9 | import freechips.rocketchip.util.AsyncResetReg 10 | 11 | class TestHarness()(implicit p: Parameters) extends Module { 12 | val io = IO(new Bundle { 13 | val success = Output(Bool()) 14 | }) 15 | 16 | val ldut = LazyModule(new ExampleRocketSystem) 17 | val dut = Module(ldut.module) 18 | 19 | // Allow the debug ndreset to reset the dut, but not until the initial reset has completed 20 | dut.reset := (reset.asBool | dut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool 21 | 22 | dut.dontTouchPorts() 23 | dut.tieOffInterrupts() 24 | SimAXIMem.connectMem(ldut) 25 | SimAXIMem.connectMMIO(ldut) 26 | ldut.l2_frontend_bus_axi4.foreach(_.tieoff) 27 | Debug.connectDebug(dut.debug, dut.resetctrl, dut.psd, clock, reset.asBool, io.success) 28 | } 29 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/GenerateArtefacts.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.stage.phases.Elaborate 6 | import firrtl.AnnotationSeq 7 | import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions} 8 | import firrtl.options.Viewer.view 9 | import freechips.rocketchip.stage.RocketChipOptions 10 | import freechips.rocketchip.util.{ElaborationArtefacts, HasRocketChipStageUtils} 11 | 12 | /** Writes [[ElaborationArtefacts]] into files */ 13 | class GenerateArtefacts extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 14 | 15 | override val prerequisites = Seq(Dependency[Checks], Dependency[Elaborate]) 16 | 17 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 18 | val targetDir = view[StageOptions](annotations).targetDir 19 | 20 | ElaborationArtefacts.files.foreach { case (extension, contents) => 21 | writeOutputFile(targetDir, s"${view[RocketChipOptions](annotations).longName.get}.${extension}", contents ()) 22 | } 23 | 24 | annotations 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/scala/system/ExampleRocketSystem.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.system 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.subsystem._ 9 | import freechips.rocketchip.prci.SimpleClockGroupSource 10 | import freechips.rocketchip.devices.tilelink._ 11 | import freechips.rocketchip.util.DontTouch 12 | 13 | /** Example Top with periphery devices and ports, and a Rocket subsystem */ 14 | class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem 15 | with HasAsyncExtInterrupts 16 | with CanHaveMasterAXI4MemPort 17 | with CanHaveMasterAXI4MMIOPort 18 | with CanHaveSlaveAXI4Port 19 | with HasPeripheryBootROM { 20 | override lazy val module = new ExampleRocketSystemModuleImp(this) 21 | } 22 | 23 | class ExampleRocketSystemModuleImp[+L <: ExampleRocketSystem](_outer: L) extends RocketSubsystemModuleImp(_outer) 24 | with HasRTCModuleImp 25 | with HasExtInterruptsModuleImp 26 | with HasPeripheryBootROMModuleImp 27 | with DontTouch 28 | -------------------------------------------------------------------------------- /scripts/debug_rom/Makefile: -------------------------------------------------------------------------------- 1 | # See LICENSE.SiFive for license details 2 | # Recursive make is bad, but in this case we're cross compiling which is a 3 | # pretty unusual use case. 4 | 5 | CC = $(RISCV)/bin/riscv64-unknown-elf-gcc 6 | OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy 7 | 8 | COMPILE = $(CC) -nostdlib -nostartfiles -I$(RISCV)/include/ -Tlink.ld 9 | 10 | ELFS = debug_rom 11 | DEPS = debug_rom.S link.ld 12 | 13 | all: $(patsubst %,%.h,$(ELFS)) 14 | 15 | publish: debug_rom.scala 16 | mv $< ../../src/main/scala/devices/debug/DebugRomContents.scala 17 | 18 | %.scala: %.raw 19 | xxd -i $^ | sed -e "s/^unsigned char debug_rom_raw\[\] = {/\/\/ This file was auto-generated by 'make publish' in debug\/ directory.\n\npackage freechips.rocketchip.devices.debug\n\nobject DebugRomContents {\n\n def apply() : Array[Byte] = { Array (/" \ 20 | -e "s/};/ ).map(_.toByte) }\n\n}/" \ 21 | -e "s/^unsigned int debug_rom_raw_len.*//" > $@ 22 | 23 | 24 | %.raw: % 25 | $(OBJCOPY) -O binary --only-section .text $^ $@ 26 | 27 | debug_rom: $(DEPS) 28 | $(COMPILE) -o $@ $^ 29 | 30 | clean: 31 | rm -f $(ELFS) debug_rom*.raw debug_rom*.h 32 | -------------------------------------------------------------------------------- /src/main/scala/util/ClockGate.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.config.{Field, Parameters} 7 | 8 | case object ClockGateImpl extends Field[() => ClockGate](() => new EICG_wrapper) 9 | 10 | abstract class ClockGate extends BlackBox { 11 | val io = IO(new Bundle{ 12 | val in = Input(Clock()) 13 | val test_en = Input(Bool()) 14 | val en = Input(Bool()) 15 | val out = Output(Clock()) 16 | }) 17 | } 18 | 19 | object ClockGate { 20 | def apply[T <: ClockGate]( 21 | in: Clock, 22 | en: Bool, 23 | name: Option[String] = None)(implicit p: Parameters): Clock = { 24 | val cg = Module(p(ClockGateImpl)()) 25 | name.foreach(cg.suggestName(_)) 26 | cg.io.in := in 27 | cg.io.test_en := false.B 28 | cg.io.en := en 29 | cg.io.out 30 | } 31 | 32 | def apply[T <: ClockGate]( 33 | in: Clock, 34 | en: Bool, 35 | name: String)(implicit p: Parameters): Clock = 36 | apply(in, en, Some(name)) 37 | } 38 | 39 | // behavioral model of Integrated Clock Gating cell 40 | class EICG_wrapper extends ClockGate 41 | -------------------------------------------------------------------------------- /wit-manifest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "commit": "22ebeb54301ca85fa087180596d21fa56335fdbc", 4 | "name": "hardfloat", 5 | "source": "git@github.com:ucb-bar/berkeley-hardfloat.git" 6 | }, 7 | { 8 | "commit": "dd3f744d72c45a606c4ed76da48fa44c1ee4de15", 9 | "name": "api-chisel3-sifive", 10 | "source": "git@github.com:sifive/api-chisel3-sifive.git" 11 | }, 12 | { 13 | "commit": "21ea734d809395962a8d3195a76377f6e44308f3", 14 | "name": "chisel3", 15 | "source": "git@github.com:freechipsproject/chisel3.git" 16 | }, 17 | { 18 | "commit": "7c6f58d986e67b3d0662a4cd6654a68f9cc52cf9", 19 | "name": "firrtl", 20 | "source": "git@github.com:freechipsproject/firrtl.git" 21 | }, 22 | { 23 | "commit": "77195ab12aefc373ca688e0a9c4d710c13191341", 24 | "name": "torture", 25 | "source": "git@github.com:ucb-bar/riscv-torture.git" 26 | }, 27 | { 28 | "commit": "d619ca850846d2ec36da64bf8a28e7d9a3d9ed1b", 29 | "name": "api-config-chipsalliance", 30 | "source": "git@github.com:chipsalliance/api-config-chipsalliance.git" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMPLIC.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | sealed trait OMPrivilegeMode extends OMEnum 6 | case object OMMachineMode extends OMPrivilegeMode 7 | case object OMSupervisorMode extends OMPrivilegeMode 8 | case object OMUserMode extends OMPrivilegeMode 9 | 10 | object OMModes { 11 | def getModes(hasSupervisorMode: Boolean): Seq[OMPrivilegeMode] = { 12 | hasSupervisorMode match { 13 | case false => Seq(OMMachineMode) 14 | case true => Seq(OMMachineMode, OMSupervisorMode) 15 | } 16 | } 17 | } 18 | 19 | case class OMInterruptTarget( 20 | hartId: Int, 21 | modes: Seq[OMPrivilegeMode], 22 | _types: Seq[String] = Seq("OMInterruptTarget", "OMCompoundType") 23 | ) extends OMCompoundType 24 | 25 | case class OMPLIC( 26 | memoryRegions: Seq[OMMemoryRegion], 27 | interrupts: Seq[OMInterrupt], 28 | specifications: Seq[OMSpecification], 29 | latency: Int, 30 | nPriorities: Int, 31 | nInterrupts: Int, 32 | targets: Seq[OMInterruptTarget], 33 | _types: Seq[String] = Seq("OMPLIC", "OMDevice", "OMComponent", "OMCompoundType") 34 | ) extends OMDevice 35 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMCoreComplex.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | sealed trait OMCoreComplexResetType extends OMEnum 6 | case object CoreComplexResetTypeUnspecified extends OMCoreComplexResetType 7 | case object CoreComplexResetTypeSingleSynchronous extends OMCoreComplexResetType 8 | case object CoreComplexResetTypeSingleAsynchronous extends OMCoreComplexResetType 9 | case object CoreComplexResetTypeSingleAsynchronousFull extends OMCoreComplexResetType 10 | case object CoreComplexResetTypeSeparateCoreAndUncoreSynchronous extends OMCoreComplexResetType 11 | case object CoreComplexResetTypeSeparateCoreAndUncoreAsynchronous extends OMCoreComplexResetType 12 | case object CoreComplexResetTypeSeparateCoreAndUncoreAsynchronousFull extends OMCoreComplexResetType 13 | case object CoreComplexResetTypeSeparateGPRAsynchronousFull extends OMCoreComplexResetType 14 | 15 | case class OMCoreComplex( 16 | components: Seq[OMComponent], 17 | documentationName: String, 18 | resetType: Option[OMCoreComplexResetType], 19 | _types: Seq[String] = Seq("OMCoreComplex", "OMComponent", "OMCompoundType") 20 | ) extends OMComponent 21 | -------------------------------------------------------------------------------- /src/main/scala/util/CoreMonitor.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | // See LICENSE.SiFive for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import chisel3._ 7 | 8 | // this bundle is used to expose some internal core signals 9 | // to verification monitors which sample instruction commits 10 | class CoreMonitorBundle(val xLen: Int) extends Bundle with Clocked { 11 | val excpt = Bool() 12 | val priv_mode = UInt(width = 3.W) 13 | val hartid = UInt(width = xLen.W) 14 | val timer = UInt(width = 32.W) 15 | val valid = Bool() 16 | val pc = UInt(width = xLen.W) 17 | val wrdst = UInt(width = 5.W) 18 | val wrdata = UInt(width = xLen.W) 19 | val wrenx = Bool() 20 | val wrenf = Bool() 21 | @deprecated("replace wren with wrenx or wrenf to specify integer or floating point","") 22 | def wren: Bool = wrenx || wrenf 23 | val rd0src = UInt(width = 5.W) 24 | val rd0val = UInt(width = xLen.W) 25 | val rd1src = UInt(width = 5.W) 26 | val rd1val = UInt(width = xLen.W) 27 | val inst = UInt(width = 32.W) 28 | } 29 | 30 | // mark a module that has cores with CoreMonitorBundles 31 | trait HasCoreMonitorBundles { 32 | def coreMonitorBundles: List[CoreMonitorBundle] 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/amba/axi4/Protocol.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axi4 4 | 5 | import Chisel._ 6 | import chisel3.util.{Irrevocable, IrrevocableIO} 7 | 8 | object AXI4Parameters 9 | { 10 | // These are all fixed by the AXI4 standard: 11 | val lenBits = 8 12 | val sizeBits = 3 13 | val burstBits = 2 14 | val lockBits = 1 15 | val cacheBits = 4 16 | val protBits = 3 17 | val qosBits = 4 18 | val respBits = 2 19 | 20 | def CACHE_RALLOCATE = UInt(8, width = cacheBits) 21 | def CACHE_WALLOCATE = UInt(4, width = cacheBits) 22 | def CACHE_MODIFIABLE = UInt(2, width = cacheBits) 23 | def CACHE_BUFFERABLE = UInt(1, width = cacheBits) 24 | 25 | def PROT_PRIVILEDGED = UInt(1, width = protBits) 26 | def PROT_INSECURE = UInt(2, width = protBits) 27 | def PROT_INSTRUCTION = UInt(4, width = protBits) 28 | 29 | def BURST_FIXED = UInt(0, width = burstBits) 30 | def BURST_INCR = UInt(1, width = burstBits) 31 | def BURST_WRAP = UInt(2, width = burstBits) 32 | 33 | def RESP_OKAY = UInt(0, width = respBits) 34 | def RESP_EXOKAY = UInt(1, width = respBits) 35 | def RESP_SLVERR = UInt(2, width = respBits) 36 | def RESP_DECERR = UInt(3, width = respBits) 37 | } 38 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/GenerateROMs.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.stage.ChiselCircuitAnnotation 6 | import chisel3.stage.phases.{Convert, Elaborate} 7 | import firrtl.AnnotationSeq 8 | import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions} 9 | import firrtl.options.Viewer.view 10 | import freechips.rocketchip.stage.RocketChipOptions 11 | import freechips.rocketchip.util.HasRocketChipStageUtils 12 | 13 | /** Dumps ROM information into a file */ 14 | class GenerateROMs extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 15 | 16 | override val prerequisites = Seq(Dependency[Checks], Dependency[Elaborate]) 17 | override val dependents = Seq(Dependency[Convert]) 18 | 19 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 20 | val targetDir = view[StageOptions](annotations).targetDir 21 | val fileName = s"${view[RocketChipOptions](annotations).longName.get}.rom.conf" 22 | 23 | annotations.flatMap { 24 | case a: ChiselCircuitAnnotation => 25 | writeOutputFile(targetDir, fileName, enumerateROMs(a.circuit)) 26 | Some(a) 27 | case a => Some(a) 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/scala/unittest/TestGenerator.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.unittest 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config._ 7 | import freechips.rocketchip.diplomacy._ 8 | 9 | abstract class LazyUnitTest(implicit p: Parameters) extends LazyModule 10 | { self => 11 | protected def finished: Bool 12 | 13 | lazy val module = new LazyModuleImp(this) { 14 | val finished = IO(Bool(OUTPUT)) 15 | finished := self.finished 16 | } 17 | } 18 | 19 | // FYI, you can call .finished on a Seq[LazyUnitTest] 20 | class TestGenerator(gen: LazyModule => Seq[LazyUnitTest]) 21 | { 22 | def apply(lm: LazyModule) = gen(lm) 23 | def ++ (other: TestGenerator) = new TestGenerator(gen = lm => gen(lm) ++ other(lm)) 24 | } 25 | 26 | object TestGenerator 27 | { 28 | def apply(matcher: PartialFunction[LazyModule, Seq[LazyUnitTest]]): TestGenerator = 29 | new TestGenerator(gen = matcher.lift(_).getOrElse(Nil)) 30 | def recurse(other: TestGenerator): TestGenerator = { 31 | def helper(lm: LazyModule, tail: Seq[LazyUnitTest]): Seq[LazyUnitTest] = 32 | lm.getChildren.foldLeft(other(lm) ++ tail) { case (tail, child) => helper(child, tail) } 33 | new TestGenerator(gen = helper(_, Nil)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/FrontBus.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import freechips.rocketchip.config.{Parameters} 6 | import freechips.rocketchip.devices.tilelink._ 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.tilelink._ 9 | import freechips.rocketchip.util.{Location} 10 | 11 | case class FrontBusParams( 12 | beatBytes: Int, 13 | blockBytes: Int, 14 | dtsFrequency: Option[BigInt] = None, 15 | zeroDevice: Option[AddressSet] = None, 16 | errorDevice: Option[DevNullParams] = None) 17 | extends HasTLBusParams 18 | with HasBuiltInDeviceParams 19 | with TLBusWrapperInstantiationLike 20 | { 21 | def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): FrontBus = { 22 | val fbus = LazyModule(new FrontBus(this, loc.name)) 23 | fbus.suggestName(loc.name) 24 | context.tlBusWrapperLocationMap += (loc -> fbus) 25 | fbus 26 | } 27 | } 28 | 29 | class FrontBus(params: FrontBusParams, name: String = "front_bus")(implicit p: Parameters) 30 | extends TLBusWrapper(params, name) 31 | with HasTLXbarPhy { 32 | val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) 33 | val prefixNode = None 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/csrc/SimDTM.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | dtm_t* dtm; 8 | 9 | extern "C" int debug_tick 10 | ( 11 | unsigned char* debug_req_valid, 12 | unsigned char debug_req_ready, 13 | int* debug_req_bits_addr, 14 | int* debug_req_bits_op, 15 | int* debug_req_bits_data, 16 | unsigned char debug_resp_valid, 17 | unsigned char* debug_resp_ready, 18 | int debug_resp_bits_resp, 19 | int debug_resp_bits_data 20 | ) 21 | { 22 | if (!dtm) { 23 | s_vpi_vlog_info info; 24 | if (!vpi_get_vlog_info(&info)) 25 | abort(); 26 | dtm = new dtm_t(info.argc, info.argv); 27 | } 28 | 29 | dtm_t::resp resp_bits; 30 | resp_bits.resp = debug_resp_bits_resp; 31 | resp_bits.data = debug_resp_bits_data; 32 | 33 | dtm->tick 34 | ( 35 | debug_req_ready, 36 | debug_resp_valid, 37 | resp_bits 38 | ); 39 | 40 | *debug_resp_ready = dtm->resp_ready(); 41 | *debug_req_valid = dtm->req_valid(); 42 | *debug_req_bits_addr = dtm->req_bits().addr; 43 | *debug_req_bits_op = dtm->req_bits().op; 44 | *debug_req_bits_data = dtm->req_bits().data; 45 | 46 | return dtm->done() ? (dtm->exit_code() << 1 | 1) : 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/tilelink/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | package object tilelink 9 | { 10 | type TLInwardNode = InwardNodeHandle[TLMasterPortParameters, TLSlavePortParameters, TLEdgeIn, TLBundle] 11 | type TLOutwardNode = OutwardNodeHandle[TLMasterPortParameters, TLSlavePortParameters, TLEdgeOut, TLBundle] 12 | type TLNode = NodeHandle[TLMasterPortParameters, TLSlavePortParameters, TLEdgeIn, TLBundle, TLMasterPortParameters, TLSlavePortParameters, TLEdgeOut, TLBundle] 13 | type TLManagerParameters = TLSlaveParameters 14 | type TLManagerPortParameters = TLSlavePortParameters 15 | type TLClientParameters = TLMasterParameters 16 | type TLClientPortParameters = TLMasterPortParameters 17 | 18 | implicit class TLClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal { 19 | def crossIn (n: TLInwardNode) (implicit valName: ValName) = TLInwardCrossingHelper (valName.name, x, n) 20 | def crossOut(n: TLOutwardNode)(implicit valName: ValName) = TLOutwardCrossingHelper(valName.name, x, n) 21 | def cross(n: TLInwardNode) (implicit valName: ValName) = crossIn(n) 22 | def cross(n: TLOutwardNode)(implicit valName: ValName) = crossOut(n) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/util/CRC.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | 7 | object CRC 8 | { 9 | // A divisor of 0x1d5 is interpretted to be x^8 + x^7 + x^6 + x^4 + x^2 + 1 10 | // Let n be the highest term in the divisor; n=8 in 0x1d5. 11 | // Then, this function calculates c mod d, returning an n-bit UInt. 12 | // coefficient.width must be <= width 13 | def apply(divisor: BigInt, coefficient: UInt, width: Integer): UInt = { 14 | require (divisor > 0 && divisor.testBit(0)) 15 | require (width > 0) 16 | assert (coefficient >> width === UInt(0)) 17 | val n = log2Floor(divisor) 18 | val m = width 19 | if (m <= n) return coefficient 20 | 21 | // Initialize the reduction matrix 22 | val array = Array.tabulate(m) { BigInt(1) << _ } 23 | // Reduce the matrix of terms larger than n 24 | for { 25 | i <- (n until m).reverse 26 | j <- 0 to n 27 | if divisor.testBit(j) 28 | } array(i-(n-j)) ^= array(i) 29 | // Construct the circuit 30 | Cat(Seq.tabulate(n) { i => (UInt(array(i)) & coefficient).xorR } .reverse) 31 | } 32 | 33 | // Find more great CRC polynomials here: https://users.ece.cmu.edu/~koopman/crc/ 34 | val CRC_16F_4_2 = BigInt(0x1a2eb) // HD=4 for <32751 bits and HD=6 for <93 bits 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/util/Frequency.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import Chisel._ 7 | 8 | /** Given a list of (frequency, value) pairs, return a random value 9 | * according to the frequency distribution. The sum of the 10 | * frequencies in the distribution must be a power of two. 11 | */ 12 | object Frequency { 13 | def apply(dist : List[(Int, Bits)]) : Bits = { 14 | // Distribution must be non-empty 15 | require(dist.length > 0) 16 | 17 | // Require that the frequencies sum to a power of two 18 | val (freqs, vals) = dist.unzip 19 | val total = freqs.sum 20 | require(isPow2(total)) 21 | 22 | // First item in the distribution 23 | val (firstFreq, firstVal) = dist.head 24 | 25 | // Result wire 26 | val result = Wire(Bits(width = firstVal.getWidth)) 27 | result := UInt(0) 28 | 29 | // Random value 30 | val randVal = LCG(log2Up(total)) 31 | 32 | // Pick return value 33 | var count = firstFreq 34 | var select = when (randVal < UInt(firstFreq)) { result := firstVal } 35 | for (p <- dist.drop(1)) { 36 | count = count + p._1 37 | select = select.elsewhen(randVal < UInt(count)) { result := p._2 } 38 | } 39 | 40 | return result 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/main/scala/util/IDPool.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | class IDPool(numIds: Int) extends Module { 9 | require (numIds > 0) 10 | val idWidth = log2Up(numIds) 11 | 12 | val io = IO(new Bundle { 13 | val free = Flipped(Valid(UInt(idWidth.W))) 14 | val alloc = Irrevocable(UInt(idWidth.W)) 15 | }) 16 | 17 | // True indicates that the id is available 18 | val bitmap = RegInit(~0.U(numIds.W)) 19 | val select = RegInit(0.U(idWidth.W)) 20 | val valid = RegInit(true.B) 21 | 22 | io.alloc.valid := valid 23 | io.alloc.bits := select 24 | 25 | val taken = (io.alloc.ready << io.alloc.bits)(numIds-1, 0) 26 | val given = (io.free .valid << io.free .bits)(numIds-1, 0) 27 | val bitmap1 = (bitmap & ~taken) | given 28 | val select1 = OHToUInt(~(leftOR(bitmap1, numIds) << 1) & bitmap1, numIds) 29 | val valid1 = bitmap1.orR 30 | 31 | // Clock gate the bitmap 32 | when (io.alloc.ready || io.free.valid) { 33 | bitmap := bitmap1 34 | valid := valid1 35 | } 36 | 37 | // Make select irrevocable 38 | when (io.alloc.ready || (!io.alloc.valid && io.free.valid)) { 39 | select := select1 40 | } 41 | 42 | // No double freeing 43 | assert (!io.free.valid || !(bitmap & ~taken)(io.free.bits)) 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/util/Repeater.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3._ 6 | import chisel3.util.{Decoupled, DecoupledIO} 7 | 8 | // A Repeater passes its input to its output, unless repeat is asserted. 9 | // When repeat is asserted, the Repeater copies the input and repeats it next cycle. 10 | class Repeater[T <: Data](gen: T) extends Module 11 | { 12 | val io = IO( new Bundle { 13 | val repeat = Input(Bool()) 14 | val full = Output(Bool()) 15 | val enq = Flipped(Decoupled(gen.cloneType)) 16 | val deq = Decoupled(gen.cloneType) 17 | } ) 18 | 19 | val full = RegInit(false.B) 20 | val saved = Reg(gen.cloneType) 21 | 22 | // When !full, a repeater is pass-through 23 | io.deq.valid := io.enq.valid || full 24 | io.enq.ready := io.deq.ready && !full 25 | io.deq.bits := Mux(full, saved, io.enq.bits) 26 | io.full := full 27 | 28 | when (io.enq.fire() && io.repeat) { full := true.B; saved := io.enq.bits } 29 | when (io.deq.fire() && !io.repeat) { full := false.B } 30 | } 31 | 32 | object Repeater 33 | { 34 | def apply[T <: Data](enq: DecoupledIO[T], repeat: Bool): DecoupledIO[T] = { 35 | val repeater = Module(new Repeater(chiselTypeOf(enq.bits))) 36 | repeater.io.repeat := repeat 37 | repeater.io.enq <> enq 38 | repeater.io.deq 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/scala/prci/ClockDomain.scala: -------------------------------------------------------------------------------- 1 | package freechips.rocketchip.prci 2 | 3 | import chisel3._ 4 | import freechips.rocketchip.config.Parameters 5 | import freechips.rocketchip.diplomacy._ 6 | 7 | abstract class ClockDomain(implicit p: Parameters) extends LazyModule 8 | with LazyScope 9 | with HasClockDomainCrossing 10 | { 11 | def clockBundle: ClockBundle 12 | 13 | lazy val module = new LazyRawModuleImp(this) { 14 | childClock := clockBundle.clock 15 | childReset := clockBundle.reset 16 | 17 | // these are just for backwards compatibility with external devices 18 | // that were manually wiring themselves to the domain's clock/reset input: 19 | val clock = IO(Output(chiselTypeOf(clockBundle.clock))) 20 | val reset = IO(Output(chiselTypeOf(clockBundle.reset))) 21 | clock := clockBundle.clock 22 | reset := clockBundle.reset 23 | } 24 | } 25 | 26 | class ClockSinkDomain(take: Option[ClockParameters] = None)(implicit p: Parameters) extends ClockDomain 27 | { 28 | val clockNode = ClockSinkNode(Seq(ClockSinkParameters(take = take))) 29 | def clockBundle = clockNode.in.head._1 30 | } 31 | 32 | class ClockSourceDomain(give: Option[ClockParameters] = None)(implicit p: Parameters) extends ClockDomain 33 | { 34 | val clockNode = ClockSourceNode(Seq(ClockSourceParameters(give = give))) 35 | def clockBundle = clockNode.out.head._1 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/amba/ahb/AHBLite.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.ahb 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.tilelink._ 9 | 10 | class AHBLite()(implicit p: Parameters) extends LazyModule { 11 | val node = AHBMasterAdapterNode( 12 | masterFn = { mp => mp }, 13 | slaveFn = { sp => sp.copy(lite = false) }) 14 | 15 | lazy val module = new LazyModuleImp(this) { 16 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 17 | require (edgeOut.slave.lite) // or else this adapter is pointless 18 | 19 | out.hmastlock.get := in.hlock.get 20 | in.hgrant.get := Bool(true) 21 | in.hresp := out.hresp // zero-extended 22 | 23 | in.hready := out.hready 24 | out.htrans := in.htrans 25 | out.hsize := in.hsize 26 | out.hburst := in.hburst 27 | out.hwrite := in.hwrite 28 | out.hprot := in.hprot 29 | out.haddr := in.haddr 30 | out.hwdata := in.hwdata 31 | out.hauser :<> in.hauser 32 | in.hduser :<> out.hduser 33 | in.hrdata := out.hrdata 34 | } 35 | } 36 | } 37 | 38 | object AHBLite { 39 | def apply()(implicit p: Parameters) = { 40 | val ahblite = LazyModule(new AHBLite) 41 | ahblite.node 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.stage.phases.Elaborate 6 | import firrtl.AnnotationSeq 7 | import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions} 8 | import firrtl.options.Viewer.view 9 | import freechips.rocketchip.stage.RocketChipOptions 10 | import freechips.rocketchip.system.TestGeneration 11 | import freechips.rocketchip.util.HasRocketChipStageUtils 12 | 13 | /** Generates a make script to run tests in [[RocketTestSuiteAnnotation]]. */ 14 | class GenerateTestSuiteMakefrags extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 15 | 16 | override val prerequisites = Seq(Dependency[Checks], Dependency[Elaborate]) 17 | 18 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 19 | val targetDir = view[StageOptions](annotations).targetDir 20 | val fileName = s"${view[RocketChipOptions](annotations).longName.get}.d" 21 | 22 | annotations.flatMap { 23 | case a: RocketTestSuiteAnnotation => 24 | val makefrag = a.tests.groupBy(_.kind) 25 | .map { case (kind, s) => TestGeneration.gen(kind, s) } 26 | .mkString("\n") 27 | writeOutputFile(targetDir, fileName, makefrag) 28 | Some(a) 29 | case a => Some(a) 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMMulDiv.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | import freechips.rocketchip.rocket.MulDivParams 6 | 7 | case class OMMulDiv( 8 | divideBitsPerCycle: Int, 9 | divideMaxLatency: Int, 10 | divideMinLatency: Int, 11 | multiplyBitsPerCycle: Int, 12 | multiplyFullyPipelined: Boolean, 13 | multiplyMaxLatency: Int, 14 | multiplyMinLatency: Int, 15 | _types: Seq[String] = Seq("OMMulDiv", "OMComponent", "OMCompoundType") 16 | ) extends OMComponent 17 | 18 | 19 | object OMMulDiv { 20 | def makeOMI(md: MulDivParams, xLen: Int): OMMulDiv = { 21 | val mulMinLatency = 22 | if (md.mulUnroll > 0) { 23 | if (md.mulEarlyOut) { 2 } 24 | else { xLen/md.mulUnroll } 25 | } 26 | else { xLen } 27 | 28 | val divMinLatency = 29 | if (md.divUnroll > 0) { 30 | if (md.divEarlyOut) { 3 } 31 | else { 2 } 32 | } 33 | else { xLen } 34 | 35 | OMMulDiv( 36 | divideBitsPerCycle = md.divUnroll, 37 | divideMaxLatency = xLen / md.divUnroll, 38 | divideMinLatency = divMinLatency, 39 | multiplyBitsPerCycle = md.mulUnroll, 40 | multiplyFullyPipelined = md.mulUnroll == xLen, 41 | multiplyMaxLatency = xLen / md.mulUnroll, 42 | multiplyMinLatency = mulMinLatency 43 | ) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/scala/util/Broadcaster.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import Chisel._ 7 | 8 | /** Takes in data on one decoupled interface and broadcasts it 9 | * to N decoupled output interfaces. 10 | */ 11 | class Broadcaster[T <: Data](typ: T, n: Int) extends Module { 12 | val io = new Bundle { 13 | val in = Decoupled(typ).flip 14 | val out = Vec(n, Decoupled(typ)) 15 | } 16 | 17 | require (n > 0) 18 | 19 | if (n == 1) { 20 | io.out.head <> io.in 21 | } else { 22 | val idx = Reg(init = UInt(0, log2Up(n))) 23 | val save = Reg(typ) 24 | 25 | io.out.head.valid := idx === UInt(0) && io.in.valid 26 | io.out.head.bits := io.in.bits 27 | for (i <- 1 until n) { 28 | io.out(i).valid := idx === UInt(i) 29 | io.out(i).bits := save 30 | } 31 | io.in.ready := io.out.head.ready && idx === UInt(0) 32 | 33 | when (io.in.fire()) { save := io.in.bits } 34 | 35 | when (io.out(idx).fire()) { 36 | when (idx === UInt(n - 1)) { idx := UInt(0) } 37 | .otherwise { idx := idx + UInt(1) } 38 | } 39 | } 40 | } 41 | 42 | object Broadcaster { 43 | def apply[T <: Data](in: DecoupledIO[T], n: Int): Vec[DecoupledIO[T]] = { 44 | val split = Module(new Broadcaster(in.bits, n)) 45 | split.io.in <> in 46 | split.io.out 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/OMRocketCore.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | import freechips.rocketchip.rocket.BTBParams 6 | 7 | case class OMRocketBranchPredictor( 8 | nBtbEntries: Int, 9 | nBhtEntries: Int, 10 | nRasEntries: Int, 11 | _types: Seq[String] = Seq("OMRocketBranchPredictor", "OMBranchPredictor", "OMComponent", "OMCompoundType") 12 | ) extends OMBranchPredictor 13 | 14 | case class OMRocketCore( 15 | isa: OMISA, 16 | mulDiv: Option[OMMulDiv], 17 | fpu: Option[OMFPU], 18 | performanceMonitor: Option[OMPerformanceMonitor], 19 | pmp: Option[OMPMP], 20 | documentationName: String, 21 | hartIds: Seq[Int], 22 | hasVectoredInterrupts: Boolean, 23 | interruptLatency: Int, 24 | nLocalInterrupts: Int, 25 | nBreakpoints: Int, 26 | branchPredictor: Option[OMRocketBranchPredictor], 27 | dcache: Option[OMDCache], 28 | icache: Option[OMICache], 29 | busErrorUnit: Option[OMBusError], 30 | hasClockGate: Boolean, 31 | hasSCIE: Boolean, 32 | _types: Seq[String] = Seq("OMRocketCore", "OMCore", "OMComponent", "OMCompoundType") 33 | ) extends OMCore 34 | 35 | object OMBTB { 36 | def makeOMI(p: BTBParams): OMRocketBranchPredictor = { 37 | OMRocketBranchPredictor( 38 | nBtbEntries = p.nEntries, 39 | nBhtEntries = p.bhtParams.map(_.nEntries).getOrElse(0), 40 | nRasEntries = p.nRAS 41 | ) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/scala/amba/package.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.util._ 7 | 8 | package object amba { 9 | class AMBAProtBundle extends Bundle { 10 | val bufferable = Bool() // writeback caching ok? 11 | val modifiable = Bool() // legal to read/write-combine/expand this request? 12 | val readalloc = Bool() 13 | val writealloc = Bool() 14 | val privileged = Bool() // machine_mode=true, user_mode=false 15 | val secure = Bool() // secure_master=true, normal=false 16 | val fetch = Bool() // instruct_fetch=true, load/store=false 17 | } 18 | 19 | case object AMBAProt extends ControlKey[AMBAProtBundle]("amba_prot") 20 | case class AMBAProtField() extends BundleField(AMBAProt) { 21 | def data = Output(new AMBAProtBundle) 22 | def default(x: AMBAProtBundle) { 23 | x.bufferable := false.B 24 | x.modifiable := false.B 25 | x.readalloc := false.B 26 | x.writealloc := false.B 27 | x.privileged := true.B 28 | x.secure := true.B 29 | x.fetch := false.B 30 | } 31 | } 32 | 33 | // Used to convert a TileLink corrupt signal into an AMBA user bit 34 | case object AMBACorrupt extends DataKey[Bool]("corrupt") 35 | case class AMBACorruptField() extends BundleField(AMBACorrupt) { 36 | def data = Output(Bool()) 37 | def default(x: Bool) { x := false.B } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/PreElaboration.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.RawModule 6 | import chisel3.stage.ChiselGeneratorAnnotation 7 | import firrtl.AnnotationSeq 8 | import firrtl.options.Viewer.view 9 | import firrtl.options.{Dependency, Phase, PreservesAll} 10 | import freechips.rocketchip.config.Parameters 11 | import freechips.rocketchip.diplomacy._ 12 | import freechips.rocketchip.stage.RocketChipOptions 13 | import freechips.rocketchip.util.HasRocketChipStageUtils 14 | 15 | /** Constructs a generator function that returns a top module with given config parameters */ 16 | class PreElaboration extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 17 | 18 | override val prerequisites = Seq(Dependency[Checks]) 19 | override val dependents = Seq(Dependency[chisel3.stage.phases.Elaborate]) 20 | 21 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 22 | 23 | val rOpts = view[RocketChipOptions](annotations) 24 | val topMod = rOpts.topModule.get 25 | 26 | val config = getConfig(rOpts.configNames.get) 27 | 28 | val gen = () => 29 | topMod 30 | .getConstructor(classOf[Parameters]) 31 | .newInstance(config) match { 32 | case a: RawModule => a 33 | case a: LazyModule => LazyModule(a).module 34 | } 35 | 36 | ChiselGeneratorAnnotation(gen) +: annotations 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE.Berkeley: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014, The Regents of the University of California 2 | (Regents). All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the Regents nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 16 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 17 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 18 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 | 20 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 23 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 24 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | -------------------------------------------------------------------------------- /src/main/scala/util/SimpleProduct.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | // To mix this trait, you must supply: 6 | // override def canEqual(that: Any): Boolean = that.isInstanceOf[YourClass] 7 | // override def productPrefix: String = "YourClass" 8 | // def productArity: Int = # of fields 9 | // def productElement(n: Int): Any = field accessors 10 | // In exchange you get: 11 | // def equals(that: Any): Boolean = same type and same fields 12 | // def hashCode: Int = hash of all fields (and productPrefix) 13 | // def toString: String = formats as "productPrefix(field1, field2, ...)" 14 | trait SimpleProduct extends Product with Equals { 15 | override def equals(other: Any): Boolean = other match { 16 | case that: SimpleProduct => 17 | def canEq = that.canEqual(this) && this.canEqual(that) 18 | def iter = that.productIterator zip this.productIterator 19 | canEq && iter.forall { case (a, b) => a == b } 20 | case _ => false 21 | } 22 | 23 | override def hashCode: Int = scala.util.hashing.MurmurHash3.productHash(this) 24 | 25 | override def toString: String = { 26 | val b = new StringBuilder(productPrefix) 27 | val iter = productIterator 28 | b += '(' 29 | if (iter.hasNext) { 30 | b ++= iter.next().toString 31 | while (iter.hasNext) { 32 | b ++= ", " 33 | b ++= iter.next().toString 34 | } 35 | } 36 | b += ')' 37 | b.toString 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | **Type of issue**: bug report | feature request | other enhancement 8 | 9 | 10 | **Impact**: no functional change | API addition (no impact on existing code) | API modification | unknown 11 | 12 | 13 | **Development Phase**: request | proposal 14 | 15 | **Other information** 16 | 17 | 18 | **If the current behavior is a bug, please provide the steps to reproduce the problem:** 19 | 20 | **What is the current behavior?** 21 | 22 | **What is the expected behavior?** 23 | 24 | **Please tell us about your environment:** 25 | 29 | **What is the use case for changing the behavior?** 30 | -------------------------------------------------------------------------------- /src/main/resources/csrc/remote_bitbang.h: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | #ifndef REMOTE_BITBANG_H 4 | #define REMOTE_BITBANG_H 5 | 6 | #include 7 | #include 8 | 9 | class remote_bitbang_t 10 | { 11 | public: 12 | // Create a new server, listening for connections from localhost on the given 13 | // port. 14 | remote_bitbang_t(uint16_t port); 15 | 16 | // Do a bit of work. 17 | void tick(unsigned char * jtag_tck, 18 | unsigned char * jtag_tms, 19 | unsigned char * jtag_tdi, 20 | unsigned char * jtag_trstn, 21 | unsigned char jtag_tdo); 22 | 23 | unsigned char done() {return quit;} 24 | 25 | int exit_code() {return err;} 26 | 27 | private: 28 | 29 | int err; 30 | 31 | unsigned char tck; 32 | unsigned char tms; 33 | unsigned char tdi; 34 | unsigned char trstn; 35 | unsigned char tdo; 36 | unsigned char quit; 37 | 38 | int socket_fd; 39 | int client_fd; 40 | 41 | static const ssize_t buf_size = 64 * 1024; 42 | char recv_buf[buf_size]; 43 | ssize_t recv_start, recv_end; 44 | 45 | // Check for a client connecting, and accept if there is one. 46 | void accept(); 47 | // Execute any commands the client has for us. 48 | // But we only execute 1 because we need time for the 49 | // simulation to run. 50 | void execute_command(); 51 | 52 | // Reset. Currently does nothing. 53 | void reset(); 54 | 55 | void set_pins(char _tck, char _tms, char _tdi); 56 | 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /LICENSE.jtag: -------------------------------------------------------------------------------- 1 | chisel-jtag license terms 2 | 3 | Copyright (c) 2016 The Regents of the University of 4 | California (Regents). All Rights Reserved. Redistribution and use in 5 | source and binary forms, with or without modification, are permitted 6 | provided that the following conditions are met: 7 | * Redistributions of source code must retain the above 8 | copyright notice, this list of conditions and the following 9 | two paragraphs of disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | two paragraphs of disclaimer in the documentation and/or other materials 13 | provided with the distribution. 14 | * Neither the name of the Regents nor the names of its contributors 15 | may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 18 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 19 | ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 20 | REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF 24 | ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION 25 | TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 26 | MODIFICATIONS. 27 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/Configs.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | package freechips.rocketchip.groundtest 5 | 6 | import Chisel._ 7 | import freechips.rocketchip.config.Config 8 | import freechips.rocketchip.subsystem._ 9 | import freechips.rocketchip.system.BaseConfig 10 | import freechips.rocketchip.rocket.{DCacheParams} 11 | import freechips.rocketchip.tile.{MaxHartIdBits, XLen} 12 | 13 | /** Actual testing target Configs */ 14 | 15 | class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseConfig) 16 | 17 | class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig) 18 | 19 | /* Composable Configs to set individual parameters */ 20 | 21 | class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192) extends Config((site, here, up) => { 22 | case GroundTestTilesKey => params.map { dcp => TraceGenParams( 23 | dcache = Some(dcp), 24 | wordBits = site(XLen), 25 | addrBits = 32, 26 | addrBag = { 27 | val nSets = dcp.nSets 28 | val nWays = dcp.nWays 29 | val blockOffset = site(SystemBusKey).blockOffset 30 | val nBeats = site(SystemBusKey).blockBeats 31 | List.tabulate(nWays) { i => 32 | Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) } 33 | }.flatten 34 | }, 35 | maxRequests = nReqs, 36 | memStart = site(ExtMem).get.master.base, 37 | numGens = params.size) 38 | } 39 | case MaxHartIdBits => log2Up(params.size) 40 | }) 41 | -------------------------------------------------------------------------------- /src/test/scala/generatorTests/StageGeneratorSpec.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package generatorTests 4 | 5 | import java.io.File 6 | 7 | import chisel3.aop.injecting.InjectingAspect 8 | import chisel3._ 9 | import firrtl.options.TargetDirAnnotation 10 | import freechips.rocketchip.stage.{ConfigsAnnotation, TopModuleAnnotation} 11 | import freechips.rocketchip.system.{RocketChipStage, TestHarness} 12 | import org.scalatest.FlatSpec 13 | 14 | /** run via SBT with 15 | * > testOnly generatorTests.StageGeneratorSpec 16 | * 17 | * Output can be viewed in the testbuild directory. The wire named "hello" should show up in the generated 18 | * *.anno.json file. 19 | */ 20 | class StageGeneratorSpec extends FlatSpec { 21 | 22 | val dummyAspect = InjectingAspect( 23 | {dut: TestHarness => Seq(dut.dut)}, 24 | {dut: freechips.rocketchip.system.ExampleRocketSystemModuleImp[freechips.rocketchip.system.ExampleRocketSystem] => 25 | val dummyWire = Wire(UInt(3.W)).suggestName("hello") 26 | dummyWire := 5.U 27 | dontTouch(dummyWire) 28 | } 29 | ) 30 | 31 | "Test" should "pass" in { 32 | val dirName = System.getProperty("user.dir") + "/testbuild" 33 | val dir = new File(dirName) 34 | if (!dir.exists()) dir.mkdirs() 35 | 36 | new RocketChipStage().run(Seq( 37 | new TargetDirAnnotation(dirName), 38 | new TopModuleAnnotation(Class.forName("freechips.rocketchip.system.TestHarness")), 39 | new ConfigsAnnotation(Seq("freechips.rocketchip.system.DefaultConfig")), 40 | dummyAspect 41 | )) 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Bundles.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.util._ 7 | 8 | // Signal directions are from the master's point-of-view 9 | class APBBundle(val params: APBBundleParameters) extends Bundle 10 | { 11 | // Flow control signals from the master 12 | val psel = Bool(OUTPUT) 13 | val penable = Bool(OUTPUT) 14 | 15 | // Payload signals 16 | val pwrite = Bool(OUTPUT) 17 | val paddr = UInt(OUTPUT, width = params.addrBits) 18 | val pprot = UInt(OUTPUT, width = params.protBits) 19 | val pwdata = UInt(OUTPUT, width = params.dataBits) 20 | val pstrb = UInt(OUTPUT, width = params.dataBits/8) 21 | val pauser = BundleMap(params.requestFields) 22 | 23 | val pready = Bool(INPUT) 24 | val pslverr = Bool(INPUT) 25 | val prdata = UInt(INPUT, width = params.dataBits) 26 | val pduser = BundleMap(params.responseFields) 27 | 28 | def tieoff() { 29 | pready.dir match { 30 | case INPUT => 31 | pready := Bool(false) 32 | pslverr := Bool(false) 33 | prdata := UInt(0) 34 | pduser :<= BundleMap() 35 | case OUTPUT => 36 | pwrite := Bool(false) 37 | paddr := UInt(0) 38 | pprot := APBParameters.PROT_DEFAULT 39 | pwdata := UInt(0) 40 | pstrb := UInt(0) 41 | pauser :<= BundleMap() 42 | case _ => 43 | } 44 | } 45 | } 46 | 47 | object APBBundle 48 | { 49 | def apply(params: APBBundleParameters) = new APBBundle(params) 50 | } 51 | -------------------------------------------------------------------------------- /src/main/scala/util/DescribedSRAM.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | // See LICENSE.SiFive for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import chisel3.internal.InstanceId 7 | import chisel3.{Data, SyncReadMem, Vec} 8 | import chisel3.util.log2Ceil 9 | import freechips.rocketchip.amba.axi4.AXI4RAM 10 | import freechips.rocketchip.diplomacy.DiplomaticSRAM 11 | import freechips.rocketchip.diplomaticobjectmodel.DiplomaticObjectModelAddressing 12 | import freechips.rocketchip.diplomaticobjectmodel.model.{OMSRAM, OMRTLModule} 13 | import scala.math.log10 14 | 15 | object DescribedSRAM { 16 | def apply[T <: Data]( 17 | name: String, 18 | desc: String, 19 | size: BigInt, // depth 20 | data: T 21 | ): (SyncReadMem[T], OMSRAM) = { 22 | 23 | val mem = SyncReadMem(size, data) 24 | 25 | mem.suggestName(name) 26 | 27 | val granWidth = data match { 28 | case v: Vec[_] => v.head.getWidth 29 | case d => d.getWidth 30 | } 31 | 32 | val uid = 0 33 | 34 | val omSRAM = DiplomaticObjectModelAddressing.makeOMSRAM( 35 | desc = desc, 36 | width = data.getWidth, 37 | depth = size, 38 | granWidth = granWidth, 39 | uid = uid, 40 | rtlModule = OMRTLModule(moduleName=name) 41 | ) 42 | 43 | Annotated.srams( 44 | component = mem, 45 | name = name, 46 | address_width = log2Ceil(size), 47 | data_width = data.getWidth, 48 | depth = size, 49 | description = desc, 50 | write_mask_granularity = granWidth 51 | ) 52 | 53 | (mem, omSRAM) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/scala/stage/RocketChipOptions.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage 4 | 5 | class RocketChipOptions private[stage] ( 6 | val topModule: Option[Class[_ <: Any]] = None, 7 | val configNames: Option[Seq[String]] = None, 8 | val outputBaseName: Option[String] = None) { 9 | 10 | private[stage] def copy( 11 | topModule: Option[Class[_ <: Any]] = topModule, 12 | configNames: Option[Seq[String]] = configNames, 13 | outputBaseName: Option[String] = outputBaseName, 14 | ): RocketChipOptions = { 15 | 16 | new RocketChipOptions( 17 | topModule=topModule, 18 | configNames=configNames, 19 | outputBaseName=outputBaseName, 20 | ) 21 | } 22 | 23 | lazy val topPackage: Option[String] = topModule match { 24 | case Some(a) => Some(a.getPackage.getName) 25 | case _ => None 26 | } 27 | 28 | lazy val configClass: Option[String] = configNames match { 29 | case Some(names) => 30 | val classNames = names.map{ n => n.split('.').last } 31 | Some(classNames.mkString("_")) 32 | case _ => None 33 | } 34 | 35 | lazy val longName: Option[String] = outputBaseName match { 36 | case Some(name) => Some(name) 37 | case _ => 38 | if (!topPackage.isEmpty && !configClass.isEmpty) Some(s"${topPackage.get}.${configClass.get}") else None 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/scala/prci/ClockDivider.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | package freechips.rocketchip.prci 3 | 4 | import chisel3._ 5 | import chisel3.util.isPow2 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.util.{ClockDivider3, Pow2ClockDivider} 9 | 10 | /* An example clock adapter that divides all clocks passed through this node by an integer factor 11 | */ 12 | class ClockDivider(div: Int)(implicit p: Parameters) extends LazyModule { 13 | val node = ClockAdapterNode( 14 | sourceFn = { case src => src.copy(give = src.give.map(x => x.copy(freqMHz = x.freqMHz / 2))) }, 15 | sinkFn = { case snk => snk.copy(take = snk.take.map(x => x.copy(freqMHz = x.freqMHz * 2))) }) 16 | 17 | lazy val module = new LazyModuleImp(this) { 18 | (node.in zip node.out).foreach { case ((in, _), (out, _)) => 19 | val div_clock: Clock = div match { 20 | case x if isPow2(x) => Pow2ClockDivider(in.clock, x) 21 | case 3 => { 22 | val div3 = Module(new ClockDivider3) 23 | div3.io.clk_in := in.clock 24 | div3.io.clk_out 25 | } 26 | case x => throw new IllegalArgumentException(s"rocketchip.util only supports clock division by powers of 2, or exactly 3, but got $x") 27 | } 28 | out.clock := div_clock 29 | out.reset := withClock(out.clock) { RegNext(in.reset) } 30 | } 31 | } 32 | } 33 | 34 | // TODO make a version of this that output a clock group with two members, 35 | // one of which is the original clock and the other of which is some number of divided clocks 36 | -------------------------------------------------------------------------------- /src/main/scala/tilelink/Example.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tilelink 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.regmapper._ 8 | 9 | case class ExampleParams(num: Int, address: BigInt) 10 | 11 | trait ExampleBundle 12 | { 13 | val params: ExampleParams 14 | val gpio = UInt(width = params.num) 15 | } 16 | 17 | trait ExampleModule extends HasRegMap 18 | { 19 | val params: ExampleParams 20 | val io: ExampleBundle 21 | val interrupts: Vec[Bool] 22 | 23 | val state = RegInit(UInt(0, width = params.num)) 24 | val pending = RegInit(UInt(0xf, width = 4)) 25 | 26 | io.gpio := state 27 | interrupts := pending.asBools 28 | 29 | regmap( 30 | 0 -> Seq( 31 | RegField(params.num, state, 32 | RegFieldDesc("state", "State: Example of a R/W Register with description.", reset = Some(0)))), 33 | 4 -> Seq( 34 | RegField.w1ToClear(4, pending, state, 35 | Some(RegFieldDesc("pending", "Pending: Example of a special (W1ToC) Register. " + 36 | "Writing a bit here causes it to be reset to 0. " + 37 | "The bits are set when the corresponding bit in 'state' is high.", 38 | reset=Some(0xF), volatile=true)))) 39 | ) 40 | } 41 | 42 | // Create a concrete TL2 version of the abstract Example slave 43 | class TLExample(params: ExampleParams)(implicit p: Parameters) 44 | extends TLRegisterRouter(params.address, "somedev", Seq("ucbbar,random-interface"), 4)( 45 | new TLRegBundle(params, _) with ExampleBundle)( 46 | new TLRegModule(params, _, _) with ExampleModule) 47 | -------------------------------------------------------------------------------- /src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.devices.tilelink 4 | 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.tilelink._ 8 | 9 | trait HasBuiltInDeviceParams { 10 | val zeroDevice: Option[AddressSet] 11 | val errorDevice: Option[DevNullParams] 12 | } 13 | 14 | sealed trait BuiltInDevices { 15 | def errorOpt: Option[TLError] 16 | def zeroOpt: Option[TLZero] 17 | } 18 | 19 | object BuiltInDevices { 20 | def none = new BuiltInDevices { 21 | val errorOpt = None 22 | val zeroOpt = None 23 | } 24 | 25 | def attach( 26 | params: HasBuiltInDeviceParams with HasTLBusParams, 27 | outwardNode: TLOutwardNode)(implicit p: Parameters) = new BuiltInDevices { 28 | val errorOpt = params.errorDevice.map { dnp => LazyScope("wrapped_error_device") { 29 | val error = LazyModule(new TLError( 30 | params = dnp, 31 | beatBytes = params.beatBytes)) 32 | 33 | error.node := TLBuffer() := outwardNode 34 | error 35 | }} 36 | 37 | val zeroOpt = params.zeroDevice.map { addr => LazyScope("wrapped_zero_device") { 38 | val zero = LazyModule(new TLZero( 39 | address = addr, 40 | beatBytes = params.beatBytes)) 41 | zero.node := TLFragmenter(params.beatBytes, params.blockBytes) := TLBuffer() := outwardNode 42 | zero 43 | }} 44 | } 45 | } 46 | 47 | /* Optionally add some built-in devices to a bus wrapper */ 48 | trait CanHaveBuiltInDevices { 49 | def builtInDevices: BuiltInDevices 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/scala/jtag/Utils.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.jtag for license details. 2 | 3 | package freechips.rocketchip.jtag 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | /** Bundle representing a tristate pin. 9 | */ 10 | class Tristate extends Bundle { 11 | val data = Bool() 12 | val driven = Bool() // active high, pin is hi-Z when driven is low 13 | } 14 | 15 | /** A module that counts transitions on the input clock line, used as a basic sanity check and 16 | * debug indicator clock-crossing designs. 17 | */ 18 | class ClockedCounter(counts: BigInt, init: Option[BigInt]) extends Module { 19 | require(counts > 0, "really?") 20 | 21 | val width = log2Ceil(counts) 22 | class CountIO extends Bundle { 23 | val count = Output(UInt(width.W)) 24 | } 25 | val io = IO(new CountIO) 26 | 27 | val count = init match { 28 | case Some(init) => RegInit(init.U(width.W)) 29 | case None => Reg(UInt(width.W)) 30 | } 31 | 32 | when (count === (counts - 1).asUInt) { 33 | count := 0.U 34 | } .otherwise { 35 | count := count + 1.U 36 | } 37 | io.count := count 38 | } 39 | 40 | /** Count transitions on the input bit by specifying it as a clock to a counter. 41 | */ 42 | object ClockedCounter { 43 | def apply (data: Bool, counts: BigInt, init: BigInt): UInt = { 44 | withClock(data.asClock) { 45 | val counter = Module(new ClockedCounter(counts, Some(init))) 46 | counter.io.count 47 | } 48 | } 49 | 50 | def apply (data: Bool, counts: BigInt): UInt = { 51 | withClock(data.asClock) { 52 | val counter = Module(new ClockedCounter(counts, None)) 53 | counter.io.count 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/scala/tile/L1Cache.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tile 4 | 5 | import Chisel._ 6 | 7 | import freechips.rocketchip.config.{Parameters, Field} 8 | import freechips.rocketchip.tilelink.ClientMetadata 9 | import freechips.rocketchip.util._ 10 | 11 | trait L1CacheParams { 12 | def nSets: Int 13 | def nWays: Int 14 | def rowBits: Int 15 | def nTLBEntries: Int 16 | def blockBytes: Int // TODO this is ignored in favor of p(CacheBlockBytes) in BaseTile 17 | } 18 | 19 | trait HasL1CacheParameters extends HasTileParameters { 20 | val cacheParams: L1CacheParams 21 | 22 | def nSets = cacheParams.nSets 23 | def blockOffBits = lgCacheBlockBytes 24 | def idxBits = log2Up(cacheParams.nSets) 25 | def untagBits = blockOffBits + idxBits 26 | def pgUntagBits = if (usingVM) untagBits min pgIdxBits else untagBits 27 | def tagBits = tlBundleParams.addressBits - pgUntagBits 28 | def nWays = cacheParams.nWays 29 | def wayBits = log2Up(nWays) 30 | def isDM = nWays == 1 31 | def rowBits = cacheParams.rowBits 32 | def rowBytes = rowBits/8 33 | def rowOffBits = log2Up(rowBytes) 34 | def nTLBEntries = cacheParams.nTLBEntries 35 | 36 | def cacheDataBits = tlBundleParams.dataBits 37 | def cacheDataBytes = cacheDataBits / 8 38 | def cacheDataBeats = (cacheBlockBytes * 8) / cacheDataBits 39 | def refillCycles = cacheDataBeats 40 | } 41 | 42 | abstract class L1CacheModule(implicit val p: Parameters) extends Module 43 | with HasL1CacheParameters 44 | 45 | abstract class L1CacheBundle(implicit val p: Parameters) extends Bundle 46 | with HasL1CacheParameters 47 | -------------------------------------------------------------------------------- /src/main/scala/util/LCG.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import Chisel._ 7 | 8 | /** A 16-bit psuedo-random generator based on a linear conguential 9 | * generator (LCG). The state is stored in an unitialised register. 10 | * When using the C++ backend, it is straigtforward to arrange a 11 | * random initial value for each uninitialised register, effectively 12 | * seeding each LCG16 instance with a different seed. 13 | */ 14 | class LCG16 extends Module { 15 | val io = new Bundle { 16 | val out = UInt(OUTPUT, 16) 17 | val inc = Bool(INPUT) 18 | } 19 | val state = Reg(UInt(width = 32)) 20 | when (io.inc) { 21 | state := state * UInt(1103515245, 32) + UInt(12345, 32) 22 | } 23 | io.out := state(30, 15) 24 | } 25 | 26 | /** An n-bit psuedo-random generator made from many instances of a 27 | * 16-bit LCG. Parameter 'width' must be larger than 0. 28 | */ 29 | class LCG(val w: Int) extends Module { 30 | val io = new Bundle { 31 | val out = UInt(OUTPUT, w) 32 | val inc = Bool(INPUT) 33 | } 34 | require(w > 0) 35 | val numLCG16s : Int = (w+15)/16 36 | val outs = Seq.fill(numLCG16s) { LCG16(io.inc) } 37 | io.out := Cat(outs) 38 | } 39 | 40 | object LCG16 { 41 | def apply(inc: Bool = Bool(true)): UInt = { 42 | val lcg = Module(new LCG16) 43 | lcg.io.inc := inc 44 | lcg.io.out 45 | } 46 | } 47 | 48 | object LCG { 49 | def apply(w: Int, inc: Bool = Bool(true)): UInt = { 50 | val lcg = Module(new LCG(w)) 51 | lcg.io.inc := inc 52 | lcg.io.out 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/main/scala/util/TraceCoreInterface.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | // See LICENSE.SiFive for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import chisel3._ 7 | import chisel3.util._ 8 | import chisel3.experimental.ChiselEnum 9 | import freechips.rocketchip.tile._ 10 | 11 | // Definitions for Trace core Interface defined in RISC-V Processor Trace Specification V1.0 12 | object TraceItype extends ChiselEnum { 13 | val ITNothing = Value(0.U) 14 | val ITException = Value(1.U) 15 | val ITInterrupt = Value(2.U) 16 | val ITExcReturn = Value(3.U) 17 | val ITBrNTaken = Value(4.U) 18 | val ITBrTaken = Value(5.U) 19 | val ITReserved6 = Value(6.U) 20 | val ITReserved7 = Value(7.U) 21 | val ITUnCall = Value(8.U) 22 | val ITInCall = Value(9.U) 23 | val ITUnTail = Value(10.U) 24 | val ITInTail = Value(11.U) 25 | val ITCoSwap = Value(12.U) 26 | val ITReturn = Value(13.U) 27 | val ITUnJump = Value(14.U) 28 | val ITInJump = Value(15.U) 29 | } 30 | 31 | class TraceCoreParams ( 32 | val nGroups: Int = 1, 33 | val iretireWidth: Int = 1, 34 | val xlen: Int = 32, 35 | val iaddrWidth: Int = 32 36 | ) 37 | 38 | class TraceCoreGroup (val params: TraceCoreParams) extends Bundle { 39 | val iretire = UInt(params.iretireWidth.W) 40 | val iaddr = UInt(params.iaddrWidth.W) 41 | val itype = TraceItype() 42 | val ilastsize = UInt(1.W) 43 | } 44 | 45 | class TraceCoreInterface (val params: TraceCoreParams) extends Bundle { 46 | val group = Vec(params.nGroups, new TraceCoreGroup(params)) 47 | val priv = UInt(4.W) 48 | val tval = UInt(params.xlen.W) 49 | val cause = UInt(params.xlen.W) 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/scala/amba/axi4/CrossingHelper.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axi4 4 | 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | case class AXI4InwardCrossingHelper(name: String, scope: LazyScope, node: AXI4InwardNode) { 9 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): AXI4InwardNode = { 10 | xing match { 11 | case x: AsynchronousCrossing => 12 | node :*=* scope { AXI4AsyncCrossingSink(x.asSinkParams) :*=* AXI4AsyncNameNode(name) } :*=* AXI4AsyncNameNode(name) :*=* AXI4AsyncCrossingSource(x.sourceSync) 13 | case RationalCrossing(direction) => 14 | throw new IllegalArgumentException("AXI4 Rational crossing unimplemented") 15 | case SynchronousCrossing(buffer) => 16 | node :*=* scope { AXI4Buffer(buffer) :*=* AXI4NameNode(name) } :*=* AXI4NameNode(name) 17 | } 18 | } 19 | } 20 | 21 | case class AXI4OutwardCrossingHelper(name: String, scope: LazyScope, node: AXI4OutwardNode) { 22 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): AXI4OutwardNode = { 23 | xing match { 24 | case x: AsynchronousCrossing => 25 | AXI4AsyncCrossingSink(x.asSinkParams) :*=* AXI4AsyncNameNode(name) :*=* scope { AXI4AsyncNameNode(name) :*=* AXI4AsyncCrossingSource(x.sourceSync) } :*=* node 26 | case RationalCrossing(direction) => 27 | throw new IllegalArgumentException("AXI4 Rational crossing unimplemented") 28 | case SynchronousCrossing(buffer) => 29 | AXI4NameNode(name) :*=* scope { AXI4NameNode(name) :*=* AXI4Buffer(buffer) } :*=* node 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/GroundTestSubsystem.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.groundtest 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.{Field, Parameters} 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.diplomaticobjectmodel.model.OMInterrupt 9 | import freechips.rocketchip.interrupts._ 10 | import freechips.rocketchip.subsystem._ 11 | import freechips.rocketchip.tilelink._ 12 | import freechips.rocketchip.tile._ 13 | 14 | import scala.math.max 15 | 16 | case object TileId extends Field[Int] 17 | 18 | class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem 19 | with CanHaveMasterAXI4MemPort { 20 | val tileParams = p(GroundTestTilesKey) 21 | val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(c.build(i, p)) } 22 | 23 | tiles.map(_.masterNode).foreach { m => 24 | sbus.fromTile(None, buffer = BufferParams.default){ m } 25 | } 26 | 27 | val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), beatBytes=pbus.beatBytes)) 28 | pbus.coupleTo("TestRAM") { testram.node := TLFragmenter(pbus) := _ } 29 | 30 | // No PLIC in ground test; so just sink the interrupts to nowhere 31 | IntSinkNode(IntSinkPortSimple()) :=* ibus.toPLIC 32 | 33 | override lazy val module = new GroundTestSubsystemModuleImp(this) 34 | } 35 | 36 | class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) { 37 | val success = IO(Bool(OUTPUT)) 38 | 39 | outer.tiles.zipWithIndex.map { case(t, i) => t.module.constants.hartid := UInt(i) } 40 | 41 | val status = DebugCombiner(outer.tiles.map(_.module.status)) 42 | success := status.finished 43 | } 44 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/Checks.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import firrtl.AnnotationSeq 6 | import firrtl.annotations.Annotation 7 | import firrtl.options.{OptionsException, Phase, PreservesAll, TargetDirAnnotation} 8 | import freechips.rocketchip.stage._ 9 | 10 | import scala.collection.mutable 11 | 12 | /** Checks for the correct type and number of command line arguments */ 13 | class Checks extends Phase with PreservesAll[Phase] { 14 | 15 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 16 | val targetDir, topModule, configNames, outputBaseName = mutable.ListBuffer[Annotation]() 17 | 18 | annotations.foreach { 19 | case a: TargetDirAnnotation => a +=: targetDir 20 | case a: TopModuleAnnotation => a +=: topModule 21 | case a: ConfigsAnnotation => a +=: configNames 22 | case a: OutputBaseNameAnnotation => a +=: outputBaseName 23 | case _ => 24 | } 25 | 26 | def required(annoList: mutable.ListBuffer[Annotation], option: String): Unit = { 27 | if (annoList.size != 1) { 28 | throw new OptionsException(s"Exactly one $option required") 29 | } 30 | } 31 | 32 | def optional(annoList: mutable.ListBuffer[Annotation], option: String): Unit = { 33 | if (annoList.size > 1) { 34 | throw new OptionsException(s"Too many $option options have been specified") 35 | } 36 | } 37 | 38 | required(targetDir, "target directory") 39 | required(topModule, "top module") 40 | required(configNames, "configs string (','-delimited)") 41 | 42 | optional(outputBaseName, "output base name") 43 | 44 | annotations 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/util/Location.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import scala.language.dynamics 6 | import scala.collection.mutable.Map 7 | 8 | class Location[T](val name: String) extends Dynamic { 9 | def selectDynamic[A](portname: String): Location[A] = new Location[A](s"${name}_${portname}") 10 | def applyDynamic[A](portname: String)(args: A*): (Location[A], A) = { 11 | require(args.size == 1, "Location: can't support multiple things at one port yet") 12 | (new Location[A](s"${name}_${portname}"), args.head) 13 | } 14 | override def toString = s"Location($name)" 15 | } 16 | 17 | object Location { 18 | def apply[T](name: String): Location[T] = new Location[T](name) 19 | } 20 | 21 | class LocationMap[T] private (val internalMap: Map[String, T]) extends Map[Location[_], T] { 22 | def +=(kv: (Location[_], T)) = { (internalMap += (kv._1.name -> kv._2)); this } 23 | def -=(key: Location[_]) = { (internalMap -= key.name); this } 24 | def get(key: Location[_]) = internalMap.get(key.name) 25 | def iterator = internalMap.iterator.map(kv => (new Location(kv._1), kv._2)) 26 | // TODO override def default to provide specific exception on missing location? 27 | // TODO figure out how to be more clever about applying sub-type casting 28 | // for other the other Map trait methods 29 | def required[L <: T](key: Location[_]): L = internalMap(key.name).asInstanceOf[L] 30 | def optional[L <: T](key: Location[_]): Option[L] = internalMap.lift(key.name).map(_.asInstanceOf[L]) 31 | } 32 | 33 | object LocationMap { 34 | def apply[T](lm: Map[String, T]): LocationMap[T] = new LocationMap(lm) 35 | def empty[T]: LocationMap[T] = new LocationMap(Map.empty[String, T]) 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/prci/ResetWrangler.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | package freechips.rocketchip.prci 3 | 4 | import chisel3._ 5 | import chisel3.util._ 6 | import freechips.rocketchip.config._ 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.util._ 9 | 10 | class ResetWrangler(debounceNs: Double = 100000)(implicit p: Parameters) extends LazyModule 11 | { 12 | val node = ClockAdapterNode() 13 | 14 | lazy val module = new LazyRawModuleImp(this) { 15 | val (in, _) = node.in.unzip 16 | val (out, _) = node.out.unzip 17 | 18 | val status = IO(Output(UInt(in.size.W))) 19 | status := Cat(in.map(_.reset.asBool).reverse) 20 | val causes = in.map(_.reset).foldLeft(false.B)(_.asBool || _.asBool) 21 | 22 | require(node.in.forall(_._2.clock.isDefined), "Cannot wrangle reset for an unspecified clock frequency") 23 | val (slowIn, slowEdge) = node.in.minBy(_._2.clock.get.freqMHz) 24 | val slowPeriodNs = 1000 / slowEdge.clock.get.freqMHz 25 | val slowTicks = math.ceil(debounceNs/slowPeriodNs).toInt max 7 26 | val slowBits = log2Ceil(slowTicks+1) 27 | 28 | // debounce 29 | val increment = Wire(Bool()) 30 | val incremented = Wire(UInt(slowBits.W)) 31 | val debounced = withClockAndReset(slowIn.clock, causes) { 32 | AsyncResetReg(incremented, 0, increment, Some("debounce")) 33 | } 34 | increment := debounced =/= slowTicks.U 35 | incremented := debounced + 1.U 36 | val deglitched = AsyncResetReg(increment, slowIn.clock, causes, true, Some("deglitch")) 37 | 38 | // catch and sync increment to each domain 39 | (in zip out) foreach { case (i, o) => 40 | o.clock := i.clock 41 | o.reset := ResetCatchAndSync(o.clock, deglitched) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/system/RocketChipStageGenerator.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.system 4 | 5 | import chisel3.stage.{ChiselCli, ChiselStage} 6 | import firrtl.options.PhaseManager.PhaseDependency 7 | import firrtl.options.{Dependency, Phase, PreservesAll, Shell, StageMain} 8 | import firrtl.stage.FirrtlCli 9 | import freechips.rocketchip.stage.RocketChipCli 10 | 11 | class RocketChipStage extends ChiselStage with PreservesAll[Phase] { 12 | 13 | override val shell = new Shell("rocket-chip") with RocketChipCli with ChiselCli with FirrtlCli 14 | override val targets: Seq[PhaseDependency] = Seq( 15 | Dependency[freechips.rocketchip.stage.phases.Checks], 16 | Dependency[freechips.rocketchip.stage.phases.TransformAnnotations], 17 | Dependency[freechips.rocketchip.stage.phases.PreElaboration], 18 | Dependency[chisel3.stage.phases.Checks], 19 | Dependency[chisel3.stage.phases.Elaborate], 20 | Dependency[freechips.rocketchip.stage.phases.GenerateROMs], 21 | Dependency[chisel3.stage.phases.AddImplicitOutputFile], 22 | Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], 23 | Dependency[chisel3.stage.phases.MaybeAspectPhase], 24 | Dependency[chisel3.stage.phases.Emitter], 25 | Dependency[chisel3.stage.phases.Convert], 26 | Dependency[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], 27 | Dependency[freechips.rocketchip.stage.phases.AddDefaultTests], 28 | Dependency[freechips.rocketchip.stage.phases.GenerateTestSuiteMakefrags], 29 | Dependency[freechips.rocketchip.stage.phases.GenerateArtefacts], 30 | ) 31 | 32 | // TODO: need a RunPhaseAnnotation to inject phases into ChiselStage 33 | } 34 | 35 | object Generator extends StageMain(new RocketChipStage) 36 | -------------------------------------------------------------------------------- /src/main/scala/util/ReduceOthers.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | 7 | object ReduceOthers { 8 | // Given a list of bools, create this output: 9 | // out[i] = AND[j=0..out.size, j!=i] in[j] 10 | def apply(x: Seq[Bool]): Seq[Bool] = { 11 | val (literals, variables) = x.partition(_.isLit) 12 | 13 | val falses = literals.count(_.litValue == 0) 14 | if (falses > 2) { 15 | Seq.fill(x.size) { Bool(false) } 16 | } else if (falses == 1) { 17 | x.map { b => 18 | if (b.isLit && b.litValue == 0) { 19 | variables.foldLeft(Bool(true))(_ && _) 20 | } else { 21 | Bool(false) 22 | } 23 | } 24 | } else { 25 | var (out, all) = helper(variables) 26 | x.map { b => 27 | if (b.isLit) { 28 | all 29 | } else { 30 | val sel = out.head 31 | out = out.tail 32 | sel 33 | } 34 | } 35 | } 36 | } 37 | // Take pairs of (output_wire, input_bool) 38 | def apply(x: Seq[(Bool, Bool)]) { 39 | (x.map(_._1) zip apply(x.map(_._2))) foreach { case (w, x) => w := x } 40 | } 41 | private def helper(x: Seq[Bool]): (Seq[Bool], Bool) = { 42 | if (x.size <= 1) { 43 | (Seq.fill(x.size) { Bool(true) }, x.headOption.getOrElse(Bool(true))) 44 | } else if (x.size <= 3) { 45 | (Seq.tabulate(x.size) { i => 46 | (x.take(i) ++ x.drop(i+1)).reduce(_ && _) 47 | }, x.reduce(_ && _)) 48 | } else { 49 | val (half, all) = helper(x.grouped(2).map(_.reduce(_ && _)).toList) 50 | (Seq.tabulate(x.size) { i => 51 | if ((i ^ 1) >= x.size) half(i/2) else x(i ^ 1) && half(i / 2) 52 | }, all) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/scala/tilelink/Map.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tilelink 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import scala.math.{min,max} 9 | 10 | // Moves the AddressSets of slave devices around 11 | // Combine with TLFilter to remove slaves or reduce their size 12 | class TLMap(fn: AddressSet => BigInt)(implicit p: Parameters) extends LazyModule 13 | { 14 | val node = TLAdapterNode( 15 | clientFn = { cp => cp }, 16 | managerFn = { mp => 17 | mp.v1copy(managers = mp.managers.map(m => 18 | m.v1copy(address = m.address.map(a => 19 | AddressSet(fn(a), a.mask)))))}) 20 | 21 | lazy val module = new LazyModuleImp(this) { 22 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 23 | out <> in 24 | val convert = edgeIn.manager.managers.flatMap(_.address) zip edgeOut.manager.managers.flatMap(_.address) 25 | def forward(x: UInt) = 26 | convert.map { case (i, o) => Mux(i.contains(x), UInt(o.base) | (x & UInt(o.mask)), UInt(0)) }.reduce(_ | _) 27 | def backward(x: UInt) = 28 | convert.map { case (i, o) => Mux(o.contains(x), UInt(i.base) | (x & UInt(i.mask)), UInt(0)) }.reduce(_ | _) 29 | 30 | out.a.bits.address := forward(in.a.bits.address) 31 | if (edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe) { 32 | out.c.bits.address := forward(in.c.bits.address) 33 | in.b.bits.address := backward(out.b.bits.address) 34 | } 35 | } 36 | } 37 | } 38 | 39 | object TLMap 40 | { 41 | def apply(fn: AddressSet => BigInt)(implicit p: Parameters): TLNode = 42 | { 43 | val map = LazyModule(new TLMap(fn)) 44 | map.node 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/regmapper/DescribedReg.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | package freechips.rocketchip.regmapper 3 | 4 | import Chisel._ 5 | import chisel3.experimental._ 6 | import chisel3.{Input, Output} 7 | import freechips.rocketchip.util.{AsyncResetRegVec, SimpleRegIO} 8 | 9 | object DescribedReg { 10 | import freechips.rocketchip.regmapper.RegFieldAccessType._ 11 | import freechips.rocketchip.regmapper.RegFieldWrType._ 12 | import freechips.rocketchip.regmapper.RegFieldRdAction._ 13 | 14 | def apply[T <: Data]( 15 | gen: => T, 16 | name: String, 17 | desc: String, 18 | reset: Option[T], 19 | access: RegFieldAccessType = RW, 20 | wrType: Option[RegFieldWrType] = None, 21 | rdAction: Option[RegFieldRdAction] = None, 22 | volatile: Boolean = false, 23 | enumerations: Map[BigInt, (String, String)] = Map()): (T, RegFieldDesc) = { 24 | val rdesc = RegFieldDesc(name, desc, None, None, 25 | access, wrType, rdAction, volatile, reset.map{_.litValue}, enumerations) 26 | val reg = reset.map{i => RegInit(i)}.getOrElse(Reg(gen)) 27 | reg.suggestName(name + "_reg") 28 | (reg, rdesc) 29 | } 30 | 31 | def async( 32 | width: Int, 33 | name: String, 34 | desc: String, 35 | reset: Int, 36 | access: RegFieldAccessType = RW, 37 | wrType: Option[RegFieldWrType] = None, 38 | rdAction: Option[RegFieldRdAction] = None, 39 | volatile: Boolean = false, 40 | enumerations: Map[BigInt, (String, String)] = Map()): (SimpleRegIO, RegFieldDesc) = { 41 | val rdesc = RegFieldDesc(name, desc, None, None, 42 | access, wrType, rdAction, volatile, Some(reset), enumerations) 43 | val reg = Module(new AsyncResetRegVec(w = width, init = reset)) 44 | reg.suggestName(name + "_reg") 45 | (reg.io, rdesc) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/devices/tilelink/BusBlocker.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.devices.tilelink 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.regmapper._ 9 | import freechips.rocketchip.tilelink._ 10 | import freechips.rocketchip.util._ 11 | 12 | /** BasicBusBlocker uses a single bit register to control whether 13 | * accesses of all types are allowed to proceed or bypassed to 14 | * a /dev/null device. It has a second bit register to report 15 | * whether any requests are pending on either path. 16 | */ 17 | 18 | case class BasicBusBlockerParams( 19 | controlAddress: BigInt, 20 | controlBeatBytes: Int, 21 | deviceBeatBytes: Int, 22 | deadlock: Boolean = false) 23 | 24 | class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters) 25 | extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock) 26 | { 27 | val device = new SimpleDevice("basic-bus-blocker", Seq("sifive,basic-bus-blocker0")) 28 | 29 | val controlNode = TLRegisterNode( 30 | address = Seq(AddressSet(params.controlAddress, 0xFFF)), 31 | device = device, 32 | beatBytes = params.controlBeatBytes) 33 | 34 | lazy val module = new LazyModuleImp(this) { 35 | val allow = RegInit(true.B) 36 | val pending = RegNext(bar.module.io.pending) 37 | 38 | controlNode.regmap( 39 | 0 -> Seq(RegField (32, allow, 40 | RegFieldDesc("allow", 41 | "Used to enable/disable bus transactions", reset=Some(1)))), 42 | 4 -> Seq(RegField.r(32, pending, RegFieldDesc("pending", 43 | "Indicates if bus transactions are in-flight", volatile=true))) 44 | ) 45 | 46 | bar.module.io.bypass := !allow 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/scala/stage/phases/GenerateFirrtlAnnos.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage.phases 4 | 5 | import chisel3.stage.phases.{Convert, Elaborate, MaybeAspectPhase} 6 | import firrtl.AnnotationSeq 7 | import firrtl.annotations.{Annotation, DeletedAnnotation, JsonProtocol} 8 | import firrtl.options.Viewer.view 9 | import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions, TargetDirAnnotation, Unserializable} 10 | import freechips.rocketchip.stage.RocketChipOptions 11 | import freechips.rocketchip.util.HasRocketChipStageUtils 12 | 13 | /** Writes FIRRTL annotations into a file */ 14 | class GenerateFirrtlAnnos extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { 15 | 16 | override val prerequisites = Seq( 17 | Dependency[Checks], 18 | Dependency[Elaborate], 19 | Dependency[Convert], 20 | Dependency[MaybeAspectPhase] 21 | ) 22 | 23 | override def transform(annotations: AnnotationSeq): AnnotationSeq = { 24 | val targetDir = view[StageOptions](annotations).targetDir 25 | val fileName = s"${view[RocketChipOptions](annotations).longName.get}.anno.json" 26 | 27 | val annos = scala.collection.mutable.Buffer[Annotation]() 28 | annotations.flatMap { 29 | case a: Unserializable => 30 | Some(a) 31 | case a: TargetDirAnnotation => 32 | /** Don't serialize, in case of downstream FIRRTL call */ 33 | Some(a) 34 | case a @ DeletedAnnotation(_, _: Unserializable) => 35 | /** [[DeletedAnnotation]]s of unserializable annotations cannot be serialized */ 36 | Some(a) 37 | case a => 38 | annos += a 39 | Some(a) 40 | } 41 | 42 | writeOutputFile(targetDir, fileName, JsonProtocol.serialize(annos)) 43 | 44 | annotations 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/unittest/UnitTest.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.unittest 4 | 5 | import Chisel._ 6 | import chisel3.MultiIOModule 7 | import freechips.rocketchip.config._ 8 | import freechips.rocketchip.util._ 9 | 10 | trait UnitTestIO { 11 | val finished = Bool(OUTPUT) 12 | val start = Bool(INPUT) 13 | } 14 | 15 | trait HasUnitTestIO { 16 | val io: UnitTestIO 17 | } 18 | 19 | trait UnitTestLegacyModule extends HasUnitTestIO { 20 | val io = new Bundle with UnitTestIO 21 | } 22 | 23 | trait UnitTestModule extends MultiIOModule with HasUnitTestIO { 24 | val io = IO(new Bundle with UnitTestIO) 25 | ElaborationArtefacts.add("plusArgs", PlusArgArtefacts.serialize_cHeader) 26 | } 27 | 28 | abstract class UnitTest(val timeout: Int = 4096) extends Module with UnitTestLegacyModule { 29 | val testName = this.getClass.getSimpleName 30 | 31 | when (io.start) { printf(s"Started UnitTest $testName\n") } 32 | 33 | val timed_out = SimpleTimer(timeout, io.start, io.finished) 34 | assert(!timed_out, s"UnitTest $testName timed out") 35 | } 36 | 37 | case object UnitTests extends Field[Parameters => Seq[UnitTest]] 38 | 39 | class UnitTestSuite(implicit p: Parameters) extends Module { 40 | val io = new Bundle { 41 | val finished = Bool(OUTPUT) 42 | } 43 | 44 | val tests = p(UnitTests)(p) 45 | 46 | val s_idle :: s_start :: s_busy :: s_done :: Nil = Enum(Bits(), 4) 47 | val state = Reg(init = s_idle) 48 | val tests_finished = Vec(tests.map(_.io.finished)).reduce(_&&_) 49 | 50 | tests.foreach { _.io.start := (state === s_start) } 51 | io.finished := (state === s_done) 52 | 53 | when (state === s_idle) { state := s_start } 54 | when (state === s_start) { state := s_busy } 55 | when (state === s_busy && tests_finished) { state := s_done } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Test.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.tilelink._ 9 | import freechips.rocketchip.unittest._ 10 | 11 | class RRTest0(address: BigInt)(implicit p: Parameters) extends APBRegisterRouter(address, 0, 32, 0, 4)( 12 | new APBRegBundle((), _) with RRTest0Bundle)( 13 | new APBRegModule((), _, _) with RRTest0Module) 14 | 15 | class RRTest1(address: BigInt)(implicit p: Parameters) extends APBRegisterRouter(address, 0, 32, 1, 4, false)( 16 | new APBRegBundle((), _) with RRTest1Bundle)( 17 | new APBRegModule((), _, _) with RRTest1Module) 18 | 19 | class APBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule 20 | { 21 | val fuzz = LazyModule(new TLFuzzer(txns)) 22 | val model = LazyModule(new TLRAMModel("APBFuzzMaster")) 23 | val xbar = LazyModule(new APBFanout) 24 | val ram = LazyModule(new APBRAM(AddressSet(0x0, 0xff), fuzzReady = true, fuzzError = true)) 25 | val gpio = LazyModule(new RRTest0(0x100)) 26 | 27 | ram.node := xbar.node 28 | gpio.node := xbar.node 29 | (xbar.node 30 | := TLToAPB(aFlow) 31 | := TLDelayer(0.2) 32 | := TLBuffer(BufferParams.flow) 33 | := TLDelayer(0.2) 34 | := TLFragmenter(4, 8) 35 | := model.node 36 | := fuzz.node) 37 | 38 | lazy val module = new LazyModuleImp(this) with UnitTestModule { 39 | io.finished := fuzz.module.io.finished 40 | } 41 | } 42 | 43 | class APBBridgeTest(aFlow: Boolean, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { 44 | val dut = Module(LazyModule(new APBFuzzBridge(aFlow, txns)).module) 45 | io.finished := dut.io.finished 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/regmapper/RegisterRouter.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.regmapper 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.interrupts._ 9 | import freechips.rocketchip.tilelink._ 10 | 11 | case class RegisterRouterParams( 12 | name: String, 13 | compat: Seq[String], 14 | base: BigInt, 15 | size: BigInt = 4096, 16 | concurrency: Int = 0, 17 | beatBytes: Int = 4, 18 | undefZero: Boolean = true, 19 | executable: Boolean = false) 20 | 21 | abstract class RegisterRouter(devParams: RegisterRouterParams)(implicit p: Parameters) 22 | extends LazyModule 23 | with HasClockDomainCrossing { 24 | 25 | require (isPow2(devParams.size)) 26 | val address = Seq(AddressSet(devParams.base, devParams.size-1)) 27 | val concurrency = devParams.concurrency 28 | val beatBytes = devParams.beatBytes 29 | val undefZero = devParams.undefZero 30 | val executable = devParams.executable 31 | val device = new SimpleDevice(devParams.name, devParams.compat) { 32 | override def describe(resources: ResourceBindings): Description = { 33 | val Description(name, mapping) = super.describe(resources) 34 | Description(name, mapping ++ extraResources(resources)) 35 | } 36 | } 37 | // Allow devices to extend the DTS mapping 38 | def extraResources(resources: ResourceBindings) = Map[String, Seq[ResourceValue]]() 39 | 40 | protected def regmap(mapping: RegField.Map*): Unit 41 | } 42 | 43 | abstract class IORegisterRouter[T <: Data](devParams: RegisterRouterParams, portBundle: => T)(implicit p: Parameters) 44 | extends RegisterRouter(devParams) { 45 | val ioNode = BundleBridgeSource(() => portBundle.cloneType) 46 | val port = InModuleBody { ioNode.bundle } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/tilelink/CrossingHelper.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tilelink 4 | 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.util.RationalDirection 8 | 9 | case class TLInwardCrossingHelper(name: String, scope: LazyScope, node: TLInwardNode) { 10 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): TLInwardNode = { 11 | xing match { 12 | case x: AsynchronousCrossing => 13 | node :*=* scope { TLAsyncCrossingSink(x.asSinkParams) :*=* TLAsyncNameNode(name) } :*=* TLAsyncNameNode(name) :*=* TLAsyncCrossingSource(x.sourceSync) 14 | case RationalCrossing(direction) => 15 | node :*=* scope { TLRationalCrossingSink(direction.flip) :*=* TLRationalNameNode(name) } :*=* TLRationalNameNode(name) :*=* TLRationalCrossingSource() 16 | case SynchronousCrossing(buffer) => 17 | node :*=* scope { TLBuffer(buffer) :*=* TLNameNode(name) } :*=* TLNameNode(name) 18 | } 19 | } 20 | } 21 | 22 | case class TLOutwardCrossingHelper(name: String, scope: LazyScope, node: TLOutwardNode) { 23 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): TLOutwardNode = { 24 | xing match { 25 | case x: AsynchronousCrossing => 26 | TLAsyncCrossingSink(x.asSinkParams) :*=* TLAsyncNameNode(name) :*=* scope { TLAsyncNameNode(name) :*=* TLAsyncCrossingSource(x.sourceSync) } :*=* node 27 | case RationalCrossing(direction) => 28 | TLRationalCrossingSink(direction) :*=* TLRationalNameNode(name) :*=* scope { TLRationalNameNode(name) :*=* TLRationalCrossingSource() } :*=* node 29 | case SynchronousCrossing(buffer) => 30 | TLNameNode(name) :*=* scope { TLNameNode(name) :*=* TLBuffer(buffer) } :*=* node 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /README_TRAVIS.md: -------------------------------------------------------------------------------- 1 | # Travis Notes for Administrators 2 | 3 | Administrators: Are PRs taking > 1 hr to run through Travis? If you look at the Travis logs is it building `rocket-tools`? 4 | 5 | This is because someone committed a PR to `master` which bumped `rocket-tools` and the master cache needs to be updated. 6 | This is the procedure to follow to get things fast again. We don't generally branch updates (e.g. to `master`), just PRs. 7 | 8 | To get the `master` cache good again: 9 | ---------------------------------- 10 | 11 | 1. Wait for the PR that is changing `rocket-tools` to go green. 12 | 2. On Travis, click `More Options -> Caches` on the upper right. 13 | 3. Click `Delete` for the `master` Cache. 14 | 4. Click `More Options->Settings` 15 | 5. On the `General Settings` section, switch the `Build Branch Updates` toggle to `ON`. 16 | 6. Perform the PR's merge to `master`. This will cause the `master` cache to build `rocket-tools`. 17 | 7. Once the merge commit goes green on Travis, switch the `Build Branch Updates` toggle to `OFF`. 18 | 19 | For other PRs which were happening in parallel to the bump of `rocket-tools`: 20 | ---------------------------------------------------------------------------- 21 | 22 | If your PR already has a cache and you want to keep doing development with the old version of `rocket-tools`, no action is needed. 23 | 24 | If you want to merge or rebase your PR on top of `master` with the new version of `rocket-tools`, you should delete your PR branch's local cache. Otherwise it will rebuild the branch cache instead of using `master`'s cache. To do this: 25 | 26 | 1. Wait for the previous steps to go through so that the `master` cache is done. 27 | 2. On Travis, click `More Options -> Caches` on the upper right. 28 | 3. Click `Delete` for your PR branch's cache. 29 | 4. Push updates to the PR as usual, it should download the new `master` cache. 30 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/SystemBus.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.{Parameters} 7 | import freechips.rocketchip.devices.tilelink._ 8 | import freechips.rocketchip.diplomacy._ 9 | import freechips.rocketchip.tilelink._ 10 | import freechips.rocketchip.util._ 11 | 12 | case class SystemBusParams( 13 | beatBytes: Int, 14 | blockBytes: Int, 15 | policy: TLArbiter.Policy = TLArbiter.roundRobin, 16 | dtsFrequency: Option[BigInt] = None, 17 | zeroDevice: Option[AddressSet] = None, 18 | errorDevice: Option[DevNullParams] = None, 19 | replication: Option[ReplicatedRegion] = None) 20 | extends HasTLBusParams 21 | with HasBuiltInDeviceParams 22 | with TLBusWrapperInstantiationLike 23 | { 24 | def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): SystemBus = { 25 | val sbus = LazyModule(new SystemBus(this, loc.name)) 26 | sbus.suggestName(loc.name) 27 | context.tlBusWrapperLocationMap += (loc -> sbus) 28 | sbus 29 | } 30 | } 31 | 32 | class SystemBus(params: SystemBusParams, name: String = "system_bus")(implicit p: Parameters) 33 | extends TLBusWrapper(params, name) 34 | { 35 | private val replicator = params.replication.map(r => LazyModule(new RegionReplicator(r))) 36 | val prefixNode = replicator.map(_.prefix) 37 | 38 | private val system_bus_xbar = LazyModule(new TLXbar(policy = params.policy)) 39 | val inwardNode: TLInwardNode = system_bus_xbar.node :=* TLFIFOFixer(TLFIFOFixer.allVolatile) :=* replicator.map(_.node).getOrElse(TLTempNode()) 40 | val outwardNode: TLOutwardNode = system_bus_xbar.node 41 | def busView: TLEdge = system_bus_xbar.node.edges.in.head 42 | 43 | val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/util/ClockDivider.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import chisel3._ 6 | import chisel3.withClock 7 | import chisel3.util.HasBlackBoxResource 8 | 9 | /** This black-boxes a Clock Divider by 2. 10 | * The output clock is phase-aligned to the input clock. 11 | * If you use this in synthesis, make sure your sdc 12 | * declares that you want it to do the same. 13 | * 14 | * Because Chisel does not support 15 | * blocking assignments, it is impossible 16 | * to create a deterministic divided clock. 17 | */ 18 | class ClockDivider2 extends BlackBox with HasBlackBoxResource { 19 | val io = IO(new Bundle { 20 | val clk_out = Output(Clock()) 21 | val clk_in = Input(Clock()) 22 | }) 23 | 24 | addResource("/vsrc/ClockDivider2.v") 25 | } 26 | class ClockDivider3 extends BlackBox with HasBlackBoxResource { 27 | val io = IO(new Bundle { 28 | val clk_out = Output(Clock()) 29 | val clk_in = Input(Clock()) 30 | }) 31 | 32 | addResource("/vsrc/ClockDivider3.v") 33 | } 34 | 35 | /** Divide the clock by power of 2 times. 36 | * @param pow2 divides the clock 2 ^ pow2 times */ 37 | class Pow2ClockDivider(pow2: Int) extends Module { 38 | val io = IO(new Bundle { 39 | val clock_out = Output(Clock()) 40 | }) 41 | 42 | if (pow2 == 0) { 43 | io.clock_out := clock 44 | } else { 45 | val dividers = Seq.fill(pow2) { Module(new ClockDivider2) } 46 | 47 | dividers.init.zip(dividers.tail).map { case (last, next) => 48 | next.io.clk_in := last.io.clk_out 49 | } 50 | 51 | dividers.head.io.clk_in := clock 52 | io.clock_out := dividers.last.io.clk_out 53 | } 54 | } 55 | 56 | object Pow2ClockDivider { 57 | def apply(pow2: Int): Clock = Module(new Pow2ClockDivider(pow2)).io.clock_out 58 | def apply(clock_in: Clock, pow2: Int): Clock = withClock(clock_in) { apply(pow2) } 59 | } 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to Rocket Chip 2 | ===================== 3 | 4 | Thank you for your interest in contributing to Rocket Chip! 5 | 6 | ## Table of Contents 7 | 8 | + [Bumping Submodules](#bumping) 9 | 10 | ### Bumping Submodules 11 | 12 | Several projects are managed as git submodules as well as [Wit](https://github.com/sifive/wit) dependencies. 13 | 14 | ### When to bump 15 | 16 | Most projects will be bumped by developers as needed; however, 17 | sometimes users may wish to speed up the bumping process. 18 | For more stable projects like Chisel 3 and FIRRTL, 19 | please only bump to stable branches as defined by the specific subproject. 20 | As of March 2020 these branches are `3.2.x` in Chisel 3 and `1.2.x` in FIRRTL. 21 | 22 | ### How to bump 23 | 24 | 1. Bump the Git submodule 25 | 26 | ```bash 27 | # Check out a branch (starting at rocket-chip root 28 | git checkout -b my-bumping-branch 29 | 30 | # Check out the commit of the submodule you wish to bump to 31 | cd 32 | git checkout 33 | cd .. 34 | ``` 35 | 36 | 2. Bump the Wit submodule 37 | 38 | Update the `commit` field for the specific submodule in `wit-manifest.json`. 39 | You can do this by simply editing the file in your text editor of choice. 40 | 41 | **Tip** `git -C rev-parse HEAD` will give you the commit hash 42 | 43 | 3. Commit the changes 44 | 45 | ```bash 46 | # Add and commit the submodule 47 | git add 48 | git add wit-manifest.json 49 | git commit -m "" 50 | ``` 51 | 52 | If you are bumping `Chisel 3` or `FIRRTL`, it is ideal to include some notes about 53 | major feature or performance improvements in your commit message. 54 | 55 | 4. Open a Pull Request on Github 56 | 57 | Please see the Github documentation for [Pull Requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) 58 | -------------------------------------------------------------------------------- /src/main/scala/amba/ahb/Protocol.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.ahb 4 | 5 | import Chisel._ 6 | 7 | object AHBParameters 8 | { 9 | // These are all fixed by the AHB standard: 10 | val transBits = 2 11 | val burstBits = 3 12 | val protBits = 4 13 | val sizeBits = 3 // 8*2^s 14 | val userBits = 3 15 | val hrespBits = 2 // AHB full 16 | 17 | def TRANS_IDLE = UInt(0, width = transBits) // No transfer requested, not in a burst 18 | def TRANS_BUSY = UInt(1, width = transBits) // No transfer requested, in a burst 19 | def TRANS_NONSEQ = UInt(2, width = transBits) // First (potentially only) request in a burst 20 | def TRANS_SEQ = UInt(3, width = transBits) // Following requests in a burst 21 | 22 | def BURST_SINGLE = UInt(0, width = burstBits) // Single access (no burst) 23 | def BURST_INCR = UInt(1, width = burstBits) // Incrementing burst of arbitrary length, not crossing 1KB 24 | def BURST_WRAP4 = UInt(2, width = burstBits) // 4-beat wrapping burst 25 | def BURST_INCR4 = UInt(3, width = burstBits) // 4-beat incrementing burst 26 | def BURST_WRAP8 = UInt(4, width = burstBits) // 8-beat wrapping burst 27 | def BURST_INCR8 = UInt(5, width = burstBits) // 8-beat incrementing burst 28 | def BURST_WRAP16 = UInt(6, width = burstBits) // 16-beat wrapping burst 29 | def BURST_INCR16 = UInt(7, width = burstBits) // 16-beat incrementing burst 30 | 31 | val maxTransfer = 16 32 | 33 | def RESP_OKAY = UInt(0, width=2) 34 | def RESP_ERROR = UInt(1, width=2) 35 | // Only in AHB-Full: 36 | def RESP_RETRY = UInt(2, width=2) 37 | def RESP_SPLIT = UInt(3, width=2) 38 | 39 | def PROT_DATA = UInt(1, width = protBits) 40 | def PROT_PRIVILEDGED = UInt(2, width = protBits) 41 | def PROT_BUFFERABLE = UInt(4, width = protBits) 42 | def PROT_CACHEABLE = UInt(8, width = protBits) 43 | def PROT_DEFAULT = PROT_DATA | PROT_PRIVILEDGED 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/devices/tilelink/ClockBlocker.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.devices.tilelink 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.prci._ 9 | import freechips.rocketchip.regmapper._ 10 | import freechips.rocketchip.tilelink._ 11 | import freechips.rocketchip.util._ 12 | 13 | /** This device extends a basic bus blocker by allowing it to gate the clocks of the device 14 | * whose tilelink port is being blocked. For now it is only possible to block 15 | * a single TL port and all the clocks simultaneously. 16 | */ 17 | 18 | class TLClockBlocker(params: BasicBusBlockerParams)(implicit p: Parameters) 19 | extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock) 20 | { 21 | val device = new SimpleDevice("clock-blocker", Seq("sifive,clock-blocker0")) 22 | 23 | val controlNode = TLRegisterNode( 24 | address = Seq(AddressSet(params.controlAddress, 0xFFF)), 25 | device = device, 26 | beatBytes = params.controlBeatBytes) 27 | 28 | val clockNode = ClockAdapterNode() 29 | 30 | lazy val module = new LazyModuleImp(this) { 31 | val allow = RegInit(true.B) 32 | val pending = RegNext(bar.module.io.pending) 33 | 34 | controlNode.regmap( 35 | 0 -> Seq(RegField (32, allow, 36 | RegFieldDesc("allow", 37 | "Used to enable/disable bus transactions", reset=Some(1)))), 38 | 4 -> Seq(RegField.r(32, pending, RegFieldDesc("pending", 39 | "Indicates if bus transactions are in-flight", volatile=true))) 40 | ) 41 | 42 | bar.module.io.bypass := !allow 43 | 44 | val (clock_in, _) = clockNode.in.unzip 45 | val (clock_out, _) = clockNode.out.unzip 46 | 47 | (clock_in zip clock_out) foreach { case (i, o) => 48 | o.clock := ClockGate(i.clock, allow || pending) 49 | o.reset := i.reset 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/scala/util/GeneratorUtils.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import java.io.{File, FileWriter} 6 | 7 | import Chisel.throwException 8 | import chipsalliance.rocketchip.config.{Config, Parameters} 9 | import chisel3.internal.firrtl.Circuit 10 | 11 | trait HasRocketChipStageUtils { 12 | 13 | def getConfig(fullConfigClassNames: Seq[String]): Config = { 14 | new Config(fullConfigClassNames.foldRight(Parameters.empty) { case (currentName, config) => 15 | val currentConfig = try { 16 | Class.forName(currentName).newInstance.asInstanceOf[Config] 17 | } catch { 18 | case e: java.lang.ClassNotFoundException => 19 | throwException(s"""Unable to find part "$currentName" from "$fullConfigClassNames", did you misspell it?""", e) 20 | } 21 | currentConfig ++ config 22 | }) 23 | } 24 | 25 | def enumerateROMs(circuit: Circuit): String = { 26 | val res = new StringBuilder 27 | val configs = 28 | circuit.components flatMap { m => 29 | m.id match { 30 | case rom: BlackBoxedROM => Some((rom.name, ROMGenerator.lookup(rom))) 31 | case _ => None 32 | } 33 | } 34 | configs foreach { case (name, c) => 35 | res append s"name ${name} depth ${c.depth} width ${c.width}\n" 36 | } 37 | res.toString 38 | } 39 | 40 | def writeOutputFile(targetDir: String, fname: String, contents: String): File = { 41 | val f = new File(targetDir, fname) 42 | val fw = new FileWriter(f) 43 | fw.write(contents) 44 | fw.close 45 | f 46 | } 47 | 48 | } 49 | 50 | object ElaborationArtefacts { 51 | var files: Seq[(String, () => String)] = Nil 52 | 53 | def add(extension: String, contents: => String) { 54 | files = (extension, () => contents) +: files 55 | } 56 | 57 | def contains(extension: String): Boolean = { 58 | files.foldLeft(false)((t, s) => {s._1 == extension | t}) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/scala/interrupts/CrossingHelper.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.interrupts 4 | 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | 8 | case class IntInwardCrossingHelper(name: String, scope: LazyScope, node: IntInwardNode) { 9 | def apply(xing: ClockCrossingType = NoCrossing, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntInwardNode = { 10 | xing match { 11 | case x: AsynchronousCrossing => 12 | node :*=* scope { IntSyncAsyncCrossingSink(x.sinkSync) :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) 13 | case RationalCrossing(_) => 14 | node :*=* scope { IntSyncRationalCrossingSink() :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) 15 | case SynchronousCrossing(_) => 16 | node :*=* scope { IntSyncSyncCrossingSink() :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) 17 | } 18 | } 19 | } 20 | 21 | case class IntOutwardCrossingHelper(name: String, scope: LazyScope, node: IntOutwardNode) { 22 | def apply(xing: ClockCrossingType = NoCrossing, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntOutwardNode = { 23 | xing match { 24 | case x: AsynchronousCrossing => 25 | IntSyncAsyncCrossingSink(x.sinkSync) :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node 26 | case RationalCrossing(_) => 27 | IntSyncRationalCrossingSink() :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node 28 | case SynchronousCrossing(buffer) => 29 | IntSyncSyncCrossingSink() :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/scala/system/SimAXIMem.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.system // TODO this should really be in a testharness package 4 | 5 | import chisel3._ 6 | import freechips.rocketchip.amba._ 7 | import freechips.rocketchip.amba.axi4._ 8 | import freechips.rocketchip.config.{Parameters} 9 | import freechips.rocketchip.diplomacy._ 10 | import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MMIOPort, CanHaveMasterAXI4MemPort, ExtMem} 11 | 12 | /** Memory with AXI port for use in elaboratable test harnesses. */ 13 | class SimAXIMem(edge: AXI4EdgeParameters, size: BigInt)(implicit p: Parameters) extends SimpleLazyModule { 14 | val node = AXI4MasterNode(List(edge.master)) 15 | val srams = AddressSet.misaligned(0, size).map { aSet => 16 | LazyModule(new AXI4RAM( 17 | address = aSet, 18 | beatBytes = edge.bundle.dataBits/8, 19 | wcorrupt=edge.slave.requestKeys.contains(AMBACorrupt))) 20 | } 21 | val xbar = AXI4Xbar() 22 | srams.foreach{ s => s.node := AXI4Buffer() := AXI4Fragmenter() := xbar } 23 | xbar := node 24 | val io_axi4 = InModuleBody { node.makeIOs() } 25 | } 26 | 27 | object SimAXIMem { 28 | def connectMMIO(dut: CanHaveMasterAXI4MMIOPort)(implicit p: Parameters): Seq[SimAXIMem] = { 29 | dut.mmio_axi4.zip(dut.mmioAXI4Node.in).map { case (io, (_, edge)) => 30 | // test harness size capped to 4KB (ignoring p(ExtMem).get.master.size) 31 | val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)) 32 | Module(mmio_mem.module).suggestName("mmio_mem") 33 | mmio_mem.io_axi4.head <> io 34 | mmio_mem 35 | } 36 | } 37 | 38 | def connectMem(dut: CanHaveMasterAXI4MemPort)(implicit p: Parameters): Seq[SimAXIMem] = { 39 | dut.mem_axi4.zip(dut.memAXI4Node.in).map { case (io, (_, edge)) => 40 | val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)) 41 | Module(mem.module).suggestName("mem") 42 | mem.io_axi4.head <> io 43 | mem 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/util/ResetCatchAndSync.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | import chisel3.{withClockAndReset, withReset} 7 | 8 | /** Reset: asynchronous assert, 9 | * synchronous de-assert 10 | * 11 | */ 12 | 13 | class ResetCatchAndSync (sync: Int = 3) extends Module { 14 | 15 | override def desiredName = s"ResetCatchAndSync_d${sync}" 16 | 17 | val io = new Bundle { 18 | val sync_reset = Bool(OUTPUT) 19 | val psd = new PSDTestMode().asInput 20 | } 21 | 22 | // Bypass both the resets to the flops themselves (to prevent DFT holes on 23 | // those flops) and on the output of the synchronizer circuit (to control 24 | // reset to any flops this circuit drives). 25 | 26 | val post_psd_reset = Mux(io.psd.test_mode, io.psd.test_mode_reset, reset) 27 | withReset(post_psd_reset) { 28 | io.sync_reset := Mux(io.psd.test_mode, io.psd.test_mode_reset, 29 | ~AsyncResetSynchronizerShiftReg(Bool(true), sync)) 30 | } 31 | } 32 | 33 | object ResetCatchAndSync { 34 | 35 | def apply(clk: Clock, rst: Bool, sync: Int = 3, name: Option[String] = None, 36 | psd: Option[PSDTestMode] = None): Bool = { 37 | 38 | withClockAndReset(clk, rst) { 39 | val catcher = Module (new ResetCatchAndSync(sync)) 40 | if (name.isDefined) {catcher.suggestName(name.get)} 41 | catcher.io.psd <> psd.getOrElse(Wire(new PSDTestMode()).fromBits(UInt(0))) 42 | catcher.io.sync_reset 43 | } 44 | } 45 | 46 | def apply(clk: Clock, rst: Bool, sync: Int, name: String): Bool = apply(clk, rst, sync, Some(name)) 47 | def apply(clk: Clock, rst: Bool, name: String): Bool = apply(clk, rst, name = Some(name)) 48 | 49 | def apply(clk: Clock, rst: Bool, sync: Int, name: String, psd: PSDTestMode): Bool = 50 | apply(clk, rst, sync, Some(name), Some(psd)) 51 | def apply(clk: Clock, rst: Bool, name: String, psd: PSDTestMode): Bool = 52 | apply(clk, rst, name = Some(name), psd = Some(psd)) 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/scala/stage/RocketChipAnnotations.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.stage 4 | 5 | import chisel3.experimental.BaseModule 6 | import firrtl.annotations.{Annotation, NoTargetAnnotation} 7 | import firrtl.options.{HasShellOptions, ShellOption, Unserializable} 8 | 9 | sealed trait RocketChipOption extends Unserializable { this: Annotation => } 10 | 11 | /* required options */ 12 | 13 | /** Path to top module class */ 14 | case class TopModuleAnnotation(clazz: Class[_ <: Any]) extends NoTargetAnnotation with RocketChipOption 15 | private[stage] object TopModuleAnnotation extends HasShellOptions { 16 | override val options = Seq( 17 | new ShellOption[String]( 18 | longOption = "top-module", 19 | toAnnotationSeq = a => Seq(TopModuleAnnotation(Class.forName(a).asInstanceOf[Class[_ <: BaseModule]])), 20 | helpText = "", 21 | shortOption = Some("T") 22 | ) 23 | ) 24 | } 25 | 26 | /** Paths to config classes */ 27 | case class ConfigsAnnotation(configNames: Seq[String]) extends NoTargetAnnotation with RocketChipOption 28 | private[stage] object ConfigsAnnotation extends HasShellOptions { 29 | override val options = Seq( 30 | new ShellOption[Seq[String]]( 31 | longOption = "configs", 32 | toAnnotationSeq = a => Seq(ConfigsAnnotation(a)), 33 | helpText = "", 34 | shortOption = Some("C") 35 | ) 36 | ) 37 | } 38 | 39 | /* optional options */ 40 | 41 | /** Optional base name for generated files' filenames */ 42 | case class OutputBaseNameAnnotation(outputBaseName: String) extends NoTargetAnnotation with RocketChipOption 43 | private[stage] object OutputBaseNameAnnotation extends HasShellOptions { 44 | override val options = Seq( 45 | new ShellOption[String]( 46 | longOption = "name", 47 | toAnnotationSeq = a => Seq(OutputBaseNameAnnotation(a)), 48 | helpText = "", 49 | shortOption = Some("n") 50 | ) 51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/JSON.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | import scala.collection.immutable.SortedMap 6 | 7 | object JSON 8 | { 9 | def apply(res: ResourceValue): String = { 10 | val root = res match { 11 | case ResourceMap(value, _) => value.toList match { 12 | case Seq(("/", Seq(subtree))) => subtree 13 | case _ => res 14 | } 15 | case _ => res 16 | } 17 | helper(root)(SortedMap(map(root):_*)).mkString 18 | } 19 | 20 | private def map(res: ResourceValue, path: String = ""): Seq[(String, String)] = res match { 21 | case ResourceMap(value, labels) => { 22 | labels.map(_ -> path) ++ 23 | value.flatMap { case (key, seq) => seq.flatMap(map(_, path + "/" + key)) } 24 | } 25 | case _ => Nil 26 | } 27 | 28 | private def helper(res: ResourceValue)(implicit path: Map[String, String]): Seq[String] = res match { 29 | case ResourceAddress(address, ResourcePermissions(r, w, x, c, a)) => 30 | AddressRange.fromSets(address).map { case AddressRange(base, size) => 31 | s"""{"base":${base},"size":${size},"r":${r},"w":${w},"x":${x},"c":${c},"a":${a}}"""} 32 | case ResourceMapping(address, offset, ResourcePermissions(r, w, x, c, a)) => 33 | AddressRange.fromSets(address).map { case AddressRange(base, size) => 34 | s"""{"base":${base},"size":${size},"offset":${offset},"r":${r},"w":${w},"x":${x},"c":${c},"a":${a}}"""} 35 | case ResourceInt(value) => Seq(value.toString) 36 | case ResourceString(value) => Seq("\"" + value + "\"") 37 | case ResourceReference(value) => Seq("\"&" + path(value) + "\"") 38 | case ResourceAlias(value) => Seq("\"&" + path(value) + "\"") 39 | case ResourceMap(value, _) => { 40 | Seq(value.map { 41 | case (key, Seq(v: ResourceMap)) => s""""${key}":${helper(v).mkString}""" 42 | case (key, seq) => s""""${key}":[${seq.flatMap(helper).mkString(",")}]""" 43 | }.mkString("{", ",", "}")) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/tile/CustomCSRs.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.tile 4 | 5 | import chisel3._ 6 | 7 | import freechips.rocketchip.config.Parameters 8 | 9 | case class CustomCSR(id: Int, mask: BigInt, init: Option[BigInt]) 10 | 11 | object CustomCSR { 12 | def constant(id: Int, value: BigInt): CustomCSR = CustomCSR(id, BigInt(0), Some(value)) 13 | } 14 | 15 | class CustomCSRIO(implicit p: Parameters) extends CoreBundle { 16 | val wen = Bool() 17 | val wdata = UInt(xLen.W) 18 | val value = UInt(xLen.W) 19 | } 20 | 21 | class CustomCSRs(implicit p: Parameters) extends CoreBundle { 22 | // Not all cores have these CSRs, but those that do should follow the same 23 | // numbering conventions. So we list them here but default them to None. 24 | protected def bpmCSRId = 0x7c0 25 | protected def bpmCSR: Option[CustomCSR] = None 26 | 27 | protected def chickenCSRId = 0x7c1 28 | protected def chickenCSR: Option[CustomCSR] = None 29 | 30 | // If you override this, you'll want to concatenate super.decls 31 | def decls: Seq[CustomCSR] = bpmCSR.toSeq ++ chickenCSR 32 | 33 | val csrs = Vec(decls.size, new CustomCSRIO) 34 | 35 | def flushBTB = getOrElse(bpmCSR, _.wen, false.B) 36 | def bpmStatic = getOrElse(bpmCSR, _.value(0), false.B) 37 | def disableDCacheClockGate = getOrElse(chickenCSR, _.value(0), false.B) 38 | def disableICacheClockGate = getOrElse(chickenCSR, _.value(1), false.B) 39 | def disableCoreClockGate = getOrElse(chickenCSR, _.value(2), false.B) 40 | def disableSpeculativeICacheRefill = getOrElse(chickenCSR, _.value(3), false.B) 41 | def suppressCorruptOnGrantData = getOrElse(chickenCSR, _.value(9), false.B) 42 | 43 | protected def getByIdOrElse[T](id: Int, f: CustomCSRIO => T, alt: T): T = { 44 | val idx = decls.indexWhere(_.id == id) 45 | if (idx < 0) alt else f(csrs(idx)) 46 | } 47 | 48 | protected def getOrElse[T](csr: Option[CustomCSR], f: CustomCSRIO => T, alt: T): T = 49 | csr.map(c => getByIdOrElse(c.id, f, alt)).getOrElse(alt) 50 | } 51 | -------------------------------------------------------------------------------- /scripts/tracegen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This file was originally written by Matthew Naylor, University of 4 | # Cambridge. 5 | # 6 | # This software was partly developed by the University of Cambridge 7 | # Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 8 | # ("CTSRD"), as part of the DARPA CRASH research programme. 9 | # 10 | # This software was partly developed by the University of Cambridge 11 | # Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 12 | # ("MRC2"), as part of the DARPA MRC research programme. 13 | # 14 | # This software was partly developed by the University of Cambridge 15 | # Computer Laboratory as part of the Rigorous Engineering of 16 | # Mainstream Systems (REMS) project, funded by EPSRC grant 17 | # EP/K008528/1. 18 | 19 | # ------- 20 | # Outline 21 | # ------- 22 | 23 | # Usage: 24 | # 25 | # tracegen.py EMULATOR SEED 26 | # 27 | # This script generates a trace using the given emulator (built 28 | # with CONFIG=TraceGenConfig). It waits until all cores have 29 | # completed trace generation before terminating the emulator. 30 | 31 | import sys 32 | import subprocess 33 | import re 34 | 35 | def main(): 36 | if len(sys.argv) != 3: 37 | sys.stderr.write("Usage: tracegen.py EMULATOR SEED\n") 38 | sys.exit(-1) 39 | 40 | p = subprocess.Popen([sys.argv[1], 41 | "+verbose", "-s" + sys.argv[2]], 42 | stderr=subprocess.PIPE, stdout=subprocess.PIPE) 43 | if p == None: 44 | sys.stderr.write("File not found: " + sys.argv[1] + "\n") 45 | sys.exit(-1) 46 | 47 | numFinished = 0 48 | while True: 49 | line = p.stderr.readline() 50 | if line[0:9] == "FINISHED ": 51 | total = int(line[9:-1]) 52 | numFinished = numFinished + 1 53 | if numFinished == total: 54 | break 55 | elif line[0:15] == "Completed after": 56 | break 57 | elif line[0:7] == "testing": 58 | continue 59 | else: 60 | print line, 61 | 62 | p.terminate() 63 | 64 | try: 65 | main() 66 | except KeyboardInterrupt: 67 | sys.exit(-1) 68 | -------------------------------------------------------------------------------- /src/main/scala/diplomacy/SRAM.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomacy 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomaticobjectmodel.DiplomaticObjectModelAddressing 8 | import freechips.rocketchip.diplomaticobjectmodel.model._ 9 | import freechips.rocketchip.util.DescribedSRAM 10 | 11 | abstract class DiplomaticSRAM( 12 | address: AddressSet, 13 | beatBytes: Int, 14 | devName: Option[String], 15 | dtsCompat: Option[Seq[String]] = None)(implicit p: Parameters) extends LazyModule 16 | { 17 | val device = devName 18 | .map(new SimpleDevice(_, dtsCompat.getOrElse(Seq("sifive,sram0")))) 19 | .getOrElse(new MemoryDevice()) 20 | 21 | def getOMMemRegions(resourceBindings: ResourceBindings): Seq[OMMemoryRegion] = { 22 | DiplomaticObjectModelAddressing.getOMMemoryRegions(devName.getOrElse(""), resourceBindings) // TODO name source??? 23 | } 24 | 25 | val resources = device.reg("mem") 26 | 27 | def bigBits(x: BigInt, tail: List[Boolean] = Nil): List[Boolean] = 28 | if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) 29 | 30 | def mask: List[Boolean] = bigBits(address.mask >> log2Ceil(beatBytes)) 31 | 32 | // Use single-ported memory with byte-write enable 33 | def makeSinglePortedByteWriteSeqMem(size: BigInt, lanes: Int = beatBytes, bits: Int = 8) = { 34 | // We require the address range to include an entire beat (for the write mask) 35 | 36 | val (mem, omSRAM) = DescribedSRAM( 37 | name = devName.getOrElse("mem"), 38 | desc = devName.getOrElse("mem"), 39 | size = size, 40 | data = Vec(lanes, UInt(width = bits)) 41 | ) 42 | devName.foreach(n => mem.suggestName(n.split("-").last)) 43 | 44 | val omMem: OMMemory = DiplomaticObjectModelAddressing.makeOMMemory( 45 | desc = "mem", //lim._2.name.map(n => n).getOrElse(lim._1.name), 46 | depth = size, 47 | data = Vec(lanes, UInt(width = bits)) 48 | ) 49 | 50 | (mem, omSRAM, Seq(omMem)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/scala/diplomaticobjectmodel/model/ISASpecifications.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.diplomaticobjectmodel.model 4 | 5 | import freechips.rocketchip.util.BooleanToAugmentedBoolean 6 | import freechips.rocketchip.tile.CoreParams 7 | 8 | sealed trait PrivilegedArchitectureExtension extends OMEnum 9 | case object MachineLevelISA extends PrivilegedArchitectureExtension 10 | case object SupervisorLevelISA extends PrivilegedArchitectureExtension 11 | 12 | object PrivilegedArchitectureExtensions { 13 | val specifications = Map[PrivilegedArchitectureExtension, String]( 14 | MachineLevelISA -> "Machine-Level ISA", 15 | SupervisorLevelISA -> "Supervisor-Level ISA" 16 | ) 17 | 18 | def specVersion(extension: PrivilegedArchitectureExtension, version: String): OMSpecification = OMSpecification(specifications(extension), version) 19 | } 20 | 21 | object BaseExtensions { 22 | val specifications = Map[OMBaseInstructionSet, String]( 23 | RV32E -> "RV32E Base Integer Instruction Set", 24 | RV32I -> "RV32I Base Integer Instruction Set", 25 | RV64E -> "RV64E Base Integer Instruction Set", 26 | RV64I -> "RV64I Base Integer Instruction Set" 27 | ) 28 | 29 | def specVersion(extension: OMBaseInstructionSet, version: String): OMSpecification = OMSpecification(specifications(extension), version) 30 | } 31 | 32 | object ISAExtensions { 33 | val specifications = Map[OMExtensionType, String]( 34 | M -> "M Standard Extension for Integer Multiplication and Division", 35 | A -> "A Standard Extension for Atomic Instruction", 36 | F -> "F Standard Extension for Single-Precision Floating-Point", 37 | D -> "D Standard Extension for Double-Precision Floating-Point", 38 | C -> "C Standard Extension for Compressed Instruction", 39 | U -> "The RISC‑V Instruction Set Manual, Volume II: Privileged Architecture", 40 | S -> "Supervisor-Level ISA" 41 | ) 42 | 43 | def specVersion(extension: OMExtensionType, version: String): OMSpecification = OMSpecification(specifications(extension), version) 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/scala/groundtest/DummyPTW.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | package freechips.rocketchip.groundtest 5 | 6 | import Chisel._ 7 | 8 | import freechips.rocketchip.config.Parameters 9 | import freechips.rocketchip.rocket._ 10 | import freechips.rocketchip.tile.CoreModule 11 | import freechips.rocketchip.util.ParameterizedBundle 12 | 13 | class DummyPTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { 14 | val io = new Bundle { 15 | val requestors = Vec(n, new TLBPTWIO).flip 16 | } 17 | 18 | val req_arb = Module(new RRArbiter(Valid(new PTWReq), n)) 19 | req_arb.io.in <> io.requestors.map(_.req) 20 | req_arb.io.out.ready := Bool(true) 21 | 22 | def vpn_to_ppn(vpn: UInt): UInt = vpn(ppnBits - 1, 0) 23 | 24 | class QueueChannel extends ParameterizedBundle()(p) { 25 | val ppn = UInt(width = ppnBits) 26 | val chosen = UInt(width = log2Up(n)) 27 | } 28 | 29 | val s1_ppn = vpn_to_ppn(req_arb.io.out.bits.bits.addr) 30 | val s2_ppn = RegEnable(s1_ppn, req_arb.io.out.valid) 31 | val s2_chosen = RegEnable(req_arb.io.chosen, req_arb.io.out.valid) 32 | val s2_valid = Reg(next = req_arb.io.out.valid && req_arb.io.out.bits.valid) 33 | 34 | val s2_resp = Wire(init = 0.U.asTypeOf(new PTWResp)) 35 | s2_resp.pte.ppn := s2_ppn 36 | s2_resp.pte.reserved_for_software := UInt(0) 37 | s2_resp.level := UInt(pgLevels-1) 38 | s2_resp.pte.d := Bool(true) 39 | s2_resp.pte.a := Bool(true) 40 | s2_resp.pte.g := Bool(false) 41 | s2_resp.pte.u := Bool(true) 42 | s2_resp.pte.r := Bool(true) 43 | s2_resp.pte.w := Bool(true) 44 | s2_resp.pte.x := Bool(false) 45 | s2_resp.pte.v := Bool(true) 46 | 47 | io.requestors.zipWithIndex.foreach { case (requestor, i) => 48 | requestor.resp.valid := s2_valid && s2_chosen === UInt(i) 49 | requestor.resp.bits := s2_resp 50 | requestor.status := 0.U.asTypeOf(requestor.status) 51 | requestor.ptbr.mode := requestor.ptbr.pgLevelsToMode(pgLevels).U 52 | requestor.ptbr.asid := UInt(0) 53 | requestor.ptbr.ppn := UInt(0) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/resources/vsrc/AsyncResetReg.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes an Async Reset 4 | * Reg. 5 | * 6 | * Because Chisel doesn't support 7 | * parameterized black boxes, 8 | * we unfortunately have to 9 | * instantiate a number of these. 10 | * 11 | * We also have to hard-code the set/reset. 12 | * 13 | * Do not confuse an asynchronous 14 | * reset signal with an asynchronously 15 | * reset reg. You should still 16 | * properly synchronize your reset 17 | * deassertion. 18 | * 19 | * @param d Data input 20 | * @param q Data Output 21 | * @param clk Clock Input 22 | * @param rst Reset Input 23 | * @param en Write Enable Input 24 | * 25 | */ 26 | 27 | `ifdef RANDOMIZE_GARBAGE_ASSIGN 28 | `define RANDOMIZE 29 | `endif 30 | `ifdef RANDOMIZE_INVALID_ASSIGN 31 | `define RANDOMIZE 32 | `endif 33 | `ifdef RANDOMIZE_REG_INIT 34 | `define RANDOMIZE 35 | `endif 36 | `ifdef RANDOMIZE_MEM_INIT 37 | `define RANDOMIZE 38 | `endif 39 | 40 | module AsyncResetReg (d, q, en, clk, rst); 41 | parameter RESET_VALUE = 0; 42 | 43 | input wire d; 44 | output reg q; 45 | input wire en; 46 | input wire clk; 47 | input wire rst; 48 | 49 | // There is a lot of initialization 50 | // here you don't normally find in Verilog 51 | // async registers because of scenarios in which reset 52 | // is not actually asserted cleanly at time 0, 53 | // and we want to make sure to properly model 54 | // that, yet Chisel codebase is absolutely intolerant 55 | // of Xs. 56 | `ifndef SYNTHESIS 57 | initial begin:B0 58 | `ifdef RANDOMIZE 59 | integer initvar; 60 | reg [31:0] _RAND; 61 | _RAND = {1{$random}}; 62 | q = _RAND[0]; 63 | `endif // RANDOMIZE 64 | if (rst) begin 65 | q = RESET_VALUE[0]; 66 | end 67 | end 68 | `endif 69 | 70 | always @(posedge clk or posedge rst) begin 71 | 72 | if (rst) begin 73 | q <= RESET_VALUE[0]; 74 | end else if (en) begin 75 | q <= d; 76 | end 77 | end 78 | 79 | endmodule // AsyncResetReg 80 | 81 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/MemoryBus.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config._ 7 | import freechips.rocketchip.devices.tilelink._ 8 | import freechips.rocketchip.diplomacy._ 9 | import freechips.rocketchip.interrupts._ 10 | import freechips.rocketchip.tilelink._ 11 | import freechips.rocketchip.util._ 12 | 13 | /** Parameterization of the memory-side bus created for each memory channel */ 14 | case class MemoryBusParams( 15 | beatBytes: Int, 16 | blockBytes: Int, 17 | dtsFrequency: Option[BigInt] = None, 18 | zeroDevice: Option[AddressSet] = None, 19 | errorDevice: Option[DevNullParams] = None, 20 | replication: Option[ReplicatedRegion] = None) 21 | extends HasTLBusParams 22 | with HasBuiltInDeviceParams 23 | with HasRegionReplicatorParams 24 | with TLBusWrapperInstantiationLike 25 | { 26 | def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): MemoryBus = { 27 | val mbus = LazyModule(new MemoryBus(this, loc.name)) 28 | mbus.suggestName(loc.name) 29 | context.tlBusWrapperLocationMap += (loc -> mbus) 30 | mbus 31 | } 32 | } 33 | 34 | /** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ 35 | class MemoryBus(params: MemoryBusParams, name: String = "memory_bus")(implicit p: Parameters) 36 | extends TLBusWrapper(params, name)(p) 37 | { 38 | private val replicator = params.replication.map(r => LazyModule(new RegionReplicator(r))) 39 | val prefixNode = replicator.map(_.prefix) 40 | 41 | private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar") 42 | val inwardNode: TLInwardNode = 43 | replicator.map(xbar.node :*=* TLFIFOFixer(TLFIFOFixer.all) :*=* _.node) 44 | .getOrElse(xbar.node :*=* TLFIFOFixer(TLFIFOFixer.all)) 45 | 46 | val outwardNode: TLOutwardNode = ProbePicker() :*= xbar.node 47 | def busView: TLEdge = xbar.node.edges.in.head 48 | 49 | val builtInDevices: BuiltInDevices = BuiltInDevices.attach(params, outwardNode) 50 | } 51 | -------------------------------------------------------------------------------- /src/main/scala/util/HellaQueue.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | package freechips.rocketchip.util 4 | 5 | import Chisel._ 6 | 7 | class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Module { 8 | val io = new QueueIO(data, entries) 9 | require(entries > 1) 10 | 11 | val do_flow = Wire(Bool()) 12 | val do_enq = io.enq.fire() && !do_flow 13 | val do_deq = io.deq.fire() && !do_flow 14 | 15 | val maybe_full = Reg(init=Bool(false)) 16 | val enq_ptr = Counter(do_enq, entries)._1 17 | val (deq_ptr, deq_done) = Counter(do_deq, entries) 18 | when (do_enq =/= do_deq) { maybe_full := do_enq } 19 | 20 | val ptr_match = enq_ptr === deq_ptr 21 | val empty = ptr_match && !maybe_full 22 | val full = ptr_match && maybe_full 23 | val atLeastTwo = full || enq_ptr - deq_ptr >= UInt(2) 24 | do_flow := empty && io.deq.ready 25 | 26 | val ram = SeqMem(entries, data) 27 | when (do_enq) { ram.write(enq_ptr, io.enq.bits) } 28 | 29 | // BUG! does not hold the output of the SRAM when !ready 30 | // ... However, HellaQueue is correct due to the pipe stage 31 | val ren = io.deq.ready && (atLeastTwo || !io.deq.valid && !empty) 32 | val raddr = Mux(io.deq.valid, Mux(deq_done, UInt(0), deq_ptr + UInt(1)), deq_ptr) 33 | val ram_out_valid = Reg(next = ren) 34 | 35 | io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid) 36 | io.enq.ready := !full 37 | io.deq.bits := Mux(empty, io.enq.bits, ram.read(raddr, ren)) 38 | } 39 | 40 | class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Module { 41 | val io = new QueueIO(data, entries) 42 | 43 | val fq = Module(new HellaFlowQueue(entries)(data)) 44 | fq.io.enq <> io.enq 45 | io.deq <> Queue(fq.io.deq, 1, pipe = true) 46 | } 47 | 48 | object HellaQueue { 49 | def apply[T <: Data](enq: DecoupledIO[T], entries: Int) = { 50 | val q = Module((new HellaQueue(entries)) { enq.bits }) 51 | q.io.enq.valid := enq.valid // not using <> so that override is allowed 52 | q.io.enq.bits := enq.bits 53 | enq.ready := q.io.enq.ready 54 | q.io.deq 55 | } 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Xbar.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import Chisel._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.diplomacy._ 8 | import freechips.rocketchip.util._ 9 | import freechips.rocketchip.regmapper._ 10 | import scala.math.{min,max} 11 | 12 | class APBFanout()(implicit p: Parameters) extends LazyModule { 13 | val node = APBNexusNode( 14 | masterFn = { case Seq(m) => m }, 15 | slaveFn = { seq => 16 | seq(0).copy( 17 | slaves = seq.flatMap(_.slaves), 18 | requestKeys = seq.flatMap(_.requestKeys).distinct, 19 | responseFields = BundleField.union(seq.flatMap(_.responseFields))) }) 20 | 21 | lazy val module = new LazyModuleImp(this) { 22 | if (node.edges.in.size >= 1) { 23 | require (node.edges.in.size == 1, "APBFanout does not support multiple masters") 24 | require (node.edges.out.size > 0, "APBFanout requires at least one slave") 25 | 26 | val (in, _) = node.in(0) 27 | 28 | // Require consistent bus widths 29 | val (io_out, edgesOut) = node.out.unzip 30 | val port0 = edgesOut(0).slave 31 | edgesOut.foreach { edge => 32 | val port = edge.slave 33 | require (port.beatBytes == port0.beatBytes, 34 | s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}") 35 | } 36 | 37 | val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten) 38 | val routingMask = AddressDecoder(port_addrs) 39 | val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct) 40 | 41 | val sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _))) 42 | (sel zip io_out) foreach { case (sel, out) => 43 | out :<> in 44 | out.psel := sel && in.psel 45 | out.penable := sel && in.penable 46 | } 47 | 48 | in.pready := !Mux1H(sel, io_out.map(!_.pready)) 49 | in.pslverr := Mux1H(sel, io_out.map(_.pslverr)) 50 | in.prdata := Mux1H(sel, io_out.map(_.prdata)) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/scala/amba/apb/Nodes.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.apb 4 | 5 | import Chisel._ 6 | import chisel3.internal.sourceinfo.SourceInfo 7 | import freechips.rocketchip.config.{Parameters, Field} 8 | import freechips.rocketchip.diplomacy._ 9 | 10 | case object APBMonitorBuilder extends Field[APBMonitorArgs => APBMonitorBase] 11 | 12 | object APBImp extends SimpleNodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] 13 | { 14 | def edge(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = APBEdgeParameters(pd, pu, p, sourceInfo) 15 | def bundle(e: APBEdgeParameters) = APBBundle(e.bundle) 16 | def render(e: APBEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, (e.slave.beatBytes * 8).toString) 17 | 18 | override def monitor(bundle: APBBundle, edge: APBEdgeParameters) { 19 | edge.params.lift(APBMonitorBuilder).foreach { builder => 20 | val monitor = Module(builder(APBMonitorArgs(edge))) 21 | monitor.io.in := bundle 22 | } 23 | } 24 | 25 | override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters = 26 | pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) 27 | override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters = 28 | pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) }) 29 | } 30 | 31 | case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams) 32 | case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams) 33 | case class APBNexusNode( 34 | masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters, 35 | slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters)( 36 | implicit valName: ValName) 37 | extends NexusNode(APBImp)(masterFn, slaveFn) 38 | 39 | case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)() 40 | -------------------------------------------------------------------------------- /src/main/scala/amba/axis/Nodes.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axis 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | import chisel3.internal.sourceinfo.SourceInfo 8 | import freechips.rocketchip.config.Parameters 9 | import freechips.rocketchip.diplomacy._ 10 | 11 | object AXISImp extends SimpleNodeImp[AXISMasterPortParameters, AXISSlavePortParameters, AXISEdgeParameters, AXISBundle] 12 | { 13 | def edge(pd: AXISMasterPortParameters, pu: AXISSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = AXISEdgeParameters.v1(pd, pu, p, sourceInfo) 14 | def bundle(e: AXISEdgeParameters) = AXISBundle(e.bundle) 15 | def render(e: AXISEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, (e.beatBytes * 8).toString) 16 | 17 | override def mixO(pd: AXISMasterPortParameters, node: OutwardNode[AXISMasterPortParameters, AXISSlavePortParameters, AXISBundle]): AXISMasterPortParameters = 18 | pd.v1copy(masters = pd.masters.map { c => c.v1copy (nodePath = node +: c.nodePath) }) 19 | override def mixI(pu: AXISSlavePortParameters, node: InwardNode[AXISMasterPortParameters, AXISSlavePortParameters, AXISBundle]): AXISSlavePortParameters = 20 | pu.v1copy(slaves = pu.slaves.map { m => m.v1copy (nodePath = node +: m.nodePath) }) 21 | } 22 | 23 | case class AXISMasterNode(portParams: Seq[AXISMasterPortParameters])(implicit valName: ValName) extends SourceNode(AXISImp)(portParams) 24 | case class AXISSlaveNode(portParams: Seq[AXISSlavePortParameters])(implicit valName: ValName) extends SinkNode(AXISImp)(portParams) 25 | case class AXISNexusNode( 26 | masterFn: Seq[AXISMasterPortParameters] => AXISMasterPortParameters, 27 | slaveFn: Seq[AXISSlavePortParameters] => AXISSlavePortParameters)( 28 | implicit valName: ValName) 29 | extends NexusNode(AXISImp)(masterFn, slaveFn) 30 | 31 | case class AXISAdapterNode( 32 | masterFn: AXISMasterPortParameters => AXISMasterPortParameters = { m => m }, 33 | slaveFn: AXISSlavePortParameters => AXISSlavePortParameters = { s => s })( 34 | implicit valName: ValName) 35 | extends AdapterNode(AXISImp)(masterFn, slaveFn) 36 | case class AXISIdentityNode()(implicit valName: ValName) extends IdentityNode(AXISImp)() 37 | -------------------------------------------------------------------------------- /src/main/scala/util/Counters.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | // See LICENSE.SiFive for license details. 3 | 4 | package freechips.rocketchip.util 5 | 6 | import Chisel._ 7 | import scala.math.max 8 | 9 | // Produces 0-width value when counting to 1 10 | class ZCounter(val n: Int) { 11 | val value = Reg(init=UInt(0, log2Ceil(n))) 12 | def inc(): Bool = { 13 | if (n == 1) Bool(true) 14 | else { 15 | val wrap = value === UInt(n-1) 16 | value := Mux(Bool(!isPow2(n)) && wrap, UInt(0), value + UInt(1)) 17 | wrap 18 | } 19 | } 20 | } 21 | 22 | object ZCounter { 23 | def apply(n: Int) = new ZCounter(n) 24 | def apply(cond: Bool, n: Int): (UInt, Bool) = { 25 | val c = new ZCounter(n) 26 | var wrap: Bool = null 27 | when (cond) { wrap = c.inc() } 28 | (c.value, cond && wrap) 29 | } 30 | } 31 | 32 | object TwoWayCounter { 33 | def apply(up: Bool, down: Bool, max: Int): UInt = { 34 | val cnt = Reg(init = UInt(0, log2Up(max+1))) 35 | when (up && !down) { cnt := cnt + UInt(1) } 36 | when (down && !up) { cnt := cnt - UInt(1) } 37 | cnt 38 | } 39 | } 40 | 41 | // a counter that clock gates most of its MSBs using the LSB carry-out 42 | case class WideCounter(width: Int, inc: UInt = UInt(1), reset: Boolean = true) 43 | { 44 | private val isWide = width > 2*inc.getWidth 45 | private val smallWidth = if (isWide) inc.getWidth max log2Up(width) else width 46 | private val small = if (reset) Reg(init=UInt(0, smallWidth)) else Reg(UInt(width = smallWidth)) 47 | private val nextSmall = small +& inc 48 | small := nextSmall 49 | 50 | private val large = if (isWide) { 51 | val r = if (reset) Reg(init=UInt(0, width - smallWidth)) else Reg(UInt(width = width - smallWidth)) 52 | when (nextSmall(smallWidth)) { r := r + UInt(1) } 53 | r 54 | } else null 55 | 56 | val value = if (isWide) Cat(large, small) else small 57 | lazy val carryOut = { 58 | val lo = (small ^ nextSmall) >> 1 59 | if (!isWide) lo else { 60 | val hi = Mux(nextSmall(smallWidth), large ^ (large +& UInt(1)), UInt(0)) >> 1 61 | Cat(hi, lo) 62 | } 63 | } 64 | 65 | def := (x: UInt) = { 66 | small := x 67 | if (isWide) large := x >> smallWidth 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/scala/subsystem/CrossingWrapper.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.subsystem 4 | 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.tilelink._ 8 | import freechips.rocketchip.amba.axi4._ 9 | import freechips.rocketchip.interrupts._ 10 | 11 | 12 | @deprecated("Only use this trait if you are confident you island will only ever be crossed to a single clock", "rocket-chip 1.3") 13 | trait HasCrossing extends CrossesToOnlyOneClockDomain { this: LazyModule => } 14 | 15 | /** Given a constant crossing type, define a bunch of helper methods for 16 | * crossing to all the procotols. 17 | * Note: only use this if you don't care that all signals of a given protocol 18 | * type will have the same name prefixes (e.g. "tl_in_xing_*"). 19 | */ 20 | trait CrossesToOnlyOneClockDomain extends HasClockDomainCrossing { this: LazyModule => 21 | 22 | def crossing: ClockCrossingType 23 | 24 | def crossTLIn(n: TLInwardNode)(implicit p: Parameters): TLInwardNode = { 25 | val tlInXing = this.crossIn(n) 26 | tlInXing(crossing) 27 | } 28 | 29 | def crossTLOut(n: TLOutwardNode)(implicit p: Parameters): TLOutwardNode = { 30 | val tlOutXing = this.crossOut(n) 31 | tlOutXing(crossing) 32 | } 33 | 34 | def crossAXI4In(n: AXI4InwardNode)(implicit p: Parameters): AXI4InwardNode = { 35 | val axi4InXing = this.crossIn(n) 36 | axi4InXing(crossing) 37 | } 38 | 39 | def crossAXI4Out(n: AXI4OutwardNode)(implicit p: Parameters): AXI4OutwardNode = { 40 | val axi4OutXing = this.crossOut(n) 41 | axi4OutXing(crossing) 42 | } 43 | 44 | def crossIntIn(n: IntInwardNode)(implicit p: Parameters): IntInwardNode = { 45 | val intInXing = this.crossIn(n) 46 | intInXing(crossing) 47 | } 48 | 49 | def crossIntOut(n: IntOutwardNode)(implicit p: Parameters): IntOutwardNode = { 50 | val intOutXing = this.crossOut(n) 51 | intOutXing(crossing) 52 | } 53 | } 54 | 55 | /** A convenient way of creating a LazyScope with a particular uniform clock relationship */ 56 | class CrossingWrapper(val crossing: ClockCrossingType)(implicit p: Parameters) extends SimpleLazyModule with CrossesToOnlyOneClockDomain 57 | -------------------------------------------------------------------------------- /src/main/scala/amba/axi4/Buffer.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | package freechips.rocketchip.amba.axi4 4 | 5 | import Chisel._ 6 | import chisel3.util.IrrevocableIO 7 | import freechips.rocketchip.config.Parameters 8 | import freechips.rocketchip.diplomacy._ 9 | import scala.math.{min,max} 10 | 11 | // pipe is only used if a queue has depth = 1 12 | class AXI4Buffer( 13 | aw: BufferParams, 14 | w: BufferParams, 15 | b: BufferParams, 16 | ar: BufferParams, 17 | r: BufferParams)(implicit p: Parameters) extends LazyModule 18 | { 19 | def this(aw: BufferParams, br: BufferParams)(implicit p: Parameters) = this(aw, aw, br, aw, br) 20 | def this(x: BufferParams)(implicit p: Parameters) = this(x, x) 21 | def this()(implicit p: Parameters) = this(BufferParams.default) 22 | 23 | val node = AXI4AdapterNode( 24 | masterFn = { p => p }, 25 | slaveFn = { p => p.copy(minLatency = p.minLatency + min(aw.latency,ar.latency) + min(r.latency,b.latency)) }) 26 | 27 | lazy val module = new LazyModuleImp(this) { 28 | def buffer[T <: Data](config: BufferParams, data: IrrevocableIO[T]): IrrevocableIO[T] = { 29 | if (config.isDefined) { 30 | Queue.irrevocable(data, config.depth, pipe=config.pipe, flow=config.flow) 31 | } else { 32 | data 33 | } 34 | } 35 | 36 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 37 | out.aw <> buffer(aw, in .aw) 38 | out.w <> buffer(w, in .w) 39 | in .b <> buffer(b, out.b) 40 | out.ar <> buffer(ar, in .ar) 41 | in .r <> buffer(r, out.r) 42 | } 43 | } 44 | } 45 | 46 | object AXI4Buffer 47 | { 48 | def apply() (implicit p: Parameters): AXI4Node = apply(BufferParams.default) 49 | def apply(z: BufferParams) (implicit p: Parameters): AXI4Node = apply(z, z) 50 | def apply(aw: BufferParams, br: BufferParams)(implicit p: Parameters): AXI4Node = apply(aw, aw, br, aw, br) 51 | def apply( 52 | aw: BufferParams, 53 | w: BufferParams, 54 | b: BufferParams, 55 | ar: BufferParams, 56 | r: BufferParams)(implicit p: Parameters): AXI4Node = 57 | { 58 | val axi4buf = LazyModule(new AXI4Buffer(aw, w, b, ar, r)) 59 | axi4buf.node 60 | } 61 | } 62 | --------------------------------------------------------------------------------