forked from libre-chip/fayalite
Compare commits
11 commits
5087f16099
...
36bad52978
Author | SHA1 | Date | |
---|---|---|---|
36bad52978 | |||
21c73051ec | |||
304d8da0e8 | |||
2af38de900 | |||
c756aeec70 | |||
903ca1bf30 | |||
8d030ac65d | |||
562c479b62 | |||
393f78a14d | |||
8616ee4737 | |||
|
2e7d685dc7 |
21 changed files with 16779 additions and 803 deletions
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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(());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: [],
|
||||
..
|
||||
}
|
|
@ -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: [],
|
||||
..
|
||||
}
|
|
@ -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),
|
||||
],
|
||||
..
|
||||
}
|
|
@ -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
|
@ -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
|
2776
crates/fayalite/tests/sim/expected/memories.txt
Normal file
2776
crates/fayalite/tests/sim/expected/memories.txt
Normal file
File diff suppressed because it is too large
Load diff
408
crates/fayalite/tests/sim/expected/memories.vcd
Normal file
408
crates/fayalite/tests/sim/expected/memories.vcd
Normal file
|
@ -0,0 +1,408 @@
|
|||
$timescale 1 ps $end
|
||||
$scope module memories $end
|
||||
$scope struct r $end
|
||||
$var wire 4 ! addr $end
|
||||
$var wire 1 " en $end
|
||||
$var wire 1 # clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 $ \0 $end
|
||||
$var wire 8 % \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct w $end
|
||||
$var wire 4 & addr $end
|
||||
$var wire 1 ' en $end
|
||||
$var wire 1 ( clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 ) \0 $end
|
||||
$var wire 8 * \1 $end
|
||||
$upscope $end
|
||||
$scope struct mask $end
|
||||
$var wire 1 + \0 $end
|
||||
$var wire 1 , \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct mem $end
|
||||
$scope struct contents $end
|
||||
$scope struct [0] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 9 \0 $end
|
||||
$var reg 8 I \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [1] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 : \0 $end
|
||||
$var reg 8 J \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [2] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 ; \0 $end
|
||||
$var reg 8 K \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [3] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 < \0 $end
|
||||
$var reg 8 L \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [4] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 = \0 $end
|
||||
$var reg 8 M \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [5] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 > \0 $end
|
||||
$var reg 8 N \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [6] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 ? \0 $end
|
||||
$var reg 8 O \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [7] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 @ \0 $end
|
||||
$var reg 8 P \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [8] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 A \0 $end
|
||||
$var reg 8 Q \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [9] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 B \0 $end
|
||||
$var reg 8 R \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [10] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 C \0 $end
|
||||
$var reg 8 S \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [11] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 D \0 $end
|
||||
$var reg 8 T \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [12] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 E \0 $end
|
||||
$var reg 8 U \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [13] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 F \0 $end
|
||||
$var reg 8 V \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [14] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 G \0 $end
|
||||
$var reg 8 W \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [15] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 H \0 $end
|
||||
$var reg 8 X \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct r0 $end
|
||||
$var wire 4 - addr $end
|
||||
$var wire 1 . en $end
|
||||
$var wire 1 / clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 0 \0 $end
|
||||
$var wire 8 1 \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct w1 $end
|
||||
$var wire 4 2 addr $end
|
||||
$var wire 1 3 en $end
|
||||
$var wire 1 4 clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 5 \0 $end
|
||||
$var wire 8 6 \1 $end
|
||||
$upscope $end
|
||||
$scope struct mask $end
|
||||
$var wire 1 7 \0 $end
|
||||
$var wire 1 8 \1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
b1 9
|
||||
b100011 I
|
||||
b1 :
|
||||
b100011 J
|
||||
b1 ;
|
||||
b100011 K
|
||||
b1 <
|
||||
b100011 L
|
||||
b1 =
|
||||
b100011 M
|
||||
b1 >
|
||||
b100011 N
|
||||
b1 ?
|
||||
b100011 O
|
||||
b1 @
|
||||
b100011 P
|
||||
b1 A
|
||||
b100011 Q
|
||||
b1 B
|
||||
b100011 R
|
||||
b1 C
|
||||
b100011 S
|
||||
b1 D
|
||||
b100011 T
|
||||
b1 E
|
||||
b100011 U
|
||||
b1 F
|
||||
b100011 V
|
||||
b1 G
|
||||
b100011 W
|
||||
b1 H
|
||||
b100011 X
|
||||
b0 !
|
||||
0"
|
||||
0#
|
||||
b0 $
|
||||
b0 %
|
||||
b0 &
|
||||
0'
|
||||
0(
|
||||
b0 )
|
||||
b0 *
|
||||
0+
|
||||
0,
|
||||
b0 -
|
||||
0.
|
||||
0/
|
||||
b0 0
|
||||
b0 1
|
||||
b0 2
|
||||
03
|
||||
04
|
||||
b0 5
|
||||
b0 6
|
||||
07
|
||||
08
|
||||
$end
|
||||
#1000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#2000000
|
||||
1"
|
||||
0#
|
||||
b1 $
|
||||
b100011 %
|
||||
1'
|
||||
0(
|
||||
b10000 )
|
||||
b100000 *
|
||||
1+
|
||||
1,
|
||||
1.
|
||||
0/
|
||||
b1 0
|
||||
b100011 1
|
||||
13
|
||||
04
|
||||
b10000 5
|
||||
b100000 6
|
||||
17
|
||||
18
|
||||
#3000000
|
||||
b10000 9
|
||||
b100000 I
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
b10000 $
|
||||
b100000 %
|
||||
b10000 0
|
||||
b100000 1
|
||||
#4000000
|
||||
0#
|
||||
0(
|
||||
b110000 )
|
||||
b1000000 *
|
||||
0+
|
||||
0/
|
||||
04
|
||||
b110000 5
|
||||
b1000000 6
|
||||
07
|
||||
#5000000
|
||||
b10000 9
|
||||
b1000000 I
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
b1000000 %
|
||||
b1000000 1
|
||||
#6000000
|
||||
0#
|
||||
0(
|
||||
b1010000 )
|
||||
b1100000 *
|
||||
1+
|
||||
0,
|
||||
0/
|
||||
04
|
||||
b1010000 5
|
||||
b1100000 6
|
||||
17
|
||||
08
|
||||
#7000000
|
||||
b1010000 9
|
||||
b1000000 I
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
b1010000 $
|
||||
b1010000 0
|
||||
#8000000
|
||||
0#
|
||||
0(
|
||||
b1110000 )
|
||||
b10000000 *
|
||||
0+
|
||||
0/
|
||||
04
|
||||
b1110000 5
|
||||
b10000000 6
|
||||
07
|
||||
#9000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#10000000
|
||||
0#
|
||||
0'
|
||||
0(
|
||||
b10010000 )
|
||||
b10100000 *
|
||||
0/
|
||||
03
|
||||
04
|
||||
b10010000 5
|
||||
b10100000 6
|
||||
#11000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#12000000
|
||||
0#
|
||||
b1 &
|
||||
1'
|
||||
0(
|
||||
1+
|
||||
1,
|
||||
0/
|
||||
b1 2
|
||||
13
|
||||
04
|
||||
17
|
||||
18
|
||||
#13000000
|
||||
b10010000 :
|
||||
b10100000 J
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#14000000
|
||||
0#
|
||||
b10 &
|
||||
0(
|
||||
b10110000 )
|
||||
b11000000 *
|
||||
0/
|
||||
b10 2
|
||||
04
|
||||
b10110000 5
|
||||
b11000000 6
|
||||
#15000000
|
||||
b10110000 ;
|
||||
b11000000 K
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#16000000
|
||||
0#
|
||||
0'
|
||||
0(
|
||||
b11010000 )
|
||||
b11100000 *
|
||||
0/
|
||||
03
|
||||
04
|
||||
b11010000 5
|
||||
b11100000 6
|
||||
#17000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#18000000
|
||||
b1 !
|
||||
0#
|
||||
b10010000 $
|
||||
b10100000 %
|
||||
0(
|
||||
b1 -
|
||||
0/
|
||||
b10010000 0
|
||||
b10100000 1
|
||||
04
|
||||
#19000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#20000000
|
||||
b10 !
|
||||
0#
|
||||
b10110000 $
|
||||
b11000000 %
|
||||
0(
|
||||
b10 -
|
||||
0/
|
||||
b10110000 0
|
||||
b11000000 1
|
||||
04
|
||||
#21000000
|
||||
1#
|
||||
1(
|
||||
1/
|
||||
14
|
||||
#22000000
|
||||
0#
|
||||
0(
|
||||
0/
|
||||
04
|
1694
crates/fayalite/tests/sim/expected/memories2.txt
Normal file
1694
crates/fayalite/tests/sim/expected/memories2.txt
Normal file
File diff suppressed because it is too large
Load diff
363
crates/fayalite/tests/sim/expected/memories2.vcd
Normal file
363
crates/fayalite/tests/sim/expected/memories2.vcd
Normal file
|
@ -0,0 +1,363 @@
|
|||
$timescale 1 ps $end
|
||||
$scope module memories2 $end
|
||||
$scope struct rw $end
|
||||
$var wire 3 ! addr $end
|
||||
$var wire 1 " en $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 2 $ rdata $end
|
||||
$var wire 1 % wmode $end
|
||||
$var wire 2 & wdata $end
|
||||
$var wire 1 ' wmask $end
|
||||
$upscope $end
|
||||
$scope struct mem $end
|
||||
$scope struct contents $end
|
||||
$scope struct [0] $end
|
||||
$scope struct mem $end
|
||||
$var string 1 1 \$tag $end
|
||||
$var reg 1 6 HdlSome $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [1] $end
|
||||
$scope struct mem $end
|
||||
$var string 1 2 \$tag $end
|
||||
$var reg 1 7 HdlSome $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [2] $end
|
||||
$scope struct mem $end
|
||||
$var string 1 3 \$tag $end
|
||||
$var reg 1 8 HdlSome $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [3] $end
|
||||
$scope struct mem $end
|
||||
$var string 1 4 \$tag $end
|
||||
$var reg 1 9 HdlSome $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [4] $end
|
||||
$scope struct mem $end
|
||||
$var string 1 5 \$tag $end
|
||||
$var reg 1 : HdlSome $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct rw0 $end
|
||||
$var wire 3 ( addr $end
|
||||
$var wire 1 ) en $end
|
||||
$var wire 1 * clk $end
|
||||
$scope struct rdata $end
|
||||
$var string 1 + \$tag $end
|
||||
$var wire 1 , HdlSome $end
|
||||
$upscope $end
|
||||
$var wire 1 - wmode $end
|
||||
$scope struct wdata $end
|
||||
$var string 1 . \$tag $end
|
||||
$var wire 1 / HdlSome $end
|
||||
$upscope $end
|
||||
$var wire 1 0 wmask $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
sHdlSome\x20(1) 1
|
||||
16
|
||||
sHdlSome\x20(1) 2
|
||||
17
|
||||
sHdlSome\x20(1) 3
|
||||
18
|
||||
sHdlSome\x20(1) 4
|
||||
19
|
||||
sHdlSome\x20(1) 5
|
||||
1:
|
||||
b0 !
|
||||
0"
|
||||
0#
|
||||
b0 $
|
||||
0%
|
||||
b0 &
|
||||
0'
|
||||
b0 (
|
||||
0)
|
||||
0*
|
||||
sHdlNone\x20(0) +
|
||||
0,
|
||||
0-
|
||||
sHdlNone\x20(0) .
|
||||
0/
|
||||
00
|
||||
$end
|
||||
#250000
|
||||
1#
|
||||
1*
|
||||
#500000
|
||||
#750000
|
||||
0#
|
||||
0*
|
||||
#1000000
|
||||
1"
|
||||
1)
|
||||
#1250000
|
||||
1#
|
||||
1*
|
||||
b11 $
|
||||
sHdlSome\x20(1) +
|
||||
1,
|
||||
#1500000
|
||||
#1750000
|
||||
0#
|
||||
0*
|
||||
#2000000
|
||||
0"
|
||||
0)
|
||||
#2250000
|
||||
1#
|
||||
1*
|
||||
b0 $
|
||||
sHdlNone\x20(0) +
|
||||
0,
|
||||
#2500000
|
||||
#2750000
|
||||
0#
|
||||
0*
|
||||
#3000000
|
||||
1"
|
||||
1%
|
||||
1'
|
||||
1)
|
||||
1-
|
||||
10
|
||||
#3250000
|
||||
sHdlNone\x20(0) 1
|
||||
06
|
||||
1#
|
||||
1*
|
||||
#3500000
|
||||
#3750000
|
||||
0#
|
||||
0*
|
||||
#4000000
|
||||
0%
|
||||
0'
|
||||
0-
|
||||
00
|
||||
#4250000
|
||||
1#
|
||||
1*
|
||||
#4500000
|
||||
#4750000
|
||||
0#
|
||||
0*
|
||||
#5000000
|
||||
1%
|
||||
b11 &
|
||||
1-
|
||||
sHdlSome\x20(1) .
|
||||
1/
|
||||
#5250000
|
||||
1#
|
||||
1*
|
||||
#5500000
|
||||
#5750000
|
||||
0#
|
||||
0*
|
||||
#6000000
|
||||
b1 !
|
||||
b1 &
|
||||
1'
|
||||
b1 (
|
||||
0/
|
||||
10
|
||||
#6250000
|
||||
sHdlSome\x20(1) 2
|
||||
07
|
||||
1#
|
||||
1*
|
||||
#6500000
|
||||
#6750000
|
||||
0#
|
||||
0*
|
||||
#7000000
|
||||
b10 !
|
||||
b10 &
|
||||
b10 (
|
||||
sHdlNone\x20(0) .
|
||||
#7250000
|
||||
sHdlNone\x20(0) 3
|
||||
08
|
||||
1#
|
||||
1*
|
||||
#7500000
|
||||
#7750000
|
||||
0#
|
||||
0*
|
||||
#8000000
|
||||
b11 !
|
||||
b11 &
|
||||
b11 (
|
||||
sHdlSome\x20(1) .
|
||||
1/
|
||||
#8250000
|
||||
sHdlSome\x20(1) 4
|
||||
19
|
||||
1#
|
||||
1*
|
||||
#8500000
|
||||
#8750000
|
||||
0#
|
||||
0*
|
||||
#9000000
|
||||
b100 !
|
||||
b10 &
|
||||
b100 (
|
||||
sHdlNone\x20(0) .
|
||||
0/
|
||||
#9250000
|
||||
sHdlNone\x20(0) 5
|
||||
0:
|
||||
1#
|
||||
1*
|
||||
#9500000
|
||||
#9750000
|
||||
0#
|
||||
0*
|
||||
#10000000
|
||||
b101 !
|
||||
b1 &
|
||||
b101 (
|
||||
sHdlSome\x20(1) .
|
||||
#10250000
|
||||
1#
|
||||
1*
|
||||
#10500000
|
||||
#10750000
|
||||
0#
|
||||
0*
|
||||
#11000000
|
||||
b110 !
|
||||
b110 (
|
||||
#11250000
|
||||
1#
|
||||
1*
|
||||
#11500000
|
||||
#11750000
|
||||
0#
|
||||
0*
|
||||
#12000000
|
||||
b111 !
|
||||
b111 (
|
||||
#12250000
|
||||
1#
|
||||
1*
|
||||
#12500000
|
||||
#12750000
|
||||
0#
|
||||
0*
|
||||
#13000000
|
||||
0%
|
||||
b0 &
|
||||
0'
|
||||
0-
|
||||
sHdlNone\x20(0) .
|
||||
00
|
||||
#13250000
|
||||
1#
|
||||
1*
|
||||
#13500000
|
||||
#13750000
|
||||
0#
|
||||
0*
|
||||
#14000000
|
||||
b110 !
|
||||
b110 (
|
||||
#14250000
|
||||
1#
|
||||
1*
|
||||
#14500000
|
||||
#14750000
|
||||
0#
|
||||
0*
|
||||
#15000000
|
||||
b101 !
|
||||
b101 (
|
||||
#15250000
|
||||
1#
|
||||
1*
|
||||
#15500000
|
||||
#15750000
|
||||
0#
|
||||
0*
|
||||
#16000000
|
||||
b100 !
|
||||
b100 (
|
||||
#16250000
|
||||
1#
|
||||
1*
|
||||
#16500000
|
||||
#16750000
|
||||
0#
|
||||
0*
|
||||
#17000000
|
||||
b11 !
|
||||
b11 (
|
||||
#17250000
|
||||
1#
|
||||
1*
|
||||
b11 $
|
||||
sHdlSome\x20(1) +
|
||||
1,
|
||||
#17500000
|
||||
#17750000
|
||||
0#
|
||||
0*
|
||||
#18000000
|
||||
b10 !
|
||||
b10 (
|
||||
#18250000
|
||||
1#
|
||||
1*
|
||||
b0 $
|
||||
sHdlNone\x20(0) +
|
||||
0,
|
||||
#18500000
|
||||
#18750000
|
||||
0#
|
||||
0*
|
||||
#19000000
|
||||
b0 !
|
||||
b0 (
|
||||
#19250000
|
||||
1#
|
||||
1*
|
||||
#19500000
|
||||
#19750000
|
||||
0#
|
||||
0*
|
||||
#20000000
|
||||
b1 !
|
||||
b1 (
|
||||
#20250000
|
||||
1#
|
||||
1*
|
||||
b1 $
|
||||
sHdlSome\x20(1) +
|
||||
#20500000
|
||||
#20750000
|
||||
0#
|
||||
0*
|
||||
#21000000
|
||||
b0 !
|
||||
0"
|
||||
b0 (
|
||||
0)
|
||||
#21250000
|
||||
1#
|
||||
1*
|
||||
b0 $
|
||||
sHdlNone\x20(0) +
|
||||
#21500000
|
||||
#21750000
|
||||
0#
|
||||
0*
|
||||
#22000000
|
4882
crates/fayalite/tests/sim/expected/memories3.txt
Normal file
4882
crates/fayalite/tests/sim/expected/memories3.txt
Normal file
File diff suppressed because it is too large
Load diff
836
crates/fayalite/tests/sim/expected/memories3.vcd
Normal file
836
crates/fayalite/tests/sim/expected/memories3.vcd
Normal file
|
@ -0,0 +1,836 @@
|
|||
$timescale 1 ps $end
|
||||
$scope module memories3 $end
|
||||
$scope struct r $end
|
||||
$var wire 3 ! addr $end
|
||||
$var wire 1 " en $end
|
||||
$var wire 1 # clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 $ \[0] $end
|
||||
$var wire 8 % \[1] $end
|
||||
$var wire 8 & \[2] $end
|
||||
$var wire 8 ' \[3] $end
|
||||
$var wire 8 ( \[4] $end
|
||||
$var wire 8 ) \[5] $end
|
||||
$var wire 8 * \[6] $end
|
||||
$var wire 8 + \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct w $end
|
||||
$var wire 3 , addr $end
|
||||
$var wire 1 - en $end
|
||||
$var wire 1 . clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 / \[0] $end
|
||||
$var wire 8 0 \[1] $end
|
||||
$var wire 8 1 \[2] $end
|
||||
$var wire 8 2 \[3] $end
|
||||
$var wire 8 3 \[4] $end
|
||||
$var wire 8 4 \[5] $end
|
||||
$var wire 8 5 \[6] $end
|
||||
$var wire 8 6 \[7] $end
|
||||
$upscope $end
|
||||
$scope struct mask $end
|
||||
$var wire 1 7 \[0] $end
|
||||
$var wire 1 8 \[1] $end
|
||||
$var wire 1 9 \[2] $end
|
||||
$var wire 1 : \[3] $end
|
||||
$var wire 1 ; \[4] $end
|
||||
$var wire 1 < \[5] $end
|
||||
$var wire 1 = \[6] $end
|
||||
$var wire 1 > \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct mem $end
|
||||
$scope struct contents $end
|
||||
$scope struct [0] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 ] \[0] $end
|
||||
$var reg 8 e \[1] $end
|
||||
$var reg 8 m \[2] $end
|
||||
$var reg 8 u \[3] $end
|
||||
$var reg 8 } \[4] $end
|
||||
$var reg 8 '" \[5] $end
|
||||
$var reg 8 /" \[6] $end
|
||||
$var reg 8 7" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [1] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 ^ \[0] $end
|
||||
$var reg 8 f \[1] $end
|
||||
$var reg 8 n \[2] $end
|
||||
$var reg 8 v \[3] $end
|
||||
$var reg 8 ~ \[4] $end
|
||||
$var reg 8 (" \[5] $end
|
||||
$var reg 8 0" \[6] $end
|
||||
$var reg 8 8" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [2] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 _ \[0] $end
|
||||
$var reg 8 g \[1] $end
|
||||
$var reg 8 o \[2] $end
|
||||
$var reg 8 w \[3] $end
|
||||
$var reg 8 !" \[4] $end
|
||||
$var reg 8 )" \[5] $end
|
||||
$var reg 8 1" \[6] $end
|
||||
$var reg 8 9" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [3] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 ` \[0] $end
|
||||
$var reg 8 h \[1] $end
|
||||
$var reg 8 p \[2] $end
|
||||
$var reg 8 x \[3] $end
|
||||
$var reg 8 "" \[4] $end
|
||||
$var reg 8 *" \[5] $end
|
||||
$var reg 8 2" \[6] $end
|
||||
$var reg 8 :" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [4] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 a \[0] $end
|
||||
$var reg 8 i \[1] $end
|
||||
$var reg 8 q \[2] $end
|
||||
$var reg 8 y \[3] $end
|
||||
$var reg 8 #" \[4] $end
|
||||
$var reg 8 +" \[5] $end
|
||||
$var reg 8 3" \[6] $end
|
||||
$var reg 8 ;" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [5] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 b \[0] $end
|
||||
$var reg 8 j \[1] $end
|
||||
$var reg 8 r \[2] $end
|
||||
$var reg 8 z \[3] $end
|
||||
$var reg 8 $" \[4] $end
|
||||
$var reg 8 ," \[5] $end
|
||||
$var reg 8 4" \[6] $end
|
||||
$var reg 8 <" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [6] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 c \[0] $end
|
||||
$var reg 8 k \[1] $end
|
||||
$var reg 8 s \[2] $end
|
||||
$var reg 8 { \[3] $end
|
||||
$var reg 8 %" \[4] $end
|
||||
$var reg 8 -" \[5] $end
|
||||
$var reg 8 5" \[6] $end
|
||||
$var reg 8 =" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct [7] $end
|
||||
$scope struct mem $end
|
||||
$var reg 8 d \[0] $end
|
||||
$var reg 8 l \[1] $end
|
||||
$var reg 8 t \[2] $end
|
||||
$var reg 8 | \[3] $end
|
||||
$var reg 8 &" \[4] $end
|
||||
$var reg 8 ." \[5] $end
|
||||
$var reg 8 6" \[6] $end
|
||||
$var reg 8 >" \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct r0 $end
|
||||
$var wire 3 ? addr $end
|
||||
$var wire 1 @ en $end
|
||||
$var wire 1 A clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 B \[0] $end
|
||||
$var wire 8 C \[1] $end
|
||||
$var wire 8 D \[2] $end
|
||||
$var wire 8 E \[3] $end
|
||||
$var wire 8 F \[4] $end
|
||||
$var wire 8 G \[5] $end
|
||||
$var wire 8 H \[6] $end
|
||||
$var wire 8 I \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope struct w1 $end
|
||||
$var wire 3 J addr $end
|
||||
$var wire 1 K en $end
|
||||
$var wire 1 L clk $end
|
||||
$scope struct data $end
|
||||
$var wire 8 M \[0] $end
|
||||
$var wire 8 N \[1] $end
|
||||
$var wire 8 O \[2] $end
|
||||
$var wire 8 P \[3] $end
|
||||
$var wire 8 Q \[4] $end
|
||||
$var wire 8 R \[5] $end
|
||||
$var wire 8 S \[6] $end
|
||||
$var wire 8 T \[7] $end
|
||||
$upscope $end
|
||||
$scope struct mask $end
|
||||
$var wire 1 U \[0] $end
|
||||
$var wire 1 V \[1] $end
|
||||
$var wire 1 W \[2] $end
|
||||
$var wire 1 X \[3] $end
|
||||
$var wire 1 Y \[4] $end
|
||||
$var wire 1 Z \[5] $end
|
||||
$var wire 1 [ \[6] $end
|
||||
$var wire 1 \ \[7] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
b0 ]
|
||||
b0 e
|
||||
b0 m
|
||||
b0 u
|
||||
b0 }
|
||||
b0 '"
|
||||
b0 /"
|
||||
b0 7"
|
||||
b0 ^
|
||||
b0 f
|
||||
b0 n
|
||||
b0 v
|
||||
b0 ~
|
||||
b0 ("
|
||||
b0 0"
|
||||
b0 8"
|
||||
b0 _
|
||||
b0 g
|
||||
b0 o
|
||||
b0 w
|
||||
b0 !"
|
||||
b0 )"
|
||||
b0 1"
|
||||
b0 9"
|
||||
b0 `
|
||||
b0 h
|
||||
b0 p
|
||||
b0 x
|
||||
b0 ""
|
||||
b0 *"
|
||||
b0 2"
|
||||
b0 :"
|
||||
b0 a
|
||||
b0 i
|
||||
b0 q
|
||||
b0 y
|
||||
b0 #"
|
||||
b0 +"
|
||||
b0 3"
|
||||
b0 ;"
|
||||
b0 b
|
||||
b0 j
|
||||
b0 r
|
||||
b0 z
|
||||
b0 $"
|
||||
b0 ,"
|
||||
b0 4"
|
||||
b0 <"
|
||||
b0 c
|
||||
b0 k
|
||||
b0 s
|
||||
b0 {
|
||||
b0 %"
|
||||
b0 -"
|
||||
b0 5"
|
||||
b0 ="
|
||||
b0 d
|
||||
b0 l
|
||||
b0 t
|
||||
b0 |
|
||||
b0 &"
|
||||
b0 ."
|
||||
b0 6"
|
||||
b0 >"
|
||||
b0 !
|
||||
0"
|
||||
0#
|
||||
b0 $
|
||||
b0 %
|
||||
b0 &
|
||||
b0 '
|
||||
b0 (
|
||||
b0 )
|
||||
b0 *
|
||||
b0 +
|
||||
b0 ,
|
||||
1-
|
||||
0.
|
||||
b10010 /
|
||||
b110100 0
|
||||
b1010110 1
|
||||
b1111000 2
|
||||
b10011010 3
|
||||
b10111100 4
|
||||
b11011110 5
|
||||
b11110000 6
|
||||
07
|
||||
18
|
||||
09
|
||||
1:
|
||||
1;
|
||||
0<
|
||||
0=
|
||||
1>
|
||||
b0 ?
|
||||
0@
|
||||
0A
|
||||
b0 B
|
||||
b0 C
|
||||
b0 D
|
||||
b0 E
|
||||
b0 F
|
||||
b0 G
|
||||
b0 H
|
||||
b0 I
|
||||
b0 J
|
||||
1K
|
||||
0L
|
||||
b10010 M
|
||||
b110100 N
|
||||
b1010110 O
|
||||
b1111000 P
|
||||
b10011010 Q
|
||||
b10111100 R
|
||||
b11011110 S
|
||||
b11110000 T
|
||||
0U
|
||||
1V
|
||||
0W
|
||||
1X
|
||||
1Y
|
||||
0Z
|
||||
0[
|
||||
1\
|
||||
$end
|
||||
#250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#500000
|
||||
#750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#1000000
|
||||
1"
|
||||
b1 ,
|
||||
0-
|
||||
b0 /
|
||||
b0 0
|
||||
b0 1
|
||||
b0 2
|
||||
b0 3
|
||||
b0 4
|
||||
b0 5
|
||||
b0 6
|
||||
08
|
||||
0:
|
||||
0;
|
||||
0>
|
||||
1@
|
||||
b1 J
|
||||
0K
|
||||
b0 M
|
||||
b0 N
|
||||
b0 O
|
||||
b0 P
|
||||
b0 Q
|
||||
b0 R
|
||||
b0 S
|
||||
b0 T
|
||||
0V
|
||||
0X
|
||||
0Y
|
||||
0\
|
||||
#1250000
|
||||
b0 ]
|
||||
b110100 e
|
||||
b0 m
|
||||
b1111000 u
|
||||
b10011010 }
|
||||
b0 '"
|
||||
b0 /"
|
||||
b11110000 7"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#1500000
|
||||
#1750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#2000000
|
||||
#2250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#2500000
|
||||
#2750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#3000000
|
||||
b0 ,
|
||||
1-
|
||||
b11111110 /
|
||||
b11011100 0
|
||||
b10111010 1
|
||||
b10011000 2
|
||||
b1110110 3
|
||||
b1010100 4
|
||||
b110010 5
|
||||
b10000 6
|
||||
17
|
||||
18
|
||||
19
|
||||
1:
|
||||
1;
|
||||
1<
|
||||
1=
|
||||
1>
|
||||
b0 J
|
||||
1K
|
||||
b11111110 M
|
||||
b11011100 N
|
||||
b10111010 O
|
||||
b10011000 P
|
||||
b1110110 Q
|
||||
b1010100 R
|
||||
b110010 S
|
||||
b10000 T
|
||||
1U
|
||||
1V
|
||||
1W
|
||||
1X
|
||||
1Y
|
||||
1Z
|
||||
1[
|
||||
1\
|
||||
#3250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b110100 C
|
||||
b1111000 E
|
||||
b10011010 F
|
||||
b11110000 I
|
||||
1L
|
||||
b110100 %
|
||||
b1111000 '
|
||||
b10011010 (
|
||||
b11110000 +
|
||||
#3500000
|
||||
#3750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#4000000
|
||||
#4250000
|
||||
b11111110 ]
|
||||
b11011100 e
|
||||
b10111010 m
|
||||
b10011000 u
|
||||
b1110110 }
|
||||
b1010100 '"
|
||||
b110010 /"
|
||||
b10000 7"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#4500000
|
||||
#4750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#5000000
|
||||
#5250000
|
||||
b11111110 ]
|
||||
b11011100 e
|
||||
b10111010 m
|
||||
b10011000 u
|
||||
b1110110 }
|
||||
b1010100 '"
|
||||
b110010 /"
|
||||
b10000 7"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#5500000
|
||||
#5750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#6000000
|
||||
0"
|
||||
b1 ,
|
||||
b10011 /
|
||||
b1010111 0
|
||||
b10011011 1
|
||||
b11011111 2
|
||||
b10 3
|
||||
b1000110 4
|
||||
b10001010 5
|
||||
b11001110 6
|
||||
0@
|
||||
b1 J
|
||||
b10011 M
|
||||
b1010111 N
|
||||
b10011011 O
|
||||
b11011111 P
|
||||
b10 Q
|
||||
b1000110 R
|
||||
b10001010 S
|
||||
b11001110 T
|
||||
#6250000
|
||||
b11111110 ]
|
||||
b11011100 e
|
||||
b10111010 m
|
||||
b10011000 u
|
||||
b1110110 }
|
||||
b1010100 '"
|
||||
b110010 /"
|
||||
b10000 7"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b11111110 B
|
||||
b11011100 C
|
||||
b10111010 D
|
||||
b10011000 E
|
||||
b1110110 F
|
||||
b1010100 G
|
||||
b110010 H
|
||||
b10000 I
|
||||
1L
|
||||
b11111110 $
|
||||
b11011100 %
|
||||
b10111010 &
|
||||
b10011000 '
|
||||
b1110110 (
|
||||
b1010100 )
|
||||
b110010 *
|
||||
b10000 +
|
||||
#6500000
|
||||
#6750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#7000000
|
||||
b10 ,
|
||||
b1110100 /
|
||||
b1100101 0
|
||||
b1110011 1
|
||||
b1110100 2
|
||||
b1101001 3
|
||||
b1101110 4
|
||||
b1100111 5
|
||||
b100001 6
|
||||
b10 J
|
||||
b1110100 M
|
||||
b1100101 N
|
||||
b1110011 O
|
||||
b1110100 P
|
||||
b1101001 Q
|
||||
b1101110 R
|
||||
b1100111 S
|
||||
b100001 T
|
||||
#7250000
|
||||
b10011 ^
|
||||
b1010111 f
|
||||
b10011011 n
|
||||
b11011111 v
|
||||
b10 ~
|
||||
b1000110 ("
|
||||
b10001010 0"
|
||||
b11001110 8"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b0 B
|
||||
b0 C
|
||||
b0 D
|
||||
b0 E
|
||||
b0 F
|
||||
b0 G
|
||||
b0 H
|
||||
b0 I
|
||||
1L
|
||||
b0 $
|
||||
b0 %
|
||||
b0 &
|
||||
b0 '
|
||||
b0 (
|
||||
b0 )
|
||||
b0 *
|
||||
b0 +
|
||||
#7500000
|
||||
#7750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#8000000
|
||||
b11 ,
|
||||
b1101101 /
|
||||
b1101111 0
|
||||
b1110010 1
|
||||
b1100101 2
|
||||
b100000 3
|
||||
b1110100 4
|
||||
b1110011 5
|
||||
b1110100 6
|
||||
b11 J
|
||||
b1101101 M
|
||||
b1101111 N
|
||||
b1110010 O
|
||||
b1100101 P
|
||||
b100000 Q
|
||||
b1110100 R
|
||||
b1110011 S
|
||||
b1110100 T
|
||||
#8250000
|
||||
b1110100 _
|
||||
b1100101 g
|
||||
b1110011 o
|
||||
b1110100 w
|
||||
b1101001 !"
|
||||
b1101110 )"
|
||||
b1100111 1"
|
||||
b100001 9"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#8500000
|
||||
#8750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#9000000
|
||||
1"
|
||||
b0 ,
|
||||
0-
|
||||
b0 /
|
||||
b0 0
|
||||
b0 1
|
||||
b0 2
|
||||
b0 3
|
||||
b0 4
|
||||
b0 5
|
||||
b0 6
|
||||
07
|
||||
08
|
||||
09
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
0>
|
||||
1@
|
||||
b0 J
|
||||
0K
|
||||
b0 M
|
||||
b0 N
|
||||
b0 O
|
||||
b0 P
|
||||
b0 Q
|
||||
b0 R
|
||||
b0 S
|
||||
b0 T
|
||||
0U
|
||||
0V
|
||||
0W
|
||||
0X
|
||||
0Y
|
||||
0Z
|
||||
0[
|
||||
0\
|
||||
#9250000
|
||||
b1101101 `
|
||||
b1101111 h
|
||||
b1110010 p
|
||||
b1100101 x
|
||||
b100000 ""
|
||||
b1110100 *"
|
||||
b1110011 2"
|
||||
b1110100 :"
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
1L
|
||||
#9500000
|
||||
#9750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#10000000
|
||||
b1 !
|
||||
b1 ?
|
||||
#10250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b11111110 B
|
||||
b11011100 C
|
||||
b10111010 D
|
||||
b10011000 E
|
||||
b1110110 F
|
||||
b1010100 G
|
||||
b110010 H
|
||||
b10000 I
|
||||
1L
|
||||
b11111110 $
|
||||
b11011100 %
|
||||
b10111010 &
|
||||
b10011000 '
|
||||
b1110110 (
|
||||
b1010100 )
|
||||
b110010 *
|
||||
b10000 +
|
||||
#10500000
|
||||
#10750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#11000000
|
||||
b10 !
|
||||
b10 ?
|
||||
#11250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b10011 B
|
||||
b1010111 C
|
||||
b10011011 D
|
||||
b11011111 E
|
||||
b10 F
|
||||
b1000110 G
|
||||
b10001010 H
|
||||
b11001110 I
|
||||
1L
|
||||
b10011 $
|
||||
b1010111 %
|
||||
b10011011 &
|
||||
b11011111 '
|
||||
b10 (
|
||||
b1000110 )
|
||||
b10001010 *
|
||||
b11001110 +
|
||||
#11500000
|
||||
#11750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#12000000
|
||||
b11 !
|
||||
b11 ?
|
||||
#12250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b1110100 B
|
||||
b1100101 C
|
||||
b1110011 D
|
||||
b1110100 E
|
||||
b1101001 F
|
||||
b1101110 G
|
||||
b1100111 H
|
||||
b100001 I
|
||||
1L
|
||||
b1110100 $
|
||||
b1100101 %
|
||||
b1110011 &
|
||||
b1110100 '
|
||||
b1101001 (
|
||||
b1101110 )
|
||||
b1100111 *
|
||||
b100001 +
|
||||
#12500000
|
||||
#12750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#13000000
|
||||
b0 !
|
||||
0"
|
||||
b0 ?
|
||||
0@
|
||||
#13250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b1101101 B
|
||||
b1101111 C
|
||||
b1110010 D
|
||||
b1100101 E
|
||||
b100000 F
|
||||
b1110100 G
|
||||
b1110011 H
|
||||
b1110100 I
|
||||
1L
|
||||
b1101101 $
|
||||
b1101111 %
|
||||
b1110010 &
|
||||
b1100101 '
|
||||
b100000 (
|
||||
b1110100 )
|
||||
b1110011 *
|
||||
b1110100 +
|
||||
#13500000
|
||||
#13750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#14000000
|
||||
#14250000
|
||||
1#
|
||||
1.
|
||||
1A
|
||||
b0 B
|
||||
b0 C
|
||||
b0 D
|
||||
b0 E
|
||||
b0 F
|
||||
b0 G
|
||||
b0 H
|
||||
b0 I
|
||||
1L
|
||||
b0 $
|
||||
b0 %
|
||||
b0 &
|
||||
b0 '
|
||||
b0 (
|
||||
b0 )
|
||||
b0 *
|
||||
b0 +
|
||||
#14500000
|
||||
#14750000
|
||||
0#
|
||||
0.
|
||||
0A
|
||||
0L
|
||||
#15000000
|
|
@ -3,12 +3,12 @@ Simulation {
|
|||
insns: Insns {
|
||||
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: [],
|
||||
..
|
||||
}
|
|
@ -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),
|
||||
],
|
||||
..
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue