forked from libre-chip/fayalite
		
	Compare commits
	
		
			11 commits
		
	
	
		
			8616ee4737
			...
			9b06019bf5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9b06019bf5 | |||
| 36bad52978 | |||
| 21c73051ec | |||
| 304d8da0e8 | |||
| 2af38de900 | |||
| c756aeec70 | |||
| 903ca1bf30 | |||
| 8d030ac65d | |||
| 562c479b62 | |||
| 393f78a14d | |||
|  | 2e7d685dc7 | 
					 21 changed files with 15500 additions and 1242 deletions
				
			
		|  | @ -4,12 +4,14 @@ | ||||||
| use crate::{ | use crate::{ | ||||||
|     expr::{ops::BundleLiteral, Expr, ToExpr}, |     expr::{ops::BundleLiteral, Expr, ToExpr}, | ||||||
|     intern::{Intern, Interned}, |     intern::{Intern, Interned}, | ||||||
|  |     sim::{SimValue, ToSimValue}, | ||||||
|     source_location::SourceLocation, |     source_location::SourceLocation, | ||||||
|     ty::{ |     ty::{ | ||||||
|         impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, StaticType, Type, |         impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, StaticType, Type, | ||||||
|         TypeProperties, TypeWithDeref, |         TypeProperties, TypeWithDeref, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
|  | use bitvec::vec::BitVec; | ||||||
| use hashbrown::HashMap; | use hashbrown::HashMap; | ||||||
| use std::{fmt, marker::PhantomData}; | use std::{fmt, marker::PhantomData}; | ||||||
| 
 | 
 | ||||||
|  | @ -323,7 +325,7 @@ macro_rules! impl_tuple_builder_fields { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| macro_rules! impl_tuples { | macro_rules! impl_tuples { | ||||||
|     ([$({#[num = $num:literal, field = $field:ident] $var:ident: $T:ident})*] []) => { |     ([$({#[num = $num:literal, field = $field:ident, ty = $ty_var:ident: $Ty:ident] $var:ident: $T:ident})*] []) => { | ||||||
|         impl_tuple_builder_fields! { |         impl_tuple_builder_fields! { | ||||||
|             {} |             {} | ||||||
|             [$({ |             [$({ | ||||||
|  | @ -423,6 +425,79 @@ macro_rules! impl_tuples { | ||||||
|                 BundleLiteral::new(ty, field_values[..].intern()).to_expr() |                 BundleLiteral::new(ty, field_values[..].intern()).to_expr() | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         impl<$($T: ToSimValue<CanonicalType>,)*> ToSimValue<CanonicalType> for ($($T,)*) { | ||||||
|  |             #[track_caller] | ||||||
|  |             fn to_sim_value(&self, ty: CanonicalType) -> SimValue<CanonicalType> { | ||||||
|  |                 ToSimValue::<Bundle>::to_sim_value(self, Bundle::from_canonical(ty)).into_canonical() | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn into_sim_value(self, ty: CanonicalType) -> SimValue<CanonicalType> | ||||||
|  |             { | ||||||
|  |                 ToSimValue::<Bundle>::into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn box_into_sim_value(self: Box<Self>, ty: CanonicalType) -> SimValue<CanonicalType> { | ||||||
|  |                 ToSimValue::<Bundle>::box_into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         impl<$($T: ToSimValue<CanonicalType>,)*> ToSimValue<Bundle> for ($($T,)*) { | ||||||
|  |             #[track_caller] | ||||||
|  |             fn to_sim_value(&self, ty: Bundle) -> SimValue<Bundle> { | ||||||
|  |                 let ($($var,)*) = self; | ||||||
|  |                 let [$($ty_var,)*] = *ty.fields() else { | ||||||
|  |                     panic!("bundle has wrong number of fields"); | ||||||
|  |                 }; | ||||||
|  |                 $(let $var = $var.to_sim_value($ty_var.ty);)* | ||||||
|  |                 ToSimValue::into_sim_value(($($var,)*), ty) | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn into_sim_value(self, ty: Bundle) -> SimValue<Bundle> { | ||||||
|  |                 #![allow(unused_mut)] | ||||||
|  |                 #![allow(clippy::unused_unit)] | ||||||
|  |                 let ($($var,)*) = self; | ||||||
|  |                 let [$($ty_var,)*] = *ty.fields() else { | ||||||
|  |                     panic!("bundle has wrong number of fields"); | ||||||
|  |                 }; | ||||||
|  |                 let mut bits: Option<BitVec> = None; | ||||||
|  |                 $(let $var = $var.into_sim_value($ty_var.ty); | ||||||
|  |                 assert_eq!($var.ty(), $ty_var.ty); | ||||||
|  |                 if !$var.bits().is_empty() { | ||||||
|  |                     if let Some(bits) = &mut bits { | ||||||
|  |                         bits.extend_from_bitslice($var.bits()); | ||||||
|  |                     } else { | ||||||
|  |                         let mut $var = $var.into_bits(); | ||||||
|  |                         $var.reserve(ty.type_properties().bit_width - $var.len()); | ||||||
|  |                         bits = Some($var); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 )* | ||||||
|  |                 bits.unwrap_or_else(BitVec::new).into_sim_value(ty) | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn box_into_sim_value(self: Box<Self>, ty: Bundle) -> SimValue<Bundle> { | ||||||
|  |                 Self::into_sim_value(*self, ty) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         impl<$($T: ToSimValue<$Ty>, $Ty: Type,)*> ToSimValue<($($Ty,)*)> for ($($T,)*) { | ||||||
|  |             #[track_caller] | ||||||
|  |             fn to_sim_value(&self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { | ||||||
|  |                 let ($($var,)*) = self; | ||||||
|  |                 let ($($ty_var,)*) = ty; | ||||||
|  |                 $(let $var = $var.to_sim_value($ty_var).into_canonical();)* | ||||||
|  |                 SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn into_sim_value(self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { | ||||||
|  |                 let ($($var,)*) = self; | ||||||
|  |                 let ($($ty_var,)*) = ty; | ||||||
|  |                 $(let $var = $var.into_sim_value($ty_var).into_canonical();)* | ||||||
|  |                 SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) | ||||||
|  |             } | ||||||
|  |             #[track_caller] | ||||||
|  |             fn box_into_sim_value(self: Box<Self>, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { | ||||||
|  |                 Self::into_sim_value(*self, ty) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     }; |     }; | ||||||
|     ([$($lhs:tt)*] [$rhs_first:tt $($rhs:tt)*]) => { |     ([$($lhs:tt)*] [$rhs_first:tt $($rhs:tt)*]) => { | ||||||
|         impl_tuples!([$($lhs)*] []); |         impl_tuples!([$($lhs)*] []); | ||||||
|  | @ -432,18 +507,18 @@ macro_rules! impl_tuples { | ||||||
| 
 | 
 | ||||||
| impl_tuples! { | impl_tuples! { | ||||||
|     [] [ |     [] [ | ||||||
|         {#[num = 0, field = field_0] v0: T0} |         {#[num = 0, field = field_0, ty = ty0: Ty0] v0: T0} | ||||||
|         {#[num = 1, field = field_1] v1: T1} |         {#[num = 1, field = field_1, ty = ty1: Ty1] v1: T1} | ||||||
|         {#[num = 2, field = field_2] v2: T2} |         {#[num = 2, field = field_2, ty = ty2: Ty2] v2: T2} | ||||||
|         {#[num = 3, field = field_3] v3: T3} |         {#[num = 3, field = field_3, ty = ty3: Ty3] v3: T3} | ||||||
|         {#[num = 4, field = field_4] v4: T4} |         {#[num = 4, field = field_4, ty = ty4: Ty4] v4: T4} | ||||||
|         {#[num = 5, field = field_5] v5: T5} |         {#[num = 5, field = field_5, ty = ty5: Ty5] v5: T5} | ||||||
|         {#[num = 6, field = field_6] v6: T6} |         {#[num = 6, field = field_6, ty = ty6: Ty6] v6: T6} | ||||||
|         {#[num = 7, field = field_7] v7: T7} |         {#[num = 7, field = field_7, ty = ty7: Ty7] v7: T7} | ||||||
|         {#[num = 8, field = field_8] v8: T8} |         {#[num = 8, field = field_8, ty = ty8: Ty8] v8: T8} | ||||||
|         {#[num = 9, field = field_9] v9: T9} |         {#[num = 9, field = field_9, ty = ty9: Ty9] v9: T9} | ||||||
|         {#[num = 10, field = field_10] v10: T10} |         {#[num = 10, field = field_10, ty = ty10: Ty10] v10: T10} | ||||||
|         {#[num = 11, field = field_11] v11: T11} |         {#[num = 11, field = field_11, ty = ty11: Ty11] v11: T11} | ||||||
|     ] |     ] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -528,3 +603,27 @@ impl<T: ?Sized + Send + Sync + 'static> ToExpr for PhantomData<T> { | ||||||
|         BundleLiteral::new(PhantomData, Interned::default()).to_expr() |         BundleLiteral::new(PhantomData, Interned::default()).to_expr() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | impl<T: ?Sized + Send + Sync + 'static> ToSimValue<Self> for PhantomData<T> { | ||||||
|  |     #[track_caller] | ||||||
|  |     fn to_sim_value(&self, ty: Self) -> SimValue<Self> { | ||||||
|  |         ToSimValue::into_sim_value(BitVec::new(), ty) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ?Sized> ToSimValue<Bundle> for PhantomData<T> { | ||||||
|  |     #[track_caller] | ||||||
|  |     fn to_sim_value(&self, ty: Bundle) -> SimValue<Bundle> { | ||||||
|  |         assert!(ty.fields().is_empty()); | ||||||
|  |         ToSimValue::into_sim_value(BitVec::new(), ty) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ?Sized> ToSimValue<CanonicalType> for PhantomData<T> { | ||||||
|  |     #[track_caller] | ||||||
|  |     fn to_sim_value(&self, ty: CanonicalType) -> SimValue<CanonicalType> { | ||||||
|  |         let ty = Bundle::from_canonical(ty); | ||||||
|  |         assert!(ty.fields().is_empty()); | ||||||
|  |         ToSimValue::into_sim_value(BitVec::new(), ty).into_canonical() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -519,7 +519,12 @@ impl<Element: Type, Len: Size> fmt::Debug for Mem<Element, Len> { | ||||||
|         f.debug_struct("Mem") |         f.debug_struct("Mem") | ||||||
|             .field("name", scoped_name) |             .field("name", scoped_name) | ||||||
|             .field("array_type", array_type) |             .field("array_type", array_type) | ||||||
|             .field("initial_value", initial_value) |             .field( | ||||||
|  |                 "initial_value", | ||||||
|  |                 &initial_value.as_ref().map(|initial_value| { | ||||||
|  |                     DebugMemoryData::from_bit_slice(*array_type, initial_value) | ||||||
|  |                 }), | ||||||
|  |             ) | ||||||
|             .field("read_latency", read_latency) |             .field("read_latency", read_latency) | ||||||
|             .field("write_latency", write_latency) |             .field("write_latency", write_latency) | ||||||
|             .field("read_under_write", read_under_write) |             .field("read_under_write", read_under_write) | ||||||
|  | @ -1079,3 +1084,61 @@ pub fn splat_mask<T: Type>(ty: T, value: Expr<Bool>) -> Expr<AsMask<T>> { | ||||||
|         )), |         )), | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pub trait DebugMemoryDataGetElement { | ||||||
|  |     fn get_element(&self, element_index: usize, array_type: Array) -> &BitSlice; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a, F: ?Sized + Fn(usize, Array) -> &'a BitSlice> DebugMemoryDataGetElement for &'a F { | ||||||
|  |     fn get_element(&self, element_index: usize, array_type: Array) -> &BitSlice { | ||||||
|  |         self(element_index, array_type) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone)] | ||||||
|  | pub struct DebugMemoryData<GetElement: DebugMemoryDataGetElement> { | ||||||
|  |     pub array_type: Array, | ||||||
|  |     pub get_element: GetElement, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl DebugMemoryDataGetElement for &'_ BitSlice { | ||||||
|  |     fn get_element(&self, element_index: usize, array_type: Array) -> &BitSlice { | ||||||
|  |         assert!(element_index < array_type.len()); | ||||||
|  |         let stride = array_type.element().bit_width(); | ||||||
|  |         let start = element_index | ||||||
|  |             .checked_mul(stride) | ||||||
|  |             .expect("memory is too big"); | ||||||
|  |         let end = start.checked_add(stride).expect("memory is too big"); | ||||||
|  |         &self[start..end] | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> DebugMemoryData<&'a BitSlice> { | ||||||
|  |     pub fn from_bit_slice<T: Type, Depth: Size>( | ||||||
|  |         array_type: ArrayType<T, Depth>, | ||||||
|  |         bit_slice: &'a BitSlice, | ||||||
|  |     ) -> Self { | ||||||
|  |         let array_type = array_type.as_dyn_array(); | ||||||
|  |         assert_eq!(bit_slice.len(), array_type.type_properties().bit_width); | ||||||
|  |         Self { | ||||||
|  |             array_type, | ||||||
|  |             get_element: bit_slice, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<GetElement: DebugMemoryDataGetElement> fmt::Debug for DebugMemoryData<GetElement> { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         if self.array_type.len() == 0 { | ||||||
|  |             return f.write_str("[]"); | ||||||
|  |         } | ||||||
|  |         writeln!(f, "[\n    // len = {:#x}", self.array_type.len())?; | ||||||
|  |         for element_index in 0..self.array_type.len() { | ||||||
|  |             let element = crate::util::BitSliceWriteWithBase( | ||||||
|  |                 self.get_element.get_element(element_index, self.array_type), | ||||||
|  |             ); | ||||||
|  |             writeln!(f, "    [{element_index:#x}]: {element:#x},")?; | ||||||
|  |         } | ||||||
|  |         f.write_str("]") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -2,6 +2,7 @@ | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|  |     array::Array, | ||||||
|     int::{BoolOrIntType, SInt, UInt}, |     int::{BoolOrIntType, SInt, UInt}, | ||||||
|     intern::{Intern, Interned, Memoize}, |     intern::{Intern, Interned, Memoize}, | ||||||
|     source_location::SourceLocation, |     source_location::SourceLocation, | ||||||
|  | @ -9,17 +10,17 @@ use crate::{ | ||||||
|     util::get_many_mut, |     util::get_many_mut, | ||||||
| }; | }; | ||||||
| use bitvec::{boxed::BitBox, slice::BitSlice}; | use bitvec::{boxed::BitBox, slice::BitSlice}; | ||||||
| use hashbrown::HashMap; | use hashbrown::{HashMap, HashSet}; | ||||||
| use num_bigint::BigInt; | use num_bigint::BigInt; | ||||||
| use num_traits::{One, Signed, ToPrimitive, Zero}; | use num_traits::{One, Signed, ToPrimitive, Zero}; | ||||||
| use std::{ | use std::{ | ||||||
|     any::TypeId, |     any::TypeId, | ||||||
|     borrow::BorrowMut, |     borrow::BorrowMut, | ||||||
|     convert::Infallible, |     convert::Infallible, | ||||||
|     fmt, |     fmt::{self, Write}, | ||||||
|     hash::{Hash, Hasher}, |     hash::{Hash, Hasher}, | ||||||
|     marker::PhantomData, |     marker::PhantomData, | ||||||
|     ops::{Deref, DerefMut, Index, IndexMut}, |     ops::{ControlFlow, Deref, DerefMut, Index, IndexMut}, | ||||||
| }; | }; | ||||||
| use vec_map::VecMap; | use vec_map::VecMap; | ||||||
| 
 | 
 | ||||||
|  | @ -174,7 +175,37 @@ fn make_array_into_iter<T, const I: usize, const N: usize>( | ||||||
| 
 | 
 | ||||||
| impl fmt::Debug for Insn { | impl fmt::Debug for Insn { | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|         self.debug_fmt::<InsnsBuildingDone>(f, None, None) |         self.debug_fmt::<InsnsBuildingDone>(f, None, None, None) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct PrefixLinesWrapper<'a, W> { | ||||||
|  |     writer: W, | ||||||
|  |     at_beginning_of_line: bool, | ||||||
|  |     blank_line_prefix: &'a str, | ||||||
|  |     line_prefix: &'a str, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: fmt::Write> fmt::Write for PrefixLinesWrapper<'_, T> { | ||||||
|  |     fn write_str(&mut self, input: &str) -> fmt::Result { | ||||||
|  |         for part in input.split_inclusive('\n') { | ||||||
|  |             if part.is_empty() { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if self.at_beginning_of_line { | ||||||
|  |                 let prefix = match part { | ||||||
|  |                     "\n" => self.blank_line_prefix, | ||||||
|  |                     _ => self.line_prefix, | ||||||
|  |                 }; | ||||||
|  |                 if !prefix.is_empty() { | ||||||
|  |                     self.writer.write_str(prefix)?; | ||||||
|  |                 } | ||||||
|  |                 self.at_beginning_of_line = false; | ||||||
|  |             } | ||||||
|  |             self.writer.write_str(part)?; | ||||||
|  |             self.at_beginning_of_line = part.ends_with('\n'); | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -184,15 +215,22 @@ impl Insn { | ||||||
|         f: &mut fmt::Formatter<'_>, |         f: &mut fmt::Formatter<'_>, | ||||||
|         labels: Option<&Labels>, |         labels: Option<&Labels>, | ||||||
|         state_layout: Option<&StateLayout<BK>>, |         state_layout: Option<&StateLayout<BK>>, | ||||||
|  |         state: Option<&State>, | ||||||
|     ) -> fmt::Result { |     ) -> fmt::Result { | ||||||
|         let (insn_name, fields) = self.fields_with_names(); |         let (insn_name, fields) = self.fields_with_names(); | ||||||
|         write!(f, "{insn_name}")?; |         write!(f, "{insn_name}")?; | ||||||
|         if fields.len() == 0 { |         if fields.len() == 0 { | ||||||
|             return Ok(()); |             return Ok(()); | ||||||
|         } |         } | ||||||
|  |         let mut f = PrefixLinesWrapper { | ||||||
|  |             writer: f, | ||||||
|  |             at_beginning_of_line: false, | ||||||
|  |             blank_line_prefix: "", | ||||||
|  |             line_prefix: "    ", | ||||||
|  |         }; | ||||||
|         writeln!(f, " {{")?; |         writeln!(f, " {{")?; | ||||||
|         for (field_name, field) in fields { |         for (field_name, field) in fields { | ||||||
|             write!(f, "    {field_name}: ")?; |             write!(f, "{field_name}: ")?; | ||||||
|             match field.kind { |             match field.kind { | ||||||
|                 InsnFieldKind::BranchTarget => match field.ty { |                 InsnFieldKind::BranchTarget => match field.ty { | ||||||
|                     InsnFieldType::USize(&label_index) => { |                     InsnFieldType::USize(&label_index) => { | ||||||
|  | @ -227,35 +265,100 @@ impl Insn { | ||||||
|                 | InsnFieldKind::Output |                 | InsnFieldKind::Output | ||||||
|                 | InsnFieldKind::Immediate => {} |                 | InsnFieldKind::Immediate => {} | ||||||
|             } |             } | ||||||
|  |             macro_rules! debug_fmt_state_part { | ||||||
|  |                 ($v:expr) => { | ||||||
|  |                     $v.debug_fmt(&mut f, ",", " // ", "        // ", "", state_layout, state) | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|             match field.ty { |             match field.ty { | ||||||
|                 InsnFieldType::Memory(v) => { |                 InsnFieldType::Memory(v) => { | ||||||
|                     v.debug_fmt(f, ",", " // ", "", state_layout)?; |                     debug_fmt_state_part!(v)?; | ||||||
|                 } |                 } | ||||||
|                 InsnFieldType::SmallSlot(v) => { |                 InsnFieldType::SmallSlot(v) => { | ||||||
|                     v.debug_fmt(f, ",", " // ", "", state_layout)?; |                     debug_fmt_state_part!(v)?; | ||||||
|                 } |                 } | ||||||
|                 InsnFieldType::BigSlot(v) => { |                 InsnFieldType::BigSlot(v) => { | ||||||
|                     v.debug_fmt(f, ",", " // ", "", state_layout)?; |                     debug_fmt_state_part!(v)?; | ||||||
|                 } |                 } | ||||||
|                 InsnFieldType::SmallSlotArrayIndexed(v) => { |                 InsnFieldType::SmallSlotArrayIndexed(v) => { | ||||||
|                     v.debug_fmt(f, ",", " // ", "", state_layout)?; |                     debug_fmt_state_part!(v)?; | ||||||
|                 } |                 } | ||||||
|                 InsnFieldType::BigSlotArrayIndexed(v) => { |                 InsnFieldType::BigSlotArrayIndexed(v) => { | ||||||
|                     v.debug_fmt(f, ",", " // ", "", state_layout)?; |                     debug_fmt_state_part!(v)?; | ||||||
|                 } |                 } | ||||||
|                 InsnFieldType::SmallUInt(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::SmallUInt(v) => write!(f, "{v:#x}")?, | ||||||
|                 InsnFieldType::SmallSInt(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::SmallSInt(v) => write!(f, "{v:#x}")?, | ||||||
|                 InsnFieldType::InternedBigInt(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::InternedBigInt(v) => write!(f, "{v:#x}")?, | ||||||
|                 InsnFieldType::U8(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::U8(v) => write!(f, "{v:#x}")?, | ||||||
|                 InsnFieldType::USize(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::USize(v) => write!(f, "{v}")?, | ||||||
|                 InsnFieldType::Empty(v) => fmt::Debug::fmt(v, f)?, |                 InsnFieldType::Empty(v) => write!(f, "{v:?}")?, | ||||||
|             } |             } | ||||||
|             writeln!(f, ",")?; |             writeln!(f, ",")?; | ||||||
|         } |         } | ||||||
|         write!(f, "}}") |         write!(f.writer, "}}") | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub(crate) trait Breakpoints { | ||||||
|  |     type Break; | ||||||
|  |     fn check_for_breakpoint(&mut self, pc: usize) -> ControlFlow<Self::Break>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ?Sized + Breakpoints> Breakpoints for &'_ mut T { | ||||||
|  |     type Break = T::Break; | ||||||
|  |     fn check_for_breakpoint(&mut self, pc: usize) -> ControlFlow<Self::Break> { | ||||||
|  |         T::check_for_breakpoint(self, pc) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: ?Sized + Breakpoints> Breakpoints for Box<T> { | ||||||
|  |     type Break = T::Break; | ||||||
|  |     fn check_for_breakpoint(&mut self, pc: usize) -> ControlFlow<Self::Break> { | ||||||
|  |         T::check_for_breakpoint(self, pc) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Breakpoints for () { | ||||||
|  |     type Break = Infallible; | ||||||
|  |     fn check_for_breakpoint(&mut self, _pc: usize) -> ControlFlow<Self::Break> { | ||||||
|  |         ControlFlow::Continue(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub(crate) struct BreakpointsSet { | ||||||
|  |     pub(crate) last_was_break: bool, | ||||||
|  |     pub(crate) set: HashSet<usize>, | ||||||
|  |     pub(crate) trace: bool, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] | ||||||
|  | pub(crate) enum BreakAction { | ||||||
|  |     DumpStateAndContinue, | ||||||
|  |     Continue, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Breakpoints for BreakpointsSet { | ||||||
|  |     type Break = BreakAction; | ||||||
|  |     fn check_for_breakpoint(&mut self, pc: usize) -> ControlFlow<Self::Break> { | ||||||
|  |         let retval = if self.last_was_break { | ||||||
|  |             ControlFlow::Continue(()) | ||||||
|  |         } else if self.set.contains(&pc) { | ||||||
|  |             ControlFlow::Break(BreakAction::DumpStateAndContinue) | ||||||
|  |         } else if self.trace { | ||||||
|  |             ControlFlow::Break(BreakAction::Continue) | ||||||
|  |         } else { | ||||||
|  |             ControlFlow::Continue(()) | ||||||
|  |         }; | ||||||
|  |         self.last_was_break = retval.is_break(); | ||||||
|  |         retval | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub(crate) enum RunResult<Break, Return> { | ||||||
|  |     Break(Break), | ||||||
|  |     Return(Return), | ||||||
|  | } | ||||||
|  | 
 | ||||||
| macro_rules! impl_insns { | macro_rules! impl_insns { | ||||||
|     ( |     ( | ||||||
|         #[insn = $Insn:ident, next_macro = $next_macro:ident, branch_macro = $branch_macro:ident] |         #[insn = $Insn:ident, next_macro = $next_macro:ident, branch_macro = $branch_macro:ident] | ||||||
|  | @ -402,11 +505,14 @@ macro_rules! impl_insns { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         impl $State { |         impl $State { | ||||||
|             $vis fn $run(&mut $self) -> $run_ret_ty { |             $vis fn $run<B: Breakpoints>(&mut $self, mut breakpoints: B) -> RunResult<B::Break, $run_ret_ty> { | ||||||
|                 let mut $state = $state_init; |                 let mut $state = $state_init; | ||||||
|                 $($setup)* |                 $($setup)* | ||||||
|                 let mut insn = $state.insns[$state.pc]; |                 let mut insn = $state.insns[$state.pc]; | ||||||
|                 let retval = 'main_loop: loop { |                 let retval = 'main_loop: loop { | ||||||
|  |                     if let ControlFlow::Break(b) = breakpoints.check_for_breakpoint($state.pc) { | ||||||
|  |                         break RunResult::Break(b); | ||||||
|  |                     } | ||||||
|                     macro_rules! $next_macro { |                     macro_rules! $next_macro { | ||||||
|                         () => { |                         () => { | ||||||
|                             $state.pc += 1; |                             $state.pc += 1; | ||||||
|  | @ -542,6 +648,7 @@ struct InsnsDebug<'a, BK: InsnsBuildingKind> { | ||||||
|     insn_source_locations: &'a [SourceLocation], |     insn_source_locations: &'a [SourceLocation], | ||||||
|     labels: &'a BK::Labels, |     labels: &'a BK::Labels, | ||||||
|     state_layout: &'a StateLayout<BK>, |     state_layout: &'a StateLayout<BK>, | ||||||
|  |     state: Option<&'a State>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct InsnDebug<'a, BK: InsnsBuildingKind> { | struct InsnDebug<'a, BK: InsnsBuildingKind> { | ||||||
|  | @ -550,6 +657,7 @@ struct InsnDebug<'a, BK: InsnsBuildingKind> { | ||||||
|     insn: &'a Insn, |     insn: &'a Insn, | ||||||
|     labels: Option<&'a Labels>, |     labels: Option<&'a Labels>, | ||||||
|     state_layout: &'a StateLayout<BK>, |     state_layout: &'a StateLayout<BK>, | ||||||
|  |     state: Option<&'a State>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<BK: InsnsBuildingKind> fmt::Debug for InsnDebug<'_, BK> { | impl<BK: InsnsBuildingKind> fmt::Debug for InsnDebug<'_, BK> { | ||||||
|  | @ -565,7 +673,9 @@ impl<BK: InsnsBuildingKind> fmt::Debug for InsnDebug<'_, BK> { | ||||||
|         if let Some(source_location) = self.source_location { |         if let Some(source_location) = self.source_location { | ||||||
|             writeln!(f, "// at: {source_location}")?; |             writeln!(f, "// at: {source_location}")?; | ||||||
|         } |         } | ||||||
|         self.insn.debug_fmt(f, self.labels, Some(self.state_layout)) |         write!(f, "{}: ", self.address)?; | ||||||
|  |         self.insn | ||||||
|  |             .debug_fmt(f, self.labels, Some(self.state_layout), self.state) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -590,6 +700,7 @@ impl<'a, BK: InsnsBuildingKind> fmt::Debug for InsnsDebug<'a, BK> { | ||||||
|                 insn, |                 insn, | ||||||
|                 labels, |                 labels, | ||||||
|                 state_layout: self.state_layout, |                 state_layout: self.state_layout, | ||||||
|  |                 state: self.state, | ||||||
|             }); |             }); | ||||||
|             last_source_location = Some(source_location); |             last_source_location = Some(source_location); | ||||||
|         } |         } | ||||||
|  | @ -597,8 +708,45 @@ impl<'a, BK: InsnsBuildingKind> fmt::Debug for InsnsDebug<'a, BK> { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<BK: InsnsBuildingKind> fmt::Debug for Insns<BK> { | impl<BK: InsnsBuildingKind> Insns<BK> { | ||||||
|  |     pub(crate) fn debug_insn_at<'a>( | ||||||
|  |         &'a self, | ||||||
|  |         address: usize, | ||||||
|  |         state: Option<&'a State>, | ||||||
|  |     ) -> impl fmt::Debug + 'a { | ||||||
|  |         let Self { | ||||||
|  |             insns, | ||||||
|  |             insn_source_locations, | ||||||
|  |             labels, | ||||||
|  |             state_layout, | ||||||
|  |         } = self; | ||||||
|  |         InsnDebug { | ||||||
|  |             address, | ||||||
|  |             source_location: Some(insn_source_locations[address]), | ||||||
|  |             insn: &insns[address], | ||||||
|  |             labels: BK::labels(labels), | ||||||
|  |             state_layout, | ||||||
|  |             state, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl State { | ||||||
|  |     pub(crate) fn debug_insn_at(&self, address: usize) -> impl fmt::Debug + '_ { | ||||||
|  |         self.insns.debug_insn_at(address, Some(self)) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct InsnsOfState<'a>(&'a State); | ||||||
|  | 
 | ||||||
|  | impl fmt::Debug for InsnsOfState<'_> { | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         self.0.insns.debug_fmt(Some(self.0), f) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<BK: InsnsBuildingKind> Insns<BK> { | ||||||
|  |     fn debug_fmt(&self, state: Option<&State>, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|         let Self { |         let Self { | ||||||
|             insns, |             insns, | ||||||
|             insn_source_locations, |             insn_source_locations, | ||||||
|  | @ -614,12 +762,19 @@ impl<BK: InsnsBuildingKind> fmt::Debug for Insns<BK> { | ||||||
|                     insn_source_locations, |                     insn_source_locations, | ||||||
|                     labels, |                     labels, | ||||||
|                     state_layout, |                     state_layout, | ||||||
|  |                     state, | ||||||
|                 }, |                 }, | ||||||
|             ) |             ) | ||||||
|             .finish_non_exhaustive() |             .finish_non_exhaustive() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl<BK: InsnsBuildingKind> fmt::Debug for Insns<BK> { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         self.debug_fmt(None, f) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub(crate) trait StatePartKind: | pub(crate) trait StatePartKind: | ||||||
|     Send + Sync + Ord + Hash + fmt::Debug + 'static + Copy + Default |     Send + Sync + Ord + Hash + fmt::Debug + 'static + Copy + Default | ||||||
| { | { | ||||||
|  | @ -634,6 +789,11 @@ pub(crate) trait StatePartKind: | ||||||
|         state_layout: &StateLayout<BK>, |         state_layout: &StateLayout<BK>, | ||||||
|         part_index: StatePartIndex<Self>, |         part_index: StatePartIndex<Self>, | ||||||
|     ) -> Option<&Self::DebugData>; |     ) -> Option<&Self::DebugData>; | ||||||
|  |     fn debug_fmt_state_value( | ||||||
|  |         state: &State, | ||||||
|  |         index: StatePartIndex<Self>, | ||||||
|  |         f: &mut impl fmt::Write, | ||||||
|  |     ) -> fmt::Result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(crate) trait StatePartsValue { | pub(crate) trait StatePartsValue { | ||||||
|  | @ -986,19 +1146,39 @@ macro_rules! make_state_part_kinds { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         #[derive(Debug)] |  | ||||||
|         pub(crate) struct State { |         pub(crate) struct State { | ||||||
|             pub(crate) insns: Interned<Insns<InsnsBuildingDone>>, |             pub(crate) insns: Interned<Insns<InsnsBuildingDone>>, | ||||||
|             pub(crate) pc: usize, |             pub(crate) pc: usize, | ||||||
|  |             pub(crate) memory_write_log: Vec<(StatePartIndex<StatePartKindMemories>, usize)>, | ||||||
|             $(pub(crate) $state_field: StatePart<$StateKind>,)* |             $(pub(crate) $state_field: StatePart<$StateKind>,)* | ||||||
|             $(pub(crate) $type_field: StatePart<$TypeKind>,)* |             $(pub(crate) $type_field: StatePart<$TypeKind>,)* | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         impl fmt::Debug for State { | ||||||
|  |             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |                 let Self { | ||||||
|  |                     insns: _, | ||||||
|  |                     pc, | ||||||
|  |                     memory_write_log, | ||||||
|  |                     $($state_field,)* | ||||||
|  |                     $($type_field,)* | ||||||
|  |                 } = self; | ||||||
|  |                 f.debug_struct("State") | ||||||
|  |                     .field("insns", &InsnsOfState(self)) | ||||||
|  |                     .field("pc", pc) | ||||||
|  |                     .field("memory_write_log", memory_write_log) | ||||||
|  |                     $(.field(stringify!($state_field), $state_field))* | ||||||
|  |                     $(.field(stringify!($type_field), $type_field))* | ||||||
|  |                     .finish() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         impl State { |         impl State { | ||||||
|             pub(crate) fn new(insns: Interned<Insns<InsnsBuildingDone>>) -> Self { |             pub(crate) fn new(insns: Interned<Insns<InsnsBuildingDone>>) -> Self { | ||||||
|                 Self { |                 Self { | ||||||
|                     insns, |                     insns, | ||||||
|                     pc: 0, |                     pc: 0, | ||||||
|  |                     memory_write_log: Vec::with_capacity(32), | ||||||
|                     $($state_field: StatePart::new(&insns.state_layout.$state_field.layout_data),)* |                     $($state_field: StatePart::new(&insns.state_layout.$state_field.layout_data),)* | ||||||
|                     $($type_field: StatePart::new(&insns.state_layout.ty.$type_field.layout_data),)* |                     $($type_field: StatePart::new(&insns.state_layout.ty.$type_field.layout_data),)* | ||||||
|                 } |                 } | ||||||
|  | @ -1009,6 +1189,7 @@ macro_rules! make_state_part_kinds { | ||||||
|                     insns: &self.insns.insns, |                     insns: &self.insns.insns, | ||||||
|                     pc: self.pc, |                     pc: self.pc, | ||||||
|                     orig_pc: &mut self.pc, |                     orig_pc: &mut self.pc, | ||||||
|  |                     memory_write_log: &mut self.memory_write_log, | ||||||
|                     $($state_field: self.$state_field.borrow(),)* |                     $($state_field: self.$state_field.borrow(),)* | ||||||
|                     $($type_field: self.$type_field.borrow(),)* |                     $($type_field: self.$type_field.borrow(),)* | ||||||
|                 } |                 } | ||||||
|  | @ -1021,6 +1202,7 @@ macro_rules! make_state_part_kinds { | ||||||
|             pub(crate) insns: &'a [Insn], |             pub(crate) insns: &'a [Insn], | ||||||
|             pub(crate) orig_pc: &'a mut usize, |             pub(crate) orig_pc: &'a mut usize, | ||||||
|             pub(crate) pc: usize, |             pub(crate) pc: usize, | ||||||
|  |             pub(crate) memory_write_log: &'a mut Vec<(StatePartIndex<StatePartKindMemories>, usize)>, | ||||||
|             $(pub(crate) $state_field: BorrowedStatePart<'a, $StateKind>,)* |             $(pub(crate) $state_field: BorrowedStatePart<'a, $StateKind>,)* | ||||||
|             $(pub(crate) $type_field: BorrowedStatePart<'a, $TypeKind>,)* |             $(pub(crate) $type_field: BorrowedStatePart<'a, $TypeKind>,)* | ||||||
|         } |         } | ||||||
|  | @ -1194,6 +1376,25 @@ macro_rules! make_state_part_kinds { | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Copy, Clone, Hash, PartialEq, Eq)] | ||||||
|  | pub(crate) struct MemoryData<T: Deref<Target = BitSlice>> { | ||||||
|  |     pub(crate) array_type: Array, | ||||||
|  |     pub(crate) data: T, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Deref<Target = BitSlice>> fmt::Debug for MemoryData<T> { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         let Self { array_type, data } = self; | ||||||
|  |         f.debug_struct("MemoryData") | ||||||
|  |             .field("array_type", array_type) | ||||||
|  |             .field( | ||||||
|  |                 "data", | ||||||
|  |                 &crate::memory::DebugMemoryData::from_bit_slice(*array_type, data), | ||||||
|  |             ) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| make_state_part_kinds! { | make_state_part_kinds! { | ||||||
|     /*#[state, field = small_stack]
 |     /*#[state, field = small_stack]
 | ||||||
|     impl StatePartKind for StatePartKindSmallStack { |     impl StatePartKind for StatePartKindSmallStack { | ||||||
|  | @ -1239,11 +1440,14 @@ make_state_part_kinds! { | ||||||
|     impl StatePartKind for StatePartKindMemories { |     impl StatePartKind for StatePartKindMemories { | ||||||
|         const NAME: &'static str = "Memories"; |         const NAME: &'static str = "Memories"; | ||||||
|         type DebugData = (); |         type DebugData = (); | ||||||
|         type LayoutData = Interned<BitSlice>; |         type LayoutData = MemoryData<Interned<BitSlice>>; | ||||||
|         type State = Box<[BitBox]>; |         type State = Box<[MemoryData<BitBox>]>; | ||||||
|         type BorrowedState<'a> = &'a mut [BitBox]; |         type BorrowedState<'a> = &'a mut [MemoryData<BitBox>]; | ||||||
|         fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { |         fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { | ||||||
|             layout_data.iter().map(|initial_data| BitBox::from_bitslice(initial_data)).collect() |             layout_data.iter().map(|MemoryData { array_type, data }| MemoryData { | ||||||
|  |                 array_type: *array_type, | ||||||
|  |                 data: BitBox::from_bitslice(data), | ||||||
|  |             }).collect() | ||||||
|         } |         } | ||||||
|         fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { |         fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { | ||||||
|             state |             state | ||||||
|  | @ -1254,6 +1458,13 @@ make_state_part_kinds! { | ||||||
|         ) -> Option<&Self::DebugData> { |         ) -> Option<&Self::DebugData> { | ||||||
|             state_layout.memories.debug_data.get(part_index.as_usize()) |             state_layout.memories.debug_data.get(part_index.as_usize()) | ||||||
|         } |         } | ||||||
|  |         fn debug_fmt_state_value( | ||||||
|  |             state: &State, | ||||||
|  |             index: StatePartIndex<Self>, | ||||||
|  |             f: &mut impl fmt::Write, | ||||||
|  |         ) -> fmt::Result { | ||||||
|  |             write!(f, "{:#?}", &state.memories[index]) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     #[type, field = small_slots] |     #[type, field = small_slots] | ||||||
|     impl StatePartKind for StatePartKindSmallSlots { |     impl StatePartKind for StatePartKindSmallSlots { | ||||||
|  | @ -1274,6 +1485,15 @@ make_state_part_kinds! { | ||||||
|         ) -> Option<&Self::DebugData> { |         ) -> Option<&Self::DebugData> { | ||||||
|             state_layout.ty.small_slots.debug_data.get(part_index.as_usize()) |             state_layout.ty.small_slots.debug_data.get(part_index.as_usize()) | ||||||
|         } |         } | ||||||
|  |         fn debug_fmt_state_value( | ||||||
|  |             state: &State, | ||||||
|  |             index: StatePartIndex<Self>, | ||||||
|  |             f: &mut impl fmt::Write, | ||||||
|  |         ) -> fmt::Result { | ||||||
|  |             let value = state.small_slots[index]; | ||||||
|  |             write!(f, "{value:#x} {}", value as SmallSInt)?; | ||||||
|  |             Ok(()) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     #[type, field = big_slots] |     #[type, field = big_slots] | ||||||
|     impl StatePartKind for StatePartKindBigSlots { |     impl StatePartKind for StatePartKindBigSlots { | ||||||
|  | @ -1294,6 +1514,13 @@ make_state_part_kinds! { | ||||||
|         ) -> Option<&Self::DebugData> { |         ) -> Option<&Self::DebugData> { | ||||||
|             state_layout.ty.big_slots.debug_data.get(part_index.as_usize()) |             state_layout.ty.big_slots.debug_data.get(part_index.as_usize()) | ||||||
|         } |         } | ||||||
|  |         fn debug_fmt_state_value( | ||||||
|  |             state: &State, | ||||||
|  |             index: StatePartIndex<Self>, | ||||||
|  |             f: &mut impl fmt::Write, | ||||||
|  |         ) -> fmt::Result { | ||||||
|  |             write!(f, "{:#x}", state.big_slots[index]) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1469,45 +1696,40 @@ pub(crate) struct StatePartArrayIndexed<K: StatePartKind> { | ||||||
| impl<K: StatePartKind> StatePartArrayIndexed<K> { | impl<K: StatePartKind> StatePartArrayIndexed<K> { | ||||||
|     pub(crate) fn debug_fmt<BK: InsnsBuildingKind>( |     pub(crate) fn debug_fmt<BK: InsnsBuildingKind>( | ||||||
|         &self, |         &self, | ||||||
|         f: &mut fmt::Formatter<'_>, |         f: &mut impl fmt::Write, | ||||||
|         before_debug_info_text: &str, |         before_debug_info_text: &str, | ||||||
|         comment_start: &str, |         comment_start: &str, | ||||||
|  |         comment_line_start: &str, | ||||||
|         comment_end: &str, |         comment_end: &str, | ||||||
|         state_layout: Option<&StateLayout<BK>>, |         state_layout: Option<&StateLayout<BK>>, | ||||||
|  |         state: Option<&State>, | ||||||
|     ) -> fmt::Result { |     ) -> fmt::Result { | ||||||
|         if let Some(state_layout) = state_layout { |  | ||||||
|         let Self { base, indexes } = *self; |         let Self { base, indexes } = *self; | ||||||
|         if indexes.is_empty() { |         if indexes.is_empty() { | ||||||
|             base.debug_fmt( |             base.debug_fmt( | ||||||
|                 f, |                 f, | ||||||
|                 before_debug_info_text, |                 before_debug_info_text, | ||||||
|                 comment_start, |                 comment_start, | ||||||
|  |                 comment_line_start, | ||||||
|                 comment_end, |                 comment_end, | ||||||
|                     Some(state_layout), |                 state_layout, | ||||||
|  |                 state, | ||||||
|             ) |             ) | ||||||
|         } else { |         } else { | ||||||
|                 base.debug_fmt(f, "", " /* ", " */ ", Some(state_layout))?; |             base.debug_fmt(f, "", " /* ", "", " */ ", state_layout, state)?; | ||||||
|             for StatePartArrayIndex { index, len, stride } in indexes { |             for StatePartArrayIndex { index, len, stride } in indexes { | ||||||
|                 f.write_str("[")?; |                 f.write_str("[")?; | ||||||
|                     index.debug_fmt(f, "", " /* ", " */ ", Some(state_layout))?; |                 index.debug_fmt(f, "", " /* ", "", " */ ", state_layout, state)?; | ||||||
|                 write!(f, ", len={len}, stride={}]", stride.value)?; |                 write!(f, ", len={len}, stride={}]", stride.value)?; | ||||||
|             } |             } | ||||||
|             f.write_str(before_debug_info_text) |             f.write_str(before_debug_info_text) | ||||||
|         } |         } | ||||||
|         } else { |  | ||||||
|             let Self { base, indexes } = self; |  | ||||||
|             f.debug_struct("StatePartArrayIndexed") |  | ||||||
|                 .field("base", base) |  | ||||||
|                 .field("indexes", indexes) |  | ||||||
|                 .finish()?; |  | ||||||
|             f.write_str(before_debug_info_text) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<K: StatePartKind + fmt::Debug> fmt::Debug for StatePartArrayIndexed<K> { | impl<K: StatePartKind + fmt::Debug> fmt::Debug for StatePartArrayIndexed<K> { | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|         self.debug_fmt::<InsnsBuildingDone>(f, "", "", "", None) |         self.debug_fmt::<InsnsBuildingDone>(f, "", "", "", "", None, None) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1574,18 +1796,40 @@ impl<K: StatePartKind> StatePartIndex<K> { | ||||||
|     } |     } | ||||||
|     pub(crate) fn debug_fmt<BK: InsnsBuildingKind>( |     pub(crate) fn debug_fmt<BK: InsnsBuildingKind>( | ||||||
|         &self, |         &self, | ||||||
|         f: &mut fmt::Formatter<'_>, |         f: &mut impl fmt::Write, | ||||||
|         before_debug_info_text: &str, |         before_debug_info_text: &str, | ||||||
|         comment_start: &str, |         comment_start: &str, | ||||||
|  |         comment_line_start: &str, | ||||||
|         comment_end: &str, |         comment_end: &str, | ||||||
|         state_layout: Option<&StateLayout<BK>>, |         state_layout: Option<&StateLayout<BK>>, | ||||||
|  |         state: Option<&State>, | ||||||
|     ) -> fmt::Result { |     ) -> fmt::Result { | ||||||
|         write!(f, "StatePartIndex<{}>({})", K::NAME, self.value)?; |         write!(f, "StatePartIndex<{}>({})", K::NAME, self.value)?; | ||||||
|         f.write_str(before_debug_info_text)?; |         f.write_str(before_debug_info_text)?; | ||||||
|         if let Some(state_layout) = state_layout { |         let debug_data = | ||||||
|             if let Some(debug_data) = K::part_debug_data(state_layout, *self) { |             state_layout.and_then(|state_layout| K::part_debug_data(state_layout, *self)); | ||||||
|                 write!(f, "{comment_start}{debug_data:?}{comment_end}")?; |         if state.is_some() || debug_data.is_some() { | ||||||
|  |             f.write_str(comment_start)?; | ||||||
|         } |         } | ||||||
|  |         let mut f = PrefixLinesWrapper { | ||||||
|  |             writer: f, | ||||||
|  |             at_beginning_of_line: false, | ||||||
|  |             blank_line_prefix: comment_line_start.trim_end(), | ||||||
|  |             line_prefix: comment_line_start, | ||||||
|  |         }; | ||||||
|  |         if let Some(state) = state { | ||||||
|  |             f.write_str("(")?; | ||||||
|  |             K::debug_fmt_state_value(state, *self, &mut f)?; | ||||||
|  |             f.write_str(")")?; | ||||||
|  |         } | ||||||
|  |         if state.is_some() && debug_data.is_some() { | ||||||
|  |             f.write_str(" ")?; | ||||||
|  |         } | ||||||
|  |         if let Some(debug_data) = debug_data { | ||||||
|  |             write!(f, "{debug_data:?}")?; | ||||||
|  |         } | ||||||
|  |         if state.is_some() || debug_data.is_some() { | ||||||
|  |             f.writer.write_str(comment_end)?; | ||||||
|         } |         } | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  | @ -1593,7 +1837,7 @@ impl<K: StatePartKind> StatePartIndex<K> { | ||||||
| 
 | 
 | ||||||
| impl<K: StatePartKind> fmt::Debug for StatePartIndex<K> { | impl<K: StatePartKind> fmt::Debug for StatePartIndex<K> { | ||||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|         self.debug_fmt::<InsnsBuildingDone>(f, "", "", "", None) |         self.debug_fmt::<InsnsBuildingDone>(f, "", "", "", "", None, None) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1707,7 +1951,7 @@ impl<K: StatePartKind, BK: InsnsBuildingKind> fmt::Debug for StatePartLayout<K, | ||||||
|             layout_data, |             layout_data, | ||||||
|             _phantom: _, |             _phantom: _, | ||||||
|         } = self; |         } = self; | ||||||
|         write!(f, "StatePartAllocationLayout<{}>", K::NAME)?; |         write!(f, "StatePartLayout<{}>", K::NAME)?; | ||||||
|         let mut debug_struct = f.debug_struct(""); |         let mut debug_struct = f.debug_struct(""); | ||||||
|         debug_struct |         debug_struct | ||||||
|             .field("len", &debug_data.len()) |             .field("len", &debug_data.len()) | ||||||
|  | @ -2146,6 +2390,7 @@ impl State { | ||||||
|         let Self { |         let Self { | ||||||
|             insns: _, |             insns: _, | ||||||
|             pc, |             pc, | ||||||
|  |             memory_write_log: _, | ||||||
|             memories: _, |             memories: _, | ||||||
|             small_slots: _, |             small_slots: _, | ||||||
|             big_slots: _, |             big_slots: _, | ||||||
|  | @ -2172,6 +2417,18 @@ impl BorrowedState<'_> { | ||||||
|         } |         } | ||||||
|         Some(retval) |         Some(retval) | ||||||
|     } |     } | ||||||
|  |     fn log_memory_write(&mut self, memory: StatePartIndex<StatePartKindMemories>, addr: SmallUInt) { | ||||||
|  |         let Ok(addr) = usize::try_from(addr) else { | ||||||
|  |             return; | ||||||
|  |         }; | ||||||
|  |         if addr < self.memories[memory].array_type.len() { | ||||||
|  |             let log_entry = (memory, addr); | ||||||
|  |             if self.memory_write_log.last().copied() == Some(log_entry) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             self.memory_write_log.push(log_entry); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl TypeIndexRange { | impl TypeIndexRange { | ||||||
|  | @ -2503,6 +2760,18 @@ impl_insns! { | ||||||
|         state.big_slots[dest] = value; |         state.big_slots[dest] = value; | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|  |     XorSmallImmediate { | ||||||
|  |         #[kind = Output] | ||||||
|  |         dest: StatePartIndex<StatePartKindSmallSlots>, | ||||||
|  |         #[kind = Input] | ||||||
|  |         lhs: StatePartIndex<StatePartKindSmallSlots>, | ||||||
|  |         #[kind = Immediate] | ||||||
|  |         rhs: SmallUInt, | ||||||
|  |     } => { | ||||||
|  |         let value = state.small_slots[lhs] ^ rhs; | ||||||
|  |         state.small_slots[dest] = value; | ||||||
|  |         next!(); | ||||||
|  |     } | ||||||
|     NotS { |     NotS { | ||||||
|         #[kind = Output] |         #[kind = Output] | ||||||
|         dest: StatePartIndex<StatePartKindBigSlots>, |         dest: StatePartIndex<StatePartKindBigSlots>, | ||||||
|  | @ -2525,16 +2794,6 @@ impl_insns! { | ||||||
|         state.big_slots[dest] = value; |         state.big_slots[dest] = value; | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|     NotSmall { |  | ||||||
|         #[kind = Output] |  | ||||||
|         dest: StatePartIndex<StatePartKindSmallSlots>, |  | ||||||
|         #[kind = Input] |  | ||||||
|         src: StatePartIndex<StatePartKindSmallSlots>, |  | ||||||
|     } => { |  | ||||||
|         let value = !state.small_slots[src]; |  | ||||||
|         state.small_slots[dest] = value; |  | ||||||
|         next!(); |  | ||||||
|     } |  | ||||||
|     Neg { |     Neg { | ||||||
|         #[kind = Output] |         #[kind = Output] | ||||||
|         dest: StatePartIndex<StatePartKindBigSlots>, |         dest: StatePartIndex<StatePartKindBigSlots>, | ||||||
|  | @ -2861,7 +3120,7 @@ impl_insns! { | ||||||
|         width: usize, |         width: usize, | ||||||
|     } => { |     } => { | ||||||
|         let addr = state.small_slots[addr]; |         let addr = state.small_slots[addr]; | ||||||
|         state.big_slots[dest] = memory_read_big::<UInt>(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default(); |         state.big_slots[dest] = memory_read_big::<UInt>(&mut state.memories[memory].data, addr, stride, start, width).unwrap_or_default(); | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|     MemoryReadSInt { |     MemoryReadSInt { | ||||||
|  | @ -2879,7 +3138,7 @@ impl_insns! { | ||||||
|         width: usize, |         width: usize, | ||||||
|     } => { |     } => { | ||||||
|         let addr = state.small_slots[addr]; |         let addr = state.small_slots[addr]; | ||||||
|         state.big_slots[dest] = memory_read_big::<SInt>(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default(); |         state.big_slots[dest] = memory_read_big::<SInt>(&mut state.memories[memory].data, addr, stride, start, width).unwrap_or_default(); | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|     MemoryWriteUInt { |     MemoryWriteUInt { | ||||||
|  | @ -2897,7 +3156,8 @@ impl_insns! { | ||||||
|         width: usize, |         width: usize, | ||||||
|     } => { |     } => { | ||||||
|         let addr = state.small_slots[addr]; |         let addr = state.small_slots[addr]; | ||||||
|         memory_write_big::<UInt>(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]); |         memory_write_big::<UInt>(&mut state.memories[memory].data, addr, stride, start, width, &mut state.big_slots[value]); | ||||||
|  |         state.log_memory_write(memory, addr); | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|     MemoryWriteSInt { |     MemoryWriteSInt { | ||||||
|  | @ -2915,10 +3175,11 @@ impl_insns! { | ||||||
|         width: usize, |         width: usize, | ||||||
|     } => { |     } => { | ||||||
|         let addr = state.small_slots[addr]; |         let addr = state.small_slots[addr]; | ||||||
|         memory_write_big::<SInt>(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]); |         memory_write_big::<SInt>(&mut state.memories[memory].data, addr, stride, start, width, &mut state.big_slots[value]); | ||||||
|  |         state.log_memory_write(memory, addr); | ||||||
|         next!(); |         next!(); | ||||||
|     } |     } | ||||||
|     Return => { |     Return => { | ||||||
|         break; |         break RunResult::Return(()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,13 +9,14 @@ use crate::{ | ||||||
|         time::{SimDuration, SimInstant}, |         time::{SimDuration, SimInstant}, | ||||||
|         TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl, |         TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl, | ||||||
|         TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, |         TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, | ||||||
|         TraceMemPort, TraceModule, TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, |         TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule, | ||||||
|         TraceScope, TraceSyncReset, TraceUInt, TraceWire, TraceWriter, TraceWriterDecls, |         TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSyncReset, | ||||||
|  |         TraceUInt, TraceWire, TraceWriter, TraceWriterDecls, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| use bitvec::slice::BitSlice; | use bitvec::{order::Lsb0, slice::BitSlice}; | ||||||
| use std::{ | use std::{ | ||||||
|     fmt::{self, Display}, |     fmt, | ||||||
|     io::{self, Write}, |     io::{self, Write}, | ||||||
|     mem, |     mem, | ||||||
| }; | }; | ||||||
|  | @ -112,20 +113,20 @@ macro_rules! trait_arg { | ||||||
|     ( |     ( | ||||||
|         trait $Arg:ident { |         trait $Arg:ident { | ||||||
|             $( |             $( | ||||||
|                 fn $fn:ident(self) -> $ty:ty; |                 fn $fn:ident(&mut self) -> $ty:ty; | ||||||
|             )* |             )* | ||||||
|         } |         } | ||||||
|     ) => { |     ) => { | ||||||
|         trait $Arg: Sized { |         trait $Arg: Sized { | ||||||
|             $(fn $fn(self) -> $ty { |             $(fn $fn(&mut self) -> $ty { | ||||||
|                 unreachable!() |                 unreachable!() | ||||||
|             })* |             })* | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $( |         $( | ||||||
|             impl $Arg for $ty { |             impl $Arg for $ty { | ||||||
|                 fn $fn(self) -> $ty { |                 fn $fn(&mut self) -> $ty { | ||||||
|                     self |                     self.reborrow() | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         )* |         )* | ||||||
|  | @ -134,21 +135,52 @@ macro_rules! trait_arg { | ||||||
| 
 | 
 | ||||||
| trait_arg! { | trait_arg! { | ||||||
|     trait Arg { |     trait Arg { | ||||||
|         fn module(self) -> ArgModule; |         fn module(&mut self) -> ArgModule<'_>; | ||||||
|         fn module_body(self) -> ArgModuleBody; |         fn module_body(&mut self) -> ArgModuleBody<'_>; | ||||||
|         fn in_type(self) -> ArgInType; |         fn in_type(&mut self) -> ArgInType<'_>; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct ArgModule {} | struct ArgModule<'a> { | ||||||
|  |     properties: &'a mut VcdWriterProperties, | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| struct ArgModuleBody {} | impl<'a> ArgModule<'a> { | ||||||
|  |     fn reborrow(&mut self) -> ArgModule<'_> { | ||||||
|  |         ArgModule { | ||||||
|  |             properties: self.properties, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Copy)] | struct ArgModuleBody<'a> { | ||||||
| struct ArgInType { |     properties: &'a mut VcdWriterProperties, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> ArgModuleBody<'a> { | ||||||
|  |     fn reborrow(&mut self) -> ArgModuleBody<'_> { | ||||||
|  |         ArgModuleBody { | ||||||
|  |             properties: self.properties, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ArgInType<'a> { | ||||||
|     source_var_type: &'static str, |     source_var_type: &'static str, | ||||||
|     sink_var_type: &'static str, |     sink_var_type: &'static str, | ||||||
|     duplex_var_type: &'static str, |     duplex_var_type: &'static str, | ||||||
|  |     properties: &'a mut VcdWriterProperties, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'a> ArgInType<'a> { | ||||||
|  |     fn reborrow(&mut self) -> ArgInType<'_> { | ||||||
|  |         ArgInType { | ||||||
|  |             source_var_type: self.source_var_type, | ||||||
|  |             sink_var_type: self.sink_var_type, | ||||||
|  |             duplex_var_type: self.duplex_var_type, | ||||||
|  |             properties: self.properties, | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| trait WriteTrace: Copy { | trait WriteTrace: Copy { | ||||||
|  | @ -179,11 +211,10 @@ impl WriteTrace for TraceScalar { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn write_scalar_id<W: io::Write>(writer: &mut W, id: TraceScalarId) -> io::Result<()> { | fn write_vcd_id<W: io::Write>(writer: &mut W, mut id: usize) -> io::Result<()> { | ||||||
|     let min_char = b'!'; |     let min_char = b'!'; | ||||||
|     let max_char = b'~'; |     let max_char = b'~'; | ||||||
|     let base = (max_char - min_char + 1) as usize; |     let base = (max_char - min_char + 1) as usize; | ||||||
|     let mut id = id.as_usize(); |  | ||||||
|     loop { |     loop { | ||||||
|         let digit = (id % base) as u8 + min_char; |         let digit = (id % base) as u8 + min_char; | ||||||
|         id /= base; |         id /= base; | ||||||
|  | @ -195,7 +226,7 @@ fn write_scalar_id<W: io::Write>(writer: &mut W, id: TraceScalarId) -> io::Resul | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn write_escaped<W: io::Write>(writer: &mut W, value: impl Display) -> io::Result<()> { | fn write_escaped<W: io::Write>(writer: &mut W, value: impl fmt::Display) -> io::Result<()> { | ||||||
|     // escaping rules from function GTKWave uses to decode VCD strings:
 |     // escaping rules from function GTKWave uses to decode VCD strings:
 | ||||||
|     // https://github.com/gtkwave/gtkwave/blob/491f24d7e8619cfc1fcc65704ee5c967d1083c18/lib/libfst/fstapi.c#L7090
 |     // https://github.com/gtkwave/gtkwave/blob/491f24d7e8619cfc1fcc65704ee5c967d1083c18/lib/libfst/fstapi.c#L7090
 | ||||||
|     struct Wrapper<W>(W); |     struct Wrapper<W>(W); | ||||||
|  | @ -247,14 +278,47 @@ fn is_unescaped_verilog_identifier(ident: &str) -> bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn write_vcd_var<W: io::Write>( | fn write_vcd_var<W: io::Write>( | ||||||
|  |     properties: &mut VcdWriterProperties, | ||||||
|  |     memory_element_part_body: MemoryElementPartBody, | ||||||
|     writer: &mut W, |     writer: &mut W, | ||||||
|     var_type: &str, |     var_type: &str, | ||||||
|     size: usize, |     size: usize, | ||||||
|     id: TraceScalarId, |     location: TraceLocation, | ||||||
|     name: &str, |     name: &str, | ||||||
| ) -> io::Result<()> { | ) -> io::Result<()> { | ||||||
|  |     let id = match location { | ||||||
|  |         TraceLocation::Scalar(id) => id.as_usize(), | ||||||
|  |         TraceLocation::Memory(TraceMemoryLocation { | ||||||
|  |             id, | ||||||
|  |             depth, | ||||||
|  |             stride: _, | ||||||
|  |             start, | ||||||
|  |             len, | ||||||
|  |         }) => { | ||||||
|  |             let MemoryProperties { | ||||||
|  |                 element_parts, | ||||||
|  |                 element_part_index, | ||||||
|  |                 element_index, | ||||||
|  |             } = &mut properties.memory_properties[id.as_usize()]; | ||||||
|  |             let first_id; | ||||||
|  |             if let Some(element_part) = element_parts.get(*element_part_index) { | ||||||
|  |                 first_id = element_part.first_id; | ||||||
|  |             } else { | ||||||
|  |                 first_id = properties.next_scalar_id; | ||||||
|  |                 properties.next_scalar_id += depth; | ||||||
|  |                 element_parts.push(MemoryElementPart { | ||||||
|  |                     first_id, | ||||||
|  |                     start, | ||||||
|  |                     len, | ||||||
|  |                     body: memory_element_part_body, | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |             *element_part_index += 1; | ||||||
|  |             first_id + *element_index | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|     write!(writer, "$var {var_type} {size} ")?; |     write!(writer, "$var {var_type} {size} ")?; | ||||||
|     write_scalar_id(writer, id)?; |     write_vcd_id(writer, id)?; | ||||||
|     writer.write_all(b" ")?; |     writer.write_all(b" ")?; | ||||||
|     if !is_unescaped_verilog_identifier(name) { |     if !is_unescaped_verilog_identifier(name) { | ||||||
|         writer.write_all(b"\\")?; |         writer.write_all(b"\\")?; | ||||||
|  | @ -264,31 +328,49 @@ fn write_vcd_var<W: io::Write>( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceUInt { | impl WriteTrace for TraceUInt { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgInType { |         let ArgInType { | ||||||
|             source_var_type, |             source_var_type, | ||||||
|             sink_var_type, |             sink_var_type, | ||||||
|             duplex_var_type, |             duplex_var_type, | ||||||
|  |             properties, | ||||||
|         } = arg.in_type(); |         } = arg.in_type(); | ||||||
|         let Self { id, name, ty, flow } = self; |         let Self { | ||||||
|         let var_type = match flow { |             location, | ||||||
|  |             name, | ||||||
|  |             ty, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|  |         let mut var_type = match flow { | ||||||
|             Flow::Source => source_var_type, |             Flow::Source => source_var_type, | ||||||
|             Flow::Sink => sink_var_type, |             Flow::Sink => sink_var_type, | ||||||
|             Flow::Duplex => duplex_var_type, |             Flow::Duplex => duplex_var_type, | ||||||
|         }; |         }; | ||||||
|         if ty.width() == 0 { |         if ty.width() == 0 { | ||||||
|             write_vcd_var(writer, "string", ty.width(), id, &name) |             var_type = "string"; | ||||||
|         } else { |  | ||||||
|             write_vcd_var(writer, var_type, ty.width(), id, &name) |  | ||||||
|         } |         } | ||||||
|  |         write_vcd_var( | ||||||
|  |             properties, | ||||||
|  |             MemoryElementPartBody::Scalar, | ||||||
|  |             writer, | ||||||
|  |             var_type, | ||||||
|  |             ty.width(), | ||||||
|  |             location, | ||||||
|  |             &name, | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceSInt { | impl WriteTrace for TraceSInt { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, ty, flow } = self; |         let Self { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             ty, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|         TraceUInt { |         TraceUInt { | ||||||
|             id, |             location, | ||||||
|             name, |             name, | ||||||
|             ty: UInt::new_dyn(ty.width()), |             ty: UInt::new_dyn(ty.width()), | ||||||
|             flow, |             flow, | ||||||
|  | @ -299,9 +381,13 @@ impl WriteTrace for TraceSInt { | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceBool { | impl WriteTrace for TraceBool { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, flow } = self; |         let Self { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|         TraceUInt { |         TraceUInt { | ||||||
|             id, |             location, | ||||||
|             name, |             name, | ||||||
|             flow, |             flow, | ||||||
|             ty: UInt::new_dyn(1), |             ty: UInt::new_dyn(1), | ||||||
|  | @ -312,46 +398,93 @@ impl WriteTrace for TraceBool { | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceFieldlessEnum { | impl WriteTrace for TraceFieldlessEnum { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, ty, flow } = self; |         let Self { | ||||||
|         TraceEnumDiscriminant { id, name, ty, flow }.write_trace(writer, arg) |             location, | ||||||
|  |             name, | ||||||
|  |             ty, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|  |         TraceEnumDiscriminant { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             ty, | ||||||
|  |             flow, | ||||||
|  |         } | ||||||
|  |         .write_trace(writer, arg) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceEnumDiscriminant { | impl WriteTrace for TraceEnumDiscriminant { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgInType { |         let ArgInType { | ||||||
|             source_var_type: _, |             source_var_type: _, | ||||||
|             sink_var_type: _, |             sink_var_type: _, | ||||||
|             duplex_var_type: _, |             duplex_var_type: _, | ||||||
|  |             properties, | ||||||
|         } = arg.in_type(); |         } = arg.in_type(); | ||||||
|         let Self { |         let Self { | ||||||
|             id, |             location, | ||||||
|             name, |             name, | ||||||
|             ty: _, |             ty, | ||||||
|             flow: _, |             flow: _, | ||||||
|         } = self; |         } = self; | ||||||
|         write_vcd_var(writer, "string", 1, id, &name) |         write_vcd_var( | ||||||
|  |             properties, | ||||||
|  |             MemoryElementPartBody::EnumDiscriminant { ty }, | ||||||
|  |             writer, | ||||||
|  |             "string", | ||||||
|  |             1, | ||||||
|  |             location, | ||||||
|  |             &name, | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceClock { | impl WriteTrace for TraceClock { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, flow } = self; |         let Self { | ||||||
|         TraceBool { id, name, flow }.write_trace(writer, arg) |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|  |         TraceBool { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } | ||||||
|  |         .write_trace(writer, arg) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceSyncReset { | impl WriteTrace for TraceSyncReset { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, flow } = self; |         let Self { | ||||||
|         TraceBool { id, name, flow }.write_trace(writer, arg) |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|  |         TraceBool { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } | ||||||
|  |         .write_trace(writer, arg) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceAsyncReset { | impl WriteTrace for TraceAsyncReset { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { | ||||||
|         let Self { id, name, flow } = self; |         let Self { | ||||||
|         TraceBool { id, name, flow }.write_trace(writer, arg) |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } = self; | ||||||
|  |         TraceBool { | ||||||
|  |             location, | ||||||
|  |             name, | ||||||
|  |             flow, | ||||||
|  |         } | ||||||
|  |         .write_trace(writer, arg) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -360,6 +493,7 @@ impl WriteTrace for TraceScope { | ||||||
|         match self { |         match self { | ||||||
|             Self::Module(v) => v.write_trace(writer, arg), |             Self::Module(v) => v.write_trace(writer, arg), | ||||||
|             Self::Instance(v) => v.write_trace(writer, arg), |             Self::Instance(v) => v.write_trace(writer, arg), | ||||||
|  |             Self::Mem(v) => v.write_trace(writer, arg), | ||||||
|             Self::MemPort(v) => v.write_trace(writer, arg), |             Self::MemPort(v) => v.write_trace(writer, arg), | ||||||
|             Self::Wire(v) => v.write_trace(writer, arg), |             Self::Wire(v) => v.write_trace(writer, arg), | ||||||
|             Self::Reg(v) => v.write_trace(writer, arg), |             Self::Reg(v) => v.write_trace(writer, arg), | ||||||
|  | @ -372,12 +506,12 @@ impl WriteTrace for TraceScope { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceModule { | impl WriteTrace for TraceModule { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgModule {} = arg.module(); |         let ArgModule { properties } = arg.module(); | ||||||
|         let Self { name, children } = self; |         let Self { name, children } = self; | ||||||
|         write_vcd_scope(writer, "module", &name, |writer| { |         write_vcd_scope(writer, "module", &name, |writer| { | ||||||
|             for child in children { |             for child in children { | ||||||
|                 child.write_trace(writer, ArgModuleBody {})?; |                 child.write_trace(writer, ArgModuleBody { properties })?; | ||||||
|             } |             } | ||||||
|             Ok(()) |             Ok(()) | ||||||
|         }) |         }) | ||||||
|  | @ -385,8 +519,8 @@ impl WriteTrace for TraceModule { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceInstance { | impl WriteTrace for TraceInstance { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgModuleBody {} = arg.module_body(); |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|         let Self { |         let Self { | ||||||
|             name: _, |             name: _, | ||||||
|             instance_io, |             instance_io, | ||||||
|  | @ -399,21 +533,74 @@ impl WriteTrace for TraceInstance { | ||||||
|                 source_var_type: "wire", |                 source_var_type: "wire", | ||||||
|                 sink_var_type: "wire", |                 sink_var_type: "wire", | ||||||
|                 duplex_var_type: "wire", |                 duplex_var_type: "wire", | ||||||
|  |                 properties, | ||||||
|             }, |             }, | ||||||
|         )?; |         )?; | ||||||
|         module.write_trace(writer, ArgModule {}) |         module.write_trace(writer, ArgModule { properties }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl WriteTrace for TraceMem { | ||||||
|  |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|  |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|  |         let Self { | ||||||
|  |             id, | ||||||
|  |             name, | ||||||
|  |             stride: _, | ||||||
|  |             element_type, | ||||||
|  |             ports, | ||||||
|  |             array_type, | ||||||
|  |         } = self; | ||||||
|  |         write_vcd_scope(writer, "struct", &*name, |writer| { | ||||||
|  |             write_vcd_scope(writer, "struct", "contents", |writer| { | ||||||
|  |                 for element_index in 0..array_type.len() { | ||||||
|  |                     write_vcd_scope(writer, "struct", &format!("[{element_index}]"), |writer| { | ||||||
|  |                         properties.memory_properties[id.as_usize()].element_index = element_index; | ||||||
|  |                         properties.memory_properties[id.as_usize()].element_part_index = 0; | ||||||
|  |                         element_type.write_trace( | ||||||
|  |                             writer, | ||||||
|  |                             ArgInType { | ||||||
|  |                                 source_var_type: "reg", | ||||||
|  |                                 sink_var_type: "reg", | ||||||
|  |                                 duplex_var_type: "reg", | ||||||
|  |                                 properties, | ||||||
|  |                             }, | ||||||
|  |                         ) | ||||||
|  |                     })?; | ||||||
|  |                 } | ||||||
|  |                 Ok(()) | ||||||
|  |             })?; | ||||||
|  |             for port in ports { | ||||||
|  |                 port.write_trace(writer, ArgModuleBody { properties })?; | ||||||
|  |             } | ||||||
|  |             Ok(()) | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceMemPort { | impl WriteTrace for TraceMemPort { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         todo!() |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|  |         let Self { | ||||||
|  |             name: _, | ||||||
|  |             bundle, | ||||||
|  |             ty: _, | ||||||
|  |         } = self; | ||||||
|  |         bundle.write_trace( | ||||||
|  |             writer, | ||||||
|  |             ArgInType { | ||||||
|  |                 source_var_type: "wire", | ||||||
|  |                 sink_var_type: "wire", | ||||||
|  |                 duplex_var_type: "wire", | ||||||
|  |                 properties, | ||||||
|  |             }, | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceWire { | impl WriteTrace for TraceWire { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgModuleBody {} = arg.module_body(); |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|         let Self { |         let Self { | ||||||
|             name: _, |             name: _, | ||||||
|             child, |             child, | ||||||
|  | @ -425,14 +612,15 @@ impl WriteTrace for TraceWire { | ||||||
|                 source_var_type: "wire", |                 source_var_type: "wire", | ||||||
|                 sink_var_type: "wire", |                 sink_var_type: "wire", | ||||||
|                 duplex_var_type: "wire", |                 duplex_var_type: "wire", | ||||||
|  |                 properties, | ||||||
|             }, |             }, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceReg { | impl WriteTrace for TraceReg { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgModuleBody {} = arg.module_body(); |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|         let Self { |         let Self { | ||||||
|             name: _, |             name: _, | ||||||
|             child, |             child, | ||||||
|  | @ -444,14 +632,15 @@ impl WriteTrace for TraceReg { | ||||||
|                 source_var_type: "reg", |                 source_var_type: "reg", | ||||||
|                 sink_var_type: "reg", |                 sink_var_type: "reg", | ||||||
|                 duplex_var_type: "reg", |                 duplex_var_type: "reg", | ||||||
|  |                 properties, | ||||||
|             }, |             }, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceModuleIO { | impl WriteTrace for TraceModuleIO { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let ArgModuleBody {} = arg.module_body(); |         let ArgModuleBody { properties } = arg.module_body(); | ||||||
|         let Self { |         let Self { | ||||||
|             name: _, |             name: _, | ||||||
|             child, |             child, | ||||||
|  | @ -464,14 +653,15 @@ impl WriteTrace for TraceModuleIO { | ||||||
|                 source_var_type: "wire", |                 source_var_type: "wire", | ||||||
|                 sink_var_type: "wire", |                 sink_var_type: "wire", | ||||||
|                 duplex_var_type: "wire", |                 duplex_var_type: "wire", | ||||||
|  |                 properties, | ||||||
|             }, |             }, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceBundle { | impl WriteTrace for TraceBundle { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let arg = arg.in_type(); |         let mut arg = arg.in_type(); | ||||||
|         let Self { |         let Self { | ||||||
|             name, |             name, | ||||||
|             fields, |             fields, | ||||||
|  | @ -480,7 +670,7 @@ impl WriteTrace for TraceBundle { | ||||||
|         } = self; |         } = self; | ||||||
|         write_vcd_scope(writer, "struct", &name, |writer| { |         write_vcd_scope(writer, "struct", &name, |writer| { | ||||||
|             for field in fields { |             for field in fields { | ||||||
|                 field.write_trace(writer, arg)?; |                 field.write_trace(writer, arg.reborrow())?; | ||||||
|             } |             } | ||||||
|             Ok(()) |             Ok(()) | ||||||
|         }) |         }) | ||||||
|  | @ -488,8 +678,8 @@ impl WriteTrace for TraceBundle { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceArray { | impl WriteTrace for TraceArray { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let arg = arg.in_type(); |         let mut arg = arg.in_type(); | ||||||
|         let Self { |         let Self { | ||||||
|             name, |             name, | ||||||
|             elements, |             elements, | ||||||
|  | @ -498,7 +688,7 @@ impl WriteTrace for TraceArray { | ||||||
|         } = self; |         } = self; | ||||||
|         write_vcd_scope(writer, "struct", &name, |writer| { |         write_vcd_scope(writer, "struct", &name, |writer| { | ||||||
|             for element in elements { |             for element in elements { | ||||||
|                 element.write_trace(writer, arg)?; |                 element.write_trace(writer, arg.reborrow())?; | ||||||
|             } |             } | ||||||
|             Ok(()) |             Ok(()) | ||||||
|         }) |         }) | ||||||
|  | @ -506,8 +696,8 @@ impl WriteTrace for TraceArray { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl WriteTrace for TraceEnumWithFields { | impl WriteTrace for TraceEnumWithFields { | ||||||
|     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> { |     fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { | ||||||
|         let arg = arg.in_type(); |         let mut arg = arg.in_type(); | ||||||
|         let Self { |         let Self { | ||||||
|             name, |             name, | ||||||
|             discriminant, |             discriminant, | ||||||
|  | @ -516,9 +706,9 @@ impl WriteTrace for TraceEnumWithFields { | ||||||
|             flow: _, |             flow: _, | ||||||
|         } = self; |         } = self; | ||||||
|         write_vcd_scope(writer, "struct", &name, |writer| { |         write_vcd_scope(writer, "struct", &name, |writer| { | ||||||
|             discriminant.write_trace(writer, arg)?; |             discriminant.write_trace(writer, arg.reborrow())?; | ||||||
|             for field in non_empty_fields { |             for field in non_empty_fields { | ||||||
|                 field.write_trace(writer, arg)?; |                 field.write_trace(writer, arg.reborrow())?; | ||||||
|             } |             } | ||||||
|             Ok(()) |             Ok(()) | ||||||
|         }) |         }) | ||||||
|  | @ -529,76 +719,184 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> { | ||||||
|     type Error = io::Error; |     type Error = io::Error; | ||||||
|     type TraceWriter = VcdWriter<W>; |     type TraceWriter = VcdWriter<W>; | ||||||
| 
 | 
 | ||||||
|     fn write_decls(self, module: TraceModule) -> Result<Self::TraceWriter, Self::Error> { |     fn write_decls( | ||||||
|  |         self, | ||||||
|  |         module: TraceModule, | ||||||
|  |         trace_scalar_id_count: usize, | ||||||
|  |         trace_memory_id_count: usize, | ||||||
|  |     ) -> Result<Self::TraceWriter, Self::Error> { | ||||||
|         let Self { |         let Self { | ||||||
|             mut writer, |             mut writer, | ||||||
|             timescale, |             timescale, | ||||||
|         } = self; |         } = self; | ||||||
|         writeln!(writer, "$timescale {} $end", vcd_timescale(timescale))?; |         writeln!(writer, "$timescale {} $end", vcd_timescale(timescale))?; | ||||||
|         module.write_trace(&mut writer, ArgModule {})?; |         let mut properties = VcdWriterProperties { | ||||||
|  |             next_scalar_id: trace_scalar_id_count, | ||||||
|  |             memory_properties: (0..trace_memory_id_count) | ||||||
|  |                 .map(|_| MemoryProperties { | ||||||
|  |                     element_parts: Vec::with_capacity(8), | ||||||
|  |                     element_part_index: 0, | ||||||
|  |                     element_index: 0, | ||||||
|  |                 }) | ||||||
|  |                 .collect(), | ||||||
|  |         }; | ||||||
|  |         module.write_trace( | ||||||
|  |             &mut writer, | ||||||
|  |             ArgModule { | ||||||
|  |                 properties: &mut properties, | ||||||
|  |             }, | ||||||
|  |         )?; | ||||||
|         writeln!(writer, "$enddefinitions $end")?; |         writeln!(writer, "$enddefinitions $end")?; | ||||||
|         writeln!(writer, "$dumpvars")?; |         writeln!(writer, "$dumpvars")?; | ||||||
|         Ok(VcdWriter { |         Ok(VcdWriter { | ||||||
|             writer, |             writer, | ||||||
|             finished_init: false, |             finished_init: false, | ||||||
|             timescale, |             timescale, | ||||||
|  |             properties, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | enum MemoryElementPartBody { | ||||||
|  |     Scalar, | ||||||
|  |     EnumDiscriminant { ty: Enum }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct MemoryElementPart { | ||||||
|  |     first_id: usize, | ||||||
|  |     start: usize, | ||||||
|  |     len: usize, | ||||||
|  |     body: MemoryElementPartBody, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct MemoryProperties { | ||||||
|  |     element_parts: Vec<MemoryElementPart>, | ||||||
|  |     element_part_index: usize, | ||||||
|  |     element_index: usize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct VcdWriterProperties { | ||||||
|  |     next_scalar_id: usize, | ||||||
|  |     memory_properties: Box<[MemoryProperties]>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub struct VcdWriter<W: io::Write + 'static> { | pub struct VcdWriter<W: io::Write + 'static> { | ||||||
|     writer: W, |     writer: W, | ||||||
|     finished_init: bool, |     finished_init: bool, | ||||||
|     timescale: SimDuration, |     timescale: SimDuration, | ||||||
|  |     properties: VcdWriterProperties, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<W: io::Write + 'static> VcdWriter<W> { | impl<W: io::Write + 'static> VcdWriter<W> { | ||||||
|     pub fn timescale(&self) -> SimDuration { |     pub fn timescale(&self) -> SimDuration { | ||||||
|         self.timescale |         self.timescale | ||||||
|     } |     } | ||||||
|     fn write_string_value_change( | } | ||||||
|         &mut self, | 
 | ||||||
|         value: impl Display, | fn write_string_value_change( | ||||||
|         id: TraceScalarId, |     writer: &mut impl io::Write, | ||||||
|     ) -> io::Result<()> { |     value: impl fmt::Display, | ||||||
|         self.writer.write_all(b"s")?; |     id: usize, | ||||||
|         write_escaped(&mut self.writer, value)?; | ) -> io::Result<()> { | ||||||
|         self.writer.write_all(b" ")?; |     writer.write_all(b"s")?; | ||||||
|         write_scalar_id(&mut self.writer, id)?; |     write_escaped(writer, value)?; | ||||||
|         self.writer.write_all(b"\n") |     writer.write_all(b" ")?; | ||||||
|  |     write_vcd_id(writer, id)?; | ||||||
|  |     writer.write_all(b"\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn write_bits_value_change( | ||||||
|  |     writer: &mut impl io::Write, | ||||||
|  |     value: &BitSlice, | ||||||
|  |     id: usize, | ||||||
|  | ) -> io::Result<()> { | ||||||
|  |     match value.len() { | ||||||
|  |         0 => writer.write_all(b"s0 ")?, | ||||||
|  |         1 => writer.write_all(if value[0] { b"1" } else { b"0" })?, | ||||||
|  |         _ => { | ||||||
|  |             writer.write_all(b"b")?; | ||||||
|  |             let mut any_ones = false; | ||||||
|  |             for bit in value.iter().rev() { | ||||||
|  |                 if *bit { | ||||||
|  |                     any_ones = true; | ||||||
|  |                     writer.write_all(b"1")?; | ||||||
|  |                 } else if any_ones { | ||||||
|  |                     writer.write_all(b"0")?; | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |             if !any_ones { | ||||||
|  |                 writer.write_all(b"0")?; | ||||||
|  |             } | ||||||
|  |             writer.write_all(b" ")?; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     write_vcd_id(writer, id)?; | ||||||
|  |     writer.write_all(b"\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn write_enum_discriminant_value_change( | ||||||
|  |     writer: &mut impl io::Write, | ||||||
|  |     variant_index: usize, | ||||||
|  |     ty: Enum, | ||||||
|  |     id: usize, | ||||||
|  | ) -> io::Result<()> { | ||||||
|  |     write_string_value_change( | ||||||
|  |         writer, | ||||||
|  |         format_args!( | ||||||
|  |             "{} ({variant_index})", | ||||||
|  |             ty.variants() | ||||||
|  |                 .get(variant_index) | ||||||
|  |                 .map(|v| &*v.name) | ||||||
|  |                 .unwrap_or("<invalid>"), | ||||||
|  |         ), | ||||||
|  |         id, | ||||||
|  |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<W: io::Write> TraceWriter for VcdWriter<W> { | impl<W: io::Write> TraceWriter for VcdWriter<W> { | ||||||
|     type Error = io::Error; |     type Error = io::Error; | ||||||
| 
 | 
 | ||||||
|  |     fn set_memory_element( | ||||||
|  |         &mut self, | ||||||
|  |         memory: TraceMemoryId, | ||||||
|  |         element_index: usize, | ||||||
|  |         element_data: &BitSlice, | ||||||
|  |     ) -> Result<(), Self::Error> { | ||||||
|  |         for &MemoryElementPart { | ||||||
|  |             first_id, | ||||||
|  |             start, | ||||||
|  |             len, | ||||||
|  |             ref body, | ||||||
|  |         } in &self.properties.memory_properties[memory.as_usize()].element_parts | ||||||
|  |         { | ||||||
|  |             match body { | ||||||
|  |                 MemoryElementPartBody::Scalar => write_bits_value_change( | ||||||
|  |                     &mut self.writer, | ||||||
|  |                     &element_data[start..start + len], | ||||||
|  |                     first_id + element_index, | ||||||
|  |                 )?, | ||||||
|  |                 MemoryElementPartBody::EnumDiscriminant { ty } => { | ||||||
|  |                     let mut variant_index = 0; | ||||||
|  |                     BitSlice::<usize, Lsb0>::from_element_mut(&mut variant_index)[..len] | ||||||
|  |                         .clone_from_bitslice(&element_data[start..start + len]); | ||||||
|  |                     write_enum_discriminant_value_change( | ||||||
|  |                         &mut self.writer, | ||||||
|  |                         variant_index, | ||||||
|  |                         *ty, | ||||||
|  |                         first_id + element_index, | ||||||
|  |                     )? | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> { |     fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> { | ||||||
|         match value.len() { |         write_bits_value_change(&mut self.writer, value, id.as_usize()) | ||||||
|             0 => self.writer.write_all(b"s0 ")?, |  | ||||||
|             1 => self.writer.write_all(if value[0] { b"1" } else { b"0" })?, |  | ||||||
|             _ => { |  | ||||||
|                 self.writer.write_all(b"b")?; |  | ||||||
|                 let mut any_ones = false; |  | ||||||
|                 for bit in value.iter().rev() { |  | ||||||
|                     if *bit { |  | ||||||
|                         any_ones = true; |  | ||||||
|                         self.writer.write_all(b"1")?; |  | ||||||
|                     } else if any_ones { |  | ||||||
|                         self.writer.write_all(b"0")?; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 if !any_ones { |  | ||||||
|                     self.writer.write_all(b"0")?; |  | ||||||
|                 } |  | ||||||
|                 self.writer.write_all(b" ")?; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         write_scalar_id(&mut self.writer, id)?; |  | ||||||
|         self.writer.write_all(b"\n") |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn set_signal_sint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> { |     fn set_signal_sint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> { | ||||||
|         self.set_signal_uint(id, value) |         write_bits_value_change(&mut self.writer, value, id.as_usize()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn finish_init(&mut self) -> Result<(), Self::Error> { |     fn finish_init(&mut self) -> Result<(), Self::Error> { | ||||||
|  | @ -630,16 +928,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> { | ||||||
|         variant_index: usize, |         variant_index: usize, | ||||||
|         ty: Enum, |         ty: Enum, | ||||||
|     ) -> Result<(), Self::Error> { |     ) -> Result<(), Self::Error> { | ||||||
|         self.write_string_value_change( |         write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize()) | ||||||
|             format_args!( |  | ||||||
|                 "{} ({variant_index})", |  | ||||||
|                 ty.variants() |  | ||||||
|                     .get(variant_index) |  | ||||||
|                     .map(|v| &*v.name) |  | ||||||
|                     .unwrap_or("<invalid>"), |  | ||||||
|             ), |  | ||||||
|             id, |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -649,6 +938,7 @@ impl<W: io::Write> fmt::Debug for VcdWriter<W> { | ||||||
|             writer: _, |             writer: _, | ||||||
|             finished_init, |             finished_init, | ||||||
|             timescale, |             timescale, | ||||||
|  |             properties: _, | ||||||
|         } = self; |         } = self; | ||||||
|         f.debug_struct("VcdWriter") |         f.debug_struct("VcdWriter") | ||||||
|             .field("finished_init", finished_init) |             .field("finished_init", finished_init) | ||||||
|  |  | ||||||
|  | @ -7,12 +7,13 @@ use fayalite::{ | ||||||
|     clock::{Clock, ClockDomain}, |     clock::{Clock, ClockDomain}, | ||||||
|     expr::{CastTo, HdlPartialEq}, |     expr::{CastTo, HdlPartialEq}, | ||||||
|     firrtl::ExportOptions, |     firrtl::ExportOptions, | ||||||
|     formal::{any_seq, formal_reset, hdl_assert, hdl_assume}, |     formal::{any_const, any_seq, formal_reset, hdl_assert, hdl_assume}, | ||||||
|     hdl_module, |     hdl, hdl_module, | ||||||
|     int::{Bool, UInt}, |     int::{Bool, DynSize, Size, UInt, UIntType}, | ||||||
|     module::{connect, connect_any, reg_builder, wire}, |     module::{connect, connect_any, instance, memory, reg_builder, wire}, | ||||||
|     reset::ToReset, |     reset::ToReset, | ||||||
|     testing::assert_formal, |     testing::assert_formal, | ||||||
|  |     ty::StaticType, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// Test hidden state
 | /// Test hidden state
 | ||||||
|  | @ -131,3 +132,164 @@ mod hidden_state { | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /// Formal verification of designs containing memories
 | ||||||
|  | ///
 | ||||||
|  | /// There is a trick for memories, described in the [Zipcpu blog].
 | ||||||
|  | /// First, select a fixed but arbitrary memory address, monitoring all reads
 | ||||||
|  | /// and writes made to it. Then, assert that anything read from that location
 | ||||||
|  | /// matches the last stored value.
 | ||||||
|  | ///
 | ||||||
|  | /// A difficulty for induction is that the memory represents [hidden_state]. A
 | ||||||
|  | /// solution is to include an additional read port to the memory and assert
 | ||||||
|  | /// that the memory location effectively contains the last stored value.
 | ||||||
|  | /// This additional debug port is present only to assist the proof and is
 | ||||||
|  | /// unused (optimized out) in actual use.
 | ||||||
|  | ///
 | ||||||
|  | /// [Zipcpu blog]: <https://zipcpu.com/zipcpu/2018/07/13/memories.html>
 | ||||||
|  | mod memory { | ||||||
|  |     use super::*; | ||||||
|  | 
 | ||||||
|  |     /// Test a simple 8-bit SRAM model
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_sram() { | ||||||
|  |         #[hdl] | ||||||
|  |         struct WritePort<AddrWidth: Size> { | ||||||
|  |             addr: UIntType<AddrWidth>, | ||||||
|  |             data: UInt<8>, | ||||||
|  |             en: Bool, | ||||||
|  |         } | ||||||
|  |         #[hdl] | ||||||
|  |         struct ReadPort<AddrWidth: Size> { | ||||||
|  |             addr: UIntType<AddrWidth>, | ||||||
|  |             #[hdl(flip)] | ||||||
|  |             data: UInt<8>, | ||||||
|  |         } | ||||||
|  |         /// This debug port is only meant to assist the proof.
 | ||||||
|  |         /// For normal use in a design, a wrapper could be provided,
 | ||||||
|  |         /// omitting this port.
 | ||||||
|  |         /// The implementation is forbidden to use any information
 | ||||||
|  |         /// provided on this port in its internal workings.
 | ||||||
|  |         #[hdl] | ||||||
|  |         struct DebugPort<AddrWidth: Size> { | ||||||
|  |             selected: UIntType<AddrWidth>, | ||||||
|  |             stored: UInt<8>, | ||||||
|  |             wrote: Bool, | ||||||
|  |         } | ||||||
|  |         /// simple 1R1W SRAM model (one asynchronous read port and one
 | ||||||
|  |         /// independent write port) with `n`-bit address width
 | ||||||
|  |         #[hdl_module] | ||||||
|  |         fn example_sram(n: usize) { | ||||||
|  |             #[hdl] | ||||||
|  |             let wr: WritePort<DynSize> = m.input(WritePort[n]); | ||||||
|  |             #[hdl] | ||||||
|  |             let rd: ReadPort<DynSize> = m.input(ReadPort[n]); | ||||||
|  |             #[hdl] | ||||||
|  |             let cd: ClockDomain = m.input(); | ||||||
|  | 
 | ||||||
|  |             // declare and connect the backing memory
 | ||||||
|  |             #[hdl] | ||||||
|  |             let mut mem = memory(); | ||||||
|  |             mem.depth(1 << n); | ||||||
|  |             let read_port = mem.new_read_port(); | ||||||
|  |             let write_port = mem.new_write_port(); | ||||||
|  |             connect(write_port.clk, cd.clk); | ||||||
|  |             connect(write_port.addr, wr.addr); | ||||||
|  |             connect(write_port.en, wr.en); | ||||||
|  |             connect(write_port.data, wr.data); | ||||||
|  |             connect(write_port.mask, true); | ||||||
|  |             connect(read_port.clk, cd.clk); | ||||||
|  |             connect(read_port.addr, rd.addr); | ||||||
|  |             connect(read_port.en, true); | ||||||
|  |             connect(rd.data, read_port.data); | ||||||
|  | 
 | ||||||
|  |             // To assist with induction, ensure that the chosen memory location
 | ||||||
|  |             // really contains, always, the last value written to it.
 | ||||||
|  |             #[hdl] | ||||||
|  |             let dbg: DebugPort<DynSize> = m.input(DebugPort[n]); | ||||||
|  |             let debug_port = mem.new_read_port(); | ||||||
|  |             connect(debug_port.en, true); | ||||||
|  |             connect(debug_port.clk, cd.clk); | ||||||
|  |             connect(debug_port.addr, dbg.selected); | ||||||
|  |             #[hdl] | ||||||
|  |             if dbg.wrote { | ||||||
|  |                 hdl_assert(cd.clk, debug_port.data.cmp_eq(dbg.stored), ""); | ||||||
|  |                 // Try commenting out the assert above, induction will fail.
 | ||||||
|  |                 // Opening the trace, it can be seen that the memory contents
 | ||||||
|  |                 // and the stored value don't match, which is an unreachable
 | ||||||
|  |                 // state. By asserting the above, it will become invalid
 | ||||||
|  |                 // as well, so induction will skip this kind of situation.
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// formal verification of the SRAM module, parametrized by the
 | ||||||
|  |         /// address bit-width
 | ||||||
|  |         #[hdl_module] | ||||||
|  |         fn test_module(n: usize) { | ||||||
|  |             #[hdl] | ||||||
|  |             let clk: Clock = m.input(); | ||||||
|  |             let cd = #[hdl] | ||||||
|  |             ClockDomain { | ||||||
|  |                 clk, | ||||||
|  |                 rst: formal_reset().to_reset(), | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             // instantiate the SRAM model, connecting its inputs to
 | ||||||
|  |             // a random sequence
 | ||||||
|  |             #[hdl] | ||||||
|  |             let rd: ReadPort<DynSize> = wire(ReadPort[n]); | ||||||
|  |             connect(rd.addr, any_seq(UInt[n])); | ||||||
|  |             #[hdl] | ||||||
|  |             let wr: WritePort<DynSize> = wire(WritePort[n]); | ||||||
|  |             connect(wr.addr, any_seq(UInt[n])); | ||||||
|  |             connect(wr.data, any_seq(UInt::<8>::TYPE)); | ||||||
|  |             connect(wr.en, any_seq(Bool)); | ||||||
|  |             #[hdl] | ||||||
|  |             let dut = instance(example_sram(n)); | ||||||
|  |             connect(dut.cd, cd); | ||||||
|  |             connect(dut.rd, rd); | ||||||
|  |             connect(dut.wr, wr); | ||||||
|  | 
 | ||||||
|  |             // select a fixed but arbitrary test address
 | ||||||
|  |             #[hdl] | ||||||
|  |             let selected = wire(UInt[n]); | ||||||
|  |             connect(selected, any_const(UInt[n])); | ||||||
|  |             // store the last value written to that address
 | ||||||
|  |             #[hdl] | ||||||
|  |             let stored: UInt<8> = reg_builder().clock_domain(cd).reset(0u8); | ||||||
|  |             // since memories are not initialized, track whether we wrote to the
 | ||||||
|  |             // memory at least once
 | ||||||
|  |             #[hdl] | ||||||
|  |             let wrote: Bool = reg_builder().clock_domain(cd).reset(false); | ||||||
|  |             // on a write, capture the last written value
 | ||||||
|  |             #[hdl] | ||||||
|  |             if wr.en & wr.addr.cmp_eq(selected) { | ||||||
|  |                 connect(stored, wr.data); | ||||||
|  |                 connect(wrote, true); | ||||||
|  |             } | ||||||
|  |             // on a read, assert that the read value is the same which was stored
 | ||||||
|  |             #[hdl] | ||||||
|  |             if rd.addr.cmp_eq(selected) & wrote { | ||||||
|  |                 hdl_assert(clk, rd.data.cmp_eq(stored), ""); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // to assist induction, pass our state to the underlying instance
 | ||||||
|  |             let dbg = #[hdl] | ||||||
|  |             DebugPort { | ||||||
|  |                 selected, | ||||||
|  |                 stored, | ||||||
|  |                 wrote, | ||||||
|  |             }; | ||||||
|  |             connect(dut.dbg, dbg); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assert_formal( | ||||||
|  |             "sram", | ||||||
|  |             test_module(8), | ||||||
|  |             FormalMode::Prove, | ||||||
|  |             2, | ||||||
|  |             None, | ||||||
|  |             ExportOptions::default(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -1,12 +1,15 @@ | ||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later
 | // SPDX-License-Identifier: LGPL-3.0-or-later
 | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
|  | 
 | ||||||
| use fayalite::{ | use fayalite::{ | ||||||
|     int::UIntValue, |     int::UIntValue, | ||||||
|     prelude::*, |     prelude::*, | ||||||
|     reset::ResetType, |     reset::ResetType, | ||||||
|     sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation}, |     sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue}, | ||||||
|  |     ty::StaticType, | ||||||
|     util::RcWriter, |     util::RcWriter, | ||||||
| }; | }; | ||||||
|  | use std::num::NonZeroUsize; | ||||||
| 
 | 
 | ||||||
| #[hdl_module(outline_generated)] | #[hdl_module(outline_generated)] | ||||||
| pub fn connect_const() { | pub fn connect_const() { | ||||||
|  | @ -252,8 +255,14 @@ fn test_shift_register() { | ||||||
|     let mut sim = Simulation::new(shift_register()); |     let mut sim = Simulation::new(shift_register()); | ||||||
|     let mut writer = RcWriter::default(); |     let mut writer = RcWriter::default(); | ||||||
|     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|     sim.write_clock(sim.io().cd.clk, false); |     sim.write( | ||||||
|     sim.write_reset(sim.io().cd.rst, true); |         sim.io().cd, | ||||||
|  |         #[hdl] | ||||||
|  |         ClockDomain { | ||||||
|  |             clk: false.to_clock(), | ||||||
|  |             rst: true.to_sync_reset(), | ||||||
|  |         }, | ||||||
|  |     ); | ||||||
|     sim.write_bool(sim.io().d, false); |     sim.write_bool(sim.io().d, false); | ||||||
|     sim.advance_time(SimDuration::from_micros(1)); |     sim.advance_time(SimDuration::from_micros(1)); | ||||||
|     sim.write_clock(sim.io().cd.clk, true); |     sim.write_clock(sim.io().cd.clk, true); | ||||||
|  | @ -269,7 +278,7 @@ fn test_shift_register() { | ||||||
|                 assert_eq!( |                 assert_eq!( | ||||||
|                     *expected, |                     *expected, | ||||||
|                     sim.read_bool(sim.io().q), |                     sim.read_bool(sim.io().q), | ||||||
|                     "cycle: {cycle}\nvcd:\n{}", |                     "vcd:\n{}\ncycle: {cycle}", | ||||||
|                     String::from_utf8(writer.take()).unwrap(), |                     String::from_utf8(writer.take()).unwrap(), | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|  | @ -307,6 +316,8 @@ pub fn enums() { | ||||||
|     let which_out: UInt<2> = m.output(); |     let which_out: UInt<2> = m.output(); | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     let data_out: UInt<4> = m.output(); |     let data_out: UInt<4> = m.output(); | ||||||
|  |     #[hdl] | ||||||
|  |     let b_out: HdlOption<(UInt<1>, Bool)> = m.output(); | ||||||
| 
 | 
 | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     struct MyStruct<T> { |     struct MyStruct<T> { | ||||||
|  | @ -346,6 +357,8 @@ pub fn enums() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     connect(b_out, HdlNone()); | ||||||
|  | 
 | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     match the_reg { |     match the_reg { | ||||||
|         MyEnum::A => { |         MyEnum::A => { | ||||||
|  | @ -355,6 +368,7 @@ pub fn enums() { | ||||||
|         MyEnum::B(v) => { |         MyEnum::B(v) => { | ||||||
|             connect(which_out, 1_hdl_u2); |             connect(which_out, 1_hdl_u2); | ||||||
|             connect_any(data_out, v.0 | (v.1.cast_to_static::<UInt<1>>() << 1)); |             connect_any(data_out, v.0 | (v.1.cast_to_static::<UInt<1>>() << 1)); | ||||||
|  |             connect(b_out, HdlSome(v)); | ||||||
|         } |         } | ||||||
|         MyEnum::C(v) => { |         MyEnum::C(v) => { | ||||||
|             connect(which_out, 2_hdl_u2); |             connect(which_out, 2_hdl_u2); | ||||||
|  | @ -380,13 +394,33 @@ fn test_enums() { | ||||||
|     sim.advance_time(SimDuration::from_nanos(100)); |     sim.advance_time(SimDuration::from_nanos(100)); | ||||||
|     sim.write_reset(sim.io().cd.rst, false); |     sim.write_reset(sim.io().cd.rst, false); | ||||||
|     sim.advance_time(SimDuration::from_nanos(900)); |     sim.advance_time(SimDuration::from_nanos(900)); | ||||||
|     #[derive(Debug, PartialEq, Eq)] |     type BOutTy = HdlOption<(UInt<1>, Bool)>; | ||||||
|  |     #[derive(Debug)] | ||||||
|     struct IO { |     struct IO { | ||||||
|         en: bool, |         en: bool, | ||||||
|         which_in: u8, |         which_in: u8, | ||||||
|         data_in: u8, |         data_in: u8, | ||||||
|         which_out: u8, |         which_out: u8, | ||||||
|         data_out: u8, |         data_out: u8, | ||||||
|  |         b_out: Expr<BOutTy>, | ||||||
|  |     } | ||||||
|  |     impl PartialEq for IO { | ||||||
|  |         fn eq(&self, other: &Self) -> bool { | ||||||
|  |             let Self { | ||||||
|  |                 en, | ||||||
|  |                 which_in, | ||||||
|  |                 data_in, | ||||||
|  |                 which_out, | ||||||
|  |                 data_out, | ||||||
|  |                 b_out, | ||||||
|  |             } = *self; | ||||||
|  |             en == other.en | ||||||
|  |                 && which_in == other.which_in | ||||||
|  |                 && data_in == other.data_in | ||||||
|  |                 && which_out == other.which_out | ||||||
|  |                 && data_out == other.data_out | ||||||
|  |                 && b_out.to_sim_value(BOutTy::TYPE) == other.b_out.to_sim_value(BOutTy::TYPE) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     let io_cycles = [ |     let io_cycles = [ | ||||||
|         IO { |         IO { | ||||||
|  | @ -395,6 +429,7 @@ fn test_enums() { | ||||||
|             data_in: 0, |             data_in: 0, | ||||||
|             which_out: 0, |             which_out: 0, | ||||||
|             data_out: 0, |             data_out: 0, | ||||||
|  |             b_out: HdlNone(), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: true, |             en: true, | ||||||
|  | @ -402,6 +437,7 @@ fn test_enums() { | ||||||
|             data_in: 0, |             data_in: 0, | ||||||
|             which_out: 0, |             which_out: 0, | ||||||
|             data_out: 0, |             data_out: 0, | ||||||
|  |             b_out: HdlNone(), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: false, |             en: false, | ||||||
|  | @ -409,6 +445,7 @@ fn test_enums() { | ||||||
|             data_in: 0, |             data_in: 0, | ||||||
|             which_out: 1, |             which_out: 1, | ||||||
|             data_out: 0, |             data_out: 0, | ||||||
|  |             b_out: HdlSome((0_hdl_u1, false)), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: true, |             en: true, | ||||||
|  | @ -416,6 +453,7 @@ fn test_enums() { | ||||||
|             data_in: 0xF, |             data_in: 0xF, | ||||||
|             which_out: 1, |             which_out: 1, | ||||||
|             data_out: 0, |             data_out: 0, | ||||||
|  |             b_out: HdlSome((0_hdl_u1, false)), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: true, |             en: true, | ||||||
|  | @ -423,6 +461,7 @@ fn test_enums() { | ||||||
|             data_in: 0xF, |             data_in: 0xF, | ||||||
|             which_out: 1, |             which_out: 1, | ||||||
|             data_out: 0x3, |             data_out: 0x3, | ||||||
|  |             b_out: HdlSome((1_hdl_u1, true)), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: true, |             en: true, | ||||||
|  | @ -430,6 +469,7 @@ fn test_enums() { | ||||||
|             data_in: 0xF, |             data_in: 0xF, | ||||||
|             which_out: 1, |             which_out: 1, | ||||||
|             data_out: 0x3, |             data_out: 0x3, | ||||||
|  |             b_out: HdlSome((1_hdl_u1, true)), | ||||||
|         }, |         }, | ||||||
|         IO { |         IO { | ||||||
|             en: true, |             en: true, | ||||||
|  | @ -437,6 +477,7 @@ fn test_enums() { | ||||||
|             data_in: 0xF, |             data_in: 0xF, | ||||||
|             which_out: 2, |             which_out: 2, | ||||||
|             data_out: 0xF, |             data_out: 0xF, | ||||||
|  |             b_out: HdlNone(), | ||||||
|         }, |         }, | ||||||
|     ]; |     ]; | ||||||
|     for ( |     for ( | ||||||
|  | @ -447,6 +488,7 @@ fn test_enums() { | ||||||
|             data_in, |             data_in, | ||||||
|             which_out: _, |             which_out: _, | ||||||
|             data_out: _, |             data_out: _, | ||||||
|  |             b_out: _, | ||||||
|         }, |         }, | ||||||
|     ) in io_cycles.into_iter().enumerate() |     ) in io_cycles.into_iter().enumerate() | ||||||
|     { |     { | ||||||
|  | @ -467,11 +509,12 @@ fn test_enums() { | ||||||
|                 .to_bigint() |                 .to_bigint() | ||||||
|                 .try_into() |                 .try_into() | ||||||
|                 .expect("known to be in range"), |                 .expect("known to be in range"), | ||||||
|  |             b_out: sim.read(sim.io().b_out).to_expr(), | ||||||
|         }; |         }; | ||||||
|         assert_eq!( |         assert_eq!( | ||||||
|             expected, |             expected, | ||||||
|             io, |             io, | ||||||
|             "cycle: {cycle}\nvcd:\n{}", |             "vcd:\n{}\ncycle: {cycle}", | ||||||
|             String::from_utf8(writer.take()).unwrap(), |             String::from_utf8(writer.take()).unwrap(), | ||||||
|         ); |         ); | ||||||
|         sim.write_clock(sim.io().cd.clk, false); |         sim.write_clock(sim.io().cd.clk, false); | ||||||
|  | @ -492,4 +535,714 @@ fn test_enums() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO: add tests for memories
 | #[hdl_module(outline_generated)] | ||||||
|  | pub fn memories() { | ||||||
|  |     #[hdl] | ||||||
|  |     let r: fayalite::memory::ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let w: fayalite::memory::WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let mut mem = memory_with_init([(0x01u8, 0x23i8); 16]); | ||||||
|  |     mem.read_latency(0); | ||||||
|  |     mem.write_latency(NonZeroUsize::new(1).unwrap()); | ||||||
|  |     mem.read_under_write(ReadUnderWrite::Old); | ||||||
|  |     connect_any(mem.new_read_port(), r); | ||||||
|  |     connect_any(mem.new_write_port(), w); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl] | ||||||
|  | #[test] | ||||||
|  | fn test_memories() { | ||||||
|  |     let _n = SourceLocation::normalize_files_for_tests(); | ||||||
|  |     let mut sim = Simulation::new(memories()); | ||||||
|  |     let mut writer = RcWriter::default(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|  |     sim.write_clock(sim.io().r.clk, false); | ||||||
|  |     sim.write_clock(sim.io().w.clk, false); | ||||||
|  |     #[derive(Debug, PartialEq, Eq)] | ||||||
|  |     struct IO { | ||||||
|  |         r_addr: u8, | ||||||
|  |         r_en: bool, | ||||||
|  |         r_data: (u8, i8), | ||||||
|  |         w_addr: u8, | ||||||
|  |         w_en: bool, | ||||||
|  |         w_data: (u8, i8), | ||||||
|  |         w_mask: (bool, bool), | ||||||
|  |     } | ||||||
|  |     let io_cycles = [ | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: false, | ||||||
|  |             r_data: (0, 0), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: (0, 0), | ||||||
|  |             w_mask: (false, false), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x1, 0x23), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0x10, 0x20), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x10, 0x20), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0x30, 0x40), | ||||||
|  |             w_mask: (false, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x10, 0x40), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0x50, 0x60), | ||||||
|  |             w_mask: (true, false), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x50, 0x40), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0x70, -0x80), | ||||||
|  |             w_mask: (false, false), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x50, 0x40), | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: (0x90, 0xA0u8 as i8), | ||||||
|  |             w_mask: (false, false), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x50, 0x40), | ||||||
|  |             w_addr: 1, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0x90, 0xA0u8 as i8), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x50, 0x40), | ||||||
|  |             w_addr: 2, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: (0xB0, 0xC0u8 as i8), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x50, 0x40), | ||||||
|  |             w_addr: 2, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: (0xD0, 0xE0u8 as i8), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 1, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0x90, 0xA0u8 as i8), | ||||||
|  |             w_addr: 2, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: (0xD0, 0xE0u8 as i8), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 2, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: (0xB0, 0xC0u8 as i8), | ||||||
|  |             w_addr: 2, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: (0xD0, 0xE0u8 as i8), | ||||||
|  |             w_mask: (true, true), | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  |     for ( | ||||||
|  |         cycle, | ||||||
|  |         expected @ IO { | ||||||
|  |             r_addr, | ||||||
|  |             r_en, | ||||||
|  |             r_data: _, | ||||||
|  |             w_addr, | ||||||
|  |             w_en, | ||||||
|  |             w_data, | ||||||
|  |             w_mask, | ||||||
|  |         }, | ||||||
|  |     ) in io_cycles.into_iter().enumerate() | ||||||
|  |     { | ||||||
|  |         sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static()); | ||||||
|  |         sim.write_bool(sim.io().r.en, r_en); | ||||||
|  |         sim.write_bool_or_int(sim.io().w.addr, w_addr.cast_to_static()); | ||||||
|  |         sim.write_bool(sim.io().w.en, w_en); | ||||||
|  |         sim.write_bool_or_int(sim.io().w.data.0, w_data.0); | ||||||
|  |         sim.write_bool_or_int(sim.io().w.data.1, w_data.1); | ||||||
|  |         sim.write_bool(sim.io().w.mask.0, w_mask.0); | ||||||
|  |         sim.write_bool(sim.io().w.mask.1, w_mask.1); | ||||||
|  |         let io = IO { | ||||||
|  |             r_addr, | ||||||
|  |             r_en, | ||||||
|  |             r_data: ( | ||||||
|  |                 sim.read_bool_or_int(sim.io().r.data.0) | ||||||
|  |                     .to_bigint() | ||||||
|  |                     .try_into() | ||||||
|  |                     .expect("known to be in range"), | ||||||
|  |                 sim.read_bool_or_int(sim.io().r.data.1) | ||||||
|  |                     .to_bigint() | ||||||
|  |                     .try_into() | ||||||
|  |                     .expect("known to be in range"), | ||||||
|  |             ), | ||||||
|  |             w_addr, | ||||||
|  |             w_en, | ||||||
|  |             w_data, | ||||||
|  |             w_mask, | ||||||
|  |         }; | ||||||
|  |         assert_eq!( | ||||||
|  |             expected, | ||||||
|  |             io, | ||||||
|  |             "vcd:\n{}\ncycle: {cycle}", | ||||||
|  |             String::from_utf8(writer.take()).unwrap(), | ||||||
|  |         ); | ||||||
|  |         sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |         sim.write_clock(sim.io().r.clk, true); | ||||||
|  |         sim.write_clock(sim.io().w.clk, true); | ||||||
|  |         sim.advance_time(SimDuration::from_micros(1)); | ||||||
|  |         sim.write_clock(sim.io().r.clk, false); | ||||||
|  |         sim.write_clock(sim.io().w.clk, false); | ||||||
|  |     } | ||||||
|  |     sim.flush_traces().unwrap(); | ||||||
|  |     let vcd = String::from_utf8(writer.take()).unwrap(); | ||||||
|  |     println!("####### VCD:\n{vcd}\n#######"); | ||||||
|  |     if vcd != include_str!("sim/expected/memories.vcd") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  |     let sim_debug = format!("{sim:#?}"); | ||||||
|  |     println!("#######\n{sim_debug}\n#######"); | ||||||
|  |     if sim_debug != include_str!("sim/expected/memories.txt") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl_module(outline_generated)] | ||||||
|  | pub fn memories2() { | ||||||
|  |     #[hdl] | ||||||
|  |     let rw: fayalite::memory::ReadWriteStruct<UInt<2>, ConstUsize<3>> = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let mut mem = memory_with_init([HdlSome(true); 5]); | ||||||
|  |     mem.read_latency(1); | ||||||
|  |     mem.write_latency(NonZeroUsize::new(1).unwrap()); | ||||||
|  |     mem.read_under_write(ReadUnderWrite::New); | ||||||
|  |     let rw_port = mem.new_rw_port(); | ||||||
|  |     connect_any(rw_port.addr, rw.addr); | ||||||
|  |     connect(rw_port.en, rw.en); | ||||||
|  |     connect(rw_port.clk, rw.clk); | ||||||
|  |     connect_any(rw.rdata, rw_port.rdata.cast_to_bits()); | ||||||
|  |     connect(rw_port.wmode, rw.wmode); | ||||||
|  |     connect(rw_port.wdata, HdlNone()); | ||||||
|  |     #[hdl] | ||||||
|  |     if rw.wdata[0] { | ||||||
|  |         connect(rw_port.wdata, HdlSome(rw.wdata[1])); | ||||||
|  |     } | ||||||
|  |     connect(rw_port.wmask, rw.wmask); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl] | ||||||
|  | #[test] | ||||||
|  | fn test_memories2() { | ||||||
|  |     let _n = SourceLocation::normalize_files_for_tests(); | ||||||
|  |     let mut sim = Simulation::new(memories2()); | ||||||
|  |     let mut writer = RcWriter::default(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|  |     sim.write_clock(sim.io().rw.clk, false); | ||||||
|  |     #[derive(Debug, PartialEq, Eq)] | ||||||
|  |     struct IO { | ||||||
|  |         addr: u8, | ||||||
|  |         en: bool, | ||||||
|  |         rdata: u8, | ||||||
|  |         wmode: bool, | ||||||
|  |         wdata: u8, | ||||||
|  |         wmask: bool, | ||||||
|  |     } | ||||||
|  |     let io_cycles = [ | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: false, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0x3, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: false, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 3, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 1, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 1, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 2, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 2, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 3, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 3, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 4, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 2, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 5, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 1, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 6, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 1, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 7, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: true, | ||||||
|  |             wdata: 1, | ||||||
|  |             wmask: true, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 7, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 6, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 5, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 4, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 3, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 3, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 2, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 1, | ||||||
|  |             en: true, | ||||||
|  |             rdata: 1, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             addr: 0, | ||||||
|  |             en: false, | ||||||
|  |             rdata: 0, | ||||||
|  |             wmode: false, | ||||||
|  |             wdata: 0, | ||||||
|  |             wmask: false, | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  |     for ( | ||||||
|  |         cycle, | ||||||
|  |         expected @ IO { | ||||||
|  |             addr, | ||||||
|  |             en, | ||||||
|  |             rdata: _, | ||||||
|  |             wmode, | ||||||
|  |             wdata, | ||||||
|  |             wmask, | ||||||
|  |         }, | ||||||
|  |     ) in io_cycles.into_iter().enumerate() | ||||||
|  |     { | ||||||
|  |         sim.write_bool_or_int(sim.io().rw.addr, addr.cast_to_static()); | ||||||
|  |         sim.write_bool(sim.io().rw.en, en); | ||||||
|  |         sim.write_bool(sim.io().rw.wmode, wmode); | ||||||
|  |         sim.write_bool_or_int(sim.io().rw.wdata, wdata.cast_to_static()); | ||||||
|  |         sim.write_bool(sim.io().rw.wmask, wmask); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         sim.write_clock(sim.io().rw.clk, true); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         let io = IO { | ||||||
|  |             addr, | ||||||
|  |             en, | ||||||
|  |             rdata: sim | ||||||
|  |                 .read_bool_or_int(sim.io().rw.rdata) | ||||||
|  |                 .to_bigint() | ||||||
|  |                 .try_into() | ||||||
|  |                 .expect("known to be in range"), | ||||||
|  |             wmode, | ||||||
|  |             wdata, | ||||||
|  |             wmask, | ||||||
|  |         }; | ||||||
|  |         assert_eq!( | ||||||
|  |             expected, | ||||||
|  |             io, | ||||||
|  |             "vcd:\n{}\ncycle: {cycle}", | ||||||
|  |             String::from_utf8(writer.take()).unwrap(), | ||||||
|  |         ); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         sim.write_clock(sim.io().rw.clk, false); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |     } | ||||||
|  |     sim.flush_traces().unwrap(); | ||||||
|  |     let vcd = String::from_utf8(writer.take()).unwrap(); | ||||||
|  |     println!("####### VCD:\n{vcd}\n#######"); | ||||||
|  |     if vcd != include_str!("sim/expected/memories2.vcd") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  |     let sim_debug = format!("{sim:#?}"); | ||||||
|  |     println!("#######\n{sim_debug}\n#######"); | ||||||
|  |     if sim_debug != include_str!("sim/expected/memories2.txt") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl_module(outline_generated)] | ||||||
|  | pub fn memories3() { | ||||||
|  |     #[hdl] | ||||||
|  |     let r: fayalite::memory::ReadStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let w: fayalite::memory::WriteStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input(); | ||||||
|  |     #[hdl] | ||||||
|  |     let mut mem: MemBuilder<Array<UInt<8>, 8>> = memory(); | ||||||
|  |     mem.depth(8); | ||||||
|  |     mem.read_latency(2); | ||||||
|  |     mem.write_latency(NonZeroUsize::new(2).unwrap()); | ||||||
|  |     mem.read_under_write(ReadUnderWrite::Old); | ||||||
|  |     connect_any(mem.new_read_port(), r); | ||||||
|  |     connect_any(mem.new_write_port(), w); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[hdl] | ||||||
|  | #[test] | ||||||
|  | fn test_memories3() { | ||||||
|  |     let _n = SourceLocation::normalize_files_for_tests(); | ||||||
|  |     let mut sim = Simulation::new(memories3()); | ||||||
|  |     let mut writer = RcWriter::default(); | ||||||
|  |     sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); | ||||||
|  |     sim.write_clock(sim.io().r.clk, false); | ||||||
|  |     sim.write_clock(sim.io().w.clk, false); | ||||||
|  |     #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||||||
|  |     struct IO { | ||||||
|  |         r_addr: u8, | ||||||
|  |         r_en: bool, | ||||||
|  |         r_data: [u8; 8], | ||||||
|  |         w_addr: u8, | ||||||
|  |         w_en: bool, | ||||||
|  |         w_data: [u8; 8], | ||||||
|  |         w_mask: [bool; 8], | ||||||
|  |     } | ||||||
|  |     let io_cycles = [ | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: false, | ||||||
|  |             r_data: [0; 8], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0], | ||||||
|  |             w_mask: [false, true, false, true, true, false, false, true], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0; 8], | ||||||
|  |             w_addr: 1, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], | ||||||
|  |             w_addr: 1, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: false, | ||||||
|  |             r_data: [0; 8], | ||||||
|  |             w_addr: 1, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE], | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: false, | ||||||
|  |             r_data: [0; 8], | ||||||
|  |             w_addr: 2, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: *b"testing!", | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: false, | ||||||
|  |             r_data: [0; 8], | ||||||
|  |             w_addr: 3, | ||||||
|  |             w_en: true, | ||||||
|  |             w_data: *b"more tst", | ||||||
|  |             w_mask: [true; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 0, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 1, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE], | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 2, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: *b"testing!", | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |         IO { | ||||||
|  |             r_addr: 3, | ||||||
|  |             r_en: true, | ||||||
|  |             r_data: *b"more tst", | ||||||
|  |             w_addr: 0, | ||||||
|  |             w_en: false, | ||||||
|  |             w_data: [0; 8], | ||||||
|  |             w_mask: [false; 8], | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  |     for cycle in 0..io_cycles.len() + 2 { | ||||||
|  |         { | ||||||
|  |             let IO { | ||||||
|  |                 r_addr, | ||||||
|  |                 r_en, | ||||||
|  |                 r_data: _, | ||||||
|  |                 w_addr, | ||||||
|  |                 w_en, | ||||||
|  |                 w_data, | ||||||
|  |                 w_mask, | ||||||
|  |             } = io_cycles.get(cycle).copied().unwrap_or(IO { | ||||||
|  |                 r_addr: 0, | ||||||
|  |                 r_en: false, | ||||||
|  |                 r_data: [0; 8], | ||||||
|  |                 w_addr: 0, | ||||||
|  |                 w_en: false, | ||||||
|  |                 w_data: [0; 8], | ||||||
|  |                 w_mask: [false; 8], | ||||||
|  |             }); | ||||||
|  |             sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static()); | ||||||
|  |             sim.write_bool(sim.io().r.en, r_en); | ||||||
|  |             sim.write_bool_or_int(sim.io().w.addr, w_addr.cast_to_static()); | ||||||
|  |             sim.write_bool(sim.io().w.en, w_en); | ||||||
|  |             for (i, v) in w_data.into_iter().enumerate() { | ||||||
|  |                 sim.write_bool_or_int(sim.io().w.data[i], v); | ||||||
|  |             } | ||||||
|  |             for (i, v) in w_mask.into_iter().enumerate() { | ||||||
|  |                 sim.write_bool_or_int(sim.io().w.mask[i], v); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         sim.write_clock(sim.io().r.clk, true); | ||||||
|  |         sim.write_clock(sim.io().w.clk, true); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         if let Some( | ||||||
|  |             expected @ IO { | ||||||
|  |                 r_addr, | ||||||
|  |                 r_en, | ||||||
|  |                 r_data: _, | ||||||
|  |                 w_addr, | ||||||
|  |                 w_en, | ||||||
|  |                 w_data, | ||||||
|  |                 w_mask, | ||||||
|  |             }, | ||||||
|  |         ) = cycle.checked_sub(1).and_then(|i| io_cycles.get(i).copied()) | ||||||
|  |         { | ||||||
|  |             let io = IO { | ||||||
|  |                 r_addr, | ||||||
|  |                 r_en, | ||||||
|  |                 r_data: std::array::from_fn(|i| { | ||||||
|  |                     sim.read_bool_or_int(sim.io().r.data[i]) | ||||||
|  |                         .to_bigint() | ||||||
|  |                         .try_into() | ||||||
|  |                         .expect("known to be in range") | ||||||
|  |                 }), | ||||||
|  |                 w_addr, | ||||||
|  |                 w_en, | ||||||
|  |                 w_data, | ||||||
|  |                 w_mask, | ||||||
|  |             }; | ||||||
|  |             assert_eq!( | ||||||
|  |                 expected, | ||||||
|  |                 io, | ||||||
|  |                 "vcd:\n{}\ncycle: {cycle}", | ||||||
|  |                 String::from_utf8(writer.take()).unwrap(), | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |         sim.write_clock(sim.io().r.clk, false); | ||||||
|  |         sim.write_clock(sim.io().w.clk, false); | ||||||
|  |         sim.advance_time(SimDuration::from_nanos(250)); | ||||||
|  |     } | ||||||
|  |     sim.flush_traces().unwrap(); | ||||||
|  |     let vcd = String::from_utf8(writer.take()).unwrap(); | ||||||
|  |     println!("####### VCD:\n{vcd}\n#######"); | ||||||
|  |     if vcd != include_str!("sim/expected/memories3.vcd") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  |     let sim_debug = format!("{sim:#?}"); | ||||||
|  |     println!("#######\n{sim_debug}\n#######"); | ||||||
|  |     if sim_debug != include_str!("sim/expected/memories3.txt") { | ||||||
|  |         panic!(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -3,12 +3,12 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 2, |                         len: 2, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -23,7 +23,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -32,21 +32,22 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 0: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "", ty: UInt<8> }, |                     dest: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> }, | ||||||
|                     value: 5, |                     value: 0x5, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 Copy { |                 1: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const: connect_const).connect_const::o", ty: UInt<8> }, |                     dest: StatePartIndex<BigSlots>(0), // (0x5) SlotDebugData { name: "InstantiatedModule(connect_const: connect_const).connect_const::o", ty: UInt<8> }, | ||||||
|                     src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "", ty: UInt<8> }, |                     src: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 2: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 2, |         pc: 2, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|  | @ -79,12 +80,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: UInt<8>, |                 ty: UInt<8>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -112,7 +113,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "o", |                 name: "o", | ||||||
|                 child: TraceUInt { |                 child: TraceUInt { | ||||||
|                     id: TraceScalarId(0), |                     location: TraceScalarId(0), | ||||||
|                     name: "o", |                     name: "o", | ||||||
|                     ty: UInt<8>, |                     ty: UInt<8>, | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|  | @ -133,7 +134,9 @@ Simulation { | ||||||
|             last_state: 0x05, |             last_state: 0x05, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [], |     trace_writers: [], | ||||||
|     instant: 0 s, |     instant: 0 s, | ||||||
|     clocks_triggered: [], |     clocks_triggered: [], | ||||||
|  |     .. | ||||||
| } | } | ||||||
|  | @ -3,12 +3,12 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 5, |                         len: 5, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -35,7 +35,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -44,35 +44,36 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 0: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     value: 1, |                     value: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 1: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset }, |                     dest: StatePartIndex<BigSlots>(3), // (0x1) SlotDebugData { name: "", ty: AsyncReset }, | ||||||
|                     src: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 2: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset }, |                     dest: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset }, | ||||||
|                     src: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset }, |                     src: StatePartIndex<BigSlots>(3), // (0x1) SlotDebugData { name: "", ty: AsyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Copy { |                 3: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(4), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset }, |                     src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:5:1 |                 // at: module-XXXXXXXXXX.rs:5:1 | ||||||
|                 Copy { |                 4: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(1), // (0x1) SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(4), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 5: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 5, |         pc: 5, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|  | @ -108,12 +109,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Bool, |                 ty: Bool, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -142,12 +143,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: AsyncReset, |                 ty: AsyncReset, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -175,7 +176,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "reset_out", |                 name: "reset_out", | ||||||
|                 child: TraceAsyncReset { |                 child: TraceAsyncReset { | ||||||
|                     id: TraceScalarId(0), |                     location: TraceScalarId(0), | ||||||
|                     name: "reset_out", |                     name: "reset_out", | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|                 }, |                 }, | ||||||
|  | @ -185,7 +186,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "bit_out", |                 name: "bit_out", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(1), |                     location: TraceScalarId(1), | ||||||
|                     name: "bit_out", |                     name: "bit_out", | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|                 }, |                 }, | ||||||
|  | @ -212,6 +213,7 @@ Simulation { | ||||||
|             last_state: 0x1, |             last_state: 0x1, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [ |     trace_writers: [ | ||||||
|         Running( |         Running( | ||||||
|             VcdWriter { |             VcdWriter { | ||||||
|  | @ -223,4 +225,5 @@ Simulation { | ||||||
|     ], |     ], | ||||||
|     instant: 1 μs, |     instant: 1 μs, | ||||||
|     clocks_triggered: [], |     clocks_triggered: [], | ||||||
|  |     .. | ||||||
| } | } | ||||||
|  | @ -3,7 +3,7 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 4, |                         len: 4, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -25,7 +25,7 @@ Simulation { | ||||||
|                         ], |                         ], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 10, |                         len: 10, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -72,7 +72,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -81,99 +81,101 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 0: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<1> }, |                     dest: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, | ||||||
|                     value: 1, |                     value: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 1: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset }, |                     src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 2: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset }, |                     src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 3: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     value: 3, |                     value: 0x3, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 BranchIfZero { |                 4: BranchIfZero { | ||||||
|                     target: 6, |                     target: 6, | ||||||
|                     value: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 5: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Add { |                 6: Add { | ||||||
|                     dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<5> }, |                     dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, | ||||||
|                     lhs: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     rhs: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<1> }, |                     rhs: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, | ||||||
|                 }, |                 }, | ||||||
|                 CastToUInt { |                 7: CastToUInt { | ||||||
|                     dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<5> }, |                     src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, | ||||||
|                     dest_width: 4, |                     dest_width: 4, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 8: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:6:1 |                 // at: module-XXXXXXXXXX.rs:6:1 | ||||||
|                 Copy { |                 9: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 10: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, |                     src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, | ||||||
|                 }, |                 }, | ||||||
|                 AndSmall { |                 11: AndSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 12: BranchIfSmallNonZero { | ||||||
|                     target: 16, |                     target: 16, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallZero { |                 13: BranchIfSmallZero { | ||||||
|                     target: 17, |                     target: 17, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 14: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 15: Branch { | ||||||
|                     target: 17, |                     target: 17, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 16: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 NotSmall { |                 17: XorSmallImmediate { | ||||||
|                     dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                     rhs: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 18: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 18, |         pc: 18, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|         small_slots: StatePart { |         small_slots: StatePart { | ||||||
|             value: [ |             value: [ | ||||||
|                 18446744073709551614, |                 0, | ||||||
|                 0, |                 0, | ||||||
|                 1, |                 1, | ||||||
|                 0, |                 0, | ||||||
|  | @ -218,12 +220,12 @@ Simulation { | ||||||
|                     rst: AsyncReset, |                     rst: AsyncReset, | ||||||
|                 }, |                 }, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 2, |                         len: 2, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -248,12 +250,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: Clock, |                                 ty: Clock, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -275,12 +277,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: AsyncReset, |                                 ty: AsyncReset, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -313,12 +315,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Clock, |                 ty: Clock, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -347,12 +349,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: AsyncReset, |                 ty: AsyncReset, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -381,12 +383,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: UInt<4>, |                 ty: UInt<4>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -417,12 +419,12 @@ Simulation { | ||||||
|                     name: "cd", |                     name: "cd", | ||||||
|                     fields: [ |                     fields: [ | ||||||
|                         TraceClock { |                         TraceClock { | ||||||
|                             id: TraceScalarId(0), |                             location: TraceScalarId(0), | ||||||
|                             name: "clk", |                             name: "clk", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceAsyncReset { |                         TraceAsyncReset { | ||||||
|                             id: TraceScalarId(1), |                             location: TraceScalarId(1), | ||||||
|                             name: "rst", |                             name: "rst", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|  | @ -446,7 +448,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "count", |                 name: "count", | ||||||
|                 child: TraceUInt { |                 child: TraceUInt { | ||||||
|                     id: TraceScalarId(2), |                     location: TraceScalarId(2), | ||||||
|                     name: "count", |                     name: "count", | ||||||
|                     ty: UInt<4>, |                     ty: UInt<4>, | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|  | @ -457,7 +459,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "count_reg", |                 name: "count_reg", | ||||||
|                 child: TraceUInt { |                 child: TraceUInt { | ||||||
|                     id: TraceScalarId(3), |                     location: TraceScalarId(3), | ||||||
|                     name: "count_reg", |                     name: "count_reg", | ||||||
|                     ty: UInt<4>, |                     ty: UInt<4>, | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|  | @ -502,6 +504,7 @@ Simulation { | ||||||
|             last_state: 0x3, |             last_state: 0x3, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [ |     trace_writers: [ | ||||||
|         Running( |         Running( | ||||||
|             VcdWriter { |             VcdWriter { | ||||||
|  | @ -515,4 +518,5 @@ Simulation { | ||||||
|     clocks_triggered: [ |     clocks_triggered: [ | ||||||
|         StatePartIndex<SmallSlots>(1), |         StatePartIndex<SmallSlots>(1), | ||||||
|     ], |     ], | ||||||
|  |     .. | ||||||
| } | } | ||||||
|  | @ -3,7 +3,7 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 4, |                         len: 4, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -25,7 +25,7 @@ Simulation { | ||||||
|                         ], |                         ], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 9, |                         len: 9, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -68,7 +68,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -77,85 +77,87 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:6:1 |                 // at: module-XXXXXXXXXX.rs:6:1 | ||||||
|                 Copy { |                 0: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 1: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: UInt<1> }, |                     dest: StatePartIndex<BigSlots>(6), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, | ||||||
|                     value: 1, |                     value: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 Add { |                 2: Add { | ||||||
|                     dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<5> }, |                     dest: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, | ||||||
|                     lhs: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     rhs: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: UInt<1> }, |                     rhs: StatePartIndex<BigSlots>(6), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, | ||||||
|                 }, |                 }, | ||||||
|                 CastToUInt { |                 3: CastToUInt { | ||||||
|                     dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<5> }, |                     src: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, | ||||||
|                     dest_width: 4, |                     dest_width: 4, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 4: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 5: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset }, |                     src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 6: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     value: 3, |                     value: 0x3, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:3:1 |                 // at: module-XXXXXXXXXX.rs:3:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 7: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, |                     src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, | ||||||
|                 }, |                 }, | ||||||
|                 AndSmall { |                 8: AndSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallZero { |                 9: BranchIfSmallZero { | ||||||
|                     target: 14, |                     target: 14, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 10: BranchIfSmallNonZero { | ||||||
|                     target: 13, |                     target: 13, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 11: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 12: Branch { | ||||||
|                     target: 14, |                     target: 14, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 13: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 NotSmall { |                 14: XorSmallImmediate { | ||||||
|                     dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                     rhs: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 15: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 15, |         pc: 15, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|         small_slots: StatePart { |         small_slots: StatePart { | ||||||
|             value: [ |             value: [ | ||||||
|                 18446744073709551614, |                 0, | ||||||
|                 0, |                 0, | ||||||
|                 1, |                 1, | ||||||
|                 0, |                 0, | ||||||
|  | @ -199,12 +201,12 @@ Simulation { | ||||||
|                     rst: SyncReset, |                     rst: SyncReset, | ||||||
|                 }, |                 }, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 2, |                         len: 2, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -229,12 +231,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: Clock, |                                 ty: Clock, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -256,12 +258,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: SyncReset, |                                 ty: SyncReset, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -294,12 +296,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Clock, |                 ty: Clock, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -328,12 +330,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: SyncReset, |                 ty: SyncReset, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -362,12 +364,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: UInt<4>, |                 ty: UInt<4>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -398,12 +400,12 @@ Simulation { | ||||||
|                     name: "cd", |                     name: "cd", | ||||||
|                     fields: [ |                     fields: [ | ||||||
|                         TraceClock { |                         TraceClock { | ||||||
|                             id: TraceScalarId(0), |                             location: TraceScalarId(0), | ||||||
|                             name: "clk", |                             name: "clk", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSyncReset { |                         TraceSyncReset { | ||||||
|                             id: TraceScalarId(1), |                             location: TraceScalarId(1), | ||||||
|                             name: "rst", |                             name: "rst", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|  | @ -427,7 +429,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "count", |                 name: "count", | ||||||
|                 child: TraceUInt { |                 child: TraceUInt { | ||||||
|                     id: TraceScalarId(2), |                     location: TraceScalarId(2), | ||||||
|                     name: "count", |                     name: "count", | ||||||
|                     ty: UInt<4>, |                     ty: UInt<4>, | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|  | @ -438,7 +440,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "count_reg", |                 name: "count_reg", | ||||||
|                 child: TraceUInt { |                 child: TraceUInt { | ||||||
|                     id: TraceScalarId(3), |                     location: TraceScalarId(3), | ||||||
|                     name: "count_reg", |                     name: "count_reg", | ||||||
|                     ty: UInt<4>, |                     ty: UInt<4>, | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|  | @ -483,6 +485,7 @@ Simulation { | ||||||
|             last_state: 0x3, |             last_state: 0x3, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [ |     trace_writers: [ | ||||||
|         Running( |         Running( | ||||||
|             VcdWriter { |             VcdWriter { | ||||||
|  | @ -496,4 +499,5 @@ Simulation { | ||||||
|     clocks_triggered: [ |     clocks_triggered: [ | ||||||
|         StatePartIndex<SmallSlots>(1), |         StatePartIndex<SmallSlots>(1), | ||||||
|     ], |     ], | ||||||
|  |     .. | ||||||
| } | } | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -9,18 +9,25 @@ $var wire 2 $ which_in $end | ||||||
| $var wire 4 % data_in $end | $var wire 4 % data_in $end | ||||||
| $var wire 2 & which_out $end | $var wire 2 & which_out $end | ||||||
| $var wire 4 ' data_out $end | $var wire 4 ' data_out $end | ||||||
| $scope struct the_reg $end | $scope struct b_out $end | ||||||
| $var string 1 ( \$tag $end | $var string 1 ( \$tag $end | ||||||
|  | $scope struct HdlSome $end | ||||||
|  | $var wire 1 ) \0 $end | ||||||
|  | $var wire 1 * \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct the_reg $end | ||||||
|  | $var string 1 + \$tag $end | ||||||
| $scope struct B $end | $scope struct B $end | ||||||
| $var reg 1 ) \0 $end | $var reg 1 , \0 $end | ||||||
| $var reg 1 * \1 $end | $var reg 1 - \1 $end | ||||||
| $upscope $end | $upscope $end | ||||||
| $scope struct C $end | $scope struct C $end | ||||||
| $scope struct a $end | $scope struct a $end | ||||||
| $var reg 1 + \[0] $end | $var reg 1 . \[0] $end | ||||||
| $var reg 1 , \[1] $end | $var reg 1 / \[1] $end | ||||||
| $upscope $end | $upscope $end | ||||||
| $var reg 2 - b $end | $var reg 2 0 b $end | ||||||
| $upscope $end | $upscope $end | ||||||
| $upscope $end | $upscope $end | ||||||
| $upscope $end | $upscope $end | ||||||
|  | @ -33,12 +40,15 @@ b0 $ | ||||||
| b0 % | b0 % | ||||||
| b0 & | b0 & | ||||||
| b0 ' | b0 ' | ||||||
| sA\x20(0) ( | sHdlNone\x20(0) ( | ||||||
| 0) | 0) | ||||||
| 0* | 0* | ||||||
| 0+ | sA\x20(0) + | ||||||
| 0, | 0, | ||||||
| b0 - | 0- | ||||||
|  | 0. | ||||||
|  | 0/ | ||||||
|  | b0 0 | ||||||
| $end | $end | ||||||
| #1000000 | #1000000 | ||||||
| 1! | 1! | ||||||
|  | @ -55,7 +65,8 @@ b1 $ | ||||||
| #5000000 | #5000000 | ||||||
| 1! | 1! | ||||||
| b1 & | b1 & | ||||||
| sB\x20(1) ( | sHdlSome\x20(1) ( | ||||||
|  | sB\x20(1) + | ||||||
| #6000000 | #6000000 | ||||||
| 0# | 0# | ||||||
| b0 $ | b0 $ | ||||||
|  | @ -72,8 +83,10 @@ b1111 % | ||||||
| b11 ' | b11 ' | ||||||
| 1) | 1) | ||||||
| 1* | 1* | ||||||
| 1+ |  | ||||||
| 1, | 1, | ||||||
|  | 1- | ||||||
|  | 1. | ||||||
|  | 1/ | ||||||
| #10000000 | #10000000 | ||||||
| 0! | 0! | ||||||
| #11000000 | #11000000 | ||||||
|  | @ -85,8 +98,11 @@ b10 $ | ||||||
| 1! | 1! | ||||||
| b10 & | b10 & | ||||||
| b1111 ' | b1111 ' | ||||||
| sC\x20(2) ( | sHdlNone\x20(0) ( | ||||||
| b11 - | 0) | ||||||
|  | 0* | ||||||
|  | sC\x20(2) + | ||||||
|  | b11 0 | ||||||
| #14000000 | #14000000 | ||||||
| 0! | 0! | ||||||
| #15000000 | #15000000 | ||||||
|  |  | ||||||
							
								
								
									
										2776
									
								
								crates/fayalite/tests/sim/expected/memories.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2776
									
								
								crates/fayalite/tests/sim/expected/memories.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										408
									
								
								crates/fayalite/tests/sim/expected/memories.vcd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										408
									
								
								crates/fayalite/tests/sim/expected/memories.vcd
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,408 @@ | ||||||
|  | $timescale 1 ps $end | ||||||
|  | $scope module memories $end | ||||||
|  | $scope struct r $end | ||||||
|  | $var wire 4 ! addr $end | ||||||
|  | $var wire 1 " en $end | ||||||
|  | $var wire 1 # clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 $ \0 $end | ||||||
|  | $var wire 8 % \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct w $end | ||||||
|  | $var wire 4 & addr $end | ||||||
|  | $var wire 1 ' en $end | ||||||
|  | $var wire 1 ( clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 ) \0 $end | ||||||
|  | $var wire 8 * \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mask $end | ||||||
|  | $var wire 1 + \0 $end | ||||||
|  | $var wire 1 , \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $scope struct contents $end | ||||||
|  | $scope struct [0] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 9 \0 $end | ||||||
|  | $var reg 8 I \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [1] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 : \0 $end | ||||||
|  | $var reg 8 J \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [2] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 ; \0 $end | ||||||
|  | $var reg 8 K \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [3] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 < \0 $end | ||||||
|  | $var reg 8 L \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [4] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 = \0 $end | ||||||
|  | $var reg 8 M \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [5] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 > \0 $end | ||||||
|  | $var reg 8 N \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [6] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 ? \0 $end | ||||||
|  | $var reg 8 O \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [7] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 @ \0 $end | ||||||
|  | $var reg 8 P \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [8] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 A \0 $end | ||||||
|  | $var reg 8 Q \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [9] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 B \0 $end | ||||||
|  | $var reg 8 R \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [10] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 C \0 $end | ||||||
|  | $var reg 8 S \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [11] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 D \0 $end | ||||||
|  | $var reg 8 T \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [12] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 E \0 $end | ||||||
|  | $var reg 8 U \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [13] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 F \0 $end | ||||||
|  | $var reg 8 V \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [14] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 G \0 $end | ||||||
|  | $var reg 8 W \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [15] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 H \0 $end | ||||||
|  | $var reg 8 X \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct r0 $end | ||||||
|  | $var wire 4 - addr $end | ||||||
|  | $var wire 1 . en $end | ||||||
|  | $var wire 1 / clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 0 \0 $end | ||||||
|  | $var wire 8 1 \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct w1 $end | ||||||
|  | $var wire 4 2 addr $end | ||||||
|  | $var wire 1 3 en $end | ||||||
|  | $var wire 1 4 clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 5 \0 $end | ||||||
|  | $var wire 8 6 \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mask $end | ||||||
|  | $var wire 1 7 \0 $end | ||||||
|  | $var wire 1 8 \1 $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $enddefinitions $end | ||||||
|  | $dumpvars | ||||||
|  | b1 9 | ||||||
|  | b100011 I | ||||||
|  | b1 : | ||||||
|  | b100011 J | ||||||
|  | b1 ; | ||||||
|  | b100011 K | ||||||
|  | b1 < | ||||||
|  | b100011 L | ||||||
|  | b1 = | ||||||
|  | b100011 M | ||||||
|  | b1 > | ||||||
|  | b100011 N | ||||||
|  | b1 ? | ||||||
|  | b100011 O | ||||||
|  | b1 @ | ||||||
|  | b100011 P | ||||||
|  | b1 A | ||||||
|  | b100011 Q | ||||||
|  | b1 B | ||||||
|  | b100011 R | ||||||
|  | b1 C | ||||||
|  | b100011 S | ||||||
|  | b1 D | ||||||
|  | b100011 T | ||||||
|  | b1 E | ||||||
|  | b100011 U | ||||||
|  | b1 F | ||||||
|  | b100011 V | ||||||
|  | b1 G | ||||||
|  | b100011 W | ||||||
|  | b1 H | ||||||
|  | b100011 X | ||||||
|  | b0 ! | ||||||
|  | 0" | ||||||
|  | 0# | ||||||
|  | b0 $ | ||||||
|  | b0 % | ||||||
|  | b0 & | ||||||
|  | 0' | ||||||
|  | 0( | ||||||
|  | b0 ) | ||||||
|  | b0 * | ||||||
|  | 0+ | ||||||
|  | 0, | ||||||
|  | b0 - | ||||||
|  | 0. | ||||||
|  | 0/ | ||||||
|  | b0 0 | ||||||
|  | b0 1 | ||||||
|  | b0 2 | ||||||
|  | 03 | ||||||
|  | 04 | ||||||
|  | b0 5 | ||||||
|  | b0 6 | ||||||
|  | 07 | ||||||
|  | 08 | ||||||
|  | $end | ||||||
|  | #1000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #2000000 | ||||||
|  | 1" | ||||||
|  | 0# | ||||||
|  | b1 $ | ||||||
|  | b100011 % | ||||||
|  | 1' | ||||||
|  | 0( | ||||||
|  | b10000 ) | ||||||
|  | b100000 * | ||||||
|  | 1+ | ||||||
|  | 1, | ||||||
|  | 1. | ||||||
|  | 0/ | ||||||
|  | b1 0 | ||||||
|  | b100011 1 | ||||||
|  | 13 | ||||||
|  | 04 | ||||||
|  | b10000 5 | ||||||
|  | b100000 6 | ||||||
|  | 17 | ||||||
|  | 18 | ||||||
|  | #3000000 | ||||||
|  | b10000 9 | ||||||
|  | b100000 I | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | b10000 $ | ||||||
|  | b100000 % | ||||||
|  | b10000 0 | ||||||
|  | b100000 1 | ||||||
|  | #4000000 | ||||||
|  | 0# | ||||||
|  | 0( | ||||||
|  | b110000 ) | ||||||
|  | b1000000 * | ||||||
|  | 0+ | ||||||
|  | 0/ | ||||||
|  | 04 | ||||||
|  | b110000 5 | ||||||
|  | b1000000 6 | ||||||
|  | 07 | ||||||
|  | #5000000 | ||||||
|  | b10000 9 | ||||||
|  | b1000000 I | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | b1000000 % | ||||||
|  | b1000000 1 | ||||||
|  | #6000000 | ||||||
|  | 0# | ||||||
|  | 0( | ||||||
|  | b1010000 ) | ||||||
|  | b1100000 * | ||||||
|  | 1+ | ||||||
|  | 0, | ||||||
|  | 0/ | ||||||
|  | 04 | ||||||
|  | b1010000 5 | ||||||
|  | b1100000 6 | ||||||
|  | 17 | ||||||
|  | 08 | ||||||
|  | #7000000 | ||||||
|  | b1010000 9 | ||||||
|  | b1000000 I | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | b1010000 $ | ||||||
|  | b1010000 0 | ||||||
|  | #8000000 | ||||||
|  | 0# | ||||||
|  | 0( | ||||||
|  | b1110000 ) | ||||||
|  | b10000000 * | ||||||
|  | 0+ | ||||||
|  | 0/ | ||||||
|  | 04 | ||||||
|  | b1110000 5 | ||||||
|  | b10000000 6 | ||||||
|  | 07 | ||||||
|  | #9000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #10000000 | ||||||
|  | 0# | ||||||
|  | 0' | ||||||
|  | 0( | ||||||
|  | b10010000 ) | ||||||
|  | b10100000 * | ||||||
|  | 0/ | ||||||
|  | 03 | ||||||
|  | 04 | ||||||
|  | b10010000 5 | ||||||
|  | b10100000 6 | ||||||
|  | #11000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #12000000 | ||||||
|  | 0# | ||||||
|  | b1 & | ||||||
|  | 1' | ||||||
|  | 0( | ||||||
|  | 1+ | ||||||
|  | 1, | ||||||
|  | 0/ | ||||||
|  | b1 2 | ||||||
|  | 13 | ||||||
|  | 04 | ||||||
|  | 17 | ||||||
|  | 18 | ||||||
|  | #13000000 | ||||||
|  | b10010000 : | ||||||
|  | b10100000 J | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #14000000 | ||||||
|  | 0# | ||||||
|  | b10 & | ||||||
|  | 0( | ||||||
|  | b10110000 ) | ||||||
|  | b11000000 * | ||||||
|  | 0/ | ||||||
|  | b10 2 | ||||||
|  | 04 | ||||||
|  | b10110000 5 | ||||||
|  | b11000000 6 | ||||||
|  | #15000000 | ||||||
|  | b10110000 ; | ||||||
|  | b11000000 K | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #16000000 | ||||||
|  | 0# | ||||||
|  | 0' | ||||||
|  | 0( | ||||||
|  | b11010000 ) | ||||||
|  | b11100000 * | ||||||
|  | 0/ | ||||||
|  | 03 | ||||||
|  | 04 | ||||||
|  | b11010000 5 | ||||||
|  | b11100000 6 | ||||||
|  | #17000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #18000000 | ||||||
|  | b1 ! | ||||||
|  | 0# | ||||||
|  | b10010000 $ | ||||||
|  | b10100000 % | ||||||
|  | 0( | ||||||
|  | b1 - | ||||||
|  | 0/ | ||||||
|  | b10010000 0 | ||||||
|  | b10100000 1 | ||||||
|  | 04 | ||||||
|  | #19000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #20000000 | ||||||
|  | b10 ! | ||||||
|  | 0# | ||||||
|  | b10110000 $ | ||||||
|  | b11000000 % | ||||||
|  | 0( | ||||||
|  | b10 - | ||||||
|  | 0/ | ||||||
|  | b10110000 0 | ||||||
|  | b11000000 1 | ||||||
|  | 04 | ||||||
|  | #21000000 | ||||||
|  | 1# | ||||||
|  | 1( | ||||||
|  | 1/ | ||||||
|  | 14 | ||||||
|  | #22000000 | ||||||
|  | 0# | ||||||
|  | 0( | ||||||
|  | 0/ | ||||||
|  | 04 | ||||||
							
								
								
									
										1694
									
								
								crates/fayalite/tests/sim/expected/memories2.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1694
									
								
								crates/fayalite/tests/sim/expected/memories2.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										363
									
								
								crates/fayalite/tests/sim/expected/memories2.vcd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								crates/fayalite/tests/sim/expected/memories2.vcd
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,363 @@ | ||||||
|  | $timescale 1 ps $end | ||||||
|  | $scope module memories2 $end | ||||||
|  | $scope struct rw $end | ||||||
|  | $var wire 3 ! addr $end | ||||||
|  | $var wire 1 " en $end | ||||||
|  | $var wire 1 # clk $end | ||||||
|  | $var wire 2 $ rdata $end | ||||||
|  | $var wire 1 % wmode $end | ||||||
|  | $var wire 2 & wdata $end | ||||||
|  | $var wire 1 ' wmask $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $scope struct contents $end | ||||||
|  | $scope struct [0] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var string 1 1 \$tag $end | ||||||
|  | $var reg 1 6 HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [1] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var string 1 2 \$tag $end | ||||||
|  | $var reg 1 7 HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [2] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var string 1 3 \$tag $end | ||||||
|  | $var reg 1 8 HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [3] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var string 1 4 \$tag $end | ||||||
|  | $var reg 1 9 HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [4] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var string 1 5 \$tag $end | ||||||
|  | $var reg 1 : HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct rw0 $end | ||||||
|  | $var wire 3 ( addr $end | ||||||
|  | $var wire 1 ) en $end | ||||||
|  | $var wire 1 * clk $end | ||||||
|  | $scope struct rdata $end | ||||||
|  | $var string 1 + \$tag $end | ||||||
|  | $var wire 1 , HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $var wire 1 - wmode $end | ||||||
|  | $scope struct wdata $end | ||||||
|  | $var string 1 . \$tag $end | ||||||
|  | $var wire 1 / HdlSome $end | ||||||
|  | $upscope $end | ||||||
|  | $var wire 1 0 wmask $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $enddefinitions $end | ||||||
|  | $dumpvars | ||||||
|  | sHdlSome\x20(1) 1 | ||||||
|  | 16 | ||||||
|  | sHdlSome\x20(1) 2 | ||||||
|  | 17 | ||||||
|  | sHdlSome\x20(1) 3 | ||||||
|  | 18 | ||||||
|  | sHdlSome\x20(1) 4 | ||||||
|  | 19 | ||||||
|  | sHdlSome\x20(1) 5 | ||||||
|  | 1: | ||||||
|  | b0 ! | ||||||
|  | 0" | ||||||
|  | 0# | ||||||
|  | b0 $ | ||||||
|  | 0% | ||||||
|  | b0 & | ||||||
|  | 0' | ||||||
|  | b0 ( | ||||||
|  | 0) | ||||||
|  | 0* | ||||||
|  | sHdlNone\x20(0) + | ||||||
|  | 0, | ||||||
|  | 0- | ||||||
|  | sHdlNone\x20(0) . | ||||||
|  | 0/ | ||||||
|  | 00 | ||||||
|  | $end | ||||||
|  | #250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #500000 | ||||||
|  | #750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #1000000 | ||||||
|  | 1" | ||||||
|  | 1) | ||||||
|  | #1250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b11 $ | ||||||
|  | sHdlSome\x20(1) + | ||||||
|  | 1, | ||||||
|  | #1500000 | ||||||
|  | #1750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #2000000 | ||||||
|  | 0" | ||||||
|  | 0) | ||||||
|  | #2250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b0 $ | ||||||
|  | sHdlNone\x20(0) + | ||||||
|  | 0, | ||||||
|  | #2500000 | ||||||
|  | #2750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #3000000 | ||||||
|  | 1" | ||||||
|  | 1% | ||||||
|  | 1' | ||||||
|  | 1) | ||||||
|  | 1- | ||||||
|  | 10 | ||||||
|  | #3250000 | ||||||
|  | sHdlNone\x20(0) 1 | ||||||
|  | 06 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #3500000 | ||||||
|  | #3750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #4000000 | ||||||
|  | 0% | ||||||
|  | 0' | ||||||
|  | 0- | ||||||
|  | 00 | ||||||
|  | #4250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #4500000 | ||||||
|  | #4750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #5000000 | ||||||
|  | 1% | ||||||
|  | b11 & | ||||||
|  | 1- | ||||||
|  | sHdlSome\x20(1) . | ||||||
|  | 1/ | ||||||
|  | #5250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #5500000 | ||||||
|  | #5750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #6000000 | ||||||
|  | b1 ! | ||||||
|  | b1 & | ||||||
|  | 1' | ||||||
|  | b1 ( | ||||||
|  | 0/ | ||||||
|  | 10 | ||||||
|  | #6250000 | ||||||
|  | sHdlSome\x20(1) 2 | ||||||
|  | 07 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #6500000 | ||||||
|  | #6750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #7000000 | ||||||
|  | b10 ! | ||||||
|  | b10 & | ||||||
|  | b10 ( | ||||||
|  | sHdlNone\x20(0) . | ||||||
|  | #7250000 | ||||||
|  | sHdlNone\x20(0) 3 | ||||||
|  | 08 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #7500000 | ||||||
|  | #7750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #8000000 | ||||||
|  | b11 ! | ||||||
|  | b11 & | ||||||
|  | b11 ( | ||||||
|  | sHdlSome\x20(1) . | ||||||
|  | 1/ | ||||||
|  | #8250000 | ||||||
|  | sHdlSome\x20(1) 4 | ||||||
|  | 19 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #8500000 | ||||||
|  | #8750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #9000000 | ||||||
|  | b100 ! | ||||||
|  | b10 & | ||||||
|  | b100 ( | ||||||
|  | sHdlNone\x20(0) . | ||||||
|  | 0/ | ||||||
|  | #9250000 | ||||||
|  | sHdlNone\x20(0) 5 | ||||||
|  | 0: | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #9500000 | ||||||
|  | #9750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #10000000 | ||||||
|  | b101 ! | ||||||
|  | b1 & | ||||||
|  | b101 ( | ||||||
|  | sHdlSome\x20(1) . | ||||||
|  | #10250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #10500000 | ||||||
|  | #10750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #11000000 | ||||||
|  | b110 ! | ||||||
|  | b110 ( | ||||||
|  | #11250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #11500000 | ||||||
|  | #11750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #12000000 | ||||||
|  | b111 ! | ||||||
|  | b111 ( | ||||||
|  | #12250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #12500000 | ||||||
|  | #12750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #13000000 | ||||||
|  | 0% | ||||||
|  | b0 & | ||||||
|  | 0' | ||||||
|  | 0- | ||||||
|  | sHdlNone\x20(0) . | ||||||
|  | 00 | ||||||
|  | #13250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #13500000 | ||||||
|  | #13750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #14000000 | ||||||
|  | b110 ! | ||||||
|  | b110 ( | ||||||
|  | #14250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #14500000 | ||||||
|  | #14750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #15000000 | ||||||
|  | b101 ! | ||||||
|  | b101 ( | ||||||
|  | #15250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #15500000 | ||||||
|  | #15750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #16000000 | ||||||
|  | b100 ! | ||||||
|  | b100 ( | ||||||
|  | #16250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #16500000 | ||||||
|  | #16750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #17000000 | ||||||
|  | b11 ! | ||||||
|  | b11 ( | ||||||
|  | #17250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b11 $ | ||||||
|  | sHdlSome\x20(1) + | ||||||
|  | 1, | ||||||
|  | #17500000 | ||||||
|  | #17750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #18000000 | ||||||
|  | b10 ! | ||||||
|  | b10 ( | ||||||
|  | #18250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b0 $ | ||||||
|  | sHdlNone\x20(0) + | ||||||
|  | 0, | ||||||
|  | #18500000 | ||||||
|  | #18750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #19000000 | ||||||
|  | b0 ! | ||||||
|  | b0 ( | ||||||
|  | #19250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | #19500000 | ||||||
|  | #19750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #20000000 | ||||||
|  | b1 ! | ||||||
|  | b1 ( | ||||||
|  | #20250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b1 $ | ||||||
|  | sHdlSome\x20(1) + | ||||||
|  | #20500000 | ||||||
|  | #20750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #21000000 | ||||||
|  | b0 ! | ||||||
|  | 0" | ||||||
|  | b0 ( | ||||||
|  | 0) | ||||||
|  | #21250000 | ||||||
|  | 1# | ||||||
|  | 1* | ||||||
|  | b0 $ | ||||||
|  | sHdlNone\x20(0) + | ||||||
|  | #21500000 | ||||||
|  | #21750000 | ||||||
|  | 0# | ||||||
|  | 0* | ||||||
|  | #22000000 | ||||||
							
								
								
									
										4882
									
								
								crates/fayalite/tests/sim/expected/memories3.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4882
									
								
								crates/fayalite/tests/sim/expected/memories3.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										836
									
								
								crates/fayalite/tests/sim/expected/memories3.vcd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										836
									
								
								crates/fayalite/tests/sim/expected/memories3.vcd
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,836 @@ | ||||||
|  | $timescale 1 ps $end | ||||||
|  | $scope module memories3 $end | ||||||
|  | $scope struct r $end | ||||||
|  | $var wire 3 ! addr $end | ||||||
|  | $var wire 1 " en $end | ||||||
|  | $var wire 1 # clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 $ \[0] $end | ||||||
|  | $var wire 8 % \[1] $end | ||||||
|  | $var wire 8 & \[2] $end | ||||||
|  | $var wire 8 ' \[3] $end | ||||||
|  | $var wire 8 ( \[4] $end | ||||||
|  | $var wire 8 ) \[5] $end | ||||||
|  | $var wire 8 * \[6] $end | ||||||
|  | $var wire 8 + \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct w $end | ||||||
|  | $var wire 3 , addr $end | ||||||
|  | $var wire 1 - en $end | ||||||
|  | $var wire 1 . clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 / \[0] $end | ||||||
|  | $var wire 8 0 \[1] $end | ||||||
|  | $var wire 8 1 \[2] $end | ||||||
|  | $var wire 8 2 \[3] $end | ||||||
|  | $var wire 8 3 \[4] $end | ||||||
|  | $var wire 8 4 \[5] $end | ||||||
|  | $var wire 8 5 \[6] $end | ||||||
|  | $var wire 8 6 \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mask $end | ||||||
|  | $var wire 1 7 \[0] $end | ||||||
|  | $var wire 1 8 \[1] $end | ||||||
|  | $var wire 1 9 \[2] $end | ||||||
|  | $var wire 1 : \[3] $end | ||||||
|  | $var wire 1 ; \[4] $end | ||||||
|  | $var wire 1 < \[5] $end | ||||||
|  | $var wire 1 = \[6] $end | ||||||
|  | $var wire 1 > \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $scope struct contents $end | ||||||
|  | $scope struct [0] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 ] \[0] $end | ||||||
|  | $var reg 8 e \[1] $end | ||||||
|  | $var reg 8 m \[2] $end | ||||||
|  | $var reg 8 u \[3] $end | ||||||
|  | $var reg 8 } \[4] $end | ||||||
|  | $var reg 8 '" \[5] $end | ||||||
|  | $var reg 8 /" \[6] $end | ||||||
|  | $var reg 8 7" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [1] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 ^ \[0] $end | ||||||
|  | $var reg 8 f \[1] $end | ||||||
|  | $var reg 8 n \[2] $end | ||||||
|  | $var reg 8 v \[3] $end | ||||||
|  | $var reg 8 ~ \[4] $end | ||||||
|  | $var reg 8 (" \[5] $end | ||||||
|  | $var reg 8 0" \[6] $end | ||||||
|  | $var reg 8 8" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [2] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 _ \[0] $end | ||||||
|  | $var reg 8 g \[1] $end | ||||||
|  | $var reg 8 o \[2] $end | ||||||
|  | $var reg 8 w \[3] $end | ||||||
|  | $var reg 8 !" \[4] $end | ||||||
|  | $var reg 8 )" \[5] $end | ||||||
|  | $var reg 8 1" \[6] $end | ||||||
|  | $var reg 8 9" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [3] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 ` \[0] $end | ||||||
|  | $var reg 8 h \[1] $end | ||||||
|  | $var reg 8 p \[2] $end | ||||||
|  | $var reg 8 x \[3] $end | ||||||
|  | $var reg 8 "" \[4] $end | ||||||
|  | $var reg 8 *" \[5] $end | ||||||
|  | $var reg 8 2" \[6] $end | ||||||
|  | $var reg 8 :" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [4] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 a \[0] $end | ||||||
|  | $var reg 8 i \[1] $end | ||||||
|  | $var reg 8 q \[2] $end | ||||||
|  | $var reg 8 y \[3] $end | ||||||
|  | $var reg 8 #" \[4] $end | ||||||
|  | $var reg 8 +" \[5] $end | ||||||
|  | $var reg 8 3" \[6] $end | ||||||
|  | $var reg 8 ;" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [5] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 b \[0] $end | ||||||
|  | $var reg 8 j \[1] $end | ||||||
|  | $var reg 8 r \[2] $end | ||||||
|  | $var reg 8 z \[3] $end | ||||||
|  | $var reg 8 $" \[4] $end | ||||||
|  | $var reg 8 ," \[5] $end | ||||||
|  | $var reg 8 4" \[6] $end | ||||||
|  | $var reg 8 <" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [6] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 c \[0] $end | ||||||
|  | $var reg 8 k \[1] $end | ||||||
|  | $var reg 8 s \[2] $end | ||||||
|  | $var reg 8 { \[3] $end | ||||||
|  | $var reg 8 %" \[4] $end | ||||||
|  | $var reg 8 -" \[5] $end | ||||||
|  | $var reg 8 5" \[6] $end | ||||||
|  | $var reg 8 =" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct [7] $end | ||||||
|  | $scope struct mem $end | ||||||
|  | $var reg 8 d \[0] $end | ||||||
|  | $var reg 8 l \[1] $end | ||||||
|  | $var reg 8 t \[2] $end | ||||||
|  | $var reg 8 | \[3] $end | ||||||
|  | $var reg 8 &" \[4] $end | ||||||
|  | $var reg 8 ." \[5] $end | ||||||
|  | $var reg 8 6" \[6] $end | ||||||
|  | $var reg 8 >" \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct r0 $end | ||||||
|  | $var wire 3 ? addr $end | ||||||
|  | $var wire 1 @ en $end | ||||||
|  | $var wire 1 A clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 B \[0] $end | ||||||
|  | $var wire 8 C \[1] $end | ||||||
|  | $var wire 8 D \[2] $end | ||||||
|  | $var wire 8 E \[3] $end | ||||||
|  | $var wire 8 F \[4] $end | ||||||
|  | $var wire 8 G \[5] $end | ||||||
|  | $var wire 8 H \[6] $end | ||||||
|  | $var wire 8 I \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct w1 $end | ||||||
|  | $var wire 3 J addr $end | ||||||
|  | $var wire 1 K en $end | ||||||
|  | $var wire 1 L clk $end | ||||||
|  | $scope struct data $end | ||||||
|  | $var wire 8 M \[0] $end | ||||||
|  | $var wire 8 N \[1] $end | ||||||
|  | $var wire 8 O \[2] $end | ||||||
|  | $var wire 8 P \[3] $end | ||||||
|  | $var wire 8 Q \[4] $end | ||||||
|  | $var wire 8 R \[5] $end | ||||||
|  | $var wire 8 S \[6] $end | ||||||
|  | $var wire 8 T \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $scope struct mask $end | ||||||
|  | $var wire 1 U \[0] $end | ||||||
|  | $var wire 1 V \[1] $end | ||||||
|  | $var wire 1 W \[2] $end | ||||||
|  | $var wire 1 X \[3] $end | ||||||
|  | $var wire 1 Y \[4] $end | ||||||
|  | $var wire 1 Z \[5] $end | ||||||
|  | $var wire 1 [ \[6] $end | ||||||
|  | $var wire 1 \ \[7] $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $upscope $end | ||||||
|  | $enddefinitions $end | ||||||
|  | $dumpvars | ||||||
|  | b0 ] | ||||||
|  | b0 e | ||||||
|  | b0 m | ||||||
|  | b0 u | ||||||
|  | b0 } | ||||||
|  | b0 '" | ||||||
|  | b0 /" | ||||||
|  | b0 7" | ||||||
|  | b0 ^ | ||||||
|  | b0 f | ||||||
|  | b0 n | ||||||
|  | b0 v | ||||||
|  | b0 ~ | ||||||
|  | b0 (" | ||||||
|  | b0 0" | ||||||
|  | b0 8" | ||||||
|  | b0 _ | ||||||
|  | b0 g | ||||||
|  | b0 o | ||||||
|  | b0 w | ||||||
|  | b0 !" | ||||||
|  | b0 )" | ||||||
|  | b0 1" | ||||||
|  | b0 9" | ||||||
|  | b0 ` | ||||||
|  | b0 h | ||||||
|  | b0 p | ||||||
|  | b0 x | ||||||
|  | b0 "" | ||||||
|  | b0 *" | ||||||
|  | b0 2" | ||||||
|  | b0 :" | ||||||
|  | b0 a | ||||||
|  | b0 i | ||||||
|  | b0 q | ||||||
|  | b0 y | ||||||
|  | b0 #" | ||||||
|  | b0 +" | ||||||
|  | b0 3" | ||||||
|  | b0 ;" | ||||||
|  | b0 b | ||||||
|  | b0 j | ||||||
|  | b0 r | ||||||
|  | b0 z | ||||||
|  | b0 $" | ||||||
|  | b0 ," | ||||||
|  | b0 4" | ||||||
|  | b0 <" | ||||||
|  | b0 c | ||||||
|  | b0 k | ||||||
|  | b0 s | ||||||
|  | b0 { | ||||||
|  | b0 %" | ||||||
|  | b0 -" | ||||||
|  | b0 5" | ||||||
|  | b0 =" | ||||||
|  | b0 d | ||||||
|  | b0 l | ||||||
|  | b0 t | ||||||
|  | b0 | | ||||||
|  | b0 &" | ||||||
|  | b0 ." | ||||||
|  | b0 6" | ||||||
|  | b0 >" | ||||||
|  | b0 ! | ||||||
|  | 0" | ||||||
|  | 0# | ||||||
|  | b0 $ | ||||||
|  | b0 % | ||||||
|  | b0 & | ||||||
|  | b0 ' | ||||||
|  | b0 ( | ||||||
|  | b0 ) | ||||||
|  | b0 * | ||||||
|  | b0 + | ||||||
|  | b0 , | ||||||
|  | 1- | ||||||
|  | 0. | ||||||
|  | b10010 / | ||||||
|  | b110100 0 | ||||||
|  | b1010110 1 | ||||||
|  | b1111000 2 | ||||||
|  | b10011010 3 | ||||||
|  | b10111100 4 | ||||||
|  | b11011110 5 | ||||||
|  | b11110000 6 | ||||||
|  | 07 | ||||||
|  | 18 | ||||||
|  | 09 | ||||||
|  | 1: | ||||||
|  | 1; | ||||||
|  | 0< | ||||||
|  | 0= | ||||||
|  | 1> | ||||||
|  | b0 ? | ||||||
|  | 0@ | ||||||
|  | 0A | ||||||
|  | b0 B | ||||||
|  | b0 C | ||||||
|  | b0 D | ||||||
|  | b0 E | ||||||
|  | b0 F | ||||||
|  | b0 G | ||||||
|  | b0 H | ||||||
|  | b0 I | ||||||
|  | b0 J | ||||||
|  | 1K | ||||||
|  | 0L | ||||||
|  | b10010 M | ||||||
|  | b110100 N | ||||||
|  | b1010110 O | ||||||
|  | b1111000 P | ||||||
|  | b10011010 Q | ||||||
|  | b10111100 R | ||||||
|  | b11011110 S | ||||||
|  | b11110000 T | ||||||
|  | 0U | ||||||
|  | 1V | ||||||
|  | 0W | ||||||
|  | 1X | ||||||
|  | 1Y | ||||||
|  | 0Z | ||||||
|  | 0[ | ||||||
|  | 1\ | ||||||
|  | $end | ||||||
|  | #250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #500000 | ||||||
|  | #750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #1000000 | ||||||
|  | 1" | ||||||
|  | b1 , | ||||||
|  | 0- | ||||||
|  | b0 / | ||||||
|  | b0 0 | ||||||
|  | b0 1 | ||||||
|  | b0 2 | ||||||
|  | b0 3 | ||||||
|  | b0 4 | ||||||
|  | b0 5 | ||||||
|  | b0 6 | ||||||
|  | 08 | ||||||
|  | 0: | ||||||
|  | 0; | ||||||
|  | 0> | ||||||
|  | 1@ | ||||||
|  | b1 J | ||||||
|  | 0K | ||||||
|  | b0 M | ||||||
|  | b0 N | ||||||
|  | b0 O | ||||||
|  | b0 P | ||||||
|  | b0 Q | ||||||
|  | b0 R | ||||||
|  | b0 S | ||||||
|  | b0 T | ||||||
|  | 0V | ||||||
|  | 0X | ||||||
|  | 0Y | ||||||
|  | 0\ | ||||||
|  | #1250000 | ||||||
|  | b0 ] | ||||||
|  | b110100 e | ||||||
|  | b0 m | ||||||
|  | b1111000 u | ||||||
|  | b10011010 } | ||||||
|  | b0 '" | ||||||
|  | b0 /" | ||||||
|  | b11110000 7" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #1500000 | ||||||
|  | #1750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #2000000 | ||||||
|  | #2250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #2500000 | ||||||
|  | #2750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #3000000 | ||||||
|  | b0 , | ||||||
|  | 1- | ||||||
|  | b11111110 / | ||||||
|  | b11011100 0 | ||||||
|  | b10111010 1 | ||||||
|  | b10011000 2 | ||||||
|  | b1110110 3 | ||||||
|  | b1010100 4 | ||||||
|  | b110010 5 | ||||||
|  | b10000 6 | ||||||
|  | 17 | ||||||
|  | 18 | ||||||
|  | 19 | ||||||
|  | 1: | ||||||
|  | 1; | ||||||
|  | 1< | ||||||
|  | 1= | ||||||
|  | 1> | ||||||
|  | b0 J | ||||||
|  | 1K | ||||||
|  | b11111110 M | ||||||
|  | b11011100 N | ||||||
|  | b10111010 O | ||||||
|  | b10011000 P | ||||||
|  | b1110110 Q | ||||||
|  | b1010100 R | ||||||
|  | b110010 S | ||||||
|  | b10000 T | ||||||
|  | 1U | ||||||
|  | 1V | ||||||
|  | 1W | ||||||
|  | 1X | ||||||
|  | 1Y | ||||||
|  | 1Z | ||||||
|  | 1[ | ||||||
|  | 1\ | ||||||
|  | #3250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b110100 C | ||||||
|  | b1111000 E | ||||||
|  | b10011010 F | ||||||
|  | b11110000 I | ||||||
|  | 1L | ||||||
|  | b110100 % | ||||||
|  | b1111000 ' | ||||||
|  | b10011010 ( | ||||||
|  | b11110000 + | ||||||
|  | #3500000 | ||||||
|  | #3750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #4000000 | ||||||
|  | #4250000 | ||||||
|  | b11111110 ] | ||||||
|  | b11011100 e | ||||||
|  | b10111010 m | ||||||
|  | b10011000 u | ||||||
|  | b1110110 } | ||||||
|  | b1010100 '" | ||||||
|  | b110010 /" | ||||||
|  | b10000 7" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #4500000 | ||||||
|  | #4750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #5000000 | ||||||
|  | #5250000 | ||||||
|  | b11111110 ] | ||||||
|  | b11011100 e | ||||||
|  | b10111010 m | ||||||
|  | b10011000 u | ||||||
|  | b1110110 } | ||||||
|  | b1010100 '" | ||||||
|  | b110010 /" | ||||||
|  | b10000 7" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #5500000 | ||||||
|  | #5750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #6000000 | ||||||
|  | 0" | ||||||
|  | b1 , | ||||||
|  | b10011 / | ||||||
|  | b1010111 0 | ||||||
|  | b10011011 1 | ||||||
|  | b11011111 2 | ||||||
|  | b10 3 | ||||||
|  | b1000110 4 | ||||||
|  | b10001010 5 | ||||||
|  | b11001110 6 | ||||||
|  | 0@ | ||||||
|  | b1 J | ||||||
|  | b10011 M | ||||||
|  | b1010111 N | ||||||
|  | b10011011 O | ||||||
|  | b11011111 P | ||||||
|  | b10 Q | ||||||
|  | b1000110 R | ||||||
|  | b10001010 S | ||||||
|  | b11001110 T | ||||||
|  | #6250000 | ||||||
|  | b11111110 ] | ||||||
|  | b11011100 e | ||||||
|  | b10111010 m | ||||||
|  | b10011000 u | ||||||
|  | b1110110 } | ||||||
|  | b1010100 '" | ||||||
|  | b110010 /" | ||||||
|  | b10000 7" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b11111110 B | ||||||
|  | b11011100 C | ||||||
|  | b10111010 D | ||||||
|  | b10011000 E | ||||||
|  | b1110110 F | ||||||
|  | b1010100 G | ||||||
|  | b110010 H | ||||||
|  | b10000 I | ||||||
|  | 1L | ||||||
|  | b11111110 $ | ||||||
|  | b11011100 % | ||||||
|  | b10111010 & | ||||||
|  | b10011000 ' | ||||||
|  | b1110110 ( | ||||||
|  | b1010100 ) | ||||||
|  | b110010 * | ||||||
|  | b10000 + | ||||||
|  | #6500000 | ||||||
|  | #6750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #7000000 | ||||||
|  | b10 , | ||||||
|  | b1110100 / | ||||||
|  | b1100101 0 | ||||||
|  | b1110011 1 | ||||||
|  | b1110100 2 | ||||||
|  | b1101001 3 | ||||||
|  | b1101110 4 | ||||||
|  | b1100111 5 | ||||||
|  | b100001 6 | ||||||
|  | b10 J | ||||||
|  | b1110100 M | ||||||
|  | b1100101 N | ||||||
|  | b1110011 O | ||||||
|  | b1110100 P | ||||||
|  | b1101001 Q | ||||||
|  | b1101110 R | ||||||
|  | b1100111 S | ||||||
|  | b100001 T | ||||||
|  | #7250000 | ||||||
|  | b10011 ^ | ||||||
|  | b1010111 f | ||||||
|  | b10011011 n | ||||||
|  | b11011111 v | ||||||
|  | b10 ~ | ||||||
|  | b1000110 (" | ||||||
|  | b10001010 0" | ||||||
|  | b11001110 8" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b0 B | ||||||
|  | b0 C | ||||||
|  | b0 D | ||||||
|  | b0 E | ||||||
|  | b0 F | ||||||
|  | b0 G | ||||||
|  | b0 H | ||||||
|  | b0 I | ||||||
|  | 1L | ||||||
|  | b0 $ | ||||||
|  | b0 % | ||||||
|  | b0 & | ||||||
|  | b0 ' | ||||||
|  | b0 ( | ||||||
|  | b0 ) | ||||||
|  | b0 * | ||||||
|  | b0 + | ||||||
|  | #7500000 | ||||||
|  | #7750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #8000000 | ||||||
|  | b11 , | ||||||
|  | b1101101 / | ||||||
|  | b1101111 0 | ||||||
|  | b1110010 1 | ||||||
|  | b1100101 2 | ||||||
|  | b100000 3 | ||||||
|  | b1110100 4 | ||||||
|  | b1110011 5 | ||||||
|  | b1110100 6 | ||||||
|  | b11 J | ||||||
|  | b1101101 M | ||||||
|  | b1101111 N | ||||||
|  | b1110010 O | ||||||
|  | b1100101 P | ||||||
|  | b100000 Q | ||||||
|  | b1110100 R | ||||||
|  | b1110011 S | ||||||
|  | b1110100 T | ||||||
|  | #8250000 | ||||||
|  | b1110100 _ | ||||||
|  | b1100101 g | ||||||
|  | b1110011 o | ||||||
|  | b1110100 w | ||||||
|  | b1101001 !" | ||||||
|  | b1101110 )" | ||||||
|  | b1100111 1" | ||||||
|  | b100001 9" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #8500000 | ||||||
|  | #8750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #9000000 | ||||||
|  | 1" | ||||||
|  | b0 , | ||||||
|  | 0- | ||||||
|  | b0 / | ||||||
|  | b0 0 | ||||||
|  | b0 1 | ||||||
|  | b0 2 | ||||||
|  | b0 3 | ||||||
|  | b0 4 | ||||||
|  | b0 5 | ||||||
|  | b0 6 | ||||||
|  | 07 | ||||||
|  | 08 | ||||||
|  | 09 | ||||||
|  | 0: | ||||||
|  | 0; | ||||||
|  | 0< | ||||||
|  | 0= | ||||||
|  | 0> | ||||||
|  | 1@ | ||||||
|  | b0 J | ||||||
|  | 0K | ||||||
|  | b0 M | ||||||
|  | b0 N | ||||||
|  | b0 O | ||||||
|  | b0 P | ||||||
|  | b0 Q | ||||||
|  | b0 R | ||||||
|  | b0 S | ||||||
|  | b0 T | ||||||
|  | 0U | ||||||
|  | 0V | ||||||
|  | 0W | ||||||
|  | 0X | ||||||
|  | 0Y | ||||||
|  | 0Z | ||||||
|  | 0[ | ||||||
|  | 0\ | ||||||
|  | #9250000 | ||||||
|  | b1101101 ` | ||||||
|  | b1101111 h | ||||||
|  | b1110010 p | ||||||
|  | b1100101 x | ||||||
|  | b100000 "" | ||||||
|  | b1110100 *" | ||||||
|  | b1110011 2" | ||||||
|  | b1110100 :" | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | 1L | ||||||
|  | #9500000 | ||||||
|  | #9750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #10000000 | ||||||
|  | b1 ! | ||||||
|  | b1 ? | ||||||
|  | #10250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b11111110 B | ||||||
|  | b11011100 C | ||||||
|  | b10111010 D | ||||||
|  | b10011000 E | ||||||
|  | b1110110 F | ||||||
|  | b1010100 G | ||||||
|  | b110010 H | ||||||
|  | b10000 I | ||||||
|  | 1L | ||||||
|  | b11111110 $ | ||||||
|  | b11011100 % | ||||||
|  | b10111010 & | ||||||
|  | b10011000 ' | ||||||
|  | b1110110 ( | ||||||
|  | b1010100 ) | ||||||
|  | b110010 * | ||||||
|  | b10000 + | ||||||
|  | #10500000 | ||||||
|  | #10750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #11000000 | ||||||
|  | b10 ! | ||||||
|  | b10 ? | ||||||
|  | #11250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b10011 B | ||||||
|  | b1010111 C | ||||||
|  | b10011011 D | ||||||
|  | b11011111 E | ||||||
|  | b10 F | ||||||
|  | b1000110 G | ||||||
|  | b10001010 H | ||||||
|  | b11001110 I | ||||||
|  | 1L | ||||||
|  | b10011 $ | ||||||
|  | b1010111 % | ||||||
|  | b10011011 & | ||||||
|  | b11011111 ' | ||||||
|  | b10 ( | ||||||
|  | b1000110 ) | ||||||
|  | b10001010 * | ||||||
|  | b11001110 + | ||||||
|  | #11500000 | ||||||
|  | #11750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #12000000 | ||||||
|  | b11 ! | ||||||
|  | b11 ? | ||||||
|  | #12250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b1110100 B | ||||||
|  | b1100101 C | ||||||
|  | b1110011 D | ||||||
|  | b1110100 E | ||||||
|  | b1101001 F | ||||||
|  | b1101110 G | ||||||
|  | b1100111 H | ||||||
|  | b100001 I | ||||||
|  | 1L | ||||||
|  | b1110100 $ | ||||||
|  | b1100101 % | ||||||
|  | b1110011 & | ||||||
|  | b1110100 ' | ||||||
|  | b1101001 ( | ||||||
|  | b1101110 ) | ||||||
|  | b1100111 * | ||||||
|  | b100001 + | ||||||
|  | #12500000 | ||||||
|  | #12750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #13000000 | ||||||
|  | b0 ! | ||||||
|  | 0" | ||||||
|  | b0 ? | ||||||
|  | 0@ | ||||||
|  | #13250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b1101101 B | ||||||
|  | b1101111 C | ||||||
|  | b1110010 D | ||||||
|  | b1100101 E | ||||||
|  | b100000 F | ||||||
|  | b1110100 G | ||||||
|  | b1110011 H | ||||||
|  | b1110100 I | ||||||
|  | 1L | ||||||
|  | b1101101 $ | ||||||
|  | b1101111 % | ||||||
|  | b1110010 & | ||||||
|  | b1100101 ' | ||||||
|  | b100000 ( | ||||||
|  | b1110100 ) | ||||||
|  | b1110011 * | ||||||
|  | b1110100 + | ||||||
|  | #13500000 | ||||||
|  | #13750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #14000000 | ||||||
|  | #14250000 | ||||||
|  | 1# | ||||||
|  | 1. | ||||||
|  | 1A | ||||||
|  | b0 B | ||||||
|  | b0 C | ||||||
|  | b0 D | ||||||
|  | b0 E | ||||||
|  | b0 F | ||||||
|  | b0 G | ||||||
|  | b0 H | ||||||
|  | b0 I | ||||||
|  | 1L | ||||||
|  | b0 $ | ||||||
|  | b0 % | ||||||
|  | b0 & | ||||||
|  | b0 ' | ||||||
|  | b0 ( | ||||||
|  | b0 ) | ||||||
|  | b0 * | ||||||
|  | b0 + | ||||||
|  | #14500000 | ||||||
|  | #14750000 | ||||||
|  | 0# | ||||||
|  | 0. | ||||||
|  | 0A | ||||||
|  | 0L | ||||||
|  | #15000000 | ||||||
|  | @ -3,12 +3,12 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 17, |                         len: 17, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -83,7 +83,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -92,94 +92,95 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 0: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(6), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.i2", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(2), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.i2", ty: SInt<2> }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 1: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(4), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.i", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(0), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.i", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:2:1 |                 // at: module-XXXXXXXXXX.rs:2:1 | ||||||
|                 Copy { |                 2: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(10), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(10), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(6), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 3: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(4), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:1:1 |                 // at: module-XXXXXXXXXX-2.rs:1:1 | ||||||
|                 Const { |                 4: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(16), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(16), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     value: 15, |                     value: 0xf, | ||||||
|                 }, |                 }, | ||||||
|                 Const { |                 5: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(14), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(14), // (0x5) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     value: 5, |                     value: 0x5, | ||||||
|                 }, |                 }, | ||||||
|                 CmpLt { |                 6: CmpLt { | ||||||
|                     dest: StatePartIndex<BigSlots>(15), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(15), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     lhs: StatePartIndex<BigSlots>(14), // SlotDebugData { name: "", ty: UInt<4> }, |                     lhs: StatePartIndex<BigSlots>(14), // (0x5) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     rhs: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, |                     rhs: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 CastToUInt { |                 7: CastToUInt { | ||||||
|                     dest: StatePartIndex<BigSlots>(13), // SlotDebugData { name: "", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(13), // (0xe) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(10), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(10), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> }, | ||||||
|                     dest_width: 4, |                     dest_width: 4, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:7:1 |                 // at: module-XXXXXXXXXX-2.rs:7:1 | ||||||
|                 Copy { |                 8: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(11), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(13), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(13), // (0xe) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:8:1 |                 // at: module-XXXXXXXXXX-2.rs:8:1 | ||||||
|                 BranchIfZero { |                 9: BranchIfZero { | ||||||
|                     target: 11, |                     target: 11, | ||||||
|                     value: StatePartIndex<BigSlots>(15), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<BigSlots>(15), // (0x1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:9:1 |                 // at: module-XXXXXXXXXX-2.rs:9:1 | ||||||
|                 Copy { |                 10: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(11), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(16), // SlotDebugData { name: "", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(16), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:2:1 |                 // at: module-XXXXXXXXXX.rs:2:1 | ||||||
|                 Copy { |                 11: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o2", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(7), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o2", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(11), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 12: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.o2", ty: UInt<4> }, |                     dest: StatePartIndex<BigSlots>(3), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.o2", ty: UInt<4> }, | ||||||
|                     src: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o2", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(7), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o2", ty: UInt<4> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:1:1 |                 // at: module-XXXXXXXXXX-2.rs:1:1 | ||||||
|                 CastToSInt { |                 13: CastToSInt { | ||||||
|                     dest: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(12), // (-0x2) SlotDebugData { name: "", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, |                     src: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> }, | ||||||
|                     dest_width: 2, |                     dest_width: 2, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX-2.rs:6:1 |                 // at: module-XXXXXXXXXX-2.rs:6:1 | ||||||
|                 Copy { |                 14: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(9), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(12), // (-0x2) SlotDebugData { name: "", ty: SInt<2> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:2:1 |                 // at: module-XXXXXXXXXX.rs:2:1 | ||||||
|                 Copy { |                 15: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(5), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(9), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:4:1 |                 // at: module-XXXXXXXXXX.rs:4:1 | ||||||
|                 Copy { |                 16: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.o", ty: SInt<2> }, |                     dest: StatePartIndex<BigSlots>(1), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.o", ty: SInt<2> }, | ||||||
|                     src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o", ty: SInt<2> }, |                     src: StatePartIndex<BigSlots>(5), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.o", ty: SInt<2> }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 17: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 17, |         pc: 17, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|  | @ -236,12 +237,12 @@ Simulation { | ||||||
|                     o2: UInt<4>, |                     o2: UInt<4>, | ||||||
|                 }, |                 }, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 4, |                         len: 4, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -274,12 +275,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: UInt<4>, |                                 ty: UInt<4>, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -301,12 +302,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: SInt<2>, |                                 ty: SInt<2>, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -328,12 +329,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: SInt<2>, |                                 ty: SInt<2>, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -355,12 +356,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: UInt<4>, |                                 ty: UInt<4>, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -393,12 +394,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: UInt<4>, |                 ty: UInt<4>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -427,12 +428,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: SInt<2>, |                 ty: SInt<2>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -461,12 +462,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: SInt<2>, |                 ty: SInt<2>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -495,12 +496,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: UInt<4>, |                 ty: UInt<4>, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -531,25 +532,25 @@ Simulation { | ||||||
|                     name: "o", |                     name: "o", | ||||||
|                     fields: [ |                     fields: [ | ||||||
|                         TraceUInt { |                         TraceUInt { | ||||||
|                             id: TraceScalarId(0), |                             location: TraceScalarId(0), | ||||||
|                             name: "i", |                             name: "i", | ||||||
|                             ty: UInt<4>, |                             ty: UInt<4>, | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSInt { |                         TraceSInt { | ||||||
|                             id: TraceScalarId(1), |                             location: TraceScalarId(1), | ||||||
|                             name: "o", |                             name: "o", | ||||||
|                             ty: SInt<2>, |                             ty: SInt<2>, | ||||||
|                             flow: Sink, |                             flow: Sink, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSInt { |                         TraceSInt { | ||||||
|                             id: TraceScalarId(2), |                             location: TraceScalarId(2), | ||||||
|                             name: "i2", |                             name: "i2", | ||||||
|                             ty: SInt<2>, |                             ty: SInt<2>, | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceUInt { |                         TraceUInt { | ||||||
|                             id: TraceScalarId(3), |                             location: TraceScalarId(3), | ||||||
|                             name: "o2", |                             name: "o2", | ||||||
|                             ty: UInt<4>, |                             ty: UInt<4>, | ||||||
|                             flow: Sink, |                             flow: Sink, | ||||||
|  | @ -585,25 +586,25 @@ Simulation { | ||||||
|                     name: "child", |                     name: "child", | ||||||
|                     fields: [ |                     fields: [ | ||||||
|                         TraceUInt { |                         TraceUInt { | ||||||
|                             id: TraceScalarId(8), |                             location: TraceScalarId(8), | ||||||
|                             name: "i", |                             name: "i", | ||||||
|                             ty: UInt<4>, |                             ty: UInt<4>, | ||||||
|                             flow: Sink, |                             flow: Sink, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSInt { |                         TraceSInt { | ||||||
|                             id: TraceScalarId(9), |                             location: TraceScalarId(9), | ||||||
|                             name: "o", |                             name: "o", | ||||||
|                             ty: SInt<2>, |                             ty: SInt<2>, | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSInt { |                         TraceSInt { | ||||||
|                             id: TraceScalarId(10), |                             location: TraceScalarId(10), | ||||||
|                             name: "i2", |                             name: "i2", | ||||||
|                             ty: SInt<2>, |                             ty: SInt<2>, | ||||||
|                             flow: Sink, |                             flow: Sink, | ||||||
|                         }, |                         }, | ||||||
|                         TraceUInt { |                         TraceUInt { | ||||||
|                             id: TraceScalarId(11), |                             location: TraceScalarId(11), | ||||||
|                             name: "o2", |                             name: "o2", | ||||||
|                             ty: UInt<4>, |                             ty: UInt<4>, | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|  | @ -627,7 +628,7 @@ Simulation { | ||||||
|                         TraceModuleIO { |                         TraceModuleIO { | ||||||
|                             name: "i", |                             name: "i", | ||||||
|                             child: TraceUInt { |                             child: TraceUInt { | ||||||
|                                 id: TraceScalarId(4), |                                 location: TraceScalarId(4), | ||||||
|                                 name: "i", |                                 name: "i", | ||||||
|                                 ty: UInt<4>, |                                 ty: UInt<4>, | ||||||
|                                 flow: Source, |                                 flow: Source, | ||||||
|  | @ -638,7 +639,7 @@ Simulation { | ||||||
|                         TraceModuleIO { |                         TraceModuleIO { | ||||||
|                             name: "o", |                             name: "o", | ||||||
|                             child: TraceSInt { |                             child: TraceSInt { | ||||||
|                                 id: TraceScalarId(5), |                                 location: TraceScalarId(5), | ||||||
|                                 name: "o", |                                 name: "o", | ||||||
|                                 ty: SInt<2>, |                                 ty: SInt<2>, | ||||||
|                                 flow: Sink, |                                 flow: Sink, | ||||||
|  | @ -649,7 +650,7 @@ Simulation { | ||||||
|                         TraceModuleIO { |                         TraceModuleIO { | ||||||
|                             name: "i2", |                             name: "i2", | ||||||
|                             child: TraceSInt { |                             child: TraceSInt { | ||||||
|                                 id: TraceScalarId(6), |                                 location: TraceScalarId(6), | ||||||
|                                 name: "i2", |                                 name: "i2", | ||||||
|                                 ty: SInt<2>, |                                 ty: SInt<2>, | ||||||
|                                 flow: Source, |                                 flow: Source, | ||||||
|  | @ -660,7 +661,7 @@ Simulation { | ||||||
|                         TraceModuleIO { |                         TraceModuleIO { | ||||||
|                             name: "o2", |                             name: "o2", | ||||||
|                             child: TraceUInt { |                             child: TraceUInt { | ||||||
|                                 id: TraceScalarId(7), |                                 location: TraceScalarId(7), | ||||||
|                                 name: "o2", |                                 name: "o2", | ||||||
|                                 ty: UInt<4>, |                                 ty: UInt<4>, | ||||||
|                                 flow: Sink, |                                 flow: Sink, | ||||||
|  | @ -793,6 +794,7 @@ Simulation { | ||||||
|             last_state: 0xe, |             last_state: 0xe, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [ |     trace_writers: [ | ||||||
|         Running( |         Running( | ||||||
|             VcdWriter { |             VcdWriter { | ||||||
|  | @ -804,4 +806,5 @@ Simulation { | ||||||
|     ], |     ], | ||||||
|     instant: 2 μs, |     instant: 2 μs, | ||||||
|     clocks_triggered: [], |     clocks_triggered: [], | ||||||
|  |     .. | ||||||
| } | } | ||||||
|  | @ -3,7 +3,7 @@ Simulation { | ||||||
|         insns: Insns { |         insns: Insns { | ||||||
|             state_layout: StateLayout { |             state_layout: StateLayout { | ||||||
|                 ty: TypeLayout { |                 ty: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 4, |                         len: 4, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -25,7 +25,7 @@ Simulation { | ||||||
|                         ], |                         ], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 13, |                         len: 13, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -84,7 +84,7 @@ Simulation { | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 memories: StatePartAllocationLayout<Memories> { |                 memories: StatePartLayout<Memories> { | ||||||
|                     len: 0, |                     len: 0, | ||||||
|                     debug_data: [], |                     debug_data: [], | ||||||
|                     layout_data: [], |                     layout_data: [], | ||||||
|  | @ -93,146 +93,148 @@ Simulation { | ||||||
|             }, |             }, | ||||||
|             insns: [ |             insns: [ | ||||||
|                 // at: module-XXXXXXXXXX.rs:13:1 |                 // at: module-XXXXXXXXXX.rs:13:1 | ||||||
|                 Copy { |                 0: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::q", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::q", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, |                     src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:12:1 |                 // at: module-XXXXXXXXXX.rs:12:1 | ||||||
|                 Copy { |                 1: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3$next", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3$next", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, |                     src: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:10:1 |                 // at: module-XXXXXXXXXX.rs:10:1 | ||||||
|                 Copy { |                 2: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(10), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2$next", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2$next", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, |                     src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:8:1 |                 // at: module-XXXXXXXXXX.rs:8:1 | ||||||
|                 Copy { |                 3: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1$next", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1$next", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, |                     src: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:6:1 |                 // at: module-XXXXXXXXXX.rs:6:1 | ||||||
|                 Copy { |                 4: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0$next", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0$next", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::d", ty: Bool }, |                     src: StatePartIndex<BigSlots>(2), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::d", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:5:1 |                 // at: module-XXXXXXXXXX.rs:5:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 5: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset }, |                     src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Const { |                 6: Const { | ||||||
|                     dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     value: 0, |                     value: 0x0, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:5:1 |                 // at: module-XXXXXXXXXX.rs:5:1 | ||||||
|                 IsNonZeroDestIsSmall { |                 7: IsNonZeroDestIsSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock }, |                     src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock }, | ||||||
|                 }, |                 }, | ||||||
|                 AndSmall { |                 8: AndSmall { | ||||||
|                     dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallZero { |                 9: BranchIfSmallZero { | ||||||
|                     target: 14, |                     target: 14, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 10: BranchIfSmallNonZero { | ||||||
|                     target: 13, |                     target: 13, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 11: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0$next", ty: Bool }, |                     src: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0$next", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 12: Branch { | ||||||
|                     target: 14, |                     target: 14, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 13: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:7:1 |                 // at: module-XXXXXXXXXX.rs:7:1 | ||||||
|                 BranchIfSmallZero { |                 14: BranchIfSmallZero { | ||||||
|                     target: 19, |                     target: 19, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 15: BranchIfSmallNonZero { | ||||||
|                     target: 18, |                     target: 18, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 16: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1$next", ty: Bool }, |                     src: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1$next", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 17: Branch { | ||||||
|                     target: 19, |                     target: 19, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 18: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:9:1 |                 // at: module-XXXXXXXXXX.rs:9:1 | ||||||
|                 BranchIfSmallZero { |                 19: BranchIfSmallZero { | ||||||
|                     target: 24, |                     target: 24, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 20: BranchIfSmallNonZero { | ||||||
|                     target: 23, |                     target: 23, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 21: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(10), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2$next", ty: Bool }, |                     src: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2$next", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 22: Branch { | ||||||
|                     target: 24, |                     target: 24, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 23: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:11:1 |                 // at: module-XXXXXXXXXX.rs:11:1 | ||||||
|                 BranchIfSmallZero { |                 24: BranchIfSmallZero { | ||||||
|                     target: 29, |                     target: 29, | ||||||
|                     value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 BranchIfSmallNonZero { |                 25: BranchIfSmallNonZero { | ||||||
|                     target: 28, |                     target: 28, | ||||||
|                     value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool }, |                     value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 26: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3$next", ty: Bool }, |                     src: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3$next", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 Branch { |                 27: Branch { | ||||||
|                     target: 29, |                     target: 29, | ||||||
|                 }, |                 }, | ||||||
|                 Copy { |                 28: Copy { | ||||||
|                     dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, |                     dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool }, | ||||||
|                     src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool }, |                     src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:5:1 |                 // at: module-XXXXXXXXXX.rs:5:1 | ||||||
|                 NotSmall { |                 29: XorSmallImmediate { | ||||||
|                     dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool }, |                     dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, | ||||||
|                     src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool }, |                     lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, | ||||||
|  |                     rhs: 0x1, | ||||||
|                 }, |                 }, | ||||||
|                 // at: module-XXXXXXXXXX.rs:1:1 |                 // at: module-XXXXXXXXXX.rs:1:1 | ||||||
|                 Return, |                 30: Return, | ||||||
|             ], |             ], | ||||||
|             .. |             .. | ||||||
|         }, |         }, | ||||||
|         pc: 30, |         pc: 30, | ||||||
|  |         memory_write_log: [], | ||||||
|         memories: StatePart { |         memories: StatePart { | ||||||
|             value: [], |             value: [], | ||||||
|         }, |         }, | ||||||
|         small_slots: StatePart { |         small_slots: StatePart { | ||||||
|             value: [ |             value: [ | ||||||
|                 18446744073709551614, |                 0, | ||||||
|                 0, |                 0, | ||||||
|                 1, |                 1, | ||||||
|                 0, |                 0, | ||||||
|  | @ -280,12 +282,12 @@ Simulation { | ||||||
|                     rst: SyncReset, |                     rst: SyncReset, | ||||||
|                 }, |                 }, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 2, |                         len: 2, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -310,12 +312,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: Clock, |                                 ty: Clock, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -337,12 +339,12 @@ Simulation { | ||||||
|                             ty: CompiledTypeLayout { |                             ty: CompiledTypeLayout { | ||||||
|                                 ty: SyncReset, |                                 ty: SyncReset, | ||||||
|                                 layout: TypeLayout { |                                 layout: TypeLayout { | ||||||
|                                     small_slots: StatePartAllocationLayout<SmallSlots> { |                                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                                         len: 0, |                                         len: 0, | ||||||
|                                         debug_data: [], |                                         debug_data: [], | ||||||
|                                         .. |                                         .. | ||||||
|                                     }, |                                     }, | ||||||
|                                     big_slots: StatePartAllocationLayout<BigSlots> { |                                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                                         len: 1, |                                         len: 1, | ||||||
|                                         debug_data: [ |                                         debug_data: [ | ||||||
|                                             SlotDebugData { |                                             SlotDebugData { | ||||||
|  | @ -375,12 +377,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Clock, |                 ty: Clock, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -409,12 +411,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: SyncReset, |                 ty: SyncReset, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -443,12 +445,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Bool, |                 ty: Bool, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -477,12 +479,12 @@ Simulation { | ||||||
|             layout: CompiledTypeLayout { |             layout: CompiledTypeLayout { | ||||||
|                 ty: Bool, |                 ty: Bool, | ||||||
|                 layout: TypeLayout { |                 layout: TypeLayout { | ||||||
|                     small_slots: StatePartAllocationLayout<SmallSlots> { |                     small_slots: StatePartLayout<SmallSlots> { | ||||||
|                         len: 0, |                         len: 0, | ||||||
|                         debug_data: [], |                         debug_data: [], | ||||||
|                         .. |                         .. | ||||||
|                     }, |                     }, | ||||||
|                     big_slots: StatePartAllocationLayout<BigSlots> { |                     big_slots: StatePartLayout<BigSlots> { | ||||||
|                         len: 1, |                         len: 1, | ||||||
|                         debug_data: [ |                         debug_data: [ | ||||||
|                             SlotDebugData { |                             SlotDebugData { | ||||||
|  | @ -513,12 +515,12 @@ Simulation { | ||||||
|                     name: "cd", |                     name: "cd", | ||||||
|                     fields: [ |                     fields: [ | ||||||
|                         TraceClock { |                         TraceClock { | ||||||
|                             id: TraceScalarId(0), |                             location: TraceScalarId(0), | ||||||
|                             name: "clk", |                             name: "clk", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|                         TraceSyncReset { |                         TraceSyncReset { | ||||||
|                             id: TraceScalarId(1), |                             location: TraceScalarId(1), | ||||||
|                             name: "rst", |                             name: "rst", | ||||||
|                             flow: Source, |                             flow: Source, | ||||||
|                         }, |                         }, | ||||||
|  | @ -542,7 +544,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "d", |                 name: "d", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(2), |                     location: TraceScalarId(2), | ||||||
|                     name: "d", |                     name: "d", | ||||||
|                     flow: Source, |                     flow: Source, | ||||||
|                 }, |                 }, | ||||||
|  | @ -552,7 +554,7 @@ Simulation { | ||||||
|             TraceModuleIO { |             TraceModuleIO { | ||||||
|                 name: "q", |                 name: "q", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(3), |                     location: TraceScalarId(3), | ||||||
|                     name: "q", |                     name: "q", | ||||||
|                     flow: Sink, |                     flow: Sink, | ||||||
|                 }, |                 }, | ||||||
|  | @ -562,7 +564,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "reg0", |                 name: "reg0", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(4), |                     location: TraceScalarId(4), | ||||||
|                     name: "reg0", |                     name: "reg0", | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|                 }, |                 }, | ||||||
|  | @ -571,7 +573,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "reg1", |                 name: "reg1", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(5), |                     location: TraceScalarId(5), | ||||||
|                     name: "reg1", |                     name: "reg1", | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|                 }, |                 }, | ||||||
|  | @ -580,7 +582,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "reg2", |                 name: "reg2", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(6), |                     location: TraceScalarId(6), | ||||||
|                     name: "reg2", |                     name: "reg2", | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|                 }, |                 }, | ||||||
|  | @ -589,7 +591,7 @@ Simulation { | ||||||
|             TraceReg { |             TraceReg { | ||||||
|                 name: "reg3", |                 name: "reg3", | ||||||
|                 child: TraceBool { |                 child: TraceBool { | ||||||
|                     id: TraceScalarId(7), |                     location: TraceScalarId(7), | ||||||
|                     name: "reg3", |                     name: "reg3", | ||||||
|                     flow: Duplex, |                     flow: Duplex, | ||||||
|                 }, |                 }, | ||||||
|  | @ -663,6 +665,7 @@ Simulation { | ||||||
|             last_state: 0x0, |             last_state: 0x0, | ||||||
|         }, |         }, | ||||||
|     ], |     ], | ||||||
|  |     trace_memories: {}, | ||||||
|     trace_writers: [ |     trace_writers: [ | ||||||
|         Running( |         Running( | ||||||
|             VcdWriter { |             VcdWriter { | ||||||
|  | @ -676,4 +679,5 @@ Simulation { | ||||||
|     clocks_triggered: [ |     clocks_triggered: [ | ||||||
|         StatePartIndex<SmallSlots>(1), |         StatePartIndex<SmallSlots>(1), | ||||||
|     ], |     ], | ||||||
|  |     .. | ||||||
| } | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue