Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling Simulation::add_testbench multiple times makes the simulations interfere with each other #30

Open
PoignardAzur opened this issue Jul 23, 2023 · 3 comments

Comments

@PoignardAzur
Copy link

Minimal example:

#[test]
fn test() {
    let mut sim = Simulation::new();
    // TEST_A
    sim.add_testbench(move |mut endpoint: Sim<NandGate>| {
        let mut x = endpoint.init()?;
        x.input_1.next = true.into();
        x.input_2.next = true.into();
        let mut x = endpoint.wait(10 * sim_time::ONE_MICROSECOND, x).unwrap();
        sim_assert_eq!(endpoint, x.output_signal.val(), false, x);
        endpoint.done(x)
    });
    // TEST_B
    sim.add_testbench(move |mut endpoint: Sim<NandGate>| {
        let mut x = endpoint.init()?;
        x.input_1.next = false.into();
        x.input_2.next = true.into();
        let mut x = endpoint.wait(10 * sim_time::ONE_MICROSECOND, x).unwrap();
        endpoint.done(x)
    });
    sim.run_to_file(
        Box::new(NandGate::default()),
        5 * sim_time::ONE_SEC,
        "nandgate.vcd",
    )
    .unwrap();
}

(note the absence of clocks; I don't know if it's a factor)

When the tests are added in the order above, the simulation hangs instead of succeeding. If they're added in the opposite order, (TEST_B then TEST_A), the simulation succeeds.

If TEST_A is changed to fail, there are two scenarios:

  • If TEST_A is added before TEST_B, the simulation succeeds.
  • If TEST_B is added before TEST_A, the simulation fails.

Basically the simulation only "remembers" the last test.

@PoignardAzur PoignardAzur changed the title Calling Simulation::add_testbench makes the simulations interfere with each other Calling Simulation::add_testbench multiple times makes the simulations interfere with each other Jul 23, 2023
@samitbasu
Copy link
Owner

I don't think this is a problem of multiple test-benches, I think the problem is that the two testbenches are "fighting" over the inputs to your circuit. From what I can see, during the first 10 microseconds, both testbenches are driving the same inputs of the circuit to different values. In a physical circuit this would cause bad things to happen. I don't think I can detect this condition, since it is hard to enforce the single-writer principle in the testbenches.

Does that make sense? In RustHDL, test-benches execute on the same circuit simultaneously. If you want to have 2 separate test cases, you need to run 2 separate simulations.

@samitbasu
Copy link
Owner

Alternately, if you want to run multiple test benches sequentially in the same simulation, you need to make the second one wait until the first one is done (by adding a 10 microsecond wait at the beginning, for example), or just putting both test cases into a single testbench and executing them sequentially.

@PoignardAzur
Copy link
Author

Does that make sense?

Not really. I don't see the point in allowing multiple parallel test-benches if they're going to "fight" over the same circuit. Couldn't they each clone the circuit? Or, well, since blocks don't necessarily implement clone, what's the point of having multiple test benches in the same sim at all? Why not allow a single bench per test?

Even if this is the intended behavior, it feels like it kind of goes against the Rust ethos to have this hidden footgun that fires without the program even warning you about it.

or just putting both test cases into a single testbench and executing them sequentially.

That's what I ended up doing.

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

No branches or pull requests

2 participants