Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

poke in ChiselScalatestTester occurs on falling clock edge in traces #646

Open
yupferris opened this issue Jun 19, 2023 · 4 comments
Open

Comments

@yupferris
Copy link

This is surprising; I would have expected pokes to happen "immediately", typically aligned with the rising edge of the clock in a trace. Is there an option to enable this? As it is now, it's quite an adjustment to read traces this way.

@yupferris yupferris changed the title poke in ChiselScalatestTester occurs on falling edge poke in ChiselScalatestTester occurs on falling clock edge in traces Jun 19, 2023
@ekiwi
Copy link
Collaborator

ekiwi commented Jun 20, 2023

This is actually a often requested feature. It is a little difficult to implement since it would need to work for all our backends and there might be unexpected interactions with Verilog blackboxes, but it would definitely be possible to implement.

You want pokes to occur a delta cycle after the rising edge, correct? Not a delta cycle before the rising edge.

@yupferris
Copy link
Author

yupferris commented Jun 27, 2023

You want pokes to occur a delta cycle after the rising edge, correct? Not a delta cycle before the rising edge.

I'm not entirely sure what a "delta cycle" is, but I think I can relatively easily articulate what I expect. Consider the following design and test:

class Hello extends Module {
  val io = IO(new Bundle {
    val input = Input(Bool())
    val output = Output(Bool())
  })

  io.output := RegNext(io.input, false.B)
}

class HelloTests extends AnyFlatSpec with ChiselScalatestTester {
  behavior of "Hello"

  it should "demonstrate poke edges" in {
    test(new Hello).withAnnotations(Seq(chiseltest.simulator.WriteVcdAnnotation)) { dut =>
      dut.io.input.poke(false)
      dut.clock.step(1)
      dut.io.input.poke(true)
      dut.clock.step(2)
      dut.io.input.poke(false)
      dut.clock.step(2)
    }
  }
}

Running this test, I get the following trace:

image

Importantly, changes to io_output_REG (and correspondingly, io_output) are aligned with rising clock edges, which makes sense, as the clock edge should trigger those updates "immediately" (combinational logic propagation delay is not modeled, as expected). Subsequent changes to io_input, however, are aligned with the following falling clock edge.

I would have expected changes from pokes to also be aligned with the most recent rising clock edge, as if these changes were also triggered by that rising edge, and propagated "immediately". This would look like the following:

image

I'm currently working around this with a python script that shifts all of the non-clock changes to the most recent rising edge in the .vcd output (which is what I used to produce the second trace above). This is obviously less than ideal, but it does work :)

@ekiwi
Copy link
Collaborator

ekiwi commented Jun 27, 2023

OK, I think you want all pokes to apply right after the rising clock edge.

A "delta cycle" is a Verilog term for the smallest possible time-step in simulation. A rising clock edge is an instantaneous event, so you cannot really have an input change "during" the rising edge. They either have to change a litter (i.e. a delta cycle) before or after the rising edge.

@yupferris
Copy link
Author

Ok, right. Then yeah, a delta cycle after the rising edge.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants