-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rocket cosim framework #3271
Rocket cosim framework #3271
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.global _start | ||
_start: | ||
auipc t1, 0x0 | ||
addi a1, t1, 32 | ||
csrr a0, mhartid | ||
lui t0, 0x80000 | ||
slli t0,t0,32 | ||
srli t0,t0,32 | ||
jr t0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
.global _start | ||
_start: | ||
add t0,t0,x0 | ||
addi t0, x0, 0x1 | ||
addi t1, x0, 0x0 | ||
addi t3, x0, 0xa | ||
loop: | ||
add t1, t1, t0 | ||
add t0, t0, 0x1 | ||
add t3, t3, -1 | ||
bne t3, x0, loop | ||
sd t1, 0x10(x0) | ||
ld t2, 0x10(x0) | ||
addi x20, x0, 0x1 | ||
addi x21, x0, 0x1 | ||
addi x22, x0, 0x1 | ||
addi x23, x0, 0x1 | ||
addi x24, x0, 0x1 | ||
addi x25, x0, 0x1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package tests.cosim.elabotate | ||
|
||
import chisel3._ | ||
import freechips.rocketchip.diplomacy.{AddressSet, BundleBridgeSource, InModuleBody, LazyModule, RegionType, SimpleLazyModule, TransferSizes} | ||
import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple, IntSourceNode, IntSourcePortSimple} | ||
import freechips.rocketchip.subsystem._ | ||
import freechips.rocketchip.tilelink.{TLManagerNode, TLSlaveParameters, TLSlavePortParameters} | ||
import org.chipsalliance.cde.config.Parameters | ||
import freechips.rocketchip.tile.{NMI, PriorityMuxHartIdFromSeq, RocketTile} | ||
|
||
import org.chipsalliance.cde.config.{Config, Field} | ||
|
||
class DUT(p: Parameters) extends Module { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can directly use |
||
implicit val implicitP = p | ||
val tileParams = p(RocketTileParamsKey) | ||
val ldut = LazyModule(new SimpleLazyModule { | ||
implicit val implicitP = p | ||
val rocketTile = LazyModule(new RocketTile(tileParams, RocketCrossingParams(), PriorityMuxHartIdFromSeq(Seq(tileParams)))) | ||
val masterNode = TLManagerNode(Seq(TLSlavePortParameters.v1( | ||
Seq(TLSlaveParameters.v1( | ||
address = List(AddressSet(0x0, 0xffffffffL)), | ||
regionType = RegionType.UNCACHED, | ||
executable = true, | ||
supportsGet = TransferSizes(1, 64), | ||
supportsAcquireT = TransferSizes(1, 64), | ||
supportsAcquireB = TransferSizes(1, 64), | ||
supportsPutPartial = TransferSizes(1, 64), | ||
supportsPutFull = TransferSizes(1, 64), | ||
supportsLogical = TransferSizes(1, 64), | ||
supportsArithmetic = TransferSizes(1, 64), | ||
fifoId = Some(0))), | ||
beatBytes = 8, | ||
endSinkId = 4, | ||
minLatency = 1 | ||
))) | ||
masterNode :=* rocketTile.masterNode | ||
val memory = InModuleBody { | ||
masterNode.makeIOs() | ||
} | ||
|
||
val intNode = IntSourceNode(IntSourcePortSimple()) | ||
rocketTile.intInwardNode :=* intNode | ||
val intIn = InModuleBody { | ||
intNode.makeIOs() | ||
} | ||
|
||
val haltNode = IntSinkNode(IntSinkPortSimple()) | ||
haltNode :=* rocketTile.haltNode | ||
val haltOut = InModuleBody { | ||
haltNode.makeIOs() | ||
} | ||
|
||
val ceaseNode = IntSinkNode(IntSinkPortSimple()) | ||
ceaseNode :=* rocketTile.ceaseNode | ||
val ceaseOut = InModuleBody { | ||
ceaseNode.makeIOs() | ||
} | ||
|
||
val wfiNode = IntSinkNode(IntSinkPortSimple()) | ||
wfiNode :=* rocketTile.wfiNode | ||
val wfiOut = InModuleBody { | ||
wfiNode.makeIOs() | ||
} | ||
val resetVectorNode = BundleBridgeSource(() => UInt(32.W)) | ||
rocketTile.resetVectorNode := resetVectorNode | ||
val resetVector = InModuleBody { | ||
resetVectorNode.makeIO() | ||
} | ||
val hartidNode = BundleBridgeSource(() => UInt(4.W)) | ||
rocketTile.hartIdNode := hartidNode | ||
InModuleBody { | ||
hartidNode.bundle := 0.U | ||
} | ||
val nmiNode = BundleBridgeSource(Some(() => new NMI(32))) | ||
rocketTile.nmiNode := nmiNode | ||
val nmi = InModuleBody { | ||
nmiNode.makeIO() | ||
} | ||
Comment on lines
+19
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These logic is already implemented in the |
||
}) | ||
chisel3.experimental.DataMirror.fullModulePorts( | ||
// instantiate the LazyModule | ||
Module(ldut.module) | ||
).filterNot(_._2.isInstanceOf[Aggregate]).foreach { case (name, ele) => | ||
if (!(name == "clock" || name == "reset")) { | ||
chisel3.experimental.DataMirror.directionOf(ele) match { | ||
case ActualDirection.Output => | ||
val io = IO(Output(chiselTypeOf(ele))).suggestName(name) | ||
println(s"output $name") | ||
io := ele | ||
case ActualDirection.Input => | ||
val io = IO(Input(chiselTypeOf(ele))).suggestName(name) | ||
println(s"input $name") | ||
ele := io | ||
} | ||
} | ||
} | ||
Comment on lines
+80
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC this hack should be fixed. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package tests.cosim.elabotate | ||
|
||
|
||
import chisel3.aop.Select | ||
import chisel3.aop.injecting.InjectingAspect | ||
import chisel3.stage.ChiselGeneratorAnnotation | ||
import circt.stage.{CIRCTTarget, CIRCTTargetAnnotation, ChiselStage, FirtoolOption} | ||
import firrtl.options.TargetDirAnnotation | ||
import firrtl.{AnnotationSeq, ChirrtlEmitter, EmitAllModulesAnnotation} | ||
import freechips.rocketchip.devices.debug.DebugModuleKey | ||
import freechips.rocketchip.diplomacy.MonitorsEnabled | ||
import freechips.rocketchip.subsystem.{CacheBlockBytes, SystemBusKey, SystemBusParams} | ||
import mainargs._ | ||
import org.chipsalliance.cde.config.{Config, Field} | ||
import freechips.rocketchip.rocket.{DCacheParams, FrontendModule, ICacheModule, ICacheParams, MulDivParams, Rocket, RocketCoreParams} | ||
import freechips.rocketchip.tile.RocketTileParams | ||
|
||
import freechips.rocketchip.system._ | ||
import chisel3.stage.{ChiselCli, ChiselStage} | ||
import firrtl.AnnotationSeq | ||
import firrtl.options.PhaseManager.PhaseDependency | ||
import firrtl.options.{Dependency, Phase, PhaseManager, PreservesAll, Shell, Stage, StageMain} | ||
import firrtl.stage.FirrtlCli | ||
import freechips.rocketchip.stage.RocketChipCli | ||
|
||
import scala.collection.immutable.Seq | ||
|
||
/** Modified ChiselStage that includes the GenerateROMs phase */ | ||
private[freechips] final class RocketChiselStage extends ChiselStage { | ||
|
||
override val targets = Seq( | ||
Dependency[chisel3.stage.phases.Checks], | ||
Dependency[chisel3.stage.phases.Elaborate], | ||
Dependency[freechips.rocketchip.stage.phases.GenerateROMs], | ||
Dependency[chisel3.stage.phases.AddImplicitOutputFile], | ||
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], | ||
Dependency[chisel3.stage.phases.MaybeAspectPhase], | ||
Dependency[chisel3.stage.phases.Emitter], | ||
Dependency[chisel3.stage.phases.Convert] | ||
) | ||
|
||
} | ||
|
||
class RocketChipStage extends Stage with PreservesAll[Phase] { | ||
|
||
override val shell = new Shell("rocket-chip") with RocketChipCli with ChiselCli with FirrtlCli | ||
val targets: Seq[PhaseDependency] = Seq( | ||
Dependency[freechips.rocketchip.stage.phases.Checks], | ||
Dependency[freechips.rocketchip.stage.phases.TransformAnnotations], | ||
Dependency[freechips.rocketchip.stage.phases.PreElaboration], | ||
Dependency[RocketChiselStage], | ||
Dependency[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], | ||
Dependency[freechips.rocketchip.stage.phases.AddDefaultTests], | ||
Dependency[freechips.rocketchip.stage.phases.GenerateTestSuiteMakefrags], | ||
Dependency[freechips.rocketchip.stage.phases.GenerateArtefacts] | ||
) | ||
|
||
private val pm = new PhaseManager(targets) | ||
|
||
override def run(annotations: AnnotationSeq): AnnotationSeq = pm.transform(annotations) | ||
|
||
} | ||
|
||
object Generator extends StageMain(new RocketChipStage) | ||
Comment on lines
+29
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't use RC Stage here. |
||
|
||
|
||
object RocketTileParamsKey extends Field[RocketTileParams] | ||
|
||
class cosimConfig extends Config((site, here, up) => { | ||
case MonitorsEnabled => false | ||
case freechips.rocketchip.tile.XLen => 64 | ||
case freechips.rocketchip.tile.XLen => 64 | ||
case freechips.rocketchip.tile.MaxHartIdBits => 4 | ||
case freechips.rocketchip.tile.MaxHartIdBits => 4 | ||
case freechips.rocketchip.rocket.PgLevels => if (site(freechips.rocketchip.tile.XLen) == 64) 3 else 2 | ||
case freechips.rocketchip.rocket.PgLevels => if (site(freechips.rocketchip.tile.XLen) == 64) 3 else 2 | ||
case RocketTileParamsKey => RocketTileParams( | ||
core = RocketCoreParams(mulDiv = Some(MulDivParams( | ||
mulUnroll = 8, | ||
mulEarlyOut = true, | ||
divEarlyOut = true))), | ||
dcache = Some(DCacheParams( | ||
rowBits = site(SystemBusKey).beatBits, | ||
nMSHRs = 0, | ||
blockBytes = site(CacheBlockBytes))), | ||
icache = Some(ICacheParams( | ||
rowBits = site(SystemBusKey).beatBits, | ||
blockBytes = site(CacheBlockBytes)))) | ||
case SystemBusKey => SystemBusParams( | ||
beatBytes = site(freechips.rocketchip.tile.XLen) / 8, | ||
blockBytes = site(CacheBlockBytes)) | ||
case DebugModuleKey => None | ||
}) | ||
Comment on lines
+69
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to use RC default configs. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#pragma once | ||
|
||
#include <stdexcept> | ||
|
||
class CosimException : public std::runtime_error { | ||
public: | ||
explicit CosimException(const char *what) : runtime_error(what) {} | ||
}; | ||
|
||
class TimeoutException : CosimException { | ||
public: | ||
TimeoutException() : CosimException("timeout") {} | ||
}; | ||
|
||
#define CHECK_S(condition) \ | ||
LOG_IF(FATAL_S, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ | ||
<< "Check failed: " #condition " " |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#include <glog/logging.h> | ||
|
||
namespace google { | ||
|
||
class CheckFailedException : public std::runtime_error { | ||
public: | ||
explicit CheckFailedException() : std::runtime_error("check failed") {} | ||
}; | ||
|
||
class LogMessageFatal_S : public LogMessage { | ||
public: | ||
LogMessageFatal_S(const char *file, int line) : LogMessage(file, line, GLOG_ERROR){}; | ||
LogMessageFatal_S(const char *file, int line, const CheckOpString &result) : LogMessage(file, line, GLOG_ERROR) { | ||
stream() << "Check failed: " << (*result.str_) << " "; | ||
}; | ||
~LogMessageFatal_S() noexcept(false) { | ||
Flush(); | ||
throw CheckFailedException(); | ||
}; | ||
}; | ||
}// namespace google | ||
|
||
#define CHECK_OP_S(name, op, val1, val2) \ | ||
CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal_S) | ||
|
||
#define COMPACT_GOOGLE_LOG_FATAL_S google::LogMessageFatal_S(__FILE__, __LINE__) | ||
|
||
#define CHECK_EQ_S(val1, val2) CHECK_OP_S(_EQ, ==, val1, val2) | ||
#define CHECK_NE_S(val1, val2) CHECK_OP_S(_NE, !=, val1, val2) | ||
#define CHECK_LE_S(val1, val2) CHECK_OP_S(_LE, <=, val1, val2) | ||
#define CHECK_LT_S(val1, val2) CHECK_OP_S(_LT, <, val1, val2) | ||
#define CHECK_GE_S(val1, val2) CHECK_OP_S(_GE, >=, val1, val2) | ||
#define CHECK_GT_S(val1, val2) CHECK_OP_S(_GT, >, val1, val2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <args.hxx> | ||
#include <fmt/core.h> | ||
#include <glog/logging.h> | ||
|
||
#include "exceptions.h" | ||
#include "glog_exception_safe.h" | ||
#include "vbridge.h" | ||
|
||
int main(int argc, char **argv) { | ||
FLAGS_logtostderr = 1; | ||
google::InitGoogleLogging(argv[0]); | ||
google::InstallFailureSignalHandler(); | ||
|
||
args::ArgumentParser parser("Rocket"); | ||
args::ValueFlag<std::string> bin(parser, "bin", "test case path", {"bin"}); | ||
args::ValueFlag<std::string> entrance(parser, "entrance", "entrance", {"entrance"}); | ||
args::ValueFlag<std::string> wave(parser, "wave", "wave output path(in fst)", {"wave"}); | ||
args::ValueFlag<uint64_t> reset_vector(parser, "reset_vector", "set reset vector", {"reset-vector"}, 0x80000000); | ||
args::ValueFlag<uint64_t> cycles(parser, "cycles", "set simulation cycles", {"cycles"}, 1000); | ||
parser.ParseCLI(argc, argv); | ||
|
||
try { | ||
VBridge vb; | ||
vb.configure_simulator(argc, argv); | ||
vb.setup(bin.Get(), entrance.Get(), wave.Get() + ".fst", reset_vector.Get(), cycles.Get()); | ||
vb.loop(); | ||
} catch (TimeoutException &e) { | ||
return 0; | ||
} catch (google::CheckFailedException &e) { | ||
return 1; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only need to add necessary dependencies.