Compare commits

...

11 commits

21 changed files with 16779 additions and 803 deletions

View file

@ -4,12 +4,14 @@
use crate::{
expr::{ops::BundleLiteral, Expr, ToExpr},
intern::{Intern, Interned},
sim::{SimValue, ToSimValue},
source_location::SourceLocation,
ty::{
impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, StaticType, Type,
TypeProperties, TypeWithDeref,
},
};
use bitvec::vec::BitVec;
use hashbrown::HashMap;
use std::{fmt, marker::PhantomData};
@ -323,7 +325,7 @@ macro_rules! impl_tuple_builder_fields {
}
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! {
{}
[$({
@ -423,6 +425,79 @@ macro_rules! impl_tuples {
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)*]) => {
impl_tuples!([$($lhs)*] []);
@ -432,18 +507,18 @@ macro_rules! impl_tuples {
impl_tuples! {
[] [
{#[num = 0, field = field_0] v0: T0}
{#[num = 1, field = field_1] v1: T1}
{#[num = 2, field = field_2] v2: T2}
{#[num = 3, field = field_3] v3: T3}
{#[num = 4, field = field_4] v4: T4}
{#[num = 5, field = field_5] v5: T5}
{#[num = 6, field = field_6] v6: T6}
{#[num = 7, field = field_7] v7: T7}
{#[num = 8, field = field_8] v8: T8}
{#[num = 9, field = field_9] v9: T9}
{#[num = 10, field = field_10] v10: T10}
{#[num = 11, field = field_11] v11: T11}
{#[num = 0, field = field_0, ty = ty0: Ty0] v0: T0}
{#[num = 1, field = field_1, ty = ty1: Ty1] v1: T1}
{#[num = 2, field = field_2, ty = ty2: Ty2] v2: T2}
{#[num = 3, field = field_3, ty = ty3: Ty3] v3: T3}
{#[num = 4, field = field_4, ty = ty4: Ty4] v4: T4}
{#[num = 5, field = field_5, ty = ty5: Ty5] v5: T5}
{#[num = 6, field = field_6, ty = ty6: Ty6] v6: T6}
{#[num = 7, field = field_7, ty = ty7: Ty7] v7: T7}
{#[num = 8, field = field_8, ty = ty8: Ty8] v8: T8}
{#[num = 9, field = field_9, ty = ty9: Ty9] v9: T9}
{#[num = 10, field = field_10, ty = ty10: Ty10] v10: T10}
{#[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()
}
}
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()
}
}

View file

@ -519,7 +519,12 @@ impl<Element: Type, Len: Size> fmt::Debug for Mem<Element, Len> {
f.debug_struct("Mem")
.field("name", scoped_name)
.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("write_latency", write_latency)
.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

View file

@ -2,6 +2,7 @@
// See Notices.txt for copyright information
use crate::{
array::Array,
int::{BoolOrIntType, SInt, UInt},
intern::{Intern, Interned, Memoize},
source_location::SourceLocation,
@ -9,17 +10,17 @@ use crate::{
util::get_many_mut,
};
use bitvec::{boxed::BitBox, slice::BitSlice};
use hashbrown::HashMap;
use hashbrown::{HashMap, HashSet};
use num_bigint::BigInt;
use num_traits::{One, Signed, ToPrimitive, Zero};
use std::{
any::TypeId,
borrow::BorrowMut,
convert::Infallible,
fmt,
fmt::{self, Write},
hash::{Hash, Hasher},
marker::PhantomData,
ops::{Deref, DerefMut, Index, IndexMut},
ops::{ControlFlow, Deref, DerefMut, Index, IndexMut},
};
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 {
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<'_>,
labels: Option<&Labels>,
state_layout: Option<&StateLayout<BK>>,
state: Option<&State>,
) -> fmt::Result {
let (insn_name, fields) = self.fields_with_names();
write!(f, "{insn_name}")?;
if fields.len() == 0 {
return Ok(());
}
let mut f = PrefixLinesWrapper {
writer: f,
at_beginning_of_line: false,
blank_line_prefix: "",
line_prefix: " ",
};
writeln!(f, " {{")?;
for (field_name, field) in fields {
write!(f, " {field_name}: ")?;
write!(f, "{field_name}: ")?;
match field.kind {
InsnFieldKind::BranchTarget => match field.ty {
InsnFieldType::USize(&label_index) => {
@ -227,35 +265,100 @@ impl Insn {
| InsnFieldKind::Output
| InsnFieldKind::Immediate => {}
}
macro_rules! debug_fmt_state_part {
($v:expr) => {
$v.debug_fmt(&mut f, ",", " // ", " // ", "", state_layout, state)
};
}
match field.ty {
InsnFieldType::Memory(v) => {
v.debug_fmt(f, ",", " // ", "", state_layout)?;
debug_fmt_state_part!(v)?;
}
InsnFieldType::SmallSlot(v) => {
v.debug_fmt(f, ",", " // ", "", state_layout)?;
debug_fmt_state_part!(v)?;
}
InsnFieldType::BigSlot(v) => {
v.debug_fmt(f, ",", " // ", "", state_layout)?;
debug_fmt_state_part!(v)?;
}
InsnFieldType::SmallSlotArrayIndexed(v) => {
v.debug_fmt(f, ",", " // ", "", state_layout)?;
debug_fmt_state_part!(v)?;
}
InsnFieldType::BigSlotArrayIndexed(v) => {
v.debug_fmt(f, ",", " // ", "", state_layout)?;
debug_fmt_state_part!(v)?;
}
InsnFieldType::SmallUInt(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::SmallSInt(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::InternedBigInt(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::U8(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::USize(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::Empty(v) => fmt::Debug::fmt(v, f)?,
InsnFieldType::SmallUInt(v) => write!(f, "{v:#x}")?,
InsnFieldType::SmallSInt(v) => write!(f, "{v:#x}")?,
InsnFieldType::InternedBigInt(v) => write!(f, "{v:#x}")?,
InsnFieldType::U8(v) => write!(f, "{v:#x}")?,
InsnFieldType::USize(v) => write!(f, "{v}")?,
InsnFieldType::Empty(v) => write!(f, "{v:?}")?,
}
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 {
(
#[insn = $Insn:ident, next_macro = $next_macro:ident, branch_macro = $branch_macro:ident]
@ -402,11 +505,14 @@ macro_rules! impl_insns {
}
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;
$($setup)*
let mut insn = $state.insns[$state.pc];
let retval = 'main_loop: loop {
if let ControlFlow::Break(b) = breakpoints.check_for_breakpoint($state.pc) {
break RunResult::Break(b);
}
macro_rules! $next_macro {
() => {
$state.pc += 1;
@ -542,6 +648,7 @@ struct InsnsDebug<'a, BK: InsnsBuildingKind> {
insn_source_locations: &'a [SourceLocation],
labels: &'a BK::Labels,
state_layout: &'a StateLayout<BK>,
state: Option<&'a State>,
}
struct InsnDebug<'a, BK: InsnsBuildingKind> {
@ -550,6 +657,7 @@ struct InsnDebug<'a, BK: InsnsBuildingKind> {
insn: &'a Insn,
labels: Option<&'a Labels>,
state_layout: &'a StateLayout<BK>,
state: Option<&'a State>,
}
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 {
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,
labels,
state_layout: self.state_layout,
state: self.state,
});
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 {
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 {
insns,
insn_source_locations,
@ -614,12 +762,19 @@ impl<BK: InsnsBuildingKind> fmt::Debug for Insns<BK> {
insn_source_locations,
labels,
state_layout,
state,
},
)
.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:
Send + Sync + Ord + Hash + fmt::Debug + 'static + Copy + Default
{
@ -634,6 +789,11 @@ pub(crate) trait StatePartKind:
state_layout: &StateLayout<BK>,
part_index: StatePartIndex<Self>,
) -> Option<&Self::DebugData>;
fn debug_fmt_state_value(
state: &State,
index: StatePartIndex<Self>,
f: &mut impl fmt::Write,
) -> fmt::Result;
}
pub(crate) trait StatePartsValue {
@ -986,19 +1146,39 @@ macro_rules! make_state_part_kinds {
}
}
#[derive(Debug)]
pub(crate) struct State {
pub(crate) insns: Interned<Insns<InsnsBuildingDone>>,
pub(crate) pc: usize,
pub(crate) memory_write_log: Vec<(StatePartIndex<StatePartKindMemories>, usize)>,
$(pub(crate) $state_field: StatePart<$StateKind>,)*
$(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 {
pub(crate) fn new(insns: Interned<Insns<InsnsBuildingDone>>) -> Self {
Self {
insns,
pc: 0,
memory_write_log: Vec::with_capacity(32),
$($state_field: StatePart::new(&insns.state_layout.$state_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,
pc: self.pc,
orig_pc: &mut self.pc,
memory_write_log: &mut self.memory_write_log,
$($state_field: self.$state_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) orig_pc: &'a mut 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) $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! {
/*#[state, field = small_stack]
impl StatePartKind for StatePartKindSmallStack {
@ -1239,11 +1440,14 @@ make_state_part_kinds! {
impl StatePartKind for StatePartKindMemories {
const NAME: &'static str = "Memories";
type DebugData = ();
type LayoutData = Interned<BitSlice>;
type State = Box<[BitBox]>;
type BorrowedState<'a> = &'a mut [BitBox];
type LayoutData = MemoryData<Interned<BitSlice>>;
type State = Box<[MemoryData<BitBox>]>;
type BorrowedState<'a> = &'a mut [MemoryData<BitBox>];
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> {
state
@ -1254,6 +1458,13 @@ make_state_part_kinds! {
) -> Option<&Self::DebugData> {
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]
impl StatePartKind for StatePartKindSmallSlots {
@ -1274,6 +1485,15 @@ make_state_part_kinds! {
) -> Option<&Self::DebugData> {
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]
impl StatePartKind for StatePartKindBigSlots {
@ -1294,6 +1514,13 @@ make_state_part_kinds! {
) -> Option<&Self::DebugData> {
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,37 +1696,32 @@ pub(crate) struct StatePartArrayIndexed<K: StatePartKind> {
impl<K: StatePartKind> StatePartArrayIndexed<K> {
pub(crate) fn debug_fmt<BK: InsnsBuildingKind>(
&self,
f: &mut fmt::Formatter<'_>,
f: &mut impl fmt::Write,
before_debug_info_text: &str,
comment_start: &str,
comment_line_start: &str,
comment_end: &str,
state_layout: Option<&StateLayout<BK>>,
state: Option<&State>,
) -> fmt::Result {
if let Some(state_layout) = state_layout {
let Self { base, indexes } = *self;
if indexes.is_empty() {
base.debug_fmt(
f,
before_debug_info_text,
comment_start,
comment_end,
Some(state_layout),
)
} else {
base.debug_fmt(f, "", " /* ", " */ ", Some(state_layout))?;
for StatePartArrayIndex { index, len, stride } in indexes {
f.write_str("[")?;
index.debug_fmt(f, "", " /* ", " */ ", Some(state_layout))?;
write!(f, ", len={len}, stride={}]", stride.value)?;
}
f.write_str(before_debug_info_text)
}
let Self { base, indexes } = *self;
if indexes.is_empty() {
base.debug_fmt(
f,
before_debug_info_text,
comment_start,
comment_line_start,
comment_end,
state_layout,
state,
)
} else {
let Self { base, indexes } = self;
f.debug_struct("StatePartArrayIndexed")
.field("base", base)
.field("indexes", indexes)
.finish()?;
base.debug_fmt(f, "", " /* ", "", " */ ", state_layout, state)?;
for StatePartArrayIndex { index, len, stride } in indexes {
f.write_str("[")?;
index.debug_fmt(f, "", " /* ", "", " */ ", state_layout, state)?;
write!(f, ", len={len}, stride={}]", stride.value)?;
}
f.write_str(before_debug_info_text)
}
}
@ -1507,7 +1729,7 @@ impl<K: StatePartKind> StatePartArrayIndexed<K> {
impl<K: StatePartKind + fmt::Debug> fmt::Debug for StatePartArrayIndexed<K> {
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>(
&self,
f: &mut fmt::Formatter<'_>,
f: &mut impl fmt::Write,
before_debug_info_text: &str,
comment_start: &str,
comment_line_start: &str,
comment_end: &str,
state_layout: Option<&StateLayout<BK>>,
state: Option<&State>,
) -> fmt::Result {
write!(f, "StatePartIndex<{}>({})", K::NAME, self.value)?;
f.write_str(before_debug_info_text)?;
if let Some(state_layout) = state_layout {
if let Some(debug_data) = K::part_debug_data(state_layout, *self) {
write!(f, "{comment_start}{debug_data:?}{comment_end}")?;
}
let debug_data =
state_layout.and_then(|state_layout| K::part_debug_data(state_layout, *self));
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(())
}
@ -1593,7 +1837,7 @@ impl<K: StatePartKind> StatePartIndex<K> {
impl<K: StatePartKind> fmt::Debug for StatePartIndex<K> {
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,
_phantom: _,
} = self;
write!(f, "StatePartAllocationLayout<{}>", K::NAME)?;
write!(f, "StatePartLayout<{}>", K::NAME)?;
let mut debug_struct = f.debug_struct("");
debug_struct
.field("len", &debug_data.len())
@ -2146,6 +2390,7 @@ impl State {
let Self {
insns: _,
pc,
memory_write_log: _,
memories: _,
small_slots: _,
big_slots: _,
@ -2172,6 +2417,18 @@ impl BorrowedState<'_> {
}
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 {
@ -2503,6 +2760,18 @@ impl_insns! {
state.big_slots[dest] = value;
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 {
#[kind = Output]
dest: StatePartIndex<StatePartKindBigSlots>,
@ -2525,16 +2794,6 @@ impl_insns! {
state.big_slots[dest] = value;
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 {
#[kind = Output]
dest: StatePartIndex<StatePartKindBigSlots>,
@ -2861,7 +3120,7 @@ impl_insns! {
width: usize,
} => {
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!();
}
MemoryReadSInt {
@ -2879,7 +3138,7 @@ impl_insns! {
width: usize,
} => {
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!();
}
MemoryWriteUInt {
@ -2897,7 +3156,8 @@ impl_insns! {
width: usize,
} => {
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!();
}
MemoryWriteSInt {
@ -2915,10 +3175,11 @@ impl_insns! {
width: usize,
} => {
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!();
}
Return => {
break;
break RunResult::Return(());
}
}

View file

@ -9,13 +9,14 @@ use crate::{
time::{SimDuration, SimInstant},
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance,
TraceMemPort, TraceModule, TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId,
TraceScope, TraceSyncReset, TraceUInt, TraceWire, TraceWriter, TraceWriterDecls,
TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule,
TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSyncReset,
TraceUInt, TraceWire, TraceWriter, TraceWriterDecls,
},
};
use bitvec::slice::BitSlice;
use bitvec::{order::Lsb0, slice::BitSlice};
use std::{
fmt::{self, Display},
fmt,
io::{self, Write},
mem,
};
@ -112,20 +113,20 @@ macro_rules! trait_arg {
(
trait $Arg:ident {
$(
fn $fn:ident(self) -> $ty:ty;
fn $fn:ident(&mut self) -> $ty:ty;
)*
}
) => {
trait $Arg: Sized {
$(fn $fn(self) -> $ty {
$(fn $fn(&mut self) -> $ty {
unreachable!()
})*
}
$(
impl $Arg for $ty {
fn $fn(self) -> $ty {
self
fn $fn(&mut self) -> $ty {
self.reborrow()
}
}
)*
@ -134,21 +135,52 @@ macro_rules! trait_arg {
trait_arg! {
trait Arg {
fn module(self) -> ArgModule;
fn module_body(self) -> ArgModuleBody;
fn in_type(self) -> ArgInType;
fn module(&mut self) -> ArgModule<'_>;
fn module_body(&mut self) -> ArgModuleBody<'_>;
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 ArgInType {
struct ArgModuleBody<'a> {
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,
sink_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 {
@ -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 max_char = b'~';
let base = (max_char - min_char + 1) as usize;
let mut id = id.as_usize();
loop {
let digit = (id % base) as u8 + min_char;
id /= base;
@ -195,7 +226,7 @@ fn write_scalar_id<W: io::Write>(writer: &mut W, id: TraceScalarId) -> io::Resul
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:
// https://github.com/gtkwave/gtkwave/blob/491f24d7e8619cfc1fcc65704ee5c967d1083c18/lib/libfst/fstapi.c#L7090
struct Wrapper<W>(W);
@ -247,14 +278,47 @@ fn is_unescaped_verilog_identifier(ident: &str) -> bool {
}
fn write_vcd_var<W: io::Write>(
properties: &mut VcdWriterProperties,
memory_element_part_body: MemoryElementPartBody,
writer: &mut W,
var_type: &str,
size: usize,
id: TraceScalarId,
location: TraceLocation,
name: &str,
) -> 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_scalar_id(writer, id)?;
write_vcd_id(writer, id)?;
writer.write_all(b" ")?;
if !is_unescaped_verilog_identifier(name) {
writer.write_all(b"\\")?;
@ -264,31 +328,49 @@ fn write_vcd_var<W: io::Write>(
}
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 {
source_var_type,
sink_var_type,
duplex_var_type,
properties,
} = arg.in_type();
let Self { id, name, ty, flow } = self;
let var_type = match flow {
let Self {
location,
name,
ty,
flow,
} = self;
let mut var_type = match flow {
Flow::Source => source_var_type,
Flow::Sink => sink_var_type,
Flow::Duplex => duplex_var_type,
};
if ty.width() == 0 {
write_vcd_var(writer, "string", ty.width(), id, &name)
} else {
write_vcd_var(writer, var_type, ty.width(), id, &name)
var_type = "string";
}
write_vcd_var(
properties,
MemoryElementPartBody::Scalar,
writer,
var_type,
ty.width(),
location,
&name,
)
}
}
impl WriteTrace for TraceSInt {
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 {
id,
location,
name,
ty: UInt::new_dyn(ty.width()),
flow,
@ -299,9 +381,13 @@ impl WriteTrace for TraceSInt {
impl WriteTrace for TraceBool {
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 {
id,
location,
name,
flow,
ty: UInt::new_dyn(1),
@ -312,46 +398,93 @@ impl WriteTrace for TraceBool {
impl WriteTrace for TraceFieldlessEnum {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let Self { id, name, ty, flow } = self;
TraceEnumDiscriminant { id, name, ty, flow }.write_trace(writer, arg)
let Self {
location,
name,
ty,
flow,
} = self;
TraceEnumDiscriminant {
location,
name,
ty,
flow,
}
.write_trace(writer, arg)
}
}
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 {
source_var_type: _,
sink_var_type: _,
duplex_var_type: _,
properties,
} = arg.in_type();
let Self {
id,
location,
name,
ty: _,
ty,
flow: _,
} = 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 {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let Self { id, name, flow } = self;
TraceBool { id, name, flow }.write_trace(writer, arg)
let Self {
location,
name,
flow,
} = self;
TraceBool {
location,
name,
flow,
}
.write_trace(writer, arg)
}
}
impl WriteTrace for TraceSyncReset {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let Self { id, name, flow } = self;
TraceBool { id, name, flow }.write_trace(writer, arg)
let Self {
location,
name,
flow,
} = self;
TraceBool {
location,
name,
flow,
}
.write_trace(writer, arg)
}
}
impl WriteTrace for TraceAsyncReset {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let Self { id, name, flow } = self;
TraceBool { id, name, flow }.write_trace(writer, arg)
let Self {
location,
name,
flow,
} = self;
TraceBool {
location,
name,
flow,
}
.write_trace(writer, arg)
}
}
@ -360,6 +493,7 @@ impl WriteTrace for TraceScope {
match self {
Self::Module(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::Wire(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 {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let ArgModule {} = arg.module();
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
let ArgModule { properties } = arg.module();
let Self { name, children } = self;
write_vcd_scope(writer, "module", &name, |writer| {
for child in children {
child.write_trace(writer, ArgModuleBody {})?;
child.write_trace(writer, ArgModuleBody { properties })?;
}
Ok(())
})
@ -385,8 +519,8 @@ impl WriteTrace for TraceModule {
}
impl WriteTrace for TraceInstance {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let ArgModuleBody {} = arg.module_body();
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 {
name: _,
instance_io,
@ -399,21 +533,74 @@ impl WriteTrace for TraceInstance {
source_var_type: "wire",
sink_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 {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
todo!()
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 {
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 {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let ArgModuleBody {} = arg.module_body();
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 {
name: _,
child,
@ -425,14 +612,15 @@ impl WriteTrace for TraceWire {
source_var_type: "wire",
sink_var_type: "wire",
duplex_var_type: "wire",
properties,
},
)
}
}
impl WriteTrace for TraceReg {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let ArgModuleBody {} = arg.module_body();
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 {
name: _,
child,
@ -444,14 +632,15 @@ impl WriteTrace for TraceReg {
source_var_type: "reg",
sink_var_type: "reg",
duplex_var_type: "reg",
properties,
},
)
}
}
impl WriteTrace for TraceModuleIO {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let ArgModuleBody {} = arg.module_body();
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 {
name: _,
child,
@ -464,14 +653,15 @@ impl WriteTrace for TraceModuleIO {
source_var_type: "wire",
sink_var_type: "wire",
duplex_var_type: "wire",
properties,
},
)
}
}
impl WriteTrace for TraceBundle {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let arg = arg.in_type();
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
let mut arg = arg.in_type();
let Self {
name,
fields,
@ -480,7 +670,7 @@ impl WriteTrace for TraceBundle {
} = self;
write_vcd_scope(writer, "struct", &name, |writer| {
for field in fields {
field.write_trace(writer, arg)?;
field.write_trace(writer, arg.reborrow())?;
}
Ok(())
})
@ -488,8 +678,8 @@ impl WriteTrace for TraceBundle {
}
impl WriteTrace for TraceArray {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let arg = arg.in_type();
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
let mut arg = arg.in_type();
let Self {
name,
elements,
@ -498,7 +688,7 @@ impl WriteTrace for TraceArray {
} = self;
write_vcd_scope(writer, "struct", &name, |writer| {
for element in elements {
element.write_trace(writer, arg)?;
element.write_trace(writer, arg.reborrow())?;
}
Ok(())
})
@ -506,8 +696,8 @@ impl WriteTrace for TraceArray {
}
impl WriteTrace for TraceEnumWithFields {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, arg: A) -> io::Result<()> {
let arg = arg.in_type();
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
let mut arg = arg.in_type();
let Self {
name,
discriminant,
@ -516,9 +706,9 @@ impl WriteTrace for TraceEnumWithFields {
flow: _,
} = self;
write_vcd_scope(writer, "struct", &name, |writer| {
discriminant.write_trace(writer, arg)?;
discriminant.write_trace(writer, arg.reborrow())?;
for field in non_empty_fields {
field.write_trace(writer, arg)?;
field.write_trace(writer, arg.reborrow())?;
}
Ok(())
})
@ -529,76 +719,184 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
type Error = io::Error;
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 {
mut writer,
timescale,
} = self;
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, "$dumpvars")?;
Ok(VcdWriter {
writer,
finished_init: false,
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> {
writer: W,
finished_init: bool,
timescale: SimDuration,
properties: VcdWriterProperties,
}
impl<W: io::Write + 'static> VcdWriter<W> {
pub fn timescale(&self) -> SimDuration {
self.timescale
}
fn write_string_value_change(
&mut self,
value: impl Display,
id: TraceScalarId,
) -> io::Result<()> {
self.writer.write_all(b"s")?;
write_escaped(&mut self.writer, value)?;
self.writer.write_all(b" ")?;
write_scalar_id(&mut self.writer, id)?;
self.writer.write_all(b"\n")
}
fn write_string_value_change(
writer: &mut impl io::Write,
value: impl fmt::Display,
id: usize,
) -> io::Result<()> {
writer.write_all(b"s")?;
write_escaped(writer, value)?;
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> {
type Error = io::Error;
fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
match value.len() {
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")?;
}
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,
)?
}
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")
Ok(())
}
fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
write_bits_value_change(&mut self.writer, value, id.as_usize())
}
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> {
@ -630,16 +928,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
variant_index: usize,
ty: Enum,
) -> Result<(), Self::Error> {
self.write_string_value_change(
format_args!(
"{} ({variant_index})",
ty.variants()
.get(variant_index)
.map(|v| &*v.name)
.unwrap_or("<invalid>"),
),
id,
)
write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize())
}
}
@ -649,6 +938,7 @@ impl<W: io::Write> fmt::Debug for VcdWriter<W> {
writer: _,
finished_init,
timescale,
properties: _,
} = self;
f.debug_struct("VcdWriter")
.field("finished_init", finished_init)

View file

@ -7,12 +7,13 @@ use fayalite::{
clock::{Clock, ClockDomain},
expr::{CastTo, HdlPartialEq},
firrtl::ExportOptions,
formal::{any_seq, formal_reset, hdl_assert, hdl_assume},
hdl_module,
int::{Bool, UInt},
module::{connect, connect_any, reg_builder, wire},
formal::{any_const, any_seq, formal_reset, hdl_assert, hdl_assume},
hdl, hdl_module,
int::{Bool, DynSize, Size, UInt, UIntType},
module::{connect, connect_any, instance, memory, reg_builder, wire},
reset::ToReset,
testing::assert_formal,
ty::StaticType,
};
/// 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(),
);
}
}

View file

@ -1,12 +1,15 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use fayalite::{
int::UIntValue,
prelude::*,
reset::ResetType,
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation},
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue},
ty::StaticType,
util::RcWriter,
};
use std::num::NonZeroUsize;
#[hdl_module(outline_generated)]
pub fn connect_const() {
@ -252,8 +255,14 @@ fn test_shift_register() {
let mut sim = Simulation::new(shift_register());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
sim.write(
sim.io().cd,
#[hdl]
ClockDomain {
clk: false.to_clock(),
rst: true.to_sync_reset(),
},
);
sim.write_bool(sim.io().d, false);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
@ -269,7 +278,7 @@ fn test_shift_register() {
assert_eq!(
*expected,
sim.read_bool(sim.io().q),
"cycle: {cycle}\nvcd:\n{}",
"vcd:\n{}\ncycle: {cycle}",
String::from_utf8(writer.take()).unwrap(),
);
}
@ -307,6 +316,8 @@ pub fn enums() {
let which_out: UInt<2> = m.output();
#[hdl]
let data_out: UInt<4> = m.output();
#[hdl]
let b_out: HdlOption<(UInt<1>, Bool)> = m.output();
#[hdl]
struct MyStruct<T> {
@ -346,6 +357,8 @@ pub fn enums() {
}
}
connect(b_out, HdlNone());
#[hdl]
match the_reg {
MyEnum::A => {
@ -355,6 +368,7 @@ pub fn enums() {
MyEnum::B(v) => {
connect(which_out, 1_hdl_u2);
connect_any(data_out, v.0 | (v.1.cast_to_static::<UInt<1>>() << 1));
connect(b_out, HdlSome(v));
}
MyEnum::C(v) => {
connect(which_out, 2_hdl_u2);
@ -363,7 +377,6 @@ pub fn enums() {
}
}
#[cfg(todo)] // FIXME: enum lowering currently broken
#[hdl]
#[test]
fn test_enums() {
@ -381,13 +394,33 @@ fn test_enums() {
sim.advance_time(SimDuration::from_nanos(100));
sim.write_reset(sim.io().cd.rst, false);
sim.advance_time(SimDuration::from_nanos(900));
#[derive(Debug, PartialEq, Eq)]
type BOutTy = HdlOption<(UInt<1>, Bool)>;
#[derive(Debug)]
struct IO {
en: bool,
which_in: u8,
data_in: u8,
which_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 = [
IO {
@ -396,6 +429,7 @@ fn test_enums() {
data_in: 0,
which_out: 0,
data_out: 0,
b_out: HdlNone(),
},
IO {
en: true,
@ -403,6 +437,7 @@ fn test_enums() {
data_in: 0,
which_out: 0,
data_out: 0,
b_out: HdlNone(),
},
IO {
en: false,
@ -410,6 +445,7 @@ fn test_enums() {
data_in: 0,
which_out: 1,
data_out: 0,
b_out: HdlSome((0_hdl_u1, false)),
},
IO {
en: true,
@ -417,6 +453,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0,
b_out: HdlSome((0_hdl_u1, false)),
},
IO {
en: true,
@ -424,6 +461,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0x3,
b_out: HdlSome((1_hdl_u1, true)),
},
IO {
en: true,
@ -431,6 +469,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0x3,
b_out: HdlSome((1_hdl_u1, true)),
},
IO {
en: true,
@ -438,6 +477,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 2,
data_out: 0xF,
b_out: HdlNone(),
},
];
for (
@ -448,6 +488,7 @@ fn test_enums() {
data_in,
which_out: _,
data_out: _,
b_out: _,
},
) in io_cycles.into_iter().enumerate()
{
@ -468,11 +509,12 @@ fn test_enums() {
.to_bigint()
.try_into()
.expect("known to be in range"),
b_out: sim.read(sim.io().b_out).to_expr(),
};
assert_eq!(
expected,
io,
"cycle: {cycle}\nvcd:\n{}",
"vcd:\n{}\ncycle: {cycle}",
String::from_utf8(writer.take()).unwrap(),
);
sim.write_clock(sim.io().cd.clk, false);
@ -493,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!();
}
}

View file

@ -3,12 +3,12 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 2,
debug_data: [
SlotDebugData {
@ -23,7 +23,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -32,21 +32,22 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "", ty: UInt<8> },
value: 5,
0: Const {
dest: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> },
value: 0x5,
},
// at: module-XXXXXXXXXX.rs:3:1
Copy {
dest: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const: connect_const).connect_const::o", ty: UInt<8> },
src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "", ty: UInt<8> },
1: Copy {
dest: StatePartIndex<BigSlots>(0), // (0x5) SlotDebugData { name: "InstantiatedModule(connect_const: connect_const).connect_const::o", ty: UInt<8> },
src: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> },
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
2: Return,
],
..
},
pc: 2,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -79,12 +80,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: UInt<8>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -112,7 +113,7 @@ Simulation {
TraceModuleIO {
name: "o",
child: TraceUInt {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "o",
ty: UInt<8>,
flow: Sink,
@ -133,7 +134,9 @@ Simulation {
last_state: 0x05,
},
],
trace_memories: {},
trace_writers: [],
instant: 0 s,
clocks_triggered: [],
..
}

View file

@ -3,12 +3,12 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 5,
debug_data: [
SlotDebugData {
@ -35,7 +35,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -44,35 +44,36 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool },
value: 1,
0: Const {
dest: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool },
value: 0x1,
},
Copy {
dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset },
src: StatePartIndex<BigSlots>(2), // SlotDebugData { name: "", ty: Bool },
1: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x1) SlotDebugData { name: "", ty: AsyncReset },
src: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:4:1
Copy {
dest: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset },
src: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "", ty: AsyncReset },
2: Copy {
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), // (0x1) SlotDebugData { name: "", ty: AsyncReset },
},
// at: module-XXXXXXXXXX.rs:1:1
Copy {
dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", ty: AsyncReset },
3: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x1) SlotDebugData { name: "", ty: Bool },
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
Copy {
dest: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out", ty: Bool },
src: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "", ty: Bool },
4: Copy {
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), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
5: Return,
],
..
},
pc: 5,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -108,12 +109,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Bool,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -142,12 +143,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -175,7 +176,7 @@ Simulation {
TraceModuleIO {
name: "reset_out",
child: TraceAsyncReset {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "reset_out",
flow: Sink,
},
@ -185,7 +186,7 @@ Simulation {
TraceModuleIO {
name: "bit_out",
child: TraceBool {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "bit_out",
flow: Sink,
},
@ -212,6 +213,7 @@ Simulation {
last_state: 0x1,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
@ -223,4 +225,5 @@ Simulation {
],
instant: 1 μs,
clocks_triggered: [],
..
}

View file

@ -3,7 +3,7 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 4,
debug_data: [
SlotDebugData {
@ -25,7 +25,7 @@ Simulation {
],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 10,
debug_data: [
SlotDebugData {
@ -72,7 +72,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -81,99 +81,101 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<1> },
value: 1,
0: Const {
dest: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
value: 0x1,
},
Copy {
dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset },
1: Copy {
dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset },
},
// at: module-XXXXXXXXXX.rs:3:1
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset },
2: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset },
},
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> },
value: 3,
3: Const {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
value: 0x3,
},
// at: module-XXXXXXXXXX.rs:3:1
BranchIfZero {
4: BranchIfZero {
target: 6,
value: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> },
5: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
},
// at: module-XXXXXXXXXX.rs:1:1
Add {
dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<5> },
lhs: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<1> },
6: Add {
dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
},
CastToUInt {
dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<5> },
7: CastToUInt {
dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
dest_width: 4,
},
// at: module-XXXXXXXXXX.rs:4:1
Copy {
dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
src: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "", ty: UInt<4> },
8: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
},
// at: module-XXXXXXXXXX.rs:6:1
Copy {
dest: StatePartIndex<BigSlots>(2), // 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> },
9: Copy {
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", 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
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
10: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
},
AndSmall {
dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
11: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
BranchIfSmallNonZero {
12: BranchIfSmallNonZero {
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,
value: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(3), // 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> },
14: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> },
16: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
},
NotSmall {
dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
17: XorSmallImmediate {
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
18: Return,
],
..
},
pc: 18,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [
18446744073709551614,
0,
0,
1,
0,
@ -218,12 +220,12 @@ Simulation {
rst: AsyncReset,
},
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 2,
debug_data: [
SlotDebugData {
@ -248,12 +250,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -275,12 +277,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -313,12 +315,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -347,12 +349,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -381,12 +383,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -417,12 +419,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceAsyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -446,7 +448,7 @@ Simulation {
TraceModuleIO {
name: "count",
child: TraceUInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "count",
ty: UInt<4>,
flow: Sink,
@ -457,7 +459,7 @@ Simulation {
TraceReg {
name: "count_reg",
child: TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "count_reg",
ty: UInt<4>,
flow: Duplex,
@ -502,6 +504,7 @@ Simulation {
last_state: 0x3,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
@ -515,4 +518,5 @@ Simulation {
clocks_triggered: [
StatePartIndex<SmallSlots>(1),
],
..
}

View file

@ -3,7 +3,7 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 4,
debug_data: [
SlotDebugData {
@ -25,7 +25,7 @@ Simulation {
],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 9,
debug_data: [
SlotDebugData {
@ -68,7 +68,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -77,85 +77,87 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:6:1
Copy {
dest: StatePartIndex<BigSlots>(2), // 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> },
0: Copy {
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", 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
Const {
dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: UInt<1> },
value: 1,
1: Const {
dest: StatePartIndex<BigSlots>(6), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
value: 0x1,
},
Add {
dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<5> },
lhs: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: UInt<1> },
2: Add {
dest: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(6), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
},
CastToUInt {
dest: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "", ty: UInt<5> },
3: CastToUInt {
dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
dest_width: 4,
},
// at: module-XXXXXXXXXX.rs:4:1
Copy {
dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "", ty: UInt<4> },
4: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
},
// at: module-XXXXXXXXXX.rs:3:1
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset },
5: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset },
},
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> },
value: 3,
6: Const {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
value: 0x3,
},
// at: module-XXXXXXXXXX.rs:3:1
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
7: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
},
AndSmall {
dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
8: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
BranchIfSmallZero {
9: BranchIfSmallZero {
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,
value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(3), // 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> },
11: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(3), // SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // SlotDebugData { name: "", ty: UInt<4> },
13: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
},
NotSmall {
dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
14: XorSmallImmediate {
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
15: Return,
],
..
},
pc: 15,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [
18446744073709551614,
0,
0,
1,
0,
@ -199,12 +201,12 @@ Simulation {
rst: SyncReset,
},
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 2,
debug_data: [
SlotDebugData {
@ -229,12 +231,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -256,12 +258,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: SyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -294,12 +296,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -328,12 +330,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: SyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -362,12 +364,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -398,12 +400,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -427,7 +429,7 @@ Simulation {
TraceModuleIO {
name: "count",
child: TraceUInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "count",
ty: UInt<4>,
flow: Sink,
@ -438,7 +440,7 @@ Simulation {
TraceReg {
name: "count_reg",
child: TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "count_reg",
ty: UInt<4>,
flow: Duplex,
@ -483,6 +485,7 @@ Simulation {
last_state: 0x3,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
@ -496,4 +499,5 @@ Simulation {
clocks_triggered: [
StatePartIndex<SmallSlots>(1),
],
..
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
$timescale 1 ps $end
$scope module enums $end
$scope struct cd $end
$var wire 1 ! clk $end
$var wire 1 " rst $end
$upscope $end
$var wire 1 # en $end
$var wire 2 $ which_in $end
$var wire 4 % data_in $end
$var wire 2 & which_out $end
$var wire 4 ' data_out $end
$scope struct b_out $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
$var reg 1 , \0 $end
$var reg 1 - \1 $end
$upscope $end
$scope struct C $end
$scope struct a $end
$var reg 1 . \[0] $end
$var reg 1 / \[1] $end
$upscope $end
$var reg 2 0 b $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
$dumpvars
0!
1"
0#
b0 $
b0 %
b0 &
b0 '
sHdlNone\x20(0) (
0)
0*
sA\x20(0) +
0,
0-
0.
0/
b0 0
$end
#1000000
1!
#1100000
0"
#2000000
0!
#3000000
1!
#4000000
1#
b1 $
0!
#5000000
1!
b1 &
sHdlSome\x20(1) (
sB\x20(1) +
#6000000
0#
b0 $
0!
#7000000
1!
#8000000
1#
b1 $
b1111 %
0!
#9000000
1!
b11 '
1)
1*
1,
1-
1.
1/
#10000000
0!
#11000000
1!
#12000000
b10 $
0!
#13000000
1!
b10 &
b1111 '
sHdlNone\x20(0) (
0)
0*
sC\x20(2) +
b11 0
#14000000
0!
#15000000
1!
#16000000

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

View file

@ -3,12 +3,12 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 17,
debug_data: [
SlotDebugData {
@ -83,7 +83,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -92,94 +92,95 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:4:1
Copy {
dest: StatePartIndex<BigSlots>(6), // 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> },
0: Copy {
dest: StatePartIndex<BigSlots>(6), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> },
src: StatePartIndex<BigSlots>(2), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.i2", ty: SInt<2> },
},
Copy {
dest: StatePartIndex<BigSlots>(4), // 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> },
1: Copy {
dest: StatePartIndex<BigSlots>(4), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.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
Copy {
dest: StatePartIndex<BigSlots>(10), // 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> },
2: Copy {
dest: StatePartIndex<BigSlots>(10), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> },
src: StatePartIndex<BigSlots>(6), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::child.i2", ty: SInt<2> },
},
Copy {
dest: StatePartIndex<BigSlots>(8), // 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> },
3: Copy {
dest: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).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
Const {
dest: StatePartIndex<BigSlots>(16), // SlotDebugData { name: "", ty: UInt<4> },
value: 15,
4: Const {
dest: StatePartIndex<BigSlots>(16), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
value: 0xf,
},
Const {
dest: StatePartIndex<BigSlots>(14), // SlotDebugData { name: "", ty: UInt<4> },
value: 5,
5: Const {
dest: StatePartIndex<BigSlots>(14), // (0x5) SlotDebugData { name: "", ty: UInt<4> },
value: 0x5,
},
CmpLt {
dest: StatePartIndex<BigSlots>(15), // SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<BigSlots>(14), // SlotDebugData { name: "", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> },
6: CmpLt {
dest: StatePartIndex<BigSlots>(15), // (0x1) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<BigSlots>(14), // (0x5) SlotDebugData { name: "", ty: UInt<4> },
rhs: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> },
},
CastToUInt {
dest: StatePartIndex<BigSlots>(13), // SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(10), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> },
7: CastToUInt {
dest: StatePartIndex<BigSlots>(13), // (0xe) SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(10), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i2", ty: SInt<2> },
dest_width: 4,
},
// at: module-XXXXXXXXXX-2.rs:7:1
Copy {
dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> },
src: StatePartIndex<BigSlots>(13), // SlotDebugData { name: "", ty: UInt<4> },
8: Copy {
dest: StatePartIndex<BigSlots>(11), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> },
src: StatePartIndex<BigSlots>(13), // (0xe) SlotDebugData { name: "", ty: UInt<4> },
},
// at: module-XXXXXXXXXX-2.rs:8:1
BranchIfZero {
9: BranchIfZero {
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
Copy {
dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> },
src: StatePartIndex<BigSlots>(16), // SlotDebugData { name: "", ty: UInt<4> },
10: Copy {
dest: StatePartIndex<BigSlots>(11), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o2", ty: UInt<4> },
src: StatePartIndex<BigSlots>(16), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
},
// at: module-XXXXXXXXXX.rs:2:1
Copy {
dest: StatePartIndex<BigSlots>(7), // 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> },
11: Copy {
dest: StatePartIndex<BigSlots>(7), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1: mod1).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
Copy {
dest: StatePartIndex<BigSlots>(3), // 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> },
12: Copy {
dest: StatePartIndex<BigSlots>(3), // (0xf) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.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
CastToSInt {
dest: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "", ty: SInt<2> },
src: StatePartIndex<BigSlots>(8), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> },
13: CastToSInt {
dest: StatePartIndex<BigSlots>(12), // (-0x2) SlotDebugData { name: "", ty: SInt<2> },
src: StatePartIndex<BigSlots>(8), // (0xa) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::i", ty: UInt<4> },
dest_width: 2,
},
// at: module-XXXXXXXXXX-2.rs:6:1
Copy {
dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> },
src: StatePartIndex<BigSlots>(12), // SlotDebugData { name: "", ty: SInt<2> },
14: Copy {
dest: StatePartIndex<BigSlots>(9), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1.child: mod1_child).mod1_child::o", ty: SInt<2> },
src: StatePartIndex<BigSlots>(12), // (-0x2) SlotDebugData { name: "", ty: SInt<2> },
},
// at: module-XXXXXXXXXX.rs:2:1
Copy {
dest: StatePartIndex<BigSlots>(5), // 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> },
15: Copy {
dest: StatePartIndex<BigSlots>(5), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).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
Copy {
dest: StatePartIndex<BigSlots>(1), // 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> },
16: Copy {
dest: StatePartIndex<BigSlots>(1), // (-0x2) SlotDebugData { name: "InstantiatedModule(mod1: mod1).mod1::o.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
Return,
17: Return,
],
..
},
pc: 17,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -236,12 +237,12 @@ Simulation {
o2: UInt<4>,
},
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 4,
debug_data: [
SlotDebugData {
@ -274,12 +275,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -301,12 +302,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: SInt<2>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -328,12 +329,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: SInt<2>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -355,12 +356,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -393,12 +394,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -427,12 +428,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: SInt<2>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -461,12 +462,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: SInt<2>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -495,12 +496,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: UInt<4>,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -531,25 +532,25 @@ Simulation {
name: "o",
fields: [
TraceUInt {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "i",
ty: UInt<4>,
flow: Source,
},
TraceSInt {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "o",
ty: SInt<2>,
flow: Sink,
},
TraceSInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "i2",
ty: SInt<2>,
flow: Source,
},
TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "o2",
ty: UInt<4>,
flow: Sink,
@ -585,25 +586,25 @@ Simulation {
name: "child",
fields: [
TraceUInt {
id: TraceScalarId(8),
location: TraceScalarId(8),
name: "i",
ty: UInt<4>,
flow: Sink,
},
TraceSInt {
id: TraceScalarId(9),
location: TraceScalarId(9),
name: "o",
ty: SInt<2>,
flow: Source,
},
TraceSInt {
id: TraceScalarId(10),
location: TraceScalarId(10),
name: "i2",
ty: SInt<2>,
flow: Sink,
},
TraceUInt {
id: TraceScalarId(11),
location: TraceScalarId(11),
name: "o2",
ty: UInt<4>,
flow: Source,
@ -627,7 +628,7 @@ Simulation {
TraceModuleIO {
name: "i",
child: TraceUInt {
id: TraceScalarId(4),
location: TraceScalarId(4),
name: "i",
ty: UInt<4>,
flow: Source,
@ -638,7 +639,7 @@ Simulation {
TraceModuleIO {
name: "o",
child: TraceSInt {
id: TraceScalarId(5),
location: TraceScalarId(5),
name: "o",
ty: SInt<2>,
flow: Sink,
@ -649,7 +650,7 @@ Simulation {
TraceModuleIO {
name: "i2",
child: TraceSInt {
id: TraceScalarId(6),
location: TraceScalarId(6),
name: "i2",
ty: SInt<2>,
flow: Source,
@ -660,7 +661,7 @@ Simulation {
TraceModuleIO {
name: "o2",
child: TraceUInt {
id: TraceScalarId(7),
location: TraceScalarId(7),
name: "o2",
ty: UInt<4>,
flow: Sink,
@ -793,6 +794,7 @@ Simulation {
last_state: 0xe,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
@ -804,4 +806,5 @@ Simulation {
],
instant: 2 μs,
clocks_triggered: [],
..
}

View file

@ -3,7 +3,7 @@ Simulation {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 4,
debug_data: [
SlotDebugData {
@ -25,7 +25,7 @@ Simulation {
],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 13,
debug_data: [
SlotDebugData {
@ -84,7 +84,7 @@ Simulation {
..
},
},
memories: StatePartAllocationLayout<Memories> {
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
@ -93,146 +93,148 @@ Simulation {
},
insns: [
// at: module-XXXXXXXXXX.rs:13:1
Copy {
dest: StatePartIndex<BigSlots>(3), // 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 },
0: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::q", 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
Copy {
dest: StatePartIndex<BigSlots>(12), // 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 },
1: Copy {
dest: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3$next", 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
Copy {
dest: StatePartIndex<BigSlots>(10), // 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 },
2: Copy {
dest: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2$next", 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
Copy {
dest: StatePartIndex<BigSlots>(8), // 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 },
3: Copy {
dest: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1$next", 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
Copy {
dest: StatePartIndex<BigSlots>(5), // 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 },
4: Copy {
dest: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0$next", 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
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset },
5: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset },
},
// at: module-XXXXXXXXXX.rs:1:1
Const {
dest: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
value: 0,
6: Const {
dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
value: 0x0,
},
// at: module-XXXXXXXXXX.rs:5:1
IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock },
7: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock },
},
AndSmall {
dest: StatePartIndex<SmallSlots>(1), // SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
8: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
BranchIfSmallZero {
9: BranchIfSmallZero {
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,
value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(4), // 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 },
11: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(4), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool },
src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
13: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg0", ty: Bool },
src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:7:1
BranchIfSmallZero {
14: BranchIfSmallZero {
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,
value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(7), // 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 },
16: Copy {
dest: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(7), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool },
src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
18: Copy {
dest: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg1", ty: Bool },
src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:9:1
BranchIfSmallZero {
19: BranchIfSmallZero {
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,
value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(9), // 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 },
21: Copy {
dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(9), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool },
src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
23: Copy {
dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg2", ty: Bool },
src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:11:1
BranchIfSmallZero {
24: BranchIfSmallZero {
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,
value: StatePartIndex<SmallSlots>(3), // SlotDebugData { name: "", ty: Bool },
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
Copy {
dest: StatePartIndex<BigSlots>(11), // 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 },
26: Copy {
dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", 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,
},
Copy {
dest: StatePartIndex<BigSlots>(11), // SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool },
src: StatePartIndex<BigSlots>(6), // SlotDebugData { name: "", ty: Bool },
28: Copy {
dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::reg3", ty: Bool },
src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:5:1
NotSmall {
dest: StatePartIndex<SmallSlots>(0), // SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<SmallSlots>(2), // SlotDebugData { name: "", ty: Bool },
29: XorSmallImmediate {
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
Return,
30: Return,
],
..
},
pc: 30,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [
18446744073709551614,
0,
0,
1,
0,
@ -280,12 +282,12 @@ Simulation {
rst: SyncReset,
},
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 2,
debug_data: [
SlotDebugData {
@ -310,12 +312,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -337,12 +339,12 @@ Simulation {
ty: CompiledTypeLayout {
ty: SyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -375,12 +377,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -409,12 +411,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: SyncReset,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -443,12 +445,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Bool,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -477,12 +479,12 @@ Simulation {
layout: CompiledTypeLayout {
ty: Bool,
layout: TypeLayout {
small_slots: StatePartAllocationLayout<SmallSlots> {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartAllocationLayout<BigSlots> {
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
@ -513,12 +515,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -542,7 +544,7 @@ Simulation {
TraceModuleIO {
name: "d",
child: TraceBool {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "d",
flow: Source,
},
@ -552,7 +554,7 @@ Simulation {
TraceModuleIO {
name: "q",
child: TraceBool {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "q",
flow: Sink,
},
@ -562,7 +564,7 @@ Simulation {
TraceReg {
name: "reg0",
child: TraceBool {
id: TraceScalarId(4),
location: TraceScalarId(4),
name: "reg0",
flow: Duplex,
},
@ -571,7 +573,7 @@ Simulation {
TraceReg {
name: "reg1",
child: TraceBool {
id: TraceScalarId(5),
location: TraceScalarId(5),
name: "reg1",
flow: Duplex,
},
@ -580,7 +582,7 @@ Simulation {
TraceReg {
name: "reg2",
child: TraceBool {
id: TraceScalarId(6),
location: TraceScalarId(6),
name: "reg2",
flow: Duplex,
},
@ -589,7 +591,7 @@ Simulation {
TraceReg {
name: "reg3",
child: TraceBool {
id: TraceScalarId(7),
location: TraceScalarId(7),
name: "reg3",
flow: Duplex,
},
@ -663,6 +665,7 @@ Simulation {
last_state: 0x0,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
@ -676,4 +679,5 @@ Simulation {
clocks_triggered: [
StatePartIndex<SmallSlots>(1),
],
..
}