forked from libre-chip/fayalite
add simulator support for sim-only values
This commit is contained in:
parent
d3dd66cbf0
commit
db9b1c202c
52 changed files with 5441 additions and 819 deletions
|
|
@ -9,7 +9,7 @@ use fayalite::{
|
|||
sim::vcd::VcdWriterDecls,
|
||||
util::RcWriter,
|
||||
};
|
||||
use std::num::NonZeroUsize;
|
||||
use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc};
|
||||
|
||||
#[hdl_module(outline_generated)]
|
||||
pub fn connect_const() {
|
||||
|
|
@ -1626,3 +1626,99 @@ fn test_ripple_counter() {
|
|||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
/// use `Rc` to ensure you can use `!Send + !Sync` types
|
||||
type SimOnlyTestMap = BTreeMap<String, Rc<str>>;
|
||||
|
||||
#[hdl_module(outline_generated, extern)]
|
||||
fn sim_only_connects_helper() {
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
#[hdl]
|
||||
let inp: SimOnly<SimOnlyTestMap> = m.input();
|
||||
#[hdl]
|
||||
let out: SimOnly<SimOnlyTestMap> = m.output();
|
||||
m.extern_module_simulation_fn((cd, inp, out), |(cd, inp, out), mut sim| async move {
|
||||
sim.write(out, SimOnlyValue::default()).await;
|
||||
loop {
|
||||
sim.wait_for_clock_edge(cd.clk).await;
|
||||
let mut map = sim.read(inp).await;
|
||||
let foo = map.get("foo").cloned().unwrap_or_default();
|
||||
map.insert(String::from("bar"), foo);
|
||||
map.insert(String::from("foo"), Rc::from("baz"));
|
||||
sim.write(out, map).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[hdl_module(outline_generated)]
|
||||
pub fn sim_only_connects() {
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
#[hdl]
|
||||
let inp: SimOnly<SimOnlyTestMap> = m.input();
|
||||
#[hdl]
|
||||
let out1: SimOnly<SimOnlyTestMap> = m.output();
|
||||
#[hdl]
|
||||
let out2: SimOnly<SimOnlyTestMap> = m.output();
|
||||
#[hdl]
|
||||
let out3: SimOnly<SimOnlyTestMap> = m.output();
|
||||
#[hdl]
|
||||
let helper1 = instance(sim_only_connects_helper());
|
||||
#[hdl]
|
||||
let delay1: SimOnly<SimOnlyTestMap> = reg_builder()
|
||||
.clock_domain(cd)
|
||||
.reset(SimOnly::<SimOnlyTestMap>::new().uninit());
|
||||
#[hdl]
|
||||
let delay1_empty: Bool = reg_builder().clock_domain(cd).reset(true);
|
||||
connect(helper1.cd, cd);
|
||||
connect(helper1.inp, delay1);
|
||||
connect(out1, delay1);
|
||||
#[hdl]
|
||||
if delay1_empty {
|
||||
connect(helper1.inp, inp);
|
||||
connect(out1, inp);
|
||||
}
|
||||
connect(delay1, inp);
|
||||
connect(delay1_empty, false);
|
||||
connect(out2, helper1.out);
|
||||
#[hdl]
|
||||
let helper2 = instance(sim_only_connects_helper());
|
||||
connect(helper2.cd, cd);
|
||||
connect(helper2.inp, out2);
|
||||
connect(out3, helper2.out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sim_only_connects() {
|
||||
let _n = SourceLocation::normalize_files_for_tests();
|
||||
let mut sim = Simulation::new(sim_only_connects());
|
||||
let mut writer = RcWriter::default();
|
||||
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
||||
sim.write(sim.io().cd.rst, true);
|
||||
sim.write(
|
||||
sim.io().inp,
|
||||
SimOnlyValue::new(BTreeMap::from_iter([(
|
||||
String::from("extra"),
|
||||
Rc::from("value"),
|
||||
)])),
|
||||
);
|
||||
for _ in 0..8 {
|
||||
sim.write(sim.io().cd.clk, false);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
sim.write(sim.io().cd.clk, true);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
sim.write(sim.io().cd.rst, false);
|
||||
}
|
||||
sim.flush_traces().unwrap();
|
||||
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||
println!("####### VCD:\n{vcd}\n#######");
|
||||
if vcd != include_str!("sim/expected/sim_only_connects.vcd") {
|
||||
panic!();
|
||||
}
|
||||
let sim_debug = format!("{sim:#?}");
|
||||
println!("#######\n{sim_debug}\n#######");
|
||||
if sim_debug != include_str!("sim/expected/sim_only_connects.txt") {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue