Small renaming/cleanup | Use LinkedHashMaps
This commit is contained in:
@@ -86,7 +86,7 @@ object ClockingSchemeGenerators {
|
|||||||
:*= aggregator)
|
:*= aggregator)
|
||||||
|
|
||||||
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||||
val dividerOnlyClkGenerator = DividerOnlyClockGenerator()
|
val dividerOnlyClkGenerator = LazyModule(new DividerOnlyClockGenerator("buildTopClockGenerator"))
|
||||||
// provides all the divided clocks (from the top-level clock)
|
// provides all the divided clocks (from the top-level clock)
|
||||||
(aggregator
|
(aggregator
|
||||||
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
|
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
|
||||||
|
|||||||
@@ -217,6 +217,12 @@ class WithSerialTLBackingMemory extends Config((site, here, up) => {
|
|||||||
)}
|
)}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mixins to define either a specific tile frequency for a single hart or all harts
|
||||||
|
*
|
||||||
|
* @param fMHz Frequency in MHz of the tile or all tiles
|
||||||
|
* @param hartId Optional hartid to assign the frequency to (if unspecified default to all harts)
|
||||||
|
*/
|
||||||
class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockNameContainsAssignment({
|
class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockNameContainsAssignment({
|
||||||
hartId match {
|
hartId match {
|
||||||
case Some(id) => s"tile_$id"
|
case Some(id) => s"tile_$id"
|
||||||
|
|||||||
@@ -144,21 +144,15 @@ class WithSimAXIMemOverSerialTL extends OverrideHarnessBinder({
|
|||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
||||||
|
|
||||||
p(SerialTLKey).map({ sVal =>
|
p(SerialTLKey).map({ sVal =>
|
||||||
// currently only the harness AXI port supports a passthrough clock
|
|
||||||
require(sVal.axiMemOverSerialTLParams.isDefined)
|
require(sVal.axiMemOverSerialTLParams.isDefined)
|
||||||
val axiDomainParams = sVal.axiMemOverSerialTLParams.get
|
val axiDomainParams = sVal.axiMemOverSerialTLParams.get
|
||||||
|
require(sVal.isMemoryDevice)
|
||||||
|
|
||||||
val memFreq: Double = axiDomainParams.axiClockParams match {
|
val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations])
|
||||||
case Some(clkParams) => clkParams.clockFreqMHz * 1000000
|
|
||||||
case None => {
|
|
||||||
// get freq. from what the master of the serial link specifies
|
|
||||||
system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(p(SerialTLAttachKey).masterWhere).dtsFrequency.get.toDouble
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ports.map({ port =>
|
ports.map({ port =>
|
||||||
// DOC include start: HarnessClockInstantiatorEx
|
// DOC include start: HarnessClockInstantiatorEx
|
||||||
val memOverSerialTLClockBundle = p(HarnessClockInstantiatorKey).getClockBundle("mem_over_serial_tl_clock", memFreq)
|
val memOverSerialTLClockBundle = p(HarnessClockInstantiatorKey).requestClockBundle("mem_over_serial_tl_clock", memFreq)
|
||||||
val harnessMultiClockAXIRAM = SerialAdapter.connectHarnessMultiClockAXIRAM(
|
val harnessMultiClockAXIRAM = SerialAdapter.connectHarnessMultiClockAXIRAM(
|
||||||
system.serdesser.get,
|
system.serdesser.get,
|
||||||
port,
|
port,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package chipyard
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
|
|
||||||
import scala.collection.mutable.{ArrayBuffer, HashMap}
|
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||||
@@ -31,10 +31,10 @@ trait HasHarnessSignalReferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class HarnessClockInstantiator {
|
class HarnessClockInstantiator {
|
||||||
private var _clockMap: HashMap[String, (Double, ClockBundle)] = HashMap.empty
|
private val _clockMap: LinkedHashMap[String, (Double, ClockBundle)] = LinkedHashMap.empty
|
||||||
|
|
||||||
// request a clock bundle at a particular frequency
|
// request a clock bundle at a particular frequency
|
||||||
def getClockBundle(name: String, freqRequested: Double): ClockBundle = {
|
def requestClockBundle(name: String, freqRequested: Double): ClockBundle = {
|
||||||
val clockBundle = Wire(new ClockBundle(ClockBundleParameters()))
|
val clockBundle = Wire(new ClockBundle(ClockBundleParameters()))
|
||||||
_clockMap(name) = (freqRequested, clockBundle)
|
_clockMap(name) = (freqRequested, clockBundle)
|
||||||
clockBundle
|
clockBundle
|
||||||
@@ -49,7 +49,7 @@ class HarnessClockInstantiator {
|
|||||||
val pllConfig = new SimplePllConfiguration("harnessDividerOnlyClockGenerator", sinks)
|
val pllConfig = new SimplePllConfiguration("harnessDividerOnlyClockGenerator", sinks)
|
||||||
pllConfig.emitSummaries()
|
pllConfig.emitSummaries()
|
||||||
|
|
||||||
val dividedClocks = HashMap[Int, Clock]()
|
val dividedClocks = LinkedHashMap[Int, Clock]()
|
||||||
def instantiateDivider(div: Int): Clock = {
|
def instantiateDivider(div: Int): Clock = {
|
||||||
val divider = Module(new ClockDividerN(div))
|
val divider = Module(new ClockDividerN(div))
|
||||||
divider.suggestName(s"ClockDivideBy${div}")
|
divider.suggestName(s"ClockDivideBy${div}")
|
||||||
@@ -86,16 +86,15 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign
|
|||||||
val harnessReset = Wire(Reset())
|
val harnessReset = Wire(Reset())
|
||||||
|
|
||||||
val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop")
|
val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop")
|
||||||
withClockAndReset(harnessClock, harnessReset) {
|
val dut = Module(lazyDut.module)
|
||||||
val dut = Module(lazyDut.module)
|
|
||||||
}
|
|
||||||
io.success := false.B
|
io.success := false.B
|
||||||
|
|
||||||
val freqMHz = lazyDut match {
|
val freqMHz = lazyDut match {
|
||||||
case d: HasReferenceClockFreq => d.refClockFreqMHz.getOrElse(p(DefaultClockFrequencyKey))
|
case d: HasReferenceClockFreq => d.refClockFreqMHz.getOrElse(p(DefaultClockFrequencyKey))
|
||||||
case _ => p(DefaultClockFrequencyKey)
|
case _ => p(DefaultClockFrequencyKey)
|
||||||
}
|
}
|
||||||
val refClkBundle = p(HarnessClockInstantiatorKey).getClockBundle("buildtop_reference_clock", freqMHz * (1000 * 1000))
|
val refClkBundle = p(HarnessClockInstantiatorKey).requestClockBundle("buildtop_reference_clock", freqMHz * (1000 * 1000))
|
||||||
|
|
||||||
harnessClock := refClkBundle.clock
|
harnessClock := refClkBundle.clock
|
||||||
harnessReset := WireInit(refClkBundle.reset)
|
harnessReset := WireInit(refClkBundle.reset)
|
||||||
|
|||||||
@@ -145,7 +145,3 @@ class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object DividerOnlyClockGenerator {
|
|
||||||
def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new DividerOnlyClockGenerator(valName.name))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -110,21 +110,14 @@ class WithAXIOverSerialTLCombinedBridges extends OverrideHarnessBinder({
|
|||||||
implicit val p = GetSystemParameters(system)
|
implicit val p = GetSystemParameters(system)
|
||||||
|
|
||||||
p(SerialTLKey).map({ sVal =>
|
p(SerialTLKey).map({ sVal =>
|
||||||
// currently only the harness AXI port supports a passthrough clock
|
|
||||||
require(sVal.axiMemOverSerialTLParams.isDefined)
|
require(sVal.axiMemOverSerialTLParams.isDefined)
|
||||||
val axiDomainParams = sVal.axiMemOverSerialTLParams.get
|
val axiDomainParams = sVal.axiMemOverSerialTLParams.get
|
||||||
require(sVal.isMemoryDevice)
|
require(sVal.isMemoryDevice)
|
||||||
|
|
||||||
val memFreq: Double = axiDomainParams.axiClockParams match {
|
val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations])
|
||||||
case Some(clkParams) => clkParams.clockFreqMHz * 1000000
|
|
||||||
case None => {
|
|
||||||
// get freq. from what the master of the serial link specifies
|
|
||||||
system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(p(SerialTLAttachKey).masterWhere).dtsFrequency.get.toDouble
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ports.map({ port =>
|
ports.map({ port =>
|
||||||
val axiClock = p(ClockBridgeInstantiatorKey).getClock("mem_over_serial_tl_clock", memFreq)
|
val axiClock = p(ClockBridgeInstantiatorKey).requestClock("mem_over_serial_tl_clock", memFreq)
|
||||||
val axiClockBundle = Wire(new ClockBundle(ClockBundleParameters()))
|
val axiClockBundle = Wire(new ClockBundle(ClockBundleParameters()))
|
||||||
axiClockBundle.clock := axiClock
|
axiClockBundle.clock := axiClock
|
||||||
axiClockBundle.reset := ResetCatchAndSync(axiClock, th.harnessReset.asBool)
|
axiClockBundle.reset := ResetCatchAndSync(axiClock, th.harnessReset.asBool)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package firesim.firesim
|
package firesim.firesim
|
||||||
|
|
||||||
import scala.collection.mutable.{HashMap}
|
import scala.collection.mutable.{LinkedHashMap}
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.{IO}
|
import chisel3.experimental.{IO}
|
||||||
@@ -44,12 +44,12 @@ object NodeIdx {
|
|||||||
* memoize its instantiation such that it can be referenced from within a ClockScheme function.
|
* memoize its instantiation such that it can be referenced from within a ClockScheme function.
|
||||||
*/
|
*/
|
||||||
class ClockBridgeInstantiator {
|
class ClockBridgeInstantiator {
|
||||||
private var _harnessClockMap: HashMap[String, (Double, Clock)] = HashMap.empty
|
private val _harnessClockMap: LinkedHashMap[String, (Double, Clock)] = LinkedHashMap.empty
|
||||||
|
|
||||||
// Assumes that the supernode implementation results in duplicated clocks
|
// Assumes that the supernode implementation results in duplicated clocks
|
||||||
// (i.e. only 1 set of clocks is generated for all BuildTop designs)
|
// (i.e. only 1 set of clocks is generated for all BuildTop designs)
|
||||||
private var _ratClockMap: HashMap[String, (RationalClock, Clock)] = HashMap.empty
|
private val _buildtopClockMap: LinkedHashMap[String, (RationalClock, Clock)] = LinkedHashMap.empty
|
||||||
private var _ratRefTuple: Option[(String, Double)] = None
|
private var _buildtopRefTuple: Option[(String, Double)] = None
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a clock at a particular frequency
|
* Request a clock at a particular frequency
|
||||||
@@ -58,7 +58,7 @@ class ClockBridgeInstantiator {
|
|||||||
*
|
*
|
||||||
* @param freqRequested Freq. for the domain in Hz
|
* @param freqRequested Freq. for the domain in Hz
|
||||||
*/
|
*/
|
||||||
def getClock(name: String, freqRequested: Double): Clock = {
|
def requestClock(name: String, freqRequested: Double): Clock = {
|
||||||
val clkWire = Wire(new Clock)
|
val clkWire = Wire(new Clock)
|
||||||
_harnessClockMap(name) = (freqRequested, clkWire)
|
_harnessClockMap(name) = (freqRequested, clkWire)
|
||||||
clkWire
|
clkWire
|
||||||
@@ -73,15 +73,15 @@ class ClockBridgeInstantiator {
|
|||||||
*
|
*
|
||||||
* @param baseFreqRequested Freq. for the reference domain in Hz
|
* @param baseFreqRequested Freq. for the reference domain in Hz
|
||||||
*/
|
*/
|
||||||
def getClockRecordMap(allClocks: Seq[RationalClock], baseClockName: String, baseFreqRequested: Double): RecordMap[Clock] = {
|
def requestClockRecordMap(allClocks: Seq[RationalClock], baseClockName: String, baseFreqRequested: Double): RecordMap[Clock] = {
|
||||||
require(!_ratRefTuple.isDefined, "Can only request one RecordMap of Clocks")
|
require(!_buildtopRefTuple.isDefined, "Can only request one RecordMap of Clocks")
|
||||||
|
|
||||||
val ratClockRecordMapWire = Wire(RecordMap(allClocks.map { c => (c.name, Clock()) }:_*))
|
val ratClockRecordMapWire = Wire(RecordMap(allClocks.map { c => (c.name, Clock()) }:_*))
|
||||||
|
|
||||||
_ratRefTuple = Some((baseClockName, baseFreqRequested))
|
_buildtopRefTuple = Some((baseClockName, baseFreqRequested))
|
||||||
for (clock <- allClocks) {
|
for (clock <- allClocks) {
|
||||||
val clkWire = Wire(new Clock)
|
val clkWire = Wire(new Clock)
|
||||||
_ratClockMap(clock.name) = (clock, clkWire)
|
_buildtopClockMap(clock.name) = (clock, clkWire)
|
||||||
ratClockRecordMapWire(clock.name).get := clkWire
|
ratClockRecordMapWire(clock.name).get := clkWire
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,14 +92,14 @@ class ClockBridgeInstantiator {
|
|||||||
* Connect all clocks requested to ClockBridge
|
* Connect all clocks requested to ClockBridge
|
||||||
*/
|
*/
|
||||||
def instantiateFireSimClockBridge: Unit = {
|
def instantiateFireSimClockBridge: Unit = {
|
||||||
require(_ratRefTuple.isDefined, "Must have rational clocks to assign to")
|
require(_buildtopRefTuple.isDefined, "Must have rational clocks to assign to")
|
||||||
require(_ratClockMap.exists(_._1 == _ratRefTuple.get._1),
|
require(_buildtopClockMap.exists(_._1 == _buildtopRefTuple.get._1),
|
||||||
s"Provided base-clock name for rational clocks, ${_ratRefTuple.get._1}, doesn't match a name within specified rational clocks." +
|
s"Provided base-clock name for rational clocks, ${_buildtopRefTuple.get._1}, doesn't match a name within specified rational clocks." +
|
||||||
"Available clocks:\n " + _ratClockMap.map(_._1).mkString("\n "))
|
"Available clocks:\n " + _buildtopClockMap.map(_._1).mkString("\n "))
|
||||||
|
|
||||||
// Simplify the RationalClocks ratio's
|
// Simplify the RationalClocks ratio's
|
||||||
val refRatClock = _ratClockMap.find(_._1 == _ratRefTuple.get._1).get._2._1
|
val refRatClock = _buildtopClockMap.find(_._1 == _buildtopRefTuple.get._1).get._2._1
|
||||||
val simpleRatClocks = _ratClockMap.map { t =>
|
val simpleRatClocks = _buildtopClockMap.map { t =>
|
||||||
val ratClock = t._2._1
|
val ratClock = t._2._1
|
||||||
ratClock.copy(
|
ratClock.copy(
|
||||||
multiplier = ratClock.multiplier * refRatClock.divisor,
|
multiplier = ratClock.multiplier * refRatClock.divisor,
|
||||||
@@ -108,8 +108,8 @@ class ClockBridgeInstantiator {
|
|||||||
|
|
||||||
// Determine all the clock dividers (harness + rational clocks)
|
// Determine all the clock dividers (harness + rational clocks)
|
||||||
// Note: Requires that the BuildTop reference frequency is requested with proper freq.
|
// Note: Requires that the BuildTop reference frequency is requested with proper freq.
|
||||||
val refRatClockFreq = _ratRefTuple.get._2
|
val refRatClockFreq = _buildtopRefTuple.get._2
|
||||||
val refRatSinkParams = ClockSinkParameters(take=Some(ClockParameters(freqMHz=refRatClockFreq / (1000 * 1000))),name=Some(_ratRefTuple.get._1))
|
val refRatSinkParams = ClockSinkParameters(take=Some(ClockParameters(freqMHz=refRatClockFreq / (1000 * 1000))),name=Some(_buildtopRefTuple.get._1))
|
||||||
val harSinkParams = _harnessClockMap.map { case (name, (freq, bundle)) =>
|
val harSinkParams = _harnessClockMap.map { case (name, (freq, bundle)) =>
|
||||||
ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))),name=Some(name))
|
ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))),name=Some(name))
|
||||||
}.toSeq
|
}.toSeq
|
||||||
@@ -144,7 +144,7 @@ class ClockBridgeInstantiator {
|
|||||||
// Connect all clocks (harness + BuildTop clocks)
|
// Connect all clocks (harness + BuildTop clocks)
|
||||||
for (clock <- allAdjRatClks) {
|
for (clock <- allAdjRatClks) {
|
||||||
val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(clock)).get
|
val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(clock)).get
|
||||||
_ratClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField }
|
_buildtopClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField }
|
||||||
_harnessClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField }
|
_harnessClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => {
|
|||||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||||
reset := th.harnessReset
|
reset := th.harnessReset
|
||||||
input_clocks := p(ClockBridgeInstantiatorKey)
|
input_clocks := p(ClockBridgeInstantiatorKey)
|
||||||
.getClockRecordMap(rationalClockSpecs.toSeq, p(FireSimBaseClockNameKey), pllConfig.referenceFreqMHz * (1000 * 1000))
|
.requestClockRecordMap(rationalClockSpecs.toSeq, p(FireSimBaseClockNameKey), pllConfig.referenceFreqMHz * (1000 * 1000))
|
||||||
Nil })
|
Nil })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,9 +227,7 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna
|
|||||||
val lazyModule = LazyModule(p(BuildTop)(p.alterPartial({
|
val lazyModule = LazyModule(p(BuildTop)(p.alterPartial({
|
||||||
case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy
|
case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy
|
||||||
})))
|
})))
|
||||||
withClockAndReset(harnessClock, harnessReset) {
|
val module = Module(lazyModule.module)
|
||||||
val module = Module(lazyModule.module)
|
|
||||||
}
|
|
||||||
|
|
||||||
btFreqMHz = Some(lazyModule match {
|
btFreqMHz = Some(lazyModule match {
|
||||||
case d: HasReferenceClockFreq => d.refClockFreqMHz.getOrElse(p(DefaultClockFrequencyKey))
|
case d: HasReferenceClockFreq => d.refClockFreqMHz.getOrElse(p(DefaultClockFrequencyKey))
|
||||||
@@ -246,7 +244,7 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna
|
|||||||
NodeIdx.increment()
|
NodeIdx.increment()
|
||||||
}
|
}
|
||||||
|
|
||||||
harnessClock := p(ClockBridgeInstantiatorKey).getClock("buildtop_reference_clock", btFreqMHz.get * (1000 * 1000))
|
harnessClock := p(ClockBridgeInstantiatorKey).requestClock("buildtop_reference_clock", btFreqMHz.get * (1000 * 1000))
|
||||||
|
|
||||||
p(ClockBridgeInstantiatorKey).instantiateFireSimClockBridge
|
p(ClockBridgeInstantiatorKey).instantiateFireSimClockBridge
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class WithNIC extends icenet.WithIceNIC(inBufFlits = 8192, ctrlQueueDepth = 64)
|
|||||||
class WithNVDLALarge extends nvidia.blocks.dla.WithNVDLA("large")
|
class WithNVDLALarge extends nvidia.blocks.dla.WithNVDLA("large")
|
||||||
class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small")
|
class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small")
|
||||||
|
|
||||||
|
// Tweaks that are generally applied to all firesim configs (without default FireSim clocks)
|
||||||
class WithFireSimDesignTweaks extends Config(
|
class WithFireSimDesignTweaks extends Config(
|
||||||
// Required: Bake in the default FASED memory model
|
// Required: Bake in the default FASED memory model
|
||||||
new WithDefaultMemModel ++
|
new WithDefaultMemModel ++
|
||||||
@@ -82,7 +83,7 @@ class WithFireSimDesignTweaks extends Config(
|
|||||||
new chipyard.config.WithNoDebug
|
new chipyard.config.WithNoDebug
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tweaks that are generally applied to all firesim configs
|
// Tweaks that are generally applied to all firesim configs (with default FireSim clocks)
|
||||||
class WithFireSimConfigTweaks extends Config(
|
class WithFireSimConfigTweaks extends Config(
|
||||||
// Optional*: Removing this will require adjusting the UART baud rate and
|
// Optional*: Removing this will require adjusting the UART baud rate and
|
||||||
// potential target-software changes to properly capture UART output
|
// potential target-software changes to properly capture UART output
|
||||||
|
|||||||
Submodule generators/testchipip updated: 03c4ac4862...6b082f1edb
Reference in New Issue
Block a user