implement simulation of extern modules

This commit is contained in:
Jacob Lifshay 2025-03-19 17:11:41 -07:00
parent 920d8d875f
commit d1bd176b28
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
21 changed files with 2702 additions and 6958 deletions

View file

@ -5,11 +5,14 @@ use fayalite::{
int::UIntValue,
prelude::*,
reset::ResetType,
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue},
sim::{
time::SimDuration, vcd::VcdWriterDecls, ExternModuleSimGenerator,
ExternModuleSimulationState, Simulation, ToSimValue,
},
ty::StaticType,
util::RcWriter,
};
use std::num::NonZeroUsize;
use std::{future::IntoFuture, num::NonZeroUsize};
#[hdl_module(outline_generated)]
pub fn connect_const() {
@ -1443,3 +1446,61 @@ fn test_conditional_assignment_last() {
panic!();
}
}
#[hdl_module(outline_generated, extern)]
pub fn extern_module() {
#[hdl]
let i: Bool = m.input();
#[hdl]
let o: Bool = m.output();
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
struct Sim {
i: Expr<Bool>,
o: Expr<Bool>,
}
impl ExternModuleSimGenerator for Sim {
type IOType = extern_module;
fn run<'a>(
&'a self,
mut sim: ExternModuleSimulationState<Self::IOType>,
) -> impl IntoFuture<Output = ()> + 'a {
let Self { i, o } = *self;
async move {
sim.write(o, true).await;
sim.advance_time(SimDuration::from_nanos(500)).await;
let mut invert = false;
loop {
sim.advance_time(SimDuration::from_micros(1)).await;
let v = sim.read_bool(i).await;
sim.write(o, v ^ invert).await;
invert = !invert;
}
}
}
}
m.extern_module_simulation(Sim { i, o });
}
#[test]
fn test_extern_module() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(extern_module());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write(sim.io().i, false);
sim.advance_time(SimDuration::from_micros(10));
sim.write(sim.io().i, true);
sim.advance_time(SimDuration::from_micros(10));
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/extern_module.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/extern_module.txt") {
panic!();
}
}