diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 009e599..3802ae4 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -16,6 +16,7 @@ use crate::{ }, int::BoolOrIntType, intern::{Intern, Interned, Memoize}, + memory::PortKind, module::{ transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, Id, InstantiatedModule, ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration, @@ -28,9 +29,9 @@ use crate::{ Insn, InsnField, InsnFieldKind, InsnFieldType, Insns, InsnsBuilding, InsnsBuildingDone, SlotDebugData, SmallUInt, State, StatePartArrayIndex, StatePartArrayIndexed, StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots, - StatePartKindSmallSlots, StatePartLayout, StatePartLen, StatePartsValue, - TypeArrayIndex, TypeArrayIndexes, TypeIndex, TypeIndexRange, TypeLayout, TypeLen, - TypeParts, + StatePartKindMemories, StatePartKindSmallSlots, StatePartLayout, StatePartLen, + StatePartsValue, TypeArrayIndex, TypeArrayIndexes, TypeIndex, TypeIndexRange, + TypeLayout, TypeLen, TypeParts, }, time::{SimDuration, SimInstant}, }, @@ -136,7 +137,7 @@ impl CompiledTypeLayout { name: Interned::default(), ty: *input, }; - layout.big_slots = StatePartLayout::scalar(debug_data); + layout.big_slots = StatePartLayout::scalar(debug_data, ()); CompiledTypeLayout { ty: *input, layout: layout.into(), @@ -1163,14 +1164,20 @@ impl Assignment { } ( _, - InsnFieldType::SmallUInt(_) + InsnFieldType::Memory(_) + | InsnFieldType::SmallUInt(_) | InsnFieldType::SmallSInt(_) | InsnFieldType::InternedBigInt(_) | InsnFieldType::U8(_) | InsnFieldType::USize(_) | InsnFieldType::Empty(_), ) - | (InsnFieldKind::Immediate | InsnFieldKind::BranchTarget, _) => {} + | ( + InsnFieldKind::Immediate + | InsnFieldKind::Memory + | InsnFieldKind::BranchTarget, + _, + ) => {} } } } @@ -1207,6 +1214,20 @@ struct Register { source_location: SourceLocation, } +#[derive(Debug)] +enum MemoryPort { + ReadOnly {}, + WriteOnly {}, + ReadWrite {}, +} + +#[derive(Debug)] +struct Memory { + mem: Mem, + memory: StatePartIndex, + ports: Vec, +} + #[derive(Debug)] pub struct Compiler { insns: Insns, @@ -1227,6 +1248,7 @@ pub struct Compiler { enum_discriminants: HashMap, StatePartIndex>, registers: Vec, traces: Vec>, + memories: Vec, } impl Compiler { @@ -1251,6 +1273,7 @@ impl Compiler { enum_discriminants: HashMap::new(), registers: Vec::new(), traces: Vec::new(), + memories: Vec::new(), } } fn new_sim_trace(&mut self, kind: SimTraceKind) -> TraceScalarId { @@ -1809,7 +1832,7 @@ impl Compiler { let dest = self .insns .allocate_variable(&TypeLayout { - small_slots: StatePartLayout::scalar(debug_data), + small_slots: StatePartLayout::scalar(debug_data, ()), big_slots: StatePartLayout::empty(), }) .small_slots @@ -1851,7 +1874,7 @@ impl Compiler { let dest = self .insns .allocate_variable(&TypeLayout { - small_slots: StatePartLayout::scalar(debug_data), + small_slots: StatePartLayout::scalar(debug_data, ()), big_slots: StatePartLayout::empty(), }) .small_slots @@ -3038,10 +3061,13 @@ impl Compiler { .state_layout .ty .small_slots - .allocate(&StatePartLayout::scalar(SlotDebugData { - name: Interned::default(), - ty: Bool.canonical(), - })) + .allocate(&StatePartLayout::scalar( + SlotDebugData { + name: Interned::default(), + ty: Bool.canonical(), + }, + (), + )) .start }; let last_clk_was_low = alloc_small_slot("last_clk_was_low"); @@ -3098,10 +3124,13 @@ impl Compiler { .state_layout .ty .small_slots - .allocate(&StatePartLayout::scalar(SlotDebugData { - name: Interned::default(), - ty: retval_ty.canonical(), - })) + .allocate(&StatePartLayout::scalar( + SlotDebugData { + name: Interned::default(), + ty: retval_ty.canonical(), + }, + (), + )) .start; let discriminant_bit_width = enum_value.layout.ty.discriminant_bit_width(); let discriminant_mask = !(!0u64 << discriminant_bit_width); @@ -3289,6 +3318,49 @@ impl Compiler { } self.make_trace_decl(*parent_module, target_base) } + fn compile_memory( + &mut self, + mem: Mem, + instantiated_module: InstantiatedModule, + conditions: Interned<[Cond]>, + trace_decls: &mut Vec, + ) { + let memory = self + .insns + .state_layout + .memories + .allocate(&StatePartLayout::scalar( + (), + mem.initial_value().unwrap_or_else(|| { + Intern::intern_owned(BitVec::repeat( + false, + mem.array_type().type_properties().bit_width, + )) + }), + )) + .start; + let ports = mem + .ports() + .iter() + .map(|&port| { + let target_base = TargetBase::MemPort(port); + let target = TargetInInstantiatedModule { + instantiated_module, + target: target_base.into(), + }; + self.decl_conditions.insert(target, conditions); + trace_decls.push(self.make_trace_decl(instantiated_module, target_base)); + todo!("handle read/write"); + match port.port_kind() { + PortKind::ReadOnly => MemoryPort::ReadOnly {}, + PortKind::WriteOnly => MemoryPort::WriteOnly {}, + PortKind::ReadWrite => MemoryPort::ReadWrite {}, + } + }) + .collect(); + self.memories.push(Memory { mem, memory, ports }); + todo!("implement memory"); + } fn compile_block( &mut self, parent_module: Interned, @@ -3298,7 +3370,7 @@ impl Compiler { ) { let Block { memories, stmts } = block; for memory in memories { - todo!("implement memory"); + self.compile_memory(memory, *parent_module, conditions, trace_decls); } for stmt in stmts { match stmt { @@ -3613,11 +3685,17 @@ impl Compiler { } } } + fn process_memories(&mut self) { + for memory in mem::take(&mut self.memories) { + todo!(); + } + } pub fn compile(mut self) -> Compiled { let base_module = *self.compile_module(InstantiatedModule::Base(self.base_module).intern_sized()); self.process_assignments(); self.process_registers(); + self.process_memories(); let clocks_triggered = self.process_clocks(); self.insns .push(Insn::Return, self.base_module.source_location()); diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index cb1f29b..0fd0591 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -2,15 +2,18 @@ // See Notices.txt for copyright information use crate::{ + int::{BoolOrIntType, SInt, UInt}, intern::{Intern, Interned, Memoize}, source_location::SourceLocation, ty::CanonicalType, util::get_many_mut, }; +use bitvec::{boxed::BitBox, slice::BitSlice}; use hashbrown::HashMap; use num_bigint::BigInt; use num_traits::{One, Signed, ToPrimitive, Zero}; use std::{ + any::TypeId, borrow::BorrowMut, convert::Infallible, fmt, @@ -28,6 +31,7 @@ pub(crate) const MIN_BITS_FOR_NEEDING_BIG: usize = SmallUInt::BITS as usize + 1; pub(crate) enum InsnFieldKind { Input, Output, + Memory, Immediate, BranchTarget, } @@ -108,6 +112,7 @@ macro_rules! insn_field_enum { insn_field_enum! { pub(crate) enum InsnFieldType { + Memory(Transform::Type>), SmallSlot(Transform::Type>), BigSlot(Transform::Type>), SmallSlotArrayIndexed(Transform::Type>), @@ -206,7 +211,8 @@ impl Insn { continue; } } - InsnFieldType::SmallSlot(_) + InsnFieldType::Memory(_) + | InsnFieldType::SmallSlot(_) | InsnFieldType::BigSlot(_) | InsnFieldType::SmallSlotArrayIndexed(_) | InsnFieldType::BigSlotArrayIndexed(_) @@ -216,9 +222,15 @@ impl Insn { | InsnFieldType::U8(_) | InsnFieldType::Empty(_) => {} }, - InsnFieldKind::Input | InsnFieldKind::Output | InsnFieldKind::Immediate => {} + InsnFieldKind::Input + | InsnFieldKind::Memory + | InsnFieldKind::Output + | InsnFieldKind::Immediate => {} } match field.ty { + InsnFieldType::Memory(v) => { + v.debug_fmt(f, ",", " // ", "", state_layout)?; + } InsnFieldType::SmallSlot(v) => { v.debug_fmt(f, ",", " // ", "", state_layout)?; } @@ -577,9 +589,10 @@ pub(crate) trait StatePartKind: { const NAME: &'static str; type DebugData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy; + type LayoutData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy; type State: fmt::Debug + 'static + Clone; type BorrowedState<'a>: 'a; - fn new_state(len: StatePartLen) -> Self::State; + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State; fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>; fn part_debug_data( state_layout: &StateLayout, @@ -950,8 +963,8 @@ macro_rules! make_state_part_kinds { Self { insns, pc: 0, - $($state_field: StatePart::new(insns.state_layout.$state_field.len()),)* - $($type_field: StatePart::new(insns.state_layout.ty.$type_field.len()),)* + $($state_field: StatePart::new(&insns.state_layout.$state_field.layout_data),)* + $($type_field: StatePart::new(&insns.state_layout.ty.$type_field.layout_data),)* } } pub(crate) fn borrow(&mut self) -> BorrowedState<'_> { @@ -1150,10 +1163,11 @@ make_state_part_kinds! { impl StatePartKind for StatePartKindSmallStack { const NAME: &'static str = "SmallStack"; type DebugData = (); + type LayoutData = (); type State = Stack; type BorrowedState<'a> = BorrowedStack<'a, SmallUInt>; - fn new_state(len: StatePartLen) -> Self::State { - Stack::new(len.value.try_into().expect("state is too big")) + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { + Stack::new(layout_data.len()) } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { state.borrow() @@ -1169,10 +1183,11 @@ make_state_part_kinds! { impl StatePartKind for StatePartKindBigStack { const NAME: &'static str = "BigStack"; type DebugData = (); + type LayoutData = (); type State = Stack; type BorrowedState<'a> = BorrowedStack<'a, BigInt>; - fn new_state(len: StatePartLen) -> Self::State { - Stack::new(len.value.try_into().expect("state is too big")) + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { + Stack::new(layout_data.len()) } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { state.borrow() @@ -1184,14 +1199,35 @@ make_state_part_kinds! { state_layout.big_stack.debug_data.get(part_index.as_usize()) } }*/ + #[state, field = memories] + impl StatePartKind for StatePartKindMemories { + const NAME: &'static str = "Memories"; + type DebugData = (); + type LayoutData = Interned; + type State = Box<[BitBox]>; + type BorrowedState<'a> = &'a mut [BitBox]; + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { + layout_data.iter().map(|initial_data| BitBox::from_bitslice(initial_data)).collect() + } + fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { + state + } + fn part_debug_data( + state_layout: &StateLayout, + part_index: StatePartIndex, + ) -> Option<&Self::DebugData> { + state_layout.memories.debug_data.get(part_index.as_usize()) + } + } #[type, field = small_slots] impl StatePartKind for StatePartKindSmallSlots { const NAME: &'static str = "SmallSlots"; type DebugData = SlotDebugData; + type LayoutData = (); type State = Box<[SmallUInt]>; type BorrowedState<'a> = &'a mut [SmallUInt]; - fn new_state(len: StatePartLen) -> Self::State { - vec![0; len.value.try_into().expect("state is too big")].into_boxed_slice() + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { + vec![0; layout_data.len()].into_boxed_slice() } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { state @@ -1207,10 +1243,11 @@ make_state_part_kinds! { impl StatePartKind for StatePartKindBigSlots { const NAME: &'static str = "BigSlots"; type DebugData = SlotDebugData; + type LayoutData = (); type State = Box<[BigInt]>; type BorrowedState<'a> = &'a mut [BigInt]; - fn new_state(len: StatePartLen) -> Self::State { - std::iter::repeat_with(BigInt::default).take(len.value.try_into().expect("state is too big")).collect() + fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { + layout_data.iter().map(|_| BigInt::default()).collect() } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { state @@ -1348,6 +1385,7 @@ impl, BK: InsnsBuildingKind> StatePa .iter() .map(|v| v.with_prefixed_debug_names(prefix)) .collect(), + layout_data: self.layout_data.clone(), _phantom: PhantomData, } } @@ -1358,6 +1396,7 @@ impl, BK: InsnsBuildingKind> StatePa .iter() .map(|v| v.with_anonymized_debug_info()) .collect(), + layout_data: self.layout_data.clone(), _phantom: PhantomData, } } @@ -1552,6 +1591,7 @@ impl fmt::Debug for StatePartLen { #[derive(Clone, PartialEq, Eq, Hash)] pub(crate) struct StatePartLayout { pub(crate) debug_data: BK::Vec, + pub(crate) layout_data: BK::Vec, pub(crate) _phantom: PhantomData, } @@ -1572,6 +1612,7 @@ impl StatePartLayout { pub(crate) fn empty() -> Self { Self { debug_data: Default::default(), + layout_data: Default::default(), _phantom: PhantomData, } } @@ -1583,15 +1624,17 @@ impl From> fn from(value: StatePartLayout) -> Self { Self { debug_data: Intern::intern_owned(value.debug_data), + layout_data: Intern::intern_owned(value.layout_data), _phantom: PhantomData, } } } impl StatePartLayout { - pub(crate) fn scalar(debug_data: K::DebugData) -> Self { + pub(crate) fn scalar(debug_data: K::DebugData, layout_data: K::LayoutData) -> Self { Self { debug_data: vec![debug_data], + layout_data: vec![layout_data], _phantom: PhantomData, } } @@ -1609,9 +1652,11 @@ impl StatePartLayout { let len = layout.len(); let Self { debug_data, + layout_data, _phantom: _, } = self; debug_data.extend_from_slice(&layout.debug_data); + layout_data.extend_from_slice(&layout.layout_data); StatePartIndexRange { start, len } } } @@ -1620,13 +1665,18 @@ impl fmt::Debug for StatePartLayout) -> fmt::Result { let Self { debug_data, + layout_data, _phantom: _, } = self; write!(f, "StatePartAllocationLayout<{}>", K::NAME)?; - f.debug_struct("") + let mut debug_struct = f.debug_struct(""); + debug_struct .field("len", &debug_data.len()) - .field("debug_data", debug_data) - .finish_non_exhaustive() + .field("debug_data", debug_data); + if TypeId::of::() != TypeId::of::<()>() { + debug_struct.field("layout_data", layout_data); + } + debug_struct.finish_non_exhaustive() } } @@ -1723,9 +1773,9 @@ pub(crate) struct StatePart { } impl StatePart { - pub(crate) fn new(len: StatePartLen) -> Self { + pub(crate) fn new(layout_data: &[K::LayoutData]) -> Self { Self { - value: K::new_state(len), + value: K::new_state(layout_data), } } pub(crate) fn borrow<'a>(&'a mut self) -> BorrowedStatePart<'a, K> { @@ -2020,7 +2070,8 @@ impl From> for Insns { .address .expect("label address not set"); } - InsnFieldType::SmallSlot(_) + InsnFieldType::Memory(_) + | InsnFieldType::SmallSlot(_) | InsnFieldType::BigSlot(_) | InsnFieldType::SmallSlotArrayIndexed(_) | InsnFieldType::BigSlotArrayIndexed(_) @@ -2032,7 +2083,10 @@ impl From> for Insns { unreachable!() } }, - InsnFieldKind::Input | InsnFieldKind::Output | InsnFieldKind::Immediate => {} + InsnFieldKind::Input + | InsnFieldKind::Memory + | InsnFieldKind::Output + | InsnFieldKind::Immediate => {} } } } @@ -2050,6 +2104,7 @@ impl State { let Self { insns: _, pc, + memories: _, small_slots: _, big_slots: _, } = self; @@ -2161,6 +2216,44 @@ fn cast_bigint_to_uint(src: &BigInt, dest_width: usize) -> BigInt { src & &*bigint_mask(dest_width) } +fn memory_get_mut( + memory: &mut BitSlice, + addr: SmallUInt, + stride: usize, + start: usize, + width: usize, +) -> Option<&mut BitSlice> { + let start = usize::try_from(addr) + .ok()? + .checked_mul(stride)? + .checked_add(start)?; + memory.get_mut(start..start.checked_add(width)?) +} + +fn memory_read_big( + memory: &mut BitSlice, + addr: SmallUInt, + stride: usize, + start: usize, + width: usize, +) -> Option { + let bits = memory_get_mut(memory, addr, stride, start, width)?; + Some(T::bits_to_bigint(bits)) +} + +fn memory_write_big( + memory: &mut BitSlice, + addr: SmallUInt, + stride: usize, + start: usize, + width: usize, + value: &BigInt, +) -> Option<()> { + let bits = memory_get_mut(memory, addr, stride, start, width)?; + T::copy_bits_from_bigint_wrapping(value, bits); + Some(()) +} + impl_insns! { #[insn = Insn, next_macro = next, branch_macro = branch] pub(crate) fn State::run(&mut self) -> () { @@ -2702,6 +2795,78 @@ impl_insns! { next!(); } } + MemoryReadUInt { + #[kind = Output] + dest: StatePartIndex, + #[kind = Memory] + memory: StatePartIndex, + #[kind = Input] + addr: StatePartIndex, + #[kind = Immediate] + stride: usize, + #[kind = Immediate] + start: usize, + #[kind = Immediate] + width: usize, + } => { + let addr = state.small_slots[addr]; + state.big_slots[dest] = memory_read_big::(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default(); + next!(); + } + MemoryReadSInt { + #[kind = Output] + dest: StatePartIndex, + #[kind = Memory] + memory: StatePartIndex, + #[kind = Input] + addr: StatePartIndex, + #[kind = Immediate] + stride: usize, + #[kind = Immediate] + start: usize, + #[kind = Immediate] + width: usize, + } => { + let addr = state.small_slots[addr]; + state.big_slots[dest] = memory_read_big::(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default(); + next!(); + } + MemoryWriteUInt { + #[kind = Input] + value: StatePartIndex, + #[kind = Memory] + memory: StatePartIndex, + #[kind = Input] + addr: StatePartIndex, + #[kind = Immediate] + stride: usize, + #[kind = Immediate] + start: usize, + #[kind = Immediate] + width: usize, + } => { + let addr = state.small_slots[addr]; + memory_write_big::(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]); + next!(); + } + MemoryWriteSInt { + #[kind = Input] + value: StatePartIndex, + #[kind = Memory] + memory: StatePartIndex, + #[kind = Input] + addr: StatePartIndex, + #[kind = Immediate] + stride: usize, + #[kind = Immediate] + start: usize, + #[kind = Immediate] + width: usize, + } => { + let addr = state.small_slots[addr]; + memory_write_big::(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]); + next!(); + } Return => { break; } diff --git a/crates/fayalite/tests/sim/expected/connect_const.txt b/crates/fayalite/tests/sim/expected/connect_const.txt index 189056b..f361cc3 100644 --- a/crates/fayalite/tests/sim/expected/connect_const.txt +++ b/crates/fayalite/tests/sim/expected/connect_const.txt @@ -23,6 +23,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:1:1 @@ -41,6 +47,9 @@ Simulation { .. }, pc: 2, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [], }, diff --git a/crates/fayalite/tests/sim/expected/connect_const_reset.txt b/crates/fayalite/tests/sim/expected/connect_const_reset.txt index 5e6f0eb..0b0c043 100644 --- a/crates/fayalite/tests/sim/expected/connect_const_reset.txt +++ b/crates/fayalite/tests/sim/expected/connect_const_reset.txt @@ -35,6 +35,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:1:1 @@ -67,6 +73,9 @@ Simulation { .. }, pc: 5, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [], }, diff --git a/crates/fayalite/tests/sim/expected/counter_async.txt b/crates/fayalite/tests/sim/expected/counter_async.txt index b72ebbb..0f49e80 100644 --- a/crates/fayalite/tests/sim/expected/counter_async.txt +++ b/crates/fayalite/tests/sim/expected/counter_async.txt @@ -72,6 +72,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:1:1 @@ -162,6 +168,9 @@ Simulation { .. }, pc: 18, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [ 18446744073709551614, diff --git a/crates/fayalite/tests/sim/expected/counter_sync.txt b/crates/fayalite/tests/sim/expected/counter_sync.txt index dbb6134..30b84b2 100644 --- a/crates/fayalite/tests/sim/expected/counter_sync.txt +++ b/crates/fayalite/tests/sim/expected/counter_sync.txt @@ -68,6 +68,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:6:1 @@ -144,6 +150,9 @@ Simulation { .. }, pc: 15, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [ 18446744073709551614, diff --git a/crates/fayalite/tests/sim/expected/mod1.txt b/crates/fayalite/tests/sim/expected/mod1.txt index 74ba140..cf15b07 100644 --- a/crates/fayalite/tests/sim/expected/mod1.txt +++ b/crates/fayalite/tests/sim/expected/mod1.txt @@ -83,6 +83,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:4:1 @@ -174,6 +180,9 @@ Simulation { .. }, pc: 17, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [], }, diff --git a/crates/fayalite/tests/sim/expected/shift_register.txt b/crates/fayalite/tests/sim/expected/shift_register.txt index 5447d49..e89351d 100644 --- a/crates/fayalite/tests/sim/expected/shift_register.txt +++ b/crates/fayalite/tests/sim/expected/shift_register.txt @@ -84,6 +84,12 @@ Simulation { .. }, }, + memories: StatePartAllocationLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, }, insns: [ // at: module-XXXXXXXXXX.rs:13:1 @@ -221,6 +227,9 @@ Simulation { .. }, pc: 30, + memories: StatePart { + value: [], + }, small_slots: StatePart { value: [ 18446744073709551614,