Skip to content

Commit

Permalink
Merge branch '6.x' into mergify/bp/6.x/pr-3895
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkoenig committed Mar 7, 2024
2 parents 8ca012c + 31c1034 commit 7b92346
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 34 deletions.
17 changes: 13 additions & 4 deletions firrtl/src/main/scala/firrtl/annotations/JsonProtocol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.json4s.native.Serialization
import org.json4s.native.Serialization.{read, write, writePretty}

import scala.collection.mutable
import java.io.{StringWriter, Writer}

trait HasSerializationHints {
// For serialization of complicated constructor arguments, let the annotation
Expand Down Expand Up @@ -167,13 +168,21 @@ object JsonProtocol extends LazyLogging {
})
.distinct

def serializeTry(annos: Seq[Annotation]): Try[String] = {
val tags = getTags(annos)
def serializeTry(annos: Seq[Annotation]): Try[String] = serializeTry(annos, new StringWriter).map(_.toString)

/** Serialize annotations to a [[java.io.Writer]]
*
* @param annos Annotations to serialize
* @param out Writer to which the serialized annotations will be written
* @return
*/
def serializeTry[W <: Writer](annos: Iterable[Annotation], out: W): Try[W] = {
val tags = getTags(annos.toSeq)

implicit val formats = jsonFormat(tags)
Try(writePretty(annos)).recoverWith {
Try(writePretty(annos, out)).recoverWith {
case e: org.json4s.MappingException =>
val badAnnos = findUnserializeableAnnos(annos)
val badAnnos = findUnserializeableAnnos(annos.toSeq)
Failure(if (badAnnos.isEmpty) e else UnserializableAnnotationException(badAnnos))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class WriteOutputAnnotations extends Phase {
case None =>
case Some(file) =>
val pw = new PrintWriter(sopts.getBuildFileName(file, Some(".anno.json")))
pw.write(JsonProtocol.serialize(serializable))
JsonProtocol.serializeTry(serializable, pw).get // .get to throw any exceptions
pw.close()
}
}
Expand Down
20 changes: 20 additions & 0 deletions firrtl/src/test/scala/firrtl/JsonProtocolSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,24 @@ class JsonProtocolSpec extends AnyFlatSpec {
val deserAnno = JsonProtocol.deserialize(serializedAnno).head
assert(anno == deserAnno)
}

"JsonProtocol" should "support serializing directly to a Java Writer" in {
val anno = SimpleAnnotation("hello")
class NaiveWriter extends java.io.Writer {
private var contents: String = ""
def value: String = contents
def close(): Unit = contents = ""
def flush(): Unit = contents = ""
def write(cbuff: Array[Char], off: Int, len: Int): Unit = {
for (i <- off until off + len) {
contents += cbuff(i)
}
}
}
val w = new NaiveWriter
JsonProtocol.serializeTry(Seq(anno), w)
val ser1 = w.value
val ser2 = JsonProtocol.serialize(Seq(anno))
assert(ser1 == ser2)
}
}
61 changes: 36 additions & 25 deletions src/main/scala/chisel3/simulator/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package chisel3

import svsim._
import chisel3.reflect.DataMirror
import scala.collection.mutable
import java.nio.file.{Files, Path, Paths}

package object simulator {

Expand Down Expand Up @@ -107,37 +109,46 @@ package object simulator {
)
)

// Move the files indicated by a filelist.
def moveFiles(filename: String) = {
val filelist = new java.io.BufferedReader(new java.io.FileReader(filename))
try {
filelist.lines().forEach { immutableFilename =>
var filename = immutableFilename
/// Some files are provided as absolute paths
if (filename.startsWith(workspace.supportArtifactsPath)) {
filename = filename.substring(workspace.supportArtifactsPath.length + 1)
}
java.nio.file.Files.move(
java.nio.file.Paths.get(s"${workspace.supportArtifactsPath}/$filename"),
java.nio.file.Paths.get(s"${workspace.primarySourcesPath}/$filename")
)
// Move the files indicated by a filelist. No-op if the file has already
// been moved.
val movedFiles = mutable.HashSet.empty[Path]
val supportArtifactsPath = Paths.get(workspace.supportArtifactsPath)
def moveFiles(filelist: Path) =
// Extract all lines (files) from the filelist.
Files
.lines(filelist)
.map(Paths.get(_))
// Convert the files to an absolute version and a relative version.
.map {
case file if file.startsWith(supportArtifactsPath) =>
(file, file.subpath(supportArtifactsPath.getNameCount(), -1))
case file => (supportArtifactsPath.resolve(file), file)
}
// Normalize the absolute path so it can be checked if it has already
// been moved.
.map { case (abs, rel) => (abs.normalize(), rel) }
// Move the file into primarySourcesPath if it has not already been moved.
.forEach {
case (abs, _) if movedFiles.contains(abs) =>
case (abs, rel) =>
Files.move(
abs,
Paths.get(workspace.primarySourcesPath).resolve(rel)
)
movedFiles += abs
}
} finally {
filelist.close()
}
}

// Move a file in a filelist which may not exist.
def maybeMoveFiles(filename: String) = try {
moveFiles(filename)
} catch {
case _ @(_: java.nio.file.NoSuchFileException | _: java.io.FileNotFoundException) =>
// Move a file in a filelist which may not exist. Do nothing if the
// filelist does not exist.
def maybeMoveFiles(filelist: Path): Unit = filelist match {
case _ if Files.exists(filelist) => moveFiles(filelist)
case _ =>
}

// Move files indicated by 'filelist.f' (which must exist). Move files
// indicated by a black box filelist (which may exist).
moveFiles(s"${workspace.supportArtifactsPath}/filelist.f")
maybeMoveFiles(s"${workspace.supportArtifactsPath}/firrtl_black_box_resource_files.f")
moveFiles(supportArtifactsPath.resolve("filelist.f"))
maybeMoveFiles(supportArtifactsPath.resolve("firrtl_black_box_resource_files.f"))

// Initialize Module Info
val dut = someDut.get
Expand Down
11 changes: 8 additions & 3 deletions src/main/scala/chisel3/util/experimental/BoringUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,14 @@ object BoringUtils {
else if (DataMirror.hasOuterFlip(source)) Flipped(chiselTypeOf(source))
else chiselTypeOf(source)
def purePortType = createProbe match {
case Some(pi) if pi.writable => RWProbe(purePortTypeBase)
case Some(pi) => Probe(purePortTypeBase)
case None => purePortTypeBase
case Some(pi) =>
// If the source is already a probe, don't double wrap it in a probe.
purePortTypeBase.probeInfo match {
case Some(_) => purePortTypeBase
case None if pi.writable => RWProbe(purePortTypeBase)
case None => Probe(purePortTypeBase)
}
case None => purePortTypeBase
}
def isPort(d: Data): Boolean = d.topBindingOpt match {
case Some(PortBinding(_)) => true
Expand Down
17 changes: 17 additions & 0 deletions src/test/scala/chiselTests/BoringUtilsTapSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -495,4 +495,21 @@ class BoringUtilsTapSpec extends ChiselFlatSpec with ChiselRunners with Utils wi
val verilog = circt.stage.ChiselStage.emitSystemVerilog(new Foo)
}

it should "allow tapping a probe" in {
class Bar extends RawModule {
val a = IO(probe.Probe(Bool()))
}
class Foo extends RawModule {
val b = IO(probe.Probe(Bool()))
val bar = Module(new Bar)
probe.define(b, BoringUtils.tap(bar.a))
}

val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Foo)

matchesAndOmits(chirrtl)(
"define b = bar.a"
)()
}

}
2 changes: 1 addition & 1 deletion svsim/src/main/scala/verilator/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ final class Backend(
case OptimizationStyle.OptimizeForCompilationSpeed => Seq("-O1")
},

Seq("-std=c++11"),
Seq("-std=c++14"),

additionalHeaderPaths.map { path => s"-I${path}" },

Expand Down

0 comments on commit 7b92346

Please sign in to comment.