simulating circuits with deduced resets works
All checks were successful
/ deps (push) Successful in 15s
/ test (push) Successful in 4m58s
/ deps (pull_request) Successful in 14s
/ test (pull_request) Successful in 4m58s

This commit is contained in:
Jacob Lifshay 2024-11-27 23:52:07 -08:00
parent 6446b71afd
commit 3abba7f9eb
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
2 changed files with 272 additions and 7 deletions

View file

@ -16,9 +16,9 @@ use crate::{
int::BoolOrIntType, int::BoolOrIntType,
intern::{Intern, Interned, Memoize}, intern::{Intern, Interned, Memoize},
module::{ module::{
AnnotatedModuleIO, Block, Id, InstantiatedModule, ModuleBody, NameId, NormalModuleBody, transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, Id, InstantiatedModule,
ScopedNameId, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration,
StmtMatch, StmtReg, StmtWire, TargetInInstantiatedModule, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, StmtWire, TargetInInstantiatedModule,
}, },
prelude::*, prelude::*,
sim::{ sim::{
@ -1183,6 +1183,7 @@ impl Assignment {
#[derive(Debug)] #[derive(Debug)]
pub struct Compiler { pub struct Compiler {
insns: Insns<InsnsBuilding>, insns: Insns<InsnsBuilding>,
original_base_module: Interned<Module<Bundle>>,
base_module: Interned<Module<Bundle>>, base_module: Interned<Module<Bundle>>,
modules: HashMap<InstantiatedModule, CompiledModule>, modules: HashMap<InstantiatedModule, CompiledModule>,
compiled_values: HashMap<TargetInInstantiatedModule, CompiledValue<CanonicalType>>, compiled_values: HashMap<TargetInInstantiatedModule, CompiledValue<CanonicalType>>,
@ -1197,8 +1198,12 @@ pub struct Compiler {
impl Compiler { impl Compiler {
pub fn new(base_module: Interned<Module<Bundle>>) -> Self { pub fn new(base_module: Interned<Module<Bundle>>) -> Self {
let original_base_module = base_module;
let base_module = deduce_resets(base_module, true)
.unwrap_or_else(|e| panic!("failed to deduce reset types: {e}"));
Self { Self {
insns: Insns::new(), insns: Insns::new(),
original_base_module,
base_module, base_module,
modules: HashMap::new(), modules: HashMap::new(),
compiled_values: HashMap::new(), compiled_values: HashMap::new(),
@ -1295,7 +1300,7 @@ impl Compiler {
flow, flow,
} }
.into(), .into(),
CanonicalType::Reset(ty) => todo!(), CanonicalType::Reset(_) => unreachable!(),
CanonicalType::Clock(ty) => TraceClock { CanonicalType::Clock(ty) => TraceClock {
id: self.make_trace_scalar_helper( id: self.make_trace_scalar_helper(
target, target,
@ -2945,10 +2950,10 @@ impl Compiler {
io: Instance::new_unchecked( io: Instance::new_unchecked(
ScopedNameId( ScopedNameId(
NameId("<simulator>".intern(), Id::new()), NameId("<simulator>".intern(), Id::new()),
self.base_module.name_id(), self.original_base_module.name_id(),
), ),
self.base_module, self.original_base_module,
self.base_module.source_location(), self.original_base_module.source_location(),
), ),
traces: Intern::intern_owned(self.traces), traces: Intern::intern_owned(self.traces),
} }

View file

@ -156,6 +156,266 @@ fn test_connect_const() {
assert_eq!(sim.read_bool_or_int(sim.io().o), UIntValue::from(5u8)); assert_eq!(sim.read_bool_or_int(sim.io().o), UIntValue::from(5u8));
} }
#[hdl_module(outline_generated)]
pub fn connect_const_reset() {
#[hdl]
let reset_out: Reset = m.output();
#[hdl]
let bit_out: Bool = m.output();
connect(reset_out, true.to_async_reset().to_reset());
connect(bit_out, reset_out.cast_to_static());
}
#[test]
fn test_connect_const_reset() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(connect_const_reset());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.settle_step();
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
!= r#"$timescale 1 ps $end
$scope module connect_const_reset $end
$var wire 1 ! reset_out $end
$var wire 1 " bit_out $end
$upscope $end
$enddefinitions $end
$dumpvars
1 !
1 "
$end
#1000000
"# {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug
!= r#"Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
len: 5,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out",
ty: AsyncReset,
},
SlotDebugData {
name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: AsyncReset,
},
SlotDebugData {
name: "",
ty: Bool,
},
],
..
},
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool },
value: 1,
},
Copy {
dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset },
src: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:4:1
Copy {
dest: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset },
src: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset },
},
// at: module-XXXXXXXXXX.rs:1:1
Copy {
dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset },
},
// at: module-XXXXXXXXXX.rs:5:1
Copy {
dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out", ty: Bool },
src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
],
..
},
pc: 5,
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
1,
1,
1,
1,
1,
],
},
},
io: Instance {
name: <simulator>::connect_const_reset,
instantiated: Module {
name: connect_const_reset,
..
},
},
uninitialized_inputs: {},
io_targets: {
Instance {
name: <simulator>::connect_const_reset,
instantiated: Module {
name: connect_const_reset,
..
},
}.bit_out: CompiledValue {
layout: CompiledTypeLayout {
ty: Bool,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out",
ty: Bool,
},
],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
},
write: None,
},
Instance {
name: <simulator>::connect_const_reset,
instantiated: Module {
name: connect_const_reset,
..
},
}.reset_out: CompiledValue {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out",
ty: AsyncReset,
},
],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
},
write: None,
},
},
made_initial_step: true,
needs_settle: false,
trace_decls: TraceModule {
name: "connect_const_reset",
children: [
TraceModuleIO {
name: "reset_out",
child: TraceAsyncReset {
id: TraceScalarId(0),
name: "reset_out",
flow: Sink,
},
ty: AsyncReset,
flow: Sink,
},
TraceModuleIO {
name: "bit_out",
child: TraceBool {
id: TraceScalarId(1),
name: "bit_out",
flow: Sink,
},
ty: Bool,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigAsyncReset {
index: StatePartIndex<BigSlots>(0),
},
state: 0x1,
last_state: 0x1,
},
SimTrace {
id: TraceScalarId(1),
kind: BigBool {
index: StatePartIndex<BigSlots>(1),
},
state: 0x1,
last_state: 0x1,
},
],
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
instant: 1 μs,
}"# {
panic!();
}
assert_eq!(sim.read_bool_or_int(sim.io().bit_out), true);
}
#[hdl_module(outline_generated)] #[hdl_module(outline_generated)]
pub fn mod1_child() { pub fn mod1_child() {
#[hdl] #[hdl]