Skip to content

Commit

Permalink
Support views of ports in ChiselSim (#4107) (#4110)
Browse files Browse the repository at this point in the history
Also fix reifySingleData to return the Data itself if it is not a view.

(cherry picked from commit ca49d57)

Co-authored-by: Jack Koenig <[email protected]>
  • Loading branch information
mergify[bot] and jackkoenig authored May 29, 2024
1 parent 680f043 commit c6eff45
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,15 @@ package object dataview {
* @note An Aggregate may be a view of unrelated [[Data]] (eg. like a Seq or tuple) and thus this
* there is no single Data representing the Target and this function will return None
* @return The single Data target of this view or None if a single Data doesn't exist
* @note Returns Some(_) of the argument if it is not a view
*/
private[chisel3] def reifySingleData(data: Data): Option[Data] = {
val candidate: Option[Data] =
data.topBindingOpt match {
case None => None
case Some(ViewBinding(target)) => Some(target)
case Some(AggregateViewBinding(lookup)) => lookup.get(data)
case Some(_) => None
case Some(_) => Some(data)
}
candidate.flatMap { d =>
// Candidate may itself be a view, keep tracing in those cases
Expand Down
12 changes: 11 additions & 1 deletion src/main/scala/chisel3/simulator/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chisel3

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

Expand Down Expand Up @@ -33,7 +34,16 @@ package object simulator {
case (data, port) => data -> controller.port(port.name)
}.toMap
def port(data: Data): Simulation.Port = {
simulationPorts(data)
// TODO, we can support non 1-1 views, but it will require changing this API to return a Seq[Port]
// and packing/unpacking the BigInt literal representation.
val reified = reifySingleData(data).getOrElse {
val url = "https://github.com/chipsalliance/chisel/issues/new/choose"
throw new Exception(
s"Cannot poke $data as is a view that does not map to a single Data. " +
s"Please file an issue at $url requesting support for this use case."
)
}
simulationPorts(reified)
}

// -- Peek/Poke API Support
Expand Down
23 changes: 23 additions & 0 deletions src/test/scala/chiselTests/simulator/SimulatorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,28 @@ class SimulatorSpec extends AnyFunSpec with Matchers {
(actualSV should not).include("emptyBundle")
actualSV should include("bundle_x")
}

it("support peeking and poking FlatIO ports and other views of ports") {
import chisel3.experimental.dataview._
class SimpleModule extends Module {
val io = FlatIO(new Bundle {
val in = Input(UInt(8.W))
val out = Output(UInt(8.W))
})
val viewOfClock = clock.viewAs[Clock]
val delay = RegNext(io.in)
io.out := delay
}
new VerilatorSimulator("test_run_dir/simulator/flat_io_ports")
.simulate(new SimpleModule) { module =>
import PeekPokeAPI._
val dut = module.wrapped
dut.io.in.poke(12.U)
dut.viewOfClock.step(1)
dut.io.out.peek()
dut.io.out.expect(12)
}
.result
}
}
}

0 comments on commit c6eff45

Please sign in to comment.