1
0
Fork 0

Compare commits

...

10 commits

68 changed files with 22979 additions and 1617 deletions

View file

@ -224,7 +224,7 @@ impl Builder {
.args .args
.push_value(match get_field_state(field_index) { .push_value(match get_field_state(field_index) {
BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=> BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=>
::fayalite::bundle::Unfilled<#ty> ()
}, },
BuilderFieldState::Generic => { BuilderFieldState::Generic => {
let type_var = type_var_for_field_name(ident); let type_var = type_var_for_field_name(ident);
@ -383,7 +383,7 @@ impl ToTokens for Builder {
fn default() -> Self { fn default() -> Self {
#ident { #ident {
#phantom_field_name: ::fayalite::__std::marker::PhantomData, #phantom_field_name: ::fayalite::__std::marker::PhantomData,
#(#field_idents: ::fayalite::__std::default::Default::default(),)* #(#field_idents: (),)*
} }
} }
} }
@ -395,7 +395,7 @@ impl ToTokens for Builder {
let type_generics = self.generics.split_for_impl().1; let type_generics = self.generics.split_for_impl().1;
quote_spanned! {self.ident.span()=> quote_spanned! {self.ident.span()=>
#[automatically_derived] #[automatically_derived]
#[allow(non_camel_case_types, dead_code)] #[allow(non_camel_case_types, dead_code, private_interfaces)]
impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty
#filled_where_clause #filled_where_clause
{ {
@ -499,7 +499,6 @@ impl ToTokens for ParsedBundle {
}; };
builder.to_tokens(tokens); builder.to_tokens(tokens);
let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
let filled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Filled);
let mut mask_type_fields = FieldsNamed::from(fields.clone()); let mut mask_type_fields = FieldsNamed::from(fields.clone());
for Field { ty, .. } in &mut mask_type_fields.named { for Field { ty, .. } in &mut mask_type_fields.named {
*ty = parse_quote_spanned! {span=> *ty = parse_quote_spanned! {span=>
@ -517,8 +516,6 @@ impl ToTokens for ParsedBundle {
mask_type_builder.to_tokens(tokens); mask_type_builder.to_tokens(tokens);
let unfilled_mask_type_builder_ty = let unfilled_mask_type_builder_ty =
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
let filled_mask_type_builder_ty =
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Filled);
ItemStruct { ItemStruct {
attrs: vec![ attrs: vec![
common_derives(span), common_derives(span),
@ -785,7 +782,6 @@ impl ToTokens for ParsedBundle {
#where_clause #where_clause
{ {
type Builder = #unfilled_mask_type_builder_ty; type Builder = #unfilled_mask_type_builder_ty;
type FilledBuilder = #filled_mask_type_builder_ty;
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
} }
@ -935,7 +931,6 @@ impl ToTokens for ParsedBundle {
#where_clause #where_clause
{ {
type Builder = #unfilled_builder_ty; type Builder = #unfilled_builder_ty;
type FilledBuilder = #filled_builder_ty;
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
} }

View file

@ -3,111 +3,19 @@
use crate::{ use crate::{
Errors, HdlAttr, Errors, HdlAttr,
hdl_type_common::{ hdl_type_common::{
ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, TypesParser, ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType,
WrappedInConst, common_derives, get_target, known_items, PhantomConstGetBound, TypesParser, WrappedInConst, common_derives, get_target, known_items,
}, },
kw, kw,
}; };
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{ToTokens, format_ident, quote_spanned}; use quote::{ToTokens, format_ident, quote_spanned};
use syn::{ use syn::{
AngleBracketedGenericArguments, Attribute, Expr, Fields, GenericArgument, GenericParam, Attribute, Expr, Fields, GenericParam, Generics, Ident, ItemStruct, ItemType, Token, Type,
Generics, Ident, ItemStruct, ItemType, Path, PathArguments, Token, TraitBound, TypeGroup, TypeParam, TypeParen, Visibility, parse_quote_spanned, punctuated::Pair,
TraitBoundModifier, Type, TypeGroup, TypeParam, TypeParamBound, TypeParen, Visibility, token::Paren,
parse_quote_spanned, punctuated::Pair, token::Paren,
}; };
#[derive(Clone, Debug)]
pub(crate) struct PhantomConstGetBound {
pub(crate) phantom_const_get: known_items::PhantomConstGet,
pub(crate) colon2_token: Option<Token![::]>,
pub(crate) lt_token: Token![<],
pub(crate) ty: Type,
pub(crate) comma_token: Option<Token![,]>,
pub(crate) gt_token: Token![>],
}
impl From<PhantomConstGetBound> for Path {
fn from(value: PhantomConstGetBound) -> Self {
let PhantomConstGetBound {
phantom_const_get,
colon2_token,
lt_token,
ty,
comma_token,
gt_token,
} = value;
let mut path = phantom_const_get.path;
path.segments.last_mut().expect("known to exist").arguments =
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
colon2_token,
lt_token,
args: FromIterator::from_iter([Pair::new(GenericArgument::Type(ty), comma_token)]),
gt_token,
});
path
}
}
impl From<PhantomConstGetBound> for TraitBound {
fn from(value: PhantomConstGetBound) -> Self {
let path = Path::from(value);
TraitBound {
paren_token: None,
modifier: TraitBoundModifier::None,
lifetimes: None,
path,
}
}
}
impl From<PhantomConstGetBound> for TypeParamBound {
fn from(value: PhantomConstGetBound) -> Self {
TraitBound::from(value).into()
}
}
impl PhantomConstGetBound {
fn parse_opt(bound: TypeParamBound) -> Option<Self> {
let TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: TraitBoundModifier::None,
lifetimes: None,
path,
}) = bound
else {
return None;
};
let Ok((
phantom_const_get,
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
colon2_token,
lt_token,
args,
gt_token,
}),
)) = known_items::PhantomConstGet::parse_path_with_arguments(path)
else {
return None;
};
let mut args = args.into_pairs();
let (GenericArgument::Type(ty), comma_token) = args.next()?.into_tuple() else {
return None;
};
let None = args.next() else {
return None;
};
Some(Self {
phantom_const_get,
colon2_token,
lt_token,
ty,
comma_token,
gt_token,
})
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct PhantomConstAccessorTypeParam { pub(crate) struct PhantomConstAccessorTypeParam {
attrs: Vec<Attribute>, attrs: Vec<Attribute>,
@ -162,7 +70,9 @@ impl PhantomConstAccessorTypeParam {
let colon_token = colon_token.unwrap_or(Token![:](ident.span())); let colon_token = colon_token.unwrap_or(Token![:](ident.span()));
let mut bounds = bounds.into_pairs(); let mut bounds = bounds.into_pairs();
let (bound, plus_token) = bounds.next()?.into_tuple(); let (bound, plus_token) = bounds.next()?.into_tuple();
let phantom_const_get_bound = PhantomConstGetBound::parse_opt(bound)?; let phantom_const_get_bound = PhantomConstGetBound::parse_type_param_bound(bound)
.ok()?
.ok()?;
let None = bounds.next() else { let None = bounds.next() else {
return None; return None;
}; };

View file

@ -8,9 +8,9 @@ use syn::{
AngleBracketedGenericArguments, Attribute, Block, ConstParam, Expr, ExprBlock, ExprGroup, AngleBracketedGenericArguments, Attribute, Block, ConstParam, Expr, ExprBlock, ExprGroup,
ExprIndex, ExprParen, ExprPath, ExprTuple, Field, FieldMutability, Fields, FieldsNamed, ExprIndex, ExprParen, ExprPath, ExprTuple, Field, FieldMutability, Fields, FieldsNamed,
FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct, FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct,
Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, Turbofish, Type, Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, Turbofish,
TypeGenerics, TypeGroup, TypeParam, TypeParen, TypePath, TypeTuple, Visibility, WhereClause, Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple,
WherePredicate, Visibility, WhereClause, WherePredicate,
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
parse_quote, parse_quote_spanned, parse_quote, parse_quote_spanned,
punctuated::{Pair, Punctuated}, punctuated::{Pair, Punctuated},
@ -2065,6 +2065,174 @@ pub(crate) mod known_items {
); );
} }
#[derive(Clone, Debug)]
pub(crate) struct PhantomConstGetBound {
pub(crate) phantom_const_get: known_items::PhantomConstGet,
pub(crate) colon2_token: Option<Token![::]>,
pub(crate) lt_token: Token![<],
pub(crate) ty: Type,
pub(crate) comma_token: Option<Token![,]>,
pub(crate) gt_token: Token![>],
}
impl PhantomConstGetBound {
pub(crate) fn parse_path_with_arguments(path: Path) -> syn::Result<Result<Self, Path>> {
match known_items::PhantomConstGet::parse_path_with_arguments(path) {
Ok((phantom_const_get, arguments)) => {
Self::parse_path_and_arguments(phantom_const_get, arguments).map(Ok)
}
Err(path) => Ok(Err(path)),
}
}
pub(crate) fn parse_path_and_arguments(
phantom_const_get: known_items::PhantomConstGet,
arguments: PathArguments,
) -> syn::Result<Self> {
let error = |arguments: PathArguments, message: &str| {
let mut path = phantom_const_get.path.clone();
path.segments.last_mut().expect("known to exist").arguments = arguments;
syn::Error::new_spanned(path, message)
};
match arguments {
PathArguments::None => Err(error(arguments, "missing generics for PhantomConstGet")),
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
colon2_token,
lt_token,
args,
gt_token,
}) => {
let error = |args: Punctuated<GenericArgument, Token![,]>, message| {
error(
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
colon2_token,
lt_token,
args,
gt_token,
}),
message,
)
};
let mut args = args.into_pairs().peekable();
let Some((generic_argument, comma_token)) = args.next().map(Pair::into_tuple)
else {
return Err(error(
Default::default(),
"PhantomConstGet takes a type argument but no generic arguments were supplied",
));
};
if args.peek().is_some() {
return Err(error(
[Pair::new(generic_argument, comma_token)]
.into_iter()
.chain(args)
.collect(),
"PhantomConstGet takes a single type argument but too many generic arguments were supplied",
));
};
let GenericArgument::Type(ty) = generic_argument else {
return Err(error(
Punctuated::from_iter([Pair::new(generic_argument, comma_token)]),
"PhantomConstGet requires a type argument",
));
};
Ok(Self {
phantom_const_get,
colon2_token,
lt_token,
ty,
comma_token,
gt_token,
})
}
PathArguments::Parenthesized(_) => Err(error(
arguments,
"parenthetical generics are not valid for PhantomConstGet",
)),
}
}
pub(crate) fn parse_type_param_bound(
bound: TypeParamBound,
) -> syn::Result<Result<Self, TypeParamBound>> {
let TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path,
}) = bound
else {
return Ok(Err(bound));
};
Ok(match Self::parse_path_with_arguments(path)? {
Ok(v) => Ok(v),
Err(path) => Err(TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path,
})),
})
}
}
impl ToTokens for PhantomConstGetBound {
fn to_tokens(&self, tokens: &mut TokenStream) {
let Self {
phantom_const_get,
colon2_token,
lt_token,
ty,
comma_token,
gt_token,
} = self;
phantom_const_get.to_tokens(tokens);
colon2_token.to_tokens(tokens);
lt_token.to_tokens(tokens);
ty.to_tokens(tokens);
comma_token.to_tokens(tokens);
gt_token.to_tokens(tokens);
}
}
impl From<PhantomConstGetBound> for Path {
fn from(value: PhantomConstGetBound) -> Self {
let PhantomConstGetBound {
phantom_const_get,
colon2_token,
lt_token,
ty,
comma_token,
gt_token,
} = value;
let mut path = phantom_const_get.path;
path.segments.last_mut().expect("known to exist").arguments =
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
colon2_token,
lt_token,
args: FromIterator::from_iter([Pair::new(GenericArgument::Type(ty), comma_token)]),
gt_token,
});
path
}
}
impl From<PhantomConstGetBound> for TraitBound {
fn from(value: PhantomConstGetBound) -> Self {
let path = Path::from(value);
TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path,
}
}
}
impl From<PhantomConstGetBound> for TypeParamBound {
fn from(value: PhantomConstGetBound) -> Self {
TraitBound::from(value).into()
}
}
macro_rules! impl_bounds { macro_rules! impl_bounds {
( (
#[struct = $struct_type:ident] #[struct = $struct_type:ident]
@ -2072,6 +2240,10 @@ macro_rules! impl_bounds {
$( $(
$Variant:ident, $Variant:ident,
)* )*
$(
#[has_body]
$VariantHasBody:ident($variant_has_body_ty:ty),
)*
$( $(
#[unknown] #[unknown]
$Unknown:ident, $Unknown:ident,
@ -2081,6 +2253,7 @@ macro_rules! impl_bounds {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
$vis enum $enum_type { $vis enum $enum_type {
$($Variant(known_items::$Variant),)* $($Variant(known_items::$Variant),)*
$($VariantHasBody($variant_has_body_ty),)*
$($Unknown(syn::TypeParamBound),)? $($Unknown(syn::TypeParamBound),)?
} }
@ -2090,31 +2263,42 @@ macro_rules! impl_bounds {
} }
})* })*
$(impl From<$variant_has_body_ty> for $enum_type {
fn from(v: $variant_has_body_ty) -> Self {
Self::$VariantHasBody(v)
}
})*
impl ToTokens for $enum_type { impl ToTokens for $enum_type {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream) {
match self { match self {
$(Self::$Variant(v) => v.to_tokens(tokens),)* $(Self::$Variant(v) => v.to_tokens(tokens),)*
$(Self::$VariantHasBody(v) => v.to_tokens(tokens),)*
$(Self::$Unknown(v) => v.to_tokens(tokens),)? $(Self::$Unknown(v) => v.to_tokens(tokens),)?
} }
} }
} }
impl $enum_type { impl $enum_type {
$vis fn parse_path(path: Path) -> Result<Self, Path> { $vis fn parse_path_with_arguments(path: Path) -> syn::Result<Result<Self, Path>> {
#![allow(unreachable_code)] #![allow(unreachable_code)]
$(let path = match known_items::$Variant::parse_path(path) { $(let path = match known_items::$Variant::parse_path(path) {
Ok(v) => return Ok(Self::$Variant(v)), Ok(v) => return Ok(Ok(Self::$Variant(v))),
Err(path) => path, Err(path) => path,
};)* };)*
$(return Ok(Self::$Unknown(syn::TraitBound { $(let path = match <$variant_has_body_ty>::parse_path_with_arguments(path)? {
Ok(v) => return Ok(Ok(Self::$VariantHasBody(v))),
Err(path) => path,
};)*
$(return Ok(Ok(Self::$Unknown(syn::TraitBound {
paren_token: None, paren_token: None,
modifier: syn::TraitBoundModifier::None, modifier: syn::TraitBoundModifier::None,
lifetimes: None, lifetimes: None,
path, path,
}.into()));)? }.into())));)?
Err(path) Ok(Err(path))
} }
$vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> Result<Self, syn::TypeParamBound> { $vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> syn::Result<Result<Self, syn::TypeParamBound>> {
#![allow(unreachable_code)] #![allow(unreachable_code)]
if let syn::TypeParamBound::Trait(mut trait_bound) = type_param_bound { if let syn::TypeParamBound::Trait(mut trait_bound) = type_param_bound {
if let syn::TraitBound { if let syn::TraitBound {
@ -2123,24 +2307,24 @@ macro_rules! impl_bounds {
lifetimes: None, lifetimes: None,
path: _, path: _,
} = trait_bound { } = trait_bound {
match Self::parse_path(trait_bound.path) { match Self::parse_path_with_arguments(trait_bound.path)? {
Ok(retval) => return Ok(retval), Ok(retval) => return Ok(Ok(retval)),
Err(path) => trait_bound.path = path, Err(path) => trait_bound.path = path,
} }
} }
type_param_bound = trait_bound.into(); type_param_bound = trait_bound.into();
} }
$(return Ok(Self::$Unknown(type_param_bound));)? $(return Ok(Ok(Self::$Unknown(type_param_bound)));)?
Err(type_param_bound) Ok(Err(type_param_bound))
} }
} }
impl Parse for $enum_type { impl Parse for $enum_type {
fn parse(input: ParseStream) -> syn::Result<Self> { fn parse(input: ParseStream) -> syn::Result<Self> {
Self::parse_type_param_bound(input.parse()?) Self::parse_type_param_bound(input.parse()?)?
.map_err(|type_param_bound| syn::Error::new_spanned( .map_err(|type_param_bound| syn::Error::new_spanned(
type_param_bound, type_param_bound,
format_args!("expected one of: {}", [$(stringify!($Variant)),*].join(", ")), format_args!("expected one of: {}", [$(stringify!($Variant),)* $(stringify!($VariantHasBody)),*].join(", ")),
)) ))
} }
} }
@ -2149,6 +2333,7 @@ macro_rules! impl_bounds {
#[allow(non_snake_case)] #[allow(non_snake_case)]
$vis struct $struct_type { $vis struct $struct_type {
$($vis $Variant: Option<known_items::$Variant>,)* $($vis $Variant: Option<known_items::$Variant>,)*
$($vis $VariantHasBody: Option<$variant_has_body_ty>,)*
$($vis $Unknown: Vec<syn::TypeParamBound>,)? $($vis $Unknown: Vec<syn::TypeParamBound>,)?
} }
@ -2161,6 +2346,11 @@ macro_rules! impl_bounds {
separator = Some(<Token![+]>::default()); separator = Some(<Token![+]>::default());
v.to_tokens(tokens); v.to_tokens(tokens);
})* })*
$(if let Some(v) = &self.$VariantHasBody {
separator.to_tokens(tokens);
separator = Some(<Token![+]>::default());
v.to_tokens(tokens);
})*
$(for v in &self.$Unknown { $(for v in &self.$Unknown {
separator.to_tokens(tokens); separator.to_tokens(tokens);
separator = Some(<Token![+]>::default()); separator = Some(<Token![+]>::default());
@ -2174,6 +2364,7 @@ macro_rules! impl_bounds {
#[allow(non_snake_case)] #[allow(non_snake_case)]
$vis struct Iter { $vis struct Iter {
$($Variant: Option<known_items::$Variant>,)* $($Variant: Option<known_items::$Variant>,)*
$($VariantHasBody: Option<$variant_has_body_ty>,)*
$($Unknown: std::vec::IntoIter<syn::TypeParamBound>,)? $($Unknown: std::vec::IntoIter<syn::TypeParamBound>,)?
} }
@ -2184,6 +2375,7 @@ macro_rules! impl_bounds {
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
Iter { Iter {
$($Variant: self.$Variant,)* $($Variant: self.$Variant,)*
$($VariantHasBody: self.$VariantHasBody,)*
$($Unknown: self.$Unknown.into_iter(),)? $($Unknown: self.$Unknown.into_iter(),)?
} }
} }
@ -2198,6 +2390,11 @@ macro_rules! impl_bounds {
return Some($enum_type::$Variant(value)); return Some($enum_type::$Variant(value));
} }
)* )*
$(
if let Some(value) = self.$VariantHasBody.take() {
return Some($enum_type::$VariantHasBody(value));
}
)*
$( $(
if let Some(value) = self.$Unknown.next() { if let Some(value) = self.$Unknown.next() {
return Some($enum_type::$Unknown(value)); return Some($enum_type::$Unknown(value));
@ -2213,6 +2410,11 @@ macro_rules! impl_bounds {
init = f(init, $enum_type::$Variant(value)); init = f(init, $enum_type::$Variant(value));
} }
)* )*
$(
if let Some(value) = self.$VariantHasBody.take() {
init = f(init, $enum_type::$VariantHasBody(value));
}
)*
$( $(
if let Some(value) = self.$Unknown.next() { if let Some(value) = self.$Unknown.next() {
init = f(init, $enum_type::$Unknown(value)); init = f(init, $enum_type::$Unknown(value));
@ -2229,6 +2431,9 @@ macro_rules! impl_bounds {
$($enum_type::$Variant(v) => { $($enum_type::$Variant(v) => {
self.$Variant = Some(v); self.$Variant = Some(v);
})* })*
$($enum_type::$VariantHasBody(v) => {
self.$VariantHasBody = Some(v);
})*
$($enum_type::$Unknown(v) => { $($enum_type::$Unknown(v) => {
self.$Unknown.push(v); self.$Unknown.push(v);
})? })?
@ -2250,6 +2455,9 @@ macro_rules! impl_bounds {
$(if let Some(v) = v.$Variant { $(if let Some(v) = v.$Variant {
self.$Variant = Some(v); self.$Variant = Some(v);
})* })*
$(if let Some(v) = v.$VariantHasBody {
self.$VariantHasBody = Some(v);
})*
$(self.$Unknown.extend(v.$Unknown);)* $(self.$Unknown.extend(v.$Unknown);)*
}); });
} }
@ -2304,6 +2512,8 @@ impl_bounds! {
Size, Size,
StaticType, StaticType,
Type, Type,
#[has_body]
PhantomConstGet(PhantomConstGetBound),
#[unknown] #[unknown]
Unknown, Unknown,
} }
@ -2319,6 +2529,8 @@ impl_bounds! {
ResetType, ResetType,
StaticType, StaticType,
Type, Type,
#[has_body]
PhantomConstGet(PhantomConstGetBound),
#[unknown] #[unknown]
Unknown, Unknown,
} }
@ -2334,6 +2546,7 @@ impl From<ParsedTypeBound> for ParsedBound {
ParsedTypeBound::ResetType(v) => ParsedBound::ResetType(v), ParsedTypeBound::ResetType(v) => ParsedBound::ResetType(v),
ParsedTypeBound::StaticType(v) => ParsedBound::StaticType(v), ParsedTypeBound::StaticType(v) => ParsedBound::StaticType(v),
ParsedTypeBound::Type(v) => ParsedBound::Type(v), ParsedTypeBound::Type(v) => ParsedBound::Type(v),
ParsedTypeBound::PhantomConstGet(v) => ParsedBound::PhantomConstGet(v),
ParsedTypeBound::Unknown(v) => ParsedBound::Unknown(v), ParsedTypeBound::Unknown(v) => ParsedBound::Unknown(v),
} }
} }
@ -2349,6 +2562,7 @@ impl From<ParsedTypeBounds> for ParsedBounds {
ResetType, ResetType,
StaticType, StaticType,
Type, Type,
PhantomConstGet,
Unknown, Unknown,
} = value; } = value;
Self { Self {
@ -2361,6 +2575,7 @@ impl From<ParsedTypeBounds> for ParsedBounds {
Size: None, Size: None,
StaticType, StaticType,
Type, Type,
PhantomConstGet,
Unknown, Unknown,
} }
} }
@ -2397,6 +2612,10 @@ impl ParsedTypeBound {
ParsedTypeBound::Type(known_items::Type(span)), ParsedTypeBound::Type(known_items::Type(span)),
]), ]),
Self::Type(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::from(v)]), Self::Type(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::from(v)]),
Self::PhantomConstGet(v) => ParsedTypeBounds::from_iter([
ParsedTypeBound::from(v),
ParsedTypeBound::Type(known_items::Type(span)),
]),
Self::Unknown(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::Unknown(v)]), Self::Unknown(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::Unknown(v)]),
} }
} }
@ -2432,6 +2651,7 @@ impl From<ParsedSizeTypeBounds> for ParsedBounds {
Size, Size,
StaticType: None, StaticType: None,
Type: None, Type: None,
PhantomConstGet: None,
Unknown: vec![], Unknown: vec![],
} }
} }
@ -2534,6 +2754,9 @@ impl ParsedBound {
Self::Size(v) => ParsedBoundCategory::SizeType(ParsedSizeTypeBound::Size(v)), Self::Size(v) => ParsedBoundCategory::SizeType(ParsedSizeTypeBound::Size(v)),
Self::StaticType(v) => ParsedBoundCategory::Type(ParsedTypeBound::StaticType(v)), Self::StaticType(v) => ParsedBoundCategory::Type(ParsedTypeBound::StaticType(v)),
Self::Type(v) => ParsedBoundCategory::Type(ParsedTypeBound::Type(v)), Self::Type(v) => ParsedBoundCategory::Type(ParsedTypeBound::Type(v)),
Self::PhantomConstGet(v) => {
ParsedBoundCategory::Type(ParsedTypeBound::PhantomConstGet(v))
}
Self::Unknown(v) => ParsedBoundCategory::Unknown(v), Self::Unknown(v) => ParsedBoundCategory::Unknown(v),
} }
} }
@ -3419,7 +3642,8 @@ impl ParsedGenerics {
| ParsedTypeBound::BundleType(_) | ParsedTypeBound::BundleType(_)
| ParsedTypeBound::EnumType(_) | ParsedTypeBound::EnumType(_)
| ParsedTypeBound::IntType(_) | ParsedTypeBound::IntType(_)
| ParsedTypeBound::ResetType(_) => { | ParsedTypeBound::ResetType(_)
| ParsedTypeBound::PhantomConstGet(_) => {
errors.error(bound, "bounds on mask types are not implemented"); errors.error(bound, "bounds on mask types are not implemented");
} }
ParsedTypeBound::StaticType(bound) => { ParsedTypeBound::StaticType(bound) => {
@ -4388,3 +4612,124 @@ impl MakeHdlTypeExpr for ParsedTypeTuple {
}) })
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ParsedSimpleVisibility {
Public(Token![pub]),
PubCrate {
pub_token: Token![pub],
paren_token: Paren,
crate_token: Token![crate],
},
Inherited,
}
impl From<ParsedSimpleVisibility> for Visibility {
fn from(value: ParsedSimpleVisibility) -> Self {
match value {
ParsedSimpleVisibility::Public(v) => Visibility::Public(v),
ParsedSimpleVisibility::PubCrate {
pub_token,
paren_token,
crate_token,
} => Visibility::Restricted(syn::VisRestricted {
pub_token,
paren_token,
in_token: None,
path: Box::new(Ident::new("crate", crate_token.span).into()),
}),
ParsedSimpleVisibility::Inherited => Visibility::Inherited,
}
}
}
impl PartialOrd for ParsedSimpleVisibility {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ParsedSimpleVisibility {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.visibility_level().cmp(&other.visibility_level())
}
}
impl ParsedSimpleVisibility {
const VISIBILITY_LEVEL_INHERITED: u8 = 0;
const VISIBILITY_LEVEL_RESTRICTED: u8 = 1 + Self::VISIBILITY_LEVEL_INHERITED;
const VISIBILITY_LEVEL_PUB_CRATE: u8 = 1 + Self::VISIBILITY_LEVEL_RESTRICTED;
const VISIBILITY_LEVEL_PUB: u8 = 1 + Self::VISIBILITY_LEVEL_PUB_CRATE;
fn visibility_level(self) -> u8 {
match self {
Self::Public(_) => Self::VISIBILITY_LEVEL_PUB,
Self::PubCrate { .. } => Self::VISIBILITY_LEVEL_PUB_CRATE,
Self::Inherited => Self::VISIBILITY_LEVEL_INHERITED,
}
}
pub(crate) fn parse(vis: Visibility) -> Result<Self, syn::VisRestricted> {
match vis {
Visibility::Public(v) => Ok(Self::Public(v)),
Visibility::Restricted(syn::VisRestricted {
pub_token,
paren_token,
in_token: None,
path,
}) if path.is_ident("crate") => Ok(Self::PubCrate {
pub_token,
paren_token,
crate_token: Token![crate](path.get_ident().expect("just checked").span()),
}),
Visibility::Restricted(v) => Err(v),
Visibility::Inherited => Ok(Self::Inherited),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum ParsedVisibility {
Simple(ParsedSimpleVisibility),
Restricted(syn::VisRestricted),
}
impl From<ParsedVisibility> for Visibility {
fn from(value: ParsedVisibility) -> Self {
match value {
ParsedVisibility::Simple(v) => v.into(),
ParsedVisibility::Restricted(v) => Visibility::Restricted(v),
}
}
}
impl PartialOrd for ParsedVisibility {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match (self, other) {
(ParsedVisibility::Simple(l), ParsedVisibility::Simple(r)) => Some(l.cmp(r)),
(ParsedVisibility::Simple(l), ParsedVisibility::Restricted(_)) => Some(
l.visibility_level()
.cmp(&ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED),
),
(ParsedVisibility::Restricted(_), ParsedVisibility::Simple(r)) => {
Some(ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED.cmp(&r.visibility_level()))
}
(ParsedVisibility::Restricted(l), ParsedVisibility::Restricted(r)) => {
(l == r).then_some(std::cmp::Ordering::Equal)
}
}
}
}
impl ParsedVisibility {
#[allow(dead_code)]
pub(crate) fn parse(vis: Visibility) -> Self {
match ParsedSimpleVisibility::parse(vis) {
Ok(simple) => Self::Simple(simple),
Err(restricted) => Self::Restricted(restricted),
}
}
#[allow(dead_code)]
pub(crate) fn min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
self.partial_cmp(other)
.map(|ord| if ord.is_lt() { self } else { other })
}
}

View file

@ -703,8 +703,12 @@ impl JobGraph {
} }
let mut running_jobs = HashMap::default(); let mut running_jobs = HashMap::default();
let (finished_jobs_sender, finished_jobs_receiver) = mpsc::channel(); let (finished_jobs_sender, finished_jobs_receiver) = mpsc::channel();
let mut next_finished_job = None;
loop { loop {
while let Some(finished_job) = finished_jobs_receiver.try_recv().ok() { if let Some(finished_job) = next_finished_job
.take()
.or_else(|| finished_jobs_receiver.try_recv().ok())
{
let Some(RunningJob { job, thread }) = running_jobs.remove(&finished_job) let Some(RunningJob { job, thread }) = running_jobs.remove(&finished_job)
else { else {
unreachable!(); unreachable!();
@ -736,6 +740,7 @@ impl JobGraph {
} }
} }
} }
continue;
} }
if let Some(WaitingJobState { if let Some(WaitingJobState {
job_node_id, job_node_id,
@ -791,12 +796,15 @@ impl JobGraph {
.expect("failed to spawn thread for job"), .expect("failed to spawn thread for job"),
}, },
); );
continue;
} }
if running_jobs.is_empty() { if running_jobs.is_empty() {
assert!(item_name_to_waiting_jobs_map.is_empty()); assert!(item_name_to_waiting_jobs_map.is_empty());
assert!(ready_jobs.is_empty()); assert!(ready_jobs.is_empty());
return Ok(()); return Ok(());
} }
// nothing to do yet, block to avoid busy waiting
next_finished_job = finished_jobs_receiver.recv().ok();
} }
}) })
} }

View file

@ -271,7 +271,6 @@ impl Type for Bundle {
pub trait BundleType: Type<BaseType = Bundle> { pub trait BundleType: Type<BaseType = Bundle> {
type Builder: Default; type Builder: Default;
type FilledBuilder: ToExpr<Type = Self>;
fn fields(&self) -> Interned<[BundleField]>; fn fields(&self) -> Interned<[BundleField]>;
} }
@ -374,17 +373,8 @@ impl<'a> BundleSimValueToOpaque<'a> {
#[derive(Default)] #[derive(Default)]
pub struct NoBuilder; pub struct NoBuilder;
pub struct Unfilled<T: Type>(PhantomData<T>);
impl<T: Type> Default for Unfilled<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl BundleType for Bundle { impl BundleType for Bundle {
type Builder = NoBuilder; type Builder = NoBuilder;
type FilledBuilder = Expr<Bundle>;
fn fields(&self) -> Interned<[BundleField]> { fn fields(&self) -> Interned<[BundleField]> {
self.0.fields self.0.fields
} }
@ -420,15 +410,14 @@ macro_rules! impl_tuple_builder_fields {
) => { ) => {
impl< impl<
$($head_type_var,)* $($head_type_var,)*
$cur_type_var: Type,
$($tail_type_var,)* $($tail_type_var,)*
> TupleBuilder<( > TupleBuilder<(
$($head_type_var,)* $($head_type_var,)*
Unfilled<$cur_type_var>, (),
$($tail_type_var,)* $($tail_type_var,)*
)> )>
{ {
pub fn $cur_field(self, $cur_var: impl ToExpr<Type = $cur_type_var>) -> TupleBuilder<( pub fn $cur_field<$cur_type_var: Type>(self, $cur_var: impl ToExpr<Type = $cur_type_var>) -> TupleBuilder<(
$($head_type_var,)* $($head_type_var,)*
Expr<$cur_type_var>, Expr<$cur_type_var>,
$($tail_type_var,)* $($tail_type_var,)*
@ -452,6 +441,12 @@ macro_rules! impl_tuple_builder_fields {
($global:tt []) => {}; ($global:tt []) => {};
} }
macro_rules! get_unit_ty {
($($tt:tt)*) => {
()
};
}
macro_rules! impl_tuples { macro_rules! impl_tuples {
( (
[$({ [$({
@ -545,8 +540,7 @@ macro_rules! impl_tuples {
} }
} }
impl<$($T: Type,)*> BundleType for ($($T,)*) { impl<$($T: Type,)*> BundleType for ($($T,)*) {
type Builder = TupleBuilder<($(Unfilled<$T>,)*)>; type Builder = TupleBuilder<($(get_unit_ty!($T),)*)>;
type FilledBuilder = TupleBuilder<($(Expr<$T>,)*)>;
fn fields(&self) -> Interned<[BundleField]> { fn fields(&self) -> Interned<[BundleField]> {
let ($($var,)*) = self; let ($($var,)*) = self;
[$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice() [$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice()
@ -791,7 +785,6 @@ impl<T: ?Sized + Send + Sync + 'static> ToExpr for PhantomDataBuilder<T> {
impl<T: ?Sized + Send + Sync + 'static> BundleType for PhantomData<T> { impl<T: ?Sized + Send + Sync + 'static> BundleType for PhantomData<T> {
type Builder = PhantomDataBuilder<T>; type Builder = PhantomDataBuilder<T>;
type FilledBuilder = PhantomDataBuilder<T>;
fn fields(&self) -> Interned<[BundleField]> { fn fields(&self) -> Interned<[BundleField]> {
Interned::default() Interned::default()
} }

View file

@ -2326,6 +2326,7 @@ impl<'a> Exporter<'a> {
ModuleBody::Extern(ExternModuleBody { ModuleBody::Extern(ExternModuleBody {
verilog_name, verilog_name,
parameters, parameters,
clocks_for_past: _,
simulation: _, simulation: _,
}) => { }) => {
let verilog_name = Ident(verilog_name); let verilog_name = Ident(verilog_name);

View file

@ -96,7 +96,6 @@ impl Type for UIntInRangeMaskType {
impl BundleType for UIntInRangeMaskType { impl BundleType for UIntInRangeMaskType {
type Builder = NoBuilder; type Builder = NoBuilder;
type FilledBuilder = Expr<UIntInRangeMaskType>;
fn fields(&self) -> Interned<[BundleField]> { fn fields(&self) -> Interned<[BundleField]> {
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
@ -300,9 +299,7 @@ macro_rules! define_uint_in_range_type {
} }
} }
pub fn new(start: Start::SizeType, end: End::SizeType) -> Self { pub fn new(start: Start::SizeType, end: End::SizeType) -> Self {
Self::from_phantom_const_range(PhantomConst::new( Self::from_phantom_const_range(PhantomConst::new_sized($SerdeRange { start, end }))
$SerdeRange { start, end }.intern_sized(),
))
} }
pub fn bit_width(self) -> usize { pub fn bit_width(self) -> usize {
self.value.width() self.value.width()
@ -402,7 +399,6 @@ macro_rules! define_uint_in_range_type {
impl<Start: Size, End: Size> BundleType for $UIntInRangeType<Start, End> { impl<Start: Size, End: Size> BundleType for $UIntInRangeType<Start, End> {
type Builder = NoBuilder; type Builder = NoBuilder;
type FilledBuilder = Expr<Self>;
fn fields(&self) -> Interned<[BundleField]> { fn fields(&self) -> Interned<[BundleField]> {
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;

View file

@ -152,7 +152,7 @@ pub use fayalite_proc_macros::hdl_module;
/// This allows you to use some computed property of a [`PhantomConst`] to get a [`Type`] that you can use in other #[hdl] types. /// This allows you to use some computed property of a [`PhantomConst`] to get a [`Type`] that you can use in other #[hdl] types.
/// ///
/// ``` /// ```
/// # use fayalite::{intern::Intern, prelude::*}; /// # use fayalite::prelude::*;
/// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] /// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
/// pub struct Config { /// pub struct Config {
/// pub foo: usize, /// pub foo: usize,
@ -166,13 +166,13 @@ pub use fayalite_proc_macros::hdl_module;
/// // you can then use it in other types: /// // you can then use it in other types:
/// ///
/// #[hdl(no_static)] /// #[hdl(no_static)]
/// pub struct WrapMyArray<P: Type + PhantomConstGet<Config>> { /// pub struct WrapMyArray<P: PhantomConstGet<Config>> {
/// pub my_array: GetMyArray<P>, /// pub my_array: GetMyArray<P>,
/// } /// }
/// ///
/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime: /// // you can then use Fayalite's standard syntax for creating dynamic types at runtime:
/// let bar = Bundle::new(Default::default()); /// let bar = Bundle::new(Default::default());
/// let config = PhantomConst::new(Config { foo: 12, bar }.intern_sized()); /// let config = PhantomConst::new_sized(Config { foo: 12, bar });
/// let ty = WrapMyArray[config]; /// let ty = WrapMyArray[config];
/// assert_eq!(ty.my_array, Array[bar][12]); /// assert_eq!(ty.my_array, Array[bar][12]);
/// ``` /// ```
@ -182,7 +182,7 @@ pub use fayalite_proc_macros::hdl_module;
/// This allows you to use some computed property of a [`PhantomConst`] to get a [`Size`] that you can use in other #[hdl] types. /// This allows you to use some computed property of a [`PhantomConst`] to get a [`Size`] that you can use in other #[hdl] types.
/// ///
/// ``` /// ```
/// # use fayalite::{intern::Intern, prelude::*}; /// # use fayalite::prelude::*;
/// # #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] /// # #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
/// # pub struct ConfigItem {} /// # pub struct ConfigItem {}
/// # impl ConfigItem { /// # impl ConfigItem {
@ -202,12 +202,12 @@ pub use fayalite_proc_macros::hdl_module;
/// // you can then use it in other types: /// // you can then use it in other types:
/// ///
/// #[hdl(no_static)] /// #[hdl(no_static)]
/// pub struct FlagPerItem<P: Type + PhantomConstGet<Config>> { /// pub struct FlagPerItem<P: PhantomConstGet<Config>> {
/// pub flags: ArrayType<Bool, GetItemsLen<P>>, /// pub flags: ArrayType<Bool, GetItemsLen<P>>,
/// } /// }
/// ///
/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime: /// // you can then use Fayalite's standard syntax for creating dynamic types at runtime:
/// let config = PhantomConst::new(Config { items: vec![ConfigItem::new(); 5] }.intern_sized()); /// let config = PhantomConst::new_sized(Config { items: vec![ConfigItem::new(); 5] });
/// let ty = FlagPerItem[config]; /// let ty = FlagPerItem[config];
/// assert_eq!(ty.flags, Array[Bool][5]); /// assert_eq!(ty.flags, Array[Bool][5]);
/// ``` /// ```

View file

@ -41,7 +41,6 @@ use std::{
marker::PhantomData, marker::PhantomData,
mem, mem,
num::NonZeroU64, num::NonZeroU64,
ops::Deref,
rc::Rc, rc::Rc,
sync::atomic::AtomicU64, sync::atomic::AtomicU64,
}; };
@ -67,6 +66,8 @@ pub trait ModuleBuildingStatus:
type ModuleBody: fmt::Debug; type ModuleBody: fmt::Debug;
type StmtAnnotations: 'static + Send + Sync + Copy + Eq + Hash + fmt::Debug; type StmtAnnotations: 'static + Send + Sync + Copy + Eq + Hash + fmt::Debug;
type ModuleIOAnnotations; type ModuleIOAnnotations;
type ExternModuleParameters: fmt::Debug;
type ExternModuleClocksForPast: fmt::Debug;
} }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
@ -79,6 +80,8 @@ impl ModuleBuildingStatus for ModuleBuilt {
type ModuleBody = Block; type ModuleBody = Block;
type StmtAnnotations = Interned<[TargetedAnnotation]>; type StmtAnnotations = Interned<[TargetedAnnotation]>;
type ModuleIOAnnotations = Interned<[TargetedAnnotation]>; type ModuleIOAnnotations = Interned<[TargetedAnnotation]>;
type ExternModuleParameters = Interned<[ExternModuleParameter]>;
type ExternModuleClocksForPast = Interned<[Target]>;
} }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
@ -91,6 +94,8 @@ impl ModuleBuildingStatus for ModuleBuilding {
type ModuleBody = BuilderModuleBody; type ModuleBody = BuilderModuleBody;
type StmtAnnotations = (); type StmtAnnotations = ();
type ModuleIOAnnotations = Vec<TargetedAnnotation>; type ModuleIOAnnotations = Vec<TargetedAnnotation>;
type ExternModuleParameters = Vec<ExternModuleParameter>;
type ExternModuleClocksForPast = Vec<Target>;
} }
#[derive(Debug)] #[derive(Debug)]
@ -1080,26 +1085,65 @@ impl From<NormalModuleBody> for ModuleBody {
} }
} }
#[track_caller]
fn validate_clock_for_past<S: ModuleBuildingStatus>(
clock_for_past: Option<Target>,
module_io: &[AnnotatedModuleIO<S>],
) -> Target {
if let Some(clock_for_past) = clock_for_past {
assert_eq!(
clock_for_past.canonical_ty(),
Clock.canonical(),
"clock_for_past: clock is not of type Clock",
);
if clock_for_past
.base()
.module_io()
.is_some_and(|v| module_io.iter().any(|module_io| module_io.module_io == *v))
{
let mut target = clock_for_past;
while let Target::Child(child) = target {
match *child.path_element() {
TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {}
TargetPathElement::DynArrayElement(_) => {
panic!(
"clock_for_past: clock must be a static target (you can't use `Expr<UInt>` array indexes):\n{clock_for_past:?}"
);
}
}
target = *child.parent();
}
return clock_for_past;
}
}
panic!("clock_for_past: clock must be some part of this module's I/O:\n{clock_for_past:?}");
}
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub struct ExternModuleBody< pub struct ExternModuleBody<S: ModuleBuildingStatus = ModuleBuilt> {
P: Deref<Target = [ExternModuleParameter]> = Interned<[ExternModuleParameter]>,
> {
pub verilog_name: Interned<str>, pub verilog_name: Interned<str>,
pub parameters: P, pub parameters: S::ExternModuleParameters,
/// [`Clock`]s that the [`Simulation`] will store the past values of all [`ModuleIO`] for.
///
/// [`Simulation`]: crate::sim::Simulation
pub clocks_for_past: S::ExternModuleClocksForPast,
pub simulation: Option<ExternModuleSimulation>, pub simulation: Option<ExternModuleSimulation>,
} }
impl From<ExternModuleBody<Vec<ExternModuleParameter>>> for ExternModuleBody { impl From<ExternModuleBody<ModuleBuilding>> for ExternModuleBody {
fn from(value: ExternModuleBody<Vec<ExternModuleParameter>>) -> Self { fn from(value: ExternModuleBody<ModuleBuilding>) -> Self {
let ExternModuleBody { let ExternModuleBody {
verilog_name, verilog_name,
parameters, parameters,
clocks_for_past,
simulation, simulation,
} = value; } = value;
let parameters = Intern::intern_owned(parameters); let parameters = Intern::intern_owned(parameters);
let clocks_for_past = Intern::intern_owned(clocks_for_past);
Self { Self {
verilog_name, verilog_name,
parameters, parameters,
clocks_for_past,
simulation, simulation,
} }
} }
@ -1112,15 +1156,12 @@ impl From<ExternModuleBody> for ModuleBody {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ModuleBody< pub enum ModuleBody<S: ModuleBuildingStatus = ModuleBuilt> {
S: ModuleBuildingStatus = ModuleBuilt,
P: Deref<Target = [ExternModuleParameter]> = Interned<[ExternModuleParameter]>,
> {
Normal(NormalModuleBody<S>), Normal(NormalModuleBody<S>),
Extern(ExternModuleBody<P>), Extern(ExternModuleBody<S>),
} }
pub(crate) type ModuleBodyBuilding = ModuleBody<ModuleBuilding, Vec<ExternModuleParameter>>; pub(crate) type ModuleBodyBuilding = ModuleBody<ModuleBuilding>;
impl ModuleBodyBuilding { impl ModuleBodyBuilding {
pub(crate) fn builder_normal_body_opt( pub(crate) fn builder_normal_body_opt(
@ -1141,9 +1182,7 @@ impl ModuleBodyBuilding {
} }
} }
#[track_caller] #[track_caller]
pub(crate) fn builder_extern_body( pub(crate) fn builder_extern_body(&mut self) -> &mut ExternModuleBody<ModuleBuilding> {
&mut self,
) -> &mut ExternModuleBody<Vec<ExternModuleParameter>> {
if let Self::Extern(v) = self { if let Self::Extern(v) = self {
v v
} else { } else {
@ -1297,11 +1336,13 @@ impl<T: BundleType> fmt::Debug for DebugModuleBody<T> {
ModuleBody::Extern(ExternModuleBody { ModuleBody::Extern(ExternModuleBody {
verilog_name, verilog_name,
parameters, parameters,
clocks_for_past,
simulation, simulation,
}) => { }) => {
debug_struct debug_struct
.field("verilog_name", verilog_name) .field("verilog_name", verilog_name)
.field("parameters", parameters) .field("parameters", parameters)
.field("clocks_for_past", clocks_for_past)
.field("simulation", simulation); .field("simulation", simulation);
} }
} }
@ -1780,8 +1821,13 @@ impl AssertValidityState {
ModuleBody::Extern(ExternModuleBody { ModuleBody::Extern(ExternModuleBody {
verilog_name: _, verilog_name: _,
parameters: _, parameters: _,
clocks_for_past,
simulation: _, simulation: _,
}) => {} }) => {
for clock_for_past in clocks_for_past {
validate_clock_for_past(Some(clock_for_past), &self.module.module_io);
}
}
ModuleBody::Normal(NormalModuleBody { body }) => { ModuleBody::Normal(NormalModuleBody { body }) => {
let body = self.make_block_index(body); let body = self.make_block_index(body);
assert_eq!(body, 0); assert_eq!(body, 0);
@ -1811,9 +1857,17 @@ impl<T: BundleType> Module<T> {
match &mut body { match &mut body {
ModuleBody::Normal(_) => {} ModuleBody::Normal(_) => {}
ModuleBody::Extern(ExternModuleBody { ModuleBody::Extern(ExternModuleBody {
verilog_name: _,
parameters: _,
clocks_for_past,
simulation: Some(simulation), simulation: Some(simulation),
..
}) => { }) => {
let mut clocks_for_past_set = HashSet::default();
*clocks_for_past = clocks_for_past
.iter()
.copied()
.filter(|clock_for_past| clocks_for_past_set.insert(*clock_for_past))
.collect();
if module_io.iter().any(|io| { if module_io.iter().any(|io| {
!simulation !simulation
.sim_io_to_generator_map .sim_io_to_generator_map
@ -2186,6 +2240,7 @@ impl ModuleBuilder {
ModuleKind::Extern => ModuleBody::Extern(ExternModuleBody { ModuleKind::Extern => ModuleBody::Extern(ExternModuleBody {
verilog_name: name.0, verilog_name: name.0,
parameters: vec![], parameters: vec![],
clocks_for_past: vec![],
simulation: None, simulation: None,
}), }),
ModuleKind::Normal => ModuleBody::Normal(NormalModuleBody { ModuleKind::Normal => ModuleBody::Normal(NormalModuleBody {
@ -2308,6 +2363,20 @@ impl ModuleBuilder {
value: ExternModuleParameterValue::RawVerilog(raw_verilog.intern()), value: ExternModuleParameterValue::RawVerilog(raw_verilog.intern()),
}); });
} }
/// registers a [`Clock`] so you can use it with the [`ExternModuleSimulationState::read_past()`] family of functions.
///
/// [`ExternModuleSimulationState::read_past()`]: crate::sim::ExternModuleSimulationState::read_past()
#[track_caller]
pub fn register_clock_for_past(&self, clock_for_past: impl ToExpr<Type = Clock>) {
let clock_for_past = clock_for_past.to_expr().target().as_deref().copied();
let mut impl_ = self.impl_.borrow_mut();
let clock_for_past = validate_clock_for_past(clock_for_past, &impl_.io);
impl_
.body
.builder_extern_body()
.clocks_for_past
.push(clock_for_past);
}
#[track_caller] #[track_caller]
pub fn extern_module_simulation<G: ExternModuleSimGenerator>(&self, generator: G) { pub fn extern_module_simulation<G: ExternModuleSimGenerator>(&self, generator: G) {
let mut impl_ = self.impl_.borrow_mut(); let mut impl_ = self.impl_.borrow_mut();

View file

@ -2073,6 +2073,7 @@ impl_run_pass_for_struct! {
impl[] RunPass for ExternModuleBody { impl[] RunPass for ExternModuleBody {
verilog_name: _, verilog_name: _,
parameters: _, parameters: _,
clocks_for_past: _,
simulation: _, simulation: _,
} }
} }

View file

@ -131,7 +131,7 @@ impl<T: Type + PhantomConstValue> Index<T> for PhantomConstWithoutGenerics {
type Output = PhantomConst<T>; type Output = PhantomConst<T>;
fn index(&self, value: T) -> &Self::Output { fn index(&self, value: T) -> &Self::Output {
Interned::into_inner(PhantomConst::new(value.intern()).intern_sized()) Interned::into_inner(PhantomConst::new(&value).intern_sized())
} }
} }
@ -222,11 +222,26 @@ impl<T: ?Sized + PhantomConstValue> Memoize for PhantomConstCanonicalMemoize<T,
} }
impl<T: ?Sized + PhantomConstValue> PhantomConst<T> { impl<T: ?Sized + PhantomConstValue> PhantomConst<T> {
pub fn new(value: Interned<T>) -> Self { pub fn new_interned(value: Interned<T>) -> Self {
Self { Self {
value: LazyInterned::Interned(value), value: LazyInterned::Interned(value),
} }
} }
pub fn new_sized(value: T) -> Self
where
T: Clone,
{
Self::new_interned(value.intern_sized())
}
pub fn new(value: &T) -> Self {
Self::new_interned(value.intern())
}
pub fn new_deref<U: Intern + std::ops::Deref<Target = T>>(value: U) -> Self
where
T: ToOwned<Owned = U>,
{
Self::new_interned(value.intern_deref())
}
pub const fn new_lazy(v: &'static dyn LazyInternedTrait<T>) -> Self { pub const fn new_lazy(v: &'static dyn LazyInternedTrait<T>) -> Self {
Self { Self {
value: LazyInterned::new_lazy(v), value: LazyInterned::new_lazy(v),
@ -245,7 +260,7 @@ impl<T: ?Sized + PhantomConstValue> PhantomConst<T> {
if let Some(&retval) = <dyn Any>::downcast_ref::<PhantomConst>(&self) { if let Some(&retval) = <dyn Any>::downcast_ref::<PhantomConst>(&self) {
return retval; return retval;
} }
<PhantomConst>::new( <PhantomConst>::new_interned(
PhantomConstCanonicalMemoize::<T, false>(PhantomData).get_owned(self.get()), PhantomConstCanonicalMemoize::<T, false>(PhantomData).get_owned(self.get()),
) )
} }
@ -253,7 +268,7 @@ impl<T: ?Sized + PhantomConstValue> PhantomConst<T> {
if let Some(&retval) = <dyn Any>::downcast_ref::<Self>(&canonical_type) { if let Some(&retval) = <dyn Any>::downcast_ref::<Self>(&canonical_type) {
return retval; return retval;
} }
Self::new( Self::new_interned(
PhantomConstCanonicalMemoize::<T, true>(PhantomData).get_owned(canonical_type.get()), PhantomConstCanonicalMemoize::<T, true>(PhantomData).get_owned(canonical_type.get()),
) )
} }
@ -346,7 +361,9 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for PhantomConst<T> {
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
match SerdeType::<T>::deserialize(deserializer)? { match SerdeType::<T>::deserialize(deserializer)? {
SerdeCanonicalType::PhantomConst(SerdePhantomConst(value)) => Ok(Self::new(value)), SerdeCanonicalType::PhantomConst(SerdePhantomConst(value)) => {
Ok(Self::new_interned(value))
}
ty => Err(Error::invalid_value( ty => Err(Error::invalid_value(
serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), serde::de::Unexpected::Other(ty.as_serde_unexpected_str()),
&"a PhantomConst", &"a PhantomConst",

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information // See Notices.txt for copyright information
use crate::{intern::Intern, prelude::*}; use crate::prelude::*;
use ordered_float::NotNan; use ordered_float::NotNan;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -26,12 +26,9 @@ impl ClockInput {
); );
Self { Self {
clk: Clock, clk: Clock,
properties: PhantomConst::new( properties: PhantomConst::new_sized(ClockInputProperties {
ClockInputProperties { frequency: NotNan::new(frequency).expect("just checked"),
frequency: NotNan::new(frequency).expect("just checked"), }),
}
.intern_sized(),
),
} }
} }
pub fn frequency(self) -> f64 { pub fn frequency(self) -> f64 {

File diff suppressed because it is too large Load diff

View file

@ -28,12 +28,12 @@ use crate::{
ExternModuleSimulation, SimTrace, SimTraceKind, SimTraces, TraceArray, TraceAsyncReset, ExternModuleSimulation, SimTrace, SimTraceKind, SimTraces, TraceArray, TraceAsyncReset,
TraceBool, TraceBundle, TraceClock, TraceDecl, TraceEnumDiscriminant, TraceEnumWithFields, TraceBool, TraceBundle, TraceClock, TraceDecl, TraceEnumDiscriminant, TraceEnumWithFields,
TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId,
TraceMemoryLocation, TraceModule, TraceModuleIO, TraceReg, TraceSInt, TraceScalarId, TraceMemoryLocation, TraceModule, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt,
TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, TraceScalarId, TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire,
interpreter::{ interpreter::{
Insn, InsnField, InsnFieldKind, InsnFieldType, InsnOrLabel, Insns, InsnsBuilding, self, Insn, InsnField, InsnFieldKind, InsnFieldType, InsnOrLabel, Insns, InsnsBuilding,
InsnsBuildingDone, InsnsBuildingKind, Label, SmallUInt, StatePartArrayIndex, InsnsBuildingDone, InsnsBuildingKind, Label, PrefixLinesWrapper, SmallUInt,
StatePartArrayIndexed, StatePartArrayIndex, StatePartArrayIndexed,
parts::{ parts::{
MemoryData, SlotDebugData, StatePartIndex, StatePartIndexRange, StatePartKind, MemoryData, SlotDebugData, StatePartIndex, StatePartIndexRange, StatePartKind,
StatePartKindBigSlots, StatePartKindMemories, StatePartKindSimOnlySlots, StatePartKindBigSlots, StatePartKindMemories, StatePartKindSimOnlySlots,
@ -82,19 +82,73 @@ pub(crate) struct CompiledBundleField {
pub(crate) ty: CompiledTypeLayout<CanonicalType>, pub(crate) ty: CompiledTypeLayout<CanonicalType>,
} }
impl CompiledBundleField {
fn with_prefixed_debug_names(self, prefix: &str) -> Self {
let Self { offset, ty } = self;
Self {
offset,
ty: ty.with_prefixed_debug_names(prefix),
}
}
fn with_anonymized_debug_info(self) -> Self {
let Self { offset, ty } = self;
Self {
offset,
ty: ty.with_anonymized_debug_info(),
}
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub(crate) enum CompiledTypeLayoutBody { pub(crate) enum CompiledTypeLayoutBody {
Scalar, Scalar,
PhantomConst,
Array { Array {
/// debug names are ignored, use parent's layout instead /// always has at least one element even for zero-sized arrays
element: Interned<CompiledTypeLayout<CanonicalType>>, elements_non_empty: Interned<[CompiledTypeLayout<CanonicalType>]>,
}, },
Bundle { Bundle {
/// debug names are ignored, use parent's layout instead
fields: Interned<[CompiledBundleField]>, fields: Interned<[CompiledBundleField]>,
}, },
} }
impl CompiledTypeLayoutBody {
fn with_prefixed_debug_names(self, prefix: &str) -> Self {
match self {
CompiledTypeLayoutBody::Scalar | CompiledTypeLayoutBody::PhantomConst => self,
CompiledTypeLayoutBody::Array { elements_non_empty } => CompiledTypeLayoutBody::Array {
elements_non_empty: elements_non_empty
.iter()
.map(|element| element.with_prefixed_debug_names(prefix))
.collect(),
},
CompiledTypeLayoutBody::Bundle { fields } => CompiledTypeLayoutBody::Bundle {
fields: fields
.iter()
.map(|field| field.with_prefixed_debug_names(prefix))
.collect(),
},
}
}
fn with_anonymized_debug_info(self) -> Self {
match self {
CompiledTypeLayoutBody::Scalar | CompiledTypeLayoutBody::PhantomConst => self,
CompiledTypeLayoutBody::Array { elements_non_empty } => CompiledTypeLayoutBody::Array {
elements_non_empty: elements_non_empty
.iter()
.map(|element| element.with_anonymized_debug_info())
.collect(),
},
CompiledTypeLayoutBody::Bundle { fields } => CompiledTypeLayoutBody::Bundle {
fields: fields
.iter()
.map(|field| field.with_anonymized_debug_info())
.collect(),
},
}
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub(crate) struct CompiledTypeLayout<T: Type> { pub(crate) struct CompiledTypeLayout<T: Type> {
pub(crate) ty: T, pub(crate) ty: T,
@ -108,7 +162,7 @@ impl<T: Type> CompiledTypeLayout<T> {
Self { Self {
ty, ty,
layout: layout.with_prefixed_debug_names(prefix), layout: layout.with_prefixed_debug_names(prefix),
body, body: body.with_prefixed_debug_names(prefix),
} }
} }
fn with_anonymized_debug_info(self) -> Self { fn with_anonymized_debug_info(self) -> Self {
@ -116,7 +170,7 @@ impl<T: Type> CompiledTypeLayout<T> {
Self { Self {
ty, ty,
layout: layout.with_anonymized_debug_info(), layout: layout.with_anonymized_debug_info(),
body, body: body.with_anonymized_debug_info(),
} }
} }
fn get(ty: T) -> Self { fn get(ty: T) -> Self {
@ -151,28 +205,29 @@ impl<T: Type> CompiledTypeLayout<T> {
} }
CanonicalType::Array(array) => { CanonicalType::Array(array) => {
let mut layout = TypeLayout::empty(); let mut layout = TypeLayout::empty();
let element = CompiledTypeLayout::get(array.element()).intern_sized(); let element = CompiledTypeLayout::get(array.element());
let mut elements_non_empty = vec![];
for index in 0..array.len() { for index in 0..array.len() {
layout.allocate( let element = element.with_prefixed_debug_names(&format!("[{index}]"));
&element layout.allocate(&element.layout);
.layout elements_non_empty.push(element);
.with_prefixed_debug_names(&format!("[{index}]")), }
); if array.is_empty() {
elements_non_empty.push(element.with_prefixed_debug_names("[<none>]"));
} }
CompiledTypeLayout { CompiledTypeLayout {
ty: *input, ty: *input,
layout: layout.into(), layout: layout.into(),
body: CompiledTypeLayoutBody::Array { element }, body: CompiledTypeLayoutBody::Array {
} elements_non_empty: elements_non_empty.intern_deref(),
} },
CanonicalType::PhantomConst(_) => {
let unit_layout = CompiledTypeLayout::get(());
CompiledTypeLayout {
ty: *input,
layout: unit_layout.layout,
body: unit_layout.body,
} }
} }
CanonicalType::PhantomConst(_) => CompiledTypeLayout {
ty: *input,
layout: TypeLayout::empty(),
body: CompiledTypeLayoutBody::PhantomConst,
},
CanonicalType::Bundle(bundle) => { CanonicalType::Bundle(bundle) => {
let mut layout = TypeLayout::empty(); let mut layout = TypeLayout::empty();
let fields = bundle let fields = bundle
@ -184,13 +239,9 @@ impl<T: Type> CompiledTypeLayout<T> {
flipped: _, flipped: _,
ty, ty,
}| { }| {
let ty = CompiledTypeLayout::get(*ty); let ty = CompiledTypeLayout::get(*ty)
let offset = layout .with_prefixed_debug_names(&format!(".{name}"));
.allocate( let offset = layout.allocate(&ty.layout).start();
&ty.layout
.with_prefixed_debug_names(&format!(".{name}")),
)
.start();
CompiledBundleField { offset, ty } CompiledBundleField { offset, ty }
}, },
) )
@ -273,6 +324,39 @@ impl<T: Type> CompiledValue<T> {
} }
} }
pub(crate) struct DebugCompiledValueStateAsMap<'a> {
pub(crate) compiled_value: CompiledValue<CanonicalType>,
pub(crate) state_layout: &'a interpreter::parts::StateLayout<InsnsBuildingDone>,
pub(crate) state: &'a interpreter::State,
}
impl fmt::Debug for DebugCompiledValueStateAsMap<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use fmt::Write;
if self.compiled_value.range.is_empty() {
return f.write_str("{}");
}
writeln!(f, "{{")?;
let mut f = PrefixLinesWrapper::new(f, true, " ");
macro_rules! debug_fmt {
(
type_plural_fields = [$($type_plural_field:ident,)*];
) => {
$(for slot in self.compiled_value.range.$type_plural_field.iter() {
slot.debug_fmt(&mut f, ":", " ", " ", "", Some(self.state_layout), Some(self.state))?;
writeln!(f, ",")?;
})*
};
}
get_state_part_kinds! {
debug_fmt! {
type_plural_fields;
}
}
write!(f.into_inner(), "}}")
}
}
impl CompiledValue<Bundle> { impl CompiledValue<Bundle> {
fn field_by_index(self, field_index: usize) -> CompiledValue<CanonicalType> { fn field_by_index(self, field_index: usize) -> CompiledValue<CanonicalType> {
self.map(|layout, range| { self.map(|layout, range| {
@ -301,10 +385,13 @@ impl CompiledValue<Bundle> {
impl CompiledValue<Array> { impl CompiledValue<Array> {
pub(crate) fn element(self, index: usize) -> CompiledValue<CanonicalType> { pub(crate) fn element(self, index: usize) -> CompiledValue<CanonicalType> {
self.map(|layout, range| { self.map(|layout, range| {
let CompiledTypeLayoutBody::Array { element } = layout.body else { let CompiledTypeLayoutBody::Array { elements_non_empty } = layout.body else {
unreachable!(); unreachable!();
}; };
(*element, range.index_array(element.layout.len(), index)) (
elements_non_empty[index],
range.index_array(elements_non_empty[index].layout.len(), index),
)
}) })
} }
fn element_dyn( fn element_dyn(
@ -557,10 +644,11 @@ impl CompiledExpr<Array> {
self, self,
index_slot: StatePartIndex<StatePartKindSmallSlots>, index_slot: StatePartIndex<StatePartKindSmallSlots>,
) -> CompiledExpr<CanonicalType> { ) -> CompiledExpr<CanonicalType> {
let CompiledTypeLayoutBody::Array { element } = self.static_part.layout.body else { let CompiledTypeLayoutBody::Array { elements_non_empty } = self.static_part.layout.body
else {
unreachable!(); unreachable!();
}; };
let stride = element.layout.len(); let stride = elements_non_empty[0].layout.len();
let indexes = self.indexes.join(TypeArrayIndex::from_parts( let indexes = self.indexes.join(TypeArrayIndex::from_parts(
index_slot, index_slot,
self.static_part.layout.ty.len(), self.static_part.layout.ty.len(),
@ -568,10 +656,10 @@ impl CompiledExpr<Array> {
)); ));
CompiledExpr { CompiledExpr {
static_part: self.static_part.map(|layout, range| { static_part: self.static_part.map(|layout, range| {
let CompiledTypeLayoutBody::Array { element } = layout.body else { let CompiledTypeLayoutBody::Array { elements_non_empty } = layout.body else {
unreachable!(); unreachable!();
}; };
(*element, range.index_array(stride, 0)) (elements_non_empty[0], range.index_array(stride, 0))
}), }),
indexes, indexes,
} }
@ -1550,6 +1638,13 @@ struct ClockTrigger {
source_location: SourceLocation, source_location: SourceLocation,
} }
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub(crate) struct ExternModuleClockForPast {
pub(crate) clock_for_past: CompiledValue<Clock>,
pub(crate) current_to_past_map:
Interned<[(CompiledValue<CanonicalType>, CompiledValue<CanonicalType>)]>,
}
#[derive(Debug)] #[derive(Debug)]
struct Register { struct Register {
value: CompiledValue<CanonicalType>, value: CompiledValue<CanonicalType>,
@ -1637,7 +1732,9 @@ impl<T> fmt::Debug for DebugOpaque<T> {
pub(crate) struct CompiledExternModule { pub(crate) struct CompiledExternModule {
pub(crate) module_io_targets: Interned<[Target]>, pub(crate) module_io_targets: Interned<[Target]>,
pub(crate) module_io: Interned<[CompiledValue<CanonicalType>]>, pub(crate) module_io: Interned<[CompiledValue<CanonicalType>]>,
pub(crate) clocks_for_past: Interned<[ExternModuleClockForPast]>,
pub(crate) simulation: ExternModuleSimulation, pub(crate) simulation: ExternModuleSimulation,
pub(crate) debug_name: Interned<str>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -1681,18 +1778,23 @@ macro_rules! impl_compiler {
instantiated_module: InstantiatedModule, instantiated_module: InstantiatedModule,
target: MakeTraceDeclTarget, target: MakeTraceDeclTarget,
source_location: SourceLocation, source_location: SourceLocation,
empty_kind: impl FnOnce() -> SimTraceKind,
$($type_singular_field: impl FnOnce(StatePartIndex<$type_kind>) -> SimTraceKind,)* $($type_singular_field: impl FnOnce(StatePartIndex<$type_kind>) -> SimTraceKind,)*
) -> TraceLocation { ) -> TraceLocation {
match target { match target {
MakeTraceDeclTarget::Expr(target) => { MakeTraceDeclTarget::Expr(target) => {
let compiled_value = self.compile_expr(instantiated_module, target); let compiled_value = self.compile_expr(instantiated_module, target);
let compiled_value = self.compiled_expr_to_value(compiled_value, source_location); let compiled_value = self.compiled_expr_to_value(compiled_value, source_location);
TraceLocation::Scalar(self.new_sim_trace(match compiled_value.range.len().as_single() { if compiled_value.range.is_empty() {
$(Some(TypeLenSingle::$type_singular_variant) => { TraceLocation::Scalar(self.new_sim_trace(empty_kind()))
$type_singular_field(compiled_value.range.$type_plural_field.start) } else {
})* TraceLocation::Scalar(self.new_sim_trace(match compiled_value.range.len().as_single() {
None => unreachable!(), $(Some(TypeLenSingle::$type_singular_variant) => {
})) $type_singular_field(compiled_value.range.$type_plural_field.start)
})*
None => unreachable!(),
}))
}
} }
MakeTraceDeclTarget::Memory { MakeTraceDeclTarget::Memory {
id, id,
@ -1723,9 +1825,10 @@ macro_rules! impl_compiler {
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallUInt { index, ty }, |index| SimTraceKind::SmallUInt { index, ty },
|index| SimTraceKind::BigUInt { index, ty }, |index| SimTraceKind::BigUInt { index, ty },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
ty, ty,
@ -1737,9 +1840,10 @@ macro_rules! impl_compiler {
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallSInt { index, ty }, |index| SimTraceKind::SmallSInt { index, ty },
|index| SimTraceKind::BigSInt { index, ty }, |index| SimTraceKind::BigSInt { index, ty },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
ty, ty,
@ -1751,9 +1855,10 @@ macro_rules! impl_compiler {
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallBool { index }, |index| SimTraceKind::SmallBool { index },
|index| SimTraceKind::BigBool { index }, |index| SimTraceKind::BigBool { index },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
flow, flow,
@ -1798,15 +1903,16 @@ macro_rules! impl_compiler {
} }
.into() .into()
} }
CanonicalType::Bundle(_) | CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::Bundle(_) => unreachable!(),
CanonicalType::AsyncReset(_) => TraceAsyncReset { CanonicalType::AsyncReset(_) => TraceAsyncReset {
location: self.make_trace_scalar_helper( location: self.make_trace_scalar_helper(
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallAsyncReset { index }, |index| SimTraceKind::SmallAsyncReset { index },
|index| SimTraceKind::BigAsyncReset { index }, |index| SimTraceKind::BigAsyncReset { index },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
flow, flow,
@ -1817,9 +1923,10 @@ macro_rules! impl_compiler {
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallSyncReset { index }, |index| SimTraceKind::SmallSyncReset { index },
|index| SimTraceKind::BigSyncReset { index }, |index| SimTraceKind::BigSyncReset { index },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
flow, flow,
@ -1831,21 +1938,38 @@ macro_rules! impl_compiler {
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|| unreachable!(),
|index| SimTraceKind::SmallClock { index }, |index| SimTraceKind::SmallClock { index },
|index| SimTraceKind::BigClock { index }, |index| SimTraceKind::BigClock { index },
|_| unreachable!(""), |_| unreachable!(),
), ),
name, name,
flow, flow,
} }
.into(), .into(),
CanonicalType::PhantomConst(ty) => TracePhantomConst {
location: self.make_trace_scalar_helper(
instantiated_module,
target,
source_location,
|| SimTraceKind::PhantomConst { ty },
|_| unreachable!(),
|_| unreachable!(),
|_| unreachable!(),
),
name,
ty,
flow,
}
.into(),
CanonicalType::DynSimOnly(ty) => TraceSimOnly { CanonicalType::DynSimOnly(ty) => TraceSimOnly {
location: self.make_trace_scalar_helper( location: self.make_trace_scalar_helper(
instantiated_module, instantiated_module,
target, target,
source_location, source_location,
|_| unreachable!(""), || unreachable!(),
|_| unreachable!(""), |_| unreachable!(),
|_| unreachable!(),
|index| SimTraceKind::SimOnly { index, ty }, |index| SimTraceKind::SimOnly { index, ty },
), ),
name, name,
@ -2295,16 +2419,10 @@ impl Compiler {
| CanonicalType::SyncReset(_) | CanonicalType::SyncReset(_)
| CanonicalType::Reset(_) | CanonicalType::Reset(_)
| CanonicalType::Clock(_) | CanonicalType::Clock(_)
| CanonicalType::DynSimOnly(_) => { | CanonicalType::DynSimOnly(_)
| CanonicalType::PhantomConst(_) => {
self.make_trace_scalar(instantiated_module, target, name, source_location) self.make_trace_scalar(instantiated_module, target, name, source_location)
} }
CanonicalType::PhantomConst(_) => TraceBundle {
name,
fields: Interned::default(),
ty: Bundle::new(Interned::default()),
flow: target.flow(),
}
.into(),
} }
} }
fn make_trace_decl( fn make_trace_decl(
@ -3896,18 +4014,15 @@ impl Compiler {
self.enum_discriminants.insert(enum_value, retval); self.enum_discriminants.insert(enum_value, retval);
retval retval
} }
fn compile_stmt_reg<R: ResetType>( fn compile_reg<R: ResetType>(
&mut self, &mut self,
stmt_reg: StmtReg<R>, clk: CompiledValue<Clock>,
reset_and_init: Option<(Expr<R>, CompiledValue<CanonicalType>)>,
source_location: SourceLocation,
instantiated_module: InstantiatedModule, instantiated_module: InstantiatedModule,
value: CompiledValue<CanonicalType>, value: CompiledValue<CanonicalType>,
) { ) {
let StmtReg { annotations, reg } = stmt_reg; let clk = self.compile_clock(clk, source_location);
let clk = self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().clk));
let clk = self
.compiled_expr_to_value(clk, reg.source_location())
.map_ty(Clock::from_canonical);
let clk = self.compile_clock(clk, reg.source_location());
struct Dispatch; struct Dispatch;
impl ResetTypeDispatch for Dispatch { impl ResetTypeDispatch for Dispatch {
type Input<T: ResetType> = (); type Input<T: ResetType> = ();
@ -3926,18 +4041,15 @@ impl Compiler {
true true
} }
} }
let reset = if let Some(init) = reg.init() { let reset = if let Some((rst_expr, init)) = reset_and_init {
let init = self.compile_expr(instantiated_module, init); let rst = self.compile_expr(instantiated_module, Expr::canonical(rst_expr));
let init = self.compiled_expr_to_value(init, reg.source_location()); let rst = self.compiled_expr_to_value(rst, source_location);
let rst = let rst = self.compiled_value_bool_dest_is_small(rst, source_location);
self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().rst));
let rst = self.compiled_expr_to_value(rst, reg.source_location());
let rst = self.compiled_value_bool_dest_is_small(rst, reg.source_location());
let is_async = R::dispatch((), Dispatch); let is_async = R::dispatch((), Dispatch);
if is_async { if is_async {
let cond = Expr::canonical(reg.clock_domain().rst.cast_to(Bool)); let cond = Expr::canonical(rst_expr.cast_to(Bool));
let cond = self.compile_expr(instantiated_module, cond); let cond = self.compile_expr(instantiated_module, cond);
let cond = self.compiled_expr_to_value(cond, reg.source_location()); let cond = self.compiled_expr_to_value(cond, source_location);
let cond = cond.map_ty(Bool::from_canonical); let cond = cond.map_ty(Bool::from_canonical);
// write to the register's current value since asynchronous reset is combinational // write to the register's current value since asynchronous reset is combinational
let lhs = CompiledValue { let lhs = CompiledValue {
@ -3949,12 +4061,12 @@ impl Compiler {
self.compile_simple_connect( self.compile_simple_connect(
[Cond { [Cond {
body: CondBody::IfTrue { cond }, body: CondBody::IfTrue { cond },
source_location: reg.source_location(), source_location: source_location,
}] }]
.intern_slice(), .intern_slice(),
lhs, lhs,
init, init,
reg.source_location(), source_location,
); );
} }
Some(RegisterReset { Some(RegisterReset {
@ -3969,9 +4081,33 @@ impl Compiler {
value, value,
clk_triggered: clk.clk_triggered, clk_triggered: clk.clk_triggered,
reset, reset,
source_location: reg.source_location(), source_location,
}); });
} }
fn compile_stmt_reg<R: ResetType>(
&mut self,
stmt_reg: StmtReg<R>,
instantiated_module: InstantiatedModule,
value: CompiledValue<CanonicalType>,
) {
let StmtReg { annotations, reg } = stmt_reg;
let clk = self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().clk));
let clk = self
.compiled_expr_to_value(clk, reg.source_location())
.map_ty(Clock::from_canonical);
let reset_and_init = reg.init().map(|init| {
let init = self.compile_expr(instantiated_module, init);
let init = self.compiled_expr_to_value(init, reg.source_location());
(reg.clock_domain().rst, init)
});
self.compile_reg(
clk,
reset_and_init,
reg.source_location(),
instantiated_module,
value,
);
}
fn compile_declaration( fn compile_declaration(
&mut self, &mut self,
declaration: StmtDeclaration, declaration: StmtDeclaration,
@ -4237,24 +4373,24 @@ impl Compiler {
insns.push(end_label.into()); insns.push(end_label.into());
} }
} }
CompiledTypeLayoutBody::Array { element } => { CompiledTypeLayoutBody::Array { elements_non_empty } => {
let CompiledTypeLayoutBody::Array { let CompiledTypeLayoutBody::Array {
element: mask_element, elements_non_empty: mask_elements_non_empty,
} = mask_layout.body } = mask_layout.body
else { else {
unreachable!(); unreachable!();
}; };
let ty = <Array>::from_canonical(data_layout.ty); let ty = <Array>::from_canonical(data_layout.ty);
let element_bit_width = ty.element().bit_width(); let element_bit_width = ty.element().bit_width();
let element_size = element.layout.len(); let element_size = elements_non_empty[0].layout.len();
let mask_element_size = mask_element.layout.len(); let mask_element_size = mask_elements_non_empty[0].layout.len();
for element_index in 0..ty.len() { for element_index in 0..ty.len() {
self.compile_memory_port_rw_helper( self.compile_memory_port_rw_helper(
memory, memory,
stride, stride,
start, start,
*element, elements_non_empty[element_index],
*mask_element, mask_elements_non_empty[element_index],
read.as_mut().map( read.as_mut().map(
|MemoryPortReadInsns { |MemoryPortReadInsns {
addr, addr,
@ -4293,6 +4429,7 @@ impl Compiler {
start += element_bit_width; start += element_bit_width;
} }
} }
CompiledTypeLayoutBody::PhantomConst => {}
CompiledTypeLayoutBody::Bundle { fields } => { CompiledTypeLayoutBody::Bundle { fields } => {
let CompiledTypeLayoutBody::Bundle { let CompiledTypeLayoutBody::Bundle {
fields: mask_fields, fields: mask_fields,
@ -4860,6 +4997,88 @@ impl Compiler {
} }
} }
} }
fn compile_extern_module_clock_for_past(
&mut self,
instantiated_module: InstantiatedModule,
clock_for_past: Target,
) -> ExternModuleClockForPast {
let clock_for_past = TargetInInstantiatedModule {
instantiated_module,
target: clock_for_past,
};
let clock_for_past = self
.compile_value(clock_for_past)
.map_ty(Clock::from_canonical);
let clock_for_past_debug_name = match clock_for_past
.range
.len()
.as_single()
.expect("Clock is a single slot")
{
TypeLenSingle::BigSlot => {
self.insns
.state_layout
.ty
.big_slots
.debug_data(clock_for_past.range.start().big_slots)
.name
}
TypeLenSingle::SmallSlot => {
self.insns
.state_layout
.ty
.small_slots
.debug_data(clock_for_past.range.start().small_slots)
.name
}
TypeLenSingle::SimOnlySlot => {
unreachable!()
}
};
let module_prefix = format!("{instantiated_module:?}.");
let trimmed_clock_for_past_debug_name = clock_for_past_debug_name
.strip_prefix(&module_prefix)
.unwrap_or(&clock_for_past_debug_name);
let current_to_past_map = instantiated_module
.leaf_module()
.module_io()
.iter()
.map(
|&AnnotatedModuleIO {
annotations: _,
module_io,
}| {
let target_base = TargetBase::from(module_io);
let current = self.compile_value(TargetInInstantiatedModule {
instantiated_module,
target: target_base.into(),
});
let unprefixed_layout = CompiledTypeLayout::get(module_io.ty());
let past_layout = unprefixed_layout.with_prefixed_debug_names(&format!(
"{module_prefix}{:?}$past({trimmed_clock_for_past_debug_name})",
target_base.target_name(),
));
let past = CompiledValue {
range: self.insns.allocate_variable(&past_layout.layout),
layout: past_layout,
write: Some((current.layout, current.range)),
};
self.compile_reg::<SyncReset>(
clock_for_past,
None,
module_io.source_location(),
instantiated_module,
past,
);
(current, past)
},
)
.collect();
ExternModuleClockForPast {
clock_for_past,
current_to_past_map,
}
}
fn compile_module(&mut self, module: Interned<InstantiatedModule>) -> &CompiledModule { fn compile_module(&mut self, module: Interned<InstantiatedModule>) -> &CompiledModule {
let mut trace_decls = Vec::new(); let mut trace_decls = Vec::new();
let module_io = module let module_io = module
@ -4888,6 +5107,7 @@ impl Compiler {
ModuleBody::Extern(ExternModuleBody { ModuleBody::Extern(ExternModuleBody {
verilog_name: _, verilog_name: _,
parameters: _, parameters: _,
clocks_for_past,
simulation, simulation,
}) => { }) => {
let Some(simulation) = simulation else { let Some(simulation) = simulation else {
@ -4904,10 +5124,18 @@ impl Compiler {
Target::from(*simulation.sim_io_to_generator_map[&v.module_io.intern()]) Target::from(*simulation.sim_io_to_generator_map[&v.module_io.intern()])
}) })
.collect(); .collect();
let clocks_for_past = clocks_for_past
.iter()
.map(|clock_for_past| {
self.compile_extern_module_clock_for_past(*module, *clock_for_past)
})
.collect();
self.extern_modules.push(CompiledExternModule { self.extern_modules.push(CompiledExternModule {
module_io_targets, module_io_targets,
module_io, module_io,
clocks_for_past,
simulation, simulation,
debug_name: format!("{module:?}").intern_deref(),
}); });
} }
} }

View file

@ -196,13 +196,27 @@ impl fmt::Debug for Insn {
} }
} }
struct PrefixLinesWrapper<'a, W> { pub(crate) struct PrefixLinesWrapper<'a, W> {
writer: W, writer: W,
at_beginning_of_line: bool, at_beginning_of_line: bool,
blank_line_prefix: &'a str, blank_line_prefix: &'a str,
line_prefix: &'a str, line_prefix: &'a str,
} }
impl<'a, W> PrefixLinesWrapper<'a, W> {
pub(crate) fn new(writer: W, at_beginning_of_line: bool, line_prefix: &'a str) -> Self {
Self {
writer,
at_beginning_of_line,
blank_line_prefix: line_prefix.trim_end(),
line_prefix,
}
}
pub(crate) fn into_inner(self) -> W {
self.writer
}
}
impl<T: fmt::Write> fmt::Write for PrefixLinesWrapper<'_, T> { impl<T: fmt::Write> fmt::Write for PrefixLinesWrapper<'_, T> {
fn write_str(&mut self, input: &str) -> fmt::Result { fn write_str(&mut self, input: &str) -> fmt::Result {
for part in input.split_inclusive('\n') { for part in input.split_inclusive('\n') {
@ -239,12 +253,7 @@ impl Insn {
if fields.len() == 0 { if fields.len() == 0 {
return Ok(()); return Ok(());
} }
let mut f = PrefixLinesWrapper { let mut f = PrefixLinesWrapper::new(f, false, " ");
writer: f,
at_beginning_of_line: false,
blank_line_prefix: "",
line_prefix: " ",
};
writeln!(f, " {{")?; writeln!(f, " {{")?;
for (field_name, field) in fields { for (field_name, field) in fields {
write!(f, "{field_name}: ")?; write!(f, "{field_name}: ")?;
@ -320,7 +329,7 @@ impl Insn {
} }
writeln!(f, ",")?; writeln!(f, ",")?;
} }
write!(f.writer, "}}") write!(f.into_inner(), "}}")
} }
} }

View file

@ -9,7 +9,7 @@ use crate::{
Insn, InsnsBuilding, InsnsBuildingDone, InsnsBuildingKind, PrefixLinesWrapper, Insn, InsnsBuilding, InsnsBuildingDone, InsnsBuildingKind, PrefixLinesWrapper,
SmallSInt, SmallUInt, State, SmallSInt, SmallUInt, State,
}, },
value::{DynSimOnlyValue, DynSimOnly}, value::{DynSimOnly, DynSimOnlyValue},
}, },
ty::CanonicalType, ty::CanonicalType,
util::{chain, const_str_cmp}, util::{chain, const_str_cmp},
@ -435,12 +435,7 @@ impl<K: StatePartKind> StatePartIndex<K> {
if state.is_some() || debug_data.is_some() { if state.is_some() || debug_data.is_some() {
f.write_str(comment_start)?; f.write_str(comment_start)?;
} }
let mut f = PrefixLinesWrapper { let mut f = PrefixLinesWrapper::new(f, false, comment_line_start);
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 { if let Some(state) = state {
f.write_str("(")?; f.write_str("(")?;
K::debug_fmt_state_value(state, *self, &mut f)?; K::debug_fmt_state_value(state, *self, &mut f)?;
@ -453,7 +448,7 @@ impl<K: StatePartKind> StatePartIndex<K> {
write!(f, "{debug_data:?}")?; write!(f, "{debug_data:?}")?;
} }
if state.is_some() || debug_data.is_some() { if state.is_some() || debug_data.is_some() {
f.writer.write_str(comment_end)?; f.into_inner().write_str(comment_end)?;
} }
Ok(()) Ok(())
} }

View file

@ -23,10 +23,10 @@ use bitvec::{slice::BitSlice, vec::BitVec};
use hashbrown::hash_map::Entry; use hashbrown::hash_map::Entry;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
use std::{ use std::{
borrow::Cow, borrow::{Borrow, BorrowMut, Cow},
fmt::{self, Write}, fmt::{self, Write},
hash::{BuildHasher, Hash, Hasher, RandomState}, hash::{BuildHasher, Hash, Hasher, RandomState},
ops::{Deref, DerefMut}, ops::{Deref, DerefMut, Index, IndexMut},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@ -364,6 +364,74 @@ impl<T: Type> ToExpr for SimValue<T> {
} }
} }
impl<T: Type, Len: Size, I> Index<I> for SimValue<ArrayType<T, Len>>
where
[SimValue<T>]: Index<I>,
{
type Output = <[SimValue<T>] as Index<I>>::Output;
fn index(&self, index: I) -> &Self::Output {
(**self).borrow().index(index)
}
}
impl<T: Type, Len: Size, I> IndexMut<I> for SimValue<ArrayType<T, Len>>
where
[SimValue<T>]: IndexMut<I>,
{
fn index_mut(&mut self, index: I) -> &mut Self::Output {
(**self).borrow_mut().index_mut(index)
}
}
impl<T: Type, Len: Size> SimValue<ArrayType<T, Len>> {
pub fn iter(&self) -> std::slice::Iter<'_, SimValue<T>> {
(**self).borrow().iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, SimValue<T>> {
(**self).borrow_mut().iter_mut()
}
}
impl<T: Type, Len: Size> IntoIterator for SimValue<ArrayType<T, Len>> {
type Item = SimValue<T>;
type IntoIter = std::vec::IntoIter<SimValue<T>>;
fn into_iter(self) -> Self::IntoIter {
Vec::into_iter(Self::into_value(self).into())
}
}
impl<'a, T: Type, Len: Size> IntoIterator for &'a SimValue<ArrayType<T, Len>> {
type Item = &'a SimValue<T>;
type IntoIter = std::slice::Iter<'a, SimValue<T>>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T: Type, Len: Size> IntoIterator for &'a mut SimValue<ArrayType<T, Len>> {
type Item = &'a mut SimValue<T>;
type IntoIter = std::slice::IterMut<'a, SimValue<T>>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T: Type, Len: Size> AsRef<[SimValue<T>]> for SimValue<ArrayType<T, Len>> {
fn as_ref(&self) -> &[SimValue<T>] {
(**self).as_ref()
}
}
impl<T: Type, Len: Size> AsMut<[SimValue<T>]> for SimValue<ArrayType<T, Len>> {
fn as_mut(&mut self) -> &mut [SimValue<T>] {
(**self).as_mut()
}
}
pub trait SimValuePartialEq<T: Type = Self>: Type { pub trait SimValuePartialEq<T: Type = Self>: Type {
#[track_caller] #[track_caller]
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<T>) -> bool; fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<T>) -> bool;
@ -394,6 +462,30 @@ impl SimValuePartialEq<Bool> for Bool {
} }
} }
impl SimValuePartialEq for Clock {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
impl SimValuePartialEq for Reset {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
impl SimValuePartialEq for SyncReset {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
impl SimValuePartialEq for AsyncReset {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
pub trait ToSimValue: ToSimValueWithType<<Self as ToSimValue>::Type> { pub trait ToSimValue: ToSimValueWithType<<Self as ToSimValue>::Type> {
type Type: Type; type Type: Type;
@ -1302,6 +1394,20 @@ impl<T: SimOnlyValueTrait> ToSimValue for SimOnlyValue<T> {
} }
} }
impl SimValuePartialEq for DynSimOnly {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
impl<T: SimOnlyValueTrait + PartialEq<U>, U: SimOnlyValueTrait> SimValuePartialEq<SimOnly<U>>
for SimOnly<T>
{
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<SimOnly<U>>) -> bool {
***this == ***other
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -206,9 +206,25 @@ impl<T: SimOnlyValueTrait> Default for SimOnly<T> {
} }
/// a value that can only be used in a Fayalite simulation, it can't be converted to FIRRTL /// a value that can only be used in a Fayalite simulation, it can't be converted to FIRRTL
#[derive(Clone, Eq, PartialEq, Hash, Default, PartialOrd, Ord)] #[derive(Clone, Eq, Hash, Default, Ord)]
pub struct SimOnlyValue<T: SimOnlyValueTrait>(Rc<T>); pub struct SimOnlyValue<T: SimOnlyValueTrait>(Rc<T>);
impl<T: SimOnlyValueTrait + PartialEq<U>, U: SimOnlyValueTrait> PartialEq<SimOnlyValue<U>>
for SimOnlyValue<T>
{
fn eq(&self, other: &SimOnlyValue<U>) -> bool {
<T as PartialEq<U>>::eq(self, other)
}
}
impl<T: SimOnlyValueTrait + PartialOrd<U>, U: SimOnlyValueTrait> PartialOrd<SimOnlyValue<U>>
for SimOnlyValue<T>
{
fn partial_cmp(&self, other: &SimOnlyValue<U>) -> Option<std::cmp::Ordering> {
<T as PartialOrd<U>>::partial_cmp(self, other)
}
}
impl<T: SimOnlyValueTrait> SimOnlyValue<T> { impl<T: SimOnlyValueTrait> SimOnlyValue<T> {
pub fn with_dyn_ref<F: FnOnce(&DynSimOnlyValue) -> R, R>(&self, f: F) -> R { pub fn with_dyn_ref<F: FnOnce(&DynSimOnlyValue) -> R, R>(&self, f: F) -> R {
// Safety: creating a copied `Rc<T>` is safe as long as the copy isn't dropped and isn't changed // Safety: creating a copied `Rc<T>` is safe as long as the copy isn't dropped and isn't changed

View file

@ -6,12 +6,14 @@ use crate::{
expr::Flow, expr::Flow,
int::UInt, int::UInt,
intern::{Intern, Interned}, intern::{Intern, Interned},
prelude::PhantomConst,
sim::{ sim::{
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl, TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance,
TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule,
TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSimOnly, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, TraceScalar, TraceScalarId,
TraceSyncReset, TraceUInt, TraceWire, TraceWriter, TraceWriterDecls, TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, TraceWriter,
TraceWriterDecls,
time::{SimDuration, SimInstant}, time::{SimDuration, SimInstant},
value::DynSimOnlyValue, value::DynSimOnlyValue,
}, },
@ -283,6 +285,7 @@ impl WriteTrace for TraceScalar {
Self::Clock(v) => v.write_trace(writer, arg), Self::Clock(v) => v.write_trace(writer, arg),
Self::SyncReset(v) => v.write_trace(writer, arg), Self::SyncReset(v) => v.write_trace(writer, arg),
Self::AsyncReset(v) => v.write_trace(writer, arg), Self::AsyncReset(v) => v.write_trace(writer, arg),
Self::PhantomConst(v) => v.write_trace(writer, arg),
Self::SimOnly(v) => v.write_trace(writer, arg), Self::SimOnly(v) => v.write_trace(writer, arg),
} }
} }
@ -549,6 +552,33 @@ impl WriteTrace for TraceAsyncReset {
} }
} }
impl WriteTrace for TracePhantomConst {
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,
scope,
} = arg.in_type();
let Self {
location,
name,
ty: _,
flow: _,
} = self;
write_vcd_var(
properties,
MemoryElementPartBody::Scalar,
writer,
"string",
1,
location,
scope.new_identifier(name),
)
}
}
impl WriteTrace for TraceSimOnly { impl WriteTrace for TraceSimOnly {
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> { fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
let ArgInType { let ArgInType {
@ -1091,6 +1121,16 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize()) write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize())
} }
fn set_signal_phantom_const(
&mut self,
id: TraceScalarId,
ty: PhantomConst,
) -> Result<(), Self::Error> {
// avoid multi-line strings because GTKWave can't display them properly:
// https://github.com/gtkwave/gtkwave/issues/460
write_string_value_change(&mut self.writer, format_args!("{ty:?}"), id.as_usize())
}
fn set_signal_sim_only_value( fn set_signal_sim_only_value(
&mut self, &mut self,
id: TraceScalarId, id: TraceScalarId,

View file

@ -127,7 +127,7 @@ impl From<SerdeCanonicalType> for CanonicalType {
SerdeCanonicalType::Reset => Self::Reset(Reset), SerdeCanonicalType::Reset => Self::Reset(Reset),
SerdeCanonicalType::Clock => Self::Clock(Clock), SerdeCanonicalType::Clock => Self::Clock(Clock),
SerdeCanonicalType::PhantomConst(value) => { SerdeCanonicalType::PhantomConst(value) => {
Self::PhantomConst(PhantomConst::new(value.0)) Self::PhantomConst(PhantomConst::new_interned(value.0))
} }
SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value), SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value),
} }

View file

@ -210,7 +210,37 @@ pub type GetA<P: PhantomConstGet<MyPhantomConstInner>> = DynSize;
pub type GetB<P: PhantomConstGet<MyPhantomConstInner>> = UInt; pub type GetB<P: PhantomConstGet<MyPhantomConstInner>> = UInt;
#[hdl(outline_generated, no_static)] #[hdl(outline_generated, no_static)]
pub struct MyTypeWithPhantomConstParameter<P: Type + PhantomConstGet<MyPhantomConstInner>> { pub struct MyTypeWithPhantomConstParameter<P: PhantomConstGet<MyPhantomConstInner>> {
pub a: ArrayType<Bool, GetA<P>>, pub a: ArrayType<Bool, GetA<P>>,
pub b: HdlOption<GetB<P>>, pub b: HdlOption<GetB<P>>,
} }
#[hdl(outline_generated)]
struct MyPrivateType {}
#[hdl(outline_generated)]
pub(crate) struct MyPubCrateType {}
#[hdl(outline_generated)]
pub struct MyTypeWithPrivateMembers {
a: MyPrivateType,
pub(crate) b: MyPubCrateType,
pub c: Bool,
}
#[hdl(outline_generated)]
struct MyPrivateTypeWithArg<T> {
v: T,
}
#[hdl(outline_generated)]
pub(crate) struct MyPubCrateTypeWithArg<T> {
v: T,
}
#[hdl(outline_generated)]
pub struct MyTypeWithPrivateMembersWithArg<T> {
a: MyPrivateTypeWithArg<T>,
pub(crate) b: MyPubCrateTypeWithArg<T>,
pub c: T,
}

View file

@ -2026,3 +2026,472 @@ fn test_sim_only_connects() {
panic!(); panic!();
} }
} }
#[hdl_module(outline_generated, extern)]
pub fn sim_fork_join<const N: usize>()
where
ConstUsize<N>: KnownSize,
{
#[hdl]
let clocks: Array<Clock, N> = m.input();
#[hdl]
let outputs: Array<UInt<8>, N> = m.output();
m.extern_module_simulation_fn((clocks, outputs), |(clocks, outputs), mut sim| async move {
sim.write(outputs, [0u8; N]).await;
loop {
sim.fork_join(
clocks
.into_iter()
.zip(outputs)
.map(|(clock, output)| {
move |mut sim: ExternModuleSimulationState| async move {
sim.wait_for_clock_edge(clock).await;
let v = sim
.read_bool_or_int(output)
.await
.to_bigint()
.try_into()
.expect("known to be in range");
sim.write(output, 1u8.wrapping_add(v)).await;
}
})
.collect::<Vec<_>>(),
)
.await;
}
});
}
#[test]
fn test_sim_fork_join() {
let _n = SourceLocation::normalize_files_for_tests();
const N: usize = 3;
let mut sim = Simulation::new(sim_fork_join::<N>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write(sim.io().clocks, [false; N]);
let mut clocks_triggered = [false; N];
let mut expected = [0u8; N];
for i0 in 0..N {
for i1 in 0..N {
for i2 in 0..N {
for i3 in 0..N {
let indexes = [i0, i1, i2, i3];
for i in indexes {
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], true);
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], false);
if !clocks_triggered[i] {
expected[i] = expected[i].wrapping_add(1);
}
clocks_triggered[i] = true;
if clocks_triggered == [true; N] {
clocks_triggered = [false; N];
}
let output = sim.read(sim.io().outputs);
assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}");
}
}
}
}
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_fork_join.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_fork_join.txt") {
panic!();
}
}
#[hdl_module(outline_generated, extern)]
pub fn sim_fork_join_scope<const N: usize>()
where
ConstUsize<N>: KnownSize,
{
#[hdl]
let clocks: Array<Clock, N> = m.input();
#[hdl]
let outputs: Array<UInt<8>, N> = m.output();
m.extern_module_simulation_fn((clocks, outputs), |(clocks, outputs), mut sim| async move {
sim.write(outputs, [0u8; N]).await;
loop {
let written = vec![std::cell::Cell::new(false); N]; // test shared scope
let written = &written; // work around move in async move
sim.fork_join_scope(|scope, _| async move {
let mut spawned = vec![];
for i in 0..N {
let join_handle =
scope.spawn(move |_, mut sim: ExternModuleSimulationState| async move {
sim.wait_for_clock_edge(clocks[i]).await;
let v = sim
.read_bool_or_int(outputs[i])
.await
.to_bigint()
.try_into()
.expect("known to be in range");
sim.write(outputs[i], 1u8.wrapping_add(v)).await;
written[i].set(true);
i
});
if i % 2 == 0 && i < N - 1 {
spawned.push((i, join_handle));
}
}
for (i, join_handle) in spawned {
assert_eq!(i, join_handle.join().await);
}
})
.await;
for written in written {
assert!(written.get());
}
}
});
}
#[test]
fn test_sim_fork_join_scope() {
let _n = SourceLocation::normalize_files_for_tests();
const N: usize = 3;
let mut sim = Simulation::new(sim_fork_join_scope::<N>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write(sim.io().clocks, [false; N]);
let mut clocks_triggered = [false; N];
let mut expected = [0u8; N];
for i0 in 0..N {
for i1 in 0..N {
for i2 in 0..N {
for i3 in 0..N {
let indexes = [i0, i1, i2, i3];
for i in indexes {
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], true);
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], false);
if !clocks_triggered[i] {
expected[i] = expected[i].wrapping_add(1);
}
clocks_triggered[i] = true;
if clocks_triggered == [true; N] {
clocks_triggered = [false; N];
}
let output = sim.read(sim.io().outputs);
assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}");
}
}
}
}
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_fork_join_scope.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_fork_join_scope.txt") {
panic!();
}
}
#[hdl_module(outline_generated, extern)]
pub fn sim_resettable_counter<R: ResetType>() {
#[hdl]
let cd: ClockDomain<R> = m.input();
#[hdl]
let out: UInt<8> = m.output();
m.extern_module_simulation_fn((cd, out), |(cd, out), mut sim| async move {
sim.resettable(
cd,
|mut sim: ExternModuleSimulationState| async move {
sim.write(out, 0u8).await;
},
|mut sim: ExternModuleSimulationState, ()| async move {
loop {
sim.wait_for_clock_edge(cd.clk).await;
let v: u8 = sim
.read(out)
.await
.to_bigint()
.try_into()
.expect("known to be in range");
sim.write(out, v.wrapping_add(1)).await;
}
},
)
.await
});
}
fn test_sim_resettable_counter_helper<R: ResetType>(
sim: &mut Simulation<sim_resettable_counter<R>>,
immediate_reset: bool,
) {
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, immediate_reset);
for _ in 0..2 {
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, false);
for expected in 0..3u8 {
assert_eq!(sim.read(sim.io().out), expected.to_sim_value());
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, false);
}
}
}
#[test]
fn test_sim_resettable_counter_sync() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(sim_resettable_counter::<SyncReset>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
test_sim_resettable_counter_helper(&mut sim, false);
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_resettable_counter_sync.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_resettable_counter_sync.txt") {
panic!();
}
}
#[test]
fn test_sim_resettable_counter_sync_immediate_reset() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(sim_resettable_counter::<SyncReset>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
test_sim_resettable_counter_helper(&mut sim, true);
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_resettable_counter_sync_immediate_reset.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_resettable_counter_sync_immediate_reset.txt") {
panic!();
}
}
#[test]
fn test_sim_resettable_counter_async() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(sim_resettable_counter::<AsyncReset>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
test_sim_resettable_counter_helper(&mut sim, false);
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_resettable_counter_async.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_resettable_counter_async.txt") {
panic!();
}
}
#[test]
fn test_sim_resettable_counter_async_immediate_reset() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(sim_resettable_counter::<AsyncReset>());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
test_sim_resettable_counter_helper(&mut sim, true);
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_resettable_counter_async_immediate_reset.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_resettable_counter_async_immediate_reset.txt") {
panic!();
}
}
#[hdl_module(outline_generated)]
pub fn phantom_const() {
#[hdl]
let out: Array<PhantomConst<Vec<String>>, 2> =
m.output(Array::new_static(PhantomConst::new_sized(vec![
"a".into(),
"b".into(),
])));
let _ = out;
#[hdl]
let mut mem = memory(PhantomConst::new("mem_element"));
mem.depth(1);
let port = mem.new_read_port();
connect_any(port.addr, 0u8);
connect(port.clk, false.to_clock());
connect(port.en, false);
}
#[test]
fn test_phantom_const() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(phantom_const());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.advance_time(SimDuration::from_micros(1));
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/phantom_const.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/phantom_const.txt") {
panic!();
}
}
#[hdl_module(outline_generated, extern)]
pub fn sim_read_past<const N: usize>()
where
ConstUsize<N>: KnownSize,
{
#[hdl]
let clocks: Array<Clock, N> = m.input();
#[hdl]
let outputs: Array<UInt<8>, N> = m.output();
#[hdl]
let past_clocks: Array<Clock, N> = m.output();
#[hdl]
let past_outputs: Array<UInt<8>, N> = m.output();
for clock in clocks {
m.register_clock_for_past(clock);
}
m.extern_module_simulation_fn(
(clocks, outputs, past_clocks, past_outputs),
|(clocks, outputs, past_clocks, past_outputs), mut sim| async move {
sim.write(outputs, [0u8; N]).await;
sim.write(past_clocks, [false; N]).await;
sim.write(past_outputs, [0u8; N]).await;
loop {
sim.fork_join_scope(|scope, _| async move {
for (clock, output) in clocks.into_iter().zip(outputs) {
scope.spawn_detached(
move |_, mut sim: ExternModuleSimulationState| async move {
sim.wait_for_clock_edge(clock).await;
dbg!(clock);
let v = sim
.read_bool_or_int(output)
.await
.to_bigint()
.try_into()
.expect("known to be in range");
sim.write(output, 1u8.wrapping_add(v)).await;
let past_outputs_v = sim.read_past(outputs, clock).await;
dbg!(&past_outputs_v);
sim.write(past_outputs, past_outputs_v).await;
let past_clocks_v = sim.read_past(clocks, clock).await;
dbg!(&past_clocks_v);
sim.write(past_clocks, past_clocks_v).await;
},
);
}
})
.await;
}
},
);
}
#[test]
fn test_sim_read_past() {
let _n = SourceLocation::normalize_files_for_tests();
const N: usize = 3;
let mut sim = Simulation::new(sim_read_past::<N>());
// sim.set_breakpoints_unstable(Default::default(), true);
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write(sim.io().clocks, [false; N]);
let mut clocks_triggered = [false; N];
let mut expected = [0u8; N];
let mut past_clocks_expected = [false; N];
let mut past_expected = expected;
for i0 in 0..N {
for i1 in 0..N {
for i2 in 0..N {
for i3 in 0..N {
let indexes = [i0, i1, i2, i3];
for i in indexes {
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], true);
sim.advance_time(SimDuration::from_micros(1));
sim.write(sim.io().clocks[i], false);
if !clocks_triggered[i] {
past_expected = expected;
expected[i] = expected[i].wrapping_add(1);
past_clocks_expected = [false; N];
past_clocks_expected[i] = true;
}
dbg!(past_expected);
clocks_triggered[i] = true;
if clocks_triggered == [true; N] {
clocks_triggered = [false; N];
}
let output = sim.read(sim.io().outputs);
assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}");
let past_clocks = sim.read(sim.io().past_clocks);
assert_eq!(
past_clocks,
past_clocks_expected
.to_sim_value_with_type(Array::<Clock, N>::default()),
"indexes={indexes:?} i={i}"
);
let past_outputs = sim.read(sim.io().past_outputs);
dbg!(&past_outputs);
assert_eq!(
past_outputs,
past_expected.to_sim_value(),
"indexes={indexes:?} i={i}"
);
}
}
}
}
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/sim_read_past.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/sim_read_past.txt") {
panic!();
}
}

View file

@ -826,9 +826,9 @@ Simulation {
}.write_index, }.write_index,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "array_rw", name: "array_rw",
children: [ children: [
@ -1699,7 +1699,12 @@ Simulation {
}, },
), ),
], ],
instant: 34 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 34 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -122,9 +122,9 @@ Simulation {
}.i, }.i,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "conditional_assignment_last", name: "conditional_assignment_last",
children: [ children: [
@ -177,7 +177,12 @@ Simulation {
}, },
), ),
], ],
instant: 2 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 2 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -98,9 +98,9 @@ Simulation {
}.o, }.o,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "connect_const", name: "connect_const",
children: [ children: [
@ -130,7 +130,12 @@ Simulation {
], ],
trace_memories: {}, trace_memories: {},
trace_writers: [], trace_writers: [],
instant: 0 s,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 0 s,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -141,9 +141,9 @@ Simulation {
}.reset_out, }.reset_out,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "connect_const_reset", name: "connect_const_reset",
children: [ children: [
@ -197,7 +197,12 @@ Simulation {
}, },
), ),
], ],
instant: 1 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 1 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -100,51 +100,51 @@ Simulation {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, 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 }, src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset },
}, },
3: 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 },
},
4: 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 },
},
// at: module-XXXXXXXXXX.rs:1:1 // at: module-XXXXXXXXXX.rs:1:1
3: Const { 5: Const {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
value: 0x3, value: 0x3,
}, },
// at: module-XXXXXXXXXX.rs:3:1 // at: module-XXXXXXXXXX.rs:3:1
4: BranchIfZero { 6: BranchIfZero {
target: 6, target: 8,
value: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
}, },
5: Copy { 7: Copy {
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
}, },
// at: module-XXXXXXXXXX.rs:1:1 // at: module-XXXXXXXXXX.rs:1:1
6: Add { 8: Add {
dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, 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> }, 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> }, rhs: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
}, },
7: CastToUInt { 9: CastToUInt {
dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
dest_width: 4, dest_width: 4,
}, },
// at: module-XXXXXXXXXX.rs:4:1 // at: module-XXXXXXXXXX.rs:4:1
8: Copy { 10: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
}, },
// at: module-XXXXXXXXXX.rs:6:1 // at: module-XXXXXXXXXX.rs:6:1
9: Copy { 11: Copy {
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> },
src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
}, },
// at: module-XXXXXXXXXX.rs:3:1 // at: module-XXXXXXXXXX.rs:3:1
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 },
},
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 },
},
12: BranchIfSmallNonZero { 12: BranchIfSmallNonZero {
target: 16, target: 16,
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
@ -261,9 +261,9 @@ Simulation {
}.count, }.count,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "counter", name: "counter",
children: [ children: [
@ -329,7 +329,7 @@ Simulation {
index: StatePartIndex<BigSlots>(0), index: StatePartIndex<BigSlots>(0),
}, },
state: 0x1, state: 0x1,
last_state: 0x1, last_state: 0x0,
}, },
SimTrace { SimTrace {
id: TraceScalarId(1), id: TraceScalarId(1),
@ -355,7 +355,7 @@ Simulation {
ty: UInt<4>, ty: UInt<4>,
}, },
state: 0x3, state: 0x3,
last_state: 0x3, last_state: 0x2,
}, },
], ],
trace_memories: {}, trace_memories: {},
@ -368,9 +368,14 @@ Simulation {
}, },
), ),
], ],
instant: 66 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
], ],
event_queue: EventQueue(EventQueueData {
instant: 66 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -26,192 +26,192 @@ b11 $
0! 0!
#3000000 #3000000
1! 1!
b100 $
b100 # b100 #
b100 $
#4000000 #4000000
0! 0!
#5000000 #5000000
1! 1!
b101 $
b101 # b101 #
b101 $
#6000000 #6000000
0! 0!
#7000000 #7000000
1! 1!
b110 $
b110 # b110 #
b110 $
#8000000 #8000000
0! 0!
#9000000 #9000000
1! 1!
b111 $
b111 # b111 #
b111 $
#10000000 #10000000
0! 0!
#11000000 #11000000
1! 1!
b1000 $
b1000 # b1000 #
b1000 $
#12000000 #12000000
0! 0!
#13000000 #13000000
1! 1!
b1001 $
b1001 # b1001 #
b1001 $
#14000000 #14000000
0! 0!
#15000000 #15000000
1! 1!
b1010 $
b1010 # b1010 #
b1010 $
#16000000 #16000000
0! 0!
#17000000 #17000000
1! 1!
b1011 $
b1011 # b1011 #
b1011 $
#18000000 #18000000
0! 0!
#19000000 #19000000
1! 1!
b1100 $
b1100 # b1100 #
b1100 $
#20000000 #20000000
0! 0!
#21000000 #21000000
1! 1!
b1101 $
b1101 # b1101 #
b1101 $
#22000000 #22000000
0! 0!
#23000000 #23000000
1! 1!
b1110 $
b1110 # b1110 #
b1110 $
#24000000 #24000000
0! 0!
#25000000 #25000000
1! 1!
b1111 $
b1111 # b1111 #
b1111 $
#26000000 #26000000
0! 0!
#27000000 #27000000
1! 1!
b0 $
b0 # b0 #
b0 $
#28000000 #28000000
0! 0!
#29000000 #29000000
1! 1!
b1 $
b1 # b1 #
b1 $
#30000000 #30000000
0! 0!
#31000000 #31000000
1! 1!
b10 $
b10 # b10 #
b10 $
#32000000 #32000000
0! 0!
#33000000 #33000000
1! 1!
b11 $
b11 # b11 #
b11 $
#34000000 #34000000
0! 0!
#35000000 #35000000
1! 1!
b100 $
b100 # b100 #
b100 $
#36000000 #36000000
0! 0!
#37000000 #37000000
1! 1!
b101 $
b101 # b101 #
b101 $
#38000000 #38000000
0! 0!
#39000000 #39000000
1! 1!
b110 $
b110 # b110 #
b110 $
#40000000 #40000000
0! 0!
#41000000 #41000000
1! 1!
b111 $
b111 # b111 #
b111 $
#42000000 #42000000
0! 0!
#43000000 #43000000
1! 1!
b1000 $
b1000 # b1000 #
b1000 $
#44000000 #44000000
0! 0!
#45000000 #45000000
1! 1!
b1001 $
b1001 # b1001 #
b1001 $
#46000000 #46000000
0! 0!
#47000000 #47000000
1! 1!
b1010 $
b1010 # b1010 #
b1010 $
#48000000 #48000000
0! 0!
#49000000 #49000000
1! 1!
b1011 $
b1011 # b1011 #
b1011 $
#50000000 #50000000
0! 0!
#51000000 #51000000
1! 1!
b1100 $
b1100 # b1100 #
b1100 $
#52000000 #52000000
0! 0!
#53000000 #53000000
1! 1!
b1101 $
b1101 # b1101 #
b1101 $
#54000000 #54000000
0! 0!
#55000000 #55000000
1! 1!
b1110 $
b1110 # b1110 #
b1110 $
#56000000 #56000000
0! 0!
#57000000 #57000000
1! 1!
b1111 $
b1111 # b1111 #
b1111 $
#58000000 #58000000
0! 0!
#59000000 #59000000
1! 1!
b0 $
b0 # b0 #
b0 $
#60000000 #60000000
0! 0!
#61000000 #61000000
1! 1!
b1 $
b1 # b1 #
b1 $
#62000000 #62000000
0! 0!
#63000000 #63000000
1! 1!
b10 $
b10 # b10 #
b10 $
#64000000 #64000000
0! 0!
#65000000 #65000000
1! 1!
b11 $
b11 # b11 #
b11 $
#66000000 #66000000

View file

@ -112,21 +112,21 @@ Simulation {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, 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 }, src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset },
}, },
// at: module-XXXXXXXXXX.rs:1:1 6: IsNonZeroDestIsSmall {
6: Const {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
value: 0x3,
},
// at: module-XXXXXXXXXX.rs:3:1
7: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, 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 }, src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
}, },
8: AndSmall { 7: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:1:1
8: Const {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
value: 0x3,
},
// at: module-XXXXXXXXXX.rs:3:1
9: BranchIfSmallZero { 9: BranchIfSmallZero {
target: 14, target: 14,
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
@ -242,9 +242,9 @@ Simulation {
}.count, }.count,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "counter", name: "counter",
children: [ children: [
@ -310,7 +310,7 @@ Simulation {
index: StatePartIndex<BigSlots>(0), index: StatePartIndex<BigSlots>(0),
}, },
state: 0x1, state: 0x1,
last_state: 0x1, last_state: 0x0,
}, },
SimTrace { SimTrace {
id: TraceScalarId(1), id: TraceScalarId(1),
@ -336,7 +336,7 @@ Simulation {
ty: UInt<4>, ty: UInt<4>,
}, },
state: 0x3, state: 0x3,
last_state: 0x3, last_state: 0x2,
}, },
], ],
trace_memories: {}, trace_memories: {},
@ -349,9 +349,14 @@ Simulation {
}, },
), ),
], ],
instant: 66 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
], ],
event_queue: EventQueue(EventQueueData {
instant: 66 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -16,199 +16,199 @@ b0 $
$end $end
#1000000 #1000000
1! 1!
b11 $
b11 # b11 #
b11 $
0" 0"
#2000000 #2000000
0! 0!
#3000000 #3000000
1! 1!
b100 $
b100 # b100 #
b100 $
#4000000 #4000000
0! 0!
#5000000 #5000000
1! 1!
b101 $
b101 # b101 #
b101 $
#6000000 #6000000
0! 0!
#7000000 #7000000
1! 1!
b110 $
b110 # b110 #
b110 $
#8000000 #8000000
0! 0!
#9000000 #9000000
1! 1!
b111 $
b111 # b111 #
b111 $
#10000000 #10000000
0! 0!
#11000000 #11000000
1! 1!
b1000 $
b1000 # b1000 #
b1000 $
#12000000 #12000000
0! 0!
#13000000 #13000000
1! 1!
b1001 $
b1001 # b1001 #
b1001 $
#14000000 #14000000
0! 0!
#15000000 #15000000
1! 1!
b1010 $
b1010 # b1010 #
b1010 $
#16000000 #16000000
0! 0!
#17000000 #17000000
1! 1!
b1011 $
b1011 # b1011 #
b1011 $
#18000000 #18000000
0! 0!
#19000000 #19000000
1! 1!
b1100 $
b1100 # b1100 #
b1100 $
#20000000 #20000000
0! 0!
#21000000 #21000000
1! 1!
b1101 $
b1101 # b1101 #
b1101 $
#22000000 #22000000
0! 0!
#23000000 #23000000
1! 1!
b1110 $
b1110 # b1110 #
b1110 $
#24000000 #24000000
0! 0!
#25000000 #25000000
1! 1!
b1111 $
b1111 # b1111 #
b1111 $
#26000000 #26000000
0! 0!
#27000000 #27000000
1! 1!
b0 $
b0 # b0 #
b0 $
#28000000 #28000000
0! 0!
#29000000 #29000000
1! 1!
b1 $
b1 # b1 #
b1 $
#30000000 #30000000
0! 0!
#31000000 #31000000
1! 1!
b10 $
b10 # b10 #
b10 $
#32000000 #32000000
0! 0!
#33000000 #33000000
1! 1!
b11 $
b11 # b11 #
b11 $
#34000000 #34000000
0! 0!
#35000000 #35000000
1! 1!
b100 $
b100 # b100 #
b100 $
#36000000 #36000000
0! 0!
#37000000 #37000000
1! 1!
b101 $
b101 # b101 #
b101 $
#38000000 #38000000
0! 0!
#39000000 #39000000
1! 1!
b110 $
b110 # b110 #
b110 $
#40000000 #40000000
0! 0!
#41000000 #41000000
1! 1!
b111 $
b111 # b111 #
b111 $
#42000000 #42000000
0! 0!
#43000000 #43000000
1! 1!
b1000 $
b1000 # b1000 #
b1000 $
#44000000 #44000000
0! 0!
#45000000 #45000000
1! 1!
b1001 $
b1001 # b1001 #
b1001 $
#46000000 #46000000
0! 0!
#47000000 #47000000
1! 1!
b1010 $
b1010 # b1010 #
b1010 $
#48000000 #48000000
0! 0!
#49000000 #49000000
1! 1!
b1011 $
b1011 # b1011 #
b1011 $
#50000000 #50000000
0! 0!
#51000000 #51000000
1! 1!
b1100 $
b1100 # b1100 #
b1100 $
#52000000 #52000000
0! 0!
#53000000 #53000000
1! 1!
b1101 $
b1101 # b1101 #
b1101 $
#54000000 #54000000
0! 0!
#55000000 #55000000
1! 1!
b1110 $
b1110 # b1110 #
b1110 $
#56000000 #56000000
0! 0!
#57000000 #57000000
1! 1!
b1111 $
b1111 # b1111 #
b1111 $
#58000000 #58000000
0! 0!
#59000000 #59000000
1! 1!
b0 $
b0 # b0 #
b0 $
#60000000 #60000000
0! 0!
#61000000 #61000000
1! 1!
b1 $
b1 # b1 #
b1 $
#62000000 #62000000
0! 0!
#63000000 #63000000
1! 1!
b10 $
b10 # b10 #
b10 $
#64000000 #64000000
0! 0!
#65000000 #65000000
1! 1!
b11 $
b11 # b11 #
b11 $
#66000000 #66000000

View file

@ -102,9 +102,9 @@ Simulation {
uninitialized_ios: {}, uninitialized_ios: {},
io_targets: {}, io_targets: {},
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "duplicate_names", name: "duplicate_names",
children: [ children: [
@ -160,7 +160,12 @@ Simulation {
}, },
), ),
], ],
instant: 1 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 1 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -1003,65 +1003,64 @@ Simulation {
dest: StatePartIndex<SmallSlots>(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, dest: StatePartIndex<SmallSlots>(5), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.rst", ty: SyncReset }, src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.rst", ty: SyncReset },
}, },
97: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", ty: Clock },
},
98: AndSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:1:1 // at: module-XXXXXXXXXX.rs:1:1
97: Const { 99: Const {
dest: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, dest: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
value: 0x0, value: 0x0,
}, },
98: Copy { 100: Copy {
dest: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, dest: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
src: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, src: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
}, },
// at: module-XXXXXXXXXX.rs:12:1 // at: module-XXXXXXXXXX.rs:12:1
99: BranchIfZero { 101: BranchIfZero {
target: 107, target: 109,
value: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool }, value: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:13:1 // at: module-XXXXXXXXXX.rs:13:1
100: BranchIfZero { 102: BranchIfZero {
target: 102, target: 104,
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:14:1 // at: module-XXXXXXXXXX.rs:14:1
101: Copy { 103: Copy {
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
}, },
// at: module-XXXXXXXXXX.rs:13:1 // at: module-XXXXXXXXXX.rs:13:1
102: BranchIfNonZero { 104: BranchIfNonZero {
target: 107, target: 109,
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:15:1 // at: module-XXXXXXXXXX.rs:15:1
103: BranchIfZero { 105: BranchIfZero {
target: 105, target: 107,
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:16:1 // at: module-XXXXXXXXXX.rs:16:1
104: Copy { 106: Copy {
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
src: StatePartIndex<BigSlots>(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, src: StatePartIndex<BigSlots>(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
}, },
// at: module-XXXXXXXXXX.rs:15:1 // at: module-XXXXXXXXXX.rs:15:1
105: BranchIfNonZero { 107: BranchIfNonZero {
target: 107, target: 109,
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:17:1 // at: module-XXXXXXXXXX.rs:17:1
106: Copy { 108: Copy {
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
src: StatePartIndex<BigSlots>(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} }, src: StatePartIndex<BigSlots>(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
}, },
// at: module-XXXXXXXXXX.rs:11:1
107: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", ty: Clock },
},
108: AndSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:10:1 // at: module-XXXXXXXXXX.rs:10:1
109: Copy { 109: Copy {
dest: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, dest: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
@ -1454,9 +1453,9 @@ Simulation {
}.which_out, }.which_out,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "enums", name: "enums",
children: [ children: [
@ -1744,7 +1743,7 @@ Simulation {
index: StatePartIndex<BigSlots>(0), index: StatePartIndex<BigSlots>(0),
}, },
state: 0x1, state: 0x1,
last_state: 0x1, last_state: 0x0,
}, },
SimTrace { SimTrace {
id: TraceScalarId(1), id: TraceScalarId(1),
@ -1924,9 +1923,14 @@ Simulation {
}, },
), ),
], ],
instant: 16 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(3), StatePartIndex<SmallSlots>(3),
], ],
event_queue: EventQueue(EventQueueData {
instant: 16 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -102,6 +102,7 @@ Simulation {
}.o, }.o,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [ extern_modules: [
SimulationExternModuleState { SimulationExternModuleState {
@ -136,6 +137,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -186,14 +188,8 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Instant(
20.500000000000 μs,
),
},
}, },
], ],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "extern_module", name: "extern_module",
children: [ children: [
@ -234,7 +230,7 @@ Simulation {
index: StatePartIndex<BigSlots>(1), index: StatePartIndex<BigSlots>(1),
}, },
state: 0x1, state: 0x1,
last_state: 0x1, last_state: 0x0,
}, },
], ],
trace_memories: {}, trace_memories: {},
@ -247,7 +243,21 @@ Simulation {
}, },
), ),
], ],
instant: 20 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 20 μs,
events: {
Event {
instant: 20.500000000000 μs,
kind: ExternModule(
0,
),
}: Wakers(
1,
),
},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -6,8 +6,9 @@ $upscope $end
$enddefinitions $end $enddefinitions $end
$dumpvars $dumpvars
0! 0!
1" 0"
$end $end
1"
#500000 #500000
#1500000 #1500000
0" 0"

View file

@ -121,6 +121,7 @@ Simulation {
}.o, }.o,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [ extern_modules: [
SimulationExternModuleState { SimulationExternModuleState {
@ -167,6 +168,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -234,55 +236,8 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
},
}, },
], ],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "extern_module2", name: "extern_module2",
children: [ children: [
@ -356,7 +311,113 @@ Simulation {
}, },
), ),
], ],
instant: 60 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 60 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 59,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 59,
..
},
},
),
},
.. ..
} }

View file

@ -8,8 +8,9 @@ $enddefinitions $end
$dumpvars $dumpvars
1! 1!
0" 0"
b1001000 # b0 #
$end $end
b1001000 #
#1000000 #1000000
1" 1"
b1100101 # b1100101 #

View file

@ -3834,9 +3834,9 @@ Simulation {
}.w[7].mask, }.w[7].mask,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "many_memories", name: "many_memories",
children: [ children: [
@ -7759,7 +7759,6 @@ Simulation {
}, },
), ),
], ],
instant: 38 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
StatePartIndex<SmallSlots>(6), StatePartIndex<SmallSlots>(6),
@ -7778,5 +7777,11 @@ Simulation {
StatePartIndex<SmallSlots>(85), StatePartIndex<SmallSlots>(85),
StatePartIndex<SmallSlots>(90), StatePartIndex<SmallSlots>(90),
], ],
event_queue: EventQueue(EventQueueData {
instant: 38 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -1052,12 +1052,16 @@ $end
1U# 1U#
1e# 1e#
1# 1#
1$
1' 1'
1+ 1+
1,
1/ 1/
13 13
14
17 17
1; 1;
1<
1? 1?
1C 1C
1H 1H
@ -1068,29 +1072,25 @@ $end
1a 1a
1f 1f
1k 1k
1l
1o 1o
1t 1t
1x 1x
1} 1}
1~
1#" 1#"
1(" 1("
1," 1,"
11" 11"
12"
15" 15"
1:" 1:"
1>" 1>"
1C" 1C"
1D"
1G" 1G"
1L" 1L"
1P" 1P"
1$
1,
14
1<
1l
1~
12"
1D"
#4000000 #4000000
0# 0#
0' 0'
@ -1150,13 +1150,21 @@ $end
0U# 0U#
0e# 0e#
1# 1#
0$
1' 1'
0(
1+ 1+
0,
1/ 1/
00
13 13
04
17 17
08
1; 1;
0<
1? 1?
0@
1C 1C
1H 1H
1M 1M
@ -1166,37 +1174,29 @@ $end
1a 1a
1f 1f
1k 1k
0l
1o 1o
1t 1t
0u
1x 1x
1} 1}
0~
1#" 1#"
1(" 1("
0)"
1," 1,"
11" 11"
02"
15" 15"
1:" 1:"
0;"
1>" 1>"
1C" 1C"
0D"
1G" 1G"
1L" 1L"
1P"
0$
0(
0,
00
04
08
0<
0@
0l
0u
0~
0)"
02"
0;"
0D"
0M" 0M"
1P"
#6000000 #6000000
0# 0#
0' 0'

View file

@ -719,9 +719,9 @@ Simulation {
}.w.mask.1, }.w.mask.1,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "memories", name: "memories",
children: [ children: [
@ -1616,10 +1616,15 @@ Simulation {
}, },
), ),
], ],
instant: 22 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
StatePartIndex<SmallSlots>(6), StatePartIndex<SmallSlots>(6),
], ],
event_queue: EventQueue(EventQueueData {
instant: 22 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -234,13 +234,13 @@ b100000 6
b10000 9 b10000 9
b100000 I b100000 I
1# 1#
1(
1/
14
b10000 $ b10000 $
b100000 % b100000 %
1(
1/
b10000 0 b10000 0
b100000 1 b100000 1
14
#4000000 #4000000
0# 0#
0( 0(
@ -256,11 +256,11 @@ b1000000 6
b10000 9 b10000 9
b1000000 I b1000000 I
1# 1#
b1000000 %
1( 1(
1/ 1/
14
b1000000 %
b1000000 1 b1000000 1
14
#6000000 #6000000
0# 0#
0( 0(
@ -278,11 +278,11 @@ b1100000 6
b1010000 9 b1010000 9
b1000000 I b1000000 I
1# 1#
b1010000 $
1( 1(
1/ 1/
14
b1010000 $
b1010000 0 b1010000 0
14
#8000000 #8000000
0# 0#
0( 0(

View file

@ -677,9 +677,9 @@ Simulation {
}.rw.wmode, }.rw.wmode,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "memories2", name: "memories2",
children: [ children: [
@ -1260,9 +1260,14 @@ Simulation {
}, },
), ),
], ],
instant: 22 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(3), StatePartIndex<SmallSlots>(3),
], ],
event_queue: EventQueue(EventQueueData {
instant: 22 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -100,8 +100,8 @@ $end
1) 1)
#1250000 #1250000
1# 1#
1*
b11 $ b11 $
1*
sHdlSome\x20(1) + sHdlSome\x20(1) +
1, 1,
#1500000 #1500000
@ -113,8 +113,8 @@ sHdlSome\x20(1) +
0) 0)
#2250000 #2250000
1# 1#
1*
b0 $ b0 $
1*
sHdlNone\x20(0) + sHdlNone\x20(0) +
0, 0,
#2500000 #2500000
@ -303,8 +303,8 @@ b11 !
b11 ( b11 (
#17250000 #17250000
1# 1#
1*
b11 $ b11 $
1*
sHdlSome\x20(1) + sHdlSome\x20(1) +
1, 1,
#17500000 #17500000
@ -316,8 +316,8 @@ b10 !
b10 ( b10 (
#18250000 #18250000
1# 1#
1*
b0 $ b0 $
1*
sHdlNone\x20(0) + sHdlNone\x20(0) +
0, 0,
#18500000 #18500000
@ -339,8 +339,8 @@ b1 !
b1 ( b1 (
#20250000 #20250000
1# 1#
1*
b1 $ b1 $
1*
sHdlSome\x20(1) + sHdlSome\x20(1) +
#20500000 #20500000
#20750000 #20750000
@ -353,8 +353,8 @@ b0 (
0) 0)
#21250000 #21250000
1# 1#
1*
b0 $ b0 $
1*
sHdlNone\x20(0) + sHdlNone\x20(0) +
#21500000 #21500000
#21750000 #21750000

View file

@ -1761,9 +1761,9 @@ Simulation {
}.w.mask[7], }.w.mask[7],
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "memories3", name: "memories3",
children: [ children: [
@ -3275,10 +3275,15 @@ Simulation {
}, },
), ),
], ],
instant: 15 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
StatePartIndex<SmallSlots>(6), StatePartIndex<SmallSlots>(6),
], ],
event_queue: EventQueue(EventQueueData {
instant: 15 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -420,6 +420,10 @@ b10000 T
1\ 1\
#3250000 #3250000
1# 1#
b110100 %
b1111000 '
b10011010 (
b11110000 +
1. 1.
1A 1A
b110100 C b110100 C
@ -427,10 +431,6 @@ b1111000 E
b10011010 F b10011010 F
b11110000 I b11110000 I
1L 1L
b110100 %
b1111000 '
b10011010 (
b11110000 +
#3500000 #3500000
#3750000 #3750000
0# 0#
@ -508,6 +508,14 @@ b1010100 '"
b110010 /" b110010 /"
b10000 7" b10000 7"
1# 1#
b11111110 $
b11011100 %
b10111010 &
b10011000 '
b1110110 (
b1010100 )
b110010 *
b10000 +
1. 1.
1A 1A
b11111110 B b11111110 B
@ -519,14 +527,6 @@ b1010100 G
b110010 H b110010 H
b10000 I b10000 I
1L 1L
b11111110 $
b11011100 %
b10111010 &
b10011000 '
b1110110 (
b1010100 )
b110010 *
b10000 +
#6500000 #6500000
#6750000 #6750000
0# 0#
@ -562,6 +562,14 @@ b1000110 ("
b10001010 0" b10001010 0"
b11001110 8" b11001110 8"
1# 1#
b0 $
b0 %
b0 &
b0 '
b0 (
b0 )
b0 *
b0 +
1. 1.
1A 1A
b0 B b0 B
@ -573,14 +581,6 @@ b0 G
b0 H b0 H
b0 I b0 I
1L 1L
b0 $
b0 %
b0 &
b0 '
b0 (
b0 )
b0 *
b0 +
#7500000 #7500000
#7750000 #7750000
0# 0#
@ -688,6 +688,14 @@ b1 !
b1 ? b1 ?
#10250000 #10250000
1# 1#
b11111110 $
b11011100 %
b10111010 &
b10011000 '
b1110110 (
b1010100 )
b110010 *
b10000 +
1. 1.
1A 1A
b11111110 B b11111110 B
@ -699,14 +707,6 @@ b1010100 G
b110010 H b110010 H
b10000 I b10000 I
1L 1L
b11111110 $
b11011100 %
b10111010 &
b10011000 '
b1110110 (
b1010100 )
b110010 *
b10000 +
#10500000 #10500000
#10750000 #10750000
0# 0#
@ -718,6 +718,14 @@ b10 !
b10 ? b10 ?
#11250000 #11250000
1# 1#
b10011 $
b1010111 %
b10011011 &
b11011111 '
b10 (
b1000110 )
b10001010 *
b11001110 +
1. 1.
1A 1A
b10011 B b10011 B
@ -729,14 +737,6 @@ b1000110 G
b10001010 H b10001010 H
b11001110 I b11001110 I
1L 1L
b10011 $
b1010111 %
b10011011 &
b11011111 '
b10 (
b1000110 )
b10001010 *
b11001110 +
#11500000 #11500000
#11750000 #11750000
0# 0#
@ -748,6 +748,14 @@ b11 !
b11 ? b11 ?
#12250000 #12250000
1# 1#
b1110100 $
b1100101 %
b1110011 &
b1110100 '
b1101001 (
b1101110 )
b1100111 *
b100001 +
1. 1.
1A 1A
b1110100 B b1110100 B
@ -759,14 +767,6 @@ b1101110 G
b1100111 H b1100111 H
b100001 I b100001 I
1L 1L
b1110100 $
b1100101 %
b1110011 &
b1110100 '
b1101001 (
b1101110 )
b1100111 *
b100001 +
#12500000 #12500000
#12750000 #12750000
0# 0#
@ -780,6 +780,14 @@ b0 ?
0@ 0@
#13250000 #13250000
1# 1#
b1101101 $
b1101111 %
b1110010 &
b1100101 '
b100000 (
b1110100 )
b1110011 *
b1110100 +
1. 1.
1A 1A
b1101101 B b1101101 B
@ -791,14 +799,6 @@ b1110100 G
b1110011 H b1110011 H
b1110100 I b1110100 I
1L 1L
b1101101 $
b1101111 %
b1110010 &
b1100101 '
b100000 (
b1110100 )
b1110011 *
b1110100 +
#13500000 #13500000
#13750000 #13750000
0# 0#
@ -808,6 +808,14 @@ b1110100 +
#14000000 #14000000
#14250000 #14250000
1# 1#
b0 $
b0 %
b0 &
b0 '
b0 (
b0 )
b0 *
b0 +
1. 1.
1A 1A
b0 B b0 B
@ -819,14 +827,6 @@ b0 G
b0 H b0 H
b0 I b0 I
1L 1L
b0 $
b0 %
b0 &
b0 '
b0 (
b0 )
b0 *
b0 +
#14500000 #14500000
#14750000 #14750000
0# 0#

View file

@ -274,9 +274,9 @@ Simulation {
}.o.o2, }.o.o2,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "mod1", name: "mod1",
children: [ children: [
@ -558,7 +558,12 @@ Simulation {
}, },
), ),
], ],
instant: 2 μs,
clocks_triggered: [], clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 2 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -0,0 +1,515 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 5,
debug_data: [
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: UInt<0>,
},
],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 7,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr",
ty: UInt<0>,
},
SlotDebugData {
name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en",
ty: Bool,
},
SlotDebugData {
name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk",
ty: Clock,
},
SlotDebugData {
name: "",
ty: UInt<8>,
},
SlotDebugData {
name: "",
ty: UInt<0>,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 1,
debug_data: [
(),
],
layout_data: [
MemoryData {
array_type: Array<PhantomConst("mem_element"), 1>,
data: [
// len = 0x1
[0x0]: 0x0,
],
},
],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Const {
dest: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "", ty: Bool },
value: 0x0,
},
1: Copy {
dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Clock },
src: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:6:1
2: Copy {
dest: StatePartIndex<BigSlots>(2), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk", ty: Clock },
src: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Clock },
},
// at: module-XXXXXXXXXX.rs:7:1
3: Copy {
dest: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en", ty: Bool },
src: StatePartIndex<BigSlots>(5), // (0x0) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:1:1
4: Const {
dest: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
value: 0x0,
},
5: CastToUInt {
dest: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "", ty: UInt<0> },
src: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
dest_width: 0,
},
// at: module-XXXXXXXXXX.rs:5:1
6: Copy {
dest: StatePartIndex<BigSlots>(0), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr", ty: UInt<0> },
src: StatePartIndex<BigSlots>(4), // (0x0) SlotDebugData { name: "", ty: UInt<0> },
},
// at: module-XXXXXXXXXX.rs:3:1
7: CastBigToArrayIndex {
dest: StatePartIndex<SmallSlots>(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<0> },
src: StatePartIndex<BigSlots>(0), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr", ty: UInt<0> },
},
8: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en", ty: Bool },
},
9: BranchIfSmallZero {
target: 11,
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
10: Branch {
target: 11,
},
11: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(2), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk", ty: Clock },
},
12: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Bool },
},
13: BranchIfSmallZero {
target: 14,
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
},
14: XorSmallImmediate {
dest: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
15: Return,
],
..
},
pc: 15,
memory_write_log: [],
memories: StatePart {
value: [
MemoryData {
array_type: Array<PhantomConst("mem_element"), 1>,
data: [
// len = 0x1
[0x0]: 0x0,
],
},
],
},
small_slots: StatePart {
value: [
1,
0,
0,
0,
0,
],
},
big_slots: StatePart {
value: [
0,
0,
0,
0,
0,
0,
0,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::phantom_const,
instantiated: Module {
name: phantom_const,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::phantom_const,
instantiated: Module {
name: phantom_const,
..
},
}.out,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::phantom_const,
instantiated: Module {
name: phantom_const,
..
},
}.out,
Instance {
name: <simulator>::phantom_const,
instantiated: Module {
name: phantom_const,
..
},
}.out[0],
Instance {
name: <simulator>::phantom_const,
instantiated: Module {
name: phantom_const,
..
},
}.out[1],
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [],
trace_decls: TraceModule {
name: "phantom_const",
children: [
TraceModuleIO {
name: "out",
child: TraceArray {
name: "out",
elements: [
TracePhantomConst {
location: TraceScalarId(0),
name: "[0]",
ty: PhantomConst(
["a","b"],
),
flow: Sink,
},
TracePhantomConst {
location: TraceScalarId(1),
name: "[1]",
ty: PhantomConst(
["a","b"],
),
flow: Sink,
},
],
ty: Array<PhantomConst(["a","b"]), 2>,
flow: Sink,
},
ty: Array<PhantomConst(["a","b"]), 2>,
flow: Sink,
},
TraceMem {
id: TraceMemoryId(0),
name: "mem",
stride: 0,
element_type: TracePhantomConst {
location: TraceMemoryLocation {
id: TraceMemoryId(0),
depth: 1,
stride: 0,
start: 0,
len: 0,
},
name: "mem",
ty: PhantomConst(
"mem_element",
),
flow: Duplex,
},
ports: [
TraceMemPort {
name: "r0",
bundle: TraceBundle {
name: "r0",
fields: [
TraceUInt {
location: TraceScalarId(2),
name: "addr",
ty: UInt<0>,
flow: Sink,
},
TraceBool {
location: TraceScalarId(3),
name: "en",
flow: Sink,
},
TraceClock {
location: TraceScalarId(4),
name: "clk",
flow: Sink,
},
TracePhantomConst {
location: TraceScalarId(5),
name: "data",
ty: PhantomConst(
"mem_element",
),
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
addr: UInt<0>,
/* offset = 0 */
en: Bool,
/* offset = 1 */
clk: Clock,
#[hdl(flip)] /* offset = 2 */
data: PhantomConst(
"mem_element",
),
},
flow: Sink,
},
ty: Bundle {
/* offset = 0 */
addr: UInt<0>,
/* offset = 0 */
en: Bool,
/* offset = 1 */
clk: Clock,
#[hdl(flip)] /* offset = 2 */
data: PhantomConst(
"mem_element",
),
},
},
],
array_type: Array<PhantomConst("mem_element"), 1>,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: PhantomConst {
ty: PhantomConst(
["a","b"],
),
},
state: PhantomConst,
last_state: PhantomConst,
},
SimTrace {
id: TraceScalarId(1),
kind: PhantomConst {
ty: PhantomConst(
["a","b"],
),
},
state: PhantomConst,
last_state: PhantomConst,
},
SimTrace {
id: TraceScalarId(2),
kind: BigUInt {
index: StatePartIndex<BigSlots>(0),
ty: UInt<0>,
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(3),
kind: BigBool {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(4),
kind: BigClock {
index: StatePartIndex<BigSlots>(2),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(5),
kind: PhantomConst {
ty: PhantomConst(
"mem_element",
),
},
state: PhantomConst,
last_state: PhantomConst,
},
],
trace_memories: {
StatePartIndex<Memories>(0): TraceMem {
id: TraceMemoryId(0),
name: "mem",
stride: 0,
element_type: TracePhantomConst {
location: TraceMemoryLocation {
id: TraceMemoryId(0),
depth: 1,
stride: 0,
start: 0,
len: 0,
},
name: "mem",
ty: PhantomConst(
"mem_element",
),
flow: Duplex,
},
ports: [
TraceMemPort {
name: "r0",
bundle: TraceBundle {
name: "r0",
fields: [
TraceUInt {
location: TraceScalarId(2),
name: "addr",
ty: UInt<0>,
flow: Sink,
},
TraceBool {
location: TraceScalarId(3),
name: "en",
flow: Sink,
},
TraceClock {
location: TraceScalarId(4),
name: "clk",
flow: Sink,
},
TracePhantomConst {
location: TraceScalarId(5),
name: "data",
ty: PhantomConst(
"mem_element",
),
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
addr: UInt<0>,
/* offset = 0 */
en: Bool,
/* offset = 1 */
clk: Clock,
#[hdl(flip)] /* offset = 2 */
data: PhantomConst(
"mem_element",
),
},
flow: Sink,
},
ty: Bundle {
/* offset = 0 */
addr: UInt<0>,
/* offset = 0 */
en: Bool,
/* offset = 1 */
clk: Clock,
#[hdl(flip)] /* offset = 2 */
data: PhantomConst(
"mem_element",
),
},
},
],
array_type: Array<PhantomConst("mem_element"), 1>,
},
},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [
StatePartIndex<SmallSlots>(1),
],
event_queue: EventQueue(EventQueueData {
instant: 1 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
..
}

View file

@ -0,0 +1,31 @@
$timescale 1 ps $end
$scope module phantom_const $end
$scope struct out $end
$var string 1 ! \[0] $end
$var string 1 " \[1] $end
$upscope $end
$scope struct mem $end
$scope struct contents $end
$scope struct \[0] $end
$var string 1 ' mem $end
$upscope $end
$upscope $end
$scope struct r0 $end
$var string 0 # addr $end
$var wire 1 $ en $end
$var wire 1 % clk $end
$var string 1 & data $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
$dumpvars
s0 '
sPhantomConst([\"a\",\"b\"]) !
sPhantomConst([\"a\",\"b\"]) "
s0 #
0$
0%
sPhantomConst(\"mem_element\") &
$end
#1000000

View file

@ -743,6 +743,7 @@ Simulation {
}.o, }.o,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [ extern_modules: [
SimulationExternModuleState { SimulationExternModuleState {
@ -777,6 +778,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -827,52 +829,6 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 3, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 33, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
},
}, },
SimulationExternModuleState { SimulationExternModuleState {
module_state: SimulationModuleState { module_state: SimulationModuleState {
@ -906,6 +862,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -956,52 +913,6 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 6, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 44, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
},
}, },
SimulationExternModuleState { SimulationExternModuleState {
module_state: SimulationModuleState { module_state: SimulationModuleState {
@ -1035,6 +946,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -1085,55 +997,8 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 9, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 55, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
},
}, },
], ],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "ripple_counter", name: "ripple_counter",
children: [ children: [
@ -1593,11 +1458,315 @@ Simulation {
}, },
), ),
], ],
instant: 256 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
StatePartIndex<SmallSlots>(4), StatePartIndex<SmallSlots>(4),
StatePartIndex<SmallSlots>(7), StatePartIndex<SmallSlots>(7),
], ],
event_queue: EventQueue(EventQueueData {
instant: 256 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 152,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 9, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 55, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 167,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 6, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 44, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 170,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 3, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 33, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 3, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 33, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 170,
..
},
},
),
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 6, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 44, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 167,
..
},
},
),
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 9, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 55, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 152,
..
},
},
),
},
.. ..
} }

File diff suppressed because it is too large Load diff

View file

@ -128,21 +128,21 @@ Simulation {
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, 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 }, src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset },
}, },
// at: module-XXXXXXXXXX.rs:1:1 6: IsNonZeroDestIsSmall {
6: Const {
dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
value: 0x0,
},
// at: module-XXXXXXXXXX.rs:5:1
7: IsNonZeroDestIsSmall {
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, 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 }, src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock },
}, },
8: AndSmall { 7: AndSmall {
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
}, },
// at: module-XXXXXXXXXX.rs:1:1
8: Const {
dest: StatePartIndex<BigSlots>(6), // (0x0) SlotDebugData { name: "", ty: Bool },
value: 0x0,
},
// at: module-XXXXXXXXXX.rs:5:1
9: BranchIfSmallZero { 9: BranchIfSmallZero {
target: 14, target: 14,
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
@ -337,9 +337,9 @@ Simulation {
}.q, }.q,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [], extern_modules: [],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "shift_register", name: "shift_register",
children: [ children: [
@ -440,7 +440,7 @@ Simulation {
index: StatePartIndex<BigSlots>(0), index: StatePartIndex<BigSlots>(0),
}, },
state: 0x1, state: 0x1,
last_state: 0x1, last_state: 0x0,
}, },
SimTrace { SimTrace {
id: TraceScalarId(1), id: TraceScalarId(1),
@ -509,9 +509,14 @@ Simulation {
}, },
), ),
], ],
instant: 66 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
], ],
event_queue: EventQueue(EventQueueData {
instant: 66 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
.. ..
} }

View file

@ -52,9 +52,9 @@ $end
0! 0!
#11000000 #11000000
1! 1!
1$
0& 0&
1( 1(
1$
#12000000 #12000000
0! 0!
1# 1#
@ -67,10 +67,10 @@ $end
0# 0#
#15000000 #15000000
1! 1!
0$
0% 0%
1& 1&
0( 0(
0$
#16000000 #16000000
0! 0!
1# 1#
@ -83,23 +83,23 @@ $end
0! 0!
#19000000 #19000000
1! 1!
1$
1& 1&
0' 0'
1( 1(
1$
#20000000 #20000000
0! 0!
#21000000 #21000000
1! 1!
0$
1' 1'
0( 0(
0$
#22000000 #22000000
0! 0!
#23000000 #23000000
1! 1!
1(
1$ 1$
1(
#24000000 #24000000
0! 0!
0# 0#
@ -120,8 +120,8 @@ $end
0! 0!
#31000000 #31000000
1! 1!
0(
0$ 0$
0(
#32000000 #32000000
0! 0!
#33000000 #33000000

View file

@ -0,0 +1,525 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 6,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[1]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[2]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[0]",
ty: UInt<8>,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[1]",
ty: UInt<8>,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[2]",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
0,
49,
50,
50,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.clocks,
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.outputs,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.clocks,
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.clocks[0],
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.clocks[1],
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.clocks[2],
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.outputs,
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.outputs[0],
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.outputs[1],
Instance {
name: <simulator>::sim_fork_join,
instantiated: Module {
name: sim_fork_join,
..
},
}.outputs[2],
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[0],
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[1],
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[2],
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[0],
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[1],
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[2],
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}: ModuleIO {
name: sim_fork_join::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}: ModuleIO {
name: sim_fork_join::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_fork_join",
children: [
TraceModuleIO {
name: "clocks",
child: TraceArray {
name: "clocks",
elements: [
TraceClock {
location: TraceScalarId(0),
name: "[0]",
flow: Source,
},
TraceClock {
location: TraceScalarId(1),
name: "[1]",
flow: Source,
},
TraceClock {
location: TraceScalarId(2),
name: "[2]",
flow: Source,
},
],
ty: Array<Clock, 3>,
flow: Source,
},
ty: Array<Clock, 3>,
flow: Source,
},
TraceModuleIO {
name: "outputs",
child: TraceArray {
name: "outputs",
elements: [
TraceUInt {
location: TraceScalarId(3),
name: "[0]",
ty: UInt<8>,
flow: Sink,
},
TraceUInt {
location: TraceScalarId(4),
name: "[1]",
ty: UInt<8>,
flow: Sink,
},
TraceUInt {
location: TraceScalarId(5),
name: "[2]",
ty: UInt<8>,
flow: Sink,
},
],
ty: Array<UInt<8>, 3>,
flow: Sink,
},
ty: Array<UInt<8>, 3>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigClock {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigClock {
index: StatePartIndex<BigSlots>(2),
},
state: 0x0,
last_state: 0x1,
},
SimTrace {
id: TraceScalarId(3),
kind: BigUInt {
index: StatePartIndex<BigSlots>(3),
ty: UInt<8>,
},
state: 0x31,
last_state: 0x31,
},
SimTrace {
id: TraceScalarId(4),
kind: BigUInt {
index: StatePartIndex<BigSlots>(4),
ty: UInt<8>,
},
state: 0x32,
last_state: 0x32,
},
SimTrace {
id: TraceScalarId(5),
kind: BigUInt {
index: StatePartIndex<BigSlots>(5),
ty: UInt<8>,
},
state: 0x32,
last_state: 0x32,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 648 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 198,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 198,
..
},
},
),
},
..
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,525 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 6,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[1]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[2]",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[0]",
ty: UInt<8>,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[1]",
ty: UInt<8>,
},
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[2]",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
0,
49,
50,
50,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.clocks,
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.outputs,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.clocks,
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.clocks[0],
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.clocks[1],
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.clocks[2],
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.outputs,
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.outputs[0],
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.outputs[1],
Instance {
name: <simulator>::sim_fork_join_scope,
instantiated: Module {
name: sim_fork_join_scope,
..
},
}.outputs[2],
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[0],
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[1],
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}[2],
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[0],
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[1],
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}[2],
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
}: ModuleIO {
name: sim_fork_join_scope::clocks,
is_input: true,
ty: Array<Clock, 3>,
..
},
ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
}: ModuleIO {
name: sim_fork_join_scope::outputs,
is_input: false,
ty: Array<UInt<8>, 3>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_fork_join_scope",
children: [
TraceModuleIO {
name: "clocks",
child: TraceArray {
name: "clocks",
elements: [
TraceClock {
location: TraceScalarId(0),
name: "[0]",
flow: Source,
},
TraceClock {
location: TraceScalarId(1),
name: "[1]",
flow: Source,
},
TraceClock {
location: TraceScalarId(2),
name: "[2]",
flow: Source,
},
],
ty: Array<Clock, 3>,
flow: Source,
},
ty: Array<Clock, 3>,
flow: Source,
},
TraceModuleIO {
name: "outputs",
child: TraceArray {
name: "outputs",
elements: [
TraceUInt {
location: TraceScalarId(3),
name: "[0]",
ty: UInt<8>,
flow: Sink,
},
TraceUInt {
location: TraceScalarId(4),
name: "[1]",
ty: UInt<8>,
flow: Sink,
},
TraceUInt {
location: TraceScalarId(5),
name: "[2]",
ty: UInt<8>,
flow: Sink,
},
],
ty: Array<UInt<8>, 3>,
flow: Sink,
},
ty: Array<UInt<8>, 3>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigClock {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigClock {
index: StatePartIndex<BigSlots>(2),
},
state: 0x0,
last_state: 0x1,
},
SimTrace {
id: TraceScalarId(3),
kind: BigUInt {
index: StatePartIndex<BigSlots>(3),
ty: UInt<8>,
},
state: 0x31,
last_state: 0x31,
},
SimTrace {
id: TraceScalarId(4),
kind: BigUInt {
index: StatePartIndex<BigSlots>(4),
ty: UInt<8>,
},
state: 0x32,
last_state: 0x32,
},
SimTrace {
id: TraceScalarId(5),
kind: BigUInt {
index: StatePartIndex<BigSlots>(5),
ty: UInt<8>,
},
state: 0x32,
last_state: 0x32,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 648 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 198,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 198,
..
},
},
),
},
..
}

File diff suppressed because it is too large Load diff

View file

@ -557,6 +557,7 @@ Simulation {
}.out3, }.out3,
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
extern_modules: [ extern_modules: [
SimulationExternModuleState { SimulationExternModuleState {
@ -635,6 +636,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -717,52 +719,6 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 4, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 6, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
},
}, },
SimulationExternModuleState { SimulationExternModuleState {
module_state: SimulationModuleState { module_state: SimulationModuleState {
@ -840,6 +796,7 @@ Simulation {
}, },
}, },
did_initial_settle: true, did_initial_settle: true,
clocks_for_past: {},
}, },
sim: ExternModuleSimulation { sim: ExternModuleSimulation {
generator: SimGeneratorFn { generator: SimGeneratorFn {
@ -922,55 +879,8 @@ Simulation {
running_generator: Some( running_generator: Some(
..., ...,
), ),
wait_targets: {
Change {
key: CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 4, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 12, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 13, len: 0 },
},
write: None,
},
value: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
},
}, },
], ],
state_ready_to_run: false,
trace_decls: TraceModule { trace_decls: TraceModule {
name: "sim_only_connects", name: "sim_only_connects",
children: [ children: [
@ -1628,9 +1538,214 @@ Simulation {
}, },
), ),
], ],
instant: 16 μs,
clocks_triggered: [ clocks_triggered: [
StatePartIndex<SmallSlots>(1), StatePartIndex<SmallSlots>(1),
], ],
event_queue: EventQueue(EventQueueData {
instant: 16 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 30,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_only_connects.helper1: sim_only_connects_helper).sim_only_connects_helper::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 4, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 6, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 31,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_only_connects.helper2: sim_only_connects_helper).sim_only_connects_helper::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 4, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 12, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 13, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_only_connects.helper1: sim_only_connects_helper).sim_only_connects_helper::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 4, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 6, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 30,
..
},
},
),
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_only_connects.helper2: sim_only_connects_helper).sim_only_connects_helper::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 4, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 12, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 13, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x1_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 31,
..
},
},
),
},
.. ..
} }

View file

@ -72,22 +72,22 @@ s{} 8
$end $end
#1000000 #1000000
1! 1!
s{\"extra\":\x20\"value\"} $
1' 1'
s{\"extra\":\x20\"value\"} )
1+ 1+
s{\"extra\":\x20\"value\"} -
10 10
11 11
15 15
s{\"extra\":\x20\"value\"} $
s{\"extra\":\x20\"value\"} )
s{\"extra\":\x20\"value\"} -
s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} *
s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} 4
s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} % s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} %
s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} & s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} *
s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} . s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} .
s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 3 s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 3
s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 7 s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 7
s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} 8 s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} &
s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 4
s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 8
#2000000 #2000000
0! 0!
0" 0"
@ -107,9 +107,6 @@ s{\"extra\":\x20\"value\"} /
00 00
11 11
15 15
s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 4
s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} &
s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 8
#4000000 #4000000
0! 0!
0' 0'

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,552 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 3,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
3,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.clk,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.rst,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}.clk,
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}.rst,
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}: ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
}: ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_resettable_counter",
children: [
TraceModuleIO {
name: "cd",
child: TraceBundle {
name: "cd",
fields: [
TraceClock {
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceAsyncReset {
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
flow: Source,
},
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
flow: Source,
},
TraceModuleIO {
name: "out",
child: TraceUInt {
location: TraceScalarId(2),
name: "out",
ty: UInt<8>,
flow: Sink,
},
ty: UInt<8>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigAsyncReset {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigUInt {
index: StatePartIndex<BigSlots>(2),
ty: UInt<8>,
},
state: 0x03,
last_state: 0x03,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 20 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 16,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: AsyncReset,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 23,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: AsyncReset,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 16,
..
},
},
),
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 23,
..
},
},
),
},
..
}

View file

@ -0,0 +1,68 @@
$timescale 1 ps $end
$scope module sim_resettable_counter $end
$scope struct cd $end
$var wire 1 ! clk $end
$var wire 1 " rst $end
$upscope $end
$var wire 8 # out $end
$upscope $end
$enddefinitions $end
$dumpvars
0!
0"
b0 #
$end
#1000000
1!
b1 #
#2000000
0!
1"
b0 #
#3000000
1!
#4000000
0!
0"
#5000000
1!
b1 #
#6000000
0!
#7000000
1!
b10 #
#8000000
0!
#9000000
1!
b11 #
#10000000
0!
#11000000
1!
b100 #
#12000000
0!
1"
b0 #
#13000000
1!
#14000000
0!
0"
#15000000
1!
b1 #
#16000000
0!
#17000000
1!
b10 #
#18000000
0!
#19000000
1!
b11 #
#20000000
0!

View file

@ -0,0 +1,552 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 3,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
3,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.clk,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.rst,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}.clk,
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}.rst,
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
}: ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
}: ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_resettable_counter",
children: [
TraceModuleIO {
name: "cd",
child: TraceBundle {
name: "cd",
fields: [
TraceClock {
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceAsyncReset {
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
flow: Source,
},
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: AsyncReset,
},
flow: Source,
},
TraceModuleIO {
name: "out",
child: TraceUInt {
location: TraceScalarId(2),
name: "out",
ty: UInt<8>,
flow: Sink,
},
ty: UInt<8>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigAsyncReset {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigUInt {
index: StatePartIndex<BigSlots>(2),
ty: UInt<8>,
},
state: 0x03,
last_state: 0x03,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 20 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 13,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: AsyncReset,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 20,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: AsyncReset,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: AsyncReset,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 1, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: AsyncReset,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 13,
..
},
},
),
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 20,
..
},
},
),
},
..
}

View file

@ -0,0 +1,65 @@
$timescale 1 ps $end
$scope module sim_resettable_counter $end
$scope struct cd $end
$var wire 1 ! clk $end
$var wire 1 " rst $end
$upscope $end
$var wire 8 # out $end
$upscope $end
$enddefinitions $end
$dumpvars
0!
1"
b0 #
$end
#1000000
1!
#2000000
0!
#3000000
1!
#4000000
0!
0"
#5000000
1!
b1 #
#6000000
0!
#7000000
1!
b10 #
#8000000
0!
#9000000
1!
b11 #
#10000000
0!
#11000000
1!
b100 #
#12000000
0!
1"
b0 #
#13000000
1!
#14000000
0!
0"
#15000000
1!
b1 #
#16000000
0!
#17000000
1!
b10 #
#18000000
0!
#19000000
1!
b11 #
#20000000
0!

View file

@ -0,0 +1,507 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 3,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: SyncReset,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
3,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.clk,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.rst,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}.clk,
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}.rst,
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}: ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
}: ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_resettable_counter",
children: [
TraceModuleIO {
name: "cd",
child: TraceBundle {
name: "cd",
fields: [
TraceClock {
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
flow: Source,
},
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
flow: Source,
},
TraceModuleIO {
name: "out",
child: TraceUInt {
location: TraceScalarId(2),
name: "out",
ty: UInt<8>,
flow: Sink,
},
ty: UInt<8>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigSyncReset {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigUInt {
index: StatePartIndex<BigSlots>(2),
ty: UInt<8>,
},
state: 0x03,
last_state: 0x03,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 20 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 42,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 43,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 42,
..
},
SensitivitySet {
id: 43,
..
},
},
),
},
..
}

View file

@ -0,0 +1,70 @@
$timescale 1 ps $end
$scope module sim_resettable_counter $end
$scope struct cd $end
$var wire 1 ! clk $end
$var wire 1 " rst $end
$upscope $end
$var wire 8 # out $end
$upscope $end
$enddefinitions $end
$dumpvars
0!
0"
b0 #
$end
#1000000
1!
b1 #
#2000000
0!
1"
#3000000
1!
b10 #
b0 #
#4000000
0!
0"
#5000000
1!
b1 #
#6000000
0!
#7000000
1!
b10 #
#8000000
0!
#9000000
1!
b11 #
#10000000
0!
#11000000
1!
b100 #
#12000000
0!
1"
#13000000
1!
b101 #
b0 #
#14000000
0!
0"
#15000000
1!
b1 #
#16000000
0!
#17000000
1!
b10 #
#18000000
0!
#19000000
1!
b11 #
#20000000
0!

View file

@ -0,0 +1,507 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 3,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst",
ty: SyncReset,
},
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out",
ty: UInt<8>,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Return,
],
..
},
pc: 0,
memory_write_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [],
},
big_slots: StatePart {
value: [
0,
0,
3,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.clk,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.cd.rst,
Instance {
name: <simulator>::sim_resettable_counter,
instantiated: Module {
name: sim_resettable_counter,
..
},
}.out,
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [
SimulationExternModuleState {
module_state: SimulationModuleState {
base_targets: [
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
],
uninitialized_ios: {},
io_targets: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}.clk,
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}.rst,
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
did_initial_settle: true,
clocks_for_past: {},
},
sim: ExternModuleSimulation {
generator: SimGeneratorFn {
args: (
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
),
f: ...,
},
sim_io_to_generator_map: {
ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
}: ModuleIO {
name: sim_resettable_counter::cd,
is_input: true,
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
..
},
ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
}: ModuleIO {
name: sim_resettable_counter::out,
is_input: false,
ty: UInt<8>,
..
},
},
source_location: SourceLocation(
module-XXXXXXXXXX.rs:4:1,
),
},
running_generator: Some(
...,
),
},
],
trace_decls: TraceModule {
name: "sim_resettable_counter",
children: [
TraceModuleIO {
name: "cd",
child: TraceBundle {
name: "cd",
fields: [
TraceClock {
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
],
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
flow: Source,
},
ty: Bundle {
/* offset = 0 */
clk: Clock,
/* offset = 1 */
rst: SyncReset,
},
flow: Source,
},
TraceModuleIO {
name: "out",
child: TraceUInt {
location: TraceScalarId(2),
name: "out",
ty: UInt<8>,
flow: Sink,
},
ty: UInt<8>,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: BigClock {
index: StatePartIndex<BigSlots>(0),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(1),
kind: BigSyncReset {
index: StatePartIndex<BigSlots>(1),
},
state: 0x0,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(2),
kind: BigUInt {
index: StatePartIndex<BigSlots>(2),
ty: UInt<8>,
},
state: 0x03,
last_state: 0x03,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 20 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {
SensitivitySet {
id: 43,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
SensitivitySet {
id: 44,
values: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
},
changed: Cell {
value: false,
},
..
},
},
waiting_sensitivity_sets_by_compiled_value: {
CompiledValue {
layout: CompiledTypeLayout {
ty: Clock,
layout: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 0,
debug_data: [],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 1,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk",
ty: Clock,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
body: Scalar,
},
range: TypeIndexRange {
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
sim_only_slots: StatePartIndexRange<SimOnlySlots> { start: 0, len: 0 },
},
write: None,
}: (
SimValue {
ty: Clock,
value: OpaqueSimValue {
bits: 0x0_u1,
sim_only_values: [],
},
},
{
SensitivitySet {
id: 43,
..
},
SensitivitySet {
id: 44,
..
},
},
),
},
..
}

View file

@ -0,0 +1,70 @@
$timescale 1 ps $end
$scope module sim_resettable_counter $end
$scope struct cd $end
$var wire 1 ! clk $end
$var wire 1 " rst $end
$upscope $end
$var wire 8 # out $end
$upscope $end
$enddefinitions $end
$dumpvars
0!
1"
b0 #
$end
#1000000
1!
b1 #
b0 #
#2000000
0!
#3000000
1!
b1 #
b0 #
#4000000
0!
0"
#5000000
1!
b1 #
#6000000
0!
#7000000
1!
b10 #
#8000000
0!
#9000000
1!
b11 #
#10000000
0!
#11000000
1!
b100 #
#12000000
0!
1"
#13000000
1!
b101 #
b0 #
#14000000
0!
0"
#15000000
1!
b1 #
#16000000
0!
#17000000
1!
b10 #
#18000000
0!
#19000000
1!
b11 #
#20000000
0!

View file

@ -162,6 +162,7 @@
"$kind": "Struct", "$kind": "Struct",
"verilog_name": "Visible", "verilog_name": "Visible",
"parameters": "Visible", "parameters": "Visible",
"clocks_for_past": "Visible",
"simulation": "Visible" "simulation": "Visible"
} }
}, },