simulator: allow external module generators to wait for value changes and/or clock edges

This commit is contained in:
Jacob Lifshay 2025-03-25 18:26:48 -07:00
parent ab9ff4f2db
commit a115585d5a
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
6 changed files with 969 additions and 182 deletions

View file

@ -1485,3 +1485,50 @@ fn test_extern_module() {
panic!();
}
}
#[hdl_module(outline_generated, extern)]
pub fn extern_module2() {
#[hdl]
let en: Bool = m.input();
#[hdl]
let clk: Clock = m.input();
#[hdl]
let o: UInt<8> = m.output();
m.extern_module_simulation_fn((en, clk, o), |(en, clk, o), mut sim| async move {
for b in "Hello, World!\n".bytes().cycle() {
sim.write(o, b).await;
loop {
sim.wait_for_clock_edge(clk).await;
if sim.read_bool(en).await {
break;
}
}
}
});
}
#[test]
fn test_extern_module2() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(extern_module2());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
for i in 0..30 {
sim.write(sim.io().en, i % 10 < 5);
sim.write(sim.io().clk, false);
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clk, true);
sim.advance_time(SimDuration::from_micros(1));
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/extern_module2.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/extern_module2.txt") {
panic!();
}
}