simulating circuits with deduced resets works
This commit is contained in:
parent
6446b71afd
commit
3abba7f9eb
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in a new issue