-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
ADD: Timing-Accurate Core Instruction Tracing #3706
Conversation
src/main/scala/util/TraceSink.scala
Outdated
}) | ||
} | ||
|
||
class TraceSinkPrint(bb_name: String)(implicit p: Parameters) extends LazyModule { |
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.
What is bb_name
?
input[7:0] in_byte | ||
); | ||
|
||
`ifdef VCS |
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.
This should work in all RTL simulators. I think ifndef SYNTHESIS
is what you want
val trace_in = Flipped(Decoupled(UInt(8.W))) | ||
}) | ||
withClockAndReset(clock, reset) { | ||
io.trace_in.ready := true.B |
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.
You don't need withClockAndReset here... there is no synchronous logic
import org.chipsalliance.cde.config.{Parameters, Config, Field} | ||
import freechips.rocketchip.tile._ | ||
import freechips.rocketchip.subsystem._ | ||
case object TraceSinkAlwaysKey extends Field[Option[Int]](None) |
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.
What does this Int indicate?
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.
I think this can be removed now
src/main/scala/tile/RocketTile.scala
Outdated
trace_encoder_controller | ||
} | ||
|
||
val (trace_sinks, trace_sink_ids) = rocketParams.ltrace match { |
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.
val (trace_sinks, trace_sink_ids) = rocketParams.ltrace match { | |
val (trace_sinks, traceSinkIds) = rocketParams.ltrace match { |
Informal convention is snake_case for HW vars, camelCase for SW vars
src/main/scala/tile/RocketTile.scala
Outdated
} | ||
|
||
val (trace_sinks, trace_sink_ids) = rocketParams.ltrace match { | ||
case Some(t) => |
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.
I
case Some(t) => | |
case Some(t) => t.buildSinks.map {(p)}.unzip |
Does this work?
src/main/scala/tile/RocketTile.scala
Outdated
case Some(t) => | ||
val sequence = t.buildSinks.map {_(p)} | ||
(sequence.map(_._1), sequence.map(_._2)) | ||
case None => (Seq.empty, Seq.empty) |
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.
case None => (Seq.empty, Seq.empty) | |
case None => (Nil, Nil) |
bufferDepth: Int, | ||
encoderBaseAddr: BigInt, | ||
useArbiterMonitor: Boolean, | ||
// a seq of functions that takes a parameter and returns a lazymodule and a target id |
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.
Can you explain what the target id is for in a comment? I thnk that is not obvious
val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits | ||
|
||
when (io.stall) { | ||
printf("TraceEncoder stall detected\n") |
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.
This printf should probably not be here
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.
I think this RTL printf is somewhat important, so in simulation we can kind of know when stalls happen. I would prefer to keep it.
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.
It messes up the commit log, and I think there's a compelling reason to include the trace stuff by default in some designs.
You can add a PlusArg flag - PlusArg("trace_debug")
, for example, which can generate a HW bool that you can use to gate the printf.
Then at run-time, to enable the TraceEncode prints, you just pass (in CY) EXTRA_SIM_FLAGS="+trace_debug=1"
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} | ||
|
||
class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_name: String = "unknown")(implicit p: Parameters) extends LazyModule { | ||
println(s"TraceSinkArbiter nSeq: $nSeq") |
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.
Prints should be removed.
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.
High level request, can you add in a comment at the beginning of the files you added pointing out what spec exactly you implemented? Like "This is an implementation of the TraceXXX as defined in the RISC-V Trace-XXX spec"
val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits | ||
|
||
when (io.stall) { | ||
printf("TraceEncoder stall detected\n") |
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.
It messes up the commit log, and I think there's a compelling reason to include the trace stuff by default in some designs.
You can add a PlusArg flag - PlusArg("trace_debug")
, for example, which can generate a HW bool that you can use to gate the printf.
Then at run-time, to enable the TraceEncode prints, you just pass (in CY) EXTRA_SIM_FLAGS="+trace_debug=1"
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} | ||
import freechips.rocketchip.tile._ | ||
|
||
case object TraceSinkDMAKey extends Field[Option[Int]](None) |
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.
We are not putting this in RC, right?
} | ||
|
||
if (use_monitor) { | ||
val monitor = Module(new TraceSinkMonitor(s"trace_monitor_$monitor_name.out")) |
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.
Should monitor_name
reflect the hartId of the core that is being traced? In a multicore, each core should generate its own trace file, right?
src/main/scala/tile/RocketTile.scala
Outdated
case None => (Nil, Nil) | ||
} | ||
|
||
val trace_sink_arbiter = rocketParams.traceParams.map { t => |
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.
Can you just merge the arbiter and encoder modules?
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.
I'll pass through this again once you remove all the things that will not be upstreamed @iansseijelly
trace_encoder_controller | ||
} | ||
|
||
val trace_encoder = rocketParams.traceParams match { |
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.
val trace_encoder = rocketParams.traceParams match { | |
val trace_encoder = rocketParams.traceParams.map(_.buildEncoder(p)) |
src/main/scala/tile/RocketTile.scala
Outdated
@@ -177,7 +223,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) | |||
|
|||
// Pass through various external constants and reports that were bundle-bridged into the tile | |||
outer.traceSourceNode.bundle <> core.io.trace | |||
core.io.traceStall := outer.traceAuxSinkNode.bundle.stall | |||
// core.io.traceStall := outer.traceAuxSinkNode.bundle.stall |
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.
import chisel3.util._ | ||
import scala.math.min | ||
|
||
import org.chipsalliance.cde.config.Parameters |
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.
This should be removed from RC then? The abstract encoder is in RC, but the custom encoder should be elsewhere?
|
||
class TraceSinkMonitor(name: String) extends BlackBox( | ||
Map( | ||
"FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") |
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.
Clean tacit
from the naming
Hi, I have removed the non-standard components, and addressed the above items. |
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 one minor request, TraceSinkArbiter can be a Module, not a LazyModule
import freechips.rocketchip.tile._ | ||
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} | ||
|
||
class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_name: String = "unknown")(implicit p: Parameters) extends LazyModule { |
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.
This should just be a Module, not a LazyModule
outer.trace_encoder_controller.foreach { lm => | ||
outer.trace_encoder.get.module.io.control <> lm.module.io.control | ||
} | ||
|
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.
Don't construct the arbiter outside this if
block... just do it inside.... then you don't need a Option[Arbiter]
Related issue:
Type of change: feature request
Impact: API addition (no impact on existing code)
Development Phase: implementation
Release Notes
Added feature for: