forked from libre-chip/fayalite
Compare commits
No commits in common. "c11a1743f97b5219725d123d876effe717b633f2" and "b6e4cd0614e6b40d7ed3708f68037c06912a3ac7" have entirely different histories.
c11a1743f9
...
b6e4cd0614
45 changed files with 1318 additions and 15688 deletions
|
|
@ -12,7 +12,7 @@ Fayalite is a library for designing digital hardware -- a hardware description l
|
||||||
|
|
||||||
[Blinky example]: crates/fayalite/examples/blinky.rs
|
[Blinky example]: crates/fayalite/examples/blinky.rs
|
||||||
|
|
||||||
This uses the container image containing all the external programs and files that Fayalite needs to build for FPGAs, the sources for the container image are in <https://git.libre-chip.org/libre-chip/fayalite-deps>
|
This uses the container image containing all the external programs and files that Fayalite needs to build for FPGAs, the sources for the container image are in https://git.libre-chip.org/libre-chip/fayalite-deps
|
||||||
|
|
||||||
Steps:
|
Steps:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,11 +87,7 @@ impl ParsedBundle {
|
||||||
no_static: _,
|
no_static: _,
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq: _,
|
cmp_eq: _,
|
||||||
ref get,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
if let Some((get, ..)) = get {
|
|
||||||
errors.error(get, "#[hdl(get(...))] is not allowed on structs");
|
|
||||||
}
|
|
||||||
let mut fields = match fields {
|
let mut fields = match fields {
|
||||||
syn::Fields::Named(fields) => fields,
|
syn::Fields::Named(fields) => fields,
|
||||||
syn::Fields::Unnamed(fields) => {
|
syn::Fields::Unnamed(fields) => {
|
||||||
|
|
@ -449,7 +445,6 @@ impl ToTokens for ParsedBundle {
|
||||||
no_static,
|
no_static,
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
get: _,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let target = get_target(target, ident);
|
let target = get_target(target, ident);
|
||||||
let mut item_attrs = attrs.clone();
|
let mut item_attrs = attrs.clone();
|
||||||
|
|
|
||||||
|
|
@ -159,14 +159,10 @@ impl ParsedEnum {
|
||||||
no_static: _,
|
no_static: _,
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
ref get,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
if let Some((cmp_eq,)) = cmp_eq {
|
if let Some((cmp_eq,)) = cmp_eq {
|
||||||
errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums");
|
errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums");
|
||||||
}
|
}
|
||||||
if let Some((get, ..)) = get {
|
|
||||||
errors.error(get, "#[hdl(get(...))] is not allowed on enums");
|
|
||||||
}
|
|
||||||
attrs.retain(|attr| {
|
attrs.retain(|attr| {
|
||||||
if attr.path().is_ident("repr") {
|
if attr.path().is_ident("repr") {
|
||||||
errors.error(attr, "#[repr] is not supported on #[hdl] enums");
|
errors.error(attr, "#[repr] is not supported on #[hdl] enums");
|
||||||
|
|
@ -229,7 +225,6 @@ impl ToTokens for ParsedEnum {
|
||||||
no_static,
|
no_static,
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq: _, // TODO: implement cmp_eq for enums
|
cmp_eq: _, // TODO: implement cmp_eq for enums
|
||||||
get: _,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let target = get_target(target, ident);
|
let target = get_target(target, ident);
|
||||||
let mut struct_attrs = attrs.clone();
|
let mut struct_attrs = attrs.clone();
|
||||||
|
|
|
||||||
|
|
@ -3,264 +3,29 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Errors, HdlAttr,
|
Errors, HdlAttr,
|
||||||
hdl_type_common::{
|
hdl_type_common::{
|
||||||
ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType,
|
ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, TypesParser,
|
||||||
PhantomConstGetBound, TypesParser, WrappedInConst, common_derives, get_target, known_items,
|
get_target,
|
||||||
},
|
},
|
||||||
kw,
|
kw,
|
||||||
};
|
};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{ToTokens, format_ident, quote_spanned};
|
use quote::ToTokens;
|
||||||
use syn::{
|
use syn::{Attribute, Generics, Ident, ItemType, Token, Type, Visibility, parse_quote_spanned};
|
||||||
Attribute, Expr, Fields, GenericParam, Generics, Ident, ItemStruct, ItemType, Token, Type,
|
|
||||||
TypeGroup, TypeParam, TypeParen, Visibility, parse_quote_spanned, punctuated::Pair,
|
|
||||||
token::Paren,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct PhantomConstAccessorTypeParam {
|
pub(crate) struct ParsedTypeAlias {
|
||||||
attrs: Vec<Attribute>,
|
pub(crate) attrs: Vec<Attribute>,
|
||||||
ident: Ident,
|
pub(crate) options: HdlAttr<ItemOptions, kw::hdl>,
|
||||||
colon_token: Token![:],
|
pub(crate) vis: Visibility,
|
||||||
phantom_const_get_bound: PhantomConstGetBound,
|
pub(crate) type_token: Token![type],
|
||||||
plus_token: Option<Token![+]>,
|
pub(crate) ident: Ident,
|
||||||
}
|
pub(crate) generics: MaybeParsed<ParsedGenerics, Generics>,
|
||||||
|
pub(crate) eq_token: Token![=],
|
||||||
impl From<PhantomConstAccessorTypeParam> for TypeParam {
|
pub(crate) ty: MaybeParsed<ParsedType, Type>,
|
||||||
fn from(value: PhantomConstAccessorTypeParam) -> Self {
|
pub(crate) semi_token: Token![;],
|
||||||
let PhantomConstAccessorTypeParam {
|
|
||||||
attrs,
|
|
||||||
ident,
|
|
||||||
colon_token,
|
|
||||||
phantom_const_get_bound,
|
|
||||||
plus_token,
|
|
||||||
} = value;
|
|
||||||
TypeParam {
|
|
||||||
attrs,
|
|
||||||
ident,
|
|
||||||
colon_token: Some(colon_token),
|
|
||||||
bounds: FromIterator::from_iter([Pair::new(
|
|
||||||
phantom_const_get_bound.into(),
|
|
||||||
plus_token,
|
|
||||||
)]),
|
|
||||||
eq_token: None,
|
|
||||||
default: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PhantomConstAccessorTypeParam> for GenericParam {
|
|
||||||
fn from(value: PhantomConstAccessorTypeParam) -> Self {
|
|
||||||
TypeParam::from(value).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PhantomConstAccessorTypeParam {
|
|
||||||
fn parse_opt(generic_param: GenericParam) -> Option<Self> {
|
|
||||||
let GenericParam::Type(TypeParam {
|
|
||||||
attrs,
|
|
||||||
ident,
|
|
||||||
colon_token,
|
|
||||||
bounds,
|
|
||||||
eq_token: None,
|
|
||||||
default: None,
|
|
||||||
}) = generic_param
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let colon_token = colon_token.unwrap_or(Token));
|
|
||||||
let mut bounds = bounds.into_pairs();
|
|
||||||
let (bound, plus_token) = bounds.next()?.into_tuple();
|
|
||||||
let phantom_const_get_bound = PhantomConstGetBound::parse_type_param_bound(bound)
|
|
||||||
.ok()?
|
|
||||||
.ok()?;
|
|
||||||
let None = bounds.next() else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Self {
|
|
||||||
attrs,
|
|
||||||
ident,
|
|
||||||
colon_token,
|
|
||||||
phantom_const_get_bound,
|
|
||||||
plus_token,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(crate) struct PhantomConstAccessorGenerics {
|
|
||||||
lt_token: Token![<],
|
|
||||||
type_param: PhantomConstAccessorTypeParam,
|
|
||||||
comma_token: Option<Token![,]>,
|
|
||||||
gt_token: Token![>],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PhantomConstAccessorGenerics> for Generics {
|
|
||||||
fn from(value: PhantomConstAccessorGenerics) -> Self {
|
|
||||||
let PhantomConstAccessorGenerics {
|
|
||||||
lt_token,
|
|
||||||
type_param,
|
|
||||||
comma_token,
|
|
||||||
gt_token,
|
|
||||||
} = value;
|
|
||||||
Generics {
|
|
||||||
lt_token: Some(lt_token),
|
|
||||||
params: FromIterator::from_iter([Pair::new(type_param.into(), comma_token)]),
|
|
||||||
gt_token: Some(gt_token),
|
|
||||||
where_clause: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a PhantomConstAccessorGenerics> for Generics {
|
|
||||||
fn from(value: &'a PhantomConstAccessorGenerics) -> Self {
|
|
||||||
value.clone().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PhantomConstAccessorGenerics {
|
|
||||||
fn parse_opt(generics: Generics) -> Option<Self> {
|
|
||||||
let Generics {
|
|
||||||
lt_token,
|
|
||||||
params,
|
|
||||||
gt_token,
|
|
||||||
where_clause: None,
|
|
||||||
} = generics
|
|
||||||
else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let mut params = params.into_pairs();
|
|
||||||
let (generic_param, comma_token) = params.next()?.into_tuple();
|
|
||||||
let type_param = PhantomConstAccessorTypeParam::parse_opt(generic_param)?;
|
|
||||||
let span = type_param.ident.span();
|
|
||||||
let lt_token = lt_token.unwrap_or(Token);
|
|
||||||
let gt_token = gt_token.unwrap_or(Token);
|
|
||||||
let None = params.next() else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Self {
|
|
||||||
lt_token,
|
|
||||||
type_param,
|
|
||||||
comma_token,
|
|
||||||
gt_token,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(crate) enum ParsedTypeAlias {
|
|
||||||
TypeAlias {
|
|
||||||
attrs: Vec<Attribute>,
|
|
||||||
options: HdlAttr<ItemOptions, kw::hdl>,
|
|
||||||
vis: Visibility,
|
|
||||||
type_token: Token![type],
|
|
||||||
ident: Ident,
|
|
||||||
generics: MaybeParsed<ParsedGenerics, Generics>,
|
|
||||||
eq_token: Token![=],
|
|
||||||
ty: MaybeParsed<ParsedType, Type>,
|
|
||||||
semi_token: Token![;],
|
|
||||||
},
|
|
||||||
PhantomConstAccessor {
|
|
||||||
attrs: Vec<Attribute>,
|
|
||||||
options: HdlAttr<ItemOptions, kw::hdl>,
|
|
||||||
get: (kw::get, Paren, Expr),
|
|
||||||
vis: Visibility,
|
|
||||||
type_token: Token![type],
|
|
||||||
ident: Ident,
|
|
||||||
generics: PhantomConstAccessorGenerics,
|
|
||||||
eq_token: Token![=],
|
|
||||||
ty: Type,
|
|
||||||
ty_is_dyn_size: Option<known_items::DynSize>,
|
|
||||||
semi_token: Token![;],
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParsedTypeAlias {
|
impl ParsedTypeAlias {
|
||||||
fn ty_is_dyn_size(ty: &Type) -> Option<known_items::DynSize> {
|
|
||||||
match ty {
|
|
||||||
Type::Group(TypeGroup {
|
|
||||||
group_token: _,
|
|
||||||
elem,
|
|
||||||
}) => Self::ty_is_dyn_size(elem),
|
|
||||||
Type::Paren(TypeParen {
|
|
||||||
paren_token: _,
|
|
||||||
elem,
|
|
||||||
}) => Self::ty_is_dyn_size(elem),
|
|
||||||
Type::Path(syn::TypePath { qself: None, path }) => {
|
|
||||||
known_items::DynSize::parse_path(path.clone()).ok()
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn parse_phantom_const_accessor(
|
|
||||||
item: ItemType,
|
|
||||||
mut errors: Errors,
|
|
||||||
options: HdlAttr<ItemOptions, kw::hdl>,
|
|
||||||
get: (kw::get, Paren, Expr),
|
|
||||||
) -> syn::Result<Self> {
|
|
||||||
let ItemType {
|
|
||||||
attrs,
|
|
||||||
vis,
|
|
||||||
type_token,
|
|
||||||
ident,
|
|
||||||
generics,
|
|
||||||
eq_token,
|
|
||||||
ty,
|
|
||||||
semi_token,
|
|
||||||
} = item;
|
|
||||||
let ItemOptions {
|
|
||||||
outline_generated: _,
|
|
||||||
ref target,
|
|
||||||
custom_bounds,
|
|
||||||
no_static,
|
|
||||||
no_runtime_generics,
|
|
||||||
cmp_eq,
|
|
||||||
get: _,
|
|
||||||
} = options.body;
|
|
||||||
if let Some((no_static,)) = no_static {
|
|
||||||
errors.error(no_static, "no_static is not valid on type aliases");
|
|
||||||
}
|
|
||||||
if let Some((target, ..)) = target {
|
|
||||||
errors.error(
|
|
||||||
target,
|
|
||||||
"target is not implemented on PhantomConstGet type aliases",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some((no_runtime_generics,)) = no_runtime_generics {
|
|
||||||
errors.error(
|
|
||||||
no_runtime_generics,
|
|
||||||
"no_runtime_generics is not implemented on PhantomConstGet type aliases",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some((cmp_eq,)) = cmp_eq {
|
|
||||||
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
|
||||||
}
|
|
||||||
if let Some((custom_bounds,)) = custom_bounds {
|
|
||||||
errors.error(
|
|
||||||
custom_bounds,
|
|
||||||
"custom_bounds is not implemented on PhantomConstGet type aliases",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let Some(generics) = PhantomConstAccessorGenerics::parse_opt(generics) else {
|
|
||||||
errors.error(ident, "#[hdl(get(...))] type alias must be of the form:\ntype MyTypeGetter<P: PhantomConstGet<MyType>> = RetType;");
|
|
||||||
errors.finish()?;
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
errors.finish()?;
|
|
||||||
let ty_is_dyn_size = Self::ty_is_dyn_size(&ty);
|
|
||||||
Ok(Self::PhantomConstAccessor {
|
|
||||||
attrs,
|
|
||||||
options,
|
|
||||||
get,
|
|
||||||
vis,
|
|
||||||
type_token,
|
|
||||||
ident,
|
|
||||||
generics,
|
|
||||||
eq_token,
|
|
||||||
ty: *ty,
|
|
||||||
ty_is_dyn_size,
|
|
||||||
semi_token,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn parse(item: ItemType) -> syn::Result<Self> {
|
fn parse(item: ItemType) -> syn::Result<Self> {
|
||||||
let ItemType {
|
let ItemType {
|
||||||
mut attrs,
|
mut attrs,
|
||||||
|
|
@ -286,25 +51,7 @@ impl ParsedTypeAlias {
|
||||||
no_static,
|
no_static,
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
ref mut get,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
if let Some(get) = get.take() {
|
|
||||||
return Self::parse_phantom_const_accessor(
|
|
||||||
ItemType {
|
|
||||||
attrs,
|
|
||||||
vis,
|
|
||||||
type_token,
|
|
||||||
ident,
|
|
||||||
generics,
|
|
||||||
eq_token,
|
|
||||||
ty,
|
|
||||||
semi_token,
|
|
||||||
},
|
|
||||||
errors,
|
|
||||||
options,
|
|
||||||
get,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some((no_static,)) = no_static {
|
if let Some((no_static,)) = no_static {
|
||||||
errors.error(no_static, "no_static is not valid on type aliases");
|
errors.error(no_static, "no_static is not valid on type aliases");
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +67,7 @@ impl ParsedTypeAlias {
|
||||||
};
|
};
|
||||||
let ty = TypesParser::maybe_run(generics.as_ref(), *ty, &mut errors);
|
let ty = TypesParser::maybe_run(generics.as_ref(), *ty, &mut errors);
|
||||||
errors.finish()?;
|
errors.finish()?;
|
||||||
Ok(Self::TypeAlias {
|
Ok(Self {
|
||||||
attrs,
|
attrs,
|
||||||
options,
|
options,
|
||||||
vis,
|
vis,
|
||||||
|
|
@ -336,8 +83,7 @@ impl ParsedTypeAlias {
|
||||||
|
|
||||||
impl ToTokens for ParsedTypeAlias {
|
impl ToTokens for ParsedTypeAlias {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
match self {
|
let Self {
|
||||||
Self::TypeAlias {
|
|
||||||
attrs,
|
attrs,
|
||||||
options,
|
options,
|
||||||
vis,
|
vis,
|
||||||
|
|
@ -347,7 +93,7 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
eq_token,
|
eq_token,
|
||||||
ty,
|
ty,
|
||||||
semi_token,
|
semi_token,
|
||||||
} => {
|
} = self;
|
||||||
let ItemOptions {
|
let ItemOptions {
|
||||||
outline_generated: _,
|
outline_generated: _,
|
||||||
target,
|
target,
|
||||||
|
|
@ -355,7 +101,6 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
no_static: _,
|
no_static: _,
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq: _,
|
cmp_eq: _,
|
||||||
get: _,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let target = get_target(target, ident);
|
let target = get_target(target, ident);
|
||||||
let mut type_attrs = attrs.clone();
|
let mut type_attrs = attrs.clone();
|
||||||
|
|
@ -381,110 +126,11 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::PhantomConstAccessor {
|
|
||||||
attrs,
|
|
||||||
options,
|
|
||||||
get: (_get_kw, _get_paren, get_expr),
|
|
||||||
vis,
|
|
||||||
type_token,
|
|
||||||
ident,
|
|
||||||
generics,
|
|
||||||
eq_token,
|
|
||||||
ty,
|
|
||||||
ty_is_dyn_size,
|
|
||||||
semi_token,
|
|
||||||
} => {
|
|
||||||
let ItemOptions {
|
|
||||||
outline_generated: _,
|
|
||||||
target: _,
|
|
||||||
custom_bounds: _,
|
|
||||||
no_static: _,
|
|
||||||
no_runtime_generics: _,
|
|
||||||
cmp_eq: _,
|
|
||||||
get: _,
|
|
||||||
} = &options.body;
|
|
||||||
let span = ident.span();
|
|
||||||
let mut type_attrs = attrs.clone();
|
|
||||||
type_attrs.push(parse_quote_spanned! {span=>
|
|
||||||
#[allow(type_alias_bounds)]
|
|
||||||
});
|
|
||||||
let type_param_ident = &generics.type_param.ident;
|
|
||||||
let syn_generics = Generics::from(generics);
|
|
||||||
ItemType {
|
|
||||||
attrs: type_attrs,
|
|
||||||
vis: vis.clone(),
|
|
||||||
type_token: *type_token,
|
|
||||||
ident: ident.clone(),
|
|
||||||
generics: syn_generics.clone(),
|
|
||||||
eq_token: *eq_token,
|
|
||||||
ty: parse_quote_spanned! {span=>
|
|
||||||
<#ty as ::fayalite::phantom_const::ReturnSelfUnchanged<#type_param_ident>>::Type
|
|
||||||
},
|
|
||||||
semi_token: *semi_token,
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
let generics_accumulation_ident =
|
|
||||||
format_ident!("__{}__GenericsAccumulation", ident);
|
|
||||||
ItemStruct {
|
|
||||||
attrs: vec![
|
|
||||||
common_derives(span),
|
|
||||||
parse_quote_spanned! {span=>
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
},
|
|
||||||
],
|
|
||||||
vis: vis.clone(),
|
|
||||||
struct_token: Token,
|
|
||||||
ident: generics_accumulation_ident.clone(),
|
|
||||||
generics: Generics::default(),
|
|
||||||
fields: Fields::Unnamed(parse_quote_spanned! {span=>
|
|
||||||
(())
|
|
||||||
}),
|
|
||||||
semi_token: Some(Token),
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[allow(non_upper_case_globals, dead_code)]
|
|
||||||
#vis const #ident: #generics_accumulation_ident = #generics_accumulation_ident(());
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
let mut wrapped_in_const = WrappedInConst::new(tokens, span);
|
|
||||||
let tokens = wrapped_in_const.inner();
|
|
||||||
let (impl_generics, _type_generics, where_clause) = syn_generics.split_for_impl();
|
|
||||||
let phantom_const_get_ty = &generics.type_param.phantom_const_get_bound.ty;
|
|
||||||
let index_output = if let Some(ty_is_dyn_size) = ty_is_dyn_size {
|
|
||||||
known_items::usize(ty_is_dyn_size.span).to_token_stream()
|
|
||||||
} else {
|
|
||||||
ty.to_token_stream()
|
|
||||||
};
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::__std::ops::Index<#type_param_ident>
|
|
||||||
for #generics_accumulation_ident
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
type Output = #index_output;
|
|
||||||
|
|
||||||
fn index(&self, __param: #type_param_ident) -> &Self::Output {
|
|
||||||
::fayalite::phantom_const::type_alias_phantom_const_get_helper::<#phantom_const_get_ty, #index_output>(
|
|
||||||
__param,
|
|
||||||
#get_expr,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hdl_type_alias_impl(item: ItemType) -> syn::Result<TokenStream> {
|
pub(crate) fn hdl_type_alias_impl(item: ItemType) -> syn::Result<TokenStream> {
|
||||||
let item = ParsedTypeAlias::parse(item)?;
|
let item = ParsedTypeAlias::parse(item)?;
|
||||||
let outline_generated = match &item {
|
let outline_generated = item.options.body.outline_generated;
|
||||||
ParsedTypeAlias::TypeAlias { options, .. }
|
|
||||||
| ParsedTypeAlias::PhantomConstAccessor { options, .. } => options.body.outline_generated,
|
|
||||||
};
|
|
||||||
let mut contents = item.to_token_stream();
|
let mut contents = item.to_token_stream();
|
||||||
if outline_generated.is_some() {
|
if outline_generated.is_some() {
|
||||||
contents = crate::outline_generated(contents, "hdl-type-alias-");
|
contents = crate::outline_generated(contents, "hdl-type-alias-");
|
||||||
|
|
|
||||||
|
|
@ -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, TraitBound, Turbofish,
|
Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, Turbofish, Type,
|
||||||
Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple,
|
TypeGenerics, TypeGroup, TypeParam, TypeParen, TypePath, TypeTuple, Visibility, WhereClause,
|
||||||
Visibility, WhereClause, WherePredicate,
|
WherePredicate,
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
parse_quote, parse_quote_spanned,
|
parse_quote, parse_quote_spanned,
|
||||||
punctuated::{Pair, Punctuated},
|
punctuated::{Pair, Punctuated},
|
||||||
|
|
@ -27,7 +27,6 @@ crate::options! {
|
||||||
NoStatic(no_static),
|
NoStatic(no_static),
|
||||||
NoRuntimeGenerics(no_runtime_generics),
|
NoRuntimeGenerics(no_runtime_generics),
|
||||||
CmpEq(cmp_eq),
|
CmpEq(cmp_eq),
|
||||||
Get(get, Expr),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2046,7 +2045,6 @@ pub(crate) mod known_items {
|
||||||
impl_known_item!(::fayalite::int::Size);
|
impl_known_item!(::fayalite::int::Size);
|
||||||
impl_known_item!(::fayalite::int::UInt);
|
impl_known_item!(::fayalite::int::UInt);
|
||||||
impl_known_item!(::fayalite::int::UIntType);
|
impl_known_item!(::fayalite::int::UIntType);
|
||||||
impl_known_item!(::fayalite::phantom_const::PhantomConstGet);
|
|
||||||
impl_known_item!(::fayalite::reset::ResetType);
|
impl_known_item!(::fayalite::reset::ResetType);
|
||||||
impl_known_item!(::fayalite::ty::CanonicalType);
|
impl_known_item!(::fayalite::ty::CanonicalType);
|
||||||
impl_known_item!(::fayalite::ty::StaticType);
|
impl_known_item!(::fayalite::ty::StaticType);
|
||||||
|
|
@ -2065,174 +2063,6 @@ 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]
|
||||||
|
|
@ -2240,10 +2070,6 @@ macro_rules! impl_bounds {
|
||||||
$(
|
$(
|
||||||
$Variant:ident,
|
$Variant:ident,
|
||||||
)*
|
)*
|
||||||
$(
|
|
||||||
#[has_body]
|
|
||||||
$VariantHasBody:ident($variant_has_body_ty:ty),
|
|
||||||
)*
|
|
||||||
$(
|
$(
|
||||||
#[unknown]
|
#[unknown]
|
||||||
$Unknown:ident,
|
$Unknown:ident,
|
||||||
|
|
@ -2253,7 +2079,6 @@ 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),)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2263,42 +2088,31 @@ 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_with_arguments(path: Path) -> syn::Result<Result<Self, Path>> {
|
$vis fn parse_path(path: Path) -> 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(Ok(Self::$Variant(v))),
|
Ok(v) => return Ok(Self::$Variant(v)),
|
||||||
Err(path) => path,
|
Err(path) => path,
|
||||||
};)*
|
};)*
|
||||||
$(let path = match <$variant_has_body_ty>::parse_path_with_arguments(path)? {
|
$(return Ok(Self::$Unknown(syn::TraitBound {
|
||||||
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()));)?
|
||||||
Ok(Err(path))
|
Err(path)
|
||||||
}
|
}
|
||||||
$vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> syn::Result<Result<Self, syn::TypeParamBound>> {
|
$vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> 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 {
|
||||||
|
|
@ -2307,24 +2121,24 @@ macro_rules! impl_bounds {
|
||||||
lifetimes: None,
|
lifetimes: None,
|
||||||
path: _,
|
path: _,
|
||||||
} = trait_bound {
|
} = trait_bound {
|
||||||
match Self::parse_path_with_arguments(trait_bound.path)? {
|
match Self::parse_path(trait_bound.path) {
|
||||||
Ok(retval) => return Ok(Ok(retval)),
|
Ok(retval) => return 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(Ok(Self::$Unknown(type_param_bound)));)?
|
$(return Ok(Self::$Unknown(type_param_bound));)?
|
||||||
Ok(Err(type_param_bound))
|
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),)* $(stringify!($VariantHasBody)),*].join(", ")),
|
format_args!("expected one of: {}", [$(stringify!($Variant)),*].join(", ")),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2333,7 +2147,6 @@ 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>,)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2346,11 +2159,6 @@ 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());
|
||||||
|
|
@ -2364,7 +2172,6 @@ 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>,)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2375,7 +2182,6 @@ 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(),)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2390,11 +2196,6 @@ 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));
|
||||||
|
|
@ -2410,11 +2211,6 @@ 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));
|
||||||
|
|
@ -2431,9 +2227,6 @@ 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);
|
||||||
})?
|
})?
|
||||||
|
|
@ -2455,9 +2248,6 @@ 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);)*
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -2512,8 +2302,6 @@ impl_bounds! {
|
||||||
Size,
|
Size,
|
||||||
StaticType,
|
StaticType,
|
||||||
Type,
|
Type,
|
||||||
#[has_body]
|
|
||||||
PhantomConstGet(PhantomConstGetBound),
|
|
||||||
#[unknown]
|
#[unknown]
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
@ -2529,8 +2317,6 @@ impl_bounds! {
|
||||||
ResetType,
|
ResetType,
|
||||||
StaticType,
|
StaticType,
|
||||||
Type,
|
Type,
|
||||||
#[has_body]
|
|
||||||
PhantomConstGet(PhantomConstGetBound),
|
|
||||||
#[unknown]
|
#[unknown]
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
@ -2546,7 +2332,6 @@ 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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2562,7 +2347,6 @@ impl From<ParsedTypeBounds> for ParsedBounds {
|
||||||
ResetType,
|
ResetType,
|
||||||
StaticType,
|
StaticType,
|
||||||
Type,
|
Type,
|
||||||
PhantomConstGet,
|
|
||||||
Unknown,
|
Unknown,
|
||||||
} = value;
|
} = value;
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -2575,7 +2359,6 @@ impl From<ParsedTypeBounds> for ParsedBounds {
|
||||||
Size: None,
|
Size: None,
|
||||||
StaticType,
|
StaticType,
|
||||||
Type,
|
Type,
|
||||||
PhantomConstGet,
|
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2612,10 +2395,6 @@ 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)]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2651,7 +2430,6 @@ impl From<ParsedSizeTypeBounds> for ParsedBounds {
|
||||||
Size,
|
Size,
|
||||||
StaticType: None,
|
StaticType: None,
|
||||||
Type: None,
|
Type: None,
|
||||||
PhantomConstGet: None,
|
|
||||||
Unknown: vec![],
|
Unknown: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2754,9 +2532,6 @@ 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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3642,8 +3417,7 @@ 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) => {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ mod kw {
|
||||||
custom_keyword!(connect_inexact);
|
custom_keyword!(connect_inexact);
|
||||||
custom_keyword!(custom_bounds);
|
custom_keyword!(custom_bounds);
|
||||||
custom_keyword!(flip);
|
custom_keyword!(flip);
|
||||||
custom_keyword!(get);
|
|
||||||
custom_keyword!(hdl);
|
custom_keyword!(hdl);
|
||||||
custom_keyword!(hdl_module);
|
custom_keyword!(hdl_module);
|
||||||
custom_keyword!(incomplete_wire);
|
custom_keyword!(incomplete_wire);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use base64::{Engine, prelude::BASE64_URL_SAFE_NO_PAD};
|
use base64::{Engine, prelude::BASE64_URL_SAFE_NO_PAD};
|
||||||
use clap::builder::OsStringValueParser;
|
use clap::builder::OsStringValueParser;
|
||||||
use eyre::{Context, ensure, eyre};
|
use eyre::{Context, bail, ensure, eyre};
|
||||||
use serde::{
|
use serde::{
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
de::{DeserializeOwned, Error},
|
de::{DeserializeOwned, Error},
|
||||||
|
|
@ -26,7 +26,6 @@ use std::{
|
||||||
io::Write,
|
io::Write,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::ExitStatus,
|
|
||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -366,17 +365,13 @@ impl ExternalJobCaching {
|
||||||
.stdin(std::process::Stdio::null());
|
.stdin(std::process::Stdio::null());
|
||||||
Ok(cmd)
|
Ok(cmd)
|
||||||
}
|
}
|
||||||
pub fn run<F>(
|
pub fn run<F: FnOnce(std::process::Command) -> eyre::Result<()>>(
|
||||||
self,
|
self,
|
||||||
command_line: Interned<[Interned<OsStr>]>,
|
command_line: Interned<[Interned<OsStr>]>,
|
||||||
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
||||||
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
||||||
run_fn: F,
|
run_fn: F,
|
||||||
exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report,
|
) -> eyre::Result<()> {
|
||||||
) -> eyre::Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(std::process::Command) -> eyre::Result<Result<(), ExitStatus>>,
|
|
||||||
{
|
|
||||||
let mut hasher = JobCacheHasher::default();
|
let mut hasher = JobCacheHasher::default();
|
||||||
hasher.hash_iter(command_line.iter(), |hasher, arg| {
|
hasher.hash_iter(command_line.iter(), |hasher, arg| {
|
||||||
hasher.hash_sized_os_str(arg)
|
hasher.hash_sized_os_str(arg)
|
||||||
|
|
@ -424,26 +419,7 @@ impl ExternalJobCaching {
|
||||||
})
|
})
|
||||||
.expect("spawn shouldn't fail");
|
.expect("spawn shouldn't fail");
|
||||||
run_fn(cmd)
|
run_fn(cmd)
|
||||||
})?;
|
});
|
||||||
if let Err(exit_status) = result {
|
|
||||||
// check if the user may have terminated it or something, don't cache the failure
|
|
||||||
let user_maybe_terminated;
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
user_maybe_terminated = std::os::unix::process::ExitStatusExt::signal(&exit_status)
|
|
||||||
.is_some()
|
|
||||||
|| exit_status.code().is_none_or(|code| code > 1);
|
|
||||||
}
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
{
|
|
||||||
user_maybe_terminated = !exit_status.success();
|
|
||||||
}
|
|
||||||
if user_maybe_terminated {
|
|
||||||
let _ = std::fs::remove_file(self.cache_json_path);
|
|
||||||
return Err(exit_status_to_error(exit_status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let result = result.map_err(exit_status_to_error);
|
|
||||||
ExternalJobCacheV2 {
|
ExternalJobCacheV2 {
|
||||||
version: ExternalJobCacheVersion::CURRENT,
|
version: ExternalJobCacheVersion::CURRENT,
|
||||||
inputs_hash,
|
inputs_hash,
|
||||||
|
|
@ -468,26 +444,16 @@ impl ExternalJobCaching {
|
||||||
.write_to_file(self.cache_json_path)?;
|
.write_to_file(self.cache_json_path)?;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn run_maybe_cached<F>(
|
pub fn run_maybe_cached<F: FnOnce(std::process::Command) -> eyre::Result<()>>(
|
||||||
this: Option<Self>,
|
this: Option<Self>,
|
||||||
command_line: Interned<[Interned<OsStr>]>,
|
command_line: Interned<[Interned<OsStr>]>,
|
||||||
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
input_file_paths: impl IntoIterator<Item = Interned<Path>>,
|
||||||
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
output_file_paths: impl IntoIterator<Item = Interned<Path>> + Clone,
|
||||||
run_fn: F,
|
run_fn: F,
|
||||||
exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report,
|
) -> eyre::Result<()> {
|
||||||
) -> eyre::Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(std::process::Command) -> eyre::Result<Result<(), ExitStatus>>,
|
|
||||||
{
|
|
||||||
match this {
|
match this {
|
||||||
Some(this) => this.run(
|
Some(this) => this.run(command_line, input_file_paths, output_file_paths, run_fn),
|
||||||
command_line,
|
None => run_fn(Self::make_command(command_line)?),
|
||||||
input_file_paths,
|
|
||||||
output_file_paths,
|
|
||||||
run_fn,
|
|
||||||
exit_status_to_error,
|
|
||||||
),
|
|
||||||
None => run_fn(Self::make_command(command_line)?)?.map_err(exit_status_to_error),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1153,12 +1119,10 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
||||||
}
|
}
|
||||||
let status = acquired_job.run_command(cmd, |cmd| cmd.status())?;
|
let status = acquired_job.run_command(cmd, |cmd| cmd.status())?;
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
Ok(Err(status))
|
bail!("running {command_line:?} failed: {status}")
|
||||||
} else {
|
|
||||||
Ok(Ok(()))
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
},
|
},
|
||||||
|status| eyre!("running {command_line:?} failed: {status}"),
|
|
||||||
)?;
|
)?;
|
||||||
Ok(job
|
Ok(job
|
||||||
.output_paths()
|
.output_paths()
|
||||||
|
|
|
||||||
|
|
@ -703,12 +703,8 @@ 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 {
|
||||||
if let Some(finished_job) = next_finished_job
|
while let Some(finished_job) = finished_jobs_receiver.try_recv().ok() {
|
||||||
.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!();
|
||||||
|
|
@ -740,7 +736,6 @@ impl JobGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if let Some(WaitingJobState {
|
if let Some(WaitingJobState {
|
||||||
job_node_id,
|
job_node_id,
|
||||||
|
|
@ -796,15 +791,12 @@ 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();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,6 @@
|
||||||
// TODO: enable:
|
// TODO: enable:
|
||||||
// #![warn(missing_docs)]
|
// #![warn(missing_docs)]
|
||||||
|
|
||||||
#![deny(
|
|
||||||
rustdoc::bare_urls,
|
|
||||||
rustdoc::broken_intra_doc_links,
|
|
||||||
rustdoc::invalid_codeblock_attributes,
|
|
||||||
rustdoc::invalid_html_tags,
|
|
||||||
rustdoc::invalid_rust_codeblocks,
|
|
||||||
rustdoc::private_doc_tests,
|
|
||||||
rustdoc::private_intra_doc_links,
|
|
||||||
rustdoc::redundant_explicit_links,
|
|
||||||
rustdoc::unescaped_backticks
|
|
||||||
)]
|
|
||||||
|
|
||||||
//! [Main Documentation][_docs]
|
//! [Main Documentation][_docs]
|
||||||
|
|
||||||
extern crate self as fayalite;
|
extern crate self as fayalite;
|
||||||
|
|
@ -86,135 +74,6 @@ macro_rules! __cfg_expansion_helper {
|
||||||
pub use fayalite_proc_macros::hdl_module;
|
pub use fayalite_proc_macros::hdl_module;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
/// The `#[hdl]` attribute is supported on several different kinds of [Rust Items](https://doc.rust-lang.org/reference/items.html):
|
|
||||||
///
|
|
||||||
/// # Functions and Methods
|
|
||||||
/// Enable's the stuff that you can use inside a [module's body](crate::_docs::modules::module_bodies),
|
|
||||||
/// but without being a module or changing the function's signature.
|
|
||||||
/// The only exception is that you can't use stuff that requires the automatically-provided `m` variable.
|
|
||||||
///
|
|
||||||
/// # Structs
|
|
||||||
// TODO: expand on struct docs
|
|
||||||
/// e.g.:
|
|
||||||
/// ```
|
|
||||||
/// # use fayalite::prelude::*;
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # pub struct OtherStruct {}
|
|
||||||
/// #[hdl]
|
|
||||||
/// pub struct MyStruct {
|
|
||||||
/// #[hdl(flip)]
|
|
||||||
/// pub a: UInt<5>,
|
|
||||||
/// pub b: Bool,
|
|
||||||
/// #[hdl(flip)]
|
|
||||||
/// pub c: OtherStruct,
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Enums
|
|
||||||
// TODO: expand on enum docs
|
|
||||||
/// e.g.:
|
|
||||||
/// ```
|
|
||||||
/// # use fayalite::prelude::*;
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # pub struct MyStruct {}
|
|
||||||
/// #[hdl]
|
|
||||||
/// pub enum MyEnum {
|
|
||||||
/// A(UInt<3>),
|
|
||||||
/// B,
|
|
||||||
/// C(MyStruct),
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Type Aliases
|
|
||||||
///
|
|
||||||
/// There's three different ways you can create a type alias:
|
|
||||||
///
|
|
||||||
/// # Normal Type Alias
|
|
||||||
///
|
|
||||||
/// This works exactly how you'd expect:
|
|
||||||
/// ```
|
|
||||||
/// # use fayalite::prelude::*;
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # pub struct MyStruct<T: Type> {
|
|
||||||
/// # v: T,
|
|
||||||
/// # }
|
|
||||||
/// #[hdl]
|
|
||||||
/// pub type MyType<T: Type> = MyStruct<T>;
|
|
||||||
///
|
|
||||||
/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime:
|
|
||||||
///
|
|
||||||
/// let ty = MyType[UInt[3]];
|
|
||||||
/// assert_eq!(ty, MyStruct[UInt[3]]);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Type Alias that gets a [`Type`] from a [`PhantomConst`]
|
|
||||||
///
|
|
||||||
/// 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::*};
|
|
||||||
/// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
/// pub struct Config {
|
|
||||||
/// pub foo: usize,
|
|
||||||
/// pub bar: Bundle,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // the expression inside `get` is called with `Interned<Config>` and returns `Array<Bundle>`
|
|
||||||
/// #[hdl(get(|config| Array[config.bar][config.foo]))]
|
|
||||||
/// pub type GetMyArray<P: PhantomConstGet<Config>> = Array<Bundle>;
|
|
||||||
///
|
|
||||||
/// // you can then use it in other types:
|
|
||||||
///
|
|
||||||
/// #[hdl(no_static)]
|
|
||||||
/// pub struct WrapMyArray<P: PhantomConstGet<Config>> {
|
|
||||||
/// pub my_array: GetMyArray<P>,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime:
|
|
||||||
/// let bar = Bundle::new(Default::default());
|
|
||||||
/// let config = PhantomConst::new(Config { foo: 12, bar }.intern_sized());
|
|
||||||
/// let ty = WrapMyArray[config];
|
|
||||||
/// assert_eq!(ty.my_array, Array[bar][12]);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Type Alias that gets a [`Size`] from a [`PhantomConst`]
|
|
||||||
///
|
|
||||||
/// 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::*};
|
|
||||||
/// # #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
/// # pub struct ConfigItem {}
|
|
||||||
/// # impl ConfigItem {
|
|
||||||
/// # pub fn new() -> Self {
|
|
||||||
/// # Self {}
|
|
||||||
/// # }
|
|
||||||
/// # }
|
|
||||||
/// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
/// pub struct Config {
|
|
||||||
/// pub items: Vec<ConfigItem>,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // the expression inside `get` is called with `Interned<Config>` and returns `usize` (not DynSize)
|
|
||||||
/// #[hdl(get(|config| config.items.len()))]
|
|
||||||
/// pub type GetItemsLen<P: PhantomConstGet<Config>> = DynSize; // must be DynSize
|
|
||||||
///
|
|
||||||
/// // you can then use it in other types:
|
|
||||||
///
|
|
||||||
/// #[hdl(no_static)]
|
|
||||||
/// pub struct FlagPerItem<P: PhantomConstGet<Config>> {
|
|
||||||
/// pub flags: ArrayType<Bool, GetItemsLen<P>>,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // 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 ty = FlagPerItem[config];
|
|
||||||
/// assert_eq!(ty.flags, Array[Bool][5]);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`PhantomConst`]: crate::phantom_const::PhantomConst
|
|
||||||
/// [`Size`]: crate::int::Size
|
|
||||||
/// [`Type`]: crate::ty::Type
|
|
||||||
pub use fayalite_proc_macros::hdl;
|
pub use fayalite_proc_macros::hdl;
|
||||||
|
|
||||||
pub use bitvec;
|
pub use bitvec;
|
||||||
|
|
|
||||||
|
|
@ -415,71 +415,3 @@ impl<T: ?Sized + PhantomConstValue> ToSimValueWithType<CanonicalType> for Phanto
|
||||||
SimValue::into_canonical(SimValue::from_value(Self::from_canonical(ty), *self))
|
SimValue::into_canonical(SimValue::from_value(Self::from_canonical(ty), *self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
|
||||||
pub trait Sealed<T: ?Sized> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PhantomConstGet<T: ?Sized + PhantomConstValue>: sealed::Sealed<T> {
|
|
||||||
fn get(&self) -> Interned<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + PhantomConstValue, This: ?Sized + std::ops::Deref<Target: PhantomConstGet<T>>>
|
|
||||||
sealed::Sealed<T> for This
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + PhantomConstValue, This: ?Sized + std::ops::Deref<Target: PhantomConstGet<T>>>
|
|
||||||
PhantomConstGet<T> for This
|
|
||||||
{
|
|
||||||
fn get(&self) -> Interned<T> {
|
|
||||||
This::Target::get(&**self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_phantom_const_get {
|
|
||||||
(
|
|
||||||
impl PhantomConstGet<$T:ident> for $ty:ty {
|
|
||||||
fn $get:ident(&$get_self:ident) -> _ $get_body:block
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
impl<$T: ?Sized + PhantomConstValue> sealed::Sealed<$T> for $ty {}
|
|
||||||
|
|
||||||
impl<$T: ?Sized + PhantomConstValue> PhantomConstGet<$T> for $ty {
|
|
||||||
fn $get(&$get_self) -> Interned<$T> $get_body
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_phantom_const_get! {
|
|
||||||
impl PhantomConstGet<T> for PhantomConst<T> {
|
|
||||||
fn get(&self) -> _ {
|
|
||||||
PhantomConst::get(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_phantom_const_get! {
|
|
||||||
impl PhantomConstGet<T> for Expr<PhantomConst<T>> {
|
|
||||||
fn get(&self) -> _ {
|
|
||||||
PhantomConst::get(Expr::ty(*self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait ReturnSelfUnchanged<T: ?Sized> {
|
|
||||||
type Type: ?Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<This: ?Sized, T: ?Sized> ReturnSelfUnchanged<T> for This {
|
|
||||||
type Type = This;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn type_alias_phantom_const_get_helper<T: ?Sized + PhantomConstValue, R: Intern + Clone>(
|
|
||||||
param: impl PhantomConstGet<T>,
|
|
||||||
get: impl FnOnce(Interned<T>) -> R,
|
|
||||||
) -> &'static R {
|
|
||||||
Interned::into_inner(get(param.get()).intern_sized())
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ pub use crate::{
|
||||||
Instance, Module, ModuleBuilder, annotate, connect, connect_any, incomplete_wire, instance,
|
Instance, Module, ModuleBuilder, annotate, connect, connect_any, incomplete_wire, instance,
|
||||||
memory, memory_array, memory_with_init, reg_builder, wire,
|
memory, memory_array, memory_with_init, reg_builder, wire,
|
||||||
},
|
},
|
||||||
phantom_const::{PhantomConst, PhantomConstGet},
|
phantom_const::PhantomConst,
|
||||||
platform::{DynPlatform, Platform, PlatformIOBuilder, peripherals},
|
platform::{DynPlatform, Platform, PlatformIOBuilder, peripherals},
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -4,6 +4,7 @@ use fayalite::{
|
||||||
bundle::BundleType,
|
bundle::BundleType,
|
||||||
enum_::EnumType,
|
enum_::EnumType,
|
||||||
int::{BoolOrIntType, IntType},
|
int::{BoolOrIntType, IntType},
|
||||||
|
phantom_const::PhantomConst,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
ty::StaticType,
|
ty::StaticType,
|
||||||
};
|
};
|
||||||
|
|
@ -196,21 +197,3 @@ check_bounds!(CheckBoundsTTT2<#[a, Type] A: BundleType +, #[b, Type] B: Type +,
|
||||||
check_bounds!(CheckBoundsTTT3<#[a, Type] A: EnumType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
check_bounds!(CheckBoundsTTT3<#[a, Type] A: EnumType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
||||||
check_bounds!(CheckBoundsTTT4<#[a, Type] A: IntType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
check_bounds!(CheckBoundsTTT4<#[a, Type] A: IntType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
||||||
check_bounds!(CheckBoundsTTT5<#[a, Type] A: StaticType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
check_bounds!(CheckBoundsTTT5<#[a, Type] A: StaticType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct MyPhantomConstInner {
|
|
||||||
pub a: usize,
|
|
||||||
pub b: UInt,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(outline_generated, get(|v| v.a))]
|
|
||||||
pub type GetA<P: PhantomConstGet<MyPhantomConstInner>> = DynSize;
|
|
||||||
|
|
||||||
#[hdl(outline_generated, get(|v| v.b))]
|
|
||||||
pub type GetB<P: PhantomConstGet<MyPhantomConstInner>> = UInt;
|
|
||||||
|
|
||||||
#[hdl(outline_generated, no_static)]
|
|
||||||
pub struct MyTypeWithPhantomConstParameter<P: PhantomConstGet<MyPhantomConstInner>> {
|
|
||||||
pub a: ArrayType<Bool, GetA<P>>,
|
|
||||||
pub b: HdlOption<GetB<P>>,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
use fayalite::{
|
use fayalite::{
|
||||||
memory::{ReadStruct, ReadWriteStruct, WriteStruct},
|
memory::{ReadStruct, ReadWriteStruct, WriteStruct},
|
||||||
module::{instance_with_loc, memory_with_init_and_loc, reg_builder_with_loc},
|
module::{instance_with_loc, reg_builder_with_loc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
reset::ResetType,
|
reset::ResetType,
|
||||||
sim::vcd::VcdWriterDecls,
|
sim::vcd::VcdWriterDecls,
|
||||||
|
|
@ -1261,310 +1261,6 @@ fn test_memories3() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl_module(outline_generated)]
|
|
||||||
pub fn many_memories() {
|
|
||||||
#[hdl]
|
|
||||||
let r: Array<ReadStruct<Bool, ConstUsize<4>>, 8> = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let w: Array<WriteStruct<Bool, ConstUsize<4>>, 8> = m.input();
|
|
||||||
for (mem_index, (r, w)) in r.into_iter().zip(w).enumerate() {
|
|
||||||
let mut mem = memory_with_init_and_loc(
|
|
||||||
&format!("mem_{mem_index}"),
|
|
||||||
(0..16)
|
|
||||||
.map(|bit_index| mem_index.pow(5).to_expr()[bit_index])
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
SourceLocation::caller(),
|
|
||||||
);
|
|
||||||
connect_any(mem.new_read_port(), r);
|
|
||||||
connect_any(mem.new_write_port(), w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[test]
|
|
||||||
fn test_many_memories() {
|
|
||||||
let _n = SourceLocation::normalize_files_for_tests();
|
|
||||||
let mut sim = Simulation::new(many_memories());
|
|
||||||
let mut writer = RcWriter::default();
|
|
||||||
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
|
||||||
for r in sim.io().r {
|
|
||||||
sim.write_clock(r.clk, false);
|
|
||||||
}
|
|
||||||
for w in sim.io().w {
|
|
||||||
sim.write_clock(w.clk, false);
|
|
||||||
}
|
|
||||||
#[hdl(cmp_eq)]
|
|
||||||
struct IO {
|
|
||||||
r_addr: UInt<4>,
|
|
||||||
r_en: Bool,
|
|
||||||
r_data: Array<Bool, 8>,
|
|
||||||
w_addr: UInt<4>,
|
|
||||||
w_en: Bool,
|
|
||||||
w_data: Array<Bool, 8>,
|
|
||||||
w_mask: Array<Bool, 8>,
|
|
||||||
}
|
|
||||||
let io_cycles = [
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0_hdl_u4,
|
|
||||||
r_en: false,
|
|
||||||
r_data: [false; 8],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [false; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, true, false, true, false, true, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: true,
|
|
||||||
w_data: [true; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [true; 8],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: true,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false; 8],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 1_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, true, false, false, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 2_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, true, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 3_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, false, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 4_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, true, false, true, false, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 5_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, true, true, false, true, true, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 6_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, true, false, false, true, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 7_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, true, false, false, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 8_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 9_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, true, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xA_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, true, true, true, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xB_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, true, true, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xC_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, true, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xD_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, false, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xE_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, false, true],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
#[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr: 0xF_hdl_u4,
|
|
||||||
r_en: true,
|
|
||||||
r_data: [false, false, false, false, false, false, false, false],
|
|
||||||
w_addr: 0_hdl_u4,
|
|
||||||
w_en: false,
|
|
||||||
w_data: [false; 8],
|
|
||||||
w_mask: [true; 8],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
for (cycle, expected) in io_cycles.into_iter().enumerate() {
|
|
||||||
#[hdl(sim)]
|
|
||||||
let IO {
|
|
||||||
r_addr,
|
|
||||||
r_en,
|
|
||||||
r_data: _,
|
|
||||||
w_addr,
|
|
||||||
w_en,
|
|
||||||
w_data,
|
|
||||||
w_mask,
|
|
||||||
} = expected;
|
|
||||||
for (((r, w), w_data), w_mask) in sim
|
|
||||||
.io()
|
|
||||||
.r
|
|
||||||
.into_iter()
|
|
||||||
.zip(sim.io().w)
|
|
||||||
.zip(w_data.iter())
|
|
||||||
.zip(w_mask.iter())
|
|
||||||
{
|
|
||||||
sim.write(r.addr, &r_addr);
|
|
||||||
sim.write(r.en, &r_en);
|
|
||||||
sim.write(w.addr, &w_addr);
|
|
||||||
sim.write(w.en, &w_en);
|
|
||||||
sim.write(w.data, w_data);
|
|
||||||
sim.write(w.mask, w_mask);
|
|
||||||
}
|
|
||||||
let io = #[hdl(sim)]
|
|
||||||
IO {
|
|
||||||
r_addr,
|
|
||||||
r_en,
|
|
||||||
r_data: std::array::from_fn(|i| sim.read(sim.io().r[i].data)),
|
|
||||||
w_addr,
|
|
||||||
w_en,
|
|
||||||
w_data,
|
|
||||||
w_mask,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
expected,
|
|
||||||
io,
|
|
||||||
"vcd:\n{}\ncycle: {cycle}",
|
|
||||||
String::from_utf8(writer.take()).unwrap(),
|
|
||||||
);
|
|
||||||
sim.advance_time(SimDuration::from_micros(1));
|
|
||||||
for r in sim.io().r {
|
|
||||||
sim.write_clock(r.clk, true);
|
|
||||||
}
|
|
||||||
for w in sim.io().w {
|
|
||||||
sim.write_clock(w.clk, true);
|
|
||||||
}
|
|
||||||
sim.advance_time(SimDuration::from_micros(1));
|
|
||||||
for r in sim.io().r {
|
|
||||||
sim.write_clock(r.clk, false);
|
|
||||||
}
|
|
||||||
for w in sim.io().w {
|
|
||||||
sim.write_clock(w.clk, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sim.flush_traces().unwrap();
|
|
||||||
let vcd = String::from_utf8(writer.take()).unwrap();
|
|
||||||
println!("####### VCD:\n{vcd}\n#######");
|
|
||||||
if vcd != include_str!("sim/expected/many_memories.vcd") {
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
let sim_debug = format!("{sim:#?}");
|
|
||||||
println!("#######\n{sim_debug}\n#######");
|
|
||||||
if sim_debug != include_str!("sim/expected/many_memories.txt") {
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl_module(outline_generated)]
|
#[hdl_module(outline_generated)]
|
||||||
pub fn duplicate_names() {
|
pub fn duplicate_names() {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -2026,85 +1722,3 @@ 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!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -828,6 +828,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "array_rw",
|
name: "array_rw",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -1698,12 +1699,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 34 μs,
|
instant: 34 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +124,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
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: [
|
||||||
|
|
@ -176,12 +177,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 2 μs,
|
instant: 2 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +100,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "connect_const",
|
name: "connect_const",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -129,12 +130,7 @@ Simulation {
|
||||||
],
|
],
|
||||||
trace_memories: {},
|
trace_memories: {},
|
||||||
trace_writers: [],
|
trace_writers: [],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 0 s,
|
instant: 0 s,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +143,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
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: [
|
||||||
|
|
@ -196,12 +197,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 1 μs,
|
instant: 1 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -263,6 +263,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "counter",
|
name: "counter",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -328,7 +329,7 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
SimTrace {
|
SimTrace {
|
||||||
id: TraceScalarId(1),
|
id: TraceScalarId(1),
|
||||||
|
|
@ -354,7 +355,7 @@ Simulation {
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
trace_memories: {},
|
trace_memories: {},
|
||||||
|
|
@ -367,14 +368,9 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "counter",
|
name: "counter",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -309,7 +310,7 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
SimTrace {
|
SimTrace {
|
||||||
id: TraceScalarId(1),
|
id: TraceScalarId(1),
|
||||||
|
|
@ -335,7 +336,7 @@ Simulation {
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
trace_memories: {},
|
trace_memories: {},
|
||||||
|
|
@ -348,14 +349,9 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "duplicate_names",
|
name: "duplicate_names",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -159,12 +160,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 1 μs,
|
instant: 1 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1456,6 +1456,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "enums",
|
name: "enums",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -1743,7 +1744,7 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
SimTrace {
|
SimTrace {
|
||||||
id: TraceScalarId(1),
|
id: TraceScalarId(1),
|
||||||
|
|
@ -1923,14 +1924,9 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -186,8 +186,14 @@ 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: [
|
||||||
|
|
@ -241,14 +247,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 20 μs,
|
instant: 20 μs,
|
||||||
events: {
|
clocks_triggered: [],
|
||||||
Event { instant: 20.500000000000 μs, kind: ExternModule(0) }: 1,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -6,9 +6,8 @@ $upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
0!
|
0!
|
||||||
0"
|
|
||||||
$end
|
|
||||||
1"
|
1"
|
||||||
|
$end
|
||||||
#500000
|
#500000
|
||||||
#1500000
|
#1500000
|
||||||
0"
|
0"
|
||||||
|
|
|
||||||
|
|
@ -234,8 +234,55 @@ 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: [
|
||||||
|
|
@ -309,113 +356,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 60 μs,
|
instant: 60 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
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,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -8,9 +8,8 @@ $enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
1!
|
1!
|
||||||
0"
|
0"
|
||||||
b0 #
|
|
||||||
$end
|
|
||||||
b1001000 #
|
b1001000 #
|
||||||
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
1"
|
1"
|
||||||
b1100101 #
|
b1100101 #
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -721,6 +721,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "memories",
|
name: "memories",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -1615,15 +1616,10 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -234,13 +234,13 @@ b100000 6
|
||||||
b10000 9
|
b10000 9
|
||||||
b100000 I
|
b100000 I
|
||||||
1#
|
1#
|
||||||
b10000 $
|
|
||||||
b100000 %
|
|
||||||
1(
|
1(
|
||||||
1/
|
1/
|
||||||
|
14
|
||||||
|
b10000 $
|
||||||
|
b100000 %
|
||||||
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/
|
||||||
b1000000 1
|
|
||||||
14
|
14
|
||||||
|
b1000000 %
|
||||||
|
b1000000 1
|
||||||
#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/
|
||||||
b1010000 0
|
|
||||||
14
|
14
|
||||||
|
b1010000 $
|
||||||
|
b1010000 0
|
||||||
#8000000
|
#8000000
|
||||||
0#
|
0#
|
||||||
0(
|
0(
|
||||||
|
|
|
||||||
|
|
@ -679,6 +679,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "memories2",
|
name: "memories2",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -1259,14 +1260,9 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -100,8 +100,8 @@ $end
|
||||||
1)
|
1)
|
||||||
#1250000
|
#1250000
|
||||||
1#
|
1#
|
||||||
b11 $
|
|
||||||
1*
|
1*
|
||||||
|
b11 $
|
||||||
sHdlSome\x20(1) +
|
sHdlSome\x20(1) +
|
||||||
1,
|
1,
|
||||||
#1500000
|
#1500000
|
||||||
|
|
@ -113,8 +113,8 @@ sHdlSome\x20(1) +
|
||||||
0)
|
0)
|
||||||
#2250000
|
#2250000
|
||||||
1#
|
1#
|
||||||
b0 $
|
|
||||||
1*
|
1*
|
||||||
|
b0 $
|
||||||
sHdlNone\x20(0) +
|
sHdlNone\x20(0) +
|
||||||
0,
|
0,
|
||||||
#2500000
|
#2500000
|
||||||
|
|
@ -303,8 +303,8 @@ b11 !
|
||||||
b11 (
|
b11 (
|
||||||
#17250000
|
#17250000
|
||||||
1#
|
1#
|
||||||
b11 $
|
|
||||||
1*
|
1*
|
||||||
|
b11 $
|
||||||
sHdlSome\x20(1) +
|
sHdlSome\x20(1) +
|
||||||
1,
|
1,
|
||||||
#17500000
|
#17500000
|
||||||
|
|
@ -316,8 +316,8 @@ b10 !
|
||||||
b10 (
|
b10 (
|
||||||
#18250000
|
#18250000
|
||||||
1#
|
1#
|
||||||
b0 $
|
|
||||||
1*
|
1*
|
||||||
|
b0 $
|
||||||
sHdlNone\x20(0) +
|
sHdlNone\x20(0) +
|
||||||
0,
|
0,
|
||||||
#18500000
|
#18500000
|
||||||
|
|
@ -339,8 +339,8 @@ b1 !
|
||||||
b1 (
|
b1 (
|
||||||
#20250000
|
#20250000
|
||||||
1#
|
1#
|
||||||
b1 $
|
|
||||||
1*
|
1*
|
||||||
|
b1 $
|
||||||
sHdlSome\x20(1) +
|
sHdlSome\x20(1) +
|
||||||
#20500000
|
#20500000
|
||||||
#20750000
|
#20750000
|
||||||
|
|
@ -353,8 +353,8 @@ b0 (
|
||||||
0)
|
0)
|
||||||
#21250000
|
#21250000
|
||||||
1#
|
1#
|
||||||
b0 $
|
|
||||||
1*
|
1*
|
||||||
|
b0 $
|
||||||
sHdlNone\x20(0) +
|
sHdlNone\x20(0) +
|
||||||
#21500000
|
#21500000
|
||||||
#21750000
|
#21750000
|
||||||
|
|
|
||||||
|
|
@ -1763,6 +1763,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "memories3",
|
name: "memories3",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -3274,15 +3275,10 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -420,10 +420,6 @@ b10000 T
|
||||||
1\
|
1\
|
||||||
#3250000
|
#3250000
|
||||||
1#
|
1#
|
||||||
b110100 %
|
|
||||||
b1111000 '
|
|
||||||
b10011010 (
|
|
||||||
b11110000 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b110100 C
|
b110100 C
|
||||||
|
|
@ -431,6 +427,10 @@ b1111000 E
|
||||||
b10011010 F
|
b10011010 F
|
||||||
b11110000 I
|
b11110000 I
|
||||||
1L
|
1L
|
||||||
|
b110100 %
|
||||||
|
b1111000 '
|
||||||
|
b10011010 (
|
||||||
|
b11110000 +
|
||||||
#3500000
|
#3500000
|
||||||
#3750000
|
#3750000
|
||||||
0#
|
0#
|
||||||
|
|
@ -508,14 +508,6 @@ 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
|
||||||
|
|
@ -527,6 +519,14 @@ 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,14 +562,6 @@ 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
|
||||||
|
|
@ -581,6 +573,14 @@ 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,14 +688,6 @@ b1 !
|
||||||
b1 ?
|
b1 ?
|
||||||
#10250000
|
#10250000
|
||||||
1#
|
1#
|
||||||
b11111110 $
|
|
||||||
b11011100 %
|
|
||||||
b10111010 &
|
|
||||||
b10011000 '
|
|
||||||
b1110110 (
|
|
||||||
b1010100 )
|
|
||||||
b110010 *
|
|
||||||
b10000 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b11111110 B
|
b11111110 B
|
||||||
|
|
@ -707,6 +699,14 @@ 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,14 +718,6 @@ b10 !
|
||||||
b10 ?
|
b10 ?
|
||||||
#11250000
|
#11250000
|
||||||
1#
|
1#
|
||||||
b10011 $
|
|
||||||
b1010111 %
|
|
||||||
b10011011 &
|
|
||||||
b11011111 '
|
|
||||||
b10 (
|
|
||||||
b1000110 )
|
|
||||||
b10001010 *
|
|
||||||
b11001110 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b10011 B
|
b10011 B
|
||||||
|
|
@ -737,6 +729,14 @@ 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,14 +748,6 @@ b11 !
|
||||||
b11 ?
|
b11 ?
|
||||||
#12250000
|
#12250000
|
||||||
1#
|
1#
|
||||||
b1110100 $
|
|
||||||
b1100101 %
|
|
||||||
b1110011 &
|
|
||||||
b1110100 '
|
|
||||||
b1101001 (
|
|
||||||
b1101110 )
|
|
||||||
b1100111 *
|
|
||||||
b100001 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b1110100 B
|
b1110100 B
|
||||||
|
|
@ -767,6 +759,14 @@ 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,14 +780,6 @@ b0 ?
|
||||||
0@
|
0@
|
||||||
#13250000
|
#13250000
|
||||||
1#
|
1#
|
||||||
b1101101 $
|
|
||||||
b1101111 %
|
|
||||||
b1110010 &
|
|
||||||
b1100101 '
|
|
||||||
b100000 (
|
|
||||||
b1110100 )
|
|
||||||
b1110011 *
|
|
||||||
b1110100 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b1101101 B
|
b1101101 B
|
||||||
|
|
@ -799,6 +791,14 @@ 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,14 +808,6 @@ b1110100 I
|
||||||
#14000000
|
#14000000
|
||||||
#14250000
|
#14250000
|
||||||
1#
|
1#
|
||||||
b0 $
|
|
||||||
b0 %
|
|
||||||
b0 &
|
|
||||||
b0 '
|
|
||||||
b0 (
|
|
||||||
b0 )
|
|
||||||
b0 *
|
|
||||||
b0 +
|
|
||||||
1.
|
1.
|
||||||
1A
|
1A
|
||||||
b0 B
|
b0 B
|
||||||
|
|
@ -827,6 +819,14 @@ 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#
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "mod1",
|
name: "mod1",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -557,12 +558,7 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 2 μs,
|
instant: 2 μs,
|
||||||
events: {},
|
clocks_triggered: [],
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -827,6 +827,52 @@ 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 {
|
||||||
|
|
@ -910,6 +956,52 @@ 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 {
|
||||||
|
|
@ -993,8 +1085,55 @@ 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: [
|
||||||
|
|
@ -1454,315 +1593,11 @@ 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
|
|
@ -339,6 +339,7 @@ Simulation {
|
||||||
did_initial_settle: true,
|
did_initial_settle: true,
|
||||||
},
|
},
|
||||||
extern_modules: [],
|
extern_modules: [],
|
||||||
|
state_ready_to_run: false,
|
||||||
trace_decls: TraceModule {
|
trace_decls: TraceModule {
|
||||||
name: "shift_register",
|
name: "shift_register",
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -439,7 +440,7 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
SimTrace {
|
SimTrace {
|
||||||
id: TraceScalarId(1),
|
id: TraceScalarId(1),
|
||||||
|
|
@ -508,14 +509,9 @@ 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: {},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,523 +0,0 @@
|
||||||
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,
|
|
||||||
},
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
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: "",
|
|
||||||
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: "",
|
|
||||||
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
|
|
@ -717,6 +717,52 @@ 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 {
|
||||||
|
|
@ -876,8 +922,55 @@ 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: [
|
||||||
|
|
@ -1535,214 +1628,9 @@ 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: "",
|
|
||||||
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: "",
|
|
||||||
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: "",
|
|
||||||
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: "",
|
|
||||||
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,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -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{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} %
|
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\"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\"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\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} &
|
s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} 8
|
||||||
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,6 +107,9 @@ 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'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue