Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34b4a57507 |
166 changed files with 12975 additions and 91653 deletions
|
|
@ -16,9 +16,6 @@ jobs:
|
||||||
- uses: https://git.libre-chip.org/mirrors/rust-cache@v2
|
- uses: https://git.libre-chip.org/mirrors/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
save-if: ${{ github.ref == 'refs/heads/master' }}
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
- run: rustup override set 1.93.0
|
|
||||||
- run: rustup component add rust-src
|
|
||||||
- run: make -C rocq-demo
|
|
||||||
- run: cargo test
|
- run: cargo test
|
||||||
- run: cargo build --tests --features=unstable-doc
|
- run: cargo build --tests --features=unstable-doc
|
||||||
- run: cargo test --doc --features=unstable-doc
|
- run: cargo test --doc --features=unstable-doc
|
||||||
|
|
|
||||||
6
Cargo.lock
generated
6
Cargo.lock
generated
|
|
@ -319,12 +319,10 @@ dependencies = [
|
||||||
"jobslot",
|
"jobslot",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"trybuild",
|
"trybuild",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
|
|
@ -523,9 +521,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ edition = "2024"
|
||||||
repository = "https://git.libre-chip.org/libre-chip/fayalite"
|
repository = "https://git.libre-chip.org/libre-chip/fayalite"
|
||||||
keywords = ["hdl", "hardware", "semiconductors", "firrtl", "fpga"]
|
keywords = ["hdl", "hardware", "semiconductors", "firrtl", "fpga"]
|
||||||
categories = ["simulation", "development-tools", "compilers"]
|
categories = ["simulation", "development-tools", "compilers"]
|
||||||
rust-version = "1.93.0"
|
rust-version = "1.89.0"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" }
|
fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" }
|
||||||
|
|
@ -30,7 +30,6 @@ indexmap = { version = "2.5.0", features = ["serde"] }
|
||||||
jobslot = "0.2.23"
|
jobslot = "0.2.23"
|
||||||
num-bigint = "0.4.6"
|
num-bigint = "0.4.6"
|
||||||
num-traits = "0.2.16"
|
num-traits = "0.2.16"
|
||||||
once_cell = "1.21.3"
|
|
||||||
ordered-float = { version = "5.1.0", features = ["serde"] }
|
ordered-float = { version = "5.1.0", features = ["serde"] }
|
||||||
petgraph = "0.8.1"
|
petgraph = "0.8.1"
|
||||||
prettyplease = "0.2.20"
|
prettyplease = "0.2.20"
|
||||||
|
|
|
||||||
21
Makefile
Normal file
21
Makefile
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
DIRU=/home/alex/Desktop/Hacking/libre-chip/fayalite-wip/target/blinky-out
|
||||||
|
NEXTPNR_DENSITY:=--25k
|
||||||
|
|
||||||
|
all:
|
||||||
|
cp $(DIRU)/*.pcf /tmp
|
||||||
|
RUST_BACKTRACE=full cargo run --example blinky yosys-nextpnr-ecp5 \
|
||||||
|
--nextpnr /home/alex/.guix-profile/bin/nextpnr-ecp5 \
|
||||||
|
--platform orangecrab-85k -o target/blinky-out \
|
||||||
|
--ecppack /home/alex/.guix-profile/bin/ecppack \
|
||||||
|
--placeholder-dir /tmp/anyPathBuf/orangecrab_r0.2.1.pcf
|
||||||
|
ls -1 $(DIRU)/*.bit
|
||||||
|
ls:
|
||||||
|
ls -1 $(DIRU)
|
||||||
|
clean:
|
||||||
|
rm $(DIRU)/*
|
||||||
|
nextpnr:
|
||||||
|
cd $(DIRU) && nextpnr-ecp5 --json blinky.json --textcfg blinky.nextpnr.out $(NEXTPNR_DENSITY) \
|
||||||
|
--package CSFBGA285 --lpf orangecrab_r0.2.1.pcf --lpf-allow-unconstrained
|
||||||
|
pack:
|
||||||
|
cd $(DIRU) && ecppack --compress --freq 38.8 --input blinky.nextpnr.out --bit blinky.nextpnr.bit
|
||||||
|
cd $(DIRU) && file *.bit
|
||||||
|
|
@ -257,6 +257,5 @@ no_op_fold!(syn::Token![let]);
|
||||||
no_op_fold!(syn::Token![mut]);
|
no_op_fold!(syn::Token![mut]);
|
||||||
no_op_fold!(syn::Token![static]);
|
no_op_fold!(syn::Token![static]);
|
||||||
no_op_fold!(syn::Token![struct]);
|
no_op_fold!(syn::Token![struct]);
|
||||||
no_op_fold!(syn::Token![type]);
|
|
||||||
no_op_fold!(syn::Token![where]);
|
no_op_fold!(syn::Token![where]);
|
||||||
no_op_fold!(usize);
|
no_op_fold!(usize);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Errors, HdlAttr, PairsIterExt,
|
Errors, HdlAttr, PairsIterExt,
|
||||||
hdl_type_common::{
|
hdl_type_common::{
|
||||||
CustomDebugOptions, CustomDebugTrait, ItemOptions, MakeHdlTypeExpr, MaybeParsed,
|
ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedField, ParsedFieldsNamed, ParsedGenerics,
|
||||||
ParsedField, ParsedFieldsNamed, ParsedGenerics, SplitForImpl, TypesParser, WrappedInConst,
|
SplitForImpl, TypesParser, WrappedInConst, common_derives, get_target,
|
||||||
common_derives, create_struct_debug_impl, get_target,
|
|
||||||
},
|
},
|
||||||
kw,
|
kw,
|
||||||
};
|
};
|
||||||
|
|
@ -31,7 +30,6 @@ pub(crate) struct ParsedBundle {
|
||||||
pub(crate) fields: MaybeParsed<ParsedFieldsNamed, FieldsNamed>,
|
pub(crate) fields: MaybeParsed<ParsedFieldsNamed, FieldsNamed>,
|
||||||
pub(crate) field_flips: Vec<Option<HdlAttr<kw::flip, kw::hdl>>>,
|
pub(crate) field_flips: Vec<Option<HdlAttr<kw::flip, kw::hdl>>>,
|
||||||
pub(crate) mask_type_ident: Ident,
|
pub(crate) mask_type_ident: Ident,
|
||||||
pub(crate) mask_type_name: String,
|
|
||||||
pub(crate) mask_type_match_variant_ident: Ident,
|
pub(crate) mask_type_match_variant_ident: Ident,
|
||||||
pub(crate) mask_type_sim_value_ident: Ident,
|
pub(crate) mask_type_sim_value_ident: Ident,
|
||||||
pub(crate) match_variant_ident: Ident,
|
pub(crate) match_variant_ident: Ident,
|
||||||
|
|
@ -90,8 +88,6 @@ impl ParsedBundle {
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq: _,
|
cmp_eq: _,
|
||||||
ref get,
|
ref get,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display: _,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
if let Some((get, ..)) = get {
|
if let Some((get, ..)) = get {
|
||||||
errors.error(get, "#[hdl(get(...))] is not allowed on structs");
|
errors.error(get, "#[hdl(get(...))] is not allowed on structs");
|
||||||
|
|
@ -135,7 +131,6 @@ impl ParsedBundle {
|
||||||
fields,
|
fields,
|
||||||
field_flips,
|
field_flips,
|
||||||
mask_type_ident: format_ident!("__{}__MaskType", ident),
|
mask_type_ident: format_ident!("__{}__MaskType", ident),
|
||||||
mask_type_name: format!("MaskType<{}>", ident),
|
|
||||||
mask_type_match_variant_ident: format_ident!("__{}__MaskType__MatchVariant", ident),
|
mask_type_match_variant_ident: format_ident!("__{}__MaskType__MatchVariant", ident),
|
||||||
mask_type_sim_value_ident: format_ident!("__{}__MaskType__SimValue", ident),
|
mask_type_sim_value_ident: format_ident!("__{}__MaskType__SimValue", ident),
|
||||||
match_variant_ident: format_ident!("__{}__MatchVariant", ident),
|
match_variant_ident: format_ident!("__{}__MatchVariant", ident),
|
||||||
|
|
@ -453,7 +448,6 @@ impl ToTokens for ParsedBundle {
|
||||||
fields,
|
fields,
|
||||||
field_flips,
|
field_flips,
|
||||||
mask_type_ident,
|
mask_type_ident,
|
||||||
mask_type_name,
|
|
||||||
mask_type_match_variant_ident,
|
mask_type_match_variant_ident,
|
||||||
mask_type_sim_value_ident,
|
mask_type_sim_value_ident,
|
||||||
match_variant_ident,
|
match_variant_ident,
|
||||||
|
|
@ -470,20 +464,11 @@ impl ToTokens for ParsedBundle {
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
get: _,
|
get: _,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let CustomDebugOptions {
|
|
||||||
type_: custom_debug_type,
|
|
||||||
sim: custom_debug_sim,
|
|
||||||
mask_type: custom_debug_mask_type,
|
|
||||||
mask_sim: custom_debug_mask_sim,
|
|
||||||
} = options.body.custom_debug();
|
|
||||||
let target = get_target(target, ident);
|
let target = get_target(target, ident);
|
||||||
let struct_name = ident.to_string();
|
|
||||||
let mut item_attrs = attrs.clone();
|
let mut item_attrs = attrs.clone();
|
||||||
item_attrs.push(common_derives(span, false));
|
item_attrs.push(common_derives(span));
|
||||||
let type_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: item_attrs,
|
attrs: item_attrs,
|
||||||
vis: vis.clone(),
|
vis: vis.clone(),
|
||||||
struct_token: *struct_token,
|
struct_token: *struct_token,
|
||||||
|
|
@ -491,8 +476,8 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(fields.clone().into()),
|
fields: Fields::Named(fields.clone().into()),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
}
|
||||||
type_struct.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||||
if let (MaybeParsed::Parsed(generics), MaybeParsed::Parsed(fields), None) =
|
if let (MaybeParsed::Parsed(generics), MaybeParsed::Parsed(fields), None) =
|
||||||
(generics, fields, no_runtime_generics)
|
(generics, fields, no_runtime_generics)
|
||||||
|
|
@ -518,9 +503,6 @@ impl ToTokens for ParsedBundle {
|
||||||
}
|
}
|
||||||
let mut wrapped_in_const = WrappedInConst::new(tokens, span);
|
let mut wrapped_in_const = WrappedInConst::new(tokens, span);
|
||||||
let tokens = wrapped_in_const.inner();
|
let tokens = wrapped_in_const.inner();
|
||||||
if custom_debug_type.is_none() {
|
|
||||||
create_struct_debug_impl(&type_struct, &struct_name, None).to_tokens(tokens);
|
|
||||||
}
|
|
||||||
let builder = Builder {
|
let builder = Builder {
|
||||||
vis: vis.clone(),
|
vis: vis.clone(),
|
||||||
struct_token: *struct_token,
|
struct_token: *struct_token,
|
||||||
|
|
@ -548,9 +530,9 @@ impl ToTokens for ParsedBundle {
|
||||||
mask_type_builder.to_tokens(tokens);
|
mask_type_builder.to_tokens(tokens);
|
||||||
let unfilled_mask_type_builder_ty =
|
let unfilled_mask_type_builder_ty =
|
||||||
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
||||||
let mask_type_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span, false),
|
common_derives(span),
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
},
|
},
|
||||||
|
|
@ -561,20 +543,17 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(mask_type_fields.clone()),
|
fields: Fields::Named(mask_type_fields.clone()),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
|
||||||
mask_type_struct.to_tokens(tokens);
|
|
||||||
if custom_debug_mask_type.is_none() {
|
|
||||||
create_struct_debug_impl(&mask_type_struct, mask_type_name, None).to_tokens(tokens);
|
|
||||||
}
|
}
|
||||||
|
.to_tokens(tokens);
|
||||||
let mut mask_type_match_variant_fields = mask_type_fields.clone();
|
let mut mask_type_match_variant_fields = mask_type_fields.clone();
|
||||||
for Field { ty, .. } in &mut mask_type_match_variant_fields.named {
|
for Field { ty, .. } in &mut mask_type_match_variant_fields.named {
|
||||||
*ty = parse_quote_spanned! {span=>
|
*ty = parse_quote_spanned! {span=>
|
||||||
::fayalite::expr::Expr<#ty>
|
::fayalite::expr::Expr<#ty>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let mask_type_match_variant_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span, false),
|
common_derives(span),
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
},
|
},
|
||||||
|
|
@ -585,19 +564,17 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(mask_type_match_variant_fields),
|
fields: Fields::Named(mask_type_match_variant_fields),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
}
|
||||||
mask_type_match_variant_struct.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
create_struct_debug_impl(&mask_type_match_variant_struct, mask_type_name, None)
|
|
||||||
.to_tokens(tokens);
|
|
||||||
let mut match_variant_fields = FieldsNamed::from(fields.clone());
|
let mut match_variant_fields = FieldsNamed::from(fields.clone());
|
||||||
for Field { ty, .. } in &mut match_variant_fields.named {
|
for Field { ty, .. } in &mut match_variant_fields.named {
|
||||||
*ty = parse_quote_spanned! {span=>
|
*ty = parse_quote_spanned! {span=>
|
||||||
::fayalite::expr::Expr<#ty>
|
::fayalite::expr::Expr<#ty>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let match_variant_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span, false),
|
common_derives(span),
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
},
|
},
|
||||||
|
|
@ -608,19 +585,19 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(match_variant_fields),
|
fields: Fields::Named(match_variant_fields),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
}
|
||||||
match_variant_struct.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
create_struct_debug_impl(&match_variant_struct, &struct_name, None).to_tokens(tokens);
|
|
||||||
let mut mask_type_sim_value_fields = mask_type_fields;
|
let mut mask_type_sim_value_fields = mask_type_fields;
|
||||||
for Field { ty, .. } in &mut mask_type_sim_value_fields.named {
|
for Field { ty, .. } in &mut mask_type_sim_value_fields.named {
|
||||||
*ty = parse_quote_spanned! {span=>
|
*ty = parse_quote_spanned! {span=>
|
||||||
::fayalite::sim::value::SimValue<#ty>
|
::fayalite::sim::value::SimValue<#ty>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let mask_type_sim_value_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[::fayalite::__std::prelude::v1::derive(
|
#[::fayalite::__std::prelude::v1::derive(
|
||||||
|
::fayalite::__std::fmt::Debug,
|
||||||
::fayalite::__std::clone::Clone,
|
::fayalite::__std::clone::Clone,
|
||||||
)]
|
)]
|
||||||
},
|
},
|
||||||
|
|
@ -634,34 +611,19 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(mask_type_sim_value_fields),
|
fields: Fields::Named(mask_type_sim_value_fields),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
|
||||||
mask_type_sim_value_struct.to_tokens(tokens);
|
|
||||||
if custom_debug_mask_sim.is_none() {
|
|
||||||
create_struct_debug_impl(
|
|
||||||
&mask_type_struct,
|
|
||||||
mask_type_name,
|
|
||||||
Some(CustomDebugTrait {
|
|
||||||
trait_path: &parse_quote_spanned! {span=>
|
|
||||||
::fayalite::ty::SimValueDebug
|
|
||||||
},
|
|
||||||
fn_name: &format_ident!("sim_value_debug", span = span),
|
|
||||||
this_arg: &parse_quote_spanned! {span=>
|
|
||||||
value: &<Self as ::fayalite::ty::Type>::SimValue
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.to_tokens(tokens);
|
|
||||||
}
|
}
|
||||||
|
.to_tokens(tokens);
|
||||||
let mut sim_value_fields = FieldsNamed::from(fields.clone());
|
let mut sim_value_fields = FieldsNamed::from(fields.clone());
|
||||||
for Field { ty, .. } in &mut sim_value_fields.named {
|
for Field { ty, .. } in &mut sim_value_fields.named {
|
||||||
*ty = parse_quote_spanned! {span=>
|
*ty = parse_quote_spanned! {span=>
|
||||||
::fayalite::sim::value::SimValue<#ty>
|
::fayalite::sim::value::SimValue<#ty>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let sim_value_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[::fayalite::__std::prelude::v1::derive(
|
#[::fayalite::__std::prelude::v1::derive(
|
||||||
|
::fayalite::__std::fmt::Debug,
|
||||||
::fayalite::__std::clone::Clone,
|
::fayalite::__std::clone::Clone,
|
||||||
)]
|
)]
|
||||||
},
|
},
|
||||||
|
|
@ -675,36 +637,8 @@ impl ToTokens for ParsedBundle {
|
||||||
generics: generics.into(),
|
generics: generics.into(),
|
||||||
fields: Fields::Named(sim_value_fields),
|
fields: Fields::Named(sim_value_fields),
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
|
||||||
sim_value_struct.to_tokens(tokens);
|
|
||||||
if custom_debug_sim.is_none() {
|
|
||||||
create_struct_debug_impl(
|
|
||||||
&type_struct,
|
|
||||||
&struct_name,
|
|
||||||
Some(CustomDebugTrait {
|
|
||||||
trait_path: &parse_quote_spanned! {span=>
|
|
||||||
::fayalite::ty::SimValueDebug
|
|
||||||
},
|
|
||||||
fn_name: &format_ident!("sim_value_debug", span = span),
|
|
||||||
this_arg: &parse_quote_spanned! {span=>
|
|
||||||
value: &<Self as ::fayalite::ty::Type>::SimValue
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
if custom_sim_display.is_some() {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::__std::fmt::Display for #sim_value_ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
<#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.to_tokens(tokens);
|
|
||||||
}
|
}
|
||||||
|
.to_tokens(tokens);
|
||||||
let this_token = Ident::new("__this", span);
|
let this_token = Ident::new("__this", span);
|
||||||
let fields_token = Ident::new("__fields", span);
|
let fields_token = Ident::new("__fields", span);
|
||||||
let self_token = Token;
|
let self_token = Token;
|
||||||
|
|
@ -886,14 +820,6 @@ impl ToTokens for ParsedBundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics ::fayalite::__std::fmt::Debug for #mask_type_sim_value_ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
<#mask_type_ident #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::expr::ValueType for #mask_type_sim_value_ident #type_generics
|
impl #impl_generics ::fayalite::expr::ValueType for #mask_type_sim_value_ident #type_generics
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
|
|
@ -1054,14 +980,6 @@ impl ToTokens for ParsedBundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics ::fayalite::__std::fmt::Debug for #sim_value_ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
<#target #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::expr::ValueType for #sim_value_ident #type_generics
|
impl #impl_generics ::fayalite::expr::ValueType for #sim_value_ident #type_generics
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
|
|
@ -1223,7 +1141,7 @@ impl ToTokens for ParsedBundle {
|
||||||
valueless_eq_body = quote_spanned! {span=>
|
valueless_eq_body = quote_spanned! {span=>
|
||||||
let __lhs = ::fayalite::expr::ValueType::ty(&__lhs);
|
let __lhs = ::fayalite::expr::ValueType::ty(&__lhs);
|
||||||
let __rhs = ::fayalite::expr::ValueType::ty(&__rhs);
|
let __rhs = ::fayalite::expr::ValueType::ty(&__rhs);
|
||||||
#(#fields_valueless_eq)&*
|
#(#fields_valueless_eq)|*
|
||||||
};
|
};
|
||||||
valueless_ne_body = quote_spanned! {span=>
|
valueless_ne_body = quote_spanned! {span=>
|
||||||
let __lhs = ::fayalite::expr::ValueType::ty(&__lhs);
|
let __lhs = ::fayalite::expr::ValueType::ty(&__lhs);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Errors, HdlAttr, PairsIterExt,
|
Errors, HdlAttr, PairsIterExt,
|
||||||
hdl_type_common::{
|
hdl_type_common::{
|
||||||
CustomDebugOptions, ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType,
|
ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, SplitForImpl,
|
||||||
SplitForImpl, TypesParser, WrappedInConst, common_derives, create_struct_debug_impl,
|
TypesParser, WrappedInConst, common_derives, get_target,
|
||||||
get_target,
|
|
||||||
},
|
},
|
||||||
kw,
|
kw,
|
||||||
};
|
};
|
||||||
|
|
@ -159,32 +158,15 @@ impl ParsedEnum {
|
||||||
custom_bounds,
|
custom_bounds,
|
||||||
no_static: _,
|
no_static: _,
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq: _,
|
cmp_eq,
|
||||||
ref get,
|
ref get,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display: _,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
|
if let Some((cmp_eq,)) = cmp_eq {
|
||||||
|
errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums");
|
||||||
|
}
|
||||||
if let Some((get, ..)) = get {
|
if let Some((get, ..)) = get {
|
||||||
errors.error(get, "#[hdl(get(...))] is not allowed on enums");
|
errors.error(get, "#[hdl(get(...))] is not allowed on enums");
|
||||||
}
|
}
|
||||||
let CustomDebugOptions {
|
|
||||||
type_: _,
|
|
||||||
sim: _,
|
|
||||||
mask_type,
|
|
||||||
mask_sim,
|
|
||||||
} = options.body.custom_debug();
|
|
||||||
if let Some((mask_type,)) = mask_type {
|
|
||||||
errors.error(
|
|
||||||
mask_type,
|
|
||||||
"#[hdl(custom_debug(mask_type)] is not allowed on enums",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some((mask_sim,)) = mask_sim {
|
|
||||||
errors.error(
|
|
||||||
mask_sim,
|
|
||||||
"#[hdl(custom_debug(mask_sim)] 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");
|
||||||
|
|
@ -246,21 +228,12 @@ impl ToTokens for ParsedEnum {
|
||||||
custom_bounds: _,
|
custom_bounds: _,
|
||||||
no_static,
|
no_static,
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq,
|
cmp_eq: _, // TODO: implement cmp_eq for enums
|
||||||
get: _,
|
get: _,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let CustomDebugOptions {
|
|
||||||
type_: custom_debug_type,
|
|
||||||
sim: custom_debug_sim,
|
|
||||||
mask_type: _,
|
|
||||||
mask_sim: _,
|
|
||||||
} = options.body.custom_debug();
|
|
||||||
let target = get_target(target, ident);
|
let target = get_target(target, ident);
|
||||||
let enum_name = ident.to_string();
|
|
||||||
let mut struct_attrs = attrs.clone();
|
let mut struct_attrs = attrs.clone();
|
||||||
struct_attrs.push(common_derives(span, false));
|
struct_attrs.push(common_derives(span));
|
||||||
struct_attrs.push(parse_quote_spanned! {span=>
|
struct_attrs.push(parse_quote_spanned! {span=>
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
});
|
});
|
||||||
|
|
@ -300,7 +273,7 @@ impl ToTokens for ParsedEnum {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
let type_struct = ItemStruct {
|
ItemStruct {
|
||||||
attrs: struct_attrs,
|
attrs: struct_attrs,
|
||||||
vis: vis.clone(),
|
vis: vis.clone(),
|
||||||
struct_token: Token,
|
struct_token: Token,
|
||||||
|
|
@ -315,8 +288,8 @@ impl ToTokens for ParsedEnum {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
semi_token: None,
|
semi_token: None,
|
||||||
};
|
}
|
||||||
type_struct.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||||
if let (MaybeParsed::Parsed(generics), None) = (generics, no_runtime_generics) {
|
if let (MaybeParsed::Parsed(generics), None) = (generics, no_runtime_generics) {
|
||||||
generics.make_runtime_generics(tokens, vis, ident, &target, |context| {
|
generics.make_runtime_generics(tokens, vis, ident, &target, |context| {
|
||||||
|
|
@ -400,9 +373,6 @@ impl ToTokens for ParsedEnum {
|
||||||
}
|
}
|
||||||
.to_tokens(tokens);
|
.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
if custom_debug_type.is_none() {
|
|
||||||
create_struct_debug_impl(&type_struct, &enum_name, None).to_tokens(tokens);
|
|
||||||
}
|
|
||||||
let mut enum_attrs = attrs.clone();
|
let mut enum_attrs = attrs.clone();
|
||||||
enum_attrs.push(parse_quote_spanned! {span=>
|
enum_attrs.push(parse_quote_spanned! {span=>
|
||||||
#[allow(dead_code, non_camel_case_types)]
|
#[allow(dead_code, non_camel_case_types)]
|
||||||
|
|
@ -483,6 +453,7 @@ impl ToTokens for ParsedEnum {
|
||||||
let mut enum_attrs = attrs.clone();
|
let mut enum_attrs = attrs.clone();
|
||||||
enum_attrs.push(parse_quote_spanned! {span=>
|
enum_attrs.push(parse_quote_spanned! {span=>
|
||||||
#[::fayalite::__std::prelude::v1::derive(
|
#[::fayalite::__std::prelude::v1::derive(
|
||||||
|
::fayalite::__std::fmt::Debug,
|
||||||
::fayalite::__std::clone::Clone,
|
::fayalite::__std::clone::Clone,
|
||||||
)]
|
)]
|
||||||
});
|
});
|
||||||
|
|
@ -867,240 +838,6 @@ impl ToTokens for ParsedEnum {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
if custom_debug_sim.is_none() {
|
|
||||||
let debug_match_arms = Vec::from_iter(
|
|
||||||
variants
|
|
||||||
.iter()
|
|
||||||
.map(
|
|
||||||
|ParsedVariant {
|
|
||||||
attrs: _,
|
|
||||||
options: _,
|
|
||||||
ident,
|
|
||||||
field,
|
|
||||||
}| {
|
|
||||||
let variant_name = ident.to_string();
|
|
||||||
if let Some(_) = field {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#sim_value_ident::#ident(field, _) => {
|
|
||||||
f.debug_tuple(#variant_name).field(field).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#sim_value_ident::#ident(_) => {
|
|
||||||
f.write_str(#variant_name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.chain(sim_value_unknown_variant_name.as_ref().map(
|
|
||||||
|sim_value_unknown_variant_name| {
|
|
||||||
let sim_value_unknown_variant_name_str =
|
|
||||||
sim_value_unknown_variant_name.to_string();
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#sim_value_ident::#sim_value_unknown_variant_name(_) => {
|
|
||||||
f.write_str(#sim_value_unknown_variant_name_str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::ty::SimValueDebug for #target #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as ::fayalite::ty::Type>::SimValue,
|
|
||||||
f: &mut ::fayalite::__std::fmt::Formatter<'_>,
|
|
||||||
) -> ::fayalite::__std::fmt::Result {
|
|
||||||
match value {
|
|
||||||
#(#debug_match_arms)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
if custom_sim_display.is_some() {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::__std::fmt::Display for #sim_value_ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
<#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
if let Some((cmp_eq,)) = cmp_eq {
|
|
||||||
let mut cmp_eq_where_clause =
|
|
||||||
Generics::from(generics)
|
|
||||||
.where_clause
|
|
||||||
.unwrap_or_else(|| syn::WhereClause {
|
|
||||||
where_token: Token,
|
|
||||||
predicates: Punctuated::new(),
|
|
||||||
});
|
|
||||||
let mut variants_value_eq = vec![];
|
|
||||||
let mut variants_expr_eq = vec![];
|
|
||||||
let mut fields_valueless_eq = vec![];
|
|
||||||
for (
|
|
||||||
variant_index,
|
|
||||||
ParsedVariant {
|
|
||||||
attrs: _,
|
|
||||||
options: variant_options,
|
|
||||||
ident: variant_ident,
|
|
||||||
field,
|
|
||||||
},
|
|
||||||
) in variants.iter().enumerate()
|
|
||||||
{
|
|
||||||
let VariantOptions {} = variant_options.body;
|
|
||||||
if let Some(ParsedVariantField {
|
|
||||||
paren_token: _,
|
|
||||||
attrs: _,
|
|
||||||
options: field_options,
|
|
||||||
ty: field_ty,
|
|
||||||
comma_token: _,
|
|
||||||
}) = field
|
|
||||||
{
|
|
||||||
let FieldOptions {} = field_options.body;
|
|
||||||
cmp_eq_where_clause
|
|
||||||
.predicates
|
|
||||||
.push(parse_quote_spanned! {cmp_eq.span=>
|
|
||||||
#field_ty: ::fayalite::expr::HdlPartialEqImpl<#field_ty>
|
|
||||||
});
|
|
||||||
variants_value_eq.push(quote_spanned! {span=>
|
|
||||||
(#sim_value_ident::#variant_ident(__lhs_field, _), #sim_value_ident::#variant_ident(__rhs_field, _)) => {
|
|
||||||
::fayalite::expr::HdlPartialEqImpl::cmp_value_eq(
|
|
||||||
__lhs.#variant_ident,
|
|
||||||
::fayalite::__std::borrow::Cow::Borrowed(__lhs_field),
|
|
||||||
__rhs.#variant_ident,
|
|
||||||
::fayalite::__std::borrow::Cow::Borrowed(__rhs_field),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
variants_expr_eq.push(quote_spanned! {span=>
|
|
||||||
{
|
|
||||||
let (#match_variant_ident::#variant_ident(__lhs), __scope) =
|
|
||||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
|
||||||
::fayalite::__std::iter::Iterator::next(&mut __lhs_match_variant_iter)
|
|
||||||
.expect("known to have enough variants"),
|
|
||||||
)
|
|
||||||
else {
|
|
||||||
::fayalite::__std::unreachable!();
|
|
||||||
};
|
|
||||||
let (#match_variant_ident::#variant_ident(__rhs), __scope) =
|
|
||||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
|
||||||
::fayalite::__std::iter::Iterator::nth(
|
|
||||||
&mut ::fayalite::module::match_(__rhs),
|
|
||||||
#variant_index,
|
|
||||||
)
|
|
||||||
.expect("known to have variant"),
|
|
||||||
)
|
|
||||||
else {
|
|
||||||
::fayalite::__std::unreachable!();
|
|
||||||
};
|
|
||||||
::fayalite::module::connect(__retval, ::fayalite::expr::HdlPartialEqImpl::cmp_expr_eq(__lhs, __rhs));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fields_valueless_eq.push(quote_spanned! {span=>
|
|
||||||
::fayalite::expr::HdlPartialEqImpl::cmp_valueless_eq(
|
|
||||||
::fayalite::expr::Valueless::new(__lhs.#variant_ident),
|
|
||||||
::fayalite::expr::Valueless::new(__rhs.#variant_ident),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
variants_value_eq.push(quote_spanned! {span=>
|
|
||||||
(#sim_value_ident::#variant_ident(_), #sim_value_ident::#variant_ident(_)) => true,
|
|
||||||
});
|
|
||||||
variants_expr_eq.push(quote_spanned! {span=>
|
|
||||||
{
|
|
||||||
let (#match_variant_ident::#variant_ident, __scope) =
|
|
||||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
|
||||||
::fayalite::__std::iter::Iterator::next(&mut __lhs_match_variant_iter)
|
|
||||||
.expect("known to have enough variants"),
|
|
||||||
)
|
|
||||||
else {
|
|
||||||
::fayalite::__std::unreachable!();
|
|
||||||
};
|
|
||||||
let (#match_variant_ident::#variant_ident, __scope) =
|
|
||||||
::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope(
|
|
||||||
::fayalite::__std::iter::Iterator::nth(
|
|
||||||
&mut ::fayalite::module::match_(__rhs),
|
|
||||||
#variant_index,
|
|
||||||
)
|
|
||||||
.expect("known to have variant"),
|
|
||||||
)
|
|
||||||
else {
|
|
||||||
::fayalite::__std::unreachable!();
|
|
||||||
};
|
|
||||||
::fayalite::module::connect(__retval, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(sim_value_unknown_variant_name) = &sim_value_unknown_variant_name {
|
|
||||||
variants_value_eq.push(quote_spanned! {span=>
|
|
||||||
(#sim_value_ident::#sim_value_unknown_variant_name(__lhs_unknown), #sim_value_ident::#sim_value_unknown_variant_name(__rhs_unknown)) => {
|
|
||||||
__lhs_unknown == __rhs_unknown
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let valueless_eq_body = if fields_valueless_eq.is_empty() {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
::fayalite::expr::Valueless::new(::fayalite::int::Bool)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
let __lhs = ::fayalite::expr::ValueType::ty(&__lhs);
|
|
||||||
let __rhs = ::fayalite::expr::ValueType::ty(&__rhs);
|
|
||||||
#(#fields_valueless_eq)&*
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let cmp_expr_eq_wire_name = format!("{ident}_cmp_eq");
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::expr::HdlPartialEqImpl<Self> for #target #type_generics
|
|
||||||
#cmp_eq_where_clause
|
|
||||||
{
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_value_eq(
|
|
||||||
__lhs: Self,
|
|
||||||
__lhs_value: ::fayalite::__std::borrow::Cow<'_, <Self as ::fayalite::ty::Type>::SimValue>,
|
|
||||||
__rhs: Self,
|
|
||||||
__rhs_value: ::fayalite::__std::borrow::Cow<'_, <Self as ::fayalite::ty::Type>::SimValue>,
|
|
||||||
) -> ::fayalite::__std::primitive::bool {
|
|
||||||
match (&*__lhs_value, &*__rhs_value) {
|
|
||||||
#(#variants_value_eq)*
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_expr_eq(
|
|
||||||
__lhs: ::fayalite::expr::Expr<Self>,
|
|
||||||
__rhs: ::fayalite::expr::Expr<Self>,
|
|
||||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
|
||||||
let __retval = ::fayalite::module::wire(::fayalite::module::ImplicitName(#cmp_expr_eq_wire_name), ::fayalite::int::Bool);
|
|
||||||
::fayalite::module::connect(__retval, false);
|
|
||||||
let mut __lhs_match_variant_iter = ::fayalite::module::match_(__lhs);
|
|
||||||
#(#variants_expr_eq)*
|
|
||||||
__retval
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_valueless_eq(
|
|
||||||
__lhs: ::fayalite::expr::Valueless<Self>,
|
|
||||||
__rhs: ::fayalite::expr::Valueless<Self>,
|
|
||||||
) -> ::fayalite::expr::Valueless<::fayalite::int::Bool> {
|
|
||||||
#valueless_eq_body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
let variants_len = variants.len();
|
let variants_len = variants.len();
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
|
@ -1151,7 +888,6 @@ impl ToTokens for ParsedEnum {
|
||||||
#(#sim_value_from_opaque_match_arms)*
|
#(#sim_value_from_opaque_match_arms)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
fn sim_value_clone_from_opaque(
|
fn sim_value_clone_from_opaque(
|
||||||
&self,
|
&self,
|
||||||
value: &mut <Self as ::fayalite::ty::Type>::SimValue,
|
value: &mut <Self as ::fayalite::ty::Type>::SimValue,
|
||||||
|
|
@ -1197,14 +933,6 @@ impl ToTokens for ParsedEnum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics ::fayalite::__std::fmt::Debug for #sim_value_ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
<#target #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics>
|
impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics>
|
||||||
for #sim_value_ident #type_generics
|
for #sim_value_ident #type_generics
|
||||||
#where_clause
|
#where_clause
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,6 @@ impl ParsedTypeAlias {
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
get: _,
|
get: _,
|
||||||
ref custom_debug,
|
|
||||||
custom_sim_display,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
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");
|
||||||
|
|
@ -236,15 +234,6 @@ impl ParsedTypeAlias {
|
||||||
if let Some((cmp_eq,)) = cmp_eq {
|
if let Some((cmp_eq,)) = cmp_eq {
|
||||||
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
||||||
}
|
}
|
||||||
if let Some((custom_debug, _, _)) = custom_debug {
|
|
||||||
errors.error(custom_debug, "custom_debug is not valid on type aliases");
|
|
||||||
}
|
|
||||||
if let Some((custom_sim_display,)) = custom_sim_display {
|
|
||||||
errors.error(
|
|
||||||
custom_sim_display,
|
|
||||||
"custom_sim_display is not valid on type aliases",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some((custom_bounds,)) = custom_bounds {
|
if let Some((custom_bounds,)) = custom_bounds {
|
||||||
errors.error(
|
errors.error(
|
||||||
custom_bounds,
|
custom_bounds,
|
||||||
|
|
@ -298,8 +287,6 @@ impl ParsedTypeAlias {
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq,
|
cmp_eq,
|
||||||
ref mut get,
|
ref mut get,
|
||||||
ref custom_debug,
|
|
||||||
custom_sim_display,
|
|
||||||
} = options.body;
|
} = options.body;
|
||||||
if let Some(get) = get.take() {
|
if let Some(get) = get.take() {
|
||||||
return Self::parse_phantom_const_accessor(
|
return Self::parse_phantom_const_accessor(
|
||||||
|
|
@ -324,15 +311,6 @@ impl ParsedTypeAlias {
|
||||||
if let Some((cmp_eq,)) = cmp_eq {
|
if let Some((cmp_eq,)) = cmp_eq {
|
||||||
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
||||||
}
|
}
|
||||||
if let Some((custom_debug, _, _)) = custom_debug {
|
|
||||||
errors.error(custom_debug, "custom_debug is not valid on type aliases");
|
|
||||||
}
|
|
||||||
if let Some((custom_sim_display,)) = custom_sim_display {
|
|
||||||
errors.error(
|
|
||||||
custom_sim_display,
|
|
||||||
"custom_sim_display is not valid on type aliases",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let generics = if custom_bounds.is_some() {
|
let generics = if custom_bounds.is_some() {
|
||||||
MaybeParsed::Unrecognized(generics)
|
MaybeParsed::Unrecognized(generics)
|
||||||
} else if let Some(generics) = errors.ok(ParsedGenerics::parse(&mut generics)) {
|
} else if let Some(generics) = errors.ok(ParsedGenerics::parse(&mut generics)) {
|
||||||
|
|
@ -378,8 +356,6 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
no_runtime_generics,
|
no_runtime_generics,
|
||||||
cmp_eq: _,
|
cmp_eq: _,
|
||||||
get: _,
|
get: _,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display: _,
|
|
||||||
} = &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();
|
||||||
|
|
@ -426,8 +402,6 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
no_runtime_generics: _,
|
no_runtime_generics: _,
|
||||||
cmp_eq: _,
|
cmp_eq: _,
|
||||||
get: _,
|
get: _,
|
||||||
custom_debug: _,
|
|
||||||
custom_sim_display: _,
|
|
||||||
} = &options.body;
|
} = &options.body;
|
||||||
let span = ident.span();
|
let span = ident.span();
|
||||||
let mut type_attrs = attrs.clone();
|
let mut type_attrs = attrs.clone();
|
||||||
|
|
@ -453,7 +427,7 @@ impl ToTokens for ParsedTypeAlias {
|
||||||
format_ident!("__{}__GenericsAccumulation", ident);
|
format_ident!("__{}__GenericsAccumulation", ident);
|
||||||
ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span, true),
|
common_derives(span),
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ use std::{collections::HashMap, fmt, mem};
|
||||||
use syn::{
|
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, FnArg, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index,
|
FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct,
|
||||||
ItemStruct, Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound,
|
Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, Turbofish,
|
||||||
Turbofish, Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath,
|
Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple,
|
||||||
TypeTuple, Visibility, WhereClause, WherePredicate,
|
Visibility, WhereClause, WherePredicate,
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
parse_quote, parse_quote_spanned,
|
parse_quote, parse_quote_spanned,
|
||||||
punctuated::{Pair, Punctuated},
|
punctuated::{Pair, Punctuated},
|
||||||
|
|
@ -18,17 +18,6 @@ use syn::{
|
||||||
token::{Brace, Bracket, Paren},
|
token::{Brace, Bracket, Paren},
|
||||||
};
|
};
|
||||||
|
|
||||||
crate::options! {
|
|
||||||
#[options = CustomDebugOptions]
|
|
||||||
#[no_ident_fragment]
|
|
||||||
pub(crate) enum CustomDebugOption {
|
|
||||||
Type(type_),
|
|
||||||
Sim(sim),
|
|
||||||
MaskType(mask_type),
|
|
||||||
MaskSim(mask_sim),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::options! {
|
crate::options! {
|
||||||
#[options = ItemOptions]
|
#[options = ItemOptions]
|
||||||
pub(crate) enum ItemOption {
|
pub(crate) enum ItemOption {
|
||||||
|
|
@ -39,8 +28,6 @@ crate::options! {
|
||||||
NoRuntimeGenerics(no_runtime_generics),
|
NoRuntimeGenerics(no_runtime_generics),
|
||||||
CmpEq(cmp_eq),
|
CmpEq(cmp_eq),
|
||||||
Get(get, Expr),
|
Get(get, Expr),
|
||||||
CustomDebug(custom_debug, CustomDebugOptions),
|
|
||||||
CustomSimDisplay(custom_sim_display),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,36 +41,8 @@ impl ItemOptions {
|
||||||
{
|
{
|
||||||
self.no_static = Some((kw::no_static(custom_bounds.span),));
|
self.no_static = Some((kw::no_static(custom_bounds.span),));
|
||||||
}
|
}
|
||||||
if let Some((kw, _, custom_debug)) = &mut self.custom_debug {
|
|
||||||
if let CustomDebugOptions {
|
|
||||||
type_: None,
|
|
||||||
sim: None,
|
|
||||||
mask_type: None,
|
|
||||||
mask_sim: None,
|
|
||||||
} = custom_debug
|
|
||||||
{
|
|
||||||
*custom_debug = CustomDebugOptions {
|
|
||||||
type_: Some((kw::type_(kw.span),)),
|
|
||||||
sim: Some((kw::sim(kw.span),)),
|
|
||||||
mask_type: None,
|
|
||||||
mask_sim: None,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub(crate) fn custom_debug(&self) -> &CustomDebugOptions {
|
|
||||||
self.custom_debug.as_ref().map(|v| &v.2).unwrap_or(
|
|
||||||
const {
|
|
||||||
&CustomDebugOptions {
|
|
||||||
type_: None,
|
|
||||||
sim: None,
|
|
||||||
mask_type: None,
|
|
||||||
mask_sim: None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct WrappedInConst<'a> {
|
pub(crate) struct WrappedInConst<'a> {
|
||||||
|
|
@ -125,17 +84,10 @@ pub(crate) fn get_target(target: &Option<(kw::target, Paren, Path)>, item_ident:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn common_derives(span: Span, include_debug: bool) -> Attribute {
|
pub(crate) fn common_derives(span: Span) -> Attribute {
|
||||||
let debug = include_debug
|
|
||||||
.then(|| {
|
|
||||||
quote_spanned! {span=>
|
|
||||||
::fayalite::__std::fmt::Debug
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into_iter();
|
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[::fayalite::__std::prelude::v1::derive(
|
#[::fayalite::__std::prelude::v1::derive(
|
||||||
#(#debug,)*
|
::fayalite::__std::fmt::Debug,
|
||||||
::fayalite::__std::cmp::Eq,
|
::fayalite::__std::cmp::Eq,
|
||||||
::fayalite::__std::cmp::PartialEq,
|
::fayalite::__std::cmp::PartialEq,
|
||||||
::fayalite::__std::hash::Hash,
|
::fayalite::__std::hash::Hash,
|
||||||
|
|
@ -3023,7 +2975,7 @@ impl ParsedGenerics {
|
||||||
let span = ident.span();
|
let span = ident.span();
|
||||||
ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span, true),
|
common_derives(span),
|
||||||
parse_quote_spanned! {span=>
|
parse_quote_spanned! {span=>
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
},
|
},
|
||||||
|
|
@ -4781,109 +4733,3 @@ impl ParsedVisibility {
|
||||||
.map(|ord| if ord.is_lt() { self } else { other })
|
.map(|ord| if ord.is_lt() { self } else { other })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct CustomDebugTrait<'a> {
|
|
||||||
pub(crate) trait_path: &'a Path,
|
|
||||||
pub(crate) fn_name: &'a Ident,
|
|
||||||
pub(crate) this_arg: &'a FnArg,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub(crate) fn create_struct_debug_impl(
|
|
||||||
item_struct: &ItemStruct,
|
|
||||||
debug_struct_name: &str,
|
|
||||||
custom_debug_trait: Option<CustomDebugTrait<'_>>,
|
|
||||||
) -> TokenStream {
|
|
||||||
let ident = &item_struct.ident;
|
|
||||||
let span = ident.span();
|
|
||||||
let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl();
|
|
||||||
let trait_path;
|
|
||||||
let fn_name;
|
|
||||||
let this_arg;
|
|
||||||
let CustomDebugTrait {
|
|
||||||
trait_path,
|
|
||||||
fn_name,
|
|
||||||
this_arg,
|
|
||||||
} = match custom_debug_trait {
|
|
||||||
Some(v) => v,
|
|
||||||
None => {
|
|
||||||
trait_path = parse_quote_spanned! {span=>
|
|
||||||
::fayalite::__std::fmt::Debug
|
|
||||||
};
|
|
||||||
fn_name = parse_quote_spanned! {span=>
|
|
||||||
fmt
|
|
||||||
};
|
|
||||||
this_arg = parse_quote_spanned! {span=>
|
|
||||||
&self
|
|
||||||
};
|
|
||||||
CustomDebugTrait {
|
|
||||||
trait_path: &trait_path,
|
|
||||||
fn_name: &fn_name,
|
|
||||||
this_arg: &this_arg,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let this_arg_name = match this_arg {
|
|
||||||
FnArg::Receiver(this_arg) => this_arg.self_token.to_token_stream(),
|
|
||||||
FnArg::Typed(this_arg) => match &*this_arg.pat {
|
|
||||||
syn::Pat::Ident(pat_ident) => pat_ident.ident.to_token_stream(),
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
match &item_struct.fields {
|
|
||||||
Fields::Named(fields) => {
|
|
||||||
let field_idents = fields
|
|
||||||
.named
|
|
||||||
.iter()
|
|
||||||
.map(|v| v.ident.as_ref().expect("known to have field name"));
|
|
||||||
let field_names = field_idents.clone().map(|v| v.to_string());
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics #trait_path for #ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
let _ = #this_arg_name;
|
|
||||||
f.debug_struct(#debug_struct_name)
|
|
||||||
#(.field(#field_names, &#this_arg_name.#field_idents))*
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Fields::Unnamed(fields) => {
|
|
||||||
let field_members = fields
|
|
||||||
.unnamed
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, _)| syn::Index {
|
|
||||||
index: index as _,
|
|
||||||
span,
|
|
||||||
});
|
|
||||||
quote_spanned! {span=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics #trait_path for #ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
let _ = #this_arg_name;
|
|
||||||
f.debug_tuple(#debug_struct_name)
|
|
||||||
#(.field(&#this_arg_name.#field_members))*
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Fields::Unit => quote_spanned! {ident.span()=>
|
|
||||||
#[automatically_derived]
|
|
||||||
impl #impl_generics #trait_path for #ident #type_generics
|
|
||||||
#where_clause
|
|
||||||
{
|
|
||||||
fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result {
|
|
||||||
let _ = #this_arg_name;
|
|
||||||
f.write_str(#debug_struct_name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ pub(crate) trait CustomToken:
|
||||||
|
|
||||||
mod kw {
|
mod kw {
|
||||||
pub(crate) use syn::token::Extern as extern_;
|
pub(crate) use syn::token::Extern as extern_;
|
||||||
pub(crate) use syn::token::Type as type_;
|
|
||||||
|
|
||||||
macro_rules! custom_keyword {
|
macro_rules! custom_keyword {
|
||||||
($kw:ident) => {
|
($kw:ident) => {
|
||||||
|
|
@ -76,8 +75,6 @@ mod kw {
|
||||||
custom_keyword!(cmp_eq);
|
custom_keyword!(cmp_eq);
|
||||||
custom_keyword!(connect_inexact);
|
custom_keyword!(connect_inexact);
|
||||||
custom_keyword!(custom_bounds);
|
custom_keyword!(custom_bounds);
|
||||||
custom_keyword!(custom_debug);
|
|
||||||
custom_keyword!(custom_sim_display);
|
|
||||||
custom_keyword!(flip);
|
custom_keyword!(flip);
|
||||||
custom_keyword!(get);
|
custom_keyword!(get);
|
||||||
custom_keyword!(hdl);
|
custom_keyword!(hdl);
|
||||||
|
|
@ -86,8 +83,6 @@ mod kw {
|
||||||
custom_keyword!(input);
|
custom_keyword!(input);
|
||||||
custom_keyword!(instance);
|
custom_keyword!(instance);
|
||||||
custom_keyword!(m);
|
custom_keyword!(m);
|
||||||
custom_keyword!(mask_sim);
|
|
||||||
custom_keyword!(mask_type);
|
|
||||||
custom_keyword!(memory);
|
custom_keyword!(memory);
|
||||||
custom_keyword!(memory_array);
|
custom_keyword!(memory_array);
|
||||||
custom_keyword!(memory_with_init);
|
custom_keyword!(memory_with_init);
|
||||||
|
|
|
||||||
|
|
@ -1096,9 +1096,11 @@ impl Visitor<'_> {
|
||||||
let (#(#bindings,)*) = {
|
let (#(#bindings,)*) = {
|
||||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||||
let __match_value = #expr;
|
let __match_value = #expr;
|
||||||
// use method syntax to deduce what type to convert to
|
let __match_value = {
|
||||||
let __match_value = ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value)
|
use ::fayalite::sim::value::match_sim_value::*;
|
||||||
.__fayalite_match_sim_value();
|
// use method syntax to deduce the correct trait to call
|
||||||
|
::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value()
|
||||||
|
};
|
||||||
#let_token #pat #eq_token __match_value #semi_token
|
#let_token #pat #eq_token __match_value #semi_token
|
||||||
(#(#bindings_idents,)*)
|
(#(#bindings_idents,)*)
|
||||||
};
|
};
|
||||||
|
|
@ -1170,9 +1172,11 @@ impl Visitor<'_> {
|
||||||
{
|
{
|
||||||
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
type __MatchTy<T> = <T as ::fayalite::ty::Type>::SimValue;
|
||||||
let __match_value = #expr;
|
let __match_value = #expr;
|
||||||
// use method syntax to deduce what type to convert to
|
let __match_value = {
|
||||||
let __match_value = ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value)
|
use ::fayalite::sim::value::match_sim_value::*;
|
||||||
.__fayalite_match_sim_value();
|
// use method syntax to deduce the correct trait to call
|
||||||
|
::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value()
|
||||||
|
};
|
||||||
#match_token __match_value {
|
#match_token __match_value {
|
||||||
#(#arms)*
|
#(#arms)*
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,10 @@ hashbrown.workspace = true
|
||||||
jobslot.workspace = true
|
jobslot.workspace = true
|
||||||
num-bigint.workspace = true
|
num-bigint.workspace = true
|
||||||
num-traits.workspace = true
|
num-traits.workspace = true
|
||||||
once_cell.workspace = true
|
|
||||||
ordered-float.workspace = true
|
ordered-float.workspace = true
|
||||||
petgraph.workspace = true
|
petgraph.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
sha2.workspace = true
|
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
vec_map.workspace = true
|
vec_map.workspace = true
|
||||||
which.workspace = true
|
which.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -95,11 +95,11 @@
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[hdl]
|
//! #[hdl]
|
||||||
//! fn destructure_inner<T: Type>(v: <MyStruct<T> as Type>::SimValue) {
|
//! fn destructure_to_sim_value<'a, T: Type>(v: impl ToSimValue<Type = MyStruct<T>>) {
|
||||||
//! #[hdl(sim)]
|
//! #[hdl(sim)]
|
||||||
//! let MyStruct::<T> {
|
//! let MyStruct::<T> {
|
||||||
//! a,
|
//! a,
|
||||||
//! mut b,
|
//! b,
|
||||||
//! c,
|
//! c,
|
||||||
//! } = v;
|
//! } = v;
|
||||||
//!
|
//!
|
||||||
|
|
@ -107,38 +107,5 @@
|
||||||
//! let _: SimValue<UInt<8>> = a;
|
//! let _: SimValue<UInt<8>> = a;
|
||||||
//! let _: SimValue<Bool> = b;
|
//! let _: SimValue<Bool> = b;
|
||||||
//! let _: SimValue<T> = c;
|
//! let _: SimValue<T> = c;
|
||||||
//! *b = false; // can modify b since mut was used
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[hdl]
|
|
||||||
//! fn destructure_inner_ref<'a, T: Type>(v: &'a <MyStruct<T> as Type>::SimValue) {
|
|
||||||
//! #[hdl(sim)]
|
|
||||||
//! let MyStruct::<T> {
|
|
||||||
//! a,
|
|
||||||
//! b,
|
|
||||||
//! c,
|
|
||||||
//! } = v;
|
|
||||||
//!
|
|
||||||
//! // that gives these types:
|
|
||||||
//! let _: &'a SimValue<UInt<8>> = a;
|
|
||||||
//! let _: &'a SimValue<Bool> = b;
|
|
||||||
//! let _: &'a SimValue<T> = c;
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[hdl]
|
|
||||||
//! fn destructure_inner_mut<'a, T: Type>(v: &'a mut <MyStruct<T> as Type>::SimValue) {
|
|
||||||
//! #[hdl(sim)]
|
|
||||||
//! let MyStruct::<T> {
|
|
||||||
//! a,
|
|
||||||
//! b,
|
|
||||||
//! c,
|
|
||||||
//! } = v;
|
|
||||||
//!
|
|
||||||
//! **b = true; // you can modify v by modifying b which borrows from it
|
|
||||||
//!
|
|
||||||
//! // that gives these types:
|
|
||||||
//! let _: &'a mut SimValue<UInt<8>> = a;
|
|
||||||
//! let _: &'a mut SimValue<Bool> = b;
|
|
||||||
//! let _: &'a mut SimValue<T> = c;
|
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
|
||||||
|
|
@ -72,47 +72,15 @@
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[hdl]
|
//! #[hdl]
|
||||||
//! fn match_inner_move<T: Type>(v: <MyEnum<T> as Type>::SimValue) -> String {
|
//! fn match_to_sim_value<'a, T: Type>(v: impl ToSimValue<Type = MyEnum<T>>) {
|
||||||
//! #[hdl(sim)]
|
//! #[hdl(sim)]
|
||||||
//! match v {
|
//! match v {
|
||||||
//! MyEnum::<T>::A => String::from("got A"),
|
//! MyEnum::<T>::A => println!("got A"),
|
||||||
//! MyEnum::<T>::B(mut b) => {
|
//! MyEnum::<T>::B(b) => {
|
||||||
//! let _: SimValue<Bool> = b; // b has this type
|
//! let _: SimValue<Bool> = b; // b has this type
|
||||||
//! let text = format!("got B({b})");
|
|
||||||
//! *b = true; // can modify b since mut was used
|
|
||||||
//! text
|
|
||||||
//! }
|
|
||||||
//! _ => String::from("something else"),
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[hdl]
|
|
||||||
//! fn match_inner_ref<'a, T: Type>(v: &'a <MyEnum<T> as Type>::SimValue) -> u32 {
|
|
||||||
//! #[hdl(sim)]
|
|
||||||
//! match v {
|
|
||||||
//! MyEnum::<T>::A => 1,
|
|
||||||
//! MyEnum::<T>::B(b) => {
|
|
||||||
//! let _: &'a SimValue<Bool> = b; // b has this type
|
|
||||||
//! println!("got B({b})");
|
//! println!("got B({b})");
|
||||||
//! 5
|
|
||||||
//! }
|
//! }
|
||||||
//! _ => 42,
|
//! _ => println!("something else"),
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[hdl]
|
|
||||||
//! fn match_inner_mut<'a, T: Type>(v: &'a mut <MyEnum<T> as Type>::SimValue) -> Option<&'a mut SimValue<T>> {
|
|
||||||
//! #[hdl(sim)]
|
|
||||||
//! match v {
|
|
||||||
//! MyEnum::<T>::A => None,
|
|
||||||
//! MyEnum::<T>::B(b) => {
|
|
||||||
//! println!("got B({b})");
|
|
||||||
//! **b = true; // you can modify v by modifying b which borrows from it
|
|
||||||
//! let _: &'a mut SimValue<Bool> = b; // b has this type
|
|
||||||
//! None
|
|
||||||
//! }
|
|
||||||
//! MyEnum::<T>::C(v) => Some(v), // you can return matched values
|
|
||||||
//! _ => None, // HDL enums can have invalid discriminants, so we need this extra match arm
|
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
|
||||||
|
|
@ -238,10 +238,7 @@ impl TargetedAnnotation {
|
||||||
}
|
}
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn assert_valid_target(target: Interned<Target>) {
|
pub fn assert_valid_target(target: Interned<Target>) {
|
||||||
assert!(
|
assert!(target.is_static(), "can't annotate non-static targets");
|
||||||
target.is_valid_annotation_target(),
|
|
||||||
"not a valid annotation target: {target:?}",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
pub fn target(&self) -> Interned<Target> {
|
pub fn target(&self) -> Interned<Target> {
|
||||||
self.target
|
self.target
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, MatchVariantWithoutScope, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
CanonicalType, MatchVariantWithoutScope, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
||||||
OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties, TypeWithDeref,
|
OpaqueSimValueWritten, StaticType, Type, TypeProperties, TypeWithDeref,
|
||||||
serde_impls::SerdeCanonicalType,
|
serde_impls::SerdeCanonicalType,
|
||||||
},
|
},
|
||||||
util::ConstUsize,
|
util::ConstUsize,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
||||||
use std::{borrow::Cow, fmt, iter::FusedIterator, ops::Index};
|
use std::{borrow::Cow, iter::FusedIterator, ops::Index};
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ArrayType<T: Type = CanonicalType, Len: Size = DynSize> {
|
pub struct ArrayType<T: Type = CanonicalType, Len: Size = DynSize> {
|
||||||
|
|
@ -28,8 +28,8 @@ pub struct ArrayType<T: Type = CanonicalType, Len: Size = DynSize> {
|
||||||
type_properties: TypeProperties,
|
type_properties: TypeProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type, Len: Size> fmt::Debug for ArrayType<T, Len> {
|
impl<T: Type, Len: Size> std::fmt::Debug for ArrayType<T, Len> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "Array<{:?}, {}>", self.element, self.len())
|
write!(f, "Array<{:?}, {}>", self.element, self.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,42 +109,14 @@ impl<T: StaticType, Len: KnownSize> Default for ArrayType<T, Len> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MakeType<T: StaticType>(Interned<T>);
|
|
||||||
|
|
||||||
impl<T: StaticType> From<MakeType<T>> for Interned<T> {
|
|
||||||
fn from(value: MakeType<T>) -> Self {
|
|
||||||
value.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: StaticType> Default for MakeType<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(T::TYPE.intern_sized())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MakeMaskType<T: StaticType>(Interned<T::MaskType>);
|
|
||||||
|
|
||||||
impl<T: StaticType> From<MakeMaskType<T>> for Interned<T::MaskType> {
|
|
||||||
fn from(value: MakeMaskType<T>) -> Self {
|
|
||||||
value.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: StaticType> Default for MakeMaskType<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(T::MASK_TYPE.intern_sized())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: StaticType, Len: KnownSize> StaticType for ArrayType<T, Len> {
|
impl<T: StaticType, Len: KnownSize> StaticType for ArrayType<T, Len> {
|
||||||
const TYPE: Self = Self {
|
const TYPE: Self = Self {
|
||||||
element: LazyInterned::new_const::<MakeType<T>>(),
|
element: LazyInterned::new_lazy(&|| T::TYPE.intern_sized()),
|
||||||
len: Len::SIZE,
|
len: Len::SIZE,
|
||||||
type_properties: Self::TYPE_PROPERTIES,
|
type_properties: Self::TYPE_PROPERTIES,
|
||||||
};
|
};
|
||||||
const MASK_TYPE: Self::MaskType = ArrayType::<T::MaskType, Len> {
|
const MASK_TYPE: Self::MaskType = ArrayType::<T::MaskType, Len> {
|
||||||
element: LazyInterned::new_const::<MakeMaskType<T>>(),
|
element: LazyInterned::new_lazy(&|| T::MASK_TYPE.intern_sized()),
|
||||||
len: Len::SIZE,
|
len: Len::SIZE,
|
||||||
type_properties: Self::MASK_TYPE_PROPERTIES,
|
type_properties: Self::MASK_TYPE_PROPERTIES,
|
||||||
};
|
};
|
||||||
|
|
@ -182,15 +154,6 @@ impl<T: Type + Visit<State>, Len: Size, State: Visitor + ?Sized> Visit<State>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type, Len: Size> SimValueDebug for ArrayType<T, Len> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, Len: Size> Type for ArrayType<T, Len> {
|
impl<T: Type, Len: Size> Type for ArrayType<T, Len> {
|
||||||
type BaseType = Array;
|
type BaseType = Array;
|
||||||
type MaskType = ArrayType<T::MaskType, Len>;
|
type MaskType = ArrayType<T::MaskType, Len>;
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, MatchVariantWithoutScope, OpaqueSimValue, OpaqueSimValueSize,
|
CanonicalType, MatchVariantWithoutScope, OpaqueSimValue, OpaqueSimValueSize,
|
||||||
OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug,
|
OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type,
|
||||||
StaticType, Type, TypeProperties, TypeWithDeref, impl_match_variant_as_self,
|
TypeProperties, TypeWithDeref, impl_match_variant_as_self,
|
||||||
},
|
},
|
||||||
util::HashMap,
|
util::HashMap,
|
||||||
};
|
};
|
||||||
|
|
@ -271,15 +271,6 @@ impl Type for Bundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for Bundle {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait BundleType: Type<BaseType = Bundle> {
|
pub trait BundleType: Type<BaseType = Bundle> {
|
||||||
type Builder: Default;
|
type Builder: Default;
|
||||||
fn fields(&self) -> Interned<[BundleField]>;
|
fn fields(&self) -> Interned<[BundleField]>;
|
||||||
|
|
@ -480,14 +471,6 @@ macro_rules! impl_tuples {
|
||||||
#[var($var)]
|
#[var($var)]
|
||||||
})*]
|
})*]
|
||||||
}
|
}
|
||||||
impl<$($T: Type,)*> SimValueDebug for ($($T,)*) {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<$($T: Type,)*> Type for ($($T,)*) {
|
impl<$($T: Type,)*> Type for ($($T,)*) {
|
||||||
type BaseType = Bundle;
|
type BaseType = Bundle;
|
||||||
type MaskType = ($($T::MaskType,)*);
|
type MaskType = ($($T::MaskType,)*);
|
||||||
|
|
@ -790,15 +773,6 @@ impl_tuples! {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> SimValueDebug for PhantomData<T> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> Type for PhantomData<T> {
|
impl<T: ?Sized + Send + Sync + 'static> Type for PhantomData<T> {
|
||||||
type BaseType = Bundle;
|
type BaseType = Bundle;
|
||||||
type MaskType = ();
|
type MaskType = ();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::{Expr, ValueType},
|
expr::{Expr, ValueType},
|
||||||
hdl,
|
hdl,
|
||||||
|
|
@ -10,12 +9,10 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
||||||
OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties,
|
OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
||||||
impl_match_variant_as_self,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bitvec::{bits, order::Lsb0};
|
use bitvec::{bits, order::Lsb0};
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
|
||||||
pub struct Clock;
|
pub struct Clock;
|
||||||
|
|
@ -72,15 +69,6 @@ impl Type for Clock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for Clock {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clock {
|
impl Clock {
|
||||||
pub fn type_properties(self) -> TypeProperties {
|
pub fn type_properties(self) -> TypeProperties {
|
||||||
Self::TYPE_PROPERTIES
|
Self::TYPE_PROPERTIES
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::{Expr, ToExpr, ValueType, ops::VariantAccess},
|
expr::{Expr, HdlPartialEq, HdlPartialEqImpl, ToExpr, ValueType, ops::VariantAccess},
|
||||||
hdl,
|
hdl,
|
||||||
int::{Bool, UIntValue},
|
int::{Bool, UIntValue},
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
|
|
@ -10,18 +10,18 @@ use crate::{
|
||||||
EnumMatchVariantAndInactiveScopeImpl, EnumMatchVariantsIterImpl, Scope, connect,
|
EnumMatchVariantAndInactiveScopeImpl, EnumMatchVariantsIterImpl, Scope, connect,
|
||||||
enum_match_variants_helper, incomplete_wire, wire,
|
enum_match_variants_helper, incomplete_wire, wire,
|
||||||
},
|
},
|
||||||
sim::value::{SimValue, ToSimValue, ToSimValueWithType},
|
sim::value::SimValue,
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, OpaqueSimValueSize,
|
CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, OpaqueSimValueSize,
|
||||||
OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug,
|
OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type,
|
||||||
StaticType, Type, TypeProperties,
|
TypeProperties,
|
||||||
},
|
},
|
||||||
util::HashMap,
|
util::HashMap,
|
||||||
};
|
};
|
||||||
use bitvec::{order::Lsb0, slice::BitSlice, view::BitView};
|
use bitvec::{order::Lsb0, slice::BitSlice, view::BitView};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc};
|
use std::{borrow::Cow, convert::Infallible, fmt, iter::FusedIterator, sync::Arc};
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
pub struct EnumVariant {
|
pub struct EnumVariant {
|
||||||
|
|
@ -410,15 +410,6 @@ impl Type for Enum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for Enum {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
|
||||||
pub struct EnumPaddingSimValue {
|
pub struct EnumPaddingSimValue {
|
||||||
bits: Option<UIntValue>,
|
bits: Option<UIntValue>,
|
||||||
|
|
@ -732,12 +723,95 @@ pub fn enum_type_to_sim_builder<T: EnumType>(v: T) -> T::SimBuilder {
|
||||||
v.into()
|
v.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl]
|
||||||
pub enum HdlOption<T: Type> {
|
pub enum HdlOption<T: Type> {
|
||||||
HdlNone,
|
HdlNone,
|
||||||
HdlSome(T),
|
HdlSome(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Lhs: Type + HdlPartialEqImpl<Rhs>, Rhs: Type> HdlPartialEqImpl<HdlOption<Rhs>>
|
||||||
|
for HdlOption<Lhs>
|
||||||
|
{
|
||||||
|
fn cmp_value_eq(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: HdlOption<Rhs>,
|
||||||
|
rhs_value: Cow<'_, <HdlOption<Rhs> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
type SimValueMatch<T> = <T as Type>::SimValue;
|
||||||
|
match (&*lhs_value, &*rhs_value) {
|
||||||
|
(SimValueMatch::<Self>::HdlNone(_), SimValueMatch::<HdlOption<Rhs>>::HdlNone(_)) => {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
(SimValueMatch::<Self>::HdlSome(..), SimValueMatch::<HdlOption<Rhs>>::HdlNone(_))
|
||||||
|
| (SimValueMatch::<Self>::HdlNone(_), SimValueMatch::<HdlOption<Rhs>>::HdlSome(..)) => {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
(
|
||||||
|
SimValueMatch::<Self>::HdlSome(l, _),
|
||||||
|
SimValueMatch::<HdlOption<Rhs>>::HdlSome(r, _),
|
||||||
|
) => HdlPartialEqImpl::cmp_value_eq(
|
||||||
|
lhs.HdlSome,
|
||||||
|
Cow::Borrowed(&**l),
|
||||||
|
rhs.HdlSome,
|
||||||
|
Cow::Borrowed(&**r),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<HdlOption<Rhs>>) -> Expr<Bool> {
|
||||||
|
#[hdl]
|
||||||
|
let cmp_eq = wire();
|
||||||
|
#[hdl]
|
||||||
|
match lhs {
|
||||||
|
HdlSome(lhs) =>
|
||||||
|
{
|
||||||
|
#[hdl]
|
||||||
|
match rhs {
|
||||||
|
HdlSome(rhs) => connect(cmp_eq, lhs.cmp_eq(rhs)),
|
||||||
|
HdlNone => connect(cmp_eq, false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HdlNone =>
|
||||||
|
{
|
||||||
|
#[hdl]
|
||||||
|
match rhs {
|
||||||
|
HdlSome(_) => connect(cmp_eq, false),
|
||||||
|
HdlNone => connect(cmp_eq, true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmp_eq
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
fn cmp_expr_ne(lhs: Expr<Self>, rhs: Expr<HdlOption<Rhs>>) -> Expr<Bool> {
|
||||||
|
#[hdl]
|
||||||
|
let cmp_ne = wire();
|
||||||
|
#[hdl]
|
||||||
|
match lhs {
|
||||||
|
HdlSome(lhs) =>
|
||||||
|
{
|
||||||
|
#[hdl]
|
||||||
|
match rhs {
|
||||||
|
HdlSome(rhs) => connect(cmp_ne, lhs.cmp_ne(rhs)),
|
||||||
|
HdlNone => connect(cmp_ne, true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HdlNone =>
|
||||||
|
{
|
||||||
|
#[hdl]
|
||||||
|
match rhs {
|
||||||
|
HdlSome(_) => connect(cmp_ne, true),
|
||||||
|
HdlNone => connect(cmp_ne, false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmp_ne
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn HdlNone<T: StaticType>() -> Expr<HdlOption<T>> {
|
pub fn HdlNone<T: StaticType>() -> Expr<HdlOption<T>> {
|
||||||
HdlOption[T::TYPE].HdlNone()
|
HdlOption[T::TYPE].HdlNone()
|
||||||
|
|
@ -749,123 +823,6 @@ pub fn HdlSome<T: Type>(value: impl ToExpr<Type = T>) -> Expr<HdlOption<T>> {
|
||||||
HdlOption[value.ty()].HdlSome(value)
|
HdlOption[value.ty()].HdlSome(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> From<SimValue<HdlOption<T>>> for Option<SimValue<T>> {
|
|
||||||
#[hdl]
|
|
||||||
fn from(value: SimValue<HdlOption<T>>) -> Self {
|
|
||||||
#[hdl(sim)]
|
|
||||||
match value {
|
|
||||||
HdlSome(v) => Some(v),
|
|
||||||
HdlNone => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Type> From<&'a SimValue<HdlOption<T>>> for Option<&'a SimValue<T>> {
|
|
||||||
#[hdl]
|
|
||||||
fn from(value: &'a SimValue<HdlOption<T>>) -> Self {
|
|
||||||
#[hdl(sim)]
|
|
||||||
match value {
|
|
||||||
HdlSome(v) => Some(v),
|
|
||||||
HdlNone => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Type> From<&'a mut SimValue<HdlOption<T>>> for Option<&'a mut SimValue<T>> {
|
|
||||||
#[hdl]
|
|
||||||
fn from(value: &'a mut SimValue<HdlOption<T>>) -> Self {
|
|
||||||
#[hdl(sim)]
|
|
||||||
match value {
|
|
||||||
HdlSome(v) => Some(v),
|
|
||||||
HdlNone => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ValueType<Type: StaticType<MaskType: StaticType>>> ValueType for Option<T> {
|
|
||||||
type Type = HdlOption<T::Type>;
|
|
||||||
type ValueCategory = T::ValueCategory;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
StaticType::TYPE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, V: ToSimValueWithType<T>> ToSimValueWithType<HdlOption<T>> for Option<V> {
|
|
||||||
#[hdl]
|
|
||||||
fn to_sim_value_with_type(&self, ty: HdlOption<T>) -> SimValue<HdlOption<T>> {
|
|
||||||
match self {
|
|
||||||
Some(v) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
ty.HdlSome(v)
|
|
||||||
}
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
ty.HdlNone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
fn into_sim_value_with_type(self, ty: HdlOption<T>) -> SimValue<HdlOption<T>> {
|
|
||||||
match self {
|
|
||||||
Some(v) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
ty.HdlSome(v)
|
|
||||||
}
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
ty.HdlNone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ToSimValue<Type: StaticType<MaskType: StaticType>>> ToSimValue for Option<T> {
|
|
||||||
#[hdl]
|
|
||||||
fn to_sim_value(&self) -> SimValue<Self::Type> {
|
|
||||||
match self {
|
|
||||||
Some(v) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlSome(v)
|
|
||||||
}
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlNone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
fn into_sim_value(self) -> SimValue<Self::Type> {
|
|
||||||
match self {
|
|
||||||
Some(v) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlSome(v)
|
|
||||||
}
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlNone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ToExpr<Type: StaticType<MaskType: StaticType>>> ToExpr for Option<T> {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
match self {
|
|
||||||
Some(v) => HdlSome(v),
|
|
||||||
None => HdlNone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> HdlOption<T> {
|
impl<T: Type> HdlOption<T> {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn try_map<R: Type, E>(
|
pub fn try_map<R: Type, E>(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use crate::{
|
||||||
bundle::{Bundle, BundleType},
|
bundle::{Bundle, BundleType},
|
||||||
enum_::{Enum, EnumType},
|
enum_::{Enum, EnumType},
|
||||||
expr::target::{GetTarget, Target},
|
expr::target::{GetTarget, Target},
|
||||||
formal::FormalInput,
|
|
||||||
int::{Bool, DynSize, IntType, SIntValue, Size, SizeType, UInt, UIntType, UIntValue},
|
int::{Bool, DynSize, IntType, SIntValue, Size, SizeType, UInt, UIntType, UIntValue},
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
memory::{DynPortType, MemPort, PortType},
|
memory::{DynPortType, MemPort, PortType},
|
||||||
|
|
@ -18,7 +17,7 @@ use crate::{
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
||||||
sim::value::{SimValue, ToSimValue, ToSimValueWithType},
|
sim::value::{SimValue, ToSimValue, ToSimValueWithType},
|
||||||
ty::{CanonicalType, OpaqueSimValue, StaticType, TraceAsString, Type, TypeWithDeref},
|
ty::{CanonicalType, OpaqueSimValue, StaticType, Type, TypeWithDeref},
|
||||||
util::{ConstBool, ConstUsize},
|
util::{ConstBool, ConstUsize},
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
|
|
@ -219,8 +218,6 @@ expr_enum! {
|
||||||
SliceSInt(ops::SliceSInt),
|
SliceSInt(ops::SliceSInt),
|
||||||
CastToBits(ops::CastToBits),
|
CastToBits(ops::CastToBits),
|
||||||
CastBitsTo(ops::CastBitsTo),
|
CastBitsTo(ops::CastBitsTo),
|
||||||
ToTraceAsString(ops::ToTraceAsString),
|
|
||||||
TraceAsStringAsInner(ops::TraceAsStringAsInner),
|
|
||||||
ModuleIO(ModuleIO<CanonicalType>),
|
ModuleIO(ModuleIO<CanonicalType>),
|
||||||
Instance(Instance<Bundle>),
|
Instance(Instance<Bundle>),
|
||||||
Wire(Wire<CanonicalType>),
|
Wire(Wire<CanonicalType>),
|
||||||
|
|
@ -228,8 +225,6 @@ expr_enum! {
|
||||||
RegSync(Reg<CanonicalType, SyncReset>),
|
RegSync(Reg<CanonicalType, SyncReset>),
|
||||||
RegAsync(Reg<CanonicalType, AsyncReset>),
|
RegAsync(Reg<CanonicalType, AsyncReset>),
|
||||||
MemPort(MemPort<DynPortType>),
|
MemPort(MemPort<DynPortType>),
|
||||||
FormalInput(FormalInput),
|
|
||||||
SimIoForGlobal(ops::SimIoForGlobal),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,35 +389,6 @@ impl<T: Type> Expr<T> {
|
||||||
__flow: this.__flow,
|
__flow: this.__flow,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[track_caller]
|
|
||||||
pub fn as_trace_as_string(this: Self, ty: TraceAsString<T>) -> Expr<TraceAsString<T>> {
|
|
||||||
assert_eq!(this.ty(), ty.inner_ty());
|
|
||||||
ops::ToTraceAsString::new(Expr::canonical(this), ty).to_expr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Expr<CanonicalType> {
|
|
||||||
pub fn unwrap_transparent_types(mut this: Self) -> Expr<CanonicalType> {
|
|
||||||
loop {
|
|
||||||
match this.ty() {
|
|
||||||
CanonicalType::UInt(_)
|
|
||||||
| CanonicalType::SInt(_)
|
|
||||||
| CanonicalType::Bool(_)
|
|
||||||
| CanonicalType::Array(_)
|
|
||||||
| CanonicalType::Enum(_)
|
|
||||||
| CanonicalType::Bundle(_)
|
|
||||||
| CanonicalType::AsyncReset(_)
|
|
||||||
| CanonicalType::SyncReset(_)
|
|
||||||
| CanonicalType::Reset(_)
|
|
||||||
| CanonicalType::Clock(_)
|
|
||||||
| CanonicalType::PhantomConst(_)
|
|
||||||
| CanonicalType::DynSimOnly(_) => return this,
|
|
||||||
CanonicalType::TraceAsString(_) => {
|
|
||||||
this = *Expr::<TraceAsString>::from_canonical(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> ToLiteralBits for Expr<T> {
|
impl<T: Type> ToLiteralBits for Expr<T> {
|
||||||
|
|
@ -1726,204 +1692,3 @@ impl<'a, T: Type> ToSimValueInner<'a> for &'a SimValue<T> {
|
||||||
Cow::Borrowed(&**this)
|
Cow::Borrowed(&**this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToTraceAsString: ValueType {
|
|
||||||
type Output: ValueType<Type = TraceAsString<Self::Type>, ValueCategory = Self::ValueCategory>;
|
|
||||||
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output;
|
|
||||||
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
fn to_trace_as_string(&self) -> Self::Output;
|
|
||||||
fn into_trace_as_string(self) -> Self::Output
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
T: ?Sized
|
|
||||||
+ ValueType
|
|
||||||
+ ToTraceAsStringImpl<<Self as ValueType>::Type, <Self as ValueType>::ValueCategory>,
|
|
||||||
> ToTraceAsString for T
|
|
||||||
{
|
|
||||||
type Output = T::ImplOutput;
|
|
||||||
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output {
|
|
||||||
Self::to_trace_as_string_with_ty_impl(self, ty)
|
|
||||||
}
|
|
||||||
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
Self::into_trace_as_string_with_ty_impl(self, ty)
|
|
||||||
}
|
|
||||||
fn to_trace_as_string(&self) -> Self::Output {
|
|
||||||
Self::to_trace_as_string_impl(self)
|
|
||||||
}
|
|
||||||
fn into_trace_as_string(self) -> Self::Output
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
Self::into_trace_as_string_impl(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ToTraceAsStringImpl<Ty: Type, C: value_category::ValueCategory> {
|
|
||||||
type ImplOutput: ValueType<Type = TraceAsString<Ty>, ValueCategory = C>;
|
|
||||||
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput;
|
|
||||||
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
fn to_trace_as_string_with_ty_impl(this: &Self, ty: TraceAsString<Ty>) -> Self::ImplOutput;
|
|
||||||
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<Ty>) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + crate::sim::value::ToSimValue>
|
|
||||||
ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValue> for T
|
|
||||||
{
|
|
||||||
type ImplOutput = crate::ty::TraceAsStringSimValue<T::Type>;
|
|
||||||
|
|
||||||
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
|
||||||
crate::ty::TraceAsStringSimValue::new(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
crate::ty::TraceAsStringSimValue::new(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_trace_as_string_with_ty_impl(
|
|
||||||
this: &Self,
|
|
||||||
ty: TraceAsString<T::Type>,
|
|
||||||
) -> Self::ImplOutput {
|
|
||||||
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + crate::sim::value::ToSimValue>
|
|
||||||
ToTraceAsStringImpl<T::Type, value_category::ValueCategorySimValue> for T
|
|
||||||
{
|
|
||||||
type ImplOutput = SimValue<TraceAsString<T::Type>>;
|
|
||||||
|
|
||||||
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
|
||||||
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_trace_as_string_with_ty_impl(
|
|
||||||
this: &Self,
|
|
||||||
ty: TraceAsString<T::Type>,
|
|
||||||
) -> Self::ImplOutput {
|
|
||||||
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + ToExpr> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryExpr> for T {
|
|
||||||
type ImplOutput = Expr<TraceAsString<T::Type>>;
|
|
||||||
|
|
||||||
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
|
||||||
let this = this.to_expr();
|
|
||||||
ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
let this = this.to_expr();
|
|
||||||
ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_trace_as_string_with_ty_impl(
|
|
||||||
this: &Self,
|
|
||||||
ty: TraceAsString<T::Type>,
|
|
||||||
) -> Self::ImplOutput {
|
|
||||||
let this = this.to_expr();
|
|
||||||
ops::ToTraceAsString::new(
|
|
||||||
Expr::canonical(this),
|
|
||||||
ty.with_new_inner_ty(this.ty().intern_sized()),
|
|
||||||
)
|
|
||||||
.to_expr()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
let this = this.to_expr();
|
|
||||||
ops::ToTraceAsString::new(
|
|
||||||
Expr::canonical(this),
|
|
||||||
ty.with_new_inner_ty(this.ty().intern_sized()),
|
|
||||||
)
|
|
||||||
.to_expr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + ValueType> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValueless>
|
|
||||||
for T
|
|
||||||
{
|
|
||||||
type ImplOutput = Valueless<TraceAsString<T::Type>>;
|
|
||||||
|
|
||||||
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
|
||||||
Valueless::new(TraceAsString::new(this.ty()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
Valueless::new(TraceAsString::new(this.ty()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_trace_as_string_with_ty_impl(
|
|
||||||
this: &Self,
|
|
||||||
ty: TraceAsString<T::Type>,
|
|
||||||
) -> Self::ImplOutput {
|
|
||||||
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToLiteralBits for FormalInput {
|
|
||||||
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
|
||||||
Err(NotALiteralExpr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToExpr for FormalInput {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
Expr {
|
|
||||||
__enum: ExprEnum::FormalInput(*self).intern_sized(),
|
|
||||||
__ty: self.ty(),
|
|
||||||
__flow: self.flow(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,10 @@ use crate::{
|
||||||
ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless,
|
ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless,
|
||||||
target::{
|
target::{
|
||||||
GetTarget, Target, TargetPathArrayElement, TargetPathBundleField,
|
GetTarget, Target, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
TargetPathDynArrayElement, TargetPathElement,
|
||||||
TargetPathTraceAsStringInner,
|
|
||||||
},
|
},
|
||||||
value_category::ValueCategoryExpr,
|
value_category::ValueCategoryExpr,
|
||||||
},
|
},
|
||||||
formal::FormalInput,
|
|
||||||
int::{
|
int::{
|
||||||
Bool, BoolOrIntType, DynSize, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt,
|
Bool, BoolOrIntType, DynSize, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt,
|
||||||
UIntType, UIntValue,
|
UIntType, UIntValue,
|
||||||
|
|
@ -29,7 +27,7 @@ use crate::{
|
||||||
ToSyncReset,
|
ToSyncReset,
|
||||||
},
|
},
|
||||||
sim::value::{SimValue, ToSimValue},
|
sim::value::{SimValue, ToSimValue},
|
||||||
ty::{CanonicalType, StaticType, TraceAsString, Type},
|
ty::{CanonicalType, StaticType, Type},
|
||||||
util::ConstUsize,
|
util::ConstUsize,
|
||||||
};
|
};
|
||||||
use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
|
use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
|
||||||
|
|
@ -46,9 +44,6 @@ use std::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test_ops_impls;
|
|
||||||
|
|
||||||
macro_rules! make_impls {
|
macro_rules! make_impls {
|
||||||
(
|
(
|
||||||
$([$($args:tt)*])?
|
$([$($args:tt)*])?
|
||||||
|
|
@ -584,9 +579,10 @@ macro_rules! make_impls {
|
||||||
(#[kind(i64)] $($rest:tt)*) => {make_impls! { #[type([][] (i64))] $($rest)* }};
|
(#[kind(i64)] $($rest:tt)*) => {make_impls! { #[type([][] (i64))] $($rest)* }};
|
||||||
(#[kind(i128)] $($rest:tt)*) => {make_impls! { #[type([][] (i128))] $($rest)* }};
|
(#[kind(i128)] $($rest:tt)*) => {make_impls! { #[type([][] (i128))] $($rest)* }};
|
||||||
}
|
}
|
||||||
|
pub(crate) use make_impls;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) use make_impls;
|
mod test_ops_impls;
|
||||||
|
|
||||||
macro_rules! impl_simple_binary_op_trait {
|
macro_rules! impl_simple_binary_op_trait {
|
||||||
(
|
(
|
||||||
|
|
@ -4696,255 +4692,3 @@ impl<This: ExprFromIterator<A>, A> FromIterator<A> for Expr<This> {
|
||||||
This::expr_from_iter(iter)
|
This::expr_from_iter(iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct ToTraceAsString<T: Type = CanonicalType> {
|
|
||||||
inner: Expr<CanonicalType>,
|
|
||||||
ty: TraceAsString<T>,
|
|
||||||
literal_bits: Result<Interned<BitSlice>, NotALiteralExpr>,
|
|
||||||
target: Option<Interned<Target>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> fmt::Debug for ToTraceAsString<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let Self {
|
|
||||||
inner,
|
|
||||||
ty: _,
|
|
||||||
literal_bits: _,
|
|
||||||
target: _,
|
|
||||||
} = self;
|
|
||||||
f.debug_struct("ToTraceAsString")
|
|
||||||
.field("inner", inner)
|
|
||||||
.finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ToTraceAsString<T> {
|
|
||||||
pub fn new(inner: Expr<CanonicalType>, ty: TraceAsString<T>) -> Self {
|
|
||||||
assert_eq!(inner.ty(), ty.inner_ty().canonical());
|
|
||||||
let literal_bits = inner.to_literal_bits();
|
|
||||||
let target = inner.target().map(|base| {
|
|
||||||
Intern::intern_sized(
|
|
||||||
base.join(TargetPathElement::intern_sized(
|
|
||||||
TargetPathToTraceAsString {
|
|
||||||
ty: ty.canonical_trace_as_string(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
))
|
|
||||||
.canonicalized(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
Self {
|
|
||||||
inner,
|
|
||||||
ty,
|
|
||||||
literal_bits,
|
|
||||||
target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn inner(self) -> Expr<CanonicalType> {
|
|
||||||
self.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> GetTarget for ToTraceAsString<T> {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
self.target
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ToLiteralBits for ToTraceAsString<T> {
|
|
||||||
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
|
||||||
self.literal_bits
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ValueType for ToTraceAsString<T> {
|
|
||||||
type Type = TraceAsString<T>;
|
|
||||||
type ValueCategory = ValueCategoryExpr;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
self.ty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ToExpr for ToTraceAsString<T> {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
Expr {
|
|
||||||
__enum: ExprEnum::ToTraceAsString(ToTraceAsString {
|
|
||||||
inner: self.inner,
|
|
||||||
ty: self.ty.canonical_trace_as_string(),
|
|
||||||
literal_bits: self.literal_bits,
|
|
||||||
target: self.target,
|
|
||||||
})
|
|
||||||
.intern(),
|
|
||||||
__ty: self.ty,
|
|
||||||
__flow: Expr::flow(self.inner),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct TraceAsStringAsInner<T: Type = CanonicalType> {
|
|
||||||
arg: Expr<TraceAsString<CanonicalType>>,
|
|
||||||
ty: T,
|
|
||||||
literal_bits: Result<Interned<BitSlice>, NotALiteralExpr>,
|
|
||||||
target: Option<Interned<Target>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> fmt::Debug for TraceAsStringAsInner<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let Self {
|
|
||||||
arg,
|
|
||||||
ty: _,
|
|
||||||
literal_bits: _,
|
|
||||||
target: _,
|
|
||||||
} = self;
|
|
||||||
f.debug_struct("TraceAsStringAsInner")
|
|
||||||
.field("arg", arg)
|
|
||||||
.finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> TraceAsStringAsInner<T> {
|
|
||||||
pub fn from_arg_and_ty(arg: Expr<TraceAsString<CanonicalType>>, ty: T) -> Self {
|
|
||||||
assert_eq!(arg.ty().inner_ty(), ty.canonical());
|
|
||||||
let literal_bits = arg.to_literal_bits();
|
|
||||||
let target = arg.target().map(|base| {
|
|
||||||
Intern::intern_sized(
|
|
||||||
base.join(TargetPathElement::intern_sized(
|
|
||||||
TargetPathTraceAsStringInner {}.into(),
|
|
||||||
))
|
|
||||||
.canonicalized(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
Self {
|
|
||||||
arg,
|
|
||||||
ty,
|
|
||||||
literal_bits,
|
|
||||||
target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn new(arg: Expr<TraceAsString<T>>) -> Self {
|
|
||||||
Self::from_arg_and_ty(
|
|
||||||
Expr {
|
|
||||||
__enum: arg.__enum,
|
|
||||||
__ty: arg.__ty.canonical_trace_as_string(),
|
|
||||||
__flow: arg.__flow,
|
|
||||||
},
|
|
||||||
arg.ty().inner_ty(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
pub fn arg(self) -> Expr<TraceAsString<CanonicalType>> {
|
|
||||||
self.arg
|
|
||||||
}
|
|
||||||
pub fn arg_typed(self) -> Expr<TraceAsString<T>> {
|
|
||||||
Expr {
|
|
||||||
__enum: self.arg.__enum,
|
|
||||||
__ty: TraceAsString::from_canonical_trace_as_string(self.arg.__ty),
|
|
||||||
__flow: self.arg.__flow,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> GetTarget for TraceAsStringAsInner<T> {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
self.target
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ToLiteralBits for TraceAsStringAsInner<T> {
|
|
||||||
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
|
||||||
self.literal_bits
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ValueType for TraceAsStringAsInner<T> {
|
|
||||||
type Type = T;
|
|
||||||
type ValueCategory = ValueCategoryExpr;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
self.ty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> ToExpr for TraceAsStringAsInner<T> {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
Expr {
|
|
||||||
__enum: ExprEnum::TraceAsStringAsInner(TraceAsStringAsInner {
|
|
||||||
arg: self.arg,
|
|
||||||
ty: self.ty.canonical(),
|
|
||||||
literal_bits: self.literal_bits,
|
|
||||||
target: self.target,
|
|
||||||
})
|
|
||||||
.intern(),
|
|
||||||
__ty: self.ty,
|
|
||||||
__flow: Expr::flow(self.arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
/// The [`Simulation::io()`] equivalent for a global signal, this is a flipped version of a global signal
|
|
||||||
/// that allows you to e.g. use [`Simulation::write()`] to write to [`formal_global_clock()`].
|
|
||||||
///
|
|
||||||
/// [`Simulation::io()`]: crate::sim::Simulation::io
|
|
||||||
/// [`Simulation::write()`]: crate::sim::Simulation::write
|
|
||||||
/// [`formal_global_clock()`]: crate::formal::formal_global_clock
|
|
||||||
pub struct SimIoForGlobal {
|
|
||||||
global: FormalInput,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for SimIoForGlobal {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_tuple("SimIoForGlobal").field(&self.global).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SimIoForGlobal {
|
|
||||||
pub fn new(global: FormalInput) -> Self {
|
|
||||||
Self { global }
|
|
||||||
}
|
|
||||||
pub fn global(self) -> FormalInput {
|
|
||||||
self.global
|
|
||||||
}
|
|
||||||
pub(crate) fn must_connect_to(self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
pub fn flow(self) -> Flow {
|
|
||||||
self.global.flow().flip()
|
|
||||||
}
|
|
||||||
pub(crate) fn source_location(self) -> crate::source_location::SourceLocation {
|
|
||||||
self.global.source_location()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetTarget for SimIoForGlobal {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
Some(Target::from(*self).intern_sized())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToLiteralBits for SimIoForGlobal {
|
|
||||||
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
|
||||||
Err(NotALiteralExpr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ValueType for SimIoForGlobal {
|
|
||||||
type Type = CanonicalType;
|
|
||||||
type ValueCategory = ValueCategoryExpr;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
self.global.ty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToExpr for SimIoForGlobal {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
Expr {
|
|
||||||
__enum: ExprEnum::SimIoForGlobal(*self).intern(),
|
|
||||||
__ty: self.ty(),
|
|
||||||
__flow: self.flow(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,13 @@ use crate::{
|
||||||
array::Array,
|
array::Array,
|
||||||
bundle::{Bundle, BundleField},
|
bundle::{Bundle, BundleField},
|
||||||
expr::{Expr, Flow, ToExpr, ValueType, value_category::ValueCategoryExpr},
|
expr::{Expr, Flow, ToExpr, ValueType, value_category::ValueCategoryExpr},
|
||||||
formal::FormalInput,
|
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
memory::{DynPortType, MemPort},
|
memory::{DynPortType, MemPort},
|
||||||
module::{Instance, ModuleIO, TargetName},
|
module::{Instance, ModuleIO, TargetName},
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, TraceAsString, Type},
|
ty::{CanonicalType, Type},
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
@ -47,33 +46,11 @@ impl fmt::Display for TargetPathDynArrayElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct TargetPathTraceAsStringInner {}
|
|
||||||
|
|
||||||
impl fmt::Display for TargetPathTraceAsStringInner {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, ".<inner>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct TargetPathToTraceAsString {
|
|
||||||
pub ty: TraceAsString<CanonicalType>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for TargetPathToTraceAsString {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, ".to_trace_as_string(...)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum TargetPathElement {
|
pub enum TargetPathElement {
|
||||||
BundleField(TargetPathBundleField),
|
BundleField(TargetPathBundleField),
|
||||||
ArrayElement(TargetPathArrayElement),
|
ArrayElement(TargetPathArrayElement),
|
||||||
DynArrayElement(TargetPathDynArrayElement),
|
DynArrayElement(TargetPathDynArrayElement),
|
||||||
TraceAsStringInner(TargetPathTraceAsStringInner),
|
|
||||||
ToTraceAsString(TargetPathToTraceAsString),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TargetPathBundleField> for TargetPathElement {
|
impl From<TargetPathBundleField> for TargetPathElement {
|
||||||
|
|
@ -94,26 +71,12 @@ impl From<TargetPathDynArrayElement> for TargetPathElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TargetPathTraceAsStringInner> for TargetPathElement {
|
|
||||||
fn from(value: TargetPathTraceAsStringInner) -> Self {
|
|
||||||
Self::TraceAsStringInner(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TargetPathToTraceAsString> for TargetPathElement {
|
|
||||||
fn from(value: TargetPathToTraceAsString) -> Self {
|
|
||||||
Self::ToTraceAsString(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for TargetPathElement {
|
impl fmt::Display for TargetPathElement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::BundleField(v) => v.fmt(f),
|
Self::BundleField(v) => v.fmt(f),
|
||||||
Self::ArrayElement(v) => v.fmt(f),
|
Self::ArrayElement(v) => v.fmt(f),
|
||||||
Self::DynArrayElement(v) => v.fmt(f),
|
Self::DynArrayElement(v) => v.fmt(f),
|
||||||
Self::TraceAsStringInner(v) => v.fmt(f),
|
|
||||||
Self::ToTraceAsString(v) => v.fmt(f),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,15 +100,6 @@ impl TargetPathElement {
|
||||||
let parent_ty = Array::<CanonicalType>::from_canonical(parent.canonical_ty());
|
let parent_ty = Array::<CanonicalType>::from_canonical(parent.canonical_ty());
|
||||||
parent_ty.element()
|
parent_ty.element()
|
||||||
}
|
}
|
||||||
Self::TraceAsStringInner(_) => {
|
|
||||||
let parent_ty =
|
|
||||||
TraceAsString::<CanonicalType>::from_canonical(parent.canonical_ty());
|
|
||||||
parent_ty.inner_ty()
|
|
||||||
}
|
|
||||||
&Self::ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
|
||||||
assert_eq!(parent.canonical_ty(), ty.inner_ty());
|
|
||||||
ty.canonical()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn flow(&self, parent: Interned<Target>) -> Flow {
|
pub fn flow(&self, parent: Interned<Target>) -> Flow {
|
||||||
|
|
@ -157,18 +111,13 @@ impl TargetPathElement {
|
||||||
.expect("field name is known to be a valid field of parent type");
|
.expect("field name is known to be a valid field of parent type");
|
||||||
parent.flow().flip_if(field.flipped)
|
parent.flow().flip_if(field.flipped)
|
||||||
}
|
}
|
||||||
Self::ArrayElement(_)
|
Self::ArrayElement(_) => parent.flow(),
|
||||||
| Self::DynArrayElement(_)
|
Self::DynArrayElement(_) => parent.flow(),
|
||||||
| Self::TraceAsStringInner(_)
|
|
||||||
| Self::ToTraceAsString(_) => parent.flow(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_static(&self) -> bool {
|
pub fn is_static(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::BundleField(_)
|
Self::BundleField(_) | Self::ArrayElement(_) => true,
|
||||||
| Self::ArrayElement(_)
|
|
||||||
| Self::TraceAsStringInner(_)
|
|
||||||
| Self::ToTraceAsString(_) => true,
|
|
||||||
Self::DynArrayElement(_) => false,
|
Self::DynArrayElement(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -296,14 +245,6 @@ impl_target_base! {
|
||||||
#[is = is_instance]
|
#[is = is_instance]
|
||||||
#[to = instance]
|
#[to = instance]
|
||||||
Instance(Instance<Bundle>),
|
Instance(Instance<Bundle>),
|
||||||
#[from = from]
|
|
||||||
#[is = is_formal_input]
|
|
||||||
#[to = formal_input]
|
|
||||||
FormalInput(FormalInput),
|
|
||||||
#[from = from]
|
|
||||||
#[is = is_sim_io_for_global]
|
|
||||||
#[to = sim_io_for_global]
|
|
||||||
SimIoForGlobal(crate::expr::ops::SimIoForGlobal),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,8 +293,6 @@ impl TargetBase {
|
||||||
TargetBase::RegAsync(v) => TargetName(v.scoped_name(), None),
|
TargetBase::RegAsync(v) => TargetName(v.scoped_name(), None),
|
||||||
TargetBase::Wire(v) => TargetName(v.scoped_name(), None),
|
TargetBase::Wire(v) => TargetName(v.scoped_name(), None),
|
||||||
TargetBase::Instance(v) => TargetName(v.scoped_name(), None),
|
TargetBase::Instance(v) => TargetName(v.scoped_name(), None),
|
||||||
TargetBase::FormalInput(v) => TargetName(v.scoped_name(), None),
|
|
||||||
TargetBase::SimIoForGlobal(v) => TargetName(v.global().scoped_name(), None),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn canonical_ty(&self) -> CanonicalType {
|
pub fn canonical_ty(&self) -> CanonicalType {
|
||||||
|
|
@ -365,21 +304,6 @@ impl TargetBase {
|
||||||
TargetBase::RegAsync(v) => v.ty(),
|
TargetBase::RegAsync(v) => v.ty(),
|
||||||
TargetBase::Wire(v) => v.ty(),
|
TargetBase::Wire(v) => v.ty(),
|
||||||
TargetBase::Instance(v) => v.ty().canonical(),
|
TargetBase::Instance(v) => v.ty().canonical(),
|
||||||
TargetBase::FormalInput(v) => v.ty(),
|
|
||||||
TargetBase::SimIoForGlobal(v) => v.ty(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn is_valid_annotation_target(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::ModuleIO(_) => true,
|
|
||||||
Self::MemPort(_) => true,
|
|
||||||
Self::Reg(_) => true,
|
|
||||||
Self::RegSync(_) => true,
|
|
||||||
Self::RegAsync(_) => true,
|
|
||||||
Self::Wire(_) => true,
|
|
||||||
Self::Instance(_) => true,
|
|
||||||
Self::FormalInput(_) => false,
|
|
||||||
Self::SimIoForGlobal(_) => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +314,6 @@ pub struct TargetChild {
|
||||||
path_element: Interned<TargetPathElement>,
|
path_element: Interned<TargetPathElement>,
|
||||||
canonical_ty: CanonicalType,
|
canonical_ty: CanonicalType,
|
||||||
flow: Flow,
|
flow: Flow,
|
||||||
canonicalized_if_different: Option<Interned<Target>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for TargetChild {
|
impl fmt::Debug for TargetChild {
|
||||||
|
|
@ -400,7 +323,6 @@ impl fmt::Debug for TargetChild {
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: _,
|
canonical_ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
canonicalized_if_different: _,
|
|
||||||
} = self;
|
} = self;
|
||||||
parent.fmt(f)?;
|
parent.fmt(f)?;
|
||||||
fmt::Display::fmt(path_element, f)
|
fmt::Display::fmt(path_element, f)
|
||||||
|
|
@ -414,7 +336,6 @@ impl fmt::Display for TargetChild {
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: _,
|
canonical_ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
canonicalized_if_different: _,
|
|
||||||
} = self;
|
} = self;
|
||||||
parent.fmt(f)?;
|
parent.fmt(f)?;
|
||||||
path_element.fmt(f)
|
path_element.fmt(f)
|
||||||
|
|
@ -422,69 +343,14 @@ impl fmt::Display for TargetChild {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetChild {
|
impl TargetChild {
|
||||||
fn new_helper(
|
pub fn new(parent: Interned<Target>, path_element: Interned<TargetPathElement>) -> Self {
|
||||||
parent: Interned<Target>,
|
|
||||||
path_element: Interned<TargetPathElement>,
|
|
||||||
canonicalized_if_different: Option<Interned<Target>>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
parent,
|
parent,
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: path_element.canonical_ty(parent),
|
canonical_ty: path_element.canonical_ty(parent),
|
||||||
flow: path_element.flow(parent),
|
flow: path_element.flow(parent),
|
||||||
canonicalized_if_different,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn make_canonicalized_if_different(
|
|
||||||
parent: Interned<Target>,
|
|
||||||
path_element: Interned<TargetPathElement>,
|
|
||||||
) -> Option<Interned<Target>> {
|
|
||||||
use TargetPathElement::*;
|
|
||||||
match *path_element {
|
|
||||||
BundleField(_) => {}
|
|
||||||
ArrayElement(_) => {}
|
|
||||||
DynArrayElement(_) => {}
|
|
||||||
TraceAsStringInner(_) => {
|
|
||||||
if let Some(child) = parent.canonicalized().child() {
|
|
||||||
match *child.path_element() {
|
|
||||||
BundleField(_)
|
|
||||||
| ArrayElement(_)
|
|
||||||
| DynArrayElement(_)
|
|
||||||
| TraceAsStringInner(_) => {}
|
|
||||||
ToTraceAsString(_) => return Some(child.parent()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
|
||||||
if let Some(child) = parent.canonicalized().child() {
|
|
||||||
match *child.path_element() {
|
|
||||||
BundleField(_) | ArrayElement(_) | DynArrayElement(_)
|
|
||||||
| ToTraceAsString(_) => {}
|
|
||||||
TraceAsStringInner(_) => {
|
|
||||||
if ty.canonical() == child.parent().canonical_ty() {
|
|
||||||
return Some(child.parent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(
|
|
||||||
Target::Child(Self::new_helper(
|
|
||||||
parent.canonicalized_if_different()?,
|
|
||||||
path_element,
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
.intern_sized(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
pub fn new(parent: Interned<Target>, path_element: Interned<TargetPathElement>) -> Self {
|
|
||||||
Self::new_helper(
|
|
||||||
parent,
|
|
||||||
path_element,
|
|
||||||
Self::make_canonicalized_if_different(parent, path_element),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
pub fn parent(self) -> Interned<Target> {
|
pub fn parent(self) -> Interned<Target> {
|
||||||
self.parent
|
self.parent
|
||||||
}
|
}
|
||||||
|
|
@ -497,19 +363,6 @@ impl TargetChild {
|
||||||
pub fn flow(self) -> Flow {
|
pub fn flow(self) -> Flow {
|
||||||
self.flow
|
self.flow
|
||||||
}
|
}
|
||||||
pub fn is_canonicalized(self) -> bool {
|
|
||||||
self.canonicalized_if_different.is_none()
|
|
||||||
}
|
|
||||||
pub fn canonicalized_if_different(self) -> Option<Interned<Target>> {
|
|
||||||
self.canonicalized_if_different
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn canonicalized(self) -> Target {
|
|
||||||
match self.canonicalized_if_different {
|
|
||||||
Some(v) => *v,
|
|
||||||
None => Target::Child(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn bundle_field(self) -> Option<BundleField> {
|
pub fn bundle_field(self) -> Option<BundleField> {
|
||||||
if let TargetPathElement::BundleField(TargetPathBundleField { name }) = *self.path_element {
|
if let TargetPathElement::BundleField(TargetPathBundleField { name }) = *self.path_element {
|
||||||
let parent_ty = Bundle::from_canonical(self.parent.canonical_ty());
|
let parent_ty = Bundle::from_canonical(self.parent.canonical_ty());
|
||||||
|
|
@ -574,16 +427,6 @@ impl Target {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_valid_annotation_target(&self) -> bool {
|
|
||||||
let mut target = self;
|
|
||||||
loop {
|
|
||||||
match target {
|
|
||||||
Self::Base(target_base) => return target_base.is_valid_annotation_target(),
|
|
||||||
Self::Child(v) if !v.path_element().is_static() => return false,
|
|
||||||
Self::Child(v) => target = &v.parent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn join(&self, path_element: Interned<TargetPathElement>) -> Self {
|
pub fn join(&self, path_element: Interned<TargetPathElement>) -> Self {
|
||||||
TargetChild::new(self.intern(), path_element).into()
|
TargetChild::new(self.intern(), path_element).into()
|
||||||
|
|
@ -600,82 +443,6 @@ impl Target {
|
||||||
Target::Child(v) => v.canonical_ty(),
|
Target::Child(v) => v.canonical_ty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_canonicalized(self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Base(_) => true,
|
|
||||||
Self::Child(child) => child.is_canonicalized(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn canonicalized_if_different(self) -> Option<Interned<Self>> {
|
|
||||||
match self {
|
|
||||||
Self::Base(_) => None,
|
|
||||||
Self::Child(child) => child.canonicalized_if_different(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn canonicalized(self) -> Target {
|
|
||||||
match self.canonicalized_if_different() {
|
|
||||||
Some(v) => *v,
|
|
||||||
None => self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn canonicalized_interned(this: Interned<Target>) -> Interned<Target> {
|
|
||||||
this.canonicalized_if_different().unwrap_or(this)
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn unwrap_transparent_types(mut self) -> Target {
|
|
||||||
loop {
|
|
||||||
self = self.canonicalized();
|
|
||||||
match self.canonical_ty() {
|
|
||||||
CanonicalType::UInt(_)
|
|
||||||
| CanonicalType::SInt(_)
|
|
||||||
| CanonicalType::Bool(_)
|
|
||||||
| CanonicalType::Array(_)
|
|
||||||
| CanonicalType::Enum(_)
|
|
||||||
| CanonicalType::Bundle(_)
|
|
||||||
| CanonicalType::AsyncReset(_)
|
|
||||||
| CanonicalType::SyncReset(_)
|
|
||||||
| CanonicalType::Reset(_)
|
|
||||||
| CanonicalType::Clock(_)
|
|
||||||
| CanonicalType::PhantomConst(_)
|
|
||||||
| CanonicalType::DynSimOnly(_) => return self,
|
|
||||||
CanonicalType::TraceAsString(_) => {
|
|
||||||
if let Self::Child(child) = self
|
|
||||||
&& let TargetPathElement::ToTraceAsString(_) = *child.path_element()
|
|
||||||
{
|
|
||||||
self = *child.parent();
|
|
||||||
} else {
|
|
||||||
self = self.join(TargetPathElement::intern_sized(
|
|
||||||
TargetPathTraceAsStringInner {}.into(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn unwrap_transparent_types_interned(this: Interned<Target>) -> Interned<Target> {
|
|
||||||
let retval = this.unwrap_transparent_types();
|
|
||||||
if retval != *this {
|
|
||||||
retval.intern_sized()
|
|
||||||
} else {
|
|
||||||
this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
pub fn without_trailing_transparent_path_elements(mut self) -> Target {
|
|
||||||
use TargetPathElement::*;
|
|
||||||
loop {
|
|
||||||
match self {
|
|
||||||
Self::Base(_) => return self,
|
|
||||||
Self::Child(child) => match *child.path_element() {
|
|
||||||
BundleField(_) | ArrayElement(_) | DynArrayElement(_) => return self,
|
|
||||||
TraceAsStringInner(_) | ToTraceAsString(_) => self = *child.parent(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Target {
|
impl fmt::Display for Target {
|
||||||
|
|
@ -700,18 +467,6 @@ pub trait GetTarget {
|
||||||
fn target(&self) -> Option<Interned<Target>>;
|
fn target(&self) -> Option<Interned<Target>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetTarget for Target {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
Some(self.intern())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetTarget for TargetBase {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
Some(Target::Base(self.intern()).intern_sized())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetTarget for bool {
|
impl GetTarget for bool {
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
fn target(&self) -> Option<Interned<Target>> {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,189 +1,11 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::target::{GetTarget, Target},
|
|
||||||
int::BoolOrIntType,
|
int::BoolOrIntType,
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned, Memoize},
|
||||||
module::{NameId, NameIdOrGlobal, ScopedNameId},
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use std::{fmt, sync::OnceLock};
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
||||||
pub enum FormalInputKind {
|
|
||||||
FormalGlobalClock,
|
|
||||||
FormalReset,
|
|
||||||
AnyConst,
|
|
||||||
AnySeq,
|
|
||||||
AllConst,
|
|
||||||
AllSeq,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormalInputKind {
|
|
||||||
pub fn fixed_ty(self) -> Option<CanonicalType> {
|
|
||||||
match self {
|
|
||||||
Self::FormalGlobalClock => Some(Clock.into()),
|
|
||||||
Self::FormalReset => Some(SyncReset.into()),
|
|
||||||
Self::AnyConst => None,
|
|
||||||
Self::AnySeq => None,
|
|
||||||
Self::AllConst => None,
|
|
||||||
Self::AllSeq => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn fixed_id(self) -> Option<crate::module::Id> {
|
|
||||||
struct Cache {
|
|
||||||
formal_global_clock: crate::module::Id,
|
|
||||||
formal_reset: crate::module::Id,
|
|
||||||
}
|
|
||||||
static CACHE: OnceLock<Cache> = OnceLock::new();
|
|
||||||
let cache = || {
|
|
||||||
CACHE.get_or_init(
|
|
||||||
#[cold]
|
|
||||||
|| Cache {
|
|
||||||
formal_global_clock: crate::module::Id::new(),
|
|
||||||
formal_reset: crate::module::Id::new(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
Self::FormalGlobalClock => Some(cache().formal_global_clock),
|
|
||||||
Self::FormalReset => Some(cache().formal_reset),
|
|
||||||
Self::AnyConst => None,
|
|
||||||
Self::AnySeq => None,
|
|
||||||
Self::AllConst => None,
|
|
||||||
Self::AllSeq => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn fixed_source_location(self) -> Option<SourceLocation> {
|
|
||||||
match self {
|
|
||||||
Self::FormalGlobalClock | Self::FormalReset => Some(SourceLocation::builtin()),
|
|
||||||
Self::AnyConst | Self::AnySeq | Self::AllConst | Self::AllSeq => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn name(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Self::FormalGlobalClock => "formal_global_clock",
|
|
||||||
Self::FormalReset => "formal_reset",
|
|
||||||
Self::AnyConst => "any_const",
|
|
||||||
Self::AnySeq => "any_seq",
|
|
||||||
Self::AllConst => "all_const",
|
|
||||||
Self::AllSeq => "all_seq",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn interned_name(self) -> Interned<str> {
|
|
||||||
macro_rules! impl_interned_name {
|
|
||||||
($($variant:ident,)*) => {
|
|
||||||
match self {
|
|
||||||
$(Self::$variant => {
|
|
||||||
static CACHE: OnceLock<Interned<str>> = OnceLock::new();
|
|
||||||
*CACHE.get_or_init(|| Self::$variant.name().intern())
|
|
||||||
})*
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
impl_interned_name! {
|
|
||||||
FormalGlobalClock,
|
|
||||||
FormalReset,
|
|
||||||
AnyConst,
|
|
||||||
AnySeq,
|
|
||||||
AllConst,
|
|
||||||
AllSeq,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
|
||||||
struct FormalInputData {
|
|
||||||
kind: FormalInputKind,
|
|
||||||
name_id: NameId,
|
|
||||||
ty: CanonicalType,
|
|
||||||
source_location: SourceLocation,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct FormalInput(Interned<FormalInputData>);
|
|
||||||
|
|
||||||
impl fmt::Debug for FormalInput {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
if self.kind().fixed_ty().is_some() {
|
|
||||||
f.write_str(&self.name())
|
|
||||||
} else {
|
|
||||||
f.debug_tuple(&self.name()).field(&self.0.ty).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormalInput {
|
|
||||||
#[track_caller]
|
|
||||||
pub fn new(
|
|
||||||
kind: FormalInputKind,
|
|
||||||
name_id: NameId,
|
|
||||||
ty: CanonicalType,
|
|
||||||
source_location: SourceLocation,
|
|
||||||
) -> Self {
|
|
||||||
let NameId(name, id) = name_id;
|
|
||||||
assert_eq!(kind.interned_name(), name);
|
|
||||||
if let Some(fixed_ty) = kind.fixed_ty() {
|
|
||||||
assert_eq!(ty, fixed_ty);
|
|
||||||
} else {
|
|
||||||
assert!(
|
|
||||||
ty.is_castable_from_bits(),
|
|
||||||
"{name} type must be castable from bits. got:\n{ty:#?}",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(fixed_source_location) = kind.fixed_source_location() {
|
|
||||||
assert_eq!(source_location, fixed_source_location);
|
|
||||||
}
|
|
||||||
if let Some(fixed_id) = kind.fixed_id() {
|
|
||||||
assert_eq!(id, fixed_id);
|
|
||||||
}
|
|
||||||
Self(
|
|
||||||
FormalInputData {
|
|
||||||
kind,
|
|
||||||
name_id,
|
|
||||||
ty,
|
|
||||||
source_location,
|
|
||||||
}
|
|
||||||
.intern_sized(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
pub fn kind(self) -> FormalInputKind {
|
|
||||||
self.0.kind
|
|
||||||
}
|
|
||||||
pub fn name(self) -> Interned<str> {
|
|
||||||
self.0.name_id.0
|
|
||||||
}
|
|
||||||
pub fn name_id(self) -> NameId {
|
|
||||||
self.0.name_id
|
|
||||||
}
|
|
||||||
pub fn scoped_name(self) -> ScopedNameId {
|
|
||||||
ScopedNameId(NameIdOrGlobal::Global, self.name_id())
|
|
||||||
}
|
|
||||||
pub fn source_location(self) -> SourceLocation {
|
|
||||||
self.0.source_location
|
|
||||||
}
|
|
||||||
pub(crate) fn must_connect_to(self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
pub(crate) fn flow(self) -> crate::expr::Flow {
|
|
||||||
crate::expr::Flow::Source
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ValueType for FormalInput {
|
|
||||||
type Type = CanonicalType;
|
|
||||||
type ValueCategory = crate::expr::value_category::ValueCategoryExpr;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
self.0.ty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetTarget for FormalInput {
|
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
|
||||||
Some(Target::from(*self).intern_sized())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum FormalKind {
|
pub enum FormalKind {
|
||||||
|
|
@ -316,76 +138,110 @@ make_formal!(
|
||||||
hdl_cover
|
hdl_cover
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pub trait MakeFormalExpr: Type {}
|
||||||
|
|
||||||
|
impl<T: Type> MakeFormalExpr for T {}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub fn formal_global_clock() -> Expr<Clock> {
|
pub fn formal_global_clock() -> Expr<Clock> {
|
||||||
static CACHE: OnceLock<Expr<Clock>> = OnceLock::new();
|
#[hdl_module(extern)]
|
||||||
*CACHE.get_or_init(|| {
|
fn formal_global_clock() {
|
||||||
let kind = FormalInputKind::FormalGlobalClock;
|
#[hdl]
|
||||||
Expr::from_canonical(
|
let clk: Clock = m.output();
|
||||||
FormalInput::new(
|
m.annotate_module(BlackBoxInlineAnnotation {
|
||||||
kind,
|
path: "fayalite_formal_global_clock.v".intern(),
|
||||||
NameId(
|
text: r"module __fayalite_formal_global_clock(output clk);
|
||||||
kind.interned_name(),
|
(* gclk *)
|
||||||
kind.fixed_id().expect("known to have a fixed Id"),
|
reg clk;
|
||||||
),
|
endmodule
|
||||||
Clock.into(),
|
"
|
||||||
kind.fixed_source_location()
|
.intern(),
|
||||||
.expect("known to have a fixed SourceLocation"),
|
});
|
||||||
)
|
m.verilog_name("__fayalite_formal_global_clock");
|
||||||
.to_expr(),
|
}
|
||||||
)
|
#[hdl]
|
||||||
})
|
let formal_global_clock = instance(formal_global_clock());
|
||||||
|
formal_global_clock.clk
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub fn formal_reset() -> Expr<SyncReset> {
|
pub fn formal_reset() -> Expr<SyncReset> {
|
||||||
static CACHE: OnceLock<Expr<SyncReset>> = OnceLock::new();
|
#[hdl_module(extern)]
|
||||||
*CACHE.get_or_init(|| {
|
fn formal_reset() {
|
||||||
let kind = FormalInputKind::FormalReset;
|
#[hdl]
|
||||||
Expr::from_canonical(
|
let rst: SyncReset = m.output();
|
||||||
FormalInput::new(
|
m.annotate_module(BlackBoxInlineAnnotation {
|
||||||
kind,
|
path: "fayalite_formal_reset.v".intern(),
|
||||||
NameId(
|
text: r"module __fayalite_formal_reset(output rst);
|
||||||
kind.interned_name(),
|
assign rst = $initstate;
|
||||||
kind.fixed_id().expect("known to have a fixed Id"),
|
endmodule
|
||||||
),
|
"
|
||||||
SyncReset.into(),
|
.intern(),
|
||||||
kind.fixed_source_location()
|
});
|
||||||
.expect("known to have a fixed SourceLocation"),
|
m.verilog_name("__fayalite_formal_reset");
|
||||||
)
|
}
|
||||||
.to_expr(),
|
static MOD: OnceLock<Interned<Module<formal_reset>>> = OnceLock::new();
|
||||||
)
|
#[hdl]
|
||||||
})
|
let formal_reset = instance(*MOD.get_or_init(formal_reset));
|
||||||
|
formal_reset.rst
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! make_any_const_fn {
|
macro_rules! make_any_const_fn {
|
||||||
($ident:ident, $ident_with_loc:ident, $verilog_attribute:literal, $kind:ident) => {
|
($ident:ident, $verilog_attribute:literal) => {
|
||||||
#[track_caller]
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub fn $ident<T: BoolOrIntType>(ty: T) -> Expr<T> {
|
pub fn $ident<T: BoolOrIntType>(ty: T) -> Expr<T> {
|
||||||
$ident_with_loc(ty, SourceLocation::caller())
|
#[hdl_module(extern)]
|
||||||
}
|
pub(super) fn $ident<T: BoolOrIntType>(ty: T) {
|
||||||
#[track_caller]
|
#[hdl]
|
||||||
#[hdl]
|
let out: T = m.output(ty);
|
||||||
pub fn $ident_with_loc<T: BoolOrIntType>(
|
let width = ty.width();
|
||||||
ty: T,
|
let verilog_bitslice = if width == 1 {
|
||||||
source_location: SourceLocation,
|
String::new()
|
||||||
) -> Expr<T> {
|
} else {
|
||||||
let kind = FormalInputKind::$kind;
|
format!(" [{}:0]", width - 1)
|
||||||
Expr::from_canonical(
|
};
|
||||||
FormalInput::new(
|
m.annotate_module(BlackBoxInlineAnnotation {
|
||||||
kind,
|
path: Intern::intern_owned(format!(
|
||||||
NameId(kind.interned_name(), crate::module::Id::new()),
|
"fayalite_{}_{width}.v",
|
||||||
ty.canonical(),
|
stringify!($ident),
|
||||||
source_location,
|
)),
|
||||||
)
|
text: Intern::intern_owned(format!(
|
||||||
.to_expr(),
|
r"module __fayalite_{}_{width}(output{verilog_bitslice} out);
|
||||||
)
|
(* {} *)
|
||||||
|
reg{verilog_bitslice} out;
|
||||||
|
endmodule
|
||||||
|
",
|
||||||
|
stringify!($ident),
|
||||||
|
$verilog_attribute,
|
||||||
|
)),
|
||||||
|
});
|
||||||
|
m.verilog_name(format!("__fayalite_{}_{width}", stringify!($ident)));
|
||||||
|
}
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
struct TheMemoize<T>(T);
|
||||||
|
impl<T: BoolOrIntType> Memoize for TheMemoize<T> {
|
||||||
|
type Input = ();
|
||||||
|
type InputOwned = ();
|
||||||
|
type Output = Option<Interned<Module<$ident<T>>>>;
|
||||||
|
fn inner(self, _input: &Self::Input) -> Self::Output {
|
||||||
|
if self.0.width() == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some($ident(self.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let Some(module) = TheMemoize(ty).get_owned(()) else {
|
||||||
|
return 0_hdl_u0.cast_bits_to(ty);
|
||||||
|
};
|
||||||
|
#[hdl]
|
||||||
|
let $ident = instance(module);
|
||||||
|
$ident.out
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
make_any_const_fn!(any_const, any_const_with_loc, "anyconst", AnyConst);
|
make_any_const_fn!(any_const, "anyconst");
|
||||||
make_any_const_fn!(any_seq, any_seq_with_loc, "anyseq", AnySeq);
|
make_any_const_fn!(any_seq, "anyseq");
|
||||||
make_any_const_fn!(all_const, all_const_with_loc, "allconst", AllConst);
|
make_any_const_fn!(all_const, "allconst");
|
||||||
make_any_const_fn!(all_seq, all_seq_with_loc, "allseq", AllSeq);
|
make_any_const_fn!(all_seq, "allseq");
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ use crate::{
|
||||||
value_category::ValueCategoryValue,
|
value_category::ValueCategoryValue,
|
||||||
},
|
},
|
||||||
hdl,
|
hdl,
|
||||||
intern::{Intern, Interned, Memoize, OnceInterned},
|
intern::{Intern, Interned, Memoize},
|
||||||
sim::value::{SimValue, ToSimValueWithType},
|
sim::value::{SimValue, ToSimValueWithType},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, FillInDefaultedGenerics, OpaqueSimValueSize, OpaqueSimValueSlice,
|
CanonicalType, FillInDefaultedGenerics, OpaqueSimValueSize, OpaqueSimValueSlice,
|
||||||
OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug, SimValueDisplay, StaticType,
|
OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, TypeProperties,
|
||||||
Type, TypeProperties, impl_match_variant_as_self,
|
impl_match_variant_as_self,
|
||||||
},
|
},
|
||||||
util::{ConstBool, ConstUsize, GenericConstBool, GenericConstUsize, interned_bit, slice_range},
|
util::{ConstBool, ConstUsize, GenericConstBool, GenericConstUsize, interned_bit, slice_range},
|
||||||
};
|
};
|
||||||
|
|
@ -65,21 +65,14 @@ pub type DynSize = ConstUsize<DYN_SIZE>;
|
||||||
|
|
||||||
trait KnownSizeBaseSealed {}
|
trait KnownSizeBaseSealed {}
|
||||||
|
|
||||||
impl<const N: usize> KnownSizeBaseSealed for ConstUsize<N> {}
|
impl<const N: usize> KnownSizeBaseSealed for [(); N] {}
|
||||||
|
|
||||||
#[expect(private_bounds)]
|
#[expect(private_bounds)]
|
||||||
pub trait KnownSizeBase: KnownSizeBaseSealed + GetInternedIntCaches {}
|
pub trait KnownSizeBase: KnownSizeBaseSealed {}
|
||||||
|
|
||||||
macro_rules! impl_known_size_base {
|
macro_rules! impl_known_size_base {
|
||||||
($($size:literal),* $(,)?) => {
|
($($size:literal),* $(,)?) => {
|
||||||
$(impl KnownSizeBase for ConstUsize<$size> {})*
|
$(impl KnownSizeBase for [(); $size] {})*
|
||||||
$(impl GetInternedIntCaches for ConstUsize<$size> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn get_interned_int_caches() -> &'static InternedIntCaches<Self> {
|
|
||||||
static CACHES: InternedIntCaches<ConstUsize<$size>> = InternedIntCaches::new();
|
|
||||||
&CACHES
|
|
||||||
}
|
|
||||||
})*
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,34 +113,12 @@ impl_known_size_base! {
|
||||||
0x200,
|
0x200,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GetInternedIntCaches {
|
|
||||||
fn get_interned_int_caches() -> &'static InternedIntCaches<Self>
|
|
||||||
where
|
|
||||||
Self: KnownSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InternedIntCaches<Width: KnownSize> {
|
|
||||||
uint: OnceInterned<UIntType<Width>>,
|
|
||||||
sint: OnceInterned<SIntType<Width>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Width: KnownSize> InternedIntCaches<Width> {
|
|
||||||
const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
uint: OnceInterned::new(),
|
|
||||||
sint: OnceInterned::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[expect(private_bounds)]
|
|
||||||
pub trait KnownSize:
|
pub trait KnownSize:
|
||||||
GenericConstUsize
|
GenericConstUsize
|
||||||
+ sealed::SizeTypeSealed
|
+ sealed::SizeTypeSealed
|
||||||
+ sealed::SizeSealed
|
+ sealed::SizeSealed
|
||||||
+ Default
|
+ Default
|
||||||
+ FillInDefaultedGenerics<Type = Self>
|
+ FillInDefaultedGenerics<Type = Self>
|
||||||
+ GetInternedIntCaches
|
|
||||||
{
|
{
|
||||||
const SIZE: Self;
|
const SIZE: Self;
|
||||||
type ArrayMatch<Element: Type>: AsRef<[Expr<Element>]>
|
type ArrayMatch<Element: Type>: AsRef<[Expr<Element>]>
|
||||||
|
|
@ -177,7 +148,7 @@ pub trait KnownSize:
|
||||||
|
|
||||||
impl<const N: usize> KnownSize for ConstUsize<N>
|
impl<const N: usize> KnownSize for ConstUsize<N>
|
||||||
where
|
where
|
||||||
ConstUsize<N>: KnownSizeBase,
|
[(); N]: KnownSizeBase,
|
||||||
{
|
{
|
||||||
const SIZE: Self = Self;
|
const SIZE: Self = Self;
|
||||||
type ArrayMatch<Element: Type> = [Expr<Element>; N];
|
type ArrayMatch<Element: Type> = [Expr<Element>; N];
|
||||||
|
|
@ -250,10 +221,6 @@ pub trait Size:
|
||||||
fn from_usize(v: usize) -> Self::SizeType {
|
fn from_usize(v: usize) -> Self::SizeType {
|
||||||
Self::try_from_usize(v).expect("wrong size")
|
Self::try_from_usize(v).expect("wrong size")
|
||||||
}
|
}
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_uint(size_type: Self::SizeType) -> Interned<UIntType<Self>>;
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_sint(size_type: Self::SizeType) -> Interned<SIntType<Self>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::SizeTypeSealed for usize {}
|
impl sealed::SizeTypeSealed for usize {}
|
||||||
|
|
@ -262,8 +229,6 @@ impl SizeType for usize {
|
||||||
type Size = DynSize;
|
type Size = DynSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_CACHED_INT_WIDTH: usize = 1 << 10;
|
|
||||||
|
|
||||||
impl Size for DynSize {
|
impl Size for DynSize {
|
||||||
type ArrayMatch<Element: Type> = Box<[Expr<Element>]>;
|
type ArrayMatch<Element: Type> = Box<[Expr<Element>]>;
|
||||||
type ArraySimValue<Element: Type> = Box<[SimValue<Element>]>;
|
type ArraySimValue<Element: Type> = Box<[SimValue<Element>]>;
|
||||||
|
|
@ -277,36 +242,6 @@ impl Size for DynSize {
|
||||||
fn try_from_usize(v: usize) -> Option<Self::SizeType> {
|
fn try_from_usize(v: usize) -> Option<Self::SizeType> {
|
||||||
Some(v)
|
Some(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_uint(size_type: Self::SizeType) -> Interned<UIntType<Self>> {
|
|
||||||
static CACHED: [OnceInterned<UInt>; MAX_CACHED_INT_WIDTH] =
|
|
||||||
[const { OnceInterned::new() }; _];
|
|
||||||
#[cold]
|
|
||||||
fn intern_cold(width: usize) -> Interned<UInt> {
|
|
||||||
Intern::intern_sized(UInt::new(width))
|
|
||||||
}
|
|
||||||
if let Some(cached) = CACHED.get(size_type) {
|
|
||||||
cached.get_or_init(|| intern_cold(size_type))
|
|
||||||
} else {
|
|
||||||
intern_cold(size_type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_sint(size_type: Self::SizeType) -> Interned<SIntType<Self>> {
|
|
||||||
static CACHED: [OnceInterned<SInt>; MAX_CACHED_INT_WIDTH] =
|
|
||||||
[const { OnceInterned::new() }; _];
|
|
||||||
#[cold]
|
|
||||||
fn intern_cold(width: usize) -> Interned<SInt> {
|
|
||||||
Intern::intern_sized(SInt::new(width))
|
|
||||||
}
|
|
||||||
if let Some(cached) = CACHED.get(size_type) {
|
|
||||||
cached.get_or_init(|| intern_cold(size_type))
|
|
||||||
} else {
|
|
||||||
intern_cold(size_type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const VALUE: usize> sealed::SizeSealed for ConstUsize<VALUE> {}
|
impl<const VALUE: usize> sealed::SizeSealed for ConstUsize<VALUE> {}
|
||||||
|
|
@ -332,20 +267,6 @@ impl<T: KnownSize> Size for T {
|
||||||
fn try_from_usize(v: usize) -> Option<Self::SizeType> {
|
fn try_from_usize(v: usize) -> Option<Self::SizeType> {
|
||||||
if v == T::VALUE { Some(T::SIZE) } else { None }
|
if v == T::VALUE { Some(T::SIZE) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_uint(_size_type: Self::SizeType) -> Interned<UIntType<Self>> {
|
|
||||||
T::get_interned_int_caches()
|
|
||||||
.uint
|
|
||||||
.get_or_init(|| UIntType::new_static().intern_sized())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn interned_sint(_size_type: Self::SizeType) -> Interned<SIntType<Self>> {
|
|
||||||
T::get_interned_int_caches()
|
|
||||||
.sint
|
|
||||||
.get_or_init(|| SIntType::new_static().intern_sized())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
|
@ -665,7 +586,7 @@ macro_rules! impl_valueless_op_forward {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_int {
|
macro_rules! impl_int {
|
||||||
($pretty_name:ident, $name:ident, $generic_name:ident, $value:ident, $SIGNED:literal, $interned_int:ident) => {
|
($pretty_name:ident, $name:ident, $generic_name:ident, $value:ident, $SIGNED:literal) => {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct $name<Width: Size = DynSize> {
|
pub struct $name<Width: Size = DynSize> {
|
||||||
|
|
@ -1019,24 +940,6 @@ macro_rules! impl_int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Width: Size> SimValueDebug for $name<Width> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Width: Size> SimValueDisplay for $name<Width> {
|
|
||||||
fn sim_value_display(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Display::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Width: KnownSize> Default for $name<Width> {
|
impl<Width: KnownSize> Default for $name<Width> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::TYPE
|
Self::TYPE
|
||||||
|
|
@ -1100,7 +1003,7 @@ macro_rules! impl_int {
|
||||||
type Output = $name<Width::Size>;
|
type Output = $name<Width::Size>;
|
||||||
|
|
||||||
fn index(&self, width: Width) -> &Self::Output {
|
fn index(&self, width: Width) -> &Self::Output {
|
||||||
Interned::into_inner(Width::Size::$interned_int(width))
|
Interned::into_inner(Intern::intern_sized($name::new(width)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1277,29 +1180,12 @@ macro_rules! impl_int {
|
||||||
pub fn bitvec_mut(&mut self) -> &mut BitVec {
|
pub fn bitvec_mut(&mut self) -> &mut BitVec {
|
||||||
Arc::make_mut(&mut self.bits)
|
Arc::make_mut(&mut self.bits)
|
||||||
}
|
}
|
||||||
pub fn arc_bitvec_mut(&mut self) -> &mut Arc<BitVec> {
|
|
||||||
&mut self.bits
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_int!(
|
impl_int!(UInt, UIntType, UIntWithoutGenerics, UIntValue, false);
|
||||||
UInt,
|
impl_int!(SInt, SIntType, SIntWithoutGenerics, SIntValue, true);
|
||||||
UIntType,
|
|
||||||
UIntWithoutGenerics,
|
|
||||||
UIntValue,
|
|
||||||
false,
|
|
||||||
interned_uint
|
|
||||||
);
|
|
||||||
impl_int!(
|
|
||||||
SInt,
|
|
||||||
SIntType,
|
|
||||||
SIntWithoutGenerics,
|
|
||||||
SIntValue,
|
|
||||||
true,
|
|
||||||
interned_sint
|
|
||||||
);
|
|
||||||
|
|
||||||
impl UInt {
|
impl UInt {
|
||||||
/// gets the smallest `UInt` that fits `v` losslessly
|
/// gets the smallest `UInt` that fits `v` losslessly
|
||||||
|
|
@ -1920,15 +1806,6 @@ impl Type for Bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for Bool {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StaticType for Bool {
|
impl StaticType for Bool {
|
||||||
const TYPE: Self = Bool;
|
const TYPE: Self = Bool;
|
||||||
const MASK_TYPE: Self::MaskType = Bool;
|
const MASK_TYPE: Self::MaskType = Bool;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
|
CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
|
||||||
SimValueDebug, StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bitvec::{order::Lsb0, view::BitView};
|
use bitvec::{order::Lsb0, view::BitView};
|
||||||
|
|
@ -94,15 +94,6 @@ impl Type for UIntInRangeMaskType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for UIntInRangeMaskType {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BundleType for UIntInRangeMaskType {
|
impl BundleType for UIntInRangeMaskType {
|
||||||
type Builder = NoBuilder;
|
type Builder = NoBuilder;
|
||||||
|
|
||||||
|
|
@ -348,15 +339,6 @@ macro_rules! define_uint_in_range_type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Start: Size, End: Size> SimValueDebug for $UIntInRangeType<Start, End> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Start: Size, End: Size> fmt::Debug for $UIntInRangeType<Start, End> {
|
impl<Start: Size, End: Size> fmt::Debug for $UIntInRangeType<Start, End> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let Self { value, range } = self;
|
let Self { value, range } = self;
|
||||||
|
|
|
||||||
|
|
@ -4,191 +4,68 @@
|
||||||
use crate::{intern::type_map::TypeIdMap, util::DefaultBuildHasher};
|
use crate::{intern::type_map::TypeIdMap, util::DefaultBuildHasher};
|
||||||
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
|
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
|
||||||
use hashbrown::HashTable;
|
use hashbrown::HashTable;
|
||||||
use once_cell::race::OnceRef;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
borrow::{Borrow, Cow},
|
borrow::{Borrow, Cow},
|
||||||
cell::RefCell,
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ffi::{OsStr, OsString},
|
ffi::{OsStr, OsString},
|
||||||
fmt,
|
fmt,
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
hash::{BuildHasher, Hash, Hasher},
|
||||||
iter::FusedIterator,
|
iter::FusedIterator,
|
||||||
|
marker::PhantomData,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::RwLock,
|
sync::{Mutex, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod interner;
|
|
||||||
mod type_map;
|
mod type_map;
|
||||||
|
|
||||||
/// invariant: T must be zero-sized, `type_id` is unique for every possible T value.
|
pub trait LazyInternedTrait<T: ?Sized + Send + Sync + 'static>: Send + Sync + Any {
|
||||||
struct LazyInternedLazyInner<T: ?Sized + 'static> {
|
fn get(&self) -> Interned<T>;
|
||||||
type_id: TypeId,
|
|
||||||
value: T,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static> Hash for LazyInternedLazyInner<T> {
|
impl<T: ?Sized + Send + Sync + 'static, F: ?Sized + Fn() -> Interned<T> + Send + Sync + Any>
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
LazyInternedTrait<T> for F
|
||||||
let Self { type_id, value: _ } = self;
|
{
|
||||||
type_id.hash(state);
|
fn get(&self) -> Interned<T> {
|
||||||
|
self()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static> PartialEq for LazyInternedLazyInner<T> {
|
#[repr(transparent)]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
pub struct LazyInternedFn<T: ?Sized + Send + Sync + 'static>(pub &'static dyn LazyInternedTrait<T>);
|
||||||
let Self { type_id, value: _ } = self;
|
|
||||||
*type_id == other.type_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static> Eq for LazyInternedLazyInner<T> {}
|
impl<T: ?Sized + Send + Sync + 'static> Copy for LazyInternedFn<T> {}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static> fmt::Debug for LazyInternedLazyInner<T> {
|
impl<T: ?Sized + Send + Sync + 'static> Clone for LazyInternedFn<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("LazyInternedLazyInner")
|
|
||||||
.finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static> LazyInternedLazyInner<T> {
|
|
||||||
const fn new(value: T) -> Self
|
|
||||||
where
|
|
||||||
T: Sized,
|
|
||||||
{
|
|
||||||
const { assert!(size_of::<T>() == 0) };
|
|
||||||
Self {
|
|
||||||
type_id: TypeId::of::<T>(),
|
|
||||||
value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LazyInternedLazy<T: ?Sized + Send + Sync + 'static>(
|
|
||||||
&'static LazyInternedLazyInner<dyn Fn() -> Interned<T> + Send + Sync>,
|
|
||||||
);
|
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> LazyInternedLazy<T> {
|
|
||||||
pub const fn new_const<V: Default + Into<Interned<T>>>() -> Self {
|
|
||||||
Self(&const { LazyInternedLazyInner::new(|| V::default().into()) })
|
|
||||||
}
|
|
||||||
pub const fn new_const_default() -> Self
|
|
||||||
where
|
|
||||||
Interned<T>: Default,
|
|
||||||
{
|
|
||||||
Self::new_const::<Interned<T>>()
|
|
||||||
}
|
|
||||||
pub fn interned(self) -> Interned<T> {
|
|
||||||
struct Map(hashbrown::HashTable<(TypeId, &'static (dyn Any + Send + Sync))>);
|
|
||||||
impl Map {
|
|
||||||
const EMPTY: Self = Self(hashbrown::HashTable::new());
|
|
||||||
fn get<T: ?Sized + Send + Sync + 'static>(
|
|
||||||
&self,
|
|
||||||
lazy_interned_lazy: LazyInternedLazy<T>,
|
|
||||||
hash: u64,
|
|
||||||
) -> Option<&'static Interned<T>> {
|
|
||||||
let &(_, v) = self.0.find(hash, |v| v.0 == lazy_interned_lazy.0.type_id)?;
|
|
||||||
let Some(retval) = v.downcast_ref::<Interned<T>>() else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
Some(retval)
|
|
||||||
}
|
|
||||||
fn get_or_insert<T: ?Sized + Send + Sync + 'static>(
|
|
||||||
&mut self,
|
|
||||||
lazy_interned_lazy: LazyInternedLazy<T>,
|
|
||||||
hash: u64,
|
|
||||||
v: &'static Interned<T>,
|
|
||||||
) -> &'static Interned<T> {
|
|
||||||
let entry = self
|
|
||||||
.0
|
|
||||||
.entry(
|
|
||||||
hash,
|
|
||||||
|&(k, _)| k == lazy_interned_lazy.0.type_id,
|
|
||||||
|&(k, _)| type_map::TypeIdBuildHasher.hash_one(k),
|
|
||||||
)
|
|
||||||
.or_insert_with(|| (lazy_interned_lazy.0.type_id, v));
|
|
||||||
let &(_, v) = entry.get();
|
|
||||||
let Some(retval) = v.downcast_ref::<Interned<T>>() else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
retval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static GLOBAL_CACHE: RwLock<Map> = RwLock::new(Map::EMPTY);
|
|
||||||
#[cold]
|
|
||||||
fn insert_in_thread_local_cache<T: ?Sized + Send + Sync + 'static>(
|
|
||||||
cache: &RefCell<Map>,
|
|
||||||
this: LazyInternedLazy<T>,
|
|
||||||
hash: u64,
|
|
||||||
) -> Interned<T> {
|
|
||||||
let read_lock = GLOBAL_CACHE.read().unwrap();
|
|
||||||
let v = read_lock.get(this, hash);
|
|
||||||
drop(read_lock);
|
|
||||||
let v = v.unwrap_or_else(|| {
|
|
||||||
let v = Box::leak(Box::new((this.0.value)()));
|
|
||||||
GLOBAL_CACHE.write().unwrap().get_or_insert(this, hash, v)
|
|
||||||
});
|
|
||||||
*cache.borrow_mut().get_or_insert(this, hash, v)
|
|
||||||
}
|
|
||||||
thread_local! {
|
|
||||||
static THREAD_LOCAL_CACHE: RefCell<Map> = const { RefCell::new(Map::EMPTY) };
|
|
||||||
}
|
|
||||||
let hash = type_map::TypeIdBuildHasher.hash_one(self.0.type_id);
|
|
||||||
THREAD_LOCAL_CACHE.with(|cache| {
|
|
||||||
let borrow = cache.borrow();
|
|
||||||
if let Some(v) = borrow.get(self, hash) {
|
|
||||||
*v
|
|
||||||
} else {
|
|
||||||
drop(borrow);
|
|
||||||
insert_in_thread_local_cache(cache, self, hash)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> Copy for LazyInternedLazy<T> {}
|
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> Clone for LazyInternedLazy<T> {
|
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> Hash for LazyInternedLazy<T> {
|
impl<T: ?Sized + Send + Sync + 'static> Hash for LazyInternedFn<T> {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.0.hash(state);
|
self.0.get_ptr_eq_with_type_id().hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> Eq for LazyInternedLazy<T> {}
|
impl<T: ?Sized + Send + Sync + 'static> Eq for LazyInternedFn<T> {}
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> PartialEq for LazyInternedLazy<T> {
|
impl<T: ?Sized + Send + Sync + 'static> PartialEq for LazyInternedFn<T> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.0 == other.0
|
self.0.get_ptr_eq_with_type_id() == other.0.get_ptr_eq_with_type_id()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum LazyInterned<T: ?Sized + Send + Sync + 'static> {
|
pub enum LazyInterned<T: ?Sized + Send + Sync + 'static> {
|
||||||
Interned(Interned<T>),
|
Interned(Interned<T>),
|
||||||
Lazy(LazyInternedLazy<T>),
|
Lazy(LazyInternedFn<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> LazyInterned<T> {
|
impl<T: ?Sized + Send + Sync + 'static> LazyInterned<T> {
|
||||||
pub const fn new_const<V: Default + Into<Interned<T>>>() -> Self {
|
pub const fn new_lazy(v: &'static dyn LazyInternedTrait<T>) -> Self {
|
||||||
Self::Lazy(LazyInternedLazy::new_const::<V>())
|
Self::Lazy(LazyInternedFn(v))
|
||||||
}
|
|
||||||
pub const fn new_const_default() -> Self
|
|
||||||
where
|
|
||||||
Interned<T>: Default,
|
|
||||||
{
|
|
||||||
Self::new_const::<Interned<T>>()
|
|
||||||
}
|
|
||||||
pub fn interned(self) -> Interned<T> {
|
|
||||||
match self {
|
|
||||||
Self::Interned(retval) => retval,
|
|
||||||
Self::Lazy(retval) => retval.interned(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +77,7 @@ impl<T: ?Sized + Sync + Send + 'static> Clone for LazyInterned<T> {
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> Copy for LazyInterned<T> {}
|
impl<T: ?Sized + Sync + Send + 'static> Copy for LazyInterned<T> {}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> Deref for LazyInterned<T> {
|
impl<T: ?Sized + Sync + Send + 'static + Intern> Deref for LazyInterned<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
|
@ -208,9 +85,9 @@ impl<T: ?Sized + Sync + Send + 'static> Deref for LazyInterned<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> Eq for LazyInterned<T> where Interned<T>: Eq {}
|
impl<T: ?Sized + Sync + Send + 'static + Intern> Eq for LazyInterned<T> where Interned<T>: Eq {}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> PartialEq for LazyInterned<T>
|
impl<T: ?Sized + Sync + Send + 'static + Intern> PartialEq for LazyInterned<T>
|
||||||
where
|
where
|
||||||
Interned<T>: PartialEq,
|
Interned<T>: PartialEq,
|
||||||
{
|
{
|
||||||
|
|
@ -219,7 +96,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> Ord for LazyInterned<T>
|
impl<T: ?Sized + Sync + Send + 'static + Intern> Ord for LazyInterned<T>
|
||||||
where
|
where
|
||||||
Interned<T>: Ord,
|
Interned<T>: Ord,
|
||||||
{
|
{
|
||||||
|
|
@ -228,7 +105,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> PartialOrd for LazyInterned<T>
|
impl<T: ?Sized + Sync + Send + 'static + Intern> PartialOrd for LazyInterned<T>
|
||||||
where
|
where
|
||||||
Interned<T>: PartialOrd,
|
Interned<T>: PartialOrd,
|
||||||
{
|
{
|
||||||
|
|
@ -237,7 +114,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + Sync + Send + 'static> Hash for LazyInterned<T>
|
impl<T: ?Sized + Sync + Send + 'static + Intern> Hash for LazyInterned<T>
|
||||||
where
|
where
|
||||||
Interned<T>: Hash,
|
Interned<T>: Hash,
|
||||||
{
|
{
|
||||||
|
|
@ -246,6 +123,77 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Sync + Send + 'static> LazyInterned<T> {
|
||||||
|
pub fn interned(self) -> Interned<T>
|
||||||
|
where
|
||||||
|
T: Intern,
|
||||||
|
{
|
||||||
|
struct MemoizeInterned<T: ?Sized + Intern>(PhantomData<T>);
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> Hash for MemoizeInterned<T> {
|
||||||
|
fn hash<H: Hasher>(&self, _state: &mut H) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> PartialEq for MemoizeInterned<T> {
|
||||||
|
fn eq(&self, _other: &Self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> Eq for MemoizeInterned<T> {}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> Clone for MemoizeInterned<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> Copy for MemoizeInterned<T> {}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Intern> MemoizeGeneric for MemoizeInterned<T> {
|
||||||
|
type InputRef<'a> = LazyInternedFn<T>;
|
||||||
|
|
||||||
|
type InputOwned = LazyInternedFn<T>;
|
||||||
|
|
||||||
|
type InputCow<'a> = LazyInternedFn<T>;
|
||||||
|
|
||||||
|
type Output = Interned<T>;
|
||||||
|
|
||||||
|
fn input_eq(a: Self::InputRef<'_>, b: Self::InputRef<'_>) -> bool {
|
||||||
|
a == b
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_borrow(input: &Self::InputOwned) -> Self::InputRef<'_> {
|
||||||
|
*input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_cow_into_owned(input: Self::InputCow<'_>) -> Self::InputOwned {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_cow_borrow<'a>(input: &'a Self::InputCow<'_>) -> Self::InputRef<'a> {
|
||||||
|
*input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_cow_from_owned<'a>(input: Self::InputOwned) -> Self::InputCow<'a> {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_cow_from_ref(input: Self::InputRef<'_>) -> Self::InputCow<'_> {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(self, input: Self::InputRef<'_>) -> Self::Output {
|
||||||
|
input.0.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match self {
|
||||||
|
Self::Interned(retval) => retval,
|
||||||
|
Self::Lazy(retval) => MemoizeInterned(PhantomData).get(retval),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait InternedCompare {
|
pub trait InternedCompare {
|
||||||
type InternedCompareKey: Ord + Hash;
|
type InternedCompareKey: Ord + Hash;
|
||||||
fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey;
|
fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey;
|
||||||
|
|
@ -645,6 +593,71 @@ impl<T: ?Sized + 'static + Send + Sync + ToOwned> From<Interned<T>> for Cow<'_,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct InternerState<T: ?Sized + 'static + Send + Sync> {
|
||||||
|
table: HashTable<&'static T>,
|
||||||
|
hasher: DefaultBuildHasher,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Interner<T: ?Sized + 'static + Send + Sync> {
|
||||||
|
state: Mutex<InternerState<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
|
||||||
|
fn get() -> &'static Interner<T> {
|
||||||
|
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
||||||
|
TYPE_ID_MAP.get_or_insert_default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
state: Mutex::new(InternerState {
|
||||||
|
table: HashTable::new(),
|
||||||
|
hasher: Default::default(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
|
||||||
|
fn intern<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
||||||
|
&self,
|
||||||
|
alloc: F,
|
||||||
|
value: Cow<'_, T>,
|
||||||
|
) -> Interned<T> {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
let InternerState { table, hasher } = &mut *state;
|
||||||
|
let inner = *table
|
||||||
|
.entry(
|
||||||
|
hasher.hash_one(&*value),
|
||||||
|
|k| **k == *value,
|
||||||
|
|k| hasher.hash_one(&**k),
|
||||||
|
)
|
||||||
|
.or_insert_with(|| alloc(value))
|
||||||
|
.get();
|
||||||
|
Interned { inner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<T> {
|
||||||
|
fn intern_sized(&self, value: Cow<'_, T>) -> Interned<T> {
|
||||||
|
self.intern(|value| Box::leak(Box::new(value.into_owned())), value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<[T]> {
|
||||||
|
fn intern_slice(&self, value: Cow<'_, [T]>) -> Interned<[T]> {
|
||||||
|
self.intern(|value| value.into_owned().leak(), value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interner<BitSlice> {
|
||||||
|
fn intern_bit_slice(&self, value: Cow<'_, BitSlice>) -> Interned<BitSlice> {
|
||||||
|
self.intern(|value| value.into_owned().leak(), value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Interned<T: ?Sized + 'static + Send + Sync> {
|
pub struct Interned<T: ?Sized + 'static + Send + Sync> {
|
||||||
inner: &'static T,
|
inner: &'static T,
|
||||||
}
|
}
|
||||||
|
|
@ -682,62 +695,27 @@ impl<T: ?Sized + 'static + Send + Sync + AsRef<U>, U: ?Sized> AsRef<U> for Inter
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InternedSliceIter<T: Clone + 'static + Send + Sync> {
|
pub struct InternedSliceIter<T: Clone + 'static + Send + Sync> {
|
||||||
iter: std::iter::Cloned<std::slice::Iter<'static, T>>,
|
slice: Interned<[T]>,
|
||||||
}
|
index: std::ops::Range<usize>,
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync> Default for InternedSliceIter<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
iter: [].iter().cloned(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync> Iterator for InternedSliceIter<T> {
|
impl<T: Clone + 'static + Send + Sync> Iterator for InternedSliceIter<T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.iter.next()
|
self.index.next().map(|index| self.slice[index].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
self.iter.size_hint()
|
self.index.size_hint()
|
||||||
}
|
|
||||||
|
|
||||||
fn count(self) -> usize {
|
|
||||||
self.iter.count()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn last(mut self) -> Option<Self::Item> {
|
|
||||||
self.next_back()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
|
||||||
self.iter.nth(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold<B, F>(self, init: B, f: F) -> B
|
|
||||||
where
|
|
||||||
F: FnMut(B, Self::Item) -> B,
|
|
||||||
{
|
|
||||||
self.iter.fold(init, f)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync> DoubleEndedIterator for InternedSliceIter<T> {
|
impl<T: Clone + 'static + Send + Sync> DoubleEndedIterator for InternedSliceIter<T> {
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
self.iter.next_back()
|
self.index
|
||||||
}
|
.next_back()
|
||||||
|
.map(|index| self.slice[index].clone())
|
||||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
|
||||||
self.iter.nth_back(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rfold<B, F>(self, init: B, f: F) -> B
|
|
||||||
where
|
|
||||||
F: FnMut(B, Self::Item) -> B,
|
|
||||||
{
|
|
||||||
self.iter.rfold(init, f)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -751,7 +729,8 @@ impl<T: Clone + 'static + Send + Sync> IntoIterator for Interned<[T]> {
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
InternedSliceIter {
|
InternedSliceIter {
|
||||||
iter: Interned::into_inner(self).iter().cloned(),
|
index: 0..self.len(),
|
||||||
|
slice: self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -998,7 +977,7 @@ impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for T {
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
interner::Interner::get().intern_sized(this)
|
Interner::get().intern_sized(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,7 +997,7 @@ impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for [T] {
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
interner::Interner::get().intern_slice(this)
|
Interner::get().intern_slice(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1038,7 +1017,7 @@ impl Intern for BitSlice {
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
interner::Interner::get().intern_bit_slice(this)
|
Interner::get().intern_bit_slice(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1056,17 +1035,10 @@ pub trait MemoizeGeneric: 'static + Send + Sync + Hash + Eq + Copy {
|
||||||
fn inner(self, input: Self::InputRef<'_>) -> Self::Output;
|
fn inner(self, input: Self::InputRef<'_>) -> Self::Output;
|
||||||
fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output {
|
fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output {
|
||||||
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
||||||
thread_local! {
|
|
||||||
static TYPE_ID_MAP_CACHE: TypeIdMap = const { TypeIdMap::new() };
|
|
||||||
}
|
|
||||||
let map: &RwLock<(
|
let map: &RwLock<(
|
||||||
DefaultBuildHasher,
|
DefaultBuildHasher,
|
||||||
HashTable<(Self, Self::InputOwned, Self::Output)>,
|
HashTable<(Self, Self::InputOwned, Self::Output)>,
|
||||||
)> = TYPE_ID_MAP_CACHE.with(|cache| {
|
)> = TYPE_ID_MAP.get_or_insert_default();
|
||||||
cache.get_or_insert_with(|| {
|
|
||||||
TYPE_ID_MAP.get_or_insert_with(|| Box::leak(Default::default()))
|
|
||||||
})
|
|
||||||
});
|
|
||||||
fn hash_eq_key<'a, 'b, T: MemoizeGeneric>(
|
fn hash_eq_key<'a, 'b, T: MemoizeGeneric>(
|
||||||
this: &'a T,
|
this: &'a T,
|
||||||
input: T::InputRef<'b>,
|
input: T::InputRef<'b>,
|
||||||
|
|
@ -1168,35 +1140,3 @@ pub trait Memoize: 'static + Send + Sync + Hash + Eq + Copy {
|
||||||
self.get_cow(Cow::Borrowed(input))
|
self.get_cow(Cow::Borrowed(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// like `once_cell::race::OnceBox` but for `Interned<T>` instead of `Box<T>`
|
|
||||||
pub struct OnceInterned<T: 'static + Send + Sync>(OnceRef<'static, T>);
|
|
||||||
|
|
||||||
impl<T: 'static + Send + Sync + fmt::Debug> fmt::Debug for OnceInterned<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_tuple("OnceInterned").field(&self.get()).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: 'static + Send + Sync> Default for OnceInterned<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: 'static + Send + Sync> OnceInterned<T> {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self(OnceRef::new())
|
|
||||||
}
|
|
||||||
pub fn set(&self, v: Interned<T>) -> Result<(), ()> {
|
|
||||||
self.0.set(v.inner)
|
|
||||||
}
|
|
||||||
pub fn get(&self) -> Option<Interned<T>> {
|
|
||||||
self.0.get().map(|inner| Interned { inner })
|
|
||||||
}
|
|
||||||
pub fn get_or_init<F: FnOnce() -> Interned<T>>(&self, f: F) -> Interned<T> {
|
|
||||||
Interned {
|
|
||||||
inner: self.0.get_or_init(|| f().inner),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
// See Notices.txt for copyright information
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
intern::{Interned, type_map::TypeIdMap},
|
|
||||||
util::DefaultBuildHasher,
|
|
||||||
};
|
|
||||||
use bitvec::slice::BitSlice;
|
|
||||||
use hashbrown::HashTable;
|
|
||||||
use std::{
|
|
||||||
borrow::Cow,
|
|
||||||
hash::{BuildHasher, Hash},
|
|
||||||
sync::RwLock,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InternerShard<T: ?Sized + 'static + Send + Sync> {
|
|
||||||
table: HashTable<&'static T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const LOG2_SHARD_COUNT: u32 = 6;
|
|
||||||
|
|
||||||
fn shard_index_from_hash(hash: u64) -> usize {
|
|
||||||
// number of bits used for hashbrown's Tag
|
|
||||||
const HASH_BROWN_TAG_BITS: u32 = 7;
|
|
||||||
// try to extract bits of the hash that hashbrown isn't using,
|
|
||||||
// while accounting for some hash functions only returning `usize` bits.
|
|
||||||
const SHARD_INDEX_START: u32 = usize::BITS
|
|
||||||
.saturating_sub(HASH_BROWN_TAG_BITS)
|
|
||||||
.saturating_sub(LOG2_SHARD_COUNT);
|
|
||||||
let mut shard_index = hash >> SHARD_INDEX_START;
|
|
||||||
shard_index %= 1 << LOG2_SHARD_COUNT;
|
|
||||||
shard_index as usize
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct Interner<T: ?Sized + 'static + Send + Sync> {
|
|
||||||
shards: [RwLock<InternerShard<T>>; 1 << LOG2_SHARD_COUNT],
|
|
||||||
hasher: DefaultBuildHasher,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
|
|
||||||
pub(crate) fn get() -> &'static Interner<T> {
|
|
||||||
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
|
||||||
thread_local! {
|
|
||||||
static TYPE_ID_MAP_CACHE: TypeIdMap = const { TypeIdMap::new() };
|
|
||||||
}
|
|
||||||
TYPE_ID_MAP_CACHE.with(|cache| {
|
|
||||||
cache.get_or_insert_with(|| {
|
|
||||||
TYPE_ID_MAP.get_or_insert_with(|| Box::leak(Default::default()))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
shards: [const {
|
|
||||||
RwLock::new(InternerShard {
|
|
||||||
table: HashTable::new(),
|
|
||||||
})
|
|
||||||
}; _],
|
|
||||||
hasher: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
|
|
||||||
fn intern<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
|
||||||
&self,
|
|
||||||
alloc: F,
|
|
||||||
value: Cow<'_, T>,
|
|
||||||
) -> Interned<T> {
|
|
||||||
let hash = self.hasher.hash_one(&*value);
|
|
||||||
let shard_index = shard_index_from_hash(hash);
|
|
||||||
let shard = &self.shards[shard_index];
|
|
||||||
let shard_read = shard.read().unwrap();
|
|
||||||
let Some(&inner) = shard_read.table.find(hash, |k| **k == *value) else {
|
|
||||||
drop(shard_read);
|
|
||||||
return self.intern_cold(alloc, value, hash, shard);
|
|
||||||
};
|
|
||||||
Interned { inner }
|
|
||||||
}
|
|
||||||
#[cold]
|
|
||||||
fn intern_cold<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
|
||||||
&self,
|
|
||||||
alloc: F,
|
|
||||||
value: Cow<'_, T>,
|
|
||||||
hash: u64,
|
|
||||||
shard: &RwLock<InternerShard<T>>,
|
|
||||||
) -> Interned<T> {
|
|
||||||
let mut shard = shard.write().unwrap();
|
|
||||||
let inner = *shard
|
|
||||||
.table
|
|
||||||
.entry(hash, |k| **k == *value, |k| self.hasher.hash_one(&**k))
|
|
||||||
.or_insert_with(|| alloc(value))
|
|
||||||
.get();
|
|
||||||
Interned { inner }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<T> {
|
|
||||||
pub(crate) fn intern_sized(&self, value: Cow<'_, T>) -> Interned<T> {
|
|
||||||
self.intern(|value| Box::leak(Box::new(value.into_owned())), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<[T]> {
|
|
||||||
pub(crate) fn intern_slice(&self, value: Cow<'_, [T]>) -> Interned<[T]> {
|
|
||||||
self.intern(|value| value.into_owned().leak(), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Interner<BitSlice> {
|
|
||||||
pub(crate) fn intern_bit_slice(&self, value: Cow<'_, BitSlice>) -> Interned<BitSlice> {
|
|
||||||
self.intern(|value| value.into_owned().leak(), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
sync::RwLock,
|
sync::RwLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct TypeIdHasher(u64);
|
struct TypeIdHasher(u64);
|
||||||
|
|
||||||
// assumes TypeId has at least 64 bits that is a good hash
|
// assumes TypeId has at least 64 bits that is a good hash
|
||||||
impl Hasher for TypeIdHasher {
|
impl Hasher for TypeIdHasher {
|
||||||
|
|
@ -63,7 +63,7 @@ impl Hasher for TypeIdHasher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct TypeIdBuildHasher;
|
struct TypeIdBuildHasher;
|
||||||
|
|
||||||
impl BuildHasher for TypeIdBuildHasher {
|
impl BuildHasher for TypeIdBuildHasher {
|
||||||
type Hasher = TypeIdHasher;
|
type Hasher = TypeIdHasher;
|
||||||
|
|
@ -87,23 +87,20 @@ impl TypeIdMap {
|
||||||
fn insert_slow(
|
fn insert_slow(
|
||||||
&self,
|
&self,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
make: impl FnOnce() -> &'static (dyn Any + Sync + Send),
|
make: fn() -> Box<dyn Any + Sync + Send>,
|
||||||
) -> &'static (dyn Any + Sync + Send) {
|
) -> &'static (dyn Any + Sync + Send) {
|
||||||
let value = make();
|
let value = Box::leak(make());
|
||||||
let mut write_guard = self.0.write().unwrap();
|
let mut write_guard = self.0.write().unwrap();
|
||||||
*write_guard.entry(type_id).or_insert(value)
|
*write_guard.entry(type_id).or_insert(value)
|
||||||
}
|
}
|
||||||
pub(crate) fn get_or_insert_with<T: Sized + Any + Send + Sync>(
|
pub(crate) fn get_or_insert_default<T: Sized + Any + Send + Sync + Default>(&self) -> &T {
|
||||||
&self,
|
|
||||||
make: impl FnOnce() -> &'static T,
|
|
||||||
) -> &'static T {
|
|
||||||
let type_id = TypeId::of::<T>();
|
let type_id = TypeId::of::<T>();
|
||||||
let read_guard = self.0.read().unwrap();
|
let read_guard = self.0.read().unwrap();
|
||||||
let retval = read_guard.get(&type_id).map(|v| *v);
|
let retval = read_guard.get(&type_id).map(|v| *v);
|
||||||
drop(read_guard);
|
drop(read_guard);
|
||||||
let retval = match retval {
|
let retval = match retval {
|
||||||
Some(retval) => retval,
|
Some(retval) => retval,
|
||||||
None => self.insert_slow(type_id, move || make()),
|
None => self.insert_slow(type_id, move || Box::new(T::default())),
|
||||||
};
|
};
|
||||||
retval.downcast_ref().expect("known to have correct TypeId")
|
retval.downcast_ref().expect("known to have correct TypeId")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1093,7 +1093,6 @@ pub fn splat_mask<T: Type>(ty: T, value: Expr<Bool>) -> Expr<AsMask<T>> {
|
||||||
.to_expr(),
|
.to_expr(),
|
||||||
)),
|
)),
|
||||||
CanonicalType::PhantomConst(_) => Expr::from_canonical(Expr::canonical(().to_expr())),
|
CanonicalType::PhantomConst(_) => Expr::from_canonical(Expr::canonical(().to_expr())),
|
||||||
CanonicalType::TraceAsString(ty) => Expr::from_canonical(splat_mask(ty.inner_ty(), value)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
clock::{Clock, ClockDomain},
|
clock::{Clock, ClockDomain},
|
||||||
enum_::{Enum, EnumMatchVariantsIter, EnumType},
|
enum_::{Enum, EnumMatchVariantsIter, EnumType},
|
||||||
expr::{
|
expr::{
|
||||||
Expr, ExprEnum, Flow, ToExpr, ValueType,
|
Expr, Flow, ToExpr, ValueType,
|
||||||
ops::VariantAccess,
|
ops::VariantAccess,
|
||||||
target::{
|
target::{
|
||||||
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField,
|
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField,
|
||||||
|
|
@ -20,7 +20,6 @@ use crate::{
|
||||||
int::{Bool, DynSize, Size},
|
int::{Bool, DynSize, Size},
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
memory::{Mem, MemBuilder, MemBuilderTarget, PortName},
|
memory::{Mem, MemBuilder, MemBuilderTarget, PortName},
|
||||||
module::transform::visit::{Visit, Visitor},
|
|
||||||
platform::PlatformIOBuilder,
|
platform::PlatformIOBuilder,
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
||||||
|
|
@ -727,57 +726,7 @@ impl fmt::Display for NameId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum NameIdOrGlobal {
|
pub struct ScopedNameId(pub NameId, pub NameId);
|
||||||
Global,
|
|
||||||
NameId(NameId),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NameIdOrGlobal {
|
|
||||||
pub fn name_id(self) -> Option<NameId> {
|
|
||||||
match self {
|
|
||||||
Self::Global => None,
|
|
||||||
Self::NameId(v) => Some(v),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[track_caller]
|
|
||||||
pub fn assert_is_name_id(self) {
|
|
||||||
match self {
|
|
||||||
Self::Global => panic!("expected a NameId, got NameIdOrGlobal::Global"),
|
|
||||||
Self::NameId(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[track_caller]
|
|
||||||
pub fn unwrap_name_id(self) -> NameId {
|
|
||||||
match self {
|
|
||||||
Self::Global => panic!("expected a NameId, got NameIdOrGlobal::Global"),
|
|
||||||
Self::NameId(v) => v,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for NameIdOrGlobal {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
fmt::Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for NameIdOrGlobal {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Global => f.write_str("<<Global>>"),
|
|
||||||
Self::NameId(name_id) => fmt::Display::fmt(name_id, f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<NameId> for NameIdOrGlobal {
|
|
||||||
fn from(value: NameId) -> Self {
|
|
||||||
Self::NameId(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
|
||||||
pub struct ScopedNameId(pub NameIdOrGlobal, pub NameId);
|
|
||||||
|
|
||||||
impl fmt::Debug for ScopedNameId {
|
impl fmt::Debug for ScopedNameId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
@ -855,7 +804,7 @@ impl<T: BundleType> Instance<T> {
|
||||||
self.containing_module_name_id().0
|
self.containing_module_name_id().0
|
||||||
}
|
}
|
||||||
pub fn containing_module_name_id(self) -> NameId {
|
pub fn containing_module_name_id(self) -> NameId {
|
||||||
self.scoped_name.0.unwrap_name_id()
|
self.scoped_name.0
|
||||||
}
|
}
|
||||||
pub fn name(self) -> Interned<str> {
|
pub fn name(self) -> Interned<str> {
|
||||||
self.name_id().0
|
self.name_id().0
|
||||||
|
|
@ -872,13 +821,11 @@ impl<T: BundleType> Instance<T> {
|
||||||
pub fn source_location(self) -> SourceLocation {
|
pub fn source_location(self) -> SourceLocation {
|
||||||
self.source_location
|
self.source_location
|
||||||
}
|
}
|
||||||
#[track_caller]
|
|
||||||
pub fn new_unchecked(
|
pub fn new_unchecked(
|
||||||
scoped_name: ScopedNameId,
|
scoped_name: ScopedNameId,
|
||||||
instantiated: Interned<Module<T>>,
|
instantiated: Interned<Module<T>>,
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
scoped_name.0.assert_is_name_id();
|
|
||||||
Self {
|
Self {
|
||||||
scoped_name,
|
scoped_name,
|
||||||
instantiated,
|
instantiated,
|
||||||
|
|
@ -1164,10 +1111,7 @@ fn validate_clock_for_past<S: ModuleBuildingStatus>(
|
||||||
let mut target = clock_for_past;
|
let mut target = clock_for_past;
|
||||||
while let Target::Child(child) = target {
|
while let Target::Child(child) = target {
|
||||||
match *child.path_element() {
|
match *child.path_element() {
|
||||||
TargetPathElement::BundleField(_)
|
TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {}
|
||||||
| TargetPathElement::ArrayElement(_)
|
|
||||||
| TargetPathElement::ToTraceAsString(_)
|
|
||||||
| TargetPathElement::TraceAsStringInner(_) => {}
|
|
||||||
TargetPathElement::DynArrayElement(_) => {
|
TargetPathElement::DynArrayElement(_) => {
|
||||||
panic!(
|
panic!(
|
||||||
"clock_for_past: clock must be a static target (you can't use `Expr<UInt>` array indexes):\n{clock_for_past:?}"
|
"clock_for_past: clock must be a static target (you can't use `Expr<UInt>` array indexes):\n{clock_for_past:?}"
|
||||||
|
|
@ -1591,7 +1535,6 @@ impl TargetState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn new(target: Interned<Target>, declared_in_block: usize) -> Self {
|
fn new(target: Interned<Target>, declared_in_block: usize) -> Self {
|
||||||
let target = Target::unwrap_transparent_types_interned(target);
|
|
||||||
Self {
|
Self {
|
||||||
target,
|
target,
|
||||||
inner: match target.canonical_ty() {
|
inner: match target.canonical_ty() {
|
||||||
|
|
@ -1643,71 +1586,17 @@ impl TargetState {
|
||||||
declared_in_block,
|
declared_in_block,
|
||||||
written_in_blocks: RefCell::default(),
|
written_in_blocks: RefCell::default(),
|
||||||
},
|
},
|
||||||
CanonicalType::TraceAsString(_) => {
|
|
||||||
unreachable!("handled by Target::unwrap_transparent_types_interned")
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VisibleExprsStack {
|
|
||||||
buf: Vec<HashSet<ExprEnum>>,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VisibleExprsStack {
|
|
||||||
fn top(&mut self) -> &mut HashSet<ExprEnum> {
|
|
||||||
&mut self.buf[self.len - 1]
|
|
||||||
}
|
|
||||||
fn slice(&self) -> &[HashSet<ExprEnum>] {
|
|
||||||
&self.buf[..self.len]
|
|
||||||
}
|
|
||||||
fn contains(&self, v: &ExprEnum) -> bool {
|
|
||||||
self.slice().iter().any(|i| i.contains(v))
|
|
||||||
}
|
|
||||||
fn push_empty(&mut self) {
|
|
||||||
#[cold]
|
|
||||||
fn push_empty_cold(stack: &mut VisibleExprsStack) {
|
|
||||||
stack.buf.push(HashSet::default());
|
|
||||||
assert_eq!(stack.buf.len(), stack.len)
|
|
||||||
}
|
|
||||||
self.len += 1;
|
|
||||||
if self.len > self.buf.len() {
|
|
||||||
push_empty_cold(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn pop(&mut self) {
|
|
||||||
let Some(new_len) = self.len.checked_sub(1) else {
|
|
||||||
unreachable!("visible exprs stack underflow");
|
|
||||||
};
|
|
||||||
self.buf[new_len].clear();
|
|
||||||
self.len = new_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for VisibleExprsStack {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
buf: Vec::new(),
|
|
||||||
len: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AssertValidityState {
|
struct AssertValidityState {
|
||||||
module: Module<Bundle>,
|
module: Module<Bundle>,
|
||||||
blocks: Vec<Block>,
|
blocks: Vec<Block>,
|
||||||
visible_exprs: VisibleExprsStack,
|
|
||||||
target_states: HashMap<Interned<TargetBase>, TargetState>,
|
target_states: HashMap<Interned<TargetBase>, TargetState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum GetTargetStatesError {
|
|
||||||
NotFound,
|
|
||||||
IsGlobal,
|
|
||||||
FoundSimIoForGlobal(crate::expr::ops::SimIoForGlobal),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AssertValidityState {
|
impl AssertValidityState {
|
||||||
fn make_block_index(&mut self, block: Block) -> usize {
|
fn make_block_index(&mut self, block: Block) -> usize {
|
||||||
let retval = self.blocks.len();
|
let retval = self.blocks.len();
|
||||||
|
|
@ -1716,79 +1605,48 @@ impl AssertValidityState {
|
||||||
}
|
}
|
||||||
fn get_target_states<'a>(
|
fn get_target_states<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
target: Target,
|
target: &Target,
|
||||||
process_target_state: &dyn Fn(&'a TargetState, bool),
|
process_target_state: &dyn Fn(&'a TargetState, bool),
|
||||||
) -> Result<(), GetTargetStatesError> {
|
) -> Result<(), ()> {
|
||||||
let mut target = target.unwrap_transparent_types();
|
match target {
|
||||||
loop {
|
Target::Base(target_base) => {
|
||||||
break match target {
|
let target_state = self.get_base_state(*target_base)?;
|
||||||
Target::Base(target_base) => {
|
process_target_state(target_state, false);
|
||||||
let target_state = self.get_base_state(target_base)?;
|
Ok(())
|
||||||
process_target_state(target_state, false);
|
}
|
||||||
Ok(())
|
Target::Child(target_child) => self.get_target_states(
|
||||||
}
|
&target_child.parent(),
|
||||||
Target::Child(target_child) => match *target_child.path_element() {
|
&|target_state, exact_target_unknown| {
|
||||||
TargetPathElement::BundleField(_)
|
let TargetStateInner::Decomposed { subtargets } = &target_state.inner else {
|
||||||
| TargetPathElement::ArrayElement(_)
|
unreachable!(
|
||||||
| TargetPathElement::DynArrayElement(_) => self.get_target_states(
|
"TargetState::new makes TargetState tree match the Target type"
|
||||||
*target_child.parent(),
|
);
|
||||||
&|target_state, exact_target_unknown| {
|
};
|
||||||
let TargetStateInner::Decomposed { subtargets } = &target_state.inner
|
match *target_child.path_element() {
|
||||||
else {
|
TargetPathElement::BundleField(_) => process_target_state(
|
||||||
unreachable!(
|
subtargets
|
||||||
"TargetState::new makes TargetState tree match the Target type"
|
.get(&target_child.path_element())
|
||||||
);
|
.expect("bundle fields filled in by TargetState::new"),
|
||||||
};
|
exact_target_unknown,
|
||||||
match *target_child.path_element() {
|
),
|
||||||
TargetPathElement::BundleField(_) => process_target_state(
|
TargetPathElement::ArrayElement(_) => process_target_state(
|
||||||
subtargets
|
subtargets
|
||||||
.get(&target_child.path_element())
|
.get(&target_child.path_element())
|
||||||
.expect("bundle fields filled in by TargetState::new"),
|
.expect("array elements filled in by TargetState::new"),
|
||||||
exact_target_unknown,
|
exact_target_unknown,
|
||||||
),
|
),
|
||||||
TargetPathElement::ArrayElement(_) => process_target_state(
|
TargetPathElement::DynArrayElement(_) => {
|
||||||
subtargets
|
for target_state in subtargets.values() {
|
||||||
.get(&target_child.path_element())
|
process_target_state(target_state, true);
|
||||||
.expect("array elements filled in by TargetState::new"),
|
|
||||||
exact_target_unknown,
|
|
||||||
),
|
|
||||||
TargetPathElement::DynArrayElement(_) => {
|
|
||||||
for target_state in subtargets.values() {
|
|
||||||
process_target_state(target_state, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
|
||||||
| TargetPathElement::ToTraceAsString(_) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
),
|
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
|
||||||
| TargetPathElement::ToTraceAsString(_) => {
|
|
||||||
target = *target_child.parent();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_base_state(
|
fn get_base_state(&self, target_base: Interned<TargetBase>) -> Result<&TargetState, ()> {
|
||||||
&self,
|
self.target_states.get(&target_base).ok_or(())
|
||||||
target_base: Interned<TargetBase>,
|
|
||||||
) -> Result<&TargetState, GetTargetStatesError> {
|
|
||||||
match *target_base {
|
|
||||||
TargetBase::ModuleIO(_)
|
|
||||||
| TargetBase::MemPort(_)
|
|
||||||
| TargetBase::Reg(_)
|
|
||||||
| TargetBase::RegSync(_)
|
|
||||||
| TargetBase::RegAsync(_)
|
|
||||||
| TargetBase::Wire(_)
|
|
||||||
| TargetBase::Instance(_) => self
|
|
||||||
.target_states
|
|
||||||
.get(&target_base)
|
|
||||||
.ok_or(GetTargetStatesError::NotFound),
|
|
||||||
TargetBase::FormalInput(_) => Err(GetTargetStatesError::IsGlobal),
|
|
||||||
TargetBase::SimIoForGlobal(v) => Err(GetTargetStatesError::FoundSimIoForGlobal(v)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn insert_new_base(&mut self, target_base: Interned<TargetBase>, declared_in_block: usize) {
|
fn insert_new_base(&mut self, target_base: Interned<TargetBase>, declared_in_block: usize) {
|
||||||
|
|
@ -1835,7 +1693,6 @@ impl AssertValidityState {
|
||||||
&TargetPathElement::BundleField(_) => {
|
&TargetPathElement::BundleField(_) => {
|
||||||
let field = sub_target_state
|
let field = sub_target_state
|
||||||
.target
|
.target
|
||||||
.without_trailing_transparent_path_elements()
|
|
||||||
.child()
|
.child()
|
||||||
.expect("known to be a child")
|
.expect("known to be a child")
|
||||||
.bundle_field()
|
.bundle_field()
|
||||||
|
|
@ -1859,8 +1716,6 @@ impl AssertValidityState {
|
||||||
TargetPathElement::DynArrayElement { .. } => {
|
TargetPathElement::DynArrayElement { .. } => {
|
||||||
Self::set_connect_target_written(sub_target_state, is_lhs, block, true);
|
Self::set_connect_target_written(sub_target_state, is_lhs, block, true);
|
||||||
}
|
}
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
|
||||||
| TargetPathElement::ToTraceAsString(_) => unreachable!("never added"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1878,33 +1733,19 @@ impl AssertValidityState {
|
||||||
debug_assert!(!is_lhs, "the ModuleBuilder asserts lhs.target().is_some()");
|
debug_assert!(!is_lhs, "the ModuleBuilder asserts lhs.target().is_some()");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let result = self.get_target_states(*target, &|target_state, exact_target_unknown| {
|
let result = self.get_target_states(&target, &|target_state, exact_target_unknown| {
|
||||||
Self::set_connect_target_written(target_state, is_lhs, block, exact_target_unknown);
|
Self::set_connect_target_written(target_state, is_lhs, block, exact_target_unknown);
|
||||||
});
|
});
|
||||||
match result {
|
if result.is_err() {
|
||||||
Ok(()) => {}
|
if is_lhs {
|
||||||
Err(GetTargetStatesError::NotFound) => {
|
panic!("at {source_location}: tried to connect to not-yet-defined item: {target}");
|
||||||
if is_lhs {
|
} else {
|
||||||
panic!(
|
|
||||||
"at {source_location}: tried to connect to not-yet-defined item: {target}"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
panic!(
|
|
||||||
"at {source_location}: tried to connect from not-yet-defined item: {target}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(GetTargetStatesError::IsGlobal) => {
|
|
||||||
// no error
|
|
||||||
}
|
|
||||||
Err(GetTargetStatesError::FoundSimIoForGlobal(v)) => {
|
|
||||||
panic!(
|
panic!(
|
||||||
"at {source_location}: fayalite::expr::ops::SimIoForGlobal is not allowed in Modules: {v:?}"
|
"at {source_location}: tried to connect from not-yet-defined item: {target}"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[track_caller]
|
|
||||||
fn process_conditional_sub_blocks(
|
fn process_conditional_sub_blocks(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_block: usize,
|
parent_block: usize,
|
||||||
|
|
@ -1918,40 +1759,17 @@ impl AssertValidityState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn assert_expr_validity<T: Type>(&mut self, expr: Expr<T>, source_location: SourceLocation) {
|
|
||||||
let mut visitor = AssertExprValidity { state: self };
|
|
||||||
match visitor.visit_expr(&expr) {
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => match e {
|
|
||||||
InvalidExpr::ExprIsNotVisible(expr) => {
|
|
||||||
if let Some(target) = expr.target() {
|
|
||||||
panic!(
|
|
||||||
"at {source_location}: expression isn't visible here, it's defined:\n\
|
|
||||||
at {}: {expr:?}",
|
|
||||||
target.base().source_location(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
panic!("at {source_location}: expression isn't visible here: {expr:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[track_caller]
|
|
||||||
fn assert_subtree_validity(&mut self, block: usize) {
|
fn assert_subtree_validity(&mut self, block: usize) {
|
||||||
self.visible_exprs.push_empty();
|
|
||||||
let module = self.module;
|
let module = self.module;
|
||||||
if block == 0 {
|
if block == 0 {
|
||||||
for module_io in &*module.module_io {
|
for module_io in &*module.module_io {
|
||||||
self.insert_new_base(TargetBase::intern_sized(module_io.module_io.into()), block);
|
self.insert_new_base(TargetBase::intern_sized(module_io.module_io.into()), block);
|
||||||
self.visible_exprs.top().insert(module_io.module_io.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let Block { memories, stmts } = self.blocks[block];
|
let Block { memories, stmts } = self.blocks[block];
|
||||||
for m in memories {
|
for m in memories {
|
||||||
for port in m.ports() {
|
for port in m.ports() {
|
||||||
self.insert_new_base(TargetBase::intern_sized(port.into()), block);
|
self.insert_new_base(TargetBase::intern_sized(port.into()), block);
|
||||||
self.visible_exprs.top().insert(port.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
|
|
@ -1965,104 +1783,44 @@ impl AssertValidityState {
|
||||||
} = connect;
|
} = connect;
|
||||||
self.set_connect_side_written(lhs, source_location, true, block);
|
self.set_connect_side_written(lhs, source_location, true, block);
|
||||||
self.set_connect_side_written(rhs, source_location, false, block);
|
self.set_connect_side_written(rhs, source_location, false, block);
|
||||||
self.assert_expr_validity(lhs, source_location);
|
|
||||||
self.assert_expr_validity(rhs, source_location);
|
|
||||||
}
|
|
||||||
Stmt::Formal(formal) => {
|
|
||||||
let StmtFormal {
|
|
||||||
kind: _,
|
|
||||||
clk,
|
|
||||||
pred,
|
|
||||||
en,
|
|
||||||
text: _,
|
|
||||||
source_location,
|
|
||||||
} = formal;
|
|
||||||
self.assert_expr_validity(clk, source_location);
|
|
||||||
self.assert_expr_validity(pred, source_location);
|
|
||||||
self.assert_expr_validity(en, source_location);
|
|
||||||
}
|
}
|
||||||
|
Stmt::Formal(_) => {}
|
||||||
Stmt::If(if_stmt) => {
|
Stmt::If(if_stmt) => {
|
||||||
let StmtIf {
|
let sub_blocks = if_stmt.blocks.map(|block| self.make_block_index(block));
|
||||||
cond,
|
|
||||||
source_location,
|
|
||||||
blocks: sub_blocks,
|
|
||||||
} = if_stmt;
|
|
||||||
self.assert_expr_validity(cond, source_location);
|
|
||||||
let sub_blocks = sub_blocks.map(|block| self.make_block_index(block));
|
|
||||||
self.process_conditional_sub_blocks(block, sub_blocks)
|
self.process_conditional_sub_blocks(block, sub_blocks)
|
||||||
}
|
}
|
||||||
Stmt::Match(match_stmt) => {
|
Stmt::Match(match_stmt) => {
|
||||||
match_stmt.assert_validity();
|
match_stmt.assert_validity();
|
||||||
let StmtMatch {
|
|
||||||
expr,
|
|
||||||
source_location,
|
|
||||||
blocks: sub_blocks,
|
|
||||||
} = match_stmt;
|
|
||||||
self.assert_expr_validity(expr, source_location);
|
|
||||||
let sub_blocks = Vec::from_iter(
|
let sub_blocks = Vec::from_iter(
|
||||||
sub_blocks
|
match_stmt
|
||||||
|
.blocks
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|block| self.make_block_index(block)),
|
.map(|block| self.make_block_index(block)),
|
||||||
);
|
);
|
||||||
self.visible_exprs.push_empty();
|
self.process_conditional_sub_blocks(block, sub_blocks.iter().copied())
|
||||||
let visible_exprs_top = self.visible_exprs.top();
|
|
||||||
for variant_index in 0..expr.ty().variants().len() {
|
|
||||||
visible_exprs_top
|
|
||||||
.insert(<VariantAccess>::new_by_index(expr, variant_index).into());
|
|
||||||
}
|
|
||||||
self.process_conditional_sub_blocks(block, sub_blocks.iter().copied());
|
|
||||||
self.visible_exprs.pop();
|
|
||||||
}
|
}
|
||||||
Stmt::Declaration(StmtDeclaration::Wire(StmtWire {
|
Stmt::Declaration(StmtDeclaration::Wire(StmtWire {
|
||||||
annotations: _,
|
annotations: _,
|
||||||
wire,
|
wire,
|
||||||
})) => {
|
})) => self.insert_new_base(TargetBase::intern_sized(wire.into()), block),
|
||||||
self.insert_new_base(TargetBase::intern_sized(wire.into()), block);
|
|
||||||
self.visible_exprs.top().insert(wire.into());
|
|
||||||
}
|
|
||||||
Stmt::Declaration(StmtDeclaration::Reg(StmtReg {
|
Stmt::Declaration(StmtDeclaration::Reg(StmtReg {
|
||||||
annotations: _,
|
annotations: _,
|
||||||
reg,
|
reg,
|
||||||
})) => {
|
})) => self.insert_new_base(TargetBase::intern_sized(reg.into()), block),
|
||||||
self.assert_expr_validity(reg.clock_domain(), reg.source_location());
|
|
||||||
if let Some(init) = reg.init() {
|
|
||||||
self.assert_expr_validity(init, reg.source_location());
|
|
||||||
}
|
|
||||||
self.insert_new_base(TargetBase::intern_sized(reg.into()), block);
|
|
||||||
self.visible_exprs.top().insert(reg.into());
|
|
||||||
}
|
|
||||||
Stmt::Declaration(StmtDeclaration::RegSync(StmtReg {
|
Stmt::Declaration(StmtDeclaration::RegSync(StmtReg {
|
||||||
annotations: _,
|
annotations: _,
|
||||||
reg,
|
reg,
|
||||||
})) => {
|
})) => self.insert_new_base(TargetBase::intern_sized(reg.into()), block),
|
||||||
self.assert_expr_validity(reg.clock_domain(), reg.source_location());
|
|
||||||
if let Some(init) = reg.init() {
|
|
||||||
self.assert_expr_validity(init, reg.source_location());
|
|
||||||
}
|
|
||||||
self.insert_new_base(TargetBase::intern_sized(reg.into()), block);
|
|
||||||
self.visible_exprs.top().insert(reg.into());
|
|
||||||
}
|
|
||||||
Stmt::Declaration(StmtDeclaration::RegAsync(StmtReg {
|
Stmt::Declaration(StmtDeclaration::RegAsync(StmtReg {
|
||||||
annotations: _,
|
annotations: _,
|
||||||
reg,
|
reg,
|
||||||
})) => {
|
})) => self.insert_new_base(TargetBase::intern_sized(reg.into()), block),
|
||||||
self.assert_expr_validity(reg.clock_domain(), reg.source_location());
|
|
||||||
if let Some(init) = reg.init() {
|
|
||||||
self.assert_expr_validity(init, reg.source_location());
|
|
||||||
}
|
|
||||||
self.insert_new_base(TargetBase::intern_sized(reg.into()), block);
|
|
||||||
self.visible_exprs.top().insert(reg.into());
|
|
||||||
}
|
|
||||||
Stmt::Declaration(StmtDeclaration::Instance(StmtInstance {
|
Stmt::Declaration(StmtDeclaration::Instance(StmtInstance {
|
||||||
annotations: _,
|
annotations: _,
|
||||||
instance,
|
instance,
|
||||||
})) => {
|
})) => self.insert_new_base(TargetBase::intern_sized(instance.into()), block),
|
||||||
self.insert_new_base(TargetBase::intern_sized(instance.into()), block);
|
|
||||||
self.visible_exprs.top().insert(instance.into());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.visible_exprs.pop();
|
|
||||||
}
|
}
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn assert_validity(&mut self) {
|
fn assert_validity(&mut self) {
|
||||||
|
|
@ -2091,142 +1849,6 @@ impl AssertValidityState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AssertExprValidity<'a> {
|
|
||||||
state: &'a mut AssertValidityState,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum InvalidExpr {
|
|
||||||
ExprIsNotVisible(Expr<CanonicalType>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl transform::visit::Visitor for AssertExprValidity<'_> {
|
|
||||||
type Error = InvalidExpr;
|
|
||||||
fn visit_expr_enum(&mut self, v: &ExprEnum) -> Result<(), Self::Error> {
|
|
||||||
match v {
|
|
||||||
ExprEnum::UIntLiteral(_)
|
|
||||||
| ExprEnum::SIntLiteral(_)
|
|
||||||
| ExprEnum::BoolLiteral(_)
|
|
||||||
| ExprEnum::PhantomConst(_)
|
|
||||||
| ExprEnum::BundleLiteral(_)
|
|
||||||
| ExprEnum::ArrayLiteral(_)
|
|
||||||
| ExprEnum::EnumLiteral(_)
|
|
||||||
| ExprEnum::Uninit(_)
|
|
||||||
| ExprEnum::NotU(_)
|
|
||||||
| ExprEnum::NotS(_)
|
|
||||||
| ExprEnum::NotB(_)
|
|
||||||
| ExprEnum::Neg(_)
|
|
||||||
| ExprEnum::BitAndU(_)
|
|
||||||
| ExprEnum::BitAndS(_)
|
|
||||||
| ExprEnum::BitAndB(_)
|
|
||||||
| ExprEnum::BitOrU(_)
|
|
||||||
| ExprEnum::BitOrS(_)
|
|
||||||
| ExprEnum::BitOrB(_)
|
|
||||||
| ExprEnum::BitXorU(_)
|
|
||||||
| ExprEnum::BitXorS(_)
|
|
||||||
| ExprEnum::BitXorB(_)
|
|
||||||
| ExprEnum::AddU(_)
|
|
||||||
| ExprEnum::AddS(_)
|
|
||||||
| ExprEnum::SubU(_)
|
|
||||||
| ExprEnum::SubS(_)
|
|
||||||
| ExprEnum::MulU(_)
|
|
||||||
| ExprEnum::MulS(_)
|
|
||||||
| ExprEnum::DivU(_)
|
|
||||||
| ExprEnum::DivS(_)
|
|
||||||
| ExprEnum::RemU(_)
|
|
||||||
| ExprEnum::RemS(_)
|
|
||||||
| ExprEnum::DynShlU(_)
|
|
||||||
| ExprEnum::DynShlS(_)
|
|
||||||
| ExprEnum::DynShrU(_)
|
|
||||||
| ExprEnum::DynShrS(_)
|
|
||||||
| ExprEnum::FixedShlU(_)
|
|
||||||
| ExprEnum::FixedShlS(_)
|
|
||||||
| ExprEnum::FixedShrU(_)
|
|
||||||
| ExprEnum::FixedShrS(_)
|
|
||||||
| ExprEnum::CmpLtB(_)
|
|
||||||
| ExprEnum::CmpLeB(_)
|
|
||||||
| ExprEnum::CmpGtB(_)
|
|
||||||
| ExprEnum::CmpGeB(_)
|
|
||||||
| ExprEnum::CmpEqB(_)
|
|
||||||
| ExprEnum::CmpNeB(_)
|
|
||||||
| ExprEnum::CmpLtU(_)
|
|
||||||
| ExprEnum::CmpLeU(_)
|
|
||||||
| ExprEnum::CmpGtU(_)
|
|
||||||
| ExprEnum::CmpGeU(_)
|
|
||||||
| ExprEnum::CmpEqU(_)
|
|
||||||
| ExprEnum::CmpNeU(_)
|
|
||||||
| ExprEnum::CmpLtS(_)
|
|
||||||
| ExprEnum::CmpLeS(_)
|
|
||||||
| ExprEnum::CmpGtS(_)
|
|
||||||
| ExprEnum::CmpGeS(_)
|
|
||||||
| ExprEnum::CmpEqS(_)
|
|
||||||
| ExprEnum::CmpNeS(_)
|
|
||||||
| ExprEnum::CastUIntToUInt(_)
|
|
||||||
| ExprEnum::CastUIntToSInt(_)
|
|
||||||
| ExprEnum::CastSIntToUInt(_)
|
|
||||||
| ExprEnum::CastSIntToSInt(_)
|
|
||||||
| ExprEnum::CastBoolToUInt(_)
|
|
||||||
| ExprEnum::CastBoolToSInt(_)
|
|
||||||
| ExprEnum::CastUIntToBool(_)
|
|
||||||
| ExprEnum::CastSIntToBool(_)
|
|
||||||
| ExprEnum::CastBoolToSyncReset(_)
|
|
||||||
| ExprEnum::CastUIntToSyncReset(_)
|
|
||||||
| ExprEnum::CastSIntToSyncReset(_)
|
|
||||||
| ExprEnum::CastBoolToAsyncReset(_)
|
|
||||||
| ExprEnum::CastUIntToAsyncReset(_)
|
|
||||||
| ExprEnum::CastSIntToAsyncReset(_)
|
|
||||||
| ExprEnum::CastSyncResetToBool(_)
|
|
||||||
| ExprEnum::CastSyncResetToUInt(_)
|
|
||||||
| ExprEnum::CastSyncResetToSInt(_)
|
|
||||||
| ExprEnum::CastSyncResetToReset(_)
|
|
||||||
| ExprEnum::CastAsyncResetToBool(_)
|
|
||||||
| ExprEnum::CastAsyncResetToUInt(_)
|
|
||||||
| ExprEnum::CastAsyncResetToSInt(_)
|
|
||||||
| ExprEnum::CastAsyncResetToReset(_)
|
|
||||||
| ExprEnum::CastResetToBool(_)
|
|
||||||
| ExprEnum::CastResetToUInt(_)
|
|
||||||
| ExprEnum::CastResetToSInt(_)
|
|
||||||
| ExprEnum::CastBoolToClock(_)
|
|
||||||
| ExprEnum::CastUIntToClock(_)
|
|
||||||
| ExprEnum::CastSIntToClock(_)
|
|
||||||
| ExprEnum::CastClockToBool(_)
|
|
||||||
| ExprEnum::CastClockToUInt(_)
|
|
||||||
| ExprEnum::CastClockToSInt(_)
|
|
||||||
| ExprEnum::FieldAccess(_)
|
|
||||||
| ExprEnum::ArrayIndex(_)
|
|
||||||
| ExprEnum::DynArrayIndex(_)
|
|
||||||
| ExprEnum::ReduceBitAndU(_)
|
|
||||||
| ExprEnum::ReduceBitAndS(_)
|
|
||||||
| ExprEnum::ReduceBitOrU(_)
|
|
||||||
| ExprEnum::ReduceBitOrS(_)
|
|
||||||
| ExprEnum::ReduceBitXorU(_)
|
|
||||||
| ExprEnum::ReduceBitXorS(_)
|
|
||||||
| ExprEnum::SliceUInt(_)
|
|
||||||
| ExprEnum::SliceSInt(_)
|
|
||||||
| ExprEnum::CastToBits(_)
|
|
||||||
| ExprEnum::CastBitsTo(_)
|
|
||||||
| ExprEnum::ToTraceAsString(_)
|
|
||||||
| ExprEnum::TraceAsStringAsInner(_)
|
|
||||||
| ExprEnum::FormalInput(_) => v.default_visit(self),
|
|
||||||
ExprEnum::VariantAccess(_)
|
|
||||||
| ExprEnum::ModuleIO(_)
|
|
||||||
| ExprEnum::Instance(_)
|
|
||||||
| ExprEnum::Wire(_)
|
|
||||||
| ExprEnum::Reg(_)
|
|
||||||
| ExprEnum::RegSync(_)
|
|
||||||
| ExprEnum::RegAsync(_)
|
|
||||||
| ExprEnum::MemPort(_) => {
|
|
||||||
if self.state.visible_exprs.contains(v) {
|
|
||||||
// no need to visit inner expressions, we already checked them before adding them to visible_exprs
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(InvalidExpr::ExprIsNotVisible(v.to_expr()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ExprEnum::SimIoForGlobal(_) => Err(InvalidExpr::ExprIsNotVisible(v.to_expr())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BundleType> Module<T> {
|
impl<T: BundleType> Module<T> {
|
||||||
/// you generally should use the [`#[hdl_module]`][`crate::hdl_module`] proc-macro and [`ModuleBuilder`] instead
|
/// you generally should use the [`#[hdl_module]`][`crate::hdl_module`] proc-macro and [`ModuleBuilder`] instead
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
|
@ -2352,7 +1974,6 @@ impl<T: BundleType> Module<T> {
|
||||||
AssertValidityState {
|
AssertValidityState {
|
||||||
module: self.canonical(),
|
module: self.canonical(),
|
||||||
blocks: vec![],
|
blocks: vec![],
|
||||||
visible_exprs: VisibleExprsStack::default(),
|
|
||||||
target_states: HashMap::with_capacity_and_hasher(64, Default::default()),
|
target_states: HashMap::with_capacity_and_hasher(64, Default::default()),
|
||||||
}
|
}
|
||||||
.assert_validity();
|
.assert_validity();
|
||||||
|
|
@ -2458,7 +2079,7 @@ impl<T: Type, R: ResetType> RegBuilder<Expr<ClockDomain<R>>, Option<Expr<T>>, T>
|
||||||
ty,
|
ty,
|
||||||
} = self;
|
} = self;
|
||||||
ModuleBuilder::with(|module_builder| {
|
ModuleBuilder::with(|module_builder| {
|
||||||
let scoped_name = ScopedNameId(module_builder.name.into(), NameId(name, Id::new()));
|
let scoped_name = ScopedNameId(module_builder.name, NameId(name, Id::new()));
|
||||||
let reg = Reg::new_unchecked(scoped_name, source_location, ty, clock_domain, init);
|
let reg = Reg::new_unchecked(scoped_name, source_location, ty, clock_domain, init);
|
||||||
let retval = reg.to_expr();
|
let retval = reg.to_expr();
|
||||||
// convert before borrow_mut since ModuleBuilder could be reentered by T::canonical()
|
// convert before borrow_mut since ModuleBuilder could be reentered by T::canonical()
|
||||||
|
|
@ -2854,9 +2475,6 @@ pub fn annotate<T: Type>(target: Expr<T>, annotations: impl IntoAnnotations) {
|
||||||
instance,
|
instance,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
TargetBase::FormalInput(_) | TargetBase::SimIoForGlobal(_) => {
|
|
||||||
unreachable!("not a valid annotation target")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
unwrap!(m.impl_.borrow_mut().body.builder_normal_body_opt())
|
unwrap!(m.impl_.borrow_mut().body.builder_normal_body_opt())
|
||||||
|
|
@ -2871,7 +2489,7 @@ pub fn annotate<T: Type>(target: Expr<T>, annotations: impl IntoAnnotations) {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn wire_with_loc<T: Type>(name: &str, source_location: SourceLocation, ty: T) -> Expr<T> {
|
pub fn wire_with_loc<T: Type>(name: &str, source_location: SourceLocation, ty: T) -> Expr<T> {
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
let scoped_name = ScopedNameId(m.name.into(), NameId(name.intern(), Id::new()));
|
let scoped_name = ScopedNameId(m.name, NameId(name.intern(), Id::new()));
|
||||||
let wire = Wire::<T>::new_unchecked(scoped_name, source_location, ty);
|
let wire = Wire::<T>::new_unchecked(scoped_name, source_location, ty);
|
||||||
let retval = wire.to_expr();
|
let retval = wire.to_expr();
|
||||||
let canonical_wire = wire.canonical();
|
let canonical_wire = wire.canonical();
|
||||||
|
|
@ -2903,7 +2521,7 @@ fn incomplete_declaration(
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
) -> Rc<RefCell<IncompleteDeclaration>> {
|
) -> Rc<RefCell<IncompleteDeclaration>> {
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
let scoped_name = ScopedNameId(m.name.into(), NameId(name.intern(), Id::new()));
|
let scoped_name = ScopedNameId(m.name, NameId(name.intern(), Id::new()));
|
||||||
let retval = Rc::new(RefCell::new(IncompleteDeclaration::Incomplete {
|
let retval = Rc::new(RefCell::new(IncompleteDeclaration::Incomplete {
|
||||||
name: scoped_name,
|
name: scoped_name,
|
||||||
source_location,
|
source_location,
|
||||||
|
|
@ -3079,7 +2697,7 @@ pub fn instance_with_loc<T: BundleType>(
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
) -> Expr<T> {
|
) -> Expr<T> {
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
let scoped_name = ScopedNameId(m.name.into(), NameId(name.intern(), Id::new()));
|
let scoped_name = ScopedNameId(m.name, NameId(name.intern(), Id::new()));
|
||||||
let instance = Instance::<T> {
|
let instance = Instance::<T> {
|
||||||
scoped_name,
|
scoped_name,
|
||||||
instantiated,
|
instantiated,
|
||||||
|
|
@ -3118,7 +2736,7 @@ fn memory_impl<Element: Type, Len: Size>(
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
) -> MemBuilder<Element, Len> {
|
) -> MemBuilder<Element, Len> {
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
let scoped_name = ScopedNameId(m.name.into(), NameId(name.intern(), Id::new()));
|
let scoped_name = ScopedNameId(m.name, NameId(name.intern(), Id::new()));
|
||||||
let (retval, target_mem) = MemBuilder::new(scoped_name, source_location, mem_element_type);
|
let (retval, target_mem) = MemBuilder::new(scoped_name, source_location, mem_element_type);
|
||||||
let mut impl_ = m.impl_.borrow_mut();
|
let mut impl_ = m.impl_.borrow_mut();
|
||||||
let body = impl_.body.builder_normal_body();
|
let body = impl_.body.builder_normal_body();
|
||||||
|
|
@ -3273,7 +2891,7 @@ impl<T: Type> ModuleIO<T> {
|
||||||
NameId(self.bundle_field.name, self.id)
|
NameId(self.bundle_field.name, self.id)
|
||||||
}
|
}
|
||||||
pub fn scoped_name(&self) -> ScopedNameId {
|
pub fn scoped_name(&self) -> ScopedNameId {
|
||||||
ScopedNameId(self.containing_module_name.into(), self.name_id())
|
ScopedNameId(self.containing_module_name, self.name_id())
|
||||||
}
|
}
|
||||||
pub fn source_location(&self) -> SourceLocation {
|
pub fn source_location(&self) -> SourceLocation {
|
||||||
self.source_location
|
self.source_location
|
||||||
|
|
@ -3346,102 +2964,10 @@ impl fmt::Debug for InstantiatedModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
|
||||||
pub enum InstantiatedModuleOrGlobal {
|
|
||||||
Global,
|
|
||||||
InstantiatedModule(InstantiatedModule),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstantiatedModuleOrGlobal {
|
|
||||||
pub fn leaf_module_source_location(self) -> SourceLocation {
|
|
||||||
match self {
|
|
||||||
Self::Global => SourceLocation::builtin(),
|
|
||||||
Self::InstantiatedModule(v) => v.leaf_module().source_location(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InstantiatedModule> for InstantiatedModuleOrGlobal {
|
|
||||||
fn from(value: InstantiatedModule) -> Self {
|
|
||||||
Self::InstantiatedModule(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for InstantiatedModuleOrGlobal {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Global => f.write_str("Global"),
|
|
||||||
Self::InstantiatedModule(v) => v.fmt(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
pub struct TargetInInstantiatedModuleOrGlobal {
|
pub struct TargetInInstantiatedModule {
|
||||||
instantiated_module_or_global: InstantiatedModuleOrGlobal,
|
pub instantiated_module: InstantiatedModule,
|
||||||
target: Target,
|
pub target: Target,
|
||||||
}
|
|
||||||
|
|
||||||
impl TargetInInstantiatedModuleOrGlobal {
|
|
||||||
#[track_caller]
|
|
||||||
pub fn new(instantiated_module_or_global: InstantiatedModuleOrGlobal, target: Target) -> Self {
|
|
||||||
match (
|
|
||||||
instantiated_module_or_global,
|
|
||||||
target.base().target_name().0.0,
|
|
||||||
) {
|
|
||||||
(InstantiatedModuleOrGlobal::Global, NameIdOrGlobal::Global)
|
|
||||||
| (InstantiatedModuleOrGlobal::InstantiatedModule(_), NameIdOrGlobal::NameId(_)) => {
|
|
||||||
Self {
|
|
||||||
instantiated_module_or_global,
|
|
||||||
target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(InstantiatedModuleOrGlobal::Global, NameIdOrGlobal::NameId(_))
|
|
||||||
| (InstantiatedModuleOrGlobal::InstantiatedModule(_), NameIdOrGlobal::Global) => {
|
|
||||||
panic!(
|
|
||||||
"instantiated_module_or_global doesn't match target.base().target_name().0.0:\n\
|
|
||||||
instantiated_module_or_global: {instantiated_module_or_global:?}\n\
|
|
||||||
target: {target:?}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[track_caller]
|
|
||||||
pub fn from_target(
|
|
||||||
instantiated_module: impl Into<InstantiatedModuleOrGlobal>,
|
|
||||||
target: Target,
|
|
||||||
) -> Self {
|
|
||||||
let instantiated_module = instantiated_module.into();
|
|
||||||
Self {
|
|
||||||
instantiated_module_or_global: match target.base().target_name().0.0 {
|
|
||||||
NameIdOrGlobal::Global => InstantiatedModuleOrGlobal::Global,
|
|
||||||
NameIdOrGlobal::NameId(name_id) => {
|
|
||||||
let InstantiatedModuleOrGlobal::InstantiatedModule(instantiated_module) =
|
|
||||||
instantiated_module
|
|
||||||
else {
|
|
||||||
panic!(
|
|
||||||
"target is in a module, but no InstantiatedModule was provided: {target:#?}"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
name_id,
|
|
||||||
instantiated_module.leaf_module().name_id(),
|
|
||||||
"target isn't contained in module:\n\
|
|
||||||
target: {target:#?}\n\
|
|
||||||
instantiated_module: {instantiated_module:?}",
|
|
||||||
);
|
|
||||||
InstantiatedModuleOrGlobal::InstantiatedModule(instantiated_module)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn instantiated_module_or_global(self) -> InstantiatedModuleOrGlobal {
|
|
||||||
self.instantiated_module_or_global
|
|
||||||
}
|
|
||||||
pub fn target(self) -> Target {
|
|
||||||
self.target
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ use crate::{
|
||||||
ops::{self, ArrayLiteral},
|
ops::{self, ArrayLiteral},
|
||||||
target::{
|
target::{
|
||||||
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
TargetPathDynArrayElement, TargetPathElement,
|
||||||
TargetPathTraceAsStringInner,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
formal::FormalKind,
|
formal::FormalKind,
|
||||||
|
|
@ -27,7 +26,6 @@ use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
reset::{ResetType, ResetTypeDispatch},
|
reset::{ResetType, ResetTypeDispatch},
|
||||||
sim::ExternModuleSimulation,
|
sim::ExternModuleSimulation,
|
||||||
ty::TraceAsString,
|
|
||||||
util::{HashMap, HashSet},
|
util::{HashMap, HashSet},
|
||||||
};
|
};
|
||||||
use hashbrown::hash_map::Entry;
|
use hashbrown::hash_map::Entry;
|
||||||
|
|
@ -105,10 +103,6 @@ enum ResetsLayout {
|
||||||
element: Interned<ResetsLayout>,
|
element: Interned<ResetsLayout>,
|
||||||
reset_count: usize,
|
reset_count: usize,
|
||||||
},
|
},
|
||||||
Transparent {
|
|
||||||
inner: Interned<ResetsLayout>,
|
|
||||||
reset_count: usize,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResetsLayout {
|
impl ResetsLayout {
|
||||||
|
|
@ -118,8 +112,7 @@ impl ResetsLayout {
|
||||||
ResetsLayout::Reset | ResetsLayout::SyncReset | ResetsLayout::AsyncReset => 1,
|
ResetsLayout::Reset | ResetsLayout::SyncReset | ResetsLayout::AsyncReset => 1,
|
||||||
ResetsLayout::Bundle { reset_count, .. }
|
ResetsLayout::Bundle { reset_count, .. }
|
||||||
| ResetsLayout::Enum { reset_count, .. }
|
| ResetsLayout::Enum { reset_count, .. }
|
||||||
| ResetsLayout::Array { reset_count, .. }
|
| ResetsLayout::Array { reset_count, .. } => reset_count,
|
||||||
| ResetsLayout::Transparent { reset_count, .. } => reset_count,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn new(ty: CanonicalType) -> Self {
|
fn new(ty: CanonicalType) -> Self {
|
||||||
|
|
@ -173,13 +166,6 @@ impl ResetsLayout {
|
||||||
CanonicalType::Clock(_) => ResetsLayout::NoResets,
|
CanonicalType::Clock(_) => ResetsLayout::NoResets,
|
||||||
CanonicalType::PhantomConst(_) => ResetsLayout::NoResets,
|
CanonicalType::PhantomConst(_) => ResetsLayout::NoResets,
|
||||||
CanonicalType::DynSimOnly(_) => ResetsLayout::NoResets,
|
CanonicalType::DynSimOnly(_) => ResetsLayout::NoResets,
|
||||||
CanonicalType::TraceAsString(ty) => {
|
|
||||||
let inner = ResetsLayout::new(ty.inner_ty()).intern_sized();
|
|
||||||
ResetsLayout::Transparent {
|
|
||||||
inner,
|
|
||||||
reset_count: inner.reset_count(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -329,12 +315,6 @@ impl ResetGraph {
|
||||||
} => {
|
} => {
|
||||||
self.append_new_nodes_for_layout(*element, node_indexes, source_location);
|
self.append_new_nodes_for_layout(*element, node_indexes, source_location);
|
||||||
}
|
}
|
||||||
ResetsLayout::Transparent {
|
|
||||||
inner,
|
|
||||||
reset_count: _,
|
|
||||||
} => {
|
|
||||||
self.append_new_nodes_for_layout(*inner, node_indexes, source_location);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -377,21 +357,6 @@ impl Resets {
|
||||||
node_indexes: self.node_indexes,
|
node_indexes: self.node_indexes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn trace_as_string_inner(self) -> Self {
|
|
||||||
let trace_as_string = TraceAsString::from_canonical(self.ty);
|
|
||||||
let ResetsLayout::Transparent {
|
|
||||||
inner,
|
|
||||||
reset_count: _,
|
|
||||||
} = self.layout
|
|
||||||
else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
Self {
|
|
||||||
ty: trace_as_string.inner_ty(),
|
|
||||||
layout: *inner,
|
|
||||||
node_indexes: self.node_indexes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn bundle_fields(self) -> impl Iterator<Item = Self> {
|
fn bundle_fields(self) -> impl Iterator<Item = Self> {
|
||||||
let bundle = Bundle::from_canonical(self.ty);
|
let bundle = Bundle::from_canonical(self.ty);
|
||||||
let ResetsLayout::Bundle {
|
let ResetsLayout::Bundle {
|
||||||
|
|
@ -515,17 +480,6 @@ impl Resets {
|
||||||
CanonicalType::SyncReset(SyncReset)
|
CanonicalType::SyncReset(SyncReset)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
CanonicalType::TraceAsString(ty) => Ok(CanonicalType::TraceAsString(
|
|
||||||
ty.with_new_inner_ty(
|
|
||||||
self.array_elements()
|
|
||||||
.substituted_type(
|
|
||||||
reset_graph,
|
|
||||||
fallback_to_sync_reset,
|
|
||||||
fallback_error_source_location,
|
|
||||||
)?
|
|
||||||
.intern_sized(),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1059,8 +1013,7 @@ fn cast_bit_op<P: Pass, T: Type, A: Type>(
|
||||||
| CanonicalType::Bundle(_)
|
| CanonicalType::Bundle(_)
|
||||||
| CanonicalType::Reset(_)
|
| CanonicalType::Reset(_)
|
||||||
| CanonicalType::PhantomConst(_)
|
| CanonicalType::PhantomConst(_)
|
||||||
| CanonicalType::DynSimOnly(_)
|
| CanonicalType::DynSimOnly(_) => unreachable!(),
|
||||||
| CanonicalType::TraceAsString(_) => unreachable!(),
|
|
||||||
$(CanonicalType::$Variant(ty) => Expr::expr_enum($arg.cast_to(ty)),)*
|
$(CanonicalType::$Variant(ty) => Expr::expr_enum($arg.cast_to(ty)),)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1071,8 +1024,7 @@ fn cast_bit_op<P: Pass, T: Type, A: Type>(
|
||||||
CanonicalType::Array(_)
|
CanonicalType::Array(_)
|
||||||
| CanonicalType::Enum(_)
|
| CanonicalType::Enum(_)
|
||||||
| CanonicalType::Bundle(_)
|
| CanonicalType::Bundle(_)
|
||||||
| CanonicalType::Reset(_)
|
| CanonicalType::Reset(_) => unreachable!(),
|
||||||
| CanonicalType::TraceAsString(_) => unreachable!(),
|
|
||||||
CanonicalType::PhantomConst(_) |
|
CanonicalType::PhantomConst(_) |
|
||||||
CanonicalType::DynSimOnly(_) => Expr::expr_enum(arg),
|
CanonicalType::DynSimOnly(_) => Expr::expr_enum(arg),
|
||||||
$(CanonicalType::$Variant(_) => {
|
$(CanonicalType::$Variant(_) => {
|
||||||
|
|
@ -1204,10 +1156,6 @@ impl<P: Pass> RunPass<P> for ExprEnum {
|
||||||
ExprEnum::SliceSInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::SliceSInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::CastToBits(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::CastToBits(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::CastBitsTo(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::CastBitsTo(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::TraceAsStringAsInner(expr) => {
|
|
||||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
|
||||||
}
|
|
||||||
ExprEnum::ToTraceAsString(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
|
||||||
ExprEnum::ModuleIO(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::ModuleIO(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::Instance(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::Instance(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::Wire(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::Wire(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
|
|
@ -1215,10 +1163,6 @@ impl<P: Pass> RunPass<P> for ExprEnum {
|
||||||
ExprEnum::RegSync(expr) => reg_expr_run_pass(expr, pass_args),
|
ExprEnum::RegSync(expr) => reg_expr_run_pass(expr, pass_args),
|
||||||
ExprEnum::RegAsync(expr) => reg_expr_run_pass(expr, pass_args),
|
ExprEnum::RegAsync(expr) => reg_expr_run_pass(expr, pass_args),
|
||||||
ExprEnum::MemPort(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::MemPort(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::FormalInput(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
|
||||||
ExprEnum::SimIoForGlobal(_) => {
|
|
||||||
unreachable!("Module is known to not contain SimIoForGlobal from validation")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1592,67 +1536,6 @@ impl RunPassExpr for ops::CastBitsTo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunPassExpr for ops::TraceAsStringAsInner {
|
|
||||||
type Args<'a> = [Expr<CanonicalType>; 1];
|
|
||||||
|
|
||||||
fn args<'a>(&'a self) -> Self::Args<'a> {
|
|
||||||
[Expr::canonical(self.arg())]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn source_location(&self) -> Option<SourceLocation> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn union_parts(
|
|
||||||
&self,
|
|
||||||
resets: Resets,
|
|
||||||
args_resets: Vec<Resets>,
|
|
||||||
mut pass_args: PassArgs<'_, BuildResetGraph>,
|
|
||||||
) -> Result<(), DeduceResetsError> {
|
|
||||||
pass_args.union(resets, args_resets[0].trace_as_string_inner(), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new(
|
|
||||||
&self,
|
|
||||||
_ty: CanonicalType,
|
|
||||||
new_args: Vec<Expr<CanonicalType>>,
|
|
||||||
) -> Result<Self, DeduceResetsError> {
|
|
||||||
Ok(Self::new(Expr::from_canonical(new_args[0])))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RunPassExpr for ops::ToTraceAsString {
|
|
||||||
type Args<'a> = [Expr<CanonicalType>; 1];
|
|
||||||
|
|
||||||
fn args<'a>(&'a self) -> Self::Args<'a> {
|
|
||||||
[Expr::canonical(self.inner())]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn source_location(&self) -> Option<SourceLocation> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn union_parts(
|
|
||||||
&self,
|
|
||||||
resets: Resets,
|
|
||||||
args_resets: Vec<Resets>,
|
|
||||||
mut pass_args: PassArgs<'_, BuildResetGraph>,
|
|
||||||
) -> Result<(), DeduceResetsError> {
|
|
||||||
pass_args.union(resets.trace_as_string_inner(), args_resets[0], None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new(
|
|
||||||
&self,
|
|
||||||
_ty: CanonicalType,
|
|
||||||
new_args: Vec<Expr<CanonicalType>>,
|
|
||||||
) -> Result<Self, DeduceResetsError> {
|
|
||||||
Ok(Self::new(
|
|
||||||
new_args[0],
|
|
||||||
self.ty().with_new_inner_ty(new_args[0].ty().intern_sized()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RunPassExpr for ModuleIO<CanonicalType> {
|
impl RunPassExpr for ModuleIO<CanonicalType> {
|
||||||
type Args<'a> = [Expr<CanonicalType>; 0];
|
type Args<'a> = [Expr<CanonicalType>; 0];
|
||||||
|
|
||||||
|
|
@ -1808,8 +1691,7 @@ impl RunPassDispatch for AnyReg {
|
||||||
| CanonicalType::Reset(_)
|
| CanonicalType::Reset(_)
|
||||||
| CanonicalType::Clock(_)
|
| CanonicalType::Clock(_)
|
||||||
| CanonicalType::PhantomConst(_)
|
| CanonicalType::PhantomConst(_)
|
||||||
| CanonicalType::DynSimOnly(_)
|
| CanonicalType::DynSimOnly(_) => unreachable!(),
|
||||||
| CanonicalType::TraceAsString(_) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1936,7 +1818,6 @@ impl_run_pass_copy!([] SVAttributeAnnotation);
|
||||||
impl_run_pass_copy!([] UInt);
|
impl_run_pass_copy!([] UInt);
|
||||||
impl_run_pass_copy!([] usize);
|
impl_run_pass_copy!([] usize);
|
||||||
impl_run_pass_copy!([] FormalKind);
|
impl_run_pass_copy!([] FormalKind);
|
||||||
impl_run_pass_copy!([] crate::formal::FormalInput);
|
|
||||||
impl_run_pass_copy!([] PhantomConst);
|
impl_run_pass_copy!([] PhantomConst);
|
||||||
|
|
||||||
macro_rules! impl_run_pass_for_struct {
|
macro_rules! impl_run_pass_for_struct {
|
||||||
|
|
@ -2253,12 +2134,6 @@ impl<P: Pass> RunPass<P> for TargetBase {
|
||||||
&TargetBase::RegAsync(v) => v.into(),
|
&TargetBase::RegAsync(v) => v.into(),
|
||||||
TargetBase::Wire(v) => return Ok(v.run_pass(pass_args)?.map(TargetBase::Wire)),
|
TargetBase::Wire(v) => return Ok(v.run_pass(pass_args)?.map(TargetBase::Wire)),
|
||||||
TargetBase::Instance(v) => return Ok(v.run_pass(pass_args)?.map(TargetBase::Instance)),
|
TargetBase::Instance(v) => return Ok(v.run_pass(pass_args)?.map(TargetBase::Instance)),
|
||||||
TargetBase::FormalInput(v) => {
|
|
||||||
return Ok(v.run_pass(pass_args)?.map(TargetBase::FormalInput));
|
|
||||||
}
|
|
||||||
TargetBase::SimIoForGlobal(_) => {
|
|
||||||
unreachable!("Module is known to not contain SimIoForGlobal from validation")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok(reg.run_pass(pass_args)?.map(|reg| match reg {
|
Ok(reg.run_pass(pass_args)?.map(|reg| match reg {
|
||||||
AnyReg::Reg(reg) => TargetBase::Reg(reg),
|
AnyReg::Reg(reg) => TargetBase::Reg(reg),
|
||||||
|
|
@ -2298,6 +2173,30 @@ impl<P: Pass> RunPass<P> for StmtDeclaration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_run_pass_for_struct! {
|
||||||
|
impl[] RunPass for TargetPathBundleField {
|
||||||
|
name: _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_run_pass_for_struct! {
|
||||||
|
impl[] RunPass for TargetPathArrayElement {
|
||||||
|
index: _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_run_pass_for_struct! {
|
||||||
|
impl[] RunPass for TargetPathDynArrayElement {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_run_pass_for_enum! {
|
||||||
|
impl[] RunPass for TargetPathElement {
|
||||||
|
BundleField(v),
|
||||||
|
ArrayElement(v),
|
||||||
|
DynArrayElement(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_run_pass_for_enum! {
|
impl_run_pass_for_enum! {
|
||||||
impl[] RunPass for Target {
|
impl[] RunPass for Target {
|
||||||
Base(v),
|
Base(v),
|
||||||
|
|
@ -2305,28 +2204,11 @@ impl_run_pass_for_enum! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pass> RunPass<P> for TargetChild {
|
impl_run_pass_for_struct! {
|
||||||
fn run_pass(
|
#[constructor = TargetChild::new(parent, path_element)]
|
||||||
&self,
|
impl[] RunPass for TargetChild {
|
||||||
mut pass_args: PassArgs<'_, P>,
|
parent(): _,
|
||||||
) -> Result<PassOutput<Self, P>, DeduceResetsError> {
|
path_element(): _,
|
||||||
Ok(self.parent().run_pass(pass_args.as_mut())?.map(|parent| {
|
|
||||||
let path_element = match *self.path_element() {
|
|
||||||
TargetPathElement::BundleField(TargetPathBundleField { name: _ })
|
|
||||||
| TargetPathElement::ArrayElement(TargetPathArrayElement { index: _ })
|
|
||||||
| TargetPathElement::DynArrayElement(TargetPathDynArrayElement {})
|
|
||||||
| TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => {
|
|
||||||
self.path_element()
|
|
||||||
}
|
|
||||||
TargetPathElement::ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
|
||||||
TargetPathElement::from(TargetPathToTraceAsString {
|
|
||||||
ty: ty.with_new_inner_ty(parent.canonical_ty().intern_sized()),
|
|
||||||
})
|
|
||||||
.intern_sized()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TargetChild::new(parent, path_element)
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
transform::visit::{Fold, Folder},
|
transform::visit::{Fold, Folder},
|
||||||
},
|
},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, TraceAsString, Type},
|
ty::{CanonicalType, Type},
|
||||||
util::HashMap,
|
util::HashMap,
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
|
|
@ -64,7 +64,6 @@ fn contains_any_enum_types(ty: CanonicalType) -> bool {
|
||||||
.fields()
|
.fields()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|field| contains_any_enum_types(field.ty)),
|
.any(|field| contains_any_enum_types(field.ty)),
|
||||||
CanonicalType::TraceAsString(ty) => contains_any_enum_types(ty.inner_ty()),
|
|
||||||
CanonicalType::UInt(_)
|
CanonicalType::UInt(_)
|
||||||
| CanonicalType::SInt(_)
|
| CanonicalType::SInt(_)
|
||||||
| CanonicalType::Bool(_)
|
| CanonicalType::Bool(_)
|
||||||
|
|
@ -96,12 +95,11 @@ enum EnumTypeState {
|
||||||
|
|
||||||
struct ModuleState {
|
struct ModuleState {
|
||||||
module_name: NameId,
|
module_name: NameId,
|
||||||
expr_cache: HashMap<ExprEnum, ExprEnum>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleState {
|
impl ModuleState {
|
||||||
fn gen_name(&mut self, name: &str) -> ScopedNameId {
|
fn gen_name(&mut self, name: &str) -> ScopedNameId {
|
||||||
ScopedNameId(self.module_name.into(), NameId(name.intern(), Id::new()))
|
ScopedNameId(self.module_name, NameId(name.intern(), Id::new()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,24 +313,6 @@ impl State {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_stmt_connect_trace_as_string(
|
|
||||||
&mut self,
|
|
||||||
unfolded_lhs_ty: TraceAsString,
|
|
||||||
unfolded_rhs_ty: TraceAsString,
|
|
||||||
folded_lhs: Expr<TraceAsString>,
|
|
||||||
folded_rhs: Expr<TraceAsString>,
|
|
||||||
source_location: SourceLocation,
|
|
||||||
output_stmts: &mut Vec<Stmt>,
|
|
||||||
) -> Result<(), SimplifyEnumsError> {
|
|
||||||
self.handle_stmt_connect(
|
|
||||||
unfolded_lhs_ty.inner_ty(),
|
|
||||||
unfolded_rhs_ty.inner_ty(),
|
|
||||||
ops::TraceAsStringAsInner::new(folded_lhs).to_expr(),
|
|
||||||
ops::TraceAsStringAsInner::new(folded_rhs).to_expr(),
|
|
||||||
source_location,
|
|
||||||
output_stmts,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn handle_stmt_connect_bundle(
|
fn handle_stmt_connect_bundle(
|
||||||
&mut self,
|
&mut self,
|
||||||
unfolded_lhs_ty: Bundle,
|
unfolded_lhs_ty: Bundle,
|
||||||
|
|
@ -529,15 +509,6 @@ impl State {
|
||||||
source_location,
|
source_location,
|
||||||
output_stmts,
|
output_stmts,
|
||||||
),
|
),
|
||||||
CanonicalType::TraceAsString(unfolded_lhs_ty) => self
|
|
||||||
.handle_stmt_connect_trace_as_string(
|
|
||||||
unfolded_lhs_ty,
|
|
||||||
TraceAsString::from_canonical(unfolded_rhs_ty),
|
|
||||||
Expr::from_canonical(folded_lhs),
|
|
||||||
Expr::from_canonical(folded_rhs),
|
|
||||||
source_location,
|
|
||||||
output_stmts,
|
|
||||||
),
|
|
||||||
CanonicalType::UInt(_)
|
CanonicalType::UInt(_)
|
||||||
| CanonicalType::SInt(_)
|
| CanonicalType::SInt(_)
|
||||||
| CanonicalType::Bool(_)
|
| CanonicalType::Bool(_)
|
||||||
|
|
@ -557,8 +528,6 @@ fn connect_port(
|
||||||
rhs: Expr<CanonicalType>,
|
rhs: Expr<CanonicalType>,
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
) {
|
) {
|
||||||
let lhs = Expr::unwrap_transparent_types(lhs);
|
|
||||||
let rhs = Expr::unwrap_transparent_types(rhs);
|
|
||||||
if lhs.ty() == rhs.ty() {
|
if lhs.ty() == rhs.ty() {
|
||||||
stmts.push(
|
stmts.push(
|
||||||
StmtConnect {
|
StmtConnect {
|
||||||
|
|
@ -604,9 +573,6 @@ fn connect_port(
|
||||||
connect_port(stmts, lhs[index], rhs[index], source_location);
|
connect_port(stmts, lhs[index], rhs[index], source_location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(CanonicalType::TraceAsString(_), CanonicalType::TraceAsString(_)) => {
|
|
||||||
unreachable!("handled by unwrap_transparent_types")
|
|
||||||
}
|
|
||||||
(CanonicalType::Bundle(_), _)
|
(CanonicalType::Bundle(_), _)
|
||||||
| (CanonicalType::Enum(_), _)
|
| (CanonicalType::Enum(_), _)
|
||||||
| (CanonicalType::Array(_), _)
|
| (CanonicalType::Array(_), _)
|
||||||
|
|
@ -618,8 +584,7 @@ fn connect_port(
|
||||||
| (CanonicalType::SyncReset(_), _)
|
| (CanonicalType::SyncReset(_), _)
|
||||||
| (CanonicalType::Reset(_), _)
|
| (CanonicalType::Reset(_), _)
|
||||||
| (CanonicalType::PhantomConst(_), _)
|
| (CanonicalType::PhantomConst(_), _)
|
||||||
| (CanonicalType::DynSimOnly(_), _)
|
| (CanonicalType::DynSimOnly(_), _) => unreachable!(
|
||||||
| (CanonicalType::TraceAsString(_), _) => unreachable!(
|
|
||||||
"trying to connect memory ports:\n{:?}\n{:?}",
|
"trying to connect memory ports:\n{:?}\n{:?}",
|
||||||
lhs.ty(),
|
lhs.ty(),
|
||||||
rhs.ty(),
|
rhs.ty(),
|
||||||
|
|
@ -676,7 +641,6 @@ impl Folder for State {
|
||||||
fn fold_module<T: BundleType>(&mut self, v: Module<T>) -> Result<Module<T>, Self::Error> {
|
fn fold_module<T: BundleType>(&mut self, v: Module<T>) -> Result<Module<T>, Self::Error> {
|
||||||
self.module_state_stack.push(ModuleState {
|
self.module_state_stack.push(ModuleState {
|
||||||
module_name: v.name_id(),
|
module_name: v.name_id(),
|
||||||
expr_cache: HashMap::default(),
|
|
||||||
});
|
});
|
||||||
let retval = Fold::default_fold(v, self);
|
let retval = Fold::default_fold(v, self);
|
||||||
self.module_state_stack.pop();
|
self.module_state_stack.pop();
|
||||||
|
|
@ -684,39 +648,30 @@ impl Folder for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_expr_enum(&mut self, op: ExprEnum) -> Result<ExprEnum, Self::Error> {
|
fn fold_expr_enum(&mut self, op: ExprEnum) -> Result<ExprEnum, Self::Error> {
|
||||||
if let Some(folded_op) = self
|
match op {
|
||||||
.module_state_stack
|
|
||||||
.last()
|
|
||||||
.expect("known to be in module")
|
|
||||||
.expr_cache
|
|
||||||
.get(&op)
|
|
||||||
{
|
|
||||||
return Ok(*folded_op);
|
|
||||||
}
|
|
||||||
let folded_op = match op {
|
|
||||||
ExprEnum::EnumLiteral(op) => {
|
ExprEnum::EnumLiteral(op) => {
|
||||||
let folded_variant_value = op.variant_value().map(|v| v.fold(self)).transpose()?;
|
let folded_variant_value = op.variant_value().map(|v| v.fold(self)).transpose()?;
|
||||||
*Expr::expr_enum(self.handle_enum_literal(
|
Ok(*Expr::expr_enum(self.handle_enum_literal(
|
||||||
op.ty(),
|
op.ty(),
|
||||||
op.variant_index(),
|
op.variant_index(),
|
||||||
folded_variant_value,
|
folded_variant_value,
|
||||||
)?)
|
)?))
|
||||||
}
|
}
|
||||||
ExprEnum::VariantAccess(op) => {
|
ExprEnum::VariantAccess(op) => {
|
||||||
let folded_base_expr = Expr::canonical(op.base()).fold(self)?;
|
let folded_base_expr = Expr::canonical(op.base()).fold(self)?;
|
||||||
*Expr::expr_enum(self.handle_variant_access(
|
Ok(*Expr::expr_enum(self.handle_variant_access(
|
||||||
op.base().ty(),
|
op.base().ty(),
|
||||||
folded_base_expr,
|
folded_base_expr,
|
||||||
op.variant_index(),
|
op.variant_index(),
|
||||||
)?)
|
)?))
|
||||||
}
|
}
|
||||||
ExprEnum::MemPort(mem_port) => {
|
ExprEnum::MemPort(mem_port) => Ok(
|
||||||
if let Some(&wire) = self.replacement_mem_ports.get(&mem_port) {
|
if let Some(&wire) = self.replacement_mem_ports.get(&mem_port) {
|
||||||
ExprEnum::Wire(wire)
|
ExprEnum::Wire(wire)
|
||||||
} else {
|
} else {
|
||||||
ExprEnum::MemPort(mem_port.fold(self)?)
|
ExprEnum::MemPort(mem_port.fold(self)?)
|
||||||
}
|
},
|
||||||
}
|
),
|
||||||
ExprEnum::UIntLiteral(_)
|
ExprEnum::UIntLiteral(_)
|
||||||
| ExprEnum::SIntLiteral(_)
|
| ExprEnum::SIntLiteral(_)
|
||||||
| ExprEnum::BoolLiteral(_)
|
| ExprEnum::BoolLiteral(_)
|
||||||
|
|
@ -817,23 +772,13 @@ impl Folder for State {
|
||||||
| ExprEnum::SliceSInt(_)
|
| ExprEnum::SliceSInt(_)
|
||||||
| ExprEnum::CastToBits(_)
|
| ExprEnum::CastToBits(_)
|
||||||
| ExprEnum::CastBitsTo(_)
|
| ExprEnum::CastBitsTo(_)
|
||||||
| ExprEnum::TraceAsStringAsInner(_)
|
|
||||||
| ExprEnum::ToTraceAsString(_)
|
|
||||||
| ExprEnum::ModuleIO(_)
|
| ExprEnum::ModuleIO(_)
|
||||||
| ExprEnum::Instance(_)
|
| ExprEnum::Instance(_)
|
||||||
| ExprEnum::Wire(_)
|
| ExprEnum::Wire(_)
|
||||||
| ExprEnum::Reg(_)
|
| ExprEnum::Reg(_)
|
||||||
| ExprEnum::RegSync(_)
|
| ExprEnum::RegSync(_)
|
||||||
| ExprEnum::RegAsync(_)
|
| ExprEnum::RegAsync(_) => op.default_fold(self),
|
||||||
| ExprEnum::FormalInput(_)
|
}
|
||||||
| ExprEnum::SimIoForGlobal(_) => op.default_fold(self)?,
|
|
||||||
};
|
|
||||||
self.module_state_stack
|
|
||||||
.last_mut()
|
|
||||||
.expect("known to be in module")
|
|
||||||
.expr_cache
|
|
||||||
.insert(op, folded_op);
|
|
||||||
Ok(folded_op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_block(&mut self, block: Block) -> Result<Block, Self::Error> {
|
fn fold_block(&mut self, block: Block) -> Result<Block, Self::Error> {
|
||||||
|
|
@ -991,8 +936,7 @@ impl Folder for State {
|
||||||
| CanonicalType::SyncReset(_)
|
| CanonicalType::SyncReset(_)
|
||||||
| CanonicalType::Reset(_)
|
| CanonicalType::Reset(_)
|
||||||
| CanonicalType::PhantomConst(_)
|
| CanonicalType::PhantomConst(_)
|
||||||
| CanonicalType::DynSimOnly(_)
|
| CanonicalType::DynSimOnly(_) => canonical_type.default_fold(self),
|
||||||
| CanonicalType::TraceAsString(_) => canonical_type.default_fold(self),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ impl MemSplit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn new(element_type: CanonicalType) -> Self {
|
fn new(element_type: CanonicalType) -> Self {
|
||||||
match element_type.unwrap_transparent_types() {
|
match element_type {
|
||||||
CanonicalType::Bundle(bundle_ty) => MemSplit::Bundle {
|
CanonicalType::Bundle(bundle_ty) => MemSplit::Bundle {
|
||||||
fields: bundle_ty
|
fields: bundle_ty
|
||||||
.fields()
|
.fields()
|
||||||
|
|
@ -195,7 +195,6 @@ impl MemSplit {
|
||||||
| CanonicalType::SyncReset(_)
|
| CanonicalType::SyncReset(_)
|
||||||
| CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"),
|
| CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"),
|
||||||
CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"),
|
CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"),
|
||||||
CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -307,9 +306,7 @@ impl SplitMemState<'_, '_> {
|
||||||
let outer_mem_name_path_len = self.mem_name_path.len();
|
let outer_mem_name_path_len = self.mem_name_path.len();
|
||||||
match self.split {
|
match self.split {
|
||||||
MemSplit::Bundle { fields } => {
|
MemSplit::Bundle { fields } => {
|
||||||
let CanonicalType::Bundle(bundle_type) =
|
let CanonicalType::Bundle(bundle_type) = self.element_type else {
|
||||||
self.element_type.unwrap_transparent_types()
|
|
||||||
else {
|
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
for ((field, field_offset), split) in bundle_type
|
for ((field, field_offset), split) in bundle_type
|
||||||
|
|
@ -324,10 +321,7 @@ impl SplitMemState<'_, '_> {
|
||||||
let field_ty_bit_width = field.ty.bit_width();
|
let field_ty_bit_width = field.ty.bit_width();
|
||||||
self.split_state_stack.push_map(
|
self.split_state_stack.push_map(
|
||||||
|e: Expr<CanonicalType>| {
|
|e: Expr<CanonicalType>| {
|
||||||
Expr::field(
|
Expr::field(Expr::<Bundle>::from_canonical(e), &field.name)
|
||||||
Expr::<Bundle>::from_canonical(Expr::unwrap_transparent_types(e)),
|
|
||||||
&field.name,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
|initial_value_element| {
|
|initial_value_element| {
|
||||||
let Some(field_offset) = field_offset.only_bit_width() else {
|
let Some(field_offset) = field_offset.only_bit_width() else {
|
||||||
|
|
@ -383,8 +377,8 @@ impl SplitMemState<'_, '_> {
|
||||||
};
|
};
|
||||||
self.output_stmts.push(
|
self.output_stmts.push(
|
||||||
StmtConnect {
|
StmtConnect {
|
||||||
lhs: Expr::unwrap_transparent_types(Expr::field(port_expr, name)),
|
lhs: Expr::field(port_expr, name),
|
||||||
rhs: Expr::unwrap_transparent_types(Expr::field(wire_expr, name)),
|
rhs: Expr::field(wire_expr, name),
|
||||||
source_location: port.source_location(),
|
source_location: port.source_location(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -395,8 +389,7 @@ impl SplitMemState<'_, '_> {
|
||||||
self.output_mems.push(new_mem);
|
self.output_mems.push(new_mem);
|
||||||
}
|
}
|
||||||
MemSplit::Array { elements } => {
|
MemSplit::Array { elements } => {
|
||||||
let CanonicalType::Array(array_type) = self.element_type.unwrap_transparent_types()
|
let CanonicalType::Array(array_type) = self.element_type else {
|
||||||
else {
|
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
let element_type = array_type.element();
|
let element_type = array_type.element();
|
||||||
|
|
@ -405,7 +398,7 @@ impl SplitMemState<'_, '_> {
|
||||||
self.mem_name_path.truncate(outer_mem_name_path_len);
|
self.mem_name_path.truncate(outer_mem_name_path_len);
|
||||||
write!(self.mem_name_path, "_{index}").unwrap();
|
write!(self.mem_name_path, "_{index}").unwrap();
|
||||||
self.split_state_stack.push_map(
|
self.split_state_stack.push_map(
|
||||||
|e| Expr::<Array>::from_canonical(Expr::unwrap_transparent_types(e))[index],
|
|e| Expr::<Array>::from_canonical(e)[index],
|
||||||
|initial_value_element| {
|
|initial_value_element| {
|
||||||
&initial_value_element[index * element_bit_width..][..element_bit_width]
|
&initial_value_element[index * element_bit_width..][..element_bit_width]
|
||||||
},
|
},
|
||||||
|
|
@ -471,7 +464,7 @@ impl ModuleState {
|
||||||
assert_eq!(memory_element_array_range_len % input_array_type.len(), 0);
|
assert_eq!(memory_element_array_range_len % input_array_type.len(), 0);
|
||||||
let chunk_size = memory_element_array_range_len / input_array_type.len();
|
let chunk_size = memory_element_array_range_len / input_array_type.len();
|
||||||
for index in 0..input_array_type.len() {
|
for index in 0..input_array_type.len() {
|
||||||
let map = |e| Expr::<Array>::from_canonical(Expr::unwrap_transparent_types(e))[index];
|
let map = |e| Expr::<Array>::from_canonical(e)[index];
|
||||||
let wire_rdata = wire_rdata.map(map);
|
let wire_rdata = wire_rdata.map(map);
|
||||||
let wire_wdata = wire_wdata.map(map);
|
let wire_wdata = wire_wdata.map(map);
|
||||||
let wire_wmask = wire_wmask.map(map);
|
let wire_wmask = wire_wmask.map(map);
|
||||||
|
|
@ -512,8 +505,8 @@ impl ModuleState {
|
||||||
port_read: Expr<CanonicalType>| {
|
port_read: Expr<CanonicalType>| {
|
||||||
output_stmts.push(
|
output_stmts.push(
|
||||||
StmtConnect {
|
StmtConnect {
|
||||||
lhs: Expr::unwrap_transparent_types(wire_read),
|
lhs: wire_read,
|
||||||
rhs: Expr::unwrap_transparent_types(port_read),
|
rhs: port_read,
|
||||||
source_location,
|
source_location,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -524,8 +517,8 @@ impl ModuleState {
|
||||||
port_write: Expr<CanonicalType>| {
|
port_write: Expr<CanonicalType>| {
|
||||||
output_stmts.push(
|
output_stmts.push(
|
||||||
StmtConnect {
|
StmtConnect {
|
||||||
lhs: Expr::unwrap_transparent_types(port_write),
|
lhs: port_write,
|
||||||
rhs: Expr::unwrap_transparent_types(wire_write),
|
rhs: wire_write,
|
||||||
source_location,
|
source_location,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -537,8 +530,7 @@ impl ModuleState {
|
||||||
connect_read(
|
connect_read(
|
||||||
output_stmts,
|
output_stmts,
|
||||||
wire_read,
|
wire_read,
|
||||||
Expr::<UInt>::from_canonical(Expr::unwrap_transparent_types(port_read))
|
Expr::<UInt>::from_canonical(port_read).cast_bits_to(wire_read.ty()),
|
||||||
.cast_bits_to(wire_read.ty()),
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let connect_write_enum =
|
let connect_write_enum =
|
||||||
|
|
@ -552,7 +544,7 @@ impl ModuleState {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
match input_element_type.unwrap_transparent_types() {
|
match input_element_type {
|
||||||
CanonicalType::Bundle(_) => {
|
CanonicalType::Bundle(_) => {
|
||||||
unreachable!("bundle types are always split")
|
unreachable!("bundle types are always split")
|
||||||
}
|
}
|
||||||
|
|
@ -633,9 +625,6 @@ impl ModuleState {
|
||||||
| CanonicalType::SyncReset(_)
|
| CanonicalType::SyncReset(_)
|
||||||
| CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"),
|
| CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"),
|
||||||
CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"),
|
CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"),
|
||||||
CanonicalType::TraceAsString(_) => {
|
|
||||||
unreachable!("handled by unwrap_transparent_types")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,16 @@ use crate::{
|
||||||
Expr, ExprEnum, ValueType, ops,
|
Expr, ExprEnum, ValueType, ops,
|
||||||
target::{
|
target::{
|
||||||
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
TargetPathDynArrayElement, TargetPathElement,
|
||||||
TargetPathTraceAsStringInner,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
formal::{FormalInput, FormalInputKind, FormalKind},
|
formal::FormalKind,
|
||||||
int::{Bool, SIntType, SIntValue, Size, UIntType, UIntValue},
|
int::{Bool, SIntType, SIntValue, Size, UIntType, UIntValue},
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
memory::{Mem, MemPort, PortKind, PortName, PortType, ReadUnderWrite},
|
memory::{Mem, MemPort, PortKind, PortName, PortType, ReadUnderWrite},
|
||||||
module::{
|
module::{
|
||||||
AnnotatedModuleIO, Block, BlockId, ExternModuleBody, ExternModuleParameter,
|
AnnotatedModuleIO, Block, BlockId, ExternModuleBody, ExternModuleParameter,
|
||||||
ExternModuleParameterValue, Instance, Module, ModuleBody, ModuleIO, NameId, NameIdOrGlobal,
|
ExternModuleParameterValue, Instance, Module, ModuleBody, ModuleIO, NameId,
|
||||||
NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf,
|
NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf,
|
||||||
StmtInstance, StmtMatch, StmtReg, StmtWire,
|
StmtInstance, StmtMatch, StmtReg, StmtWire,
|
||||||
},
|
},
|
||||||
|
|
@ -33,7 +32,7 @@ use crate::{
|
||||||
reset::{AsyncReset, Reset, ResetType, SyncReset},
|
reset::{AsyncReset, Reset, ResetType, SyncReset},
|
||||||
sim::{ExternModuleSimulation, value::DynSimOnly},
|
sim::{ExternModuleSimulation, value::DynSimOnly},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, TraceAsString, Type},
|
ty::{CanonicalType, Type},
|
||||||
vendor::xilinx::{
|
vendor::xilinx::{
|
||||||
XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation,
|
XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation,
|
||||||
},
|
},
|
||||||
|
|
@ -482,30 +481,4 @@ impl<T: ?Sized + Visit<State>, State: ?Sized + Visitor> Visit<State> for &'_ mut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<State: ?Sized + Visitor> Visit<State> for NameIdOrGlobal {
|
|
||||||
fn visit(&self, state: &mut State) -> Result<(), <State>::Error> {
|
|
||||||
state.visit_name_id_or_global(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_visit(&self, state: &mut State) -> Result<(), <State>::Error> {
|
|
||||||
match self {
|
|
||||||
Self::Global => Ok(()),
|
|
||||||
Self::NameId(name_id) => name_id.visit(state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<State: ?Sized + Folder> Fold<State> for NameIdOrGlobal {
|
|
||||||
fn fold(self, state: &mut State) -> Result<Self, <State>::Error> {
|
|
||||||
state.fold_name_id_or_global(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_fold(self, state: &mut State) -> Result<Self, <State>::Error> {
|
|
||||||
match self {
|
|
||||||
Self::Global => Ok(Self::Global),
|
|
||||||
Self::NameId(name_id) => Ok(Self::NameId(name_id.fold(state)?)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/visit.rs"));
|
include!(concat!(env!("OUT_DIR"), "/visit.rs"));
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType},
|
expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType},
|
||||||
int::Bool,
|
int::Bool,
|
||||||
intern::{Intern, Interned, InternedCompare, LazyInterned, Memoize},
|
intern::{Intern, Interned, InternedCompare, LazyInterned, LazyInternedTrait, Memoize},
|
||||||
sim::value::{SimValue, ToSimValue, ToSimValueWithType},
|
sim::value::{SimValue, ToSimValue, ToSimValueWithType},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
|
CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
|
||||||
SimValueDebug, StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
||||||
serde_impls::{SerdeCanonicalType, SerdePhantomConst},
|
serde_impls::{SerdeCanonicalType, SerdePhantomConst},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -240,17 +240,11 @@ impl<T: ?Sized + PhantomConstValue> PhantomConst<T> {
|
||||||
{
|
{
|
||||||
Self::new_interned(value.intern_deref())
|
Self::new_interned(value.intern_deref())
|
||||||
}
|
}
|
||||||
pub const fn new_const<V: Default + Into<Interned<T>>>() -> Self {
|
pub const fn new_lazy(v: &'static dyn LazyInternedTrait<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
value: LazyInterned::new_const::<V>(),
|
value: LazyInterned::new_lazy(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub const fn new_const_default() -> Self
|
|
||||||
where
|
|
||||||
Interned<T>: Default,
|
|
||||||
{
|
|
||||||
Self::new_const::<Interned<T>>()
|
|
||||||
}
|
|
||||||
pub fn get(self) -> Interned<T> {
|
pub fn get(self) -> Interned<T> {
|
||||||
self.value.interned()
|
self.value.interned()
|
||||||
}
|
}
|
||||||
|
|
@ -327,15 +321,6 @@ impl<T: ?Sized + PhantomConstValue> Type for PhantomConst<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + PhantomConstValue> SimValueDebug for PhantomConst<T> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + PhantomConstValue> Default for PhantomConst<T>
|
impl<T: ?Sized + PhantomConstValue> Default for PhantomConst<T>
|
||||||
where
|
where
|
||||||
Interned<T>: Default,
|
Interned<T>: Default,
|
||||||
|
|
@ -349,7 +334,9 @@ impl<T: ?Sized + PhantomConstValue> StaticType for PhantomConst<T>
|
||||||
where
|
where
|
||||||
Interned<T>: Default,
|
Interned<T>: Default,
|
||||||
{
|
{
|
||||||
const TYPE: Self = Self::new_const_default();
|
const TYPE: Self = PhantomConst {
|
||||||
|
value: LazyInterned::new_lazy(&Interned::<T>::default),
|
||||||
|
};
|
||||||
const MASK_TYPE: Self::MaskType = ();
|
const MASK_TYPE: Self::MaskType = ();
|
||||||
const TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES;
|
const TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES;
|
||||||
const MASK_TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES;
|
const MASK_TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES;
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ pub use crate::{
|
||||||
enum_::{Enum, HdlNone, HdlOption, HdlSome},
|
enum_::{Enum, HdlNone, HdlOption, HdlSome},
|
||||||
expr::{
|
expr::{
|
||||||
CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr,
|
CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr,
|
||||||
ReduceBits, ToExpr, ToTraceAsString, ValueType, repeat,
|
ReduceBits, ToExpr, ValueType, repeat,
|
||||||
},
|
},
|
||||||
formal::{
|
formal::{
|
||||||
all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset, hdl_assert,
|
MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset,
|
||||||
hdl_assert_with_enable, hdl_assume, hdl_assume_with_enable, hdl_cover,
|
hdl_assert, hdl_assert_with_enable, hdl_assume, hdl_assume_with_enable, hdl_cover,
|
||||||
hdl_cover_with_enable,
|
hdl_cover_with_enable,
|
||||||
},
|
},
|
||||||
hdl, hdl_module,
|
hdl, hdl_module,
|
||||||
|
|
@ -37,8 +37,8 @@ pub use crate::{
|
||||||
value::{SimOnly, SimOnlyValue, SimValue, ToSimValue, ToSimValueWithType},
|
value::{SimOnly, SimOnlyValue, SimValue, ToSimValue, ToSimValueWithType},
|
||||||
},
|
},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
testing::{FormalMode, assert_formal, checked_vcd_output},
|
testing::{FormalMode, assert_formal},
|
||||||
ty::{AsMask, CanonicalType, TraceAsString, Type},
|
ty::{AsMask, CanonicalType, Type},
|
||||||
util::{ConstUsize, GenericConstUsize},
|
util::{ConstUsize, GenericConstUsize},
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ impl<T: Type, R: ResetType> Reg<T, R> {
|
||||||
if let Some(init) = init {
|
if let Some(init) = init {
|
||||||
assert_eq!(ty, init.ty(), "register's type must match init type");
|
assert_eq!(ty, init.ty(), "register's type must match init type");
|
||||||
}
|
}
|
||||||
scoped_name.0.assert_is_name_id();
|
|
||||||
Self {
|
Self {
|
||||||
name: scoped_name,
|
name: scoped_name,
|
||||||
source_location,
|
source_location,
|
||||||
|
|
@ -95,7 +94,7 @@ impl<T: Type, R: ResetType> Reg<T, R> {
|
||||||
self.containing_module_name_id().0
|
self.containing_module_name_id().0
|
||||||
}
|
}
|
||||||
pub fn containing_module_name_id(&self) -> NameId {
|
pub fn containing_module_name_id(&self) -> NameId {
|
||||||
self.name.0.unwrap_name_id()
|
self.name.0
|
||||||
}
|
}
|
||||||
pub fn name(&self) -> Interned<str> {
|
pub fn name(&self) -> Interned<str> {
|
||||||
self.name_id().0
|
self.name_id().0
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
clock::Clock,
|
clock::Clock,
|
||||||
expr::{CastToImpl, Expr, ValueType},
|
expr::{CastToImpl, Expr, ValueType},
|
||||||
|
|
@ -9,13 +8,11 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter,
|
||||||
OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties,
|
OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
||||||
impl_match_variant_as_self,
|
|
||||||
},
|
},
|
||||||
util::ConstUsize,
|
util::ConstUsize,
|
||||||
};
|
};
|
||||||
use bitvec::{bits, order::Lsb0};
|
use bitvec::{bits, order::Lsb0};
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
pub trait ResetTypeSealed {}
|
pub trait ResetTypeSealed {}
|
||||||
|
|
@ -103,15 +100,6 @@ macro_rules! reset_type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for $name {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
pub fn type_properties(self) -> TypeProperties {
|
pub fn type_properties(self) -> TypeProperties {
|
||||||
Self::TYPE_PROPERTIES
|
Self::TYPE_PROPERTIES
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -6,9 +6,9 @@ use crate::{
|
||||||
int::{BoolOrIntType, SInt, UInt},
|
int::{BoolOrIntType, SInt, UInt},
|
||||||
intern::{Intern, Interned, Memoize},
|
intern::{Intern, Interned, Memoize},
|
||||||
sim::interpreter::parts::{
|
sim::interpreter::parts::{
|
||||||
StateLayout, StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots,
|
StateLayout, StatePartIndex, StatePartKind, StatePartKindBigSlots, StatePartKindMemories,
|
||||||
StatePartKindMemories, StatePartKindSimOnlySlots, StatePartKindSmallSlots, StatePartLen,
|
StatePartKindSimOnlySlots, StatePartKindSmallSlots, StatePartLen, TypeIndexRange,
|
||||||
TypeIndexRange, TypeLayout, get_state_part_kinds,
|
TypeLayout, get_state_part_kinds,
|
||||||
},
|
},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
util::{HashMap, HashSet},
|
util::{HashMap, HashSet},
|
||||||
|
|
@ -17,11 +17,12 @@ use bitvec::slice::BitSlice;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::BorrowMut,
|
||||||
convert::Infallible,
|
convert::Infallible,
|
||||||
fmt::{self, Write},
|
fmt::{self, Write},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::{ControlFlow, Deref, Index, IndexMut},
|
ops::{ControlFlow, Deref, DerefMut, Index, IndexMut},
|
||||||
};
|
};
|
||||||
use vec_map::VecMap;
|
use vec_map::VecMap;
|
||||||
|
|
||||||
|
|
@ -914,21 +915,6 @@ impl<K: StatePartKind> StatePart<K> {
|
||||||
value: K::borrow_state(&mut self.value),
|
value: K::borrow_state(&mut self.value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn state_index_fetch_maybe_modified_flag(
|
|
||||||
&self,
|
|
||||||
part_index: StatePartIndex<K>,
|
|
||||||
) -> bool {
|
|
||||||
K::state_index_fetch_maybe_modified_flag(&self.value, part_index)
|
|
||||||
}
|
|
||||||
pub(crate) fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
&self,
|
|
||||||
part_index_range: StatePartIndexRange<K>,
|
|
||||||
) -> bool {
|
|
||||||
K::state_index_range_fetch_maybe_modified_flags(&self.value, part_index_range)
|
|
||||||
}
|
|
||||||
pub(crate) fn clear_all_maybe_modified_flags(&mut self) {
|
|
||||||
K::clear_all_maybe_modified_flags(&mut self.value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
|
@ -936,38 +922,56 @@ pub(crate) struct BorrowedStatePart<'a, K: StatePartKind> {
|
||||||
pub(crate) value: K::BorrowedState<'a>,
|
pub(crate) value: K::BorrowedState<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: StatePartKind> BorrowedStatePart<'_, K> {
|
impl<
|
||||||
|
'a,
|
||||||
|
K: StatePartKind<
|
||||||
|
BorrowedState<'a>: DerefMut<Target: IndexMut<usize, Output = T> + BorrowMut<[T]>>,
|
||||||
|
>,
|
||||||
|
T,
|
||||||
|
> BorrowedStatePart<'a, K>
|
||||||
|
{
|
||||||
pub(crate) fn get_disjoint_mut<const N: usize>(
|
pub(crate) fn get_disjoint_mut<const N: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexes: [StatePartIndex<K>; N],
|
indexes: [StatePartIndex<K>; N],
|
||||||
) -> [&mut K::StateElement; N] {
|
) -> [&mut T; N] {
|
||||||
K::borrowed_state_get_disjoint_mut(&mut self.value, indexes)
|
(*self.value)
|
||||||
|
.borrow_mut()
|
||||||
|
.get_disjoint_mut(indexes.map(|v| v.value as usize))
|
||||||
|
.expect("indexes are disjoint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: StatePartKind> Index<StatePartIndex<K>> for StatePart<K> {
|
impl<K: StatePartKind<State: Deref<Target: Index<usize, Output = T>>>, T> Index<StatePartIndex<K>>
|
||||||
type Output = K::StateElement;
|
for StatePart<K>
|
||||||
|
{
|
||||||
|
type Output = T;
|
||||||
fn index(&self, index: StatePartIndex<K>) -> &Self::Output {
|
fn index(&self, index: StatePartIndex<K>) -> &Self::Output {
|
||||||
K::state_index(&self.value, index)
|
&self.value[index.value as usize]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: StatePartKind> IndexMut<StatePartIndex<K>> for StatePart<K> {
|
impl<K: StatePartKind<State: DerefMut<Target: IndexMut<usize, Output = T>>>, T>
|
||||||
|
IndexMut<StatePartIndex<K>> for StatePart<K>
|
||||||
|
{
|
||||||
fn index_mut(&mut self, index: StatePartIndex<K>) -> &mut Self::Output {
|
fn index_mut(&mut self, index: StatePartIndex<K>) -> &mut Self::Output {
|
||||||
K::state_index_mut(&mut self.value, index)
|
&mut self.value[index.value as usize]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: StatePartKind> Index<StatePartIndex<K>> for BorrowedStatePart<'_, K> {
|
impl<'a, K: StatePartKind<BorrowedState<'a>: Deref<Target: Index<usize, Output = T>>>, T>
|
||||||
type Output = K::StateElement;
|
Index<StatePartIndex<K>> for BorrowedStatePart<'a, K>
|
||||||
|
{
|
||||||
|
type Output = T;
|
||||||
fn index(&self, index: StatePartIndex<K>) -> &Self::Output {
|
fn index(&self, index: StatePartIndex<K>) -> &Self::Output {
|
||||||
K::borrowed_state_index(&self.value, index)
|
&self.value[index.value as usize]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: StatePartKind> IndexMut<StatePartIndex<K>> for BorrowedStatePart<'_, K> {
|
impl<'a, K: StatePartKind<BorrowedState<'a>: DerefMut<Target: IndexMut<usize, Output = T>>>, T>
|
||||||
|
IndexMut<StatePartIndex<K>> for BorrowedStatePart<'a, K>
|
||||||
|
{
|
||||||
fn index_mut(&mut self, index: StatePartIndex<K>) -> &mut Self::Output {
|
fn index_mut(&mut self, index: StatePartIndex<K>) -> &mut Self::Output {
|
||||||
K::borrowed_state_index_mut(&mut self.value, index)
|
&mut self.value[index.value as usize]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -980,7 +984,6 @@ macro_rules! make_state {
|
||||||
pub(crate) insns: Interned<Insns<InsnsBuildingDone>>,
|
pub(crate) insns: Interned<Insns<InsnsBuildingDone>>,
|
||||||
pub(crate) pc: usize,
|
pub(crate) pc: usize,
|
||||||
pub(crate) memory_write_log: Vec<(StatePartIndex<StatePartKindMemories>, usize)>,
|
pub(crate) memory_write_log: Vec<(StatePartIndex<StatePartKindMemories>, usize)>,
|
||||||
pub(crate) assert_failed_log: Vec<usize>,
|
|
||||||
$(pub(crate) $state_plural_field: StatePart<$state_kind>,)*
|
$(pub(crate) $state_plural_field: StatePart<$state_kind>,)*
|
||||||
$(pub(crate) $type_plural_field: StatePart<$type_kind>,)*
|
$(pub(crate) $type_plural_field: StatePart<$type_kind>,)*
|
||||||
}
|
}
|
||||||
|
|
@ -991,7 +994,6 @@ macro_rules! make_state {
|
||||||
insns: _,
|
insns: _,
|
||||||
pc,
|
pc,
|
||||||
memory_write_log,
|
memory_write_log,
|
||||||
assert_failed_log,
|
|
||||||
$($state_plural_field,)*
|
$($state_plural_field,)*
|
||||||
$($type_plural_field,)*
|
$($type_plural_field,)*
|
||||||
} = self;
|
} = self;
|
||||||
|
|
@ -999,7 +1001,6 @@ macro_rules! make_state {
|
||||||
.field("insns", &InsnsOfState(self))
|
.field("insns", &InsnsOfState(self))
|
||||||
.field("pc", pc)
|
.field("pc", pc)
|
||||||
.field("memory_write_log", memory_write_log)
|
.field("memory_write_log", memory_write_log)
|
||||||
.field("assert_failed_log", assert_failed_log)
|
|
||||||
$(.field(stringify!($state_plural_field), $state_plural_field))*
|
$(.field(stringify!($state_plural_field), $state_plural_field))*
|
||||||
$(.field(stringify!($type_plural_field), $type_plural_field))*
|
$(.field(stringify!($type_plural_field), $type_plural_field))*
|
||||||
.finish()
|
.finish()
|
||||||
|
|
@ -1012,7 +1013,6 @@ macro_rules! make_state {
|
||||||
insns,
|
insns,
|
||||||
pc: 0,
|
pc: 0,
|
||||||
memory_write_log: Vec::with_capacity(32),
|
memory_write_log: Vec::with_capacity(32),
|
||||||
assert_failed_log: Vec::new(),
|
|
||||||
$($state_plural_field: StatePart::new(&insns.state_layout.$state_plural_field.layout_data),)*
|
$($state_plural_field: StatePart::new(&insns.state_layout.$state_plural_field.layout_data),)*
|
||||||
$($type_plural_field: StatePart::new(&insns.state_layout.ty.$type_plural_field.layout_data),)*
|
$($type_plural_field: StatePart::new(&insns.state_layout.ty.$type_plural_field.layout_data),)*
|
||||||
}
|
}
|
||||||
|
|
@ -1024,20 +1024,10 @@ macro_rules! make_state {
|
||||||
pc: self.pc,
|
pc: self.pc,
|
||||||
orig_pc: &mut self.pc,
|
orig_pc: &mut self.pc,
|
||||||
memory_write_log: &mut self.memory_write_log,
|
memory_write_log: &mut self.memory_write_log,
|
||||||
assert_failed_log: &mut self.assert_failed_log,
|
|
||||||
$($state_plural_field: self.$state_plural_field.borrow(),)*
|
$($state_plural_field: self.$state_plural_field.borrow(),)*
|
||||||
$($type_plural_field: self.$type_plural_field.borrow(),)*
|
$($type_plural_field: self.$type_plural_field.borrow(),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn type_index_range_fetch_maybe_modified_flags(&self, range: TypeIndexRange) -> bool {
|
|
||||||
$(self.$type_plural_field.state_index_range_fetch_maybe_modified_flags(
|
|
||||||
range.$type_plural_field,
|
|
||||||
))||*
|
|
||||||
}
|
|
||||||
pub(crate) fn clear_all_maybe_modified_flags(&mut self) {
|
|
||||||
$(self.$state_plural_field.clear_all_maybe_modified_flags();)*
|
|
||||||
$(self.$type_plural_field.clear_all_maybe_modified_flags();)*
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -1047,7 +1037,6 @@ macro_rules! make_state {
|
||||||
pub(crate) orig_pc: &'a mut usize,
|
pub(crate) orig_pc: &'a mut usize,
|
||||||
pub(crate) pc: usize,
|
pub(crate) pc: usize,
|
||||||
pub(crate) memory_write_log: &'a mut Vec<(StatePartIndex<StatePartKindMemories>, usize)>,
|
pub(crate) memory_write_log: &'a mut Vec<(StatePartIndex<StatePartKindMemories>, usize)>,
|
||||||
pub(crate) assert_failed_log: &'a mut Vec<usize>,
|
|
||||||
$(pub(crate) $state_plural_field: BorrowedStatePart<'a, $state_kind>,)*
|
$(pub(crate) $state_plural_field: BorrowedStatePart<'a, $state_kind>,)*
|
||||||
$(pub(crate) $type_plural_field: BorrowedStatePart<'a, $type_kind>,)*
|
$(pub(crate) $type_plural_field: BorrowedStatePart<'a, $type_kind>,)*
|
||||||
}
|
}
|
||||||
|
|
@ -1305,7 +1294,6 @@ impl State {
|
||||||
insns: _,
|
insns: _,
|
||||||
pc,
|
pc,
|
||||||
memory_write_log: _,
|
memory_write_log: _,
|
||||||
assert_failed_log: _,
|
|
||||||
memories: _,
|
memories: _,
|
||||||
small_slots: _,
|
small_slots: _,
|
||||||
big_slots: _,
|
big_slots: _,
|
||||||
|
|
@ -1345,10 +1333,6 @@ impl BorrowedState<'_> {
|
||||||
self.memory_write_log.push(log_entry);
|
self.memory_write_log.push(log_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cold]
|
|
||||||
fn assert_failed(&mut self, assert_index: usize) {
|
|
||||||
self.assert_failed_log.push(assert_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bigint_pow2(width: usize) -> Interned<BigInt> {
|
fn bigint_pow2(width: usize) -> Interned<BigInt> {
|
||||||
|
|
@ -2116,19 +2100,6 @@ impl_insns! {
|
||||||
state.log_memory_write(memory, addr);
|
state.log_memory_write(memory, addr);
|
||||||
next!();
|
next!();
|
||||||
}
|
}
|
||||||
Assert {
|
|
||||||
#[kind = Input]
|
|
||||||
clk_triggered: StatePartIndex<StatePartKindSmallSlots>,
|
|
||||||
#[kind = Input]
|
|
||||||
pred: StatePartIndex<StatePartKindSmallSlots>,
|
|
||||||
#[kind = Immediate]
|
|
||||||
assert_index: usize,
|
|
||||||
} => {
|
|
||||||
if state.small_slots[clk_triggered] != 0 && state.small_slots[pred] == 0 {
|
|
||||||
state.assert_failed(assert_index);
|
|
||||||
}
|
|
||||||
next!();
|
|
||||||
}
|
|
||||||
Return => {
|
Return => {
|
||||||
break RunResult::Return(());
|
break RunResult::Return(());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,6 @@ pub(crate) trait StatePartKind:
|
||||||
type LayoutData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy;
|
type LayoutData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy;
|
||||||
type State: fmt::Debug + 'static + Clone;
|
type State: fmt::Debug + 'static + Clone;
|
||||||
type BorrowedState<'a>: 'a;
|
type BorrowedState<'a>: 'a;
|
||||||
type StateElement;
|
|
||||||
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State;
|
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State;
|
||||||
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>;
|
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>;
|
||||||
fn part_debug_data<BK: InsnsBuildingKind>(
|
fn part_debug_data<BK: InsnsBuildingKind>(
|
||||||
|
|
@ -248,35 +247,6 @@ pub(crate) trait StatePartKind:
|
||||||
index: StatePartIndex<Self>,
|
index: StatePartIndex<Self>,
|
||||||
f: &mut impl fmt::Write,
|
f: &mut impl fmt::Write,
|
||||||
) -> fmt::Result;
|
) -> fmt::Result;
|
||||||
fn state_index<'a>(
|
|
||||||
state: &'a Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement;
|
|
||||||
fn state_index_mut<'a>(
|
|
||||||
state: &'a mut Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement;
|
|
||||||
fn state_index_fetch_maybe_modified_flag(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> bool;
|
|
||||||
fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index_range: StatePartIndexRange<Self>,
|
|
||||||
) -> bool;
|
|
||||||
fn clear_all_maybe_modified_flags(state: &mut Self::State);
|
|
||||||
fn borrowed_state_index<'a, 'b>(
|
|
||||||
state: &'a Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement;
|
|
||||||
fn borrowed_state_index_mut<'a, 'b>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement;
|
|
||||||
fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_indexes: [StatePartIndex<Self>; N],
|
|
||||||
) -> [&'a mut Self::StateElement; N];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! make_state_part_kinds {
|
macro_rules! make_state_part_kinds {
|
||||||
|
|
@ -302,7 +272,6 @@ impl StatePartKind for StatePartKindMemories {
|
||||||
type LayoutData = MemoryData<Interned<BitSlice>>;
|
type LayoutData = MemoryData<Interned<BitSlice>>;
|
||||||
type State = Box<[MemoryData<BitBox>]>;
|
type State = Box<[MemoryData<BitBox>]>;
|
||||||
type BorrowedState<'a> = &'a mut [MemoryData<BitBox>];
|
type BorrowedState<'a> = &'a mut [MemoryData<BitBox>];
|
||||||
type StateElement = MemoryData<BitBox>;
|
|
||||||
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
||||||
layout_data
|
layout_data
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -328,95 +297,19 @@ impl StatePartKind for StatePartKindMemories {
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
write!(f, "{:#?}", &state.memories[index])
|
write!(f, "{:#?}", &state.memories[index])
|
||||||
}
|
}
|
||||||
fn state_index<'a>(
|
|
||||||
state: &'a Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_mut<'a>(
|
|
||||||
state: &'a mut Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
&mut state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_fetch_maybe_modified_flag(
|
|
||||||
_state: &Self::State,
|
|
||||||
_part_index: StatePartIndex<Self>,
|
|
||||||
) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
_state: &Self::State,
|
|
||||||
part_index_range: StatePartIndexRange<Self>,
|
|
||||||
) -> bool {
|
|
||||||
part_index_range.len.value > 0
|
|
||||||
}
|
|
||||||
fn clear_all_maybe_modified_flags(_state: &mut Self::State) {}
|
|
||||||
fn borrowed_state_index<'a, 'b>(
|
|
||||||
state: &'a Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_index_mut<'a, 'b>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
&mut state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_indexes: [StatePartIndex<Self>; N],
|
|
||||||
) -> [&'a mut Self::StateElement; N] {
|
|
||||||
state
|
|
||||||
.get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize))
|
|
||||||
.expect("indexes are disjoint")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Default)]
|
|
||||||
pub(crate) struct StateAndModified<T, M> {
|
|
||||||
pub(crate) state: T,
|
|
||||||
pub(crate) modified: M,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Deref<Target = [E]>, M: Deref<Target = [bool]>, E: fmt::Debug> fmt::Debug
|
|
||||||
for StateAndModified<T, M>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_list()
|
|
||||||
.entries(self.state.iter().zip(self.modified.iter().copied()).map(
|
|
||||||
|(state, modified)| {
|
|
||||||
fmt::from_fn(move |f| {
|
|
||||||
state.fmt(f)?;
|
|
||||||
if modified {
|
|
||||||
f.write_str(" (modified)")?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatePartKind for StatePartKindSmallSlots {
|
impl StatePartKind for StatePartKindSmallSlots {
|
||||||
const NAME: &'static str = "SmallSlots";
|
const NAME: &'static str = "SmallSlots";
|
||||||
type DebugData = SlotDebugData;
|
type DebugData = SlotDebugData;
|
||||||
type LayoutData = ();
|
type LayoutData = ();
|
||||||
type State = StateAndModified<Box<[Self::StateElement]>, Box<[bool]>>;
|
type State = Box<[SmallUInt]>;
|
||||||
type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>;
|
type BorrowedState<'a> = &'a mut [SmallUInt];
|
||||||
type StateElement = SmallUInt;
|
|
||||||
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
||||||
StateAndModified {
|
vec![0; layout_data.len()].into_boxed_slice()
|
||||||
state: vec![0; layout_data.len()].into_boxed_slice(),
|
|
||||||
modified: vec![false; layout_data.len()].into_boxed_slice(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
||||||
let StateAndModified { state, modified } = state;
|
state
|
||||||
StateAndModified { state, modified }
|
|
||||||
}
|
}
|
||||||
fn part_debug_data<BK: InsnsBuildingKind>(
|
fn part_debug_data<BK: InsnsBuildingKind>(
|
||||||
state_layout: &StateLayout<BK>,
|
state_layout: &StateLayout<BK>,
|
||||||
|
|
@ -437,80 +330,19 @@ impl StatePartKind for StatePartKindSmallSlots {
|
||||||
write!(f, "{value:#x} {}", value as SmallSInt)?;
|
write!(f, "{value:#x} {}", value as SmallSInt)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn state_index<'a>(
|
|
||||||
state: &'a Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_mut<'a>(
|
|
||||||
state: &'a mut Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_fetch_maybe_modified_flag(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index_range: StatePartIndexRange<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index_range.start.as_usize()..]
|
|
||||||
[..part_index_range.len.as_index().as_usize()]
|
|
||||||
.contains(&true)
|
|
||||||
}
|
|
||||||
fn clear_all_maybe_modified_flags(state: &mut Self::State) {
|
|
||||||
state.modified.fill(false);
|
|
||||||
}
|
|
||||||
fn borrowed_state_index<'a, 'b>(
|
|
||||||
state: &'a Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_index_mut<'a, 'b>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_indexes: [StatePartIndex<Self>; N],
|
|
||||||
) -> [&'a mut Self::StateElement; N] {
|
|
||||||
for part_index in part_indexes {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
}
|
|
||||||
state
|
|
||||||
.state
|
|
||||||
.get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize))
|
|
||||||
.expect("indexes are disjoint")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatePartKind for StatePartKindBigSlots {
|
impl StatePartKind for StatePartKindBigSlots {
|
||||||
const NAME: &'static str = "BigSlots";
|
const NAME: &'static str = "BigSlots";
|
||||||
type DebugData = SlotDebugData;
|
type DebugData = SlotDebugData;
|
||||||
type LayoutData = ();
|
type LayoutData = ();
|
||||||
type State = StateAndModified<Box<[Self::StateElement]>, Box<[bool]>>;
|
type State = Box<[BigInt]>;
|
||||||
type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>;
|
type BorrowedState<'a> = &'a mut [BigInt];
|
||||||
type StateElement = BigInt;
|
|
||||||
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
||||||
let state: Box<[_]> = layout_data.iter().map(|_| BigInt::default()).collect();
|
layout_data.iter().map(|_| BigInt::default()).collect()
|
||||||
StateAndModified {
|
|
||||||
modified: vec![false; state.len()].into_boxed_slice(),
|
|
||||||
state,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
||||||
let StateAndModified { state, modified } = state;
|
state
|
||||||
StateAndModified { state, modified }
|
|
||||||
}
|
}
|
||||||
fn part_debug_data<BK: InsnsBuildingKind>(
|
fn part_debug_data<BK: InsnsBuildingKind>(
|
||||||
state_layout: &StateLayout<BK>,
|
state_layout: &StateLayout<BK>,
|
||||||
|
|
@ -529,80 +361,19 @@ impl StatePartKind for StatePartKindBigSlots {
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
write!(f, "{:#x}", state.big_slots[index])
|
write!(f, "{:#x}", state.big_slots[index])
|
||||||
}
|
}
|
||||||
fn state_index<'a>(
|
|
||||||
state: &'a Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_mut<'a>(
|
|
||||||
state: &'a mut Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_fetch_maybe_modified_flag(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index_range: StatePartIndexRange<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index_range.start.as_usize()..]
|
|
||||||
[..part_index_range.len.as_index().as_usize()]
|
|
||||||
.contains(&true)
|
|
||||||
}
|
|
||||||
fn clear_all_maybe_modified_flags(state: &mut Self::State) {
|
|
||||||
state.modified.fill(false);
|
|
||||||
}
|
|
||||||
fn borrowed_state_index<'a, 'b>(
|
|
||||||
state: &'a Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_index_mut<'a, 'b>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_indexes: [StatePartIndex<Self>; N],
|
|
||||||
) -> [&'a mut Self::StateElement; N] {
|
|
||||||
for part_index in part_indexes {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
}
|
|
||||||
state
|
|
||||||
.state
|
|
||||||
.get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize))
|
|
||||||
.expect("indexes are disjoint")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatePartKind for StatePartKindSimOnlySlots {
|
impl StatePartKind for StatePartKindSimOnlySlots {
|
||||||
const NAME: &'static str = "SimOnlySlots";
|
const NAME: &'static str = "SimOnlySlots";
|
||||||
type DebugData = SlotDebugData;
|
type DebugData = SlotDebugData;
|
||||||
type LayoutData = DynSimOnly;
|
type LayoutData = DynSimOnly;
|
||||||
type State = StateAndModified<Box<[Self::StateElement]>, Box<[bool]>>;
|
type State = Box<[DynSimOnlyValue]>;
|
||||||
type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>;
|
type BorrowedState<'a> = &'a mut [DynSimOnlyValue];
|
||||||
type StateElement = DynSimOnlyValue;
|
|
||||||
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
|
||||||
let state: Box<[_]> = layout_data.iter().map(|ty| ty.default_value()).collect();
|
layout_data.iter().map(|ty| ty.default_value()).collect()
|
||||||
StateAndModified {
|
|
||||||
modified: vec![false; state.len()].into_boxed_slice(),
|
|
||||||
state,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
|
||||||
let StateAndModified { state, modified } = state;
|
state
|
||||||
StateAndModified { state, modified }
|
|
||||||
}
|
}
|
||||||
fn part_debug_data<BK: InsnsBuildingKind>(
|
fn part_debug_data<BK: InsnsBuildingKind>(
|
||||||
state_layout: &StateLayout<BK>,
|
state_layout: &StateLayout<BK>,
|
||||||
|
|
@ -621,61 +392,6 @@ impl StatePartKind for StatePartKindSimOnlySlots {
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
write!(f, "{:?}", state.sim_only_slots[index])
|
write!(f, "{:?}", state.sim_only_slots[index])
|
||||||
}
|
}
|
||||||
fn state_index<'a>(
|
|
||||||
state: &'a Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_mut<'a>(
|
|
||||||
state: &'a mut Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_fetch_maybe_modified_flag(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn state_index_range_fetch_maybe_modified_flags(
|
|
||||||
state: &Self::State,
|
|
||||||
part_index_range: StatePartIndexRange<Self>,
|
|
||||||
) -> bool {
|
|
||||||
state.modified[part_index_range.start.as_usize()..]
|
|
||||||
[..part_index_range.len.as_index().as_usize()]
|
|
||||||
.contains(&true)
|
|
||||||
}
|
|
||||||
fn clear_all_maybe_modified_flags(state: &mut Self::State) {
|
|
||||||
state.modified.fill(false);
|
|
||||||
}
|
|
||||||
fn borrowed_state_index<'a, 'b>(
|
|
||||||
state: &'a Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a Self::StateElement {
|
|
||||||
&state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_index_mut<'a, 'b>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_index: StatePartIndex<Self>,
|
|
||||||
) -> &'a mut Self::StateElement {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
&mut state.state[part_index.as_usize()]
|
|
||||||
}
|
|
||||||
fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>(
|
|
||||||
state: &'a mut Self::BorrowedState<'b>,
|
|
||||||
part_indexes: [StatePartIndex<Self>; N],
|
|
||||||
) -> [&'a mut Self::StateElement; N] {
|
|
||||||
for part_index in part_indexes {
|
|
||||||
state.modified[part_index.as_usize()] = true;
|
|
||||||
}
|
|
||||||
state
|
|
||||||
.state
|
|
||||||
.get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize))
|
|
||||||
.expect("indexes are disjoint")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,23 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{
|
ty::{
|
||||||
CanonicalType, OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSlice,
|
CanonicalType, OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSlice,
|
||||||
OpaqueSimValueWriter, SimValueDebug, StaticType, Type, TypeProperties,
|
OpaqueSimValueWriter, StaticType, Type, TypeProperties, impl_match_variant_as_self,
|
||||||
impl_match_variant_as_self,
|
|
||||||
},
|
},
|
||||||
util::{
|
util::{
|
||||||
ConstUsize,
|
ConstUsize, HashMap,
|
||||||
alternating_cell::{AlternatingCell, AlternatingCellMethods},
|
alternating_cell::{AlternatingCell, AlternatingCellMethods},
|
||||||
serde_by_id::{SerdeById, SerdeByIdProperties, SerdeByIdTable, SerdeByIdTrait},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bitvec::{slice::BitSlice, vec::BitVec};
|
use bitvec::{slice::BitSlice, vec::BitVec};
|
||||||
|
use hashbrown::hash_map::Entry;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Borrow, BorrowMut, Cow},
|
borrow::{Borrow, BorrowMut, Cow},
|
||||||
fmt,
|
fmt::{self, Write},
|
||||||
|
hash::{BuildHasher, Hash, Hasher, RandomState},
|
||||||
num::NonZero,
|
num::NonZero,
|
||||||
ops::{Deref, DerefMut, Index, IndexMut},
|
ops::{Deref, DerefMut, Index, IndexMut},
|
||||||
sync::Arc,
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod sim_only_value_unsafe;
|
pub(crate) mod sim_only_value_unsafe;
|
||||||
|
|
@ -551,119 +551,113 @@ impl_sim_value_cmp_as_bool!(AsyncReset);
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod match_sim_value {
|
pub mod match_sim_value {
|
||||||
use crate::{sim::value::SimValue, ty::Type};
|
use crate::{
|
||||||
use std::ops::{Deref, DerefMut};
|
sim::value::{SimValue, ToSimValue},
|
||||||
|
ty::Type,
|
||||||
macro_rules! wrapper {
|
};
|
||||||
(
|
|
||||||
$(pub struct $wrapper:ident<$T:ident>($inner:ty);)*
|
|
||||||
) => {
|
|
||||||
$(#[doc(hidden)]
|
|
||||||
pub struct $wrapper<$T>($inner);
|
|
||||||
|
|
||||||
impl<$T> $wrapper<$T> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(value: $T) -> Self {
|
|
||||||
Self(<$inner>::new(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<$T> Deref for $wrapper<$T> {
|
|
||||||
type Target = $inner;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<$T> DerefMut for $wrapper<$T> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
})*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapper! {
|
|
||||||
pub struct MatchSimValueHelperCheckSimValue<T>(MatchSimValueHelperCheckMutSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckMutSimValue<T>(MatchSimValueHelperCheckRefSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckRefSimValue<T>(MatchSimValueHelperCheckRefRefSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckRefRefSimValue<T>(MatchSimValueHelperCheckRefMutSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckRefMutSimValue<T>(MatchSimValueHelperCheckMutRefSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckMutRefSimValue<T>(MatchSimValueHelperCheckMutMutSimValue<T>);
|
|
||||||
pub struct MatchSimValueHelperCheckMutMutSimValue<T>(MatchSimValueHelperIdentity<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type> MatchSimValueHelperCheckSimValue<SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> T::SimValue {
|
|
||||||
SimValue::into_value(self.take())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Type> MatchSimValueHelperCheckMutSimValue<&'a mut SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'a mut T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Type> MatchSimValueHelperCheckRefSimValue<&'a SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'a T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: Type> MatchSimValueHelperCheckRefRefSimValue<&'a &'b SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'b T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: Type> MatchSimValueHelperCheckRefMutSimValue<&'a &'b mut SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'a T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: Type> MatchSimValueHelperCheckMutRefSimValue<&'a mut &'b SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'b T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: Type> MatchSimValueHelperCheckMutMutSimValue<&'a mut &'b mut SimValue<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> &'a mut T::SimValue {
|
|
||||||
self.take()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct MatchSimValueHelperIdentity<T>(Option<T>);
|
pub struct MatchSimValueHelper<T>(Option<T>);
|
||||||
|
|
||||||
impl<T> MatchSimValueHelperIdentity<T> {
|
impl<T> MatchSimValueHelper<T> {
|
||||||
fn new(v: T) -> Self {
|
pub fn new(v: T) -> Self {
|
||||||
Self(Some(v))
|
Self(Some(v))
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
}
|
||||||
fn take(&mut self) -> T {
|
|
||||||
self.0.take().expect("known to be Some")
|
#[doc(hidden)]
|
||||||
|
pub trait MatchSimValue {
|
||||||
|
type MatchValue;
|
||||||
|
|
||||||
|
/// use `self` so it comes first in the method resolution order
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type> MatchSimValue for MatchSimValueHelper<SimValue<T>> {
|
||||||
|
type MatchValue = T::SimValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
SimValue::into_value(self.0.expect("should be Some"))
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
}
|
||||||
pub fn __fayalite_match_sim_value(&mut self) -> T {
|
|
||||||
self.take()
|
impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a SimValue<T>> {
|
||||||
|
type MatchValue = &'a T::SimValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
SimValue::value(self.0.expect("should be Some"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a mut SimValue<T>> {
|
||||||
|
type MatchValue = &'a mut T::SimValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
SimValue::value_mut(self.0.expect("should be Some"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ &'a T>
|
||||||
|
where
|
||||||
|
MatchSimValueHelper<&'a T>: MatchSimValue,
|
||||||
|
{
|
||||||
|
type MatchValue = <MatchSimValueHelper<&'a T> as MatchSimValue>::MatchValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ mut &'a T>
|
||||||
|
where
|
||||||
|
MatchSimValueHelper<&'a T>: MatchSimValue,
|
||||||
|
{
|
||||||
|
type MatchValue = <MatchSimValueHelper<&'a T> as MatchSimValue>::MatchValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a &'_ mut T>
|
||||||
|
where
|
||||||
|
MatchSimValueHelper<&'a T>: MatchSimValue,
|
||||||
|
{
|
||||||
|
type MatchValue = <MatchSimValueHelper<&'a T> as MatchSimValue>::MatchValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &**v)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a mut &'_ mut T>
|
||||||
|
where
|
||||||
|
MatchSimValueHelper<&'a mut T>: MatchSimValue,
|
||||||
|
{
|
||||||
|
type MatchValue = <MatchSimValueHelper<&'a mut T> as MatchSimValue>::MatchValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(self) -> Self::MatchValue {
|
||||||
|
MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &mut **v)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type MatchSimValueHelper<T> = MatchSimValueHelperCheckSimValue<T>;
|
pub trait MatchSimValueFallback {
|
||||||
|
type MatchValue;
|
||||||
|
|
||||||
|
/// use `&mut self` so it comes later in the method resolution order than MatchSimValue
|
||||||
|
fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ToSimValue> MatchSimValueFallback for MatchSimValueHelper<T> {
|
||||||
|
type MatchValue = <T::Type as Type>::SimValue;
|
||||||
|
|
||||||
|
fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue {
|
||||||
|
SimValue::into_value(self.0.take().expect("should be Some").into_sim_value())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToSimValue: ToSimValueWithType<<Self as ValueType>::Type> + ValueType {
|
pub trait ToSimValue: ToSimValueWithType<<Self as ValueType>::Type> + ValueType {
|
||||||
|
|
@ -1097,8 +1091,7 @@ impl ToSimValueWithType<CanonicalType> for bool {
|
||||||
| CanonicalType::Enum(_)
|
| CanonicalType::Enum(_)
|
||||||
| CanonicalType::Bundle(_)
|
| CanonicalType::Bundle(_)
|
||||||
| CanonicalType::PhantomConst(_)
|
| CanonicalType::PhantomConst(_)
|
||||||
| CanonicalType::DynSimOnly(_)
|
| CanonicalType::DynSimOnly(_) => {
|
||||||
| CanonicalType::TraceAsString(_) => {
|
|
||||||
panic!("can't create SimValue from bool: expected value of type: {ty:?}");
|
panic!("can't create SimValue from bool: expected value of type: {ty:?}");
|
||||||
}
|
}
|
||||||
CanonicalType::Bool(_)
|
CanonicalType::Bool(_)
|
||||||
|
|
@ -1227,17 +1220,80 @@ macro_rules! impl_to_sim_value_for_int_value {
|
||||||
impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType);
|
impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType);
|
||||||
impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType);
|
impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType);
|
||||||
|
|
||||||
impl SerdeByIdTrait for DynSimOnly {
|
#[derive(Default)]
|
||||||
fn serde_by_id_properties(&self) -> SerdeByIdProperties<Self> {
|
struct DynSimOnlySerdeTableRest {
|
||||||
self.serde_by_id_properties_inner()
|
from_serde: HashMap<DynSimOnlySerdeId, DynSimOnly>,
|
||||||
}
|
serde_id_random_state: RandomState,
|
||||||
|
buffer: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn static_table() -> &'static SerdeByIdTable<Self> {
|
impl DynSimOnlySerdeTableRest {
|
||||||
static TABLE: SerdeByIdTable<DynSimOnly> = SerdeByIdTable::new();
|
#[cold]
|
||||||
&TABLE
|
fn add_new(&mut self, ty: DynSimOnly) -> DynSimOnlySerdeId {
|
||||||
|
let mut try_number = 0u64;
|
||||||
|
let mut hasher = self.serde_id_random_state.build_hasher();
|
||||||
|
// extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits
|
||||||
|
write!(self.buffer, "{:?}", ty.type_id()).expect("shouldn't ever fail");
|
||||||
|
self.buffer.hash(&mut hasher);
|
||||||
|
loop {
|
||||||
|
let mut hasher = hasher.clone();
|
||||||
|
try_number.hash(&mut hasher);
|
||||||
|
try_number += 1;
|
||||||
|
let retval = DynSimOnlySerdeId(std::array::from_fn(|i| {
|
||||||
|
let mut hasher = hasher.clone();
|
||||||
|
i.hash(&mut hasher);
|
||||||
|
hasher.finish() as u32
|
||||||
|
}));
|
||||||
|
match self.from_serde.entry(retval) {
|
||||||
|
Entry::Occupied(_) => continue,
|
||||||
|
Entry::Vacant(e) => {
|
||||||
|
e.insert(ty);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NAME: &'static str = "DynSimOnly";
|
#[derive(Default)]
|
||||||
|
struct DynSimOnlySerdeTable {
|
||||||
|
to_serde: HashMap<DynSimOnly, DynSimOnlySerdeId>,
|
||||||
|
rest: DynSimOnlySerdeTableRest,
|
||||||
|
}
|
||||||
|
|
||||||
|
static DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE: Mutex<Option<DynSimOnlySerdeTable>> = Mutex::new(None);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
struct DynSimOnlySerdeId([u32; 4]);
|
||||||
|
|
||||||
|
impl From<DynSimOnly> for DynSimOnlySerdeId {
|
||||||
|
fn from(ty: DynSimOnly) -> Self {
|
||||||
|
let mut locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
|
||||||
|
.lock()
|
||||||
|
.expect("shouldn't be poison");
|
||||||
|
let DynSimOnlySerdeTable { to_serde, rest } = locked.get_or_insert_default();
|
||||||
|
match to_serde.entry(ty) {
|
||||||
|
Entry::Occupied(occupied_entry) => *occupied_entry.get(),
|
||||||
|
Entry::Vacant(vacant_entry) => *vacant_entry.insert(rest.add_new(ty)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DynSimOnlySerdeId {
|
||||||
|
fn ty(self) -> Option<DynSimOnly> {
|
||||||
|
let locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
|
||||||
|
.lock()
|
||||||
|
.expect("shouldn't be poison");
|
||||||
|
Some(*locked.as_ref()?.rest.from_serde.get(&self)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
struct DynSimOnlySerde<'a> {
|
||||||
|
random_id: DynSimOnlySerdeId,
|
||||||
|
#[serde(borrow)]
|
||||||
|
type_name: Cow<'a, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for DynSimOnly {
|
impl Serialize for DynSimOnly {
|
||||||
|
|
@ -1245,7 +1301,11 @@ impl Serialize for DynSimOnly {
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
SerdeById { inner: *self }.serialize(serializer)
|
DynSimOnlySerde {
|
||||||
|
random_id: (*self).into(),
|
||||||
|
type_name: Cow::Borrowed(self.type_name()),
|
||||||
|
}
|
||||||
|
.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1254,7 +1314,16 @@ impl<'de> Deserialize<'de> for DynSimOnly {
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
Ok(SerdeById::deserialize(deserializer)?.inner)
|
let deserialized = DynSimOnlySerde::deserialize(deserializer)?;
|
||||||
|
let retval = deserialized
|
||||||
|
.random_id
|
||||||
|
.ty()
|
||||||
|
.filter(|ty| ty.type_name() == deserialized.type_name);
|
||||||
|
retval.ok_or_else(|| {
|
||||||
|
D::Error::custom(
|
||||||
|
"doesn't match any DynSimOnly that was serialized this time this program was run",
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1325,15 +1394,6 @@ impl Type for DynSimOnly {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for DynSimOnly {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SimOnlyValueTrait> Type for SimOnly<T> {
|
impl<T: SimOnlyValueTrait> Type for SimOnly<T> {
|
||||||
type BaseType = DynSimOnly;
|
type BaseType = DynSimOnly;
|
||||||
type MaskType = Bool;
|
type MaskType = Bool;
|
||||||
|
|
@ -1399,15 +1459,6 @@ impl<T: SimOnlyValueTrait> Type for SimOnly<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SimOnlyValueTrait> SimValueDebug for SimOnly<T> {
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
fmt::Debug::fmt(value, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SimOnlyValueTrait> StaticType for SimOnly<T> {
|
impl<T: SimOnlyValueTrait> StaticType for SimOnly<T> {
|
||||||
const TYPE: Self = Self::new();
|
const TYPE: Self = Self::new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,7 @@
|
||||||
|
|
||||||
//! `unsafe` parts of [`DynSimOnlyValue`]
|
//! `unsafe` parts of [`DynSimOnlyValue`]
|
||||||
|
|
||||||
use crate::{
|
use crate::expr::{ValueType, value_category::ValueCategoryValue};
|
||||||
expr::{ValueType, value_category::ValueCategoryValue},
|
|
||||||
util::serde_by_id::SerdeByIdProperties,
|
|
||||||
};
|
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
use std::{
|
use std::{
|
||||||
any::{self, TypeId},
|
any::{self, TypeId},
|
||||||
|
|
@ -36,7 +33,6 @@ unsafe trait DynSimOnlyTrait: 'static + Send + Sync {
|
||||||
&self,
|
&self,
|
||||||
json_str: &str,
|
json_str: &str,
|
||||||
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>;
|
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>;
|
||||||
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safety: `type_id_dyn` is implemented correctly
|
/// Safety: `type_id_dyn` is implemented correctly
|
||||||
|
|
@ -59,9 +55,6 @@ unsafe impl<T: SimOnlyValueTrait> DynSimOnlyTrait for SimOnly<T> {
|
||||||
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> {
|
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> {
|
||||||
Ok(Rc::<T>::new(serde_json::from_str(json_str)?))
|
Ok(Rc::<T>::new(serde_json::from_str(json_str)?))
|
||||||
}
|
}
|
||||||
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly> {
|
|
||||||
SerdeByIdProperties::of::<T>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safety:
|
/// Safety:
|
||||||
|
|
@ -158,9 +151,6 @@ impl DynSimOnly {
|
||||||
pub fn default_value(self) -> DynSimOnlyValue {
|
pub fn default_value(self) -> DynSimOnlyValue {
|
||||||
DynSimOnlyValue(self.ty.default_value())
|
DynSimOnlyValue(self.ty.default_value())
|
||||||
}
|
}
|
||||||
pub(super) fn serde_by_id_properties_inner(self) -> SerdeByIdProperties<Self> {
|
|
||||||
self.ty.serde_by_id_properties_inner()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for DynSimOnly {
|
impl PartialEq for DynSimOnly {
|
||||||
|
|
|
||||||
|
|
@ -9,44 +9,26 @@ use crate::{
|
||||||
prelude::PhantomConst,
|
prelude::PhantomConst,
|
||||||
sim::{
|
sim::{
|
||||||
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
|
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
|
||||||
TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceFormalInput,
|
TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance,
|
||||||
TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation,
|
TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule,
|
||||||
TraceModule, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, TraceScalar,
|
TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, TraceScalar, TraceScalarId,
|
||||||
TraceScalarId, TraceScope, TraceSimOnly, TraceSyncReset, TraceTraceAsString, TraceUInt,
|
TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, TraceWriter,
|
||||||
TraceWire, TraceWriter, TraceWriterDecls,
|
TraceWriterDecls,
|
||||||
time::{SimDuration, SimInstant},
|
time::{SimDuration, SimInstant},
|
||||||
value::DynSimOnlyValue,
|
value::DynSimOnlyValue,
|
||||||
},
|
},
|
||||||
ty::{OpaqueSimValueSlice, TraceAsString},
|
|
||||||
util::HashMap,
|
util::HashMap,
|
||||||
};
|
};
|
||||||
use bitvec::{order::Lsb0, slice::BitSlice};
|
use bitvec::{order::Lsb0, slice::BitSlice};
|
||||||
use hashbrown::hash_map::Entry;
|
use hashbrown::hash_map::Entry;
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
|
||||||
fmt::{self, Write as _},
|
fmt::{self, Write as _},
|
||||||
io, mem,
|
io, mem,
|
||||||
num::NonZeroU64,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default)]
|
||||||
struct PathHash(Sha256);
|
|
||||||
|
|
||||||
impl PathHash {
|
|
||||||
fn joined(mut self, segment: impl AsRef<[u8]>) -> Self {
|
|
||||||
let segment = segment.as_ref();
|
|
||||||
self.0.update(u32::to_le_bytes(
|
|
||||||
segment.len().try_into().expect("path segment is too big"),
|
|
||||||
));
|
|
||||||
self.0.update(segment);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
last_inserted: HashMap<Interned<str>, usize>,
|
last_inserted: HashMap<Interned<str>, usize>,
|
||||||
path_hash: PathHash,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
@ -79,13 +61,6 @@ impl fmt::Display for VerilogIdentifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
fn new(path_hash: PathHash) -> Self {
|
|
||||||
Self {
|
|
||||||
last_inserted: Default::default(),
|
|
||||||
path_hash,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_identifier(&mut self, unescaped_name: Interned<str>) -> VerilogIdentifier {
|
fn new_identifier(&mut self, unescaped_name: Interned<str>) -> VerilogIdentifier {
|
||||||
let next_disambiguator = match self.last_inserted.entry(unescaped_name) {
|
let next_disambiguator = match self.last_inserted.entry(unescaped_name) {
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
|
|
@ -188,26 +163,6 @@ impl<W: io::Write> fmt::Debug for VcdWriterDecls<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pass in scope to ensure it's not available in child scope
|
|
||||||
fn try_write_vcd_scope<W: io::Write, R>(
|
|
||||||
writer: &mut W,
|
|
||||||
scope_type: &str,
|
|
||||||
scope_name: Interned<str>,
|
|
||||||
scope: Option<&mut Scope>,
|
|
||||||
f: impl FnOnce(&mut W, Option<&mut Scope>) -> io::Result<R>,
|
|
||||||
) -> io::Result<R> {
|
|
||||||
let Some(scope) = scope else {
|
|
||||||
return f(writer, None);
|
|
||||||
};
|
|
||||||
write_vcd_scope(
|
|
||||||
writer,
|
|
||||||
scope_type,
|
|
||||||
scope_name,
|
|
||||||
scope,
|
|
||||||
move |writer, scope| f(writer, Some(scope)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass in scope to ensure it's not available in child scope
|
/// pass in scope to ensure it's not available in child scope
|
||||||
fn write_vcd_scope<W: io::Write, R>(
|
fn write_vcd_scope<W: io::Write, R>(
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
|
|
@ -216,10 +171,12 @@ fn write_vcd_scope<W: io::Write, R>(
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
f: impl FnOnce(&mut W, &mut Scope) -> io::Result<R>,
|
f: impl FnOnce(&mut W, &mut Scope) -> io::Result<R>,
|
||||||
) -> io::Result<R> {
|
) -> io::Result<R> {
|
||||||
let path_hash = scope.path_hash.clone().joined(scope_name);
|
writeln!(
|
||||||
let scope_name = scope.new_identifier(scope_name);
|
writer,
|
||||||
writeln!(writer, "$scope {scope_type} {scope_name} $end")?;
|
"$scope {scope_type} {} $end",
|
||||||
let retval = f(writer, &mut Scope::new(path_hash))?;
|
scope.new_identifier(scope_name),
|
||||||
|
)?;
|
||||||
|
let retval = f(writer, &mut Scope::default())?;
|
||||||
writeln!(writer, "$upscope $end")?;
|
writeln!(writer, "$upscope $end")?;
|
||||||
Ok(retval)
|
Ok(retval)
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +216,6 @@ trait_arg! {
|
||||||
struct ArgModule<'a> {
|
struct ArgModule<'a> {
|
||||||
properties: &'a mut VcdWriterProperties,
|
properties: &'a mut VcdWriterProperties,
|
||||||
scope: &'a mut Scope,
|
scope: &'a mut Scope,
|
||||||
instance_name: Option<Interned<str>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArgModule<'a> {
|
impl<'a> ArgModule<'a> {
|
||||||
|
|
@ -267,7 +223,6 @@ impl<'a> ArgModule<'a> {
|
||||||
ArgModule {
|
ArgModule {
|
||||||
properties: self.properties,
|
properties: self.properties,
|
||||||
scope: self.scope,
|
scope: self.scope,
|
||||||
instance_name: self.instance_name,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +246,7 @@ struct ArgInType<'a> {
|
||||||
sink_var_type: &'static str,
|
sink_var_type: &'static str,
|
||||||
duplex_var_type: &'static str,
|
duplex_var_type: &'static str,
|
||||||
properties: &'a mut VcdWriterProperties,
|
properties: &'a mut VcdWriterProperties,
|
||||||
scope: Option<&'a mut Scope>,
|
scope: &'a mut Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArgInType<'a> {
|
impl<'a> ArgInType<'a> {
|
||||||
|
|
@ -301,7 +256,7 @@ impl<'a> ArgInType<'a> {
|
||||||
sink_var_type: self.sink_var_type,
|
sink_var_type: self.sink_var_type,
|
||||||
duplex_var_type: self.duplex_var_type,
|
duplex_var_type: self.duplex_var_type,
|
||||||
properties: self.properties,
|
properties: self.properties,
|
||||||
scope: self.scope.as_deref_mut(),
|
scope: self.scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -332,83 +287,23 @@ impl WriteTrace for TraceScalar {
|
||||||
Self::AsyncReset(v) => v.write_trace(writer, arg),
|
Self::AsyncReset(v) => v.write_trace(writer, arg),
|
||||||
Self::PhantomConst(v) => v.write_trace(writer, arg),
|
Self::PhantomConst(v) => v.write_trace(writer, arg),
|
||||||
Self::SimOnly(v) => v.write_trace(writer, arg),
|
Self::SimOnly(v) => v.write_trace(writer, arg),
|
||||||
Self::TraceAsString(v) => v.write_trace(writer, arg),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
fn write_vcd_id<W: io::Write>(writer: &mut W, mut id: usize) -> io::Result<()> {
|
||||||
#[repr(transparent)]
|
let min_char = b'!';
|
||||||
struct VcdId(NonZeroU64);
|
let max_char = b'~';
|
||||||
|
let base = (max_char - min_char + 1) as usize;
|
||||||
impl VcdId {
|
loop {
|
||||||
const CHAR_RANGE: std::ops::RangeInclusive<u8> = b'!'..=b'~';
|
let digit = (id % base) as u8 + min_char;
|
||||||
const BASE: u8 = *Self::CHAR_RANGE.end() - *Self::CHAR_RANGE.start() + 1;
|
id /= base;
|
||||||
const LOW_HALF_CHARS: u32 = 5;
|
writer.write_all(&[digit])?;
|
||||||
const LOW_HALF_MODULUS: u64 = (Self::BASE as u64).pow(Self::LOW_HALF_CHARS);
|
if id == 0 {
|
||||||
|
break;
|
||||||
const fn from_str(s: &str) -> Option<Self> {
|
|
||||||
if s.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
let mut retval = 0u64;
|
|
||||||
let mut bytes = s.as_bytes();
|
|
||||||
while let [ref rest @ .., digit] = *bytes {
|
|
||||||
bytes = rest;
|
|
||||||
let Some(digit) = digit.checked_sub(*Self::CHAR_RANGE.start()) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
if digit >= Self::BASE {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let Some(v) = retval.checked_mul(Self::BASE as _) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let Some(v) = v.checked_add(digit as _) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
retval = v;
|
|
||||||
}
|
|
||||||
let Some(retval) = NonZeroU64::new(retval) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Self(retval))
|
|
||||||
}
|
}
|
||||||
#[must_use]
|
Ok(())
|
||||||
const fn write(self, out: &mut [u8]) -> usize {
|
|
||||||
let mut id = self.0.get();
|
|
||||||
let mut len = 0;
|
|
||||||
loop {
|
|
||||||
let digit = (id % Self::BASE as u64) as u8 + *Self::CHAR_RANGE.start();
|
|
||||||
id /= Self::BASE as u64;
|
|
||||||
if len < out.len() {
|
|
||||||
out[len] = digit;
|
|
||||||
}
|
|
||||||
len += 1;
|
|
||||||
if id == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len
|
|
||||||
}
|
|
||||||
const MAX_ID_LEN: usize = Self(NonZeroU64::MAX).write(&mut []);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// check that VcdId properly round-trips
|
|
||||||
const _: () = {
|
|
||||||
let s = "RoundTrip";
|
|
||||||
let Some(id) = VcdId::from_str(s) else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
let mut buf = [0u8; VcdId::MAX_ID_LEN];
|
|
||||||
let len = id.write(&mut buf);
|
|
||||||
assert!(crate::util::const_bytes_cmp(buf.split_at(len).0, s.as_bytes()).is_eq());
|
|
||||||
};
|
|
||||||
|
|
||||||
fn write_vcd_id<W: io::Write>(writer: &mut W, id: VcdId) -> io::Result<()> {
|
|
||||||
let mut buf = [0u8; VcdId::MAX_ID_LEN];
|
|
||||||
let len = id.write(&mut buf);
|
|
||||||
writer.write_all(&buf[..len])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Escaped<T: fmt::Display>(T);
|
struct Escaped<T: fmt::Display>(T);
|
||||||
|
|
@ -451,13 +346,12 @@ impl<T: fmt::Display> fmt::Display for Escaped<T> {
|
||||||
|
|
||||||
fn write_vcd_var<W: io::Write>(
|
fn write_vcd_var<W: io::Write>(
|
||||||
properties: &mut VcdWriterProperties,
|
properties: &mut VcdWriterProperties,
|
||||||
scope: Option<&mut Scope>,
|
|
||||||
memory_element_part_body: MemoryElementPartBody,
|
memory_element_part_body: MemoryElementPartBody,
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
var_type: &str,
|
var_type: &str,
|
||||||
size: usize,
|
size: usize,
|
||||||
location: TraceLocation,
|
location: TraceLocation,
|
||||||
name: Interned<str>,
|
name: VerilogIdentifier,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let id = match location {
|
let id = match location {
|
||||||
TraceLocation::Scalar(id) => id.as_usize(),
|
TraceLocation::Scalar(id) => id.as_usize(),
|
||||||
|
|
@ -490,21 +384,9 @@ fn write_vcd_var<W: io::Write>(
|
||||||
first_id + *element_index
|
first_id + *element_index
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(scope) = scope {
|
write!(writer, "$var {var_type} {size} ")?;
|
||||||
let path_hash = scope.path_hash.clone().joined(name);
|
write_vcd_id(writer, id)?;
|
||||||
let name = scope.new_identifier(name);
|
writeln!(writer, " {name} $end")
|
||||||
let id = properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.builder_get_or_insert(id, &path_hash);
|
|
||||||
write!(writer, "$var {var_type} {size} ")?;
|
|
||||||
write_vcd_id(writer, id)?;
|
|
||||||
writeln!(writer, " {name} $end")
|
|
||||||
} else {
|
|
||||||
properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.builder_unused_scalar_id(id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteTrace for TraceUInt {
|
impl WriteTrace for TraceUInt {
|
||||||
|
|
@ -532,13 +414,12 @@ impl WriteTrace for TraceUInt {
|
||||||
}
|
}
|
||||||
write_vcd_var(
|
write_vcd_var(
|
||||||
properties,
|
properties,
|
||||||
scope,
|
|
||||||
MemoryElementPartBody::Scalar,
|
MemoryElementPartBody::Scalar,
|
||||||
writer,
|
writer,
|
||||||
var_type,
|
var_type,
|
||||||
ty.width(),
|
ty.width(),
|
||||||
location,
|
location,
|
||||||
name,
|
scope.new_identifier(name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -613,13 +494,12 @@ impl WriteTrace for TraceEnumDiscriminant {
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_var(
|
write_vcd_var(
|
||||||
properties,
|
properties,
|
||||||
scope,
|
|
||||||
MemoryElementPartBody::EnumDiscriminant { ty },
|
MemoryElementPartBody::EnumDiscriminant { ty },
|
||||||
writer,
|
writer,
|
||||||
"string",
|
"string",
|
||||||
1,
|
1,
|
||||||
location,
|
location,
|
||||||
name,
|
scope.new_identifier(name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -689,13 +569,12 @@ impl WriteTrace for TracePhantomConst {
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_var(
|
write_vcd_var(
|
||||||
properties,
|
properties,
|
||||||
scope,
|
|
||||||
MemoryElementPartBody::Scalar,
|
MemoryElementPartBody::Scalar,
|
||||||
writer,
|
writer,
|
||||||
"string",
|
"string",
|
||||||
1,
|
1,
|
||||||
location,
|
location,
|
||||||
name,
|
scope.new_identifier(name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -717,41 +596,12 @@ impl WriteTrace for TraceSimOnly {
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_var(
|
write_vcd_var(
|
||||||
properties,
|
properties,
|
||||||
scope,
|
|
||||||
MemoryElementPartBody::Scalar,
|
MemoryElementPartBody::Scalar,
|
||||||
writer,
|
writer,
|
||||||
"string",
|
"string",
|
||||||
1,
|
1,
|
||||||
location,
|
location,
|
||||||
name,
|
scope.new_identifier(name),
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WriteTrace for TraceTraceAsString {
|
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
|
||||||
let ArgInType {
|
|
||||||
source_var_type: _,
|
|
||||||
sink_var_type: _,
|
|
||||||
duplex_var_type: _,
|
|
||||||
properties,
|
|
||||||
scope,
|
|
||||||
} = arg.in_type();
|
|
||||||
let Self {
|
|
||||||
location,
|
|
||||||
name,
|
|
||||||
ty,
|
|
||||||
flow: _,
|
|
||||||
} = self;
|
|
||||||
write_vcd_var(
|
|
||||||
properties,
|
|
||||||
scope,
|
|
||||||
MemoryElementPartBody::TraceAsString { ty },
|
|
||||||
writer,
|
|
||||||
"string",
|
|
||||||
1,
|
|
||||||
location,
|
|
||||||
name,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -766,7 +616,6 @@ impl WriteTrace for TraceScope {
|
||||||
Self::Wire(v) => v.write_trace(writer, arg),
|
Self::Wire(v) => v.write_trace(writer, arg),
|
||||||
Self::Reg(v) => v.write_trace(writer, arg),
|
Self::Reg(v) => v.write_trace(writer, arg),
|
||||||
Self::ModuleIO(v) => v.write_trace(writer, arg),
|
Self::ModuleIO(v) => v.write_trace(writer, arg),
|
||||||
Self::FormalInput(v) => v.write_trace(writer, arg),
|
|
||||||
Self::Bundle(v) => v.write_trace(writer, arg),
|
Self::Bundle(v) => v.write_trace(writer, arg),
|
||||||
Self::Array(v) => v.write_trace(writer, arg),
|
Self::Array(v) => v.write_trace(writer, arg),
|
||||||
Self::EnumWithFields(v) => v.write_trace(writer, arg),
|
Self::EnumWithFields(v) => v.write_trace(writer, arg),
|
||||||
|
|
@ -776,24 +625,14 @@ impl WriteTrace for TraceScope {
|
||||||
|
|
||||||
impl WriteTrace for TraceModule {
|
impl WriteTrace for TraceModule {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModule {
|
let ArgModule { properties, scope } = arg.module();
|
||||||
properties,
|
|
||||||
scope,
|
|
||||||
instance_name,
|
|
||||||
} = arg.module();
|
|
||||||
let Self { name, children } = self;
|
let Self { name, children } = self;
|
||||||
write_vcd_scope(
|
write_vcd_scope(writer, "module", name, scope, |writer, scope| {
|
||||||
writer,
|
for child in children {
|
||||||
"module",
|
child.write_trace(writer, ArgModuleBody { properties, scope })?;
|
||||||
instance_name.unwrap_or(name),
|
}
|
||||||
scope,
|
Ok(())
|
||||||
|writer, scope| {
|
})
|
||||||
for child in children {
|
|
||||||
child.write_trace(writer, ArgModuleBody { properties, scope })?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -801,7 +640,7 @@ impl WriteTrace for TraceInstance {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties, scope } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name: _,
|
||||||
instance_io,
|
instance_io,
|
||||||
module,
|
module,
|
||||||
ty: _,
|
ty: _,
|
||||||
|
|
@ -813,17 +652,10 @@ impl WriteTrace for TraceInstance {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
scope: None,
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
module.write_trace(
|
module.write_trace(writer, ArgModule { properties, scope })
|
||||||
writer,
|
|
||||||
ArgModule {
|
|
||||||
properties,
|
|
||||||
scope,
|
|
||||||
instance_name: Some(name),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -862,7 +694,7 @@ impl WriteTrace for TraceMem {
|
||||||
sink_var_type: "reg",
|
sink_var_type: "reg",
|
||||||
duplex_var_type: "reg",
|
duplex_var_type: "reg",
|
||||||
properties,
|
properties,
|
||||||
scope: Some(scope),
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -894,7 +726,7 @@ impl WriteTrace for TraceMemPort {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
scope: Some(scope),
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -915,7 +747,7 @@ impl WriteTrace for TraceWire {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
scope: Some(scope),
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -936,7 +768,7 @@ impl WriteTrace for TraceReg {
|
||||||
sink_var_type: "reg",
|
sink_var_type: "reg",
|
||||||
duplex_var_type: "reg",
|
duplex_var_type: "reg",
|
||||||
properties,
|
properties,
|
||||||
scope: Some(scope),
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -958,28 +790,7 @@ impl WriteTrace for TraceModuleIO {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
scope: Some(scope),
|
scope,
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WriteTrace for TraceFormalInput {
|
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
|
||||||
let ArgModuleBody { properties, scope } = arg.module_body();
|
|
||||||
let Self {
|
|
||||||
name: _,
|
|
||||||
child,
|
|
||||||
formal_input: _,
|
|
||||||
} = self;
|
|
||||||
child.write_trace(
|
|
||||||
writer,
|
|
||||||
ArgInType {
|
|
||||||
source_var_type: "wire",
|
|
||||||
sink_var_type: "wire",
|
|
||||||
duplex_var_type: "wire",
|
|
||||||
properties,
|
|
||||||
scope: Some(scope),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1000,7 +811,7 @@ impl WriteTrace for TraceBundle {
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
try_write_vcd_scope(writer, "struct", name, scope, |writer, mut scope| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
field.write_trace(
|
field.write_trace(
|
||||||
writer,
|
writer,
|
||||||
|
|
@ -1009,7 +820,7 @@ impl WriteTrace for TraceBundle {
|
||||||
sink_var_type,
|
sink_var_type,
|
||||||
duplex_var_type,
|
duplex_var_type,
|
||||||
properties,
|
properties,
|
||||||
scope: scope.as_deref_mut(),
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1033,7 +844,7 @@ impl WriteTrace for TraceArray {
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
try_write_vcd_scope(writer, "struct", name, scope, |writer, mut scope| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
for element in elements {
|
for element in elements {
|
||||||
element.write_trace(
|
element.write_trace(
|
||||||
writer,
|
writer,
|
||||||
|
|
@ -1042,7 +853,7 @@ impl WriteTrace for TraceArray {
|
||||||
sink_var_type,
|
sink_var_type,
|
||||||
duplex_var_type,
|
duplex_var_type,
|
||||||
properties,
|
properties,
|
||||||
scope: scope.as_deref_mut(),
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1067,7 +878,7 @@ impl WriteTrace for TraceEnumWithFields {
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
try_write_vcd_scope(writer, "struct", name, scope, |writer, mut scope| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
discriminant.write_trace(
|
discriminant.write_trace(
|
||||||
writer,
|
writer,
|
||||||
ArgInType {
|
ArgInType {
|
||||||
|
|
@ -1075,7 +886,7 @@ impl WriteTrace for TraceEnumWithFields {
|
||||||
sink_var_type,
|
sink_var_type,
|
||||||
duplex_var_type,
|
duplex_var_type,
|
||||||
properties,
|
properties,
|
||||||
scope: scope.as_deref_mut(),
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
for field in non_empty_fields {
|
for field in non_empty_fields {
|
||||||
|
|
@ -1086,7 +897,7 @@ impl WriteTrace for TraceEnumWithFields {
|
||||||
sink_var_type,
|
sink_var_type,
|
||||||
duplex_var_type,
|
duplex_var_type,
|
||||||
properties,
|
properties,
|
||||||
scope: scope.as_deref_mut(),
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1112,9 +923,6 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
|
||||||
writeln!(writer, "$timescale {} $end", vcd_timescale(timescale))?;
|
writeln!(writer, "$timescale {} $end", vcd_timescale(timescale))?;
|
||||||
let mut properties = VcdWriterProperties {
|
let mut properties = VcdWriterProperties {
|
||||||
next_scalar_id: trace_scalar_id_count,
|
next_scalar_id: trace_scalar_id_count,
|
||||||
scalar_id_to_vcd_id_map: ScalarIdToVcdIdMapOrBuilder::Builder(
|
|
||||||
ScalarIdToVcdIdMapBuilder::default(),
|
|
||||||
),
|
|
||||||
memory_properties: (0..trace_memory_id_count)
|
memory_properties: (0..trace_memory_id_count)
|
||||||
.map(|_| MemoryProperties {
|
.map(|_| MemoryProperties {
|
||||||
element_parts: Vec::with_capacity(8),
|
element_parts: Vec::with_capacity(8),
|
||||||
|
|
@ -1127,17 +935,9 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
|
||||||
&mut writer,
|
&mut writer,
|
||||||
ArgModule {
|
ArgModule {
|
||||||
properties: &mut properties,
|
properties: &mut properties,
|
||||||
scope: &mut Scope::new(PathHash::default()),
|
scope: &mut Scope::default(),
|
||||||
instance_name: None,
|
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
let ScalarIdToVcdIdMapOrBuilder::Builder(scalar_id_to_vcd_id_map_builder) =
|
|
||||||
properties.scalar_id_to_vcd_id_map
|
|
||||||
else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
properties.scalar_id_to_vcd_id_map =
|
|
||||||
ScalarIdToVcdIdMapOrBuilder::Built(scalar_id_to_vcd_id_map_builder.build());
|
|
||||||
writeln!(writer, "$enddefinitions $end")?;
|
writeln!(writer, "$enddefinitions $end")?;
|
||||||
writeln!(writer, "$dumpvars")?;
|
writeln!(writer, "$dumpvars")?;
|
||||||
Ok(VcdWriter {
|
Ok(VcdWriter {
|
||||||
|
|
@ -1145,7 +945,6 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
|
||||||
finished_init: false,
|
finished_init: false,
|
||||||
timescale,
|
timescale,
|
||||||
properties,
|
properties,
|
||||||
trace_as_string_buf: String::with_capacity(256),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1153,7 +952,6 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
|
||||||
enum MemoryElementPartBody {
|
enum MemoryElementPartBody {
|
||||||
Scalar,
|
Scalar,
|
||||||
EnumDiscriminant { ty: Enum },
|
EnumDiscriminant { ty: Enum },
|
||||||
TraceAsString { ty: TraceAsString },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MemoryElementPart {
|
struct MemoryElementPart {
|
||||||
|
|
@ -1169,100 +967,8 @@ struct MemoryProperties {
|
||||||
element_index: usize,
|
element_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScalarIdToVcdIdMap {
|
|
||||||
scalar_id_to_vcd_id_map: Box<[Option<VcdId>]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct ScalarIdToVcdIdMapBuilder {
|
|
||||||
scalar_id_to_vcd_id_map: BTreeMap<usize, Option<VcdId>>,
|
|
||||||
lower_half_to_next_upper_half_map: HashMap<u64, u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScalarIdToVcdIdMapBuilder {
|
|
||||||
fn unused_scalar_id(&mut self, scalar_id: usize) {
|
|
||||||
self.scalar_id_to_vcd_id_map
|
|
||||||
.entry(scalar_id)
|
|
||||||
.or_insert(None);
|
|
||||||
}
|
|
||||||
/// `VcdId`s are based off of `path_hash` (and not `scalar_id`) since the hash doesn't change
|
|
||||||
/// when unrelated variables are added/removed, making the generated VCD more friendly for git diff.
|
|
||||||
fn get_or_insert(&mut self, scalar_id: usize, path_hash: &PathHash) -> VcdId {
|
|
||||||
*self
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.entry(scalar_id)
|
|
||||||
.or_insert(None)
|
|
||||||
.get_or_insert_with(|| {
|
|
||||||
let hash = u128::from_le_bytes(
|
|
||||||
*path_hash
|
|
||||||
.0
|
|
||||||
.clone()
|
|
||||||
.finalize()
|
|
||||||
.first_chunk()
|
|
||||||
.expect("known to be bigger than u128"),
|
|
||||||
);
|
|
||||||
let lower_half = (hash % VcdId::LOW_HALF_MODULUS as u128) as u64;
|
|
||||||
let next_upper_half = self
|
|
||||||
.lower_half_to_next_upper_half_map
|
|
||||||
.entry(lower_half)
|
|
||||||
.or_insert(if lower_half == 0 { 1 } else { 0 });
|
|
||||||
let upper_half = *next_upper_half;
|
|
||||||
*next_upper_half += 1;
|
|
||||||
let Some(id) = upper_half
|
|
||||||
.checked_mul(VcdId::LOW_HALF_MODULUS)
|
|
||||||
.and_then(|v| v.checked_add(lower_half))
|
|
||||||
else {
|
|
||||||
panic!("too many VcdIds");
|
|
||||||
};
|
|
||||||
VcdId(NonZeroU64::new(id).expect("known to not be zero"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn build(self) -> ScalarIdToVcdIdMap {
|
|
||||||
ScalarIdToVcdIdMap {
|
|
||||||
scalar_id_to_vcd_id_map: self
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, (scalar_id, vcd_id))| {
|
|
||||||
if index != scalar_id {
|
|
||||||
panic!("missing scalar id {index}");
|
|
||||||
}
|
|
||||||
vcd_id
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ScalarIdToVcdIdMapOrBuilder {
|
|
||||||
Builder(ScalarIdToVcdIdMapBuilder),
|
|
||||||
Built(ScalarIdToVcdIdMap),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScalarIdToVcdIdMapOrBuilder {
|
|
||||||
fn built_scalar_id_to_vcd_id(&self, scalar_id: usize) -> Option<VcdId> {
|
|
||||||
let Self::Built(v) = self else {
|
|
||||||
panic!("ScalarIdToVcdIdMap isn't built yet");
|
|
||||||
};
|
|
||||||
v.scalar_id_to_vcd_id_map[scalar_id]
|
|
||||||
}
|
|
||||||
fn builder_get_or_insert(&mut self, scalar_id: usize, path_hash: &PathHash) -> VcdId {
|
|
||||||
let Self::Builder(v) = self else {
|
|
||||||
panic!("ScalarIdToVcdIdMap is already built");
|
|
||||||
};
|
|
||||||
v.get_or_insert(scalar_id, path_hash)
|
|
||||||
}
|
|
||||||
fn builder_unused_scalar_id(&mut self, scalar_id: usize) {
|
|
||||||
let Self::Builder(v) = self else {
|
|
||||||
panic!("ScalarIdToVcdIdMap is already built");
|
|
||||||
};
|
|
||||||
v.unused_scalar_id(scalar_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VcdWriterProperties {
|
struct VcdWriterProperties {
|
||||||
next_scalar_id: usize,
|
next_scalar_id: usize,
|
||||||
scalar_id_to_vcd_id_map: ScalarIdToVcdIdMapOrBuilder,
|
|
||||||
memory_properties: Box<[MemoryProperties]>,
|
memory_properties: Box<[MemoryProperties]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1271,7 +977,6 @@ pub struct VcdWriter<W: io::Write + 'static> {
|
||||||
finished_init: bool,
|
finished_init: bool,
|
||||||
timescale: SimDuration,
|
timescale: SimDuration,
|
||||||
properties: VcdWriterProperties,
|
properties: VcdWriterProperties,
|
||||||
trace_as_string_buf: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: io::Write + 'static> VcdWriter<W> {
|
impl<W: io::Write + 'static> VcdWriter<W> {
|
||||||
|
|
@ -1283,11 +988,8 @@ impl<W: io::Write + 'static> VcdWriter<W> {
|
||||||
fn write_string_value_change(
|
fn write_string_value_change(
|
||||||
writer: &mut impl io::Write,
|
writer: &mut impl io::Write,
|
||||||
value: impl fmt::Display,
|
value: impl fmt::Display,
|
||||||
id: Option<VcdId>,
|
id: usize,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let Some(id) = id else {
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
write!(writer, "s{} ", Escaped(value))?;
|
write!(writer, "s{} ", Escaped(value))?;
|
||||||
write_vcd_id(writer, id)?;
|
write_vcd_id(writer, id)?;
|
||||||
writer.write_all(b"\n")
|
writer.write_all(b"\n")
|
||||||
|
|
@ -1296,11 +998,8 @@ fn write_string_value_change(
|
||||||
fn write_bits_value_change(
|
fn write_bits_value_change(
|
||||||
writer: &mut impl io::Write,
|
writer: &mut impl io::Write,
|
||||||
value: &BitSlice,
|
value: &BitSlice,
|
||||||
id: Option<VcdId>,
|
id: usize,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let Some(id) = id else {
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
match value.len() {
|
match value.len() {
|
||||||
0 => writer.write_all(b"s0 ")?,
|
0 => writer.write_all(b"s0 ")?,
|
||||||
1 => writer.write_all(if value[0] { b"1" } else { b"0" })?,
|
1 => writer.write_all(if value[0] { b"1" } else { b"0" })?,
|
||||||
|
|
@ -1329,7 +1028,7 @@ fn write_enum_discriminant_value_change(
|
||||||
writer: &mut impl io::Write,
|
writer: &mut impl io::Write,
|
||||||
variant_index: usize,
|
variant_index: usize,
|
||||||
ty: Enum,
|
ty: Enum,
|
||||||
id: Option<VcdId>,
|
id: usize,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
write_string_value_change(
|
write_string_value_change(
|
||||||
writer,
|
writer,
|
||||||
|
|
@ -1364,9 +1063,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
|
||||||
MemoryElementPartBody::Scalar => write_bits_value_change(
|
MemoryElementPartBody::Scalar => write_bits_value_change(
|
||||||
&mut self.writer,
|
&mut self.writer,
|
||||||
&element_data[start..start + len],
|
&element_data[start..start + len],
|
||||||
self.properties
|
first_id + element_index,
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(first_id + element_index),
|
|
||||||
)?,
|
)?,
|
||||||
MemoryElementPartBody::EnumDiscriminant { ty } => {
|
MemoryElementPartBody::EnumDiscriminant { ty } => {
|
||||||
let mut variant_index = 0;
|
let mut variant_index = 0;
|
||||||
|
|
@ -1376,49 +1073,20 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
|
||||||
&mut self.writer,
|
&mut self.writer,
|
||||||
variant_index,
|
variant_index,
|
||||||
*ty,
|
*ty,
|
||||||
self.properties
|
first_id + element_index,
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(first_id + element_index),
|
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
MemoryElementPartBody::TraceAsString { ty } => {
|
|
||||||
self.trace_as_string_buf.clear();
|
|
||||||
ty.trace_fmt_append_to_string(
|
|
||||||
&mut self.trace_as_string_buf,
|
|
||||||
OpaqueSimValueSlice::from_bitslice(&element_data[start..start + len]),
|
|
||||||
);
|
|
||||||
write_string_value_change(
|
|
||||||
&mut self.writer,
|
|
||||||
&self.trace_as_string_buf,
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(first_id + element_index),
|
|
||||||
)?;
|
|
||||||
self.trace_as_string_buf.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
|
fn set_signal_uint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
|
||||||
write_bits_value_change(
|
write_bits_value_change(&mut self.writer, value, id.as_usize())
|
||||||
&mut self.writer,
|
|
||||||
value,
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signal_sint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
|
fn set_signal_sint(&mut self, id: TraceScalarId, value: &BitSlice) -> Result<(), Self::Error> {
|
||||||
write_bits_value_change(
|
write_bits_value_change(&mut self.writer, value, id.as_usize())
|
||||||
&mut self.writer,
|
|
||||||
value,
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish_init(&mut self) -> Result<(), Self::Error> {
|
fn finish_init(&mut self) -> Result<(), Self::Error> {
|
||||||
|
|
@ -1450,14 +1118,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
|
||||||
variant_index: usize,
|
variant_index: usize,
|
||||||
ty: Enum,
|
ty: Enum,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
write_enum_discriminant_value_change(
|
write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize())
|
||||||
&mut self.writer,
|
|
||||||
variant_index,
|
|
||||||
ty,
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signal_phantom_const(
|
fn set_signal_phantom_const(
|
||||||
|
|
@ -1467,13 +1128,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
// avoid multi-line strings because GTKWave can't display them properly:
|
// avoid multi-line strings because GTKWave can't display them properly:
|
||||||
// https://github.com/gtkwave/gtkwave/issues/460
|
// https://github.com/gtkwave/gtkwave/issues/460
|
||||||
write_string_value_change(
|
write_string_value_change(&mut self.writer, format_args!("{ty:?}"), id.as_usize())
|
||||||
&mut self.writer,
|
|
||||||
format_args!("{ty:?}"),
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_signal_sim_only_value(
|
fn set_signal_sim_only_value(
|
||||||
|
|
@ -1481,23 +1136,7 @@ impl<W: io::Write> TraceWriter for VcdWriter<W> {
|
||||||
id: TraceScalarId,
|
id: TraceScalarId,
|
||||||
value: &DynSimOnlyValue,
|
value: &DynSimOnlyValue,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
write_string_value_change(
|
write_string_value_change(&mut self.writer, format_args!("{value:?}"), id.as_usize())
|
||||||
&mut self.writer,
|
|
||||||
format_args!("{value:?}"),
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_signal_string(&mut self, id: TraceScalarId, value: &str) -> Result<(), Self::Error> {
|
|
||||||
write_string_value_change(
|
|
||||||
&mut self.writer,
|
|
||||||
value,
|
|
||||||
self.properties
|
|
||||||
.scalar_id_to_vcd_id_map
|
|
||||||
.built_scalar_id_to_vcd_id(id.as_usize()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1508,7 +1147,6 @@ impl<W: io::Write> fmt::Debug for VcdWriter<W> {
|
||||||
finished_init,
|
finished_init,
|
||||||
timescale,
|
timescale,
|
||||||
properties: _,
|
properties: _,
|
||||||
trace_as_string_buf: _,
|
|
||||||
} = self;
|
} = self;
|
||||||
f.debug_struct("VcdWriter")
|
f.debug_struct("VcdWriter")
|
||||||
.field("finished_init", finished_init)
|
.field("finished_init", finished_init)
|
||||||
|
|
@ -1523,7 +1161,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope() {
|
fn test_scope() {
|
||||||
let mut scope = Scope::new(PathHash::default());
|
let mut scope = Scope::default();
|
||||||
assert_eq!(&*scope.new_identifier("foo".intern()).unescaped_name, "foo");
|
assert_eq!(&*scope.new_identifier("foo".intern()).unescaped_name, "foo");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&*scope.new_identifier("foo_0".intern()).unescaped_name,
|
&*scope.new_identifier("foo_0".intern()).unescaped_name,
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,11 @@ use crate::{
|
||||||
bundle::BundleType,
|
bundle::BundleType,
|
||||||
firrtl::ExportOptions,
|
firrtl::ExportOptions,
|
||||||
module::Module,
|
module::Module,
|
||||||
sim::{Simulation, vcd::VcdWriterDecls},
|
util::HashMap,
|
||||||
util::{HashMap, RcWriter},
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Write},
|
fmt::{self, Write},
|
||||||
panic::Location,
|
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
sync::{Mutex, OnceLock},
|
sync::{Mutex, OnceLock},
|
||||||
|
|
@ -224,190 +222,3 @@ pub fn assert_formal<M: AsRef<Module<T>>, T: BundleType>(
|
||||||
)
|
)
|
||||||
.expect("testing::assert_formal() failed");
|
.expect("testing::assert_formal() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CheckedVcdOutput {
|
|
||||||
writer: Option<RcWriter>,
|
|
||||||
expected_path: PathBuf,
|
|
||||||
expected_contents: Result<String, (Option<PathBuf>, std::io::Error)>,
|
|
||||||
location: &'static Location<'static>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CheckedVcdOutput {
|
|
||||||
#[must_use]
|
|
||||||
#[track_caller]
|
|
||||||
pub fn new<T: BundleType>(sim: &mut Simulation<T>, expected_path: PathBuf) -> Self {
|
|
||||||
let writer = RcWriter::default();
|
|
||||||
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
|
||||||
Self {
|
|
||||||
writer: Some(writer),
|
|
||||||
expected_contents: std::fs::read_to_string(&expected_path).map_err(|e| {
|
|
||||||
eprintln!(
|
|
||||||
"error: failed to read expected VCD from: {}",
|
|
||||||
expected_path.display(),
|
|
||||||
);
|
|
||||||
(std::env::current_dir().ok(), e)
|
|
||||||
}),
|
|
||||||
expected_path,
|
|
||||||
location: Location::caller(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[must_use]
|
|
||||||
#[track_caller]
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn __checked_vcd_output_macro_helper<T: BundleType>(
|
|
||||||
sim: &mut Simulation<T>,
|
|
||||||
cargo_manifest_dir: &'static str,
|
|
||||||
path: &'static str,
|
|
||||||
) -> Self {
|
|
||||||
Self::new(sim, Path::new(cargo_manifest_dir).join(path))
|
|
||||||
}
|
|
||||||
pub fn with_vcd_output<R>(&self, f: impl FnOnce(&str) -> R) -> R {
|
|
||||||
let Some(writer) = &self.writer else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
writer.clone().borrow(|output| {
|
|
||||||
let Ok(output) = str::from_utf8(output) else {
|
|
||||||
unreachable!("VcdWriter writes valid UTF-8");
|
|
||||||
};
|
|
||||||
f(output)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
#[track_caller]
|
|
||||||
pub fn finish(mut self) {
|
|
||||||
let Ok(()) = self.finish_impl(|msg| panic!("{msg}"));
|
|
||||||
}
|
|
||||||
fn finish_impl<E>(
|
|
||||||
&mut self,
|
|
||||||
error: impl FnOnce(std::fmt::Arguments<'_>) -> E,
|
|
||||||
) -> Result<(), E> {
|
|
||||||
let Self {
|
|
||||||
writer: Some(writer),
|
|
||||||
expected_path,
|
|
||||||
expected_contents,
|
|
||||||
location,
|
|
||||||
} = self
|
|
||||||
else {
|
|
||||||
// already finished
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
let Ok(vcd) = String::from_utf8(writer.take()) else {
|
|
||||||
unreachable!("VcdWriter writes valid UTF-8");
|
|
||||||
};
|
|
||||||
let expected_path_d = expected_path.display();
|
|
||||||
if expected_contents
|
|
||||||
.as_ref()
|
|
||||||
.is_ok_and(|expected_contents| *expected_contents == vcd)
|
|
||||||
{
|
|
||||||
// avoid written output from being split from threads interleaving writes to stdout
|
|
||||||
let _stdout = std::io::stderr().lock();
|
|
||||||
// use println to get output captured by tests
|
|
||||||
println!("\n{location}: generated VCD matches the expected VCD in {expected_path_d}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
// avoid written output from being split from threads interleaving writes to stderr
|
|
||||||
let _stderr = std::io::stderr().lock();
|
|
||||||
let error = |msg: std::fmt::Arguments<'_>| {
|
|
||||||
// print msg at both beginning and end so it's easier to find when the vcd is huge
|
|
||||||
Err(error(format_args!(
|
|
||||||
"\n{msg}####### VCD:\n{vcd}\n#######\n{msg}"
|
|
||||||
)))
|
|
||||||
};
|
|
||||||
let error = |msg: std::fmt::Arguments<'_>| match &*expected_contents {
|
|
||||||
Ok(_) => error(format_args!(
|
|
||||||
"{location}: generated VCD doesn't match the expected VCD in {expected_path_d}\n\
|
|
||||||
{msg}",
|
|
||||||
)),
|
|
||||||
Err((Some(current_dir), e)) => error(format_args!(
|
|
||||||
"{location}: generated VCD doesn't match the expected VCD in {expected_path_d}\n\
|
|
||||||
error: failed to read: {e}\n\
|
|
||||||
current dir: {current_dir}\n\
|
|
||||||
{msg}",
|
|
||||||
current_dir = current_dir.display(),
|
|
||||||
)),
|
|
||||||
Err((None, e)) => error(format_args!(
|
|
||||||
"{location}: generated VCD doesn't match the expected VCD in {expected_path_d}\n\
|
|
||||||
error: failed to read: {e}\n\
|
|
||||||
{msg}",
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
const OVERWRITE_VAR_NAME: &str = "OVERWRITE_EXPECTED_VCD";
|
|
||||||
const OVERWRITE_VAR_VALUE: &str = "overwrite";
|
|
||||||
match std::env::var_os(OVERWRITE_VAR_NAME) {
|
|
||||||
Some(v) if v == OVERWRITE_VAR_VALUE => match std::fs::write(&expected_path, &vcd) {
|
|
||||||
Ok(()) => error(format_args!(
|
|
||||||
"warning: since `{OVERWRITE_VAR_NAME}={OVERWRITE_VAR_VALUE}` is set -- writing the generated VCD to {expected_path_d}\n"
|
|
||||||
)),
|
|
||||||
Err(e) => error(format_args!(
|
|
||||||
"error: since `{OVERWRITE_VAR_NAME}={OVERWRITE_VAR_VALUE}` is set -- tried to write the generated VCD to {expected_path_d}\n\
|
|
||||||
error: failed to write: {e}"
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
_ => error(format_args!(
|
|
||||||
"note: rerun the test with the environment variable `{OVERWRITE_VAR_NAME}={OVERWRITE_VAR_VALUE}`\n\
|
|
||||||
to update the expected output to match the generated output.\n"
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for CheckedVcdOutput {
|
|
||||||
#[track_caller]
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let _ = self.finish_impl(|msg| {
|
|
||||||
if std::thread::panicking() {
|
|
||||||
eprintln!("{msg}"); // use eprintln to get output captured by tests
|
|
||||||
} else {
|
|
||||||
panic!("{msg}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
/// Use in tests to check that [`Simulation`] generates the expected VCD traces, by comparing to a `.vcd` file containing the expected traces.
|
|
||||||
///
|
|
||||||
/// Use like so:
|
|
||||||
/// ```
|
|
||||||
/// # use fayalite::prelude::*;
|
|
||||||
/// #
|
|
||||||
/// # #[hdl_module]
|
|
||||||
/// # fn my_module() {
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # let a: UInt<8> = m.input();
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # let b: UInt<8> = m.output();
|
|
||||||
/// # connect(b, 0u8);
|
|
||||||
/// # #[hdl]
|
|
||||||
/// # if a.cmp_eq(100u8) {
|
|
||||||
/// # connect(b, 42u8);
|
|
||||||
/// # }
|
|
||||||
/// # }
|
|
||||||
/// // inside your #[test] fn my_test():
|
|
||||||
///
|
|
||||||
/// // get the module to simulate:
|
|
||||||
/// let m = my_module();
|
|
||||||
/// // create a simulation of the module:
|
|
||||||
/// let mut sim = Simulation::new(m);
|
|
||||||
/// // set up the expected VCD traces, the given .vcd path is relative to env!("CARGO_MANIFEST_DIR")
|
|
||||||
/// let _checked_vcd_output = checked_vcd_output!(
|
|
||||||
/// &mut sim,
|
|
||||||
/// "tests/expected/my_test.vcd",
|
|
||||||
/// );
|
|
||||||
/// // now run the simulation like normal:
|
|
||||||
/// sim.write(sim.io().a, 0u8);
|
|
||||||
/// assert_eq!(sim.read(sim.io().b).as_int(), 0);
|
|
||||||
/// sim.advance_time(SimDuration::from_micros(1));
|
|
||||||
/// sim.write(sim.io().a, 100u8);
|
|
||||||
/// assert_eq!(sim.read(sim.io().b).as_int(), 42);
|
|
||||||
/// ```
|
|
||||||
macro_rules! checked_vcd_output {
|
|
||||||
($sim:expr, $path_relative_to_manifest_dir:expr $(,)?) => {
|
|
||||||
$crate::testing::CheckedVcdOutput::__checked_vcd_output_macro_helper(
|
|
||||||
$sim,
|
|
||||||
$crate::__std::env!("CARGO_MANIFEST_DIR"),
|
|
||||||
$crate::__std::concat!($path_relative_to_manifest_dir),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use checked_vcd_output;
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -12,8 +12,7 @@ use crate::{
|
||||||
prelude::PhantomConst,
|
prelude::PhantomConst,
|
||||||
reset::{AsyncReset, Reset, SyncReset},
|
reset::{AsyncReset, Reset, SyncReset},
|
||||||
sim::value::DynSimOnly,
|
sim::value::DynSimOnly,
|
||||||
ty::{BaseType, CanonicalType, TraceAsString, TraceAsStringTrait},
|
ty::{BaseType, CanonicalType},
|
||||||
util::serde_by_id::SerdeById,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
|
@ -39,7 +38,6 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for SerdePhantomConst<
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(rename = "CanonicalType")]
|
#[serde(rename = "CanonicalType")]
|
||||||
#[expect(private_interfaces)]
|
|
||||||
pub(crate) enum SerdeCanonicalType<
|
pub(crate) enum SerdeCanonicalType<
|
||||||
ArrayElement = CanonicalType,
|
ArrayElement = CanonicalType,
|
||||||
ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>,
|
ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>,
|
||||||
|
|
@ -67,10 +65,6 @@ pub(crate) enum SerdeCanonicalType<
|
||||||
Clock,
|
Clock,
|
||||||
PhantomConst(ThePhantomConst),
|
PhantomConst(ThePhantomConst),
|
||||||
DynSimOnly(DynSimOnly),
|
DynSimOnly(DynSimOnly),
|
||||||
TraceAsString {
|
|
||||||
inner_ty: Interned<CanonicalType>,
|
|
||||||
trace_as_string: SerdeById<Interned<dyn TraceAsStringTrait>>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ArrayElement, PhantomConstInner> SerdeCanonicalType<ArrayElement, PhantomConstInner> {
|
impl<ArrayElement, PhantomConstInner> SerdeCanonicalType<ArrayElement, PhantomConstInner> {
|
||||||
|
|
@ -88,7 +82,6 @@ impl<ArrayElement, PhantomConstInner> SerdeCanonicalType<ArrayElement, PhantomCo
|
||||||
Self::Clock => "a Clock",
|
Self::Clock => "a Clock",
|
||||||
Self::PhantomConst(_) => "a PhantomConst",
|
Self::PhantomConst(_) => "a PhantomConst",
|
||||||
Self::DynSimOnly(_) => "a SimOnlyValue",
|
Self::DynSimOnly(_) => "a SimOnlyValue",
|
||||||
Self::TraceAsString { .. } => "a TraceAsString",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,15 +109,6 @@ impl<T: BaseType> From<T> for SerdeCanonicalType {
|
||||||
CanonicalType::Clock(Clock {}) => Self::Clock,
|
CanonicalType::Clock(Clock {}) => Self::Clock,
|
||||||
CanonicalType::PhantomConst(ty) => Self::PhantomConst(SerdePhantomConst(ty.get())),
|
CanonicalType::PhantomConst(ty) => Self::PhantomConst(SerdePhantomConst(ty.get())),
|
||||||
CanonicalType::DynSimOnly(ty) => Self::DynSimOnly(ty),
|
CanonicalType::DynSimOnly(ty) => Self::DynSimOnly(ty),
|
||||||
CanonicalType::TraceAsString(TraceAsString {
|
|
||||||
inner_ty,
|
|
||||||
trace_as_string,
|
|
||||||
}) => Self::TraceAsString {
|
|
||||||
inner_ty: inner_ty.interned(),
|
|
||||||
trace_as_string: SerdeById {
|
|
||||||
inner: trace_as_string.interned(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,13 +130,6 @@ impl From<SerdeCanonicalType> for CanonicalType {
|
||||||
Self::PhantomConst(PhantomConst::new_interned(value.0))
|
Self::PhantomConst(PhantomConst::new_interned(value.0))
|
||||||
}
|
}
|
||||||
SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value),
|
SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value),
|
||||||
SerdeCanonicalType::TraceAsString {
|
|
||||||
inner_ty,
|
|
||||||
trace_as_string,
|
|
||||||
} => Self::TraceAsString(TraceAsString {
|
|
||||||
inner_ty: crate::intern::LazyInterned::Interned(inner_ty),
|
|
||||||
trace_as_string: crate::intern::LazyInterned::Interned(trace_as_string.inner),
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,8 @@ pub use misc::{
|
||||||
os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty,
|
os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty,
|
||||||
serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range,
|
serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range,
|
||||||
};
|
};
|
||||||
pub(crate) use misc::{InternedStrCompareAsStr, chain, copy_le_bytes_to_bitslice};
|
pub(crate) use misc::{InternedStrCompareAsStr, chain};
|
||||||
|
|
||||||
pub mod job_server;
|
pub mod job_server;
|
||||||
pub mod prefix_sum;
|
pub mod prefix_sum;
|
||||||
pub mod ready_valid;
|
pub mod ready_valid;
|
||||||
pub(crate) mod serde_by_id;
|
|
||||||
|
|
|
||||||
|
|
@ -612,43 +612,3 @@ impl std::borrow::Borrow<str> for InternedStrCompareAsStr {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn copy_le_bytes_to_bitslice(
|
|
||||||
dest: &mut BitSlice<usize, Lsb0>,
|
|
||||||
bytes: &[u8],
|
|
||||||
msb_fill: bool,
|
|
||||||
) {
|
|
||||||
let (chunks, remainder) = bytes.as_chunks();
|
|
||||||
let mut filled_to = 0;
|
|
||||||
for (i, chunk) in chunks.iter().enumerate() {
|
|
||||||
if let Some(start_bit_index) = i.checked_mul(usize::BITS as usize)
|
|
||||||
&& start_bit_index < dest.len()
|
|
||||||
{
|
|
||||||
let end_bit_index = start_bit_index
|
|
||||||
.saturating_add(usize::BITS as usize)
|
|
||||||
.min(dest.len());
|
|
||||||
let bit_len = end_bit_index - start_bit_index;
|
|
||||||
let chunk = usize::from_le_bytes(*chunk);
|
|
||||||
dest[start_bit_index..end_bit_index].copy_from_bitslice(&chunk.view_bits()[..bit_len]);
|
|
||||||
filled_to = end_bit_index;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !remainder.is_empty() {
|
|
||||||
if let Some(start_bit_index) = chunks.len().checked_mul(usize::BITS as usize)
|
|
||||||
&& start_bit_index < dest.len()
|
|
||||||
{
|
|
||||||
let end_bit_index = start_bit_index
|
|
||||||
.saturating_add(usize::BITS as usize)
|
|
||||||
.min(dest.len());
|
|
||||||
let bit_len = end_bit_index - start_bit_index;
|
|
||||||
let mut chunk = [if msb_fill { !0 } else { 0 }; _];
|
|
||||||
chunk[..remainder.len()].copy_from_slice(remainder);
|
|
||||||
let chunk = usize::from_le_bytes(chunk);
|
|
||||||
dest[start_bit_index..end_bit_index].copy_from_bitslice(&chunk.view_bits()[..bit_len]);
|
|
||||||
filled_to = end_bit_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dest[filled_to..].fill(msb_fill);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -241,13 +241,15 @@ mod tests {
|
||||||
/// happens to be in phase with the offending input or output).
|
/// happens to be in phase with the offending input or output).
|
||||||
#[hdl_module]
|
#[hdl_module]
|
||||||
fn queue_test(capacity: NonZeroUsize, inp_ready_is_comb: bool, out_valid_is_comb: bool) {
|
fn queue_test(capacity: NonZeroUsize, inp_ready_is_comb: bool, out_valid_is_comb: bool) {
|
||||||
|
#[hdl]
|
||||||
|
let clk: Clock = m.input();
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let cd = wire();
|
let cd = wire();
|
||||||
connect(
|
connect(
|
||||||
cd,
|
cd,
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ClockDomain {
|
ClockDomain {
|
||||||
clk: formal_global_clock(),
|
clk,
|
||||||
rst: formal_reset().to_reset(),
|
rst: formal_reset().to_reset(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -278,7 +280,7 @@ mod tests {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let index_to_check = wire(index_ty);
|
let index_to_check = wire(index_ty);
|
||||||
connect(index_to_check, any_const(index_ty));
|
connect(index_to_check, any_const(index_ty));
|
||||||
hdl_assume(cd.clk, index_to_check.cmp_lt(capacity.get()), "");
|
hdl_assume(clk, index_to_check.cmp_lt(capacity.get()), "");
|
||||||
|
|
||||||
// instantiate and connect the queue
|
// instantiate and connect the queue
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -298,13 +300,13 @@ mod tests {
|
||||||
let expected_count_reg = reg_builder().clock_domain(cd).reset(count_ty.zero());
|
let expected_count_reg = reg_builder().clock_domain(cd).reset(count_ty.zero());
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if ReadyValid::firing(dut.inp) & !ReadyValid::firing(dut.out) {
|
if ReadyValid::firing(dut.inp) & !ReadyValid::firing(dut.out) {
|
||||||
hdl_assert(cd.clk, expected_count_reg.cmp_ne(capacity.get()), "");
|
hdl_assert(clk, expected_count_reg.cmp_ne(capacity.get()), "");
|
||||||
connect_any(expected_count_reg, expected_count_reg + 1u8);
|
connect_any(expected_count_reg, expected_count_reg + 1u8);
|
||||||
} else if !ReadyValid::firing(dut.inp) & ReadyValid::firing(dut.out) {
|
} else if !ReadyValid::firing(dut.inp) & ReadyValid::firing(dut.out) {
|
||||||
hdl_assert(cd.clk, expected_count_reg.cmp_ne(count_ty.zero()), "");
|
hdl_assert(clk, expected_count_reg.cmp_ne(count_ty.zero()), "");
|
||||||
connect_any(expected_count_reg, expected_count_reg - 1u8);
|
connect_any(expected_count_reg, expected_count_reg - 1u8);
|
||||||
}
|
}
|
||||||
hdl_assert(cd.clk, expected_count_reg.cmp_eq(dut.count), "");
|
hdl_assert(clk, expected_count_reg.cmp_eq(dut.count), "");
|
||||||
|
|
||||||
// keep an independent write index into the FIFO's circular buffer
|
// keep an independent write index into the FIFO's circular buffer
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -372,7 +374,7 @@ mod tests {
|
||||||
match inp_firing_data {
|
match inp_firing_data {
|
||||||
// ... and we are not receiving data, then we must not
|
// ... and we are not receiving data, then we must not
|
||||||
// transmit any data.
|
// transmit any data.
|
||||||
HdlNone => hdl_assert(cd.clk, HdlOption::is_none(out_firing_data), ""),
|
HdlNone => hdl_assert(clk, HdlOption::is_none(out_firing_data), ""),
|
||||||
// If we are indeed receiving some data...
|
// If we are indeed receiving some data...
|
||||||
HdlSome(data_in) => {
|
HdlSome(data_in) => {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -380,9 +382,7 @@ mod tests {
|
||||||
// ... and transmitting at the same time, we
|
// ... and transmitting at the same time, we
|
||||||
// must be transmitting the input data itself,
|
// must be transmitting the input data itself,
|
||||||
// since the holding register is empty.
|
// since the holding register is empty.
|
||||||
HdlSome(data_out) => {
|
HdlSome(data_out) => hdl_assert(clk, data_out.cmp_eq(data_in), ""),
|
||||||
hdl_assert(cd.clk, data_out.cmp_eq(data_in), "")
|
|
||||||
}
|
|
||||||
// If we are receiving, but not transmitting,
|
// If we are receiving, but not transmitting,
|
||||||
// store the received data in the holding
|
// store the received data in the holding
|
||||||
// register.
|
// register.
|
||||||
|
|
@ -397,11 +397,11 @@ mod tests {
|
||||||
match out_firing_data {
|
match out_firing_data {
|
||||||
// ... and we are not transmitting it, we cannot
|
// ... and we are not transmitting it, we cannot
|
||||||
// receive any more data.
|
// receive any more data.
|
||||||
HdlNone => hdl_assert(cd.clk, HdlOption::is_none(inp_firing_data), ""),
|
HdlNone => hdl_assert(clk, HdlOption::is_none(inp_firing_data), ""),
|
||||||
// If we are transmitting a previously stored value...
|
// If we are transmitting a previously stored value...
|
||||||
HdlSome(data_out) => {
|
HdlSome(data_out) => {
|
||||||
// ... it must be the same data we stored earlier.
|
// ... it must be the same data we stored earlier.
|
||||||
hdl_assert(cd.clk, data_out.cmp_eq(stored), "");
|
hdl_assert(clk, data_out.cmp_eq(stored), "");
|
||||||
// Also, accept new data, if any. Otherwise,
|
// Also, accept new data, if any. Otherwise,
|
||||||
// let the holding register become empty.
|
// let the holding register become empty.
|
||||||
connect(stored_reg, inp_firing_data);
|
connect(stored_reg, inp_firing_data);
|
||||||
|
|
@ -417,17 +417,17 @@ mod tests {
|
||||||
connect(dut.dbg.index_to_check, index_to_check);
|
connect(dut.dbg.index_to_check, index_to_check);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if let HdlSome(stored) = stored_reg {
|
if let HdlSome(stored) = stored_reg {
|
||||||
hdl_assert(cd.clk, stored.cmp_eq(dut.dbg.stored), "");
|
hdl_assert(clk, stored.cmp_eq(dut.dbg.stored), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync the read and write indices
|
// sync the read and write indices
|
||||||
hdl_assert(cd.clk, inp_index_reg.cmp_eq(dut.dbg.inp_index), "");
|
hdl_assert(clk, inp_index_reg.cmp_eq(dut.dbg.inp_index), "");
|
||||||
hdl_assert(cd.clk, out_index_reg.cmp_eq(dut.dbg.out_index), "");
|
hdl_assert(clk, out_index_reg.cmp_eq(dut.dbg.out_index), "");
|
||||||
|
|
||||||
// the indices should never go past the capacity, but induction
|
// the indices should never go past the capacity, but induction
|
||||||
// doesn't know that...
|
// doesn't know that...
|
||||||
hdl_assert(cd.clk, inp_index_reg.cmp_lt(capacity.get()), "");
|
hdl_assert(clk, inp_index_reg.cmp_lt(capacity.get()), "");
|
||||||
hdl_assert(cd.clk, out_index_reg.cmp_lt(capacity.get()), "");
|
hdl_assert(clk, out_index_reg.cmp_lt(capacity.get()), "");
|
||||||
|
|
||||||
// strongly constrain the state of the holding register
|
// strongly constrain the state of the holding register
|
||||||
//
|
//
|
||||||
|
|
@ -455,7 +455,7 @@ mod tests {
|
||||||
connect(expected_stored, pending_reads.cmp_lt(dut.count));
|
connect(expected_stored, pending_reads.cmp_lt(dut.count));
|
||||||
// sync with the state of the holding register
|
// sync with the state of the holding register
|
||||||
hdl_assert(
|
hdl_assert(
|
||||||
cd.clk,
|
clk,
|
||||||
expected_stored.cmp_eq(HdlOption::is_some(stored_reg)),
|
expected_stored.cmp_eq(HdlOption::is_some(stored_reg)),
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
// See Notices.txt for copyright information
|
|
||||||
|
|
||||||
use crate::util::HashMap;
|
|
||||||
use hashbrown::hash_map::Entry;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error};
|
|
||||||
use std::{
|
|
||||||
any::TypeId,
|
|
||||||
borrow::Cow,
|
|
||||||
fmt::Write,
|
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
|
||||||
marker::PhantomData,
|
|
||||||
sync::Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) struct SerdeByIdProperties<T: SerdeByIdTrait> {
|
|
||||||
type_id: TypeId,
|
|
||||||
type_name: &'static str,
|
|
||||||
_phantom: PhantomData<fn(T) -> T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> Clone for SerdeByIdProperties<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> Copy for SerdeByIdProperties<T> {}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> SerdeByIdProperties<T> {
|
|
||||||
pub fn of<U: ?Sized + 'static>() -> Self {
|
|
||||||
Self {
|
|
||||||
type_id: TypeId::of::<U>(),
|
|
||||||
type_name: std::any::type_name::<U>(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) trait SerdeByIdTrait: Hash + Eq + Clone + 'static + Send {
|
|
||||||
fn serde_by_id_properties(&self) -> SerdeByIdProperties<Self>;
|
|
||||||
fn static_table() -> &'static SerdeByIdTable<Self>;
|
|
||||||
const NAME: &'static str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(transparent)]
|
|
||||||
struct SerdeRandomId([u32; 4]);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub(crate) struct SerdeId<'a, T: SerdeByIdTrait> {
|
|
||||||
random_id: SerdeRandomId,
|
|
||||||
#[serde(borrow)]
|
|
||||||
type_name: Cow<'a, str>,
|
|
||||||
#[serde(skip)]
|
|
||||||
_phantom: PhantomData<fn(T) -> T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: SerdeByIdTrait> Clone for SerdeId<'a, T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
random_id: self.random_id,
|
|
||||||
type_name: self.type_name.clone(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: SerdeByIdTrait> Eq for SerdeId<'a, T> {}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: SerdeByIdTrait> PartialEq<SerdeId<'b, T>> for SerdeId<'a, T> {
|
|
||||||
fn eq(&self, other: &SerdeId<'b, T>) -> bool {
|
|
||||||
let Self {
|
|
||||||
random_id,
|
|
||||||
type_name,
|
|
||||||
_phantom: _,
|
|
||||||
} = self;
|
|
||||||
*random_id == other.random_id && *type_name == other.type_name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: SerdeByIdTrait> Hash for SerdeId<'a, T> {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
let Self {
|
|
||||||
random_id,
|
|
||||||
type_name: _,
|
|
||||||
_phantom: _,
|
|
||||||
} = self;
|
|
||||||
random_id.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SerdeByIdTableRest<T: SerdeByIdTrait> {
|
|
||||||
from_serde: HashMap<SerdeId<'static, T>, T>,
|
|
||||||
serde_id_random_state: std::hash::RandomState,
|
|
||||||
buffer: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> Default for SerdeByIdTableRest<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
from_serde: Default::default(),
|
|
||||||
serde_id_random_state: Default::default(),
|
|
||||||
buffer: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> SerdeByIdTableRest<T> {
|
|
||||||
fn add_new(&mut self, value: T) -> SerdeId<'static, T> {
|
|
||||||
let properties = value.serde_by_id_properties();
|
|
||||||
let mut try_number = 0u64;
|
|
||||||
let mut hasher = self.serde_id_random_state.build_hasher();
|
|
||||||
// extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits
|
|
||||||
write!(self.buffer, "{:?}", properties.type_id).expect("shouldn't ever fail");
|
|
||||||
self.buffer.hash(&mut hasher);
|
|
||||||
loop {
|
|
||||||
let mut hasher = hasher.clone();
|
|
||||||
try_number.hash(&mut hasher);
|
|
||||||
try_number += 1;
|
|
||||||
let key = SerdeId {
|
|
||||||
random_id: SerdeRandomId(std::array::from_fn(|i| {
|
|
||||||
let mut hasher = hasher.clone();
|
|
||||||
i.hash(&mut hasher);
|
|
||||||
hasher.finish() as u32
|
|
||||||
})),
|
|
||||||
type_name: Cow::Borrowed(properties.type_name),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
};
|
|
||||||
match self.from_serde.entry(key) {
|
|
||||||
Entry::Occupied(_) => continue,
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
let key = e.key().clone();
|
|
||||||
e.insert(value);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct SerdeByIdTableMut<T: SerdeByIdTrait> {
|
|
||||||
to_serde: HashMap<T, SerdeId<'static, T>>,
|
|
||||||
rest: SerdeByIdTableRest<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> Default for SerdeByIdTableMut<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
to_serde: Default::default(),
|
|
||||||
rest: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> SerdeByIdTableMut<T> {
|
|
||||||
pub(crate) fn to_serde(&mut self, value: &T) -> SerdeId<'static, T> {
|
|
||||||
if let Some(retval) = self.to_serde.get(value) {
|
|
||||||
return retval.clone();
|
|
||||||
}
|
|
||||||
self.to_serde_insert(value)
|
|
||||||
}
|
|
||||||
#[cold]
|
|
||||||
fn to_serde_insert(&mut self, value: &T) -> SerdeId<'static, T> {
|
|
||||||
let value = value.clone();
|
|
||||||
let retval = self.rest.add_new(value.clone());
|
|
||||||
self.to_serde.insert(value, retval.clone());
|
|
||||||
retval
|
|
||||||
}
|
|
||||||
pub(crate) fn from_serde(&self, id: &SerdeId<'_, T>) -> Option<T> {
|
|
||||||
self.rest.from_serde.get(id).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct SerdeByIdTable<T: SerdeByIdTrait>(Mutex<Option<SerdeByIdTableMut<T>>>);
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> SerdeByIdTable<T> {
|
|
||||||
pub(crate) const fn new() -> Self {
|
|
||||||
Self(Mutex::new(None))
|
|
||||||
}
|
|
||||||
pub(crate) fn to_serde(&self, value: &T) -> SerdeId<'static, T> {
|
|
||||||
self.0
|
|
||||||
.lock()
|
|
||||||
.expect("shouldn't be poison")
|
|
||||||
.get_or_insert_with(
|
|
||||||
#[cold]
|
|
||||||
|| Default::default(),
|
|
||||||
)
|
|
||||||
.to_serde(value)
|
|
||||||
}
|
|
||||||
pub(crate) fn from_serde(&self, id: &SerdeId<'_, T>) -> Option<T> {
|
|
||||||
self.0
|
|
||||||
.lock()
|
|
||||||
.expect("shouldn't be poison")
|
|
||||||
.get_or_insert_with(
|
|
||||||
#[cold]
|
|
||||||
|| Default::default(),
|
|
||||||
)
|
|
||||||
.from_serde(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default, Ord, PartialOrd)]
|
|
||||||
pub(crate) struct SerdeById<T: SerdeByIdTrait> {
|
|
||||||
pub(crate) inner: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, T: SerdeByIdTrait> Deserialize<'de> for SerdeById<T> {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let id = SerdeId::deserialize(deserializer)?;
|
|
||||||
let inner = T::static_table().from_serde(&id).ok_or_else(|| {
|
|
||||||
D::Error::custom(format_args!(
|
|
||||||
"doesn't match any {} that was serialized this time this program was run: type_name={:?}",
|
|
||||||
T::NAME,
|
|
||||||
id.type_name,
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Self { inner })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SerdeByIdTrait> Serialize for SerdeById<T> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
T::static_table()
|
|
||||||
.to_serde(&self.inner)
|
|
||||||
.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
pub mod xilinx;
|
pub mod xilinx;
|
||||||
|
pub mod lattice;
|
||||||
|
|
||||||
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||||
xilinx::built_in_job_kinds()
|
xilinx::built_in_job_kinds();
|
||||||
|
lattice::built_in_job_kinds()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||||
xilinx::built_in_platforms()
|
xilinx::built_in_platforms();
|
||||||
|
lattice::built_in_platforms()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
187
crates/fayalite/src/vendor/lattice.rs
vendored
Normal file
187
crates/fayalite/src/vendor/lattice.rs
vendored
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
annotations::make_annotation_enum,
|
||||||
|
build::{GlobalParams, ToArgs, WriteArgs},
|
||||||
|
intern::Interned,
|
||||||
|
prelude::{DynPlatform, Platform},
|
||||||
|
};
|
||||||
|
use clap::ValueEnum;
|
||||||
|
use ordered_float::NotNan;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub mod orangecrab;
|
||||||
|
pub mod primitives;
|
||||||
|
pub mod yosys_nextpnr;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct LatticeArgs {
|
||||||
|
#[arg(long)]
|
||||||
|
pub device: Option<Device>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LatticeArgs {
|
||||||
|
pub fn require_device(
|
||||||
|
&self,
|
||||||
|
platform: Option<&DynPlatform>,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> clap::error::Result<Device> {
|
||||||
|
if let Some(device) = self.device {
|
||||||
|
return Ok(device);
|
||||||
|
}
|
||||||
|
if let Some(device) =
|
||||||
|
platform.and_then(|platform| platform.aspects().get_single_by_type::<Device>().copied())
|
||||||
|
{
|
||||||
|
return Ok(device);
|
||||||
|
}
|
||||||
|
Err(global_params.clap_error(
|
||||||
|
clap::error::ErrorKind::MissingRequiredArgument,
|
||||||
|
"missing --device option",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToArgs for LatticeArgs {
|
||||||
|
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
if let Some(device) = self.device {
|
||||||
|
args.write_long_option_eq("device", device.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! make_device_enum {
|
||||||
|
($vis:vis enum $Device:ident {
|
||||||
|
$(
|
||||||
|
#[
|
||||||
|
name = $name:literal,
|
||||||
|
lattice_part = $lattice_part:literal,
|
||||||
|
lattice_device = $lattice_device:literal,
|
||||||
|
lattice_family = $lattice_family:literal,
|
||||||
|
]
|
||||||
|
$variant:ident,
|
||||||
|
)*
|
||||||
|
}) => {
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)]
|
||||||
|
$vis enum $Device {
|
||||||
|
$(
|
||||||
|
#[value(name = $name, alias = $lattice_part)]
|
||||||
|
$variant,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $Device {
|
||||||
|
$vis fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(Self::$variant => $name,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$vis fn lattice_part(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(Self::$variant => $lattice_part,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$vis fn lattice_device(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(Self::$variant => $lattice_device,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$vis fn lattice_family(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(Self::$variant => $lattice_family,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeviceVisitor;
|
||||||
|
|
||||||
|
impl<'de> serde::de::Visitor<'de> for DeviceVisitor {
|
||||||
|
type Value = $Device;
|
||||||
|
|
||||||
|
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str("a Lattice device string")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
match $Device::from_str(v, false) {
|
||||||
|
Ok(v) => Ok(v),
|
||||||
|
Err(_) => Err(E::invalid_value(serde::de::Unexpected::Str(v), &self)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
match str::from_utf8(v).ok().and_then(|v| $Device::from_str(v, false).ok()) {
|
||||||
|
Some(v) => Ok(v),
|
||||||
|
None => Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for $Device {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_string(DeviceVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for $Device {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
self.as_str().serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//ECP5 variants
|
||||||
|
make_device_enum! {
|
||||||
|
pub enum Device {
|
||||||
|
#[
|
||||||
|
name = "placeholder25k",
|
||||||
|
lattice_part = "fixme",
|
||||||
|
lattice_device = "fixme",
|
||||||
|
lattice_family = "fixme",
|
||||||
|
]
|
||||||
|
Placeholder25k,
|
||||||
|
#[
|
||||||
|
name = "placeholder85k",
|
||||||
|
lattice_part = "fixme",
|
||||||
|
lattice_device = "fimxe",
|
||||||
|
lattice_family = "fixme",
|
||||||
|
]
|
||||||
|
Placeholder85k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//rest looks good
|
||||||
|
|
||||||
|
impl fmt::Display for Device {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str(self.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||||
|
orangecrab::built_in_job_kinds()
|
||||||
|
.into_iter()
|
||||||
|
.chain(yosys_nextpnr::built_in_job_kinds())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||||
|
orangecrab::built_in_platforms()
|
||||||
|
.into_iter()
|
||||||
|
.chain(yosys_nextpnr::built_in_platforms())
|
||||||
|
}
|
||||||
|
|
||||||
|
//first step yosys -p "read_verilog $<; synth_ecp5 -json $@"
|
||||||
396
crates/fayalite/src/vendor/lattice/orangecrab.rs
vendored
Normal file
396
crates/fayalite/src/vendor/lattice/orangecrab.rs
vendored
Normal file
|
|
@ -0,0 +1,396 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
intern::{Intern, Interned},
|
||||||
|
module::{instance_with_loc, reg_builder_with_loc, wire_with_loc},
|
||||||
|
platform::{
|
||||||
|
DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory,
|
||||||
|
PeripheralsBuilderFinished, Platform, PlatformAspectSet,
|
||||||
|
peripherals::{ClockInput, Led, RgbLed, Uart},
|
||||||
|
},
|
||||||
|
prelude::*,
|
||||||
|
vendor::lattice::{
|
||||||
|
Device,
|
||||||
|
primitives,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use ordered_float::NotNan;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
//keep unchanged
|
||||||
|
macro_rules! orangecrab_platform {
|
||||||
|
(
|
||||||
|
$vis:vis enum $OrangeCrabPlatform:ident {
|
||||||
|
$(#[name = $name:literal, device = $device:ident]
|
||||||
|
$Variant:ident,)*
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
$vis enum $OrangeCrabPlatform {
|
||||||
|
$($Variant,)*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $OrangeCrabPlatform {
|
||||||
|
$vis const VARIANTS: &'static [Self] = &[$(Self::$Variant,)*];
|
||||||
|
$vis fn device(self) -> Device {
|
||||||
|
match self {
|
||||||
|
$(Self::$Variant => Device::$device,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$vis const fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(Self::$Variant => $name,)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_aspects(self) -> &'static PlatformAspectSet {
|
||||||
|
match self {
|
||||||
|
$(Self::$Variant => {
|
||||||
|
static ASPECTS_SET: OnceLock<PlatformAspectSet> = OnceLock::new();
|
||||||
|
ASPECTS_SET.get_or_init(|| self.make_aspects())
|
||||||
|
})*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//untested
|
||||||
|
orangecrab_platform! {
|
||||||
|
pub enum OrangeCrabPlatform {
|
||||||
|
#[name = "orangecrab-25k", device = Placeholder25k]
|
||||||
|
OrangeCrab_25k,
|
||||||
|
#[name = "orangecrab-85k", device = Placeholder85k]
|
||||||
|
OrangeCrab_85k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ArtyA7Peripherals {
|
||||||
|
clk100_div_pow2: [Peripheral<ClockInput>; 4],
|
||||||
|
rst: Peripheral<Reset>,
|
||||||
|
rst_sync: Peripheral<SyncReset>,
|
||||||
|
ld0: Peripheral<RgbLed>,
|
||||||
|
ld1: Peripheral<RgbLed>,
|
||||||
|
ld2: Peripheral<RgbLed>,
|
||||||
|
ld3: Peripheral<RgbLed>,
|
||||||
|
ld4: Peripheral<Led>,
|
||||||
|
ld5: Peripheral<Led>,
|
||||||
|
ld6: Peripheral<Led>,
|
||||||
|
ld7: Peripheral<Led>,
|
||||||
|
uart: Peripheral<Uart>,
|
||||||
|
// TODO: add rest of peripherals when we need them
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Peripherals for ArtyA7Peripherals {
|
||||||
|
fn append_peripherals<'a>(&'a self, peripherals: &mut Vec<PeripheralRef<'a, CanonicalType>>) {
|
||||||
|
let Self {
|
||||||
|
clk100_div_pow2,
|
||||||
|
rst,
|
||||||
|
rst_sync,
|
||||||
|
ld0,
|
||||||
|
ld1,
|
||||||
|
ld2,
|
||||||
|
ld3,
|
||||||
|
ld4,
|
||||||
|
ld5,
|
||||||
|
ld6,
|
||||||
|
ld7,
|
||||||
|
uart,
|
||||||
|
} = self;
|
||||||
|
clk100_div_pow2.append_peripherals(peripherals);
|
||||||
|
rst.append_peripherals(peripherals);
|
||||||
|
rst_sync.append_peripherals(peripherals);
|
||||||
|
ld0.append_peripherals(peripherals);
|
||||||
|
ld1.append_peripherals(peripherals);
|
||||||
|
ld2.append_peripherals(peripherals);
|
||||||
|
ld3.append_peripherals(peripherals);
|
||||||
|
ld4.append_peripherals(peripherals);
|
||||||
|
ld5.append_peripherals(peripherals);
|
||||||
|
ld6.append_peripherals(peripherals);
|
||||||
|
ld7.append_peripherals(peripherals);
|
||||||
|
uart.append_peripherals(peripherals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrangeCrabPlatform {
|
||||||
|
fn make_aspects(self) -> PlatformAspectSet {
|
||||||
|
let mut retval = PlatformAspectSet::new();
|
||||||
|
retval.insert_new(self.device());
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl_module(extern)]
|
||||||
|
fn reset_sync() {
|
||||||
|
#[hdl]
|
||||||
|
let clk: Clock = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let inp: Bool = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let out: SyncReset = m.output();
|
||||||
|
m.annotate_module(BlackBoxInlineAnnotation {
|
||||||
|
path: "fayalite_orangecrab_reset_sync.v".intern(),
|
||||||
|
text: r#"module __fayalite_orangecrab_reset_sync(input clk, input inp, output out);
|
||||||
|
wire reset_0_out;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
reset_0_out <= inp;
|
||||||
|
outp <= reset_0_out;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
"#
|
||||||
|
.intern(),
|
||||||
|
});
|
||||||
|
m.verilog_name("__fayalite_orangecrab_reset_sync");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Platform for OrangeCrabPlatform {
|
||||||
|
type Peripherals = ArtyA7Peripherals;
|
||||||
|
|
||||||
|
fn name(&self) -> Interned<str> {
|
||||||
|
self.as_str().intern()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_peripherals<'builder>(
|
||||||
|
&self,
|
||||||
|
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||||
|
) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) {
|
||||||
|
let mut builder = builder_factory.builder();
|
||||||
|
|
||||||
|
let clk100_div_pow2 = std::array::from_fn(|log2_divisor| {
|
||||||
|
let divisor = 1u64 << log2_divisor;
|
||||||
|
let name = if divisor != 1 {
|
||||||
|
format!("clk100_div_{divisor}")
|
||||||
|
} else {
|
||||||
|
"clk100".into()
|
||||||
|
};
|
||||||
|
builder.input_peripheral(name, ClockInput::new(100e6 / divisor as f64))
|
||||||
|
});
|
||||||
|
builder.add_conflicts(Vec::from_iter(clk100_div_pow2.iter().map(|v| v.id())));
|
||||||
|
(
|
||||||
|
ArtyA7Peripherals {
|
||||||
|
clk100_div_pow2,
|
||||||
|
rst: builder.input_peripheral("rst", Reset),
|
||||||
|
rst_sync: builder.input_peripheral("rst_sync", SyncReset),
|
||||||
|
ld0: builder.output_peripheral("ld0", RgbLed),
|
||||||
|
ld1: builder.output_peripheral("ld1", RgbLed),
|
||||||
|
ld2: builder.output_peripheral("ld2", RgbLed),
|
||||||
|
ld3: builder.output_peripheral("ld3", RgbLed),
|
||||||
|
ld4: builder.output_peripheral("ld4", Led),
|
||||||
|
ld5: builder.output_peripheral("ld5", Led),
|
||||||
|
ld6: builder.output_peripheral("ld6", Led),
|
||||||
|
ld7: builder.output_peripheral("ld7", Led),
|
||||||
|
uart: builder.output_peripheral("uart", Uart),
|
||||||
|
},
|
||||||
|
builder.finish(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn source_location(&self) -> SourceLocation {
|
||||||
|
SourceLocation::builtin()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) {
|
||||||
|
let ArtyA7Peripherals {
|
||||||
|
clk100_div_pow2,
|
||||||
|
rst,
|
||||||
|
rst_sync,
|
||||||
|
ld0,
|
||||||
|
ld1,
|
||||||
|
ld2,
|
||||||
|
ld3,
|
||||||
|
ld4,
|
||||||
|
ld5,
|
||||||
|
ld6,
|
||||||
|
ld7,
|
||||||
|
uart,
|
||||||
|
} = peripherals;
|
||||||
|
let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| {
|
||||||
|
let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool);
|
||||||
|
/* fixme annotate(
|
||||||
|
pin,
|
||||||
|
XdcLocationAnnotation {
|
||||||
|
location: location.intern(),
|
||||||
|
},
|
||||||
|
); */
|
||||||
|
/* fixme annotate(
|
||||||
|
pin,
|
||||||
|
XdcIOStandardAnnotation {
|
||||||
|
value: io_standard.intern(),
|
||||||
|
},
|
||||||
|
); */
|
||||||
|
//let buf = instance_with_loc(
|
||||||
|
// &format!("{name}_buf"),
|
||||||
|
// //primitives::IBUF(),
|
||||||
|
// SourceLocation::builtin(),
|
||||||
|
//);
|
||||||
|
//connect(buf.I, pin);
|
||||||
|
//if invert { !buf.O } else { buf.O }
|
||||||
|
if invert { !pin } else { pin }
|
||||||
|
};
|
||||||
|
let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
|
||||||
|
let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool);
|
||||||
|
/* fixme annotate(
|
||||||
|
pin,
|
||||||
|
XdcLocationAnnotation {
|
||||||
|
location: location.intern(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
annotate(
|
||||||
|
pin,
|
||||||
|
XdcIOStandardAnnotation {
|
||||||
|
value: io_standard.intern(),
|
||||||
|
},
|
||||||
|
); */
|
||||||
|
//let buf = instance_with_loc(
|
||||||
|
// &format!("{name}_buf"),
|
||||||
|
// primitives::OBUFT(),
|
||||||
|
// SourceLocation::builtin(),
|
||||||
|
//);
|
||||||
|
//connect(pin, buf.O);
|
||||||
|
//connect(buf.T, false);
|
||||||
|
//buf.I
|
||||||
|
pin
|
||||||
|
};
|
||||||
|
let mut frequency = clk100_div_pow2[0].ty().frequency();
|
||||||
|
let mut log2_divisor = 0;
|
||||||
|
let mut clk = None;
|
||||||
|
for (cur_log2_divisor, p) in clk100_div_pow2.into_iter().enumerate() {
|
||||||
|
let Some(p) = p.into_used() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
debug_assert!(
|
||||||
|
clk.is_none(),
|
||||||
|
"conflict-handling logic should ensure at most one clock is used",
|
||||||
|
);
|
||||||
|
frequency = p.ty().frequency();
|
||||||
|
clk = Some(p);
|
||||||
|
log2_divisor = cur_log2_divisor;
|
||||||
|
}
|
||||||
|
let clk100_buf = make_buffered_input("clk100", "E3", "LVCMOS33", false);
|
||||||
|
//let startup = instance_with_loc(
|
||||||
|
// "startup",
|
||||||
|
// primitives::STARTUPE2_default_inputs(),
|
||||||
|
// SourceLocation::builtin(),
|
||||||
|
//);
|
||||||
|
//let clk_global_buf = instance_with_loc(
|
||||||
|
// "clk_global_buf",
|
||||||
|
// primitives::BUFGCE(),
|
||||||
|
// SourceLocation::builtin(),
|
||||||
|
//);
|
||||||
|
//connect(clk_global_buf.CE, startup.EOS);
|
||||||
|
let mut clk_global_buf_in = clk100_buf.to_clock();
|
||||||
|
for prev_log2_divisor in 0..log2_divisor {
|
||||||
|
let prev_divisor = 1u64 << prev_log2_divisor;
|
||||||
|
let clk_in = wire_with_loc(
|
||||||
|
&format!("clk_div_{prev_divisor}"),
|
||||||
|
SourceLocation::builtin(),
|
||||||
|
Clock,
|
||||||
|
);
|
||||||
|
connect(clk_in, clk_global_buf_in);
|
||||||
|
/* fixme
|
||||||
|
annotate(
|
||||||
|
clk_in,
|
||||||
|
XdcCreateClockAnnotation {
|
||||||
|
period: NotNan::new(1e9 / (100e6 / prev_divisor as f64))
|
||||||
|
.expect("known to be valid"),
|
||||||
|
},
|
||||||
|
); */
|
||||||
|
annotate(clk_in, DontTouchAnnotation);
|
||||||
|
let cd = wire_with_loc(
|
||||||
|
&format!("clk_div_{prev_divisor}_in"),
|
||||||
|
SourceLocation::builtin(),
|
||||||
|
ClockDomain[AsyncReset],
|
||||||
|
);
|
||||||
|
connect(cd.clk, clk_in);
|
||||||
|
//FIXME connect(cd.rst, (!startup.EOS).to_async_reset());
|
||||||
|
let divider = reg_builder_with_loc("divider", SourceLocation::builtin())
|
||||||
|
.clock_domain(cd)
|
||||||
|
.reset(false)
|
||||||
|
.build();
|
||||||
|
connect(divider, !divider);
|
||||||
|
clk_global_buf_in = divider.to_clock();
|
||||||
|
}
|
||||||
|
//connect(clk_global_buf.I, clk_global_buf_in);
|
||||||
|
let clk_out = wire_with_loc("clk_out", SourceLocation::builtin(), Clock);
|
||||||
|
//connect(clk_out, clk_global_buf.O);
|
||||||
|
connect(clk_out, clk_global_buf_in);
|
||||||
|
/* fixme annotate(
|
||||||
|
clk_out,
|
||||||
|
XdcCreateClockAnnotation {
|
||||||
|
period: NotNan::new(1e9 / frequency).expect("known to be valid"),
|
||||||
|
},
|
||||||
|
); */
|
||||||
|
annotate(clk_out, DontTouchAnnotation);
|
||||||
|
if let Some(clk) = clk {
|
||||||
|
connect(clk.instance_io_field().clk, clk_out);
|
||||||
|
}
|
||||||
|
//undo 1
|
||||||
|
let rst_value = {
|
||||||
|
let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", true);
|
||||||
|
let rst_sync = instance_with_loc("rst_sync", reset_sync(), SourceLocation::builtin());
|
||||||
|
connect(rst_sync.clk, clk_out);
|
||||||
|
connect(rst_sync.inp, rst_buf/* | !startup.EOS*/); //FIXME
|
||||||
|
rst_sync.out
|
||||||
|
};
|
||||||
|
if let Some(rst) = rst.into_used() {
|
||||||
|
connect(rst.instance_io_field(), rst_value.to_reset());
|
||||||
|
}
|
||||||
|
if let Some(rst_sync) = rst_sync.into_used() {
|
||||||
|
connect(rst_sync.instance_io_field(), rst_value);
|
||||||
|
}
|
||||||
|
let rgb_leds = [
|
||||||
|
(ld0, ("G6", "F6", "E1")),
|
||||||
|
(ld1, ("G3", "J4", "G4")),
|
||||||
|
(ld2, ("J3", "J2", "H4")),
|
||||||
|
(ld3, ("K1", "H6", "K2")),
|
||||||
|
];
|
||||||
|
for (rgb_led, (r_loc, g_loc, b_loc)) in rgb_leds {
|
||||||
|
let r = make_buffered_output(&format!("{}_r", rgb_led.name()), r_loc, "LVCMOS33");
|
||||||
|
let g = make_buffered_output(&format!("{}_g", rgb_led.name()), g_loc, "LVCMOS33");
|
||||||
|
let b = make_buffered_output(&format!("{}_b", rgb_led.name()), b_loc, "LVCMOS33");
|
||||||
|
if let Some(rgb_led) = rgb_led.into_used() {
|
||||||
|
connect(r, rgb_led.instance_io_field().r);
|
||||||
|
connect(g, rgb_led.instance_io_field().g);
|
||||||
|
connect(b, rgb_led.instance_io_field().b);
|
||||||
|
} else {
|
||||||
|
connect(r, false);
|
||||||
|
connect(g, false);
|
||||||
|
connect(b, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let leds = [(ld4, "H5"), (ld5, "J5"), (ld6, "T9"), (ld7, "T10")];
|
||||||
|
for (led, loc) in leds {
|
||||||
|
let o = make_buffered_output(&led.name(), loc, "LVCMOS33");
|
||||||
|
if let Some(led) = led.into_used() {
|
||||||
|
connect(o, led.instance_io_field().on);
|
||||||
|
} else {
|
||||||
|
connect(o, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let uart_tx = make_buffered_output("uart_tx", "D10", "LVCMOS33");
|
||||||
|
let uart_rx = make_buffered_input("uart_rx", "A9", "LVCMOS33", false);
|
||||||
|
if let Some(uart) = uart.into_used() {
|
||||||
|
connect(uart_tx, uart.instance_io_field().tx);
|
||||||
|
connect(uart.instance_io_field().rx, uart_rx);
|
||||||
|
} else {
|
||||||
|
connect(uart_tx, true); // idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aspects(&self) -> PlatformAspectSet {
|
||||||
|
self.get_aspects().clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = DynPlatform> {
|
||||||
|
OrangeCrabPlatform::VARIANTS
|
||||||
|
.iter()
|
||||||
|
.map(|&v| DynPlatform::new(v))
|
||||||
|
}
|
||||||
50
crates/fayalite/src/vendor/lattice/primitives.rs
vendored
Normal file
50
crates/fayalite/src/vendor/lattice/primitives.rs
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
//#[hdl_module(extern)]
|
||||||
|
//pub fn IBUF() {
|
||||||
|
// m.verilog_name("IBUF");
|
||||||
|
// #[hdl]
|
||||||
|
// let O: Bool = m.output();
|
||||||
|
// #[hdl]
|
||||||
|
// let I: Bool = m.input();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#[hdl_module(extern)]
|
||||||
|
//pub fn OBUFT() {
|
||||||
|
// m.verilog_name("OBUFT");
|
||||||
|
// #[hdl]
|
||||||
|
// let O: Bool = m.output();
|
||||||
|
// #[hdl]
|
||||||
|
// let I: Bool = m.input();
|
||||||
|
// #[hdl]
|
||||||
|
// let T: Bool = m.input();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#[hdl_module(extern)]
|
||||||
|
//pub fn BUFGCE() {
|
||||||
|
// m.verilog_name("BUFGCE");
|
||||||
|
// #[hdl]
|
||||||
|
// let O: Clock = m.output();
|
||||||
|
// #[hdl]
|
||||||
|
// let CE: Bool = m.input();
|
||||||
|
// #[hdl]
|
||||||
|
// let I: Clock = m.input();
|
||||||
|
//}
|
||||||
|
|
||||||
|
#[hdl_module(extern)]
|
||||||
|
pub fn FIXME_PLACEHOLDER() {
|
||||||
|
m.verilog_name("FIXME_PLACEHOLDER");
|
||||||
|
#[hdl]
|
||||||
|
let CFGCLK: Clock = m.output();
|
||||||
|
#[hdl]
|
||||||
|
let CFGMCLK: Clock = m.output();
|
||||||
|
#[hdl]
|
||||||
|
let EOS: Bool = m.output();
|
||||||
|
#[hdl]
|
||||||
|
let PREQ: Bool = m.output();
|
||||||
|
}
|
||||||
896
crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs
vendored
Normal file
896
crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs
vendored
Normal file
|
|
@ -0,0 +1,896 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
annotations::{Annotation, TargetedAnnotation},
|
||||||
|
build::{
|
||||||
|
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams,
|
||||||
|
JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||||
|
JobKindAndDependencies, ToArgs, WriteArgs,
|
||||||
|
external::{
|
||||||
|
ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait,
|
||||||
|
},
|
||||||
|
verilog::{UnadjustedVerilog, VerilogDialect, VerilogJob, VerilogJobKind},
|
||||||
|
},
|
||||||
|
bundle::{Bundle, BundleType},
|
||||||
|
expr::target::{Target, TargetBase},
|
||||||
|
firrtl::{ScalarizedModuleABI, ScalarizedModuleABIAnnotations, ScalarizedModuleABIPort},
|
||||||
|
intern::{Intern, InternSlice, Interned},
|
||||||
|
module::{
|
||||||
|
NameId, ScopedNameId, TargetName,
|
||||||
|
transform::visit::{Visit, Visitor},
|
||||||
|
},
|
||||||
|
prelude::*,
|
||||||
|
source_location::SourceLocation,
|
||||||
|
util::{HashSet, job_server::AcquiredJob},
|
||||||
|
vendor::lattice::{
|
||||||
|
Device,
|
||||||
|
/* fixme LatticeAnnotation,*/ LatticeArgs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use eyre::Context;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{
|
||||||
|
convert::Infallible,
|
||||||
|
ffi::{OsStr, OsString},
|
||||||
|
fmt::{self, Write},
|
||||||
|
ops::ControlFlow,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
|
||||||
|
pub struct YosysNextpnrWriteYsFileJobKind;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrWriteYsFileArgs {}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrWriteYsFileArgs {
|
||||||
|
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self {} = self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct YosysNextpnrWriteYsFile {
|
||||||
|
main_verilog_file: Interned<Path>,
|
||||||
|
ys_file: Interned<Path>,
|
||||||
|
json_file: Interned<Path>,
|
||||||
|
json_file_name: Interned<OsStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl YosysNextpnrWriteYsFile {
|
||||||
|
pub fn main_verilog_file(&self) -> Interned<Path> {
|
||||||
|
self.main_verilog_file
|
||||||
|
}
|
||||||
|
pub fn ys_file(&self) -> Interned<Path> {
|
||||||
|
self.ys_file
|
||||||
|
}
|
||||||
|
pub fn json_file(&self) -> Interned<Path> {
|
||||||
|
self.json_file
|
||||||
|
}
|
||||||
|
pub fn json_file_name(&self) -> Interned<OsStr> {
|
||||||
|
self.json_file_name
|
||||||
|
}
|
||||||
|
fn write_ys(
|
||||||
|
&self,
|
||||||
|
output: &mut OsString,
|
||||||
|
additional_files: &[Interned<Path>],
|
||||||
|
main_module_name_id: NameId,
|
||||||
|
) -> eyre::Result<()> {
|
||||||
|
let Self {
|
||||||
|
main_verilog_file,
|
||||||
|
ys_file: _,
|
||||||
|
json_file: _,
|
||||||
|
json_file_name,
|
||||||
|
} = self;
|
||||||
|
for verilog_file in VerilogJob::all_verilog_files(*main_verilog_file, additional_files)? {
|
||||||
|
output.push("read_verilog -sv \"");
|
||||||
|
output.push(verilog_file);
|
||||||
|
output.push("\"\n");
|
||||||
|
}
|
||||||
|
let circuit_name = crate::firrtl::get_circuit_name(main_module_name_id);
|
||||||
|
writeln!(
|
||||||
|
output,
|
||||||
|
"synth_ecp5 -top {circuit_name}"
|
||||||
|
)
|
||||||
|
.expect("writing to OsString can't fail");
|
||||||
|
output.push("write_json \"");
|
||||||
|
output.push(json_file_name);
|
||||||
|
output.push("\"\n");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JobKind for YosysNextpnrWriteYsFileJobKind {
|
||||||
|
type Args = YosysNextpnrWriteYsFileArgs;
|
||||||
|
type Job = YosysNextpnrWriteYsFile;
|
||||||
|
type Dependencies = JobKindAndDependencies<VerilogJobKind>;
|
||||||
|
|
||||||
|
fn dependencies(self) -> Self::Dependencies {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn args_to_jobs(
|
||||||
|
mut args: JobArgsAndDependencies<Self>,
|
||||||
|
params: &JobParams,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||||
|
args.dependencies
|
||||||
|
.dependencies
|
||||||
|
.args
|
||||||
|
.args
|
||||||
|
.additional_args
|
||||||
|
.verilog_dialect
|
||||||
|
.get_or_insert(VerilogDialect::Yosys);
|
||||||
|
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||||
|
let YosysNextpnrWriteYsFileArgs {} = args;
|
||||||
|
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||||
|
let verilog_job = dependencies.get_job::<VerilogJob, _>();
|
||||||
|
let json_file = base_job.file_with_ext("json");
|
||||||
|
Ok(YosysNextpnrWriteYsFile {
|
||||||
|
main_verilog_file: verilog_job.main_verilog_file(),
|
||||||
|
ys_file: base_job.file_with_ext("ys"),
|
||||||
|
json_file,
|
||||||
|
json_file_name: json_file
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(self, _job: &Self::Job) -> Interned<[JobItemName]> {
|
||||||
|
[JobItemName::DynamicPaths {
|
||||||
|
source_job_name: VerilogJobKind.name(),
|
||||||
|
}]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> {
|
||||||
|
[JobItemName::Path { path: job.ys_file }].intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(self) -> Interned<str> {
|
||||||
|
"yosys-nextpnr-ecp5-write-ys-file".intern()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
self,
|
||||||
|
job: &Self::Job,
|
||||||
|
inputs: &[JobItem],
|
||||||
|
params: &JobParams,
|
||||||
|
_global_params: &GlobalParams,
|
||||||
|
_acquired_job: &mut AcquiredJob,
|
||||||
|
) -> eyre::Result<Vec<JobItem>> {
|
||||||
|
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||||
|
let [additional_files] = inputs else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
let additional_files = VerilogJob::unwrap_additional_files(additional_files);
|
||||||
|
let mut contents = OsString::new();
|
||||||
|
job.write_ys(
|
||||||
|
&mut contents,
|
||||||
|
additional_files,
|
||||||
|
params.main_module().name_id(),
|
||||||
|
)?;
|
||||||
|
let path = job.ys_file;
|
||||||
|
std::fs::write(path, contents.as_encoded_bytes())
|
||||||
|
.wrap_err_with(|| format!("writing {path:?} failed"))?;
|
||||||
|
Ok(vec![JobItem::Path { path }])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subcommand_hidden(self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrSynthArgs {}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrSynthArgs {
|
||||||
|
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self {} = self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||||
|
pub struct YosysNextpnrSynth {
|
||||||
|
#[serde(flatten)]
|
||||||
|
write_ys_file: YosysNextpnrWriteYsFile,
|
||||||
|
ys_file_name: Interned<OsStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for YosysNextpnrSynth {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let Self {
|
||||||
|
write_ys_file:
|
||||||
|
YosysNextpnrWriteYsFile {
|
||||||
|
main_verilog_file,
|
||||||
|
ys_file,
|
||||||
|
json_file,
|
||||||
|
json_file_name,
|
||||||
|
},
|
||||||
|
ys_file_name,
|
||||||
|
} = self;
|
||||||
|
f.debug_struct("YosysNextpnrSynth")
|
||||||
|
.field("main_verilog_file", main_verilog_file)
|
||||||
|
.field("ys_file", ys_file)
|
||||||
|
.field("ys_file_name", ys_file_name)
|
||||||
|
.field("json_file", json_file)
|
||||||
|
.field("json_file_name", json_file_name)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl YosysNextpnrSynth {
|
||||||
|
pub fn main_verilog_file(&self) -> Interned<Path> {
|
||||||
|
self.write_ys_file.main_verilog_file()
|
||||||
|
}
|
||||||
|
pub fn ys_file(&self) -> Interned<Path> {
|
||||||
|
self.write_ys_file.ys_file()
|
||||||
|
}
|
||||||
|
pub fn ys_file_name(&self) -> Interned<OsStr> {
|
||||||
|
self.ys_file_name
|
||||||
|
}
|
||||||
|
pub fn json_file(&self) -> Interned<Path> {
|
||||||
|
self.write_ys_file.json_file()
|
||||||
|
}
|
||||||
|
pub fn json_file_name(&self) -> Interned<OsStr> {
|
||||||
|
self.write_ys_file.json_file_name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
|
||||||
|
pub struct Yosys;
|
||||||
|
|
||||||
|
impl ExternalProgramTrait for Yosys {
|
||||||
|
fn default_program_name() -> Interned<str> {
|
||||||
|
"yosys".intern() //must be yosys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalCommand for YosysNextpnrSynth {
|
||||||
|
type AdditionalArgs = YosysNextpnrSynthArgs;
|
||||||
|
type AdditionalJobData = Self;
|
||||||
|
type BaseJobPosition = GetJobPositionDependencies<
|
||||||
|
GetJobPositionDependencies<
|
||||||
|
GetJobPositionDependencies<<UnadjustedVerilog as ExternalCommand>::BaseJobPosition>,
|
||||||
|
>,
|
||||||
|
>;
|
||||||
|
type Dependencies = JobKindAndDependencies<YosysNextpnrWriteYsFileJobKind>;
|
||||||
|
type ExternalProgram = Yosys;
|
||||||
|
|
||||||
|
fn dependencies() -> Self::Dependencies {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn args_to_jobs(
|
||||||
|
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||||
|
params: &JobParams,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> eyre::Result<(
|
||||||
|
Self::AdditionalJobData,
|
||||||
|
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||||
|
)> {
|
||||||
|
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||||
|
let YosysNextpnrSynthArgs {} = args.additional_args;
|
||||||
|
Ok(Self {
|
||||||
|
write_ys_file: dependencies.job.job.clone(),
|
||||||
|
ys_file_name: dependencies
|
||||||
|
.job
|
||||||
|
.job
|
||||||
|
.ys_file()
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(job: &ExternalCommandJob<Self>) -> Interned<[JobItemName]> {
|
||||||
|
[
|
||||||
|
JobItemName::Path {
|
||||||
|
path: job.additional_job_data().ys_file(),
|
||||||
|
},
|
||||||
|
JobItemName::Path {
|
||||||
|
path: job.additional_job_data().main_verilog_file(),
|
||||||
|
},
|
||||||
|
JobItemName::DynamicPaths {
|
||||||
|
source_job_name: VerilogJobKind.name(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_paths(job: &ExternalCommandJob<Self>) -> Interned<[Interned<Path>]> {
|
||||||
|
[job.additional_job_data().json_file()].intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) {
|
||||||
|
args.write_arg("-s");
|
||||||
|
args.write_interned_arg(job.additional_job_data().ys_file_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_dir(job: &ExternalCommandJob<Self>) -> Option<Interned<Path>> {
|
||||||
|
Some(job.output_dir())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn job_kind_name() -> Interned<str> {
|
||||||
|
"yosys-nextpnr-ecp5-synth".intern()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subcommand_hidden() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
|
||||||
|
pub struct YosysNextpnrWritePcfFileJobKind;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrWritePcfFileArgs {}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrWritePcfFileArgs {
|
||||||
|
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self {} = self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct YosysNextpnrWritePcfFile {
|
||||||
|
firrtl_export_options: crate::firrtl::ExportOptions,
|
||||||
|
output_dir: Interned<Path>,
|
||||||
|
pcf_file: Interned<Path>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WritePcfContentsError(eyre::Report);
|
||||||
|
|
||||||
|
impl From<eyre::Report> for WritePcfContentsError {
|
||||||
|
fn from(v: eyre::Report) -> Self {
|
||||||
|
Self(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<fmt::Error> for WritePcfContentsError {
|
||||||
|
fn from(_v: fmt::Error) -> Self {
|
||||||
|
unreachable!("String write can't fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tcl_escape(s: impl AsRef<str>) -> String {
|
||||||
|
let s = s.as_ref();
|
||||||
|
if !s.contains(|ch: char| !ch.is_alphanumeric() && ch != '_') {
|
||||||
|
return s.into();
|
||||||
|
}
|
||||||
|
let mut retval = String::with_capacity(s.len().saturating_add(2));
|
||||||
|
retval.push('"');
|
||||||
|
for ch in s.chars() {
|
||||||
|
if let '$' | '\\' | '[' = ch {
|
||||||
|
retval.push('\\');
|
||||||
|
}
|
||||||
|
retval.push(ch);
|
||||||
|
}
|
||||||
|
retval.push('"');
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
enum AnnotationTarget {
|
||||||
|
None,
|
||||||
|
Module(Module<Bundle>),
|
||||||
|
Mem(Mem),
|
||||||
|
Target(Interned<Target>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnnotationTarget {
|
||||||
|
fn source_location(self) -> SourceLocation {
|
||||||
|
match self {
|
||||||
|
AnnotationTarget::None => unreachable!(),
|
||||||
|
AnnotationTarget::Module(module) => module.source_location(),
|
||||||
|
AnnotationTarget::Mem(mem) => mem.source_location(),
|
||||||
|
AnnotationTarget::Target(target) => target.base().source_location(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PcfFileWriter<W: fmt::Write> { //TODO
|
||||||
|
output: W,
|
||||||
|
module_depth: usize,
|
||||||
|
annotation_target: AnnotationTarget,
|
||||||
|
dont_touch_targets: HashSet<Interned<Target>>,
|
||||||
|
required_dont_touch_targets: HashSet<Interned<Target>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: fmt::Write> PcfFileWriter<W> {
|
||||||
|
fn run(output: W, top_module: Module<Bundle>) -> Result<(), WritePcfContentsError> {
|
||||||
|
let mut this = Self {
|
||||||
|
output,
|
||||||
|
module_depth: 0,
|
||||||
|
annotation_target: AnnotationTarget::None,
|
||||||
|
dont_touch_targets: HashSet::default(),
|
||||||
|
required_dont_touch_targets: HashSet::default(),
|
||||||
|
};
|
||||||
|
top_module.visit(&mut this)?;
|
||||||
|
let Self {
|
||||||
|
output: _,
|
||||||
|
module_depth: _,
|
||||||
|
annotation_target: _,
|
||||||
|
dont_touch_targets,
|
||||||
|
required_dont_touch_targets,
|
||||||
|
} = this;
|
||||||
|
for &target in required_dont_touch_targets.difference(&dont_touch_targets) {
|
||||||
|
return Err(eyre::eyre!(
|
||||||
|
"a DontTouchAnnotation is required since the target is also annotated with a LatticeAnnotation:\ntarget: {target:?}\nat: {}",
|
||||||
|
target.base().source_location(),
|
||||||
|
).into());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn default_visit_with<T: ?Sized + Visit<Self>>(
|
||||||
|
&mut self,
|
||||||
|
module_depth: usize,
|
||||||
|
annotation_target: AnnotationTarget,
|
||||||
|
v: &T,
|
||||||
|
) -> Result<(), WritePcfContentsError> {
|
||||||
|
let Self {
|
||||||
|
output: _,
|
||||||
|
module_depth: old_module_depth,
|
||||||
|
annotation_target: old_annotation_target,
|
||||||
|
dont_touch_targets: _,
|
||||||
|
required_dont_touch_targets: _,
|
||||||
|
} = *self;
|
||||||
|
self.module_depth = module_depth;
|
||||||
|
self.annotation_target = annotation_target;
|
||||||
|
let retval = v.default_visit(self);
|
||||||
|
self.module_depth = old_module_depth;
|
||||||
|
self.annotation_target = old_annotation_target;
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: fmt::Write> Visitor for PcfFileWriter<W> {
|
||||||
|
type Error = WritePcfContentsError;
|
||||||
|
|
||||||
|
fn visit_targeted_annotation(&mut self, v: &TargetedAnnotation) -> Result<(), Self::Error> {
|
||||||
|
self.default_visit_with(self.module_depth, AnnotationTarget::Target(v.target()), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_module<T: BundleType>(&mut self, v: &Module<T>) -> Result<(), Self::Error> {
|
||||||
|
self.default_visit_with(
|
||||||
|
self.module_depth + 1,
|
||||||
|
AnnotationTarget::Module(v.canonical()),
|
||||||
|
v,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_mem<Element: Type, Len: Size>(
|
||||||
|
&mut self,
|
||||||
|
v: &Mem<Element, Len>,
|
||||||
|
) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
Element: Visit<Self>,
|
||||||
|
{
|
||||||
|
self.default_visit_with(
|
||||||
|
self.module_depth + 1,
|
||||||
|
AnnotationTarget::Mem(v.canonical()),
|
||||||
|
v,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_dont_touch_annotation(&mut self, _v: &DontTouchAnnotation) -> Result<(), Self::Error> {
|
||||||
|
if let AnnotationTarget::Target(target) = self.annotation_target {
|
||||||
|
self.dont_touch_targets.insert(target);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME fn visit_lattice_annotation(&mut self, v: &LatticeAnnotation) -> Result<(), Self::Error> */
|
||||||
|
}
|
||||||
|
|
||||||
|
impl YosysNextpnrWritePcfFile {
|
||||||
|
fn write_pcf_contents_for_port_and_annotations(
|
||||||
|
&self,
|
||||||
|
output: &mut impl fmt::Write,
|
||||||
|
port: &ScalarizedModuleABIPort,
|
||||||
|
annotations: ScalarizedModuleABIAnnotations<'_>,
|
||||||
|
) -> Result<(), WritePcfContentsError> {
|
||||||
|
/* fixme for annotation in annotations .. */
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn write_pcf_contents(
|
||||||
|
&self,
|
||||||
|
output: &mut String,
|
||||||
|
top_module: &Module<Bundle>,
|
||||||
|
) -> eyre::Result<()> {
|
||||||
|
let scalarized_module_abi =
|
||||||
|
ScalarizedModuleABI::new(top_module, self.firrtl_export_options)
|
||||||
|
.map_err(eyre::Report::from)?;
|
||||||
|
match scalarized_module_abi.for_each_port_and_annotations(|port, annotations| {
|
||||||
|
match self.write_pcf_contents_for_port_and_annotations(output, port, annotations) {
|
||||||
|
Ok(()) => ControlFlow::Continue(()),
|
||||||
|
Err(e) => ControlFlow::Break(e),
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
ControlFlow::Continue(()) => {}
|
||||||
|
ControlFlow::Break(e) => return Err(e.0),
|
||||||
|
}
|
||||||
|
PcfFileWriter::run(output, *top_module).map_err(|e| e.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JobKind for YosysNextpnrWritePcfFileJobKind {
|
||||||
|
type Args = YosysNextpnrWritePcfFileArgs;
|
||||||
|
type Job = YosysNextpnrWritePcfFile;
|
||||||
|
type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrSynth>>;
|
||||||
|
|
||||||
|
fn dependencies(self) -> Self::Dependencies {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn args_to_jobs(
|
||||||
|
args: JobArgsAndDependencies<Self>,
|
||||||
|
params: &JobParams,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||||
|
let firrtl_export_options = args
|
||||||
|
.dependencies
|
||||||
|
.dependencies
|
||||||
|
.dependencies
|
||||||
|
.dependencies
|
||||||
|
.dependencies
|
||||||
|
.args
|
||||||
|
.args
|
||||||
|
.export_options;
|
||||||
|
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||||
|
let YosysNextpnrWritePcfFileArgs {} = args;
|
||||||
|
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||||
|
Ok(YosysNextpnrWritePcfFile {
|
||||||
|
firrtl_export_options,
|
||||||
|
output_dir: base_job.output_dir(),
|
||||||
|
pcf_file: base_job.file_with_ext("pcf"),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> {
|
||||||
|
[JobItemName::Path {
|
||||||
|
path: job.output_dir,
|
||||||
|
}]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> {
|
||||||
|
[JobItemName::Path { path: job.pcf_file }].intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(self) -> Interned<str> {
|
||||||
|
"yosys-nextpnr-ecp5-write-pcf-file".intern()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
self,
|
||||||
|
job: &Self::Job,
|
||||||
|
inputs: &[JobItem],
|
||||||
|
params: &JobParams,
|
||||||
|
_global_params: &GlobalParams,
|
||||||
|
_acquired_job: &mut AcquiredJob,
|
||||||
|
) -> eyre::Result<Vec<JobItem>> {
|
||||||
|
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||||
|
let mut pcf = String::new();
|
||||||
|
job.write_pcf_contents(&mut pcf, params.main_module())?;
|
||||||
|
std::fs::write(job.pcf_file, pcf)?;
|
||||||
|
Ok(vec![JobItem::Path { path: job.pcf_file }])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subcommand_hidden(self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
|
||||||
|
pub struct NextpnrLattice;
|
||||||
|
|
||||||
|
impl ExternalProgramTrait for NextpnrLattice {
|
||||||
|
fn default_program_name() -> Interned<str> {
|
||||||
|
"nextpnr".intern()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrRunNextpnrArgs {
|
||||||
|
#[command(flatten)]
|
||||||
|
pub common: LatticeArgs,
|
||||||
|
#[arg(long, default_value_t = 0)]
|
||||||
|
pub nextpnr_lattice_seed: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrRunNextpnrArgs {
|
||||||
|
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self {
|
||||||
|
common,
|
||||||
|
nextpnr_lattice_seed,
|
||||||
|
} = self;
|
||||||
|
common.to_args(args);
|
||||||
|
args.write_display_arg(format_args!("--nextpnr-lattice-seed={nextpnr_lattice_seed}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct YosysNextpnrRunNextpnr {
|
||||||
|
device: Device,
|
||||||
|
nextpnr_lattice_seed: i32,
|
||||||
|
pcf_file: Interned<Path>,
|
||||||
|
json_file: Interned<Path>,
|
||||||
|
json_file_name: Interned<OsStr>,
|
||||||
|
routed_json_file: Interned<Path>,
|
||||||
|
routed_json_file_name: Interned<OsStr>,
|
||||||
|
textcfg_file: Interned<Path>,
|
||||||
|
textcfg_file_name: Interned<OsStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalCommand for YosysNextpnrRunNextpnr {
|
||||||
|
type AdditionalArgs = YosysNextpnrRunNextpnrArgs;
|
||||||
|
type AdditionalJobData = Self;
|
||||||
|
type BaseJobPosition = GetJobPositionDependencies<
|
||||||
|
GetJobPositionDependencies<<YosysNextpnrSynth as ExternalCommand>::BaseJobPosition>,
|
||||||
|
>;
|
||||||
|
type Dependencies = JobKindAndDependencies<YosysNextpnrWritePcfFileJobKind>;
|
||||||
|
type ExternalProgram = NextpnrLattice;
|
||||||
|
|
||||||
|
fn dependencies() -> Self::Dependencies {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn args_to_jobs(
|
||||||
|
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||||
|
params: &JobParams,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> eyre::Result<(
|
||||||
|
Self::AdditionalJobData,
|
||||||
|
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||||
|
)> {
|
||||||
|
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||||
|
let YosysNextpnrRunNextpnrArgs {
|
||||||
|
common,
|
||||||
|
nextpnr_lattice_seed,
|
||||||
|
} = args.additional_args;
|
||||||
|
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||||
|
let write_pcf_file = dependencies.get_job::<YosysNextpnrWritePcfFile, _>();
|
||||||
|
let synth = dependencies.get_job::<ExternalCommandJob<YosysNextpnrSynth>, _>();
|
||||||
|
let routed_json_file = base_job.file_with_ext("routed.json");
|
||||||
|
let textcfg_file = base_job.file_with_ext("config"); //file must exist
|
||||||
|
Ok(Self {
|
||||||
|
device: common.require_device(base_job.platform(), global_params)?,
|
||||||
|
nextpnr_lattice_seed,
|
||||||
|
pcf_file: write_pcf_file.pcf_file,
|
||||||
|
json_file: synth.additional_job_data().json_file(),
|
||||||
|
json_file_name: synth.additional_job_data().json_file_name(),
|
||||||
|
routed_json_file: routed_json_file,
|
||||||
|
routed_json_file_name: routed_json_file
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
textcfg_file:textcfg_file,
|
||||||
|
textcfg_file_name: textcfg_file
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(job: &ExternalCommandJob<Self>) -> Interned<[JobItemName]> {
|
||||||
|
[
|
||||||
|
JobItemName::Path {
|
||||||
|
path: job.additional_job_data().json_file,
|
||||||
|
},
|
||||||
|
JobItemName::Path {
|
||||||
|
path: job.additional_job_data().pcf_file,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_paths(job: &ExternalCommandJob<Self>) -> Interned<[Interned<Path>]> {
|
||||||
|
[
|
||||||
|
job.additional_job_data().routed_json_file,
|
||||||
|
]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) {
|
||||||
|
let job_data @ YosysNextpnrRunNextpnr {
|
||||||
|
nextpnr_lattice_seed,
|
||||||
|
json_file_name,
|
||||||
|
routed_json_file_name,
|
||||||
|
textcfg_file_name,
|
||||||
|
..
|
||||||
|
} = job.additional_job_data();
|
||||||
|
args.write_long_option_eq("json", json_file_name);
|
||||||
|
args.write_long_option_eq("textcfg",textcfg_file_name);
|
||||||
|
args.write_arg("--25k");
|
||||||
|
args.write_long_option_eq("package","CSFBGA285");
|
||||||
|
args.write_long_option_eq("lpf","/tmp/orangecrab_r0.2.1.pcf");
|
||||||
|
args.write_arg("--lpf-allow-unconstrained");
|
||||||
|
//???args.write_display_arg(format_args!("--seed={nextpnr_lattice_seed}"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_dir(job: &ExternalCommandJob<Self>) -> Option<Interned<Path>> {
|
||||||
|
Some(job.output_dir())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn job_kind_name() -> Interned<str> {
|
||||||
|
"yosys-nextpnr-ecp5-run-nextpnr".intern()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subcommand_hidden() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrArgs {
|
||||||
|
#[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)]
|
||||||
|
pub pcf1: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrArgs {
|
||||||
|
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self { pcf1 } = self;
|
||||||
|
args.write_long_option_eq("pcf1", pcf1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct YosysNextpnr {
|
||||||
|
pcf1: Interned<Path>,
|
||||||
|
device: Device,
|
||||||
|
frames_file: Interned<Path>,
|
||||||
|
frames_file_name: Interned<OsStr>,
|
||||||
|
bit_file: Interned<Path>,
|
||||||
|
bit_file_name: Interned<OsStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
|
||||||
|
pub struct Ecppack;
|
||||||
|
|
||||||
|
impl ExternalProgramTrait for Ecppack {
|
||||||
|
fn default_program_name() -> Interned<str> {
|
||||||
|
"ecppack".intern()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//begin
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||||
|
pub struct YosysNextpnrRunEcpPackArgs {
|
||||||
|
#[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)]
|
||||||
|
pub placeholder_dir: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToArgs for YosysNextpnrRunEcpPackArgs {
|
||||||
|
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self { placeholder_dir } = self;
|
||||||
|
args.write_long_option_eq("placeholder-dir", placeholder_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct YosysNextpnrRunEcpPack {
|
||||||
|
placeholder_dir: Interned<Path>,
|
||||||
|
device: Device,
|
||||||
|
routed_json_file: Interned<Path>,
|
||||||
|
routed_json_file_name: Interned<OsStr>,
|
||||||
|
textcfg_file: Interned<Path>,
|
||||||
|
textcfg_file_name: Interned<OsStr>,
|
||||||
|
frames_file: Interned<Path>,
|
||||||
|
frames_file_name: Interned<OsStr>,
|
||||||
|
bit_file: Interned<Path>,
|
||||||
|
bit_file_name: Interned<OsStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalCommand for YosysNextpnrRunEcpPack {
|
||||||
|
type AdditionalArgs = YosysNextpnrRunEcpPackArgs;
|
||||||
|
type AdditionalJobData = Self;
|
||||||
|
type BaseJobPosition = GetJobPositionDependencies<
|
||||||
|
<YosysNextpnrRunNextpnr as ExternalCommand>::BaseJobPosition,
|
||||||
|
>;
|
||||||
|
type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrRunNextpnr>>;
|
||||||
|
type ExternalProgram = Ecppack;
|
||||||
|
|
||||||
|
fn dependencies() -> Self::Dependencies {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn args_to_jobs(
|
||||||
|
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||||
|
params: &JobParams,
|
||||||
|
global_params: &GlobalParams,
|
||||||
|
) -> eyre::Result<(
|
||||||
|
Self::AdditionalJobData,
|
||||||
|
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||||
|
)> {
|
||||||
|
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||||
|
let YosysNextpnrRunEcpPackArgs { placeholder_dir } = args.additional_args;
|
||||||
|
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||||
|
let frames_file = base_job.file_with_ext("frames");
|
||||||
|
let bit_file = base_job.file_with_ext("bit");
|
||||||
|
Ok(Self {
|
||||||
|
placeholder_dir: placeholder_dir.intern_deref(),
|
||||||
|
device: dependencies.job.job.additional_job_data().device,
|
||||||
|
//fixme glue code
|
||||||
|
routed_json_file: dependencies.job.job.additional_job_data().routed_json_file,
|
||||||
|
routed_json_file_name: dependencies.job.job.additional_job_data().routed_json_file_name,
|
||||||
|
textcfg_file: dependencies.job.job.additional_job_data().textcfg_file,
|
||||||
|
textcfg_file_name: dependencies.job.job.additional_job_data().textcfg_file_name,
|
||||||
|
frames_file,
|
||||||
|
frames_file_name: frames_file
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
bit_file,
|
||||||
|
bit_file_name: bit_file
|
||||||
|
.interned_file_name()
|
||||||
|
.expect("known to have file name"),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inputs(job: &ExternalCommandJob<Self>) -> Interned<[JobItemName]> {
|
||||||
|
[JobItemName::Path {
|
||||||
|
path: job.additional_job_data().routed_json_file,
|
||||||
|
}]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_paths(job: &ExternalCommandJob<Self>) -> Interned<[Interned<Path>]> {
|
||||||
|
[
|
||||||
|
job.additional_job_data().bit_file,
|
||||||
|
]
|
||||||
|
.intern_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) {
|
||||||
|
let job_data @ YosysNextpnrRunEcpPack {
|
||||||
|
placeholder_dir,
|
||||||
|
device,
|
||||||
|
routed_json_file_name,
|
||||||
|
textcfg_file_name,
|
||||||
|
frames_file_name,
|
||||||
|
bit_file_name,
|
||||||
|
..
|
||||||
|
} = job.additional_job_data();
|
||||||
|
args.write_arg("--compress");
|
||||||
|
args.write_long_option_eq("freq", "38.8"); //FIXME do not hardcode
|
||||||
|
args.write_long_option_eq("input",textcfg_file_name);
|
||||||
|
args.write_long_option_eq("bit",bit_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_dir(job: &ExternalCommandJob<Self>) -> Option<Interned<Path>> {
|
||||||
|
Some(job.output_dir())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn job_kind_name() -> Interned<str> {
|
||||||
|
"yosys-nextpnr-ecp5".intern()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end
|
||||||
|
|
||||||
|
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = DynJobKind> {
|
||||||
|
[
|
||||||
|
DynJobKind::new(YosysNextpnrWriteYsFileJobKind), //working
|
||||||
|
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrSynth>::new()), //working
|
||||||
|
DynJobKind::new(YosysNextpnrWritePcfFileJobKind), //TODO
|
||||||
|
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrRunNextpnr>::new()), //working
|
||||||
|
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrRunEcpPack>::new()), //working
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
|
@ -546,7 +546,7 @@ impl<W: fmt::Write> Visitor for XdcFileWriter<W> {
|
||||||
base.source_location(),
|
base.source_location(),
|
||||||
)? {},
|
)? {},
|
||||||
}
|
}
|
||||||
match base.canonical_ty().unwrap_transparent_types() {
|
match base.canonical_ty() {
|
||||||
CanonicalType::UInt(_)
|
CanonicalType::UInt(_)
|
||||||
| CanonicalType::SInt(_)
|
| CanonicalType::SInt(_)
|
||||||
| CanonicalType::Bool(_)
|
| CanonicalType::Bool(_)
|
||||||
|
|
@ -563,9 +563,6 @@ impl<W: fmt::Write> Visitor for XdcFileWriter<W> {
|
||||||
v,
|
v,
|
||||||
base.source_location(),
|
base.source_location(),
|
||||||
)? {},
|
)? {},
|
||||||
CanonicalType::TraceAsString(_) => {
|
|
||||||
unreachable!("handled by unwrap_transparent_types")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.required_dont_touch_targets.insert(target);
|
self.required_dont_touch_targets.insert(target);
|
||||||
match v {
|
match v {
|
||||||
|
|
@ -595,9 +592,6 @@ impl<W: fmt::Write> Visitor for XdcFileWriter<W> {
|
||||||
v,
|
v,
|
||||||
instance.source_location(),
|
instance.source_location(),
|
||||||
)? {},
|
)? {},
|
||||||
TargetBase::FormalInput(_) | TargetBase::SimIoForGlobal(_) => {
|
|
||||||
unreachable!("base.is_valid_annotation_target() is known to be false")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,11 @@ impl<T: Type> Wire<T> {
|
||||||
ty: T::from_canonical(ty),
|
ty: T::from_canonical(ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[track_caller]
|
|
||||||
pub fn new_unchecked(
|
pub fn new_unchecked(
|
||||||
scoped_name: ScopedNameId,
|
scoped_name: ScopedNameId,
|
||||||
source_location: SourceLocation,
|
source_location: SourceLocation,
|
||||||
ty: T,
|
ty: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
scoped_name.0.assert_is_name_id();
|
|
||||||
Self {
|
Self {
|
||||||
name: scoped_name,
|
name: scoped_name,
|
||||||
source_location,
|
source_location,
|
||||||
|
|
@ -78,7 +76,7 @@ impl<T: Type> Wire<T> {
|
||||||
self.containing_module_name_id().0
|
self.containing_module_name_id().0
|
||||||
}
|
}
|
||||||
pub fn containing_module_name_id(&self) -> NameId {
|
pub fn containing_module_name_id(&self) -> NameId {
|
||||||
self.name.0.unwrap_name_id()
|
self.name.0
|
||||||
}
|
}
|
||||||
pub fn name(&self) -> Interned<str> {
|
pub fn name(&self) -> Interned<str> {
|
||||||
self.name_id().0
|
self.name_id().0
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<!--
|
|
||||||
SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
See Notices.txt for copyright information
|
|
||||||
-->
|
|
||||||
|
|
||||||
`my_test.vcd` is used in the doctest of `fayalite::testing::checked_vcd_output`
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
$timescale 1 ps $end
|
|
||||||
$scope module my_module $end
|
|
||||||
$var wire 8 gAF7X a $end
|
|
||||||
$var wire 8 QS=a/ b $end
|
|
||||||
$upscope $end
|
|
||||||
$enddefinitions $end
|
|
||||||
$dumpvars
|
|
||||||
b0 gAF7X
|
|
||||||
b0 QS=a/
|
|
||||||
$end
|
|
||||||
#1000000
|
|
||||||
b1100100 gAF7X
|
|
||||||
b101010 QS=a/
|
|
||||||
|
|
@ -244,13 +244,3 @@ pub struct MyTypeWithPrivateMembersWithArg<T> {
|
||||||
pub(crate) b: MyPubCrateTypeWithArg<T>,
|
pub(crate) b: MyPubCrateTypeWithArg<T>,
|
||||||
pub c: T,
|
pub c: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(outline_generated)]
|
|
||||||
pub enum EnumWithOnlyOneVariant {
|
|
||||||
A,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(outline_generated)]
|
|
||||||
pub enum EnumWithOnlyOneVariant2<T> {
|
|
||||||
A(T),
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
// See Notices.txt for copyright information
|
|
||||||
use fayalite::{prelude::*, ty::SimValueDebug};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[hdl(outline_generated)]
|
|
||||||
struct MyStruct0<T, S: Size> {
|
|
||||||
v: T,
|
|
||||||
a: ArrayType<UInt<8>, S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[test]
|
|
||||||
fn check_my_struct0() {
|
|
||||||
let ty = MyStruct0[UInt[8]][3];
|
|
||||||
assert_eq!(
|
|
||||||
format!("{ty:?}"),
|
|
||||||
"MyStruct0 { v: UInt<8>, a: Array<UInt<8>, 3> }",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
format!("{:?}", ty.mask_type()),
|
|
||||||
"MaskType<MyStruct0> { v: Bool, a: Array<Bool, 3> }",
|
|
||||||
);
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
MyStruct0::<_, _> {
|
|
||||||
v: 0x23u8,
|
|
||||||
a: [1u8, 2, 3],
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
format!("{v:?}"),
|
|
||||||
"MyStruct0 { v: 0x23_u8, a: [0x1_u8, 0x2_u8, 0x3_u8] }",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(outline_generated, custom_debug())]
|
|
||||||
struct MyStruct1<T, S: Size> {
|
|
||||||
v: T,
|
|
||||||
a: ArrayType<UInt<8>, S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, S: Size> fmt::Debug for MyStruct1<T, S> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let Self { v, a } = self;
|
|
||||||
f.debug_struct("Custom<MyStruct1>")
|
|
||||||
.field("v", v)
|
|
||||||
.field("a", a)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, S: Size> SimValueDebug for MyStruct1<T, S> {
|
|
||||||
#[hdl]
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
#[hdl(sim)]
|
|
||||||
let Self { v, a } = value;
|
|
||||||
f.debug_struct("Custom<MyStruct1>")
|
|
||||||
.field("v", &v)
|
|
||||||
.field("a", &a)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[test]
|
|
||||||
fn check_my_struct1() {
|
|
||||||
let ty = MyStruct1[UInt[8]][3];
|
|
||||||
assert_eq!(
|
|
||||||
format!("{ty:?}"),
|
|
||||||
"Custom<MyStruct1> { v: UInt<8>, a: Array<UInt<8>, 3> }",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
format!("{:?}", ty.mask_type()),
|
|
||||||
"MaskType<MyStruct1> { v: Bool, a: Array<Bool, 3> }",
|
|
||||||
);
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
MyStruct1::<_, _> {
|
|
||||||
v: 0x23u8,
|
|
||||||
a: [1u8, 2, 3],
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
format!("{v:?}"),
|
|
||||||
"Custom<MyStruct1> { v: 0x23_u8, a: [0x1_u8, 0x2_u8, 0x3_u8] }",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(outline_generated)]
|
|
||||||
enum MyEnum0<T, S: Size> {
|
|
||||||
Unit,
|
|
||||||
V(T),
|
|
||||||
A(ArrayType<UInt<8>, S>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[test]
|
|
||||||
fn check_my_enum0() {
|
|
||||||
let ty = MyEnum0[UInt[8]][3];
|
|
||||||
assert_eq!(
|
|
||||||
format!("{ty:?}"),
|
|
||||||
"MyEnum0 { Unit: (), V: UInt<8>, A: Array<UInt<8>, 3> }",
|
|
||||||
);
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.Unit();
|
|
||||||
assert_eq!(format!("{v:?}"), "Unit");
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.V(0x23u8);
|
|
||||||
assert_eq!(format!("{v:?}"), "V(0x23_u8)");
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.A([1u8, 2, 3]);
|
|
||||||
assert_eq!(format!("{v:?}"), "A([0x1_u8, 0x2_u8, 0x3_u8])");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(outline_generated, custom_debug())]
|
|
||||||
enum MyEnum1<T, S: Size> {
|
|
||||||
Unit,
|
|
||||||
V(T),
|
|
||||||
A(ArrayType<UInt<8>, S>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, S: Size> fmt::Debug for MyEnum1<T, S> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let Self { Unit, V, A } = self;
|
|
||||||
f.debug_struct("Custom<MyEnum1>")
|
|
||||||
.field("Unit", Unit)
|
|
||||||
.field("V", V)
|
|
||||||
.field("A", A)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Type, S: Size> SimValueDebug for MyEnum1<T, S> {
|
|
||||||
#[hdl]
|
|
||||||
fn sim_value_debug(
|
|
||||||
value: &<Self as Type>::SimValue,
|
|
||||||
f: &mut fmt::Formatter<'_>,
|
|
||||||
) -> fmt::Result {
|
|
||||||
type SimValueT<T> = <T as Type>::SimValue;
|
|
||||||
match value {
|
|
||||||
SimValueT::<Self>::Unit(_) => f.write_str("MyEnum1::Unit"),
|
|
||||||
SimValueT::<Self>::V(v, _) => f.debug_tuple("MyEnum1::V").field(v).finish(),
|
|
||||||
SimValueT::<Self>::A(a, _) => f.debug_tuple("MyEnum1::A").field(a).finish(),
|
|
||||||
SimValueT::<Self>::Unknown(_) => f.write_str("MyEnum1::Unknown"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[test]
|
|
||||||
fn check_my_enum1() {
|
|
||||||
let ty = MyEnum1[UInt[8]][3];
|
|
||||||
assert_eq!(
|
|
||||||
format!("{ty:?}"),
|
|
||||||
"Custom<MyEnum1> { Unit: (), V: UInt<8>, A: Array<UInt<8>, 3> }",
|
|
||||||
);
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.Unit();
|
|
||||||
assert_eq!(format!("{v:?}"), "MyEnum1::Unit");
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.V(0x23u8);
|
|
||||||
assert_eq!(format!("{v:?}"), "MyEnum1::V(0x23_u8)");
|
|
||||||
let v = #[hdl(sim)]
|
|
||||||
ty.A([1u8, 2, 3]);
|
|
||||||
assert_eq!(format!("{v:?}"), "MyEnum1::A([0x1_u8, 0x2_u8, 0x3_u8])");
|
|
||||||
}
|
|
||||||
|
|
@ -13,7 +13,7 @@ use fayalite::{
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
#[hdl(outline_generated, cmp_eq)]
|
#[hdl(outline_generated)]
|
||||||
pub enum TestEnum {
|
pub enum TestEnum {
|
||||||
A,
|
A,
|
||||||
B(UInt<8>),
|
B(UInt<8>),
|
||||||
|
|
@ -679,270 +679,6 @@ circuit check_enum_literals:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl_module(outline_generated)]
|
|
||||||
pub fn check_enum_cmp_eq() {
|
|
||||||
#[hdl]
|
|
||||||
let lhs: TestEnum = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let rhs: TestEnum = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let eq: Bool = m.output();
|
|
||||||
connect(eq, lhs.cmp_eq(rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_enum_cmp_eq() {
|
|
||||||
let _n = SourceLocation::normalize_files_for_tests();
|
|
||||||
let m = check_enum_cmp_eq();
|
|
||||||
dbg!(m);
|
|
||||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
|
||||||
assert_export_firrtl! {
|
|
||||||
m =>
|
|
||||||
options: ExportOptions {
|
|
||||||
simplify_enums: None,
|
|
||||||
..ExportOptions::default()
|
|
||||||
},
|
|
||||||
"/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0
|
|
||||||
circuit check_enum_cmp_eq:
|
|
||||||
type Ty0 = {|A, B: UInt<8>, C: UInt<1>[3]|}
|
|
||||||
module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1]
|
|
||||||
input lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1]
|
|
||||||
input rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1]
|
|
||||||
output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
|
||||||
wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
match lhs: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
match rhs: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
B(_match_arm_value):
|
|
||||||
skip
|
|
||||||
C(_match_arm_value_1):
|
|
||||||
skip
|
|
||||||
B(_match_arm_value_2):
|
|
||||||
match rhs: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
skip
|
|
||||||
B(_match_arm_value_3):
|
|
||||||
connect TestEnum_cmp_eq, eq(_match_arm_value_2, _match_arm_value_3) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
C(_match_arm_value_4):
|
|
||||||
skip
|
|
||||||
C(_match_arm_value_5):
|
|
||||||
match rhs: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
skip
|
|
||||||
B(_match_arm_value_6):
|
|
||||||
skip
|
|
||||||
C(_match_arm_value_7):
|
|
||||||
wire _array_literal_expr: UInt<1>[3]
|
|
||||||
connect _array_literal_expr[0], eq(_match_arm_value_5[0], _match_arm_value_7[0])
|
|
||||||
connect _array_literal_expr[1], eq(_match_arm_value_5[1], _match_arm_value_7[1])
|
|
||||||
connect _array_literal_expr[2], eq(_match_arm_value_5[2], _match_arm_value_7[2])
|
|
||||||
wire _cast_array_to_bits_expr: UInt<1>[3]
|
|
||||||
connect _cast_array_to_bits_expr[0], _array_literal_expr[0]
|
|
||||||
connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
|
|
||||||
connect _cast_array_to_bits_expr[2], _array_literal_expr[2]
|
|
||||||
wire _cast_to_bits_expr: UInt<3>
|
|
||||||
connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0]))
|
|
||||||
connect TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1]
|
|
||||||
",
|
|
||||||
};
|
|
||||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
|
||||||
assert_export_firrtl! {
|
|
||||||
m =>
|
|
||||||
options: ExportOptions {
|
|
||||||
simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody),
|
|
||||||
..ExportOptions::default()
|
|
||||||
},
|
|
||||||
"/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0
|
|
||||||
circuit check_enum_cmp_eq:
|
|
||||||
type Ty0 = {|A, B, C|}
|
|
||||||
type Ty1 = {tag: Ty0, body: UInt<8>}
|
|
||||||
module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1]
|
|
||||||
input lhs: Ty1 @[module-XXXXXXXXXX.rs 2:1]
|
|
||||||
input rhs: Ty1 @[module-XXXXXXXXXX.rs 3:1]
|
|
||||||
output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
|
||||||
wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
match lhs.tag: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
match rhs.tag: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
B:
|
|
||||||
skip
|
|
||||||
C:
|
|
||||||
skip
|
|
||||||
B:
|
|
||||||
match rhs.tag: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
skip
|
|
||||||
B:
|
|
||||||
connect TestEnum_cmp_eq, eq(bits(lhs.body, 7, 0), bits(rhs.body, 7, 0)) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
C:
|
|
||||||
skip
|
|
||||||
C:
|
|
||||||
match rhs.tag: @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
A:
|
|
||||||
skip
|
|
||||||
B:
|
|
||||||
skip
|
|
||||||
C:
|
|
||||||
wire _array_literal_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[0], bits(bits(lhs.body, 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[1], bits(bits(lhs.body, 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[2], bits(bits(lhs.body, 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2]
|
|
||||||
wire _cast_bits_to_array_expr_1: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(rhs.body, 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(rhs.body, 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2]
|
|
||||||
connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
|
|
||||||
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
|
|
||||||
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
|
|
||||||
wire _cast_array_to_bits_expr: UInt<1>[3]
|
|
||||||
connect _cast_array_to_bits_expr[0], _array_literal_expr[0]
|
|
||||||
connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
|
|
||||||
connect _cast_array_to_bits_expr[2], _array_literal_expr[2]
|
|
||||||
wire _cast_to_bits_expr: UInt<3>
|
|
||||||
connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0]))
|
|
||||||
connect TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1]
|
|
||||||
",
|
|
||||||
};
|
|
||||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
|
||||||
assert_export_firrtl! {
|
|
||||||
m =>
|
|
||||||
options: ExportOptions {
|
|
||||||
simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts),
|
|
||||||
..ExportOptions::default()
|
|
||||||
},
|
|
||||||
"/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0
|
|
||||||
circuit check_enum_cmp_eq:
|
|
||||||
type Ty0 = {tag: UInt<2>, body: UInt<8>}
|
|
||||||
module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1]
|
|
||||||
input lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1]
|
|
||||||
input rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1]
|
|
||||||
output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
|
||||||
wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(lhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(lhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, eq(bits(lhs.body, 7, 0), bits(rhs.body, 7, 0)) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
else when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else:
|
|
||||||
wire _array_literal_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[0], bits(bits(lhs.body, 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[1], bits(bits(lhs.body, 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[2], bits(bits(lhs.body, 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2]
|
|
||||||
wire _cast_bits_to_array_expr_1: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(rhs.body, 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(rhs.body, 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2]
|
|
||||||
connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
|
|
||||||
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
|
|
||||||
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
|
|
||||||
wire _cast_array_to_bits_expr: UInt<1>[3]
|
|
||||||
connect _cast_array_to_bits_expr[0], _array_literal_expr[0]
|
|
||||||
connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
|
|
||||||
connect _cast_array_to_bits_expr[2], _array_literal_expr[2]
|
|
||||||
wire _cast_to_bits_expr: UInt<3>
|
|
||||||
connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0]))
|
|
||||||
connect TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1]
|
|
||||||
",
|
|
||||||
};
|
|
||||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
|
||||||
assert_export_firrtl! {
|
|
||||||
m =>
|
|
||||||
options: ExportOptions {
|
|
||||||
simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt),
|
|
||||||
..ExportOptions::default()
|
|
||||||
},
|
|
||||||
"/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0
|
|
||||||
circuit check_enum_cmp_eq:
|
|
||||||
module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1]
|
|
||||||
input lhs: UInt<10> @[module-XXXXXXXXXX.rs 2:1]
|
|
||||||
input rhs: UInt<10> @[module-XXXXXXXXXX.rs 3:1]
|
|
||||||
output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
|
||||||
wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(bits(lhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(bits(lhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect TestEnum_cmp_eq, eq(bits(bits(lhs, 9, 2), 7, 0), bits(bits(rhs, 9, 2), 7, 0)) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
else when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
skip
|
|
||||||
else:
|
|
||||||
wire _array_literal_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2]
|
|
||||||
wire _cast_bits_to_array_expr_1: UInt<1>[3]
|
|
||||||
wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0)
|
|
||||||
connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1)
|
|
||||||
connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1]
|
|
||||||
connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2)
|
|
||||||
connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2]
|
|
||||||
connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
|
|
||||||
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
|
|
||||||
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
|
|
||||||
wire _cast_array_to_bits_expr: UInt<1>[3]
|
|
||||||
connect _cast_array_to_bits_expr[0], _array_literal_expr[0]
|
|
||||||
connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
|
|
||||||
connect _cast_array_to_bits_expr[2], _array_literal_expr[2]
|
|
||||||
wire _cast_to_bits_expr: UInt<3>
|
|
||||||
connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0]))
|
|
||||||
connect TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1]
|
|
||||||
",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl_module(outline_generated)]
|
#[hdl_module(outline_generated)]
|
||||||
pub fn check_struct_enum_match() {
|
pub fn check_struct_enum_match() {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -3683,176 +3419,20 @@ circuit check_formal: %[[
|
||||||
input pred1: UInt<1> @[module-XXXXXXXXXX.rs 6:1]
|
input pred1: UInt<1> @[module-XXXXXXXXXX.rs 6:1]
|
||||||
input pred2: UInt<1> @[module-XXXXXXXXXX.rs 7:1]
|
input pred2: UInt<1> @[module-XXXXXXXXXX.rs 7:1]
|
||||||
input pred3: UInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
input pred3: UInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
||||||
inst formal_reset of formal_reset @[builtin 1:1]
|
inst formal_reset of formal_reset @[formal.rs 185:24]
|
||||||
assert(clk, pred1, and(en1, not(formal_reset.rst)), "en check 1") @[module-XXXXXXXXXX.rs 9:1]
|
assert(clk, pred1, and(en1, not(formal_reset.rst)), "en check 1") @[module-XXXXXXXXXX.rs 9:1]
|
||||||
assume(clk, pred2, and(en2, not(formal_reset.rst)), "en check 2") @[module-XXXXXXXXXX.rs 10:1]
|
inst formal_reset_1 of formal_reset @[formal.rs 185:24]
|
||||||
cover(clk, pred3, and(en3, not(formal_reset.rst)), "en check 3") @[module-XXXXXXXXXX.rs 11:1]
|
assume(clk, pred2, and(en2, not(formal_reset_1.rst)), "en check 2") @[module-XXXXXXXXXX.rs 10:1]
|
||||||
assert(clk, pred1, and(UInt<1>(0h1), not(formal_reset.rst)), "check 1") @[module-XXXXXXXXXX.rs 12:1]
|
inst formal_reset_2 of formal_reset @[formal.rs 185:24]
|
||||||
assume(clk, pred2, and(UInt<1>(0h1), not(formal_reset.rst)), "check 2") @[module-XXXXXXXXXX.rs 13:1]
|
cover(clk, pred3, and(en3, not(formal_reset_2.rst)), "en check 3") @[module-XXXXXXXXXX.rs 11:1]
|
||||||
cover(clk, pred3, and(UInt<1>(0h1), not(formal_reset.rst)), "check 3") @[module-XXXXXXXXXX.rs 14:1]
|
inst formal_reset_3 of formal_reset @[formal.rs 185:24]
|
||||||
extmodule formal_reset: @[builtin 1:1]
|
assert(clk, pred1, and(UInt<1>(0h1), not(formal_reset_3.rst)), "check 1") @[module-XXXXXXXXXX.rs 12:1]
|
||||||
output rst: UInt<1> @[builtin 1:1]
|
inst formal_reset_4 of formal_reset @[formal.rs 185:24]
|
||||||
defname = __fayalite_formal_reset
|
assume(clk, pred2, and(UInt<1>(0h1), not(formal_reset_4.rst)), "check 2") @[module-XXXXXXXXXX.rs 13:1]
|
||||||
"#,
|
inst formal_reset_5 of formal_reset @[formal.rs 185:24]
|
||||||
};
|
cover(clk, pred3, and(UInt<1>(0h1), not(formal_reset_5.rst)), "check 3") @[module-XXXXXXXXXX.rs 14:1]
|
||||||
}
|
extmodule formal_reset: @[formal.rs 169:5]
|
||||||
|
output rst: UInt<1> @[formal.rs 172:32]
|
||||||
#[hdl_module(outline_generated)]
|
|
||||||
pub fn check_formal_input() {
|
|
||||||
#[hdl]
|
|
||||||
let bool_in: Bool = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let bool_out: Bool = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let any_const_out1: Bool = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let any_const_out2: UInt<16> = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let any_const_out3: SInt<12> = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let any_seq_out: UInt<10> = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let all_const_out: UInt<10> = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let all_seq_out: UInt<10> = m.output();
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
let bool_reg = reg_builder()
|
|
||||||
.clock_domain(
|
|
||||||
#[hdl]
|
|
||||||
ClockDomain {
|
|
||||||
clk: formal_global_clock(),
|
|
||||||
rst: formal_reset(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.reset(false);
|
|
||||||
|
|
||||||
connect(bool_reg, bool_in);
|
|
||||||
connect(bool_out, bool_reg);
|
|
||||||
connect(any_const_out1, any_const(StaticType::TYPE));
|
|
||||||
connect(any_const_out2, any_const(StaticType::TYPE));
|
|
||||||
connect(any_const_out3, any_const(StaticType::TYPE));
|
|
||||||
connect(any_seq_out, any_seq(StaticType::TYPE));
|
|
||||||
connect(all_const_out, all_const(StaticType::TYPE));
|
|
||||||
connect(all_seq_out, all_seq(StaticType::TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_formal_input() {
|
|
||||||
let _n = SourceLocation::normalize_files_for_tests();
|
|
||||||
let m = check_formal_input();
|
|
||||||
dbg!(m);
|
|
||||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
|
||||||
assert_export_firrtl! {
|
|
||||||
m =>
|
|
||||||
"/test/check_formal_input.fir": r#"FIRRTL version 3.2.0
|
|
||||||
circuit check_formal_input: %[[
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "gclk",
|
|
||||||
"target": "~check_formal_input|check_formal_input>formal_global_clock"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>formal_global_clock"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "anyconst",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "anyconst",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const_1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const_1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "anyconst",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const_2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_const_2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "anyseq",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_seq"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>any_seq"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "allconst",
|
|
||||||
"target": "~check_formal_input|check_formal_input>all_const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>all_const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.AttributeAnnotation",
|
|
||||||
"description": "allseq",
|
|
||||||
"target": "~check_formal_input|check_formal_input>all_seq"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.DontTouchAnnotation",
|
|
||||||
"target": "~check_formal_input|check_formal_input>all_seq"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"class": "firrtl.transforms.BlackBoxInlineAnno",
|
|
||||||
"name": "fayalite_formal_reset.v",
|
|
||||||
"text": "module __fayalite_formal_reset(output rst);\n assign rst = $initstate;\nendmodule\n",
|
|
||||||
"target": "~check_formal_input|formal_reset"
|
|
||||||
}
|
|
||||||
]]
|
|
||||||
type Ty0 = {clk: Clock, rst: UInt<1>}
|
|
||||||
type Ty1 = {rst: UInt<1>}
|
|
||||||
module check_formal_input: @[module-XXXXXXXXXX.rs 1:1]
|
|
||||||
input bool_in: UInt<1> @[module-XXXXXXXXXX.rs 2:1]
|
|
||||||
output bool_out: UInt<1> @[module-XXXXXXXXXX.rs 3:1]
|
|
||||||
output any_const_out1: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
|
||||||
output any_const_out2: UInt<16> @[module-XXXXXXXXXX.rs 5:1]
|
|
||||||
output any_const_out3: SInt<12> @[module-XXXXXXXXXX.rs 6:1]
|
|
||||||
output any_seq_out: UInt<10> @[module-XXXXXXXXXX.rs 7:1]
|
|
||||||
output all_const_out: UInt<10> @[module-XXXXXXXXXX.rs 8:1]
|
|
||||||
output all_seq_out: UInt<10> @[module-XXXXXXXXXX.rs 9:1]
|
|
||||||
wire _bundle_literal_expr_1: Ty0
|
|
||||||
connect _bundle_literal_expr_1.clk, asClock(UInt<1>(0h0))
|
|
||||||
connect _bundle_literal_expr_1.rst, UInt<1>(0h0)
|
|
||||||
reg formal_global_clock: UInt<1>, _bundle_literal_expr_1.clk @[builtin 1:1]
|
|
||||||
inst formal_reset of formal_reset @[builtin 1:1]
|
|
||||||
reg any_const: UInt<1>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 13:1]
|
|
||||||
reg any_const_1: UInt<16>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 15:1]
|
|
||||||
reg any_const_2: SInt<12>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 17:1]
|
|
||||||
reg any_seq: UInt<10>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 19:1]
|
|
||||||
reg all_const: UInt<10>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 21:1]
|
|
||||||
reg all_seq: UInt<10>, _bundle_literal_expr_1.clk @[module-XXXXXXXXXX.rs 23:1]
|
|
||||||
wire _bundle_literal_expr: Ty0
|
|
||||||
connect _bundle_literal_expr.clk, asClock(formal_global_clock)
|
|
||||||
connect _bundle_literal_expr.rst, formal_reset.rst
|
|
||||||
regreset bool_reg: UInt<1>, _bundle_literal_expr.clk, _bundle_literal_expr.rst, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 10:1]
|
|
||||||
connect bool_reg, bool_in @[module-XXXXXXXXXX.rs 11:1]
|
|
||||||
connect bool_out, bool_reg @[module-XXXXXXXXXX.rs 12:1]
|
|
||||||
connect any_const_out1, any_const @[module-XXXXXXXXXX.rs 14:1]
|
|
||||||
connect any_const_out2, any_const_1 @[module-XXXXXXXXXX.rs 16:1]
|
|
||||||
connect any_const_out3, any_const_2 @[module-XXXXXXXXXX.rs 18:1]
|
|
||||||
connect any_seq_out, any_seq @[module-XXXXXXXXXX.rs 20:1]
|
|
||||||
connect all_const_out, all_const @[module-XXXXXXXXXX.rs 22:1]
|
|
||||||
connect all_seq_out, all_seq @[module-XXXXXXXXXX.rs 24:1]
|
|
||||||
extmodule formal_reset: @[builtin 1:1]
|
|
||||||
output rst: UInt<1> @[builtin 1:1]
|
|
||||||
defname = __fayalite_formal_reset
|
defname = __fayalite_formal_reset
|
||||||
"#,
|
"#,
|
||||||
};
|
};
|
||||||
|
|
@ -3985,10 +3565,21 @@ circuit check_enum_connect_any:
|
||||||
connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
HdlSome:
|
HdlSome:
|
||||||
wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
||||||
|
wire _cast_bits_to_bundle_expr_1: Ty5
|
||||||
|
wire _cast_bits_to_bundle_expr_flattened_1: Ty6
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 2, 0), 0, 0)
|
||||||
|
wire _cast_bits_to_enum_expr_1: Ty3
|
||||||
|
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_1.tag, 0)):
|
||||||
|
connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
|
else:
|
||||||
|
connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
|
connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_enum_expr_1
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_1.body, bits(bits(i2.body, 2, 0), 2, 1)
|
||||||
|
connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
|
||||||
; connect different types:
|
; connect different types:
|
||||||
; lhs: SInt<1>
|
; lhs: SInt<1>
|
||||||
; rhs: SInt<2>
|
; rhs: SInt<2>
|
||||||
connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _bundle_literal_expr_2: Ty4
|
wire _bundle_literal_expr_2: Ty4
|
||||||
connect _bundle_literal_expr_2.tag, {|HdlNone, HdlSome|}(HdlSome)
|
connect _bundle_literal_expr_2.tag, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2)
|
connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2)
|
||||||
|
|
@ -4010,18 +3601,18 @@ circuit check_enum_connect_any:
|
||||||
connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1]
|
connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
C:
|
C:
|
||||||
wire __connect_variant_body_3: Ty8 @[module-XXXXXXXXXX.rs 8:1]
|
wire __connect_variant_body_3: Ty8 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _cast_bits_to_bundle_expr_1: Ty8
|
wire _cast_bits_to_bundle_expr_2: Ty8
|
||||||
wire _cast_bits_to_bundle_expr_flattened_1: Ty9
|
wire _cast_bits_to_bundle_expr_flattened_2: Ty9
|
||||||
connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 0, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0)
|
||||||
wire _cast_bits_to_enum_expr_1: Ty3
|
wire _cast_bits_to_enum_expr_2: Ty3
|
||||||
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_1.tag, 0)):
|
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_2.tag, 0)):
|
||||||
connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlNone)
|
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
else:
|
else:
|
||||||
connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlSome)
|
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_enum_expr_1
|
connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2
|
||||||
connect _cast_bits_to_bundle_expr_flattened_1.body, UInt<0>(0)
|
connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0)
|
||||||
connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
|
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
|
||||||
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _bundle_literal_expr_4: Ty1
|
wire _bundle_literal_expr_4: Ty1
|
||||||
connect _bundle_literal_expr_4.tag, {|A, B, C|}(C)
|
connect _bundle_literal_expr_4.tag, {|A, B, C|}(C)
|
||||||
wire _cast_bundle_to_bits_expr_1: Ty9
|
wire _cast_bundle_to_bits_expr_1: Ty9
|
||||||
|
|
@ -4050,18 +3641,18 @@ circuit check_enum_connect_any:
|
||||||
connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
B:
|
B:
|
||||||
wire __connect_variant_body_5: Ty5 @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_5: Ty5 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _cast_bits_to_bundle_expr_2: Ty4
|
wire _cast_bits_to_bundle_expr_3: Ty4
|
||||||
wire _cast_bits_to_bundle_expr_flattened_2: Ty7
|
wire _cast_bits_to_bundle_expr_flattened_3: Ty7
|
||||||
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
||||||
wire _cast_bits_to_enum_expr_2: Ty3
|
wire _cast_bits_to_enum_expr_3: Ty3
|
||||||
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_2.tag, 0)):
|
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)):
|
||||||
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone)
|
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
else:
|
else:
|
||||||
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome)
|
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2
|
connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3
|
||||||
connect _cast_bits_to_bundle_expr_flattened_2.body, bits(bits(i1.body, 1, 0), 1, 1)
|
connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1)
|
||||||
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
|
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
|
||||||
match _cast_bits_to_bundle_expr_2.tag: @[module-XXXXXXXXXX.rs 9:1]
|
match _cast_bits_to_bundle_expr_3.tag: @[module-XXXXXXXXXX.rs 9:1]
|
||||||
HdlNone:
|
HdlNone:
|
||||||
wire _bundle_literal_expr_6: Ty5
|
wire _bundle_literal_expr_6: Ty5
|
||||||
connect _bundle_literal_expr_6.tag, {|HdlNone, HdlSome|}(HdlNone)
|
connect _bundle_literal_expr_6.tag, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
|
|
@ -4069,10 +3660,21 @@ circuit check_enum_connect_any:
|
||||||
connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
HdlSome:
|
HdlSome:
|
||||||
wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1]
|
||||||
|
wire _cast_bits_to_bundle_expr_4: Ty4
|
||||||
|
wire _cast_bits_to_bundle_expr_flattened_4: Ty7
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_4.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
||||||
|
wire _cast_bits_to_enum_expr_4: Ty3
|
||||||
|
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_4.tag, 0)):
|
||||||
|
connect _cast_bits_to_enum_expr_4, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
|
else:
|
||||||
|
connect _cast_bits_to_enum_expr_4, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
|
connect _cast_bits_to_bundle_expr_4.tag, _cast_bits_to_enum_expr_4
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_4.body, bits(bits(i1.body, 1, 0), 1, 1)
|
||||||
|
connect _cast_bits_to_bundle_expr_4.body, _cast_bits_to_bundle_expr_flattened_4.body
|
||||||
; connect different types:
|
; connect different types:
|
||||||
; lhs: SInt<2>
|
; lhs: SInt<2>
|
||||||
; rhs: SInt<1>
|
; rhs: SInt<1>
|
||||||
connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_2.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _bundle_literal_expr_7: Ty5
|
wire _bundle_literal_expr_7: Ty5
|
||||||
connect _bundle_literal_expr_7.tag, {|HdlNone, HdlSome|}(HdlSome)
|
connect _bundle_literal_expr_7.tag, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6)
|
connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6)
|
||||||
|
|
@ -4094,18 +3696,18 @@ circuit check_enum_connect_any:
|
||||||
connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1]
|
connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
C:
|
C:
|
||||||
wire __connect_variant_body_7: Ty8 @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_7: Ty8 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _cast_bits_to_bundle_expr_3: Ty8
|
wire _cast_bits_to_bundle_expr_5: Ty8
|
||||||
wire _cast_bits_to_bundle_expr_flattened_3: Ty9
|
wire _cast_bits_to_bundle_expr_flattened_5: Ty9
|
||||||
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 0, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0)
|
||||||
wire _cast_bits_to_enum_expr_3: Ty3
|
wire _cast_bits_to_enum_expr_5: Ty3
|
||||||
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)):
|
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_5.tag, 0)):
|
||||||
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone)
|
connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlNone)
|
||||||
else:
|
else:
|
||||||
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome)
|
connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlSome)
|
||||||
connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3
|
connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_enum_expr_5
|
||||||
connect _cast_bits_to_bundle_expr_flattened_3.body, UInt<0>(0)
|
connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0)
|
||||||
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
|
connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body
|
||||||
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_3 @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _bundle_literal_expr_9: Ty2
|
wire _bundle_literal_expr_9: Ty2
|
||||||
connect _bundle_literal_expr_9.tag, {|A, B, C|}(C)
|
connect _bundle_literal_expr_9.tag, {|A, B, C|}(C)
|
||||||
wire _cast_bundle_to_bits_expr_3: Ty9
|
wire _cast_bundle_to_bits_expr_3: Ty9
|
||||||
|
|
@ -4172,10 +3774,16 @@ circuit check_enum_connect_any:
|
||||||
connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
else:
|
else:
|
||||||
wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1]
|
||||||
|
wire _cast_bits_to_bundle_expr_1: Ty3
|
||||||
|
wire _cast_bits_to_bundle_expr_flattened_1: Ty3
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 2, 0), 0, 0)
|
||||||
|
connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_bundle_expr_flattened_1.tag
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_1.body, bits(bits(i2.body, 2, 0), 2, 1)
|
||||||
|
connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
|
||||||
; connect different types:
|
; connect different types:
|
||||||
; lhs: SInt<1>
|
; lhs: SInt<1>
|
||||||
; rhs: SInt<2>
|
; rhs: SInt<2>
|
||||||
connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _bundle_literal_expr_2: Ty2
|
wire _bundle_literal_expr_2: Ty2
|
||||||
connect _bundle_literal_expr_2.tag, UInt<1>(0h1)
|
connect _bundle_literal_expr_2.tag, UInt<1>(0h1)
|
||||||
connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2)
|
connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2)
|
||||||
|
|
@ -4191,13 +3799,13 @@ circuit check_enum_connect_any:
|
||||||
connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1]
|
connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
else:
|
else:
|
||||||
wire __connect_variant_body_3: Ty4 @[module-XXXXXXXXXX.rs 8:1]
|
wire __connect_variant_body_3: Ty4 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _cast_bits_to_bundle_expr_1: Ty4
|
wire _cast_bits_to_bundle_expr_2: Ty4
|
||||||
wire _cast_bits_to_bundle_expr_flattened_1: Ty4
|
wire _cast_bits_to_bundle_expr_flattened_2: Ty4
|
||||||
connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 0, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0)
|
||||||
connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_bundle_expr_flattened_1.tag
|
connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_bundle_expr_flattened_2.tag
|
||||||
connect _cast_bits_to_bundle_expr_flattened_1.body, UInt<0>(0)
|
connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0)
|
||||||
connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
|
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
|
||||||
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_1 @[module-XXXXXXXXXX.rs 8:1]
|
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1]
|
||||||
wire _bundle_literal_expr_4: Ty0
|
wire _bundle_literal_expr_4: Ty0
|
||||||
connect _bundle_literal_expr_4.tag, UInt<2>(0h2)
|
connect _bundle_literal_expr_4.tag, UInt<2>(0h2)
|
||||||
wire _cast_bundle_to_bits_expr_1: Ty4
|
wire _cast_bundle_to_bits_expr_1: Ty4
|
||||||
|
|
@ -4219,23 +3827,29 @@ circuit check_enum_connect_any:
|
||||||
connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
else when eq(i1.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 9:1]
|
else when eq(i1.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire __connect_variant_body_5: Ty3 @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_5: Ty3 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _cast_bits_to_bundle_expr_2: Ty2
|
wire _cast_bits_to_bundle_expr_3: Ty2
|
||||||
wire _cast_bits_to_bundle_expr_flattened_2: Ty2
|
wire _cast_bits_to_bundle_expr_flattened_3: Ty2
|
||||||
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
||||||
connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_bundle_expr_flattened_2.tag
|
connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_bundle_expr_flattened_3.tag
|
||||||
connect _cast_bits_to_bundle_expr_flattened_2.body, bits(bits(i1.body, 1, 0), 1, 1)
|
connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1)
|
||||||
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
|
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
|
||||||
when eq(_cast_bits_to_bundle_expr_2.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1]
|
when eq(_cast_bits_to_bundle_expr_3.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _bundle_literal_expr_6: Ty3
|
wire _bundle_literal_expr_6: Ty3
|
||||||
connect _bundle_literal_expr_6.tag, UInt<1>(0h0)
|
connect _bundle_literal_expr_6.tag, UInt<1>(0h0)
|
||||||
connect _bundle_literal_expr_6.body, UInt<2>(0h0)
|
connect _bundle_literal_expr_6.body, UInt<2>(0h0)
|
||||||
connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
else:
|
else:
|
||||||
wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1]
|
||||||
|
wire _cast_bits_to_bundle_expr_4: Ty2
|
||||||
|
wire _cast_bits_to_bundle_expr_flattened_4: Ty2
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_4.tag, bits(bits(i1.body, 1, 0), 0, 0)
|
||||||
|
connect _cast_bits_to_bundle_expr_4.tag, _cast_bits_to_bundle_expr_flattened_4.tag
|
||||||
|
connect _cast_bits_to_bundle_expr_flattened_4.body, bits(bits(i1.body, 1, 0), 1, 1)
|
||||||
|
connect _cast_bits_to_bundle_expr_4.body, _cast_bits_to_bundle_expr_flattened_4.body
|
||||||
; connect different types:
|
; connect different types:
|
||||||
; lhs: SInt<2>
|
; lhs: SInt<2>
|
||||||
; rhs: SInt<1>
|
; rhs: SInt<1>
|
||||||
connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_2.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _bundle_literal_expr_7: Ty3
|
wire _bundle_literal_expr_7: Ty3
|
||||||
connect _bundle_literal_expr_7.tag, UInt<1>(0h1)
|
connect _bundle_literal_expr_7.tag, UInt<1>(0h1)
|
||||||
connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6)
|
connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6)
|
||||||
|
|
@ -4251,13 +3865,13 @@ circuit check_enum_connect_any:
|
||||||
connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1]
|
connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
else:
|
else:
|
||||||
wire __connect_variant_body_7: Ty4 @[module-XXXXXXXXXX.rs 9:1]
|
wire __connect_variant_body_7: Ty4 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _cast_bits_to_bundle_expr_3: Ty4
|
wire _cast_bits_to_bundle_expr_5: Ty4
|
||||||
wire _cast_bits_to_bundle_expr_flattened_3: Ty4
|
wire _cast_bits_to_bundle_expr_flattened_5: Ty4
|
||||||
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 0, 0), 0, 0)
|
connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0)
|
||||||
connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_bundle_expr_flattened_3.tag
|
connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_bundle_expr_flattened_5.tag
|
||||||
connect _cast_bits_to_bundle_expr_flattened_3.body, UInt<0>(0)
|
connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0)
|
||||||
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
|
connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body
|
||||||
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_3 @[module-XXXXXXXXXX.rs 9:1]
|
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1]
|
||||||
wire _bundle_literal_expr_9: Ty1
|
wire _bundle_literal_expr_9: Ty1
|
||||||
connect _bundle_literal_expr_9.tag, UInt<2>(0h2)
|
connect _bundle_literal_expr_9.tag, UInt<2>(0h2)
|
||||||
wire _cast_bundle_to_bits_expr_3: Ty4
|
wire _cast_bundle_to_bits_expr_3: Ty4
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -419,7 +419,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 38,
|
pc: 38,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -498,7 +497,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -1220,7 +1218,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xff,
|
state: 0xff,
|
||||||
last_state: 0xff,
|
last_state: 0xff,
|
||||||
},
|
},
|
||||||
|
|
@ -1230,7 +1227,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x7f,
|
state: 0x7f,
|
||||||
last_state: 0x7f,
|
last_state: 0x7f,
|
||||||
},
|
},
|
||||||
|
|
@ -1240,7 +1236,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3f,
|
state: 0x3f,
|
||||||
last_state: 0x3f,
|
last_state: 0x3f,
|
||||||
},
|
},
|
||||||
|
|
@ -1250,7 +1245,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1f,
|
state: 0x1f,
|
||||||
last_state: 0x1f,
|
last_state: 0x1f,
|
||||||
},
|
},
|
||||||
|
|
@ -1260,7 +1254,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0f,
|
state: 0x0f,
|
||||||
last_state: 0x0f,
|
last_state: 0x0f,
|
||||||
},
|
},
|
||||||
|
|
@ -1270,7 +1263,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x07,
|
state: 0x07,
|
||||||
last_state: 0x07,
|
last_state: 0x07,
|
||||||
},
|
},
|
||||||
|
|
@ -1280,7 +1272,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x03,
|
state: 0x03,
|
||||||
last_state: 0x03,
|
last_state: 0x03,
|
||||||
},
|
},
|
||||||
|
|
@ -1290,7 +1281,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(7),
|
index: StatePartIndex<BigSlots>(7),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x01,
|
state: 0x01,
|
||||||
last_state: 0x01,
|
last_state: 0x01,
|
||||||
},
|
},
|
||||||
|
|
@ -1300,7 +1290,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -1310,7 +1299,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x80,
|
state: 0x80,
|
||||||
last_state: 0x80,
|
last_state: 0x80,
|
||||||
},
|
},
|
||||||
|
|
@ -1320,7 +1308,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(10),
|
index: StatePartIndex<BigSlots>(10),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xc0,
|
state: 0xc0,
|
||||||
last_state: 0xc0,
|
last_state: 0xc0,
|
||||||
},
|
},
|
||||||
|
|
@ -1330,7 +1317,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(11),
|
index: StatePartIndex<BigSlots>(11),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe0,
|
state: 0xe0,
|
||||||
last_state: 0xe0,
|
last_state: 0xe0,
|
||||||
},
|
},
|
||||||
|
|
@ -1340,7 +1326,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(12),
|
index: StatePartIndex<BigSlots>(12),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf0,
|
state: 0xf0,
|
||||||
last_state: 0xf0,
|
last_state: 0xf0,
|
||||||
},
|
},
|
||||||
|
|
@ -1350,7 +1335,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(13),
|
index: StatePartIndex<BigSlots>(13),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf8,
|
state: 0xf8,
|
||||||
last_state: 0xf8,
|
last_state: 0xf8,
|
||||||
},
|
},
|
||||||
|
|
@ -1360,7 +1344,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(14),
|
index: StatePartIndex<BigSlots>(14),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfc,
|
state: 0xfc,
|
||||||
last_state: 0xfc,
|
last_state: 0xfc,
|
||||||
},
|
},
|
||||||
|
|
@ -1370,7 +1353,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(15),
|
index: StatePartIndex<BigSlots>(15),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfe,
|
state: 0xfe,
|
||||||
last_state: 0xfe,
|
last_state: 0xfe,
|
||||||
},
|
},
|
||||||
|
|
@ -1380,7 +1362,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(16),
|
index: StatePartIndex<BigSlots>(16),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xff,
|
state: 0xff,
|
||||||
last_state: 0xff,
|
last_state: 0xff,
|
||||||
},
|
},
|
||||||
|
|
@ -1390,7 +1371,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(17),
|
index: StatePartIndex<BigSlots>(17),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x7f,
|
state: 0x7f,
|
||||||
last_state: 0x7f,
|
last_state: 0x7f,
|
||||||
},
|
},
|
||||||
|
|
@ -1400,7 +1380,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(18),
|
index: StatePartIndex<BigSlots>(18),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3f,
|
state: 0x3f,
|
||||||
last_state: 0x3f,
|
last_state: 0x3f,
|
||||||
},
|
},
|
||||||
|
|
@ -1410,7 +1389,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(19),
|
index: StatePartIndex<BigSlots>(19),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1f,
|
state: 0x1f,
|
||||||
last_state: 0x1f,
|
last_state: 0x1f,
|
||||||
},
|
},
|
||||||
|
|
@ -1420,7 +1398,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(20),
|
index: StatePartIndex<BigSlots>(20),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0f,
|
state: 0x0f,
|
||||||
last_state: 0x0f,
|
last_state: 0x0f,
|
||||||
},
|
},
|
||||||
|
|
@ -1430,7 +1407,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(21),
|
index: StatePartIndex<BigSlots>(21),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x07,
|
state: 0x07,
|
||||||
last_state: 0x07,
|
last_state: 0x07,
|
||||||
},
|
},
|
||||||
|
|
@ -1440,7 +1416,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(22),
|
index: StatePartIndex<BigSlots>(22),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x03,
|
state: 0x03,
|
||||||
last_state: 0x03,
|
last_state: 0x03,
|
||||||
},
|
},
|
||||||
|
|
@ -1450,7 +1425,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(23),
|
index: StatePartIndex<BigSlots>(23),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x01,
|
state: 0x01,
|
||||||
last_state: 0x01,
|
last_state: 0x01,
|
||||||
},
|
},
|
||||||
|
|
@ -1460,7 +1434,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(24),
|
index: StatePartIndex<BigSlots>(24),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -1470,7 +1443,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(25),
|
index: StatePartIndex<BigSlots>(25),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x80,
|
state: 0x80,
|
||||||
last_state: 0x80,
|
last_state: 0x80,
|
||||||
},
|
},
|
||||||
|
|
@ -1480,7 +1452,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(26),
|
index: StatePartIndex<BigSlots>(26),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xc0,
|
state: 0xc0,
|
||||||
last_state: 0xc0,
|
last_state: 0xc0,
|
||||||
},
|
},
|
||||||
|
|
@ -1490,7 +1461,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(27),
|
index: StatePartIndex<BigSlots>(27),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe0,
|
state: 0xe0,
|
||||||
last_state: 0xe0,
|
last_state: 0xe0,
|
||||||
},
|
},
|
||||||
|
|
@ -1500,7 +1470,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(28),
|
index: StatePartIndex<BigSlots>(28),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf0,
|
state: 0xf0,
|
||||||
last_state: 0xf0,
|
last_state: 0xf0,
|
||||||
},
|
},
|
||||||
|
|
@ -1510,7 +1479,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(29),
|
index: StatePartIndex<BigSlots>(29),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf8,
|
state: 0xf8,
|
||||||
last_state: 0xf8,
|
last_state: 0xf8,
|
||||||
},
|
},
|
||||||
|
|
@ -1520,7 +1488,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(30),
|
index: StatePartIndex<BigSlots>(30),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfc,
|
state: 0xfc,
|
||||||
last_state: 0xfc,
|
last_state: 0xfc,
|
||||||
},
|
},
|
||||||
|
|
@ -1530,7 +1497,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(31),
|
index: StatePartIndex<BigSlots>(31),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfe,
|
state: 0xfe,
|
||||||
last_state: 0xe1,
|
last_state: 0xe1,
|
||||||
},
|
},
|
||||||
|
|
@ -1540,7 +1506,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(32),
|
index: StatePartIndex<BigSlots>(32),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -1550,7 +1515,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(33),
|
index: StatePartIndex<BigSlots>(33),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xff,
|
state: 0xff,
|
||||||
last_state: 0xff,
|
last_state: 0xff,
|
||||||
},
|
},
|
||||||
|
|
@ -1560,7 +1524,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(34),
|
index: StatePartIndex<BigSlots>(34),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x10,
|
state: 0x10,
|
||||||
last_state: 0x0f,
|
last_state: 0x0f,
|
||||||
},
|
},
|
||||||
|
|
@ -1570,7 +1533,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(35),
|
index: StatePartIndex<BigSlots>(35),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0xe1,
|
last_state: 0xe1,
|
||||||
},
|
},
|
||||||
|
|
@ -1579,7 +1541,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(36),
|
index: StatePartIndex<BigSlots>(36),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1589,7 +1550,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(37),
|
index: StatePartIndex<BigSlots>(37),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xff,
|
state: 0xff,
|
||||||
last_state: 0xff,
|
last_state: 0xff,
|
||||||
},
|
},
|
||||||
|
|
@ -1599,7 +1559,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(38),
|
index: StatePartIndex<BigSlots>(38),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x7f,
|
state: 0x7f,
|
||||||
last_state: 0x7f,
|
last_state: 0x7f,
|
||||||
},
|
},
|
||||||
|
|
@ -1609,7 +1568,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(39),
|
index: StatePartIndex<BigSlots>(39),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3f,
|
state: 0x3f,
|
||||||
last_state: 0x3f,
|
last_state: 0x3f,
|
||||||
},
|
},
|
||||||
|
|
@ -1619,7 +1577,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(40),
|
index: StatePartIndex<BigSlots>(40),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1f,
|
state: 0x1f,
|
||||||
last_state: 0x1f,
|
last_state: 0x1f,
|
||||||
},
|
},
|
||||||
|
|
@ -1629,7 +1586,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(41),
|
index: StatePartIndex<BigSlots>(41),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0f,
|
state: 0x0f,
|
||||||
last_state: 0x0f,
|
last_state: 0x0f,
|
||||||
},
|
},
|
||||||
|
|
@ -1639,7 +1595,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(42),
|
index: StatePartIndex<BigSlots>(42),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x07,
|
state: 0x07,
|
||||||
last_state: 0x07,
|
last_state: 0x07,
|
||||||
},
|
},
|
||||||
|
|
@ -1649,7 +1604,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(43),
|
index: StatePartIndex<BigSlots>(43),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x03,
|
state: 0x03,
|
||||||
last_state: 0x03,
|
last_state: 0x03,
|
||||||
},
|
},
|
||||||
|
|
@ -1659,7 +1613,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(44),
|
index: StatePartIndex<BigSlots>(44),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x01,
|
state: 0x01,
|
||||||
last_state: 0x01,
|
last_state: 0x01,
|
||||||
},
|
},
|
||||||
|
|
@ -1669,7 +1622,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(45),
|
index: StatePartIndex<BigSlots>(45),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -1679,7 +1631,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(46),
|
index: StatePartIndex<BigSlots>(46),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x80,
|
state: 0x80,
|
||||||
last_state: 0x80,
|
last_state: 0x80,
|
||||||
},
|
},
|
||||||
|
|
@ -1689,7 +1640,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(47),
|
index: StatePartIndex<BigSlots>(47),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xc0,
|
state: 0xc0,
|
||||||
last_state: 0xc0,
|
last_state: 0xc0,
|
||||||
},
|
},
|
||||||
|
|
@ -1699,7 +1649,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(48),
|
index: StatePartIndex<BigSlots>(48),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe0,
|
state: 0xe0,
|
||||||
last_state: 0xe0,
|
last_state: 0xe0,
|
||||||
},
|
},
|
||||||
|
|
@ -1709,7 +1658,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(49),
|
index: StatePartIndex<BigSlots>(49),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf0,
|
state: 0xf0,
|
||||||
last_state: 0xf0,
|
last_state: 0xf0,
|
||||||
},
|
},
|
||||||
|
|
@ -1719,7 +1667,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(50),
|
index: StatePartIndex<BigSlots>(50),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf8,
|
state: 0xf8,
|
||||||
last_state: 0xf8,
|
last_state: 0xf8,
|
||||||
},
|
},
|
||||||
|
|
@ -1729,7 +1676,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(51),
|
index: StatePartIndex<BigSlots>(51),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfc,
|
state: 0xfc,
|
||||||
last_state: 0xfc,
|
last_state: 0xfc,
|
||||||
},
|
},
|
||||||
|
|
@ -1739,7 +1685,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(52),
|
index: StatePartIndex<BigSlots>(52),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xfe,
|
state: 0xfe,
|
||||||
last_state: 0xe1,
|
last_state: 0xe1,
|
||||||
},
|
},
|
||||||
|
|
@ -1761,6 +1706,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,283 +1,283 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module array_rw $end
|
$scope module array_rw $end
|
||||||
$scope struct array_in $end
|
$scope struct array_in $end
|
||||||
$var wire 8 Yvfu^ \[0] $end
|
$var wire 8 ! \[0] $end
|
||||||
$var wire 8 |Cs`W \[1] $end
|
$var wire 8 " \[1] $end
|
||||||
$var wire 8 M!nsb \[2] $end
|
$var wire 8 # \[2] $end
|
||||||
$var wire 8 59L{w \[3] $end
|
$var wire 8 $ \[3] $end
|
||||||
$var wire 8 o2+|F \[4] $end
|
$var wire 8 % \[4] $end
|
||||||
$var wire 8 ikzV5 \[5] $end
|
$var wire 8 & \[5] $end
|
||||||
$var wire 8 [E$Z* \[6] $end
|
$var wire 8 ' \[6] $end
|
||||||
$var wire 8 ?"~01 \[7] $end
|
$var wire 8 ( \[7] $end
|
||||||
$var wire 8 /kghT \[8] $end
|
$var wire 8 ) \[8] $end
|
||||||
$var wire 8 +}(9) \[9] $end
|
$var wire 8 * \[9] $end
|
||||||
$var wire 8 iMP}= \[10] $end
|
$var wire 8 + \[10] $end
|
||||||
$var wire 8 2M0tL \[11] $end
|
$var wire 8 , \[11] $end
|
||||||
$var wire 8 :AjkA \[12] $end
|
$var wire 8 - \[12] $end
|
||||||
$var wire 8 VM_:8 \[13] $end
|
$var wire 8 . \[13] $end
|
||||||
$var wire 8 UveL2 \[14] $end
|
$var wire 8 / \[14] $end
|
||||||
$var wire 8 A)9Z6 \[15] $end
|
$var wire 8 0 \[15] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct array_out $end
|
$scope struct array_out $end
|
||||||
$var wire 8 2zdj1 \[0] $end
|
$var wire 8 1 \[0] $end
|
||||||
$var wire 8 =;m_[ \[1] $end
|
$var wire 8 2 \[1] $end
|
||||||
$var wire 8 @9Hd \[2] $end
|
$var wire 8 3 \[2] $end
|
||||||
$var wire 8 C:="| \[3] $end
|
$var wire 8 4 \[3] $end
|
||||||
$var wire 8 IDk7# \[4] $end
|
$var wire 8 5 \[4] $end
|
||||||
$var wire 8 i]E1i \[5] $end
|
$var wire 8 6 \[5] $end
|
||||||
$var wire 8 tK,M] \[6] $end
|
$var wire 8 7 \[6] $end
|
||||||
$var wire 8 tGp!\ \[7] $end
|
$var wire 8 8 \[7] $end
|
||||||
$var wire 8 ."qjK \[8] $end
|
$var wire 8 9 \[8] $end
|
||||||
$var wire 8 AUO:R \[9] $end
|
$var wire 8 : \[9] $end
|
||||||
$var wire 8 'kx`n \[10] $end
|
$var wire 8 ; \[10] $end
|
||||||
$var wire 8 U&(K\ \[11] $end
|
$var wire 8 < \[11] $end
|
||||||
$var wire 8 q<O41 \[12] $end
|
$var wire 8 = \[12] $end
|
||||||
$var wire 8 zvj)] \[13] $end
|
$var wire 8 > \[13] $end
|
||||||
$var wire 8 >0H<( \[14] $end
|
$var wire 8 ? \[14] $end
|
||||||
$var wire 8 ARhXJ \[15] $end
|
$var wire 8 @ \[15] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 8 -n:7@ read_index $end
|
$var wire 8 A read_index $end
|
||||||
$var wire 8 >h<=Z read_data $end
|
$var wire 8 B read_data $end
|
||||||
$var wire 8 [xld3 write_index $end
|
$var wire 8 C write_index $end
|
||||||
$var wire 8 J+DYh write_data $end
|
$var wire 8 D write_data $end
|
||||||
$var wire 1 z,@WW write_en $end
|
$var wire 1 E write_en $end
|
||||||
$scope struct array_wire $end
|
$scope struct array_wire $end
|
||||||
$var wire 8 B{KJS \[0] $end
|
$var wire 8 F \[0] $end
|
||||||
$var wire 8 V'K*& \[1] $end
|
$var wire 8 G \[1] $end
|
||||||
$var wire 8 4zI$O \[2] $end
|
$var wire 8 H \[2] $end
|
||||||
$var wire 8 %TTk[ \[3] $end
|
$var wire 8 I \[3] $end
|
||||||
$var wire 8 IgSeY \[4] $end
|
$var wire 8 J \[4] $end
|
||||||
$var wire 8 &&1T" \[5] $end
|
$var wire 8 K \[5] $end
|
||||||
$var wire 8 5)-l\ \[6] $end
|
$var wire 8 L \[6] $end
|
||||||
$var wire 8 0RsLb \[7] $end
|
$var wire 8 M \[7] $end
|
||||||
$var wire 8 T>:}D \[8] $end
|
$var wire 8 N \[8] $end
|
||||||
$var wire 8 DPpZ* \[9] $end
|
$var wire 8 O \[9] $end
|
||||||
$var wire 8 %E(nf \[10] $end
|
$var wire 8 P \[10] $end
|
||||||
$var wire 8 2'pba \[11] $end
|
$var wire 8 Q \[11] $end
|
||||||
$var wire 8 e/c1: \[12] $end
|
$var wire 8 R \[12] $end
|
||||||
$var wire 8 ;w.C7 \[13] $end
|
$var wire 8 S \[13] $end
|
||||||
$var wire 8 fwdfu \[14] $end
|
$var wire 8 T \[14] $end
|
||||||
$var wire 8 *R\vx \[15] $end
|
$var wire 8 U \[15] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
b11111111 Yvfu^
|
b11111111 !
|
||||||
b1111111 |Cs`W
|
b1111111 "
|
||||||
b111111 M!nsb
|
b111111 #
|
||||||
b11111 59L{w
|
b11111 $
|
||||||
b1111 o2+|F
|
b1111 %
|
||||||
b111 ikzV5
|
b111 &
|
||||||
b11 [E$Z*
|
b11 '
|
||||||
b1 ?"~01
|
b1 (
|
||||||
b0 /kghT
|
b0 )
|
||||||
b10000000 +}(9)
|
b10000000 *
|
||||||
b11000000 iMP}=
|
b11000000 +
|
||||||
b11100000 2M0tL
|
b11100000 ,
|
||||||
b11110000 :AjkA
|
b11110000 -
|
||||||
b11111000 VM_:8
|
b11111000 .
|
||||||
b11111100 UveL2
|
b11111100 /
|
||||||
b11111110 A)9Z6
|
b11111110 0
|
||||||
b11111111 2zdj1
|
b11111111 1
|
||||||
b1111111 =;m_[
|
b1111111 2
|
||||||
b111111 @9Hd
|
b111111 3
|
||||||
b11111 C:="|
|
b11111 4
|
||||||
b1111 IDk7#
|
b1111 5
|
||||||
b111 i]E1i
|
b111 6
|
||||||
b11 tK,M]
|
b11 7
|
||||||
b1 tGp!\
|
b1 8
|
||||||
b0 ."qjK
|
b0 9
|
||||||
b10000000 AUO:R
|
b10000000 :
|
||||||
b11000000 'kx`n
|
b11000000 ;
|
||||||
b11100000 U&(K\
|
b11100000 <
|
||||||
b11110000 q<O41
|
b11110000 =
|
||||||
b11111000 zvj)]
|
b11111000 >
|
||||||
b11111100 >0H<(
|
b11111100 ?
|
||||||
b11111110 ARhXJ
|
b11111110 @
|
||||||
b0 -n:7@
|
b0 A
|
||||||
b11111111 >h<=Z
|
b11111111 B
|
||||||
b0 [xld3
|
b0 C
|
||||||
b0 J+DYh
|
b0 D
|
||||||
0z,@WW
|
0E
|
||||||
b11111111 B{KJS
|
b11111111 F
|
||||||
b1111111 V'K*&
|
b1111111 G
|
||||||
b111111 4zI$O
|
b111111 H
|
||||||
b11111 %TTk[
|
b11111 I
|
||||||
b1111 IgSeY
|
b1111 J
|
||||||
b111 &&1T"
|
b111 K
|
||||||
b11 5)-l\
|
b11 L
|
||||||
b1 0RsLb
|
b1 M
|
||||||
b0 T>:}D
|
b0 N
|
||||||
b10000000 DPpZ*
|
b10000000 O
|
||||||
b11000000 %E(nf
|
b11000000 P
|
||||||
b11100000 2'pba
|
b11100000 Q
|
||||||
b11110000 e/c1:
|
b11110000 R
|
||||||
b11111000 ;w.C7
|
b11111000 S
|
||||||
b11111100 fwdfu
|
b11111100 T
|
||||||
b11111110 *R\vx
|
b11111110 U
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
b1 -n:7@
|
b1 A
|
||||||
b1111111 >h<=Z
|
b1111111 B
|
||||||
#2000000
|
#2000000
|
||||||
b10 -n:7@
|
b10 A
|
||||||
b111111 >h<=Z
|
b111111 B
|
||||||
#3000000
|
#3000000
|
||||||
b11 -n:7@
|
b11 A
|
||||||
b11111 >h<=Z
|
b11111 B
|
||||||
#4000000
|
#4000000
|
||||||
b100 -n:7@
|
b100 A
|
||||||
b1111 >h<=Z
|
b1111 B
|
||||||
#5000000
|
#5000000
|
||||||
b101 -n:7@
|
b101 A
|
||||||
b111 >h<=Z
|
b111 B
|
||||||
#6000000
|
#6000000
|
||||||
b110 -n:7@
|
b110 A
|
||||||
b11 >h<=Z
|
b11 B
|
||||||
#7000000
|
#7000000
|
||||||
b111 -n:7@
|
b111 A
|
||||||
b1 >h<=Z
|
b1 B
|
||||||
#8000000
|
#8000000
|
||||||
b1000 -n:7@
|
b1000 A
|
||||||
b0 >h<=Z
|
b0 B
|
||||||
#9000000
|
#9000000
|
||||||
b1001 -n:7@
|
b1001 A
|
||||||
b10000000 >h<=Z
|
b10000000 B
|
||||||
#10000000
|
#10000000
|
||||||
b1010 -n:7@
|
b1010 A
|
||||||
b11000000 >h<=Z
|
b11000000 B
|
||||||
#11000000
|
#11000000
|
||||||
b1011 -n:7@
|
b1011 A
|
||||||
b11100000 >h<=Z
|
b11100000 B
|
||||||
#12000000
|
#12000000
|
||||||
b1100 -n:7@
|
b1100 A
|
||||||
b11110000 >h<=Z
|
b11110000 B
|
||||||
#13000000
|
#13000000
|
||||||
b1101 -n:7@
|
b1101 A
|
||||||
b11111000 >h<=Z
|
b11111000 B
|
||||||
#14000000
|
#14000000
|
||||||
b1110 -n:7@
|
b1110 A
|
||||||
b11111100 >h<=Z
|
b11111100 B
|
||||||
#15000000
|
#15000000
|
||||||
b1111 -n:7@
|
b1111 A
|
||||||
b11111110 >h<=Z
|
b11111110 B
|
||||||
#16000000
|
#16000000
|
||||||
b10000 -n:7@
|
b10000 A
|
||||||
b0 >h<=Z
|
b0 B
|
||||||
#17000000
|
#17000000
|
||||||
b0 2zdj1
|
b0 1
|
||||||
b0 -n:7@
|
b0 A
|
||||||
1z,@WW
|
1E
|
||||||
b0 B{KJS
|
b0 F
|
||||||
#18000000
|
#18000000
|
||||||
b11111111 2zdj1
|
b11111111 1
|
||||||
b1 =;m_[
|
b1 2
|
||||||
b11111111 >h<=Z
|
b11111111 B
|
||||||
b1 [xld3
|
b1 C
|
||||||
b1 J+DYh
|
b1 D
|
||||||
b11111111 B{KJS
|
b11111111 F
|
||||||
b1 V'K*&
|
b1 G
|
||||||
#19000000
|
#19000000
|
||||||
b1111111 =;m_[
|
b1111111 2
|
||||||
b100 @9Hd
|
b100 3
|
||||||
b10 [xld3
|
b10 C
|
||||||
b100 J+DYh
|
b100 D
|
||||||
b1111111 V'K*&
|
b1111111 G
|
||||||
b100 4zI$O
|
b100 H
|
||||||
#20000000
|
#20000000
|
||||||
b111111 @9Hd
|
b111111 3
|
||||||
b1001 C:="|
|
b1001 4
|
||||||
b11 [xld3
|
b11 C
|
||||||
b1001 J+DYh
|
b1001 D
|
||||||
b111111 4zI$O
|
b111111 H
|
||||||
b1001 %TTk[
|
b1001 I
|
||||||
#21000000
|
#21000000
|
||||||
b11111 C:="|
|
b11111 4
|
||||||
b10000 IDk7#
|
b10000 5
|
||||||
b100 [xld3
|
b100 C
|
||||||
b10000 J+DYh
|
b10000 D
|
||||||
b11111 %TTk[
|
b11111 I
|
||||||
b10000 IgSeY
|
b10000 J
|
||||||
#22000000
|
#22000000
|
||||||
b1111 IDk7#
|
b1111 5
|
||||||
b11001 i]E1i
|
b11001 6
|
||||||
b101 [xld3
|
b101 C
|
||||||
b11001 J+DYh
|
b11001 D
|
||||||
b1111 IgSeY
|
b1111 J
|
||||||
b11001 &&1T"
|
b11001 K
|
||||||
#23000000
|
#23000000
|
||||||
b111 i]E1i
|
b111 6
|
||||||
b100100 tK,M]
|
b100100 7
|
||||||
b110 [xld3
|
b110 C
|
||||||
b100100 J+DYh
|
b100100 D
|
||||||
b111 &&1T"
|
b111 K
|
||||||
b100100 5)-l\
|
b100100 L
|
||||||
#24000000
|
#24000000
|
||||||
b11 tK,M]
|
b11 7
|
||||||
b110001 tGp!\
|
b110001 8
|
||||||
b111 [xld3
|
b111 C
|
||||||
b110001 J+DYh
|
b110001 D
|
||||||
b11 5)-l\
|
b11 L
|
||||||
b110001 0RsLb
|
b110001 M
|
||||||
#25000000
|
#25000000
|
||||||
b1 tGp!\
|
b1 8
|
||||||
b1000000 ."qjK
|
b1000000 9
|
||||||
b1000 [xld3
|
b1000 C
|
||||||
b1000000 J+DYh
|
b1000000 D
|
||||||
b1 0RsLb
|
b1 M
|
||||||
b1000000 T>:}D
|
b1000000 N
|
||||||
#26000000
|
#26000000
|
||||||
b0 ."qjK
|
b0 9
|
||||||
b1010001 AUO:R
|
b1010001 :
|
||||||
b1001 [xld3
|
b1001 C
|
||||||
b1010001 J+DYh
|
b1010001 D
|
||||||
b0 T>:}D
|
b0 N
|
||||||
b1010001 DPpZ*
|
b1010001 O
|
||||||
#27000000
|
#27000000
|
||||||
b10000000 AUO:R
|
b10000000 :
|
||||||
b1100100 'kx`n
|
b1100100 ;
|
||||||
b1010 [xld3
|
b1010 C
|
||||||
b1100100 J+DYh
|
b1100100 D
|
||||||
b10000000 DPpZ*
|
b10000000 O
|
||||||
b1100100 %E(nf
|
b1100100 P
|
||||||
#28000000
|
#28000000
|
||||||
b11000000 'kx`n
|
b11000000 ;
|
||||||
b1111001 U&(K\
|
b1111001 <
|
||||||
b1011 [xld3
|
b1011 C
|
||||||
b1111001 J+DYh
|
b1111001 D
|
||||||
b11000000 %E(nf
|
b11000000 P
|
||||||
b1111001 2'pba
|
b1111001 Q
|
||||||
#29000000
|
#29000000
|
||||||
b11100000 U&(K\
|
b11100000 <
|
||||||
b10010000 q<O41
|
b10010000 =
|
||||||
b1100 [xld3
|
b1100 C
|
||||||
b10010000 J+DYh
|
b10010000 D
|
||||||
b11100000 2'pba
|
b11100000 Q
|
||||||
b10010000 e/c1:
|
b10010000 R
|
||||||
#30000000
|
#30000000
|
||||||
b11110000 q<O41
|
b11110000 =
|
||||||
b10101001 zvj)]
|
b10101001 >
|
||||||
b1101 [xld3
|
b1101 C
|
||||||
b10101001 J+DYh
|
b10101001 D
|
||||||
b11110000 e/c1:
|
b11110000 R
|
||||||
b10101001 ;w.C7
|
b10101001 S
|
||||||
#31000000
|
#31000000
|
||||||
b11111000 zvj)]
|
b11111000 >
|
||||||
b11000100 >0H<(
|
b11000100 ?
|
||||||
b1110 [xld3
|
b1110 C
|
||||||
b11000100 J+DYh
|
b11000100 D
|
||||||
b11111000 ;w.C7
|
b11111000 S
|
||||||
b11000100 fwdfu
|
b11000100 T
|
||||||
#32000000
|
#32000000
|
||||||
b11111100 >0H<(
|
b11111100 ?
|
||||||
b11100001 ARhXJ
|
b11100001 @
|
||||||
b1111 [xld3
|
b1111 C
|
||||||
b11100001 J+DYh
|
b11100001 D
|
||||||
b11111100 fwdfu
|
b11111100 T
|
||||||
b11100001 *R\vx
|
b11100001 U
|
||||||
#33000000
|
#33000000
|
||||||
b11111110 ARhXJ
|
b11111110 @
|
||||||
b10000 [xld3
|
b10000 C
|
||||||
b0 J+DYh
|
b0 D
|
||||||
b11111110 *R\vx
|
b11111110 U
|
||||||
#34000000
|
#34000000
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 5,
|
pc: 5,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -102,7 +101,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -157,7 +155,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -166,7 +163,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -188,6 +184,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module conditional_assignment_last $end
|
$scope module conditional_assignment_last $end
|
||||||
$var wire 1 xt~(W i $end
|
$var wire 1 ! i $end
|
||||||
$var wire 1 6:7im w $end
|
$var wire 1 " w $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
0xt~(W
|
0!
|
||||||
16:7im
|
1"
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
1xt~(W
|
1!
|
||||||
06:7im
|
0"
|
||||||
#2000000
|
#2000000
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 2,
|
pc: 2,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -78,7 +77,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -126,7 +124,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x05,
|
state: 0x05,
|
||||||
last_state: 0x05,
|
last_state: 0x05,
|
||||||
},
|
},
|
||||||
|
|
@ -140,6 +137,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 5,
|
pc: 5,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -107,7 +106,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -177,7 +175,6 @@ Simulation {
|
||||||
kind: BigAsyncReset {
|
kind: BigAsyncReset {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -186,7 +183,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -208,6 +204,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module connect_const_reset $end
|
$scope module connect_const_reset $end
|
||||||
$var wire 1 8ke|= reset_out $end
|
$var wire 1 ! reset_out $end
|
||||||
$var wire 1 {"c@= bit_out $end
|
$var wire 1 " bit_out $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
18ke|=
|
1!
|
||||||
1{"c@=
|
1"
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
|
|
|
||||||
|
|
@ -123,64 +123,59 @@ Simulation {
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
8: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
|
||||||
src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
9: Add {
|
8: Add {
|
||||||
dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
dest: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
||||||
lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
lhs: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
rhs: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
rhs: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
},
|
},
|
||||||
10: CastToUInt {
|
9: CastToUInt {
|
||||||
dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
||||||
dest_width: 4,
|
dest_width: 4,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:4:1
|
// at: module-XXXXXXXXXX.rs:4:1
|
||||||
11: Copy {
|
10: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:6:1
|
// at: module-XXXXXXXXXX.rs:6:1
|
||||||
12: Copy {
|
11: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:3:1
|
// at: module-XXXXXXXXXX.rs:3:1
|
||||||
13: BranchIfSmallNonZero {
|
12: BranchIfSmallNonZero {
|
||||||
target: 17,
|
target: 16,
|
||||||
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
14: BranchIfSmallZero {
|
13: BranchIfSmallZero {
|
||||||
target: 18,
|
target: 17,
|
||||||
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
15: Copy {
|
14: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
16: Branch {
|
15: Branch {
|
||||||
target: 18,
|
target: 17,
|
||||||
},
|
},
|
||||||
17: Copy {
|
16: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
18: XorSmallImmediate {
|
17: XorSmallImmediate {
|
||||||
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
rhs: 0x1,
|
rhs: 0x1,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
19: Return,
|
18: Return,
|
||||||
],
|
],
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
pc: 19,
|
pc: 18,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -217,7 +212,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -334,7 +328,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -343,7 +336,6 @@ Simulation {
|
||||||
kind: BigAsyncReset {
|
kind: BigAsyncReset {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -353,7 +345,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -363,7 +354,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -387,6 +377,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,217 +1,217 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module counter $end
|
$scope module counter $end
|
||||||
$scope struct cd $end
|
$scope struct cd $end
|
||||||
$var wire 1 `[J;" clk $end
|
$var wire 1 ! clk $end
|
||||||
$var wire 1 4pZx7 rst $end
|
$var wire 1 " rst $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 4 rPs;{ count $end
|
$var wire 4 # count $end
|
||||||
$var reg 4 6_+(g count_reg $end
|
$var reg 4 $ count_reg $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
0`[J;"
|
0!
|
||||||
04pZx7
|
0"
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
$end
|
$end
|
||||||
#500000
|
#500000
|
||||||
14pZx7
|
1"
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
#1000000
|
#1000000
|
||||||
1`[J;"
|
1!
|
||||||
#1500000
|
#1500000
|
||||||
04pZx7
|
0"
|
||||||
#2000000
|
#2000000
|
||||||
0`[J;"
|
0!
|
||||||
#3000000
|
#3000000
|
||||||
1`[J;"
|
1!
|
||||||
b100 rPs;{
|
b100 #
|
||||||
b100 6_+(g
|
b100 $
|
||||||
#4000000
|
#4000000
|
||||||
0`[J;"
|
0!
|
||||||
#5000000
|
#5000000
|
||||||
1`[J;"
|
1!
|
||||||
b101 rPs;{
|
b101 #
|
||||||
b101 6_+(g
|
b101 $
|
||||||
#6000000
|
#6000000
|
||||||
0`[J;"
|
0!
|
||||||
#7000000
|
#7000000
|
||||||
1`[J;"
|
1!
|
||||||
b110 rPs;{
|
b110 #
|
||||||
b110 6_+(g
|
b110 $
|
||||||
#8000000
|
#8000000
|
||||||
0`[J;"
|
0!
|
||||||
#9000000
|
#9000000
|
||||||
1`[J;"
|
1!
|
||||||
b111 rPs;{
|
b111 #
|
||||||
b111 6_+(g
|
b111 $
|
||||||
#10000000
|
#10000000
|
||||||
0`[J;"
|
0!
|
||||||
#11000000
|
#11000000
|
||||||
1`[J;"
|
1!
|
||||||
b1000 rPs;{
|
b1000 #
|
||||||
b1000 6_+(g
|
b1000 $
|
||||||
#12000000
|
#12000000
|
||||||
0`[J;"
|
0!
|
||||||
#13000000
|
#13000000
|
||||||
1`[J;"
|
1!
|
||||||
b1001 rPs;{
|
b1001 #
|
||||||
b1001 6_+(g
|
b1001 $
|
||||||
#14000000
|
#14000000
|
||||||
0`[J;"
|
0!
|
||||||
#15000000
|
#15000000
|
||||||
1`[J;"
|
1!
|
||||||
b1010 rPs;{
|
b1010 #
|
||||||
b1010 6_+(g
|
b1010 $
|
||||||
#16000000
|
#16000000
|
||||||
0`[J;"
|
0!
|
||||||
#17000000
|
#17000000
|
||||||
1`[J;"
|
1!
|
||||||
b1011 rPs;{
|
b1011 #
|
||||||
b1011 6_+(g
|
b1011 $
|
||||||
#18000000
|
#18000000
|
||||||
0`[J;"
|
0!
|
||||||
#19000000
|
#19000000
|
||||||
1`[J;"
|
1!
|
||||||
b1100 rPs;{
|
b1100 #
|
||||||
b1100 6_+(g
|
b1100 $
|
||||||
#20000000
|
#20000000
|
||||||
0`[J;"
|
0!
|
||||||
#21000000
|
#21000000
|
||||||
1`[J;"
|
1!
|
||||||
b1101 rPs;{
|
b1101 #
|
||||||
b1101 6_+(g
|
b1101 $
|
||||||
#22000000
|
#22000000
|
||||||
0`[J;"
|
0!
|
||||||
#23000000
|
#23000000
|
||||||
1`[J;"
|
1!
|
||||||
b1110 rPs;{
|
b1110 #
|
||||||
b1110 6_+(g
|
b1110 $
|
||||||
#24000000
|
#24000000
|
||||||
0`[J;"
|
0!
|
||||||
#25000000
|
#25000000
|
||||||
1`[J;"
|
1!
|
||||||
b1111 rPs;{
|
b1111 #
|
||||||
b1111 6_+(g
|
b1111 $
|
||||||
#26000000
|
#26000000
|
||||||
0`[J;"
|
0!
|
||||||
#27000000
|
#27000000
|
||||||
1`[J;"
|
1!
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
#28000000
|
#28000000
|
||||||
0`[J;"
|
0!
|
||||||
#29000000
|
#29000000
|
||||||
1`[J;"
|
1!
|
||||||
b1 rPs;{
|
b1 #
|
||||||
b1 6_+(g
|
b1 $
|
||||||
#30000000
|
#30000000
|
||||||
0`[J;"
|
0!
|
||||||
#31000000
|
#31000000
|
||||||
1`[J;"
|
1!
|
||||||
b10 rPs;{
|
b10 #
|
||||||
b10 6_+(g
|
b10 $
|
||||||
#32000000
|
#32000000
|
||||||
0`[J;"
|
0!
|
||||||
#33000000
|
#33000000
|
||||||
1`[J;"
|
1!
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
#34000000
|
#34000000
|
||||||
0`[J;"
|
0!
|
||||||
#35000000
|
#35000000
|
||||||
1`[J;"
|
1!
|
||||||
b100 rPs;{
|
b100 #
|
||||||
b100 6_+(g
|
b100 $
|
||||||
#36000000
|
#36000000
|
||||||
0`[J;"
|
0!
|
||||||
#37000000
|
#37000000
|
||||||
1`[J;"
|
1!
|
||||||
b101 rPs;{
|
b101 #
|
||||||
b101 6_+(g
|
b101 $
|
||||||
#38000000
|
#38000000
|
||||||
0`[J;"
|
0!
|
||||||
#39000000
|
#39000000
|
||||||
1`[J;"
|
1!
|
||||||
b110 rPs;{
|
b110 #
|
||||||
b110 6_+(g
|
b110 $
|
||||||
#40000000
|
#40000000
|
||||||
0`[J;"
|
0!
|
||||||
#41000000
|
#41000000
|
||||||
1`[J;"
|
1!
|
||||||
b111 rPs;{
|
b111 #
|
||||||
b111 6_+(g
|
b111 $
|
||||||
#42000000
|
#42000000
|
||||||
0`[J;"
|
0!
|
||||||
#43000000
|
#43000000
|
||||||
1`[J;"
|
1!
|
||||||
b1000 rPs;{
|
b1000 #
|
||||||
b1000 6_+(g
|
b1000 $
|
||||||
#44000000
|
#44000000
|
||||||
0`[J;"
|
0!
|
||||||
#45000000
|
#45000000
|
||||||
1`[J;"
|
1!
|
||||||
b1001 rPs;{
|
b1001 #
|
||||||
b1001 6_+(g
|
b1001 $
|
||||||
#46000000
|
#46000000
|
||||||
0`[J;"
|
0!
|
||||||
#47000000
|
#47000000
|
||||||
1`[J;"
|
1!
|
||||||
b1010 rPs;{
|
b1010 #
|
||||||
b1010 6_+(g
|
b1010 $
|
||||||
#48000000
|
#48000000
|
||||||
0`[J;"
|
0!
|
||||||
#49000000
|
#49000000
|
||||||
1`[J;"
|
1!
|
||||||
b1011 rPs;{
|
b1011 #
|
||||||
b1011 6_+(g
|
b1011 $
|
||||||
#50000000
|
#50000000
|
||||||
0`[J;"
|
0!
|
||||||
#51000000
|
#51000000
|
||||||
1`[J;"
|
1!
|
||||||
b1100 rPs;{
|
b1100 #
|
||||||
b1100 6_+(g
|
b1100 $
|
||||||
#52000000
|
#52000000
|
||||||
0`[J;"
|
0!
|
||||||
#53000000
|
#53000000
|
||||||
1`[J;"
|
1!
|
||||||
b1101 rPs;{
|
b1101 #
|
||||||
b1101 6_+(g
|
b1101 $
|
||||||
#54000000
|
#54000000
|
||||||
0`[J;"
|
0!
|
||||||
#55000000
|
#55000000
|
||||||
1`[J;"
|
1!
|
||||||
b1110 rPs;{
|
b1110 #
|
||||||
b1110 6_+(g
|
b1110 $
|
||||||
#56000000
|
#56000000
|
||||||
0`[J;"
|
0!
|
||||||
#57000000
|
#57000000
|
||||||
1`[J;"
|
1!
|
||||||
b1111 rPs;{
|
b1111 #
|
||||||
b1111 6_+(g
|
b1111 $
|
||||||
#58000000
|
#58000000
|
||||||
0`[J;"
|
0!
|
||||||
#59000000
|
#59000000
|
||||||
1`[J;"
|
1!
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
#60000000
|
#60000000
|
||||||
0`[J;"
|
0!
|
||||||
#61000000
|
#61000000
|
||||||
1`[J;"
|
1!
|
||||||
b1 rPs;{
|
b1 #
|
||||||
b1 6_+(g
|
b1 $
|
||||||
#62000000
|
#62000000
|
||||||
0`[J;"
|
0!
|
||||||
#63000000
|
#63000000
|
||||||
1`[J;"
|
1!
|
||||||
b10 rPs;{
|
b10 #
|
||||||
b10 6_+(g
|
b10 $
|
||||||
#64000000
|
#64000000
|
||||||
0`[J;"
|
0!
|
||||||
#65000000
|
#65000000
|
||||||
1`[J;"
|
1!
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
#66000000
|
#66000000
|
||||||
|
|
|
||||||
|
|
@ -102,67 +102,62 @@ Simulation {
|
||||||
src: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
src: StatePartIndex<BigSlots>(7), // (0x4) SlotDebugData { name: "", ty: UInt<5> },
|
||||||
dest_width: 4,
|
dest_width: 4,
|
||||||
},
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:4:1
|
||||||
|
4: Copy {
|
||||||
|
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
||||||
|
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:3:1
|
// at: module-XXXXXXXXXX.rs:3:1
|
||||||
4: IsNonZeroDestIsSmall {
|
5: IsNonZeroDestIsSmall {
|
||||||
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset },
|
src: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset },
|
||||||
},
|
},
|
||||||
5: IsNonZeroDestIsSmall {
|
6: IsNonZeroDestIsSmall {
|
||||||
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
|
src: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock },
|
||||||
},
|
},
|
||||||
6: AndSmall {
|
7: AndSmall {
|
||||||
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
rhs: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
7: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
|
||||||
src: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:4:1
|
|
||||||
8: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
|
||||||
src: StatePartIndex<BigSlots>(8), // (0x4) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
9: Const {
|
8: Const {
|
||||||
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
value: 0x3,
|
value: 0x3,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:3:1
|
// at: module-XXXXXXXXXX.rs:3:1
|
||||||
10: BranchIfSmallZero {
|
9: BranchIfSmallZero {
|
||||||
target: 15,
|
target: 14,
|
||||||
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
11: BranchIfSmallNonZero {
|
10: BranchIfSmallNonZero {
|
||||||
target: 14,
|
target: 13,
|
||||||
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
12: Copy {
|
11: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
13: Branch {
|
12: Branch {
|
||||||
target: 15,
|
target: 14,
|
||||||
},
|
},
|
||||||
14: Copy {
|
13: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
dest: StatePartIndex<BigSlots>(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> },
|
||||||
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
src: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> },
|
||||||
},
|
},
|
||||||
15: XorSmallImmediate {
|
14: XorSmallImmediate {
|
||||||
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
lhs: StatePartIndex<SmallSlots>(2), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
rhs: 0x1,
|
rhs: 0x1,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
16: Return,
|
15: Return,
|
||||||
],
|
],
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
pc: 16,
|
pc: 15,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -198,7 +193,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -315,7 +309,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -324,7 +317,6 @@ Simulation {
|
||||||
kind: BigSyncReset {
|
kind: BigSyncReset {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -334,7 +326,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -344,7 +335,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -368,6 +358,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,214 +1,214 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module counter $end
|
$scope module counter $end
|
||||||
$scope struct cd $end
|
$scope struct cd $end
|
||||||
$var wire 1 `[J;" clk $end
|
$var wire 1 ! clk $end
|
||||||
$var wire 1 4pZx7 rst $end
|
$var wire 1 " rst $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 4 rPs;{ count $end
|
$var wire 4 # count $end
|
||||||
$var reg 4 6_+(g count_reg $end
|
$var reg 4 $ count_reg $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
0`[J;"
|
0!
|
||||||
14pZx7
|
1"
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
1`[J;"
|
1!
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
04pZx7
|
0"
|
||||||
#2000000
|
#2000000
|
||||||
0`[J;"
|
0!
|
||||||
#3000000
|
#3000000
|
||||||
1`[J;"
|
1!
|
||||||
b100 rPs;{
|
b100 #
|
||||||
b100 6_+(g
|
b100 $
|
||||||
#4000000
|
#4000000
|
||||||
0`[J;"
|
0!
|
||||||
#5000000
|
#5000000
|
||||||
1`[J;"
|
1!
|
||||||
b101 rPs;{
|
b101 #
|
||||||
b101 6_+(g
|
b101 $
|
||||||
#6000000
|
#6000000
|
||||||
0`[J;"
|
0!
|
||||||
#7000000
|
#7000000
|
||||||
1`[J;"
|
1!
|
||||||
b110 rPs;{
|
b110 #
|
||||||
b110 6_+(g
|
b110 $
|
||||||
#8000000
|
#8000000
|
||||||
0`[J;"
|
0!
|
||||||
#9000000
|
#9000000
|
||||||
1`[J;"
|
1!
|
||||||
b111 rPs;{
|
b111 #
|
||||||
b111 6_+(g
|
b111 $
|
||||||
#10000000
|
#10000000
|
||||||
0`[J;"
|
0!
|
||||||
#11000000
|
#11000000
|
||||||
1`[J;"
|
1!
|
||||||
b1000 rPs;{
|
b1000 #
|
||||||
b1000 6_+(g
|
b1000 $
|
||||||
#12000000
|
#12000000
|
||||||
0`[J;"
|
0!
|
||||||
#13000000
|
#13000000
|
||||||
1`[J;"
|
1!
|
||||||
b1001 rPs;{
|
b1001 #
|
||||||
b1001 6_+(g
|
b1001 $
|
||||||
#14000000
|
#14000000
|
||||||
0`[J;"
|
0!
|
||||||
#15000000
|
#15000000
|
||||||
1`[J;"
|
1!
|
||||||
b1010 rPs;{
|
b1010 #
|
||||||
b1010 6_+(g
|
b1010 $
|
||||||
#16000000
|
#16000000
|
||||||
0`[J;"
|
0!
|
||||||
#17000000
|
#17000000
|
||||||
1`[J;"
|
1!
|
||||||
b1011 rPs;{
|
b1011 #
|
||||||
b1011 6_+(g
|
b1011 $
|
||||||
#18000000
|
#18000000
|
||||||
0`[J;"
|
0!
|
||||||
#19000000
|
#19000000
|
||||||
1`[J;"
|
1!
|
||||||
b1100 rPs;{
|
b1100 #
|
||||||
b1100 6_+(g
|
b1100 $
|
||||||
#20000000
|
#20000000
|
||||||
0`[J;"
|
0!
|
||||||
#21000000
|
#21000000
|
||||||
1`[J;"
|
1!
|
||||||
b1101 rPs;{
|
b1101 #
|
||||||
b1101 6_+(g
|
b1101 $
|
||||||
#22000000
|
#22000000
|
||||||
0`[J;"
|
0!
|
||||||
#23000000
|
#23000000
|
||||||
1`[J;"
|
1!
|
||||||
b1110 rPs;{
|
b1110 #
|
||||||
b1110 6_+(g
|
b1110 $
|
||||||
#24000000
|
#24000000
|
||||||
0`[J;"
|
0!
|
||||||
#25000000
|
#25000000
|
||||||
1`[J;"
|
1!
|
||||||
b1111 rPs;{
|
b1111 #
|
||||||
b1111 6_+(g
|
b1111 $
|
||||||
#26000000
|
#26000000
|
||||||
0`[J;"
|
0!
|
||||||
#27000000
|
#27000000
|
||||||
1`[J;"
|
1!
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
#28000000
|
#28000000
|
||||||
0`[J;"
|
0!
|
||||||
#29000000
|
#29000000
|
||||||
1`[J;"
|
1!
|
||||||
b1 rPs;{
|
b1 #
|
||||||
b1 6_+(g
|
b1 $
|
||||||
#30000000
|
#30000000
|
||||||
0`[J;"
|
0!
|
||||||
#31000000
|
#31000000
|
||||||
1`[J;"
|
1!
|
||||||
b10 rPs;{
|
b10 #
|
||||||
b10 6_+(g
|
b10 $
|
||||||
#32000000
|
#32000000
|
||||||
0`[J;"
|
0!
|
||||||
#33000000
|
#33000000
|
||||||
1`[J;"
|
1!
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
#34000000
|
#34000000
|
||||||
0`[J;"
|
0!
|
||||||
#35000000
|
#35000000
|
||||||
1`[J;"
|
1!
|
||||||
b100 rPs;{
|
b100 #
|
||||||
b100 6_+(g
|
b100 $
|
||||||
#36000000
|
#36000000
|
||||||
0`[J;"
|
0!
|
||||||
#37000000
|
#37000000
|
||||||
1`[J;"
|
1!
|
||||||
b101 rPs;{
|
b101 #
|
||||||
b101 6_+(g
|
b101 $
|
||||||
#38000000
|
#38000000
|
||||||
0`[J;"
|
0!
|
||||||
#39000000
|
#39000000
|
||||||
1`[J;"
|
1!
|
||||||
b110 rPs;{
|
b110 #
|
||||||
b110 6_+(g
|
b110 $
|
||||||
#40000000
|
#40000000
|
||||||
0`[J;"
|
0!
|
||||||
#41000000
|
#41000000
|
||||||
1`[J;"
|
1!
|
||||||
b111 rPs;{
|
b111 #
|
||||||
b111 6_+(g
|
b111 $
|
||||||
#42000000
|
#42000000
|
||||||
0`[J;"
|
0!
|
||||||
#43000000
|
#43000000
|
||||||
1`[J;"
|
1!
|
||||||
b1000 rPs;{
|
b1000 #
|
||||||
b1000 6_+(g
|
b1000 $
|
||||||
#44000000
|
#44000000
|
||||||
0`[J;"
|
0!
|
||||||
#45000000
|
#45000000
|
||||||
1`[J;"
|
1!
|
||||||
b1001 rPs;{
|
b1001 #
|
||||||
b1001 6_+(g
|
b1001 $
|
||||||
#46000000
|
#46000000
|
||||||
0`[J;"
|
0!
|
||||||
#47000000
|
#47000000
|
||||||
1`[J;"
|
1!
|
||||||
b1010 rPs;{
|
b1010 #
|
||||||
b1010 6_+(g
|
b1010 $
|
||||||
#48000000
|
#48000000
|
||||||
0`[J;"
|
0!
|
||||||
#49000000
|
#49000000
|
||||||
1`[J;"
|
1!
|
||||||
b1011 rPs;{
|
b1011 #
|
||||||
b1011 6_+(g
|
b1011 $
|
||||||
#50000000
|
#50000000
|
||||||
0`[J;"
|
0!
|
||||||
#51000000
|
#51000000
|
||||||
1`[J;"
|
1!
|
||||||
b1100 rPs;{
|
b1100 #
|
||||||
b1100 6_+(g
|
b1100 $
|
||||||
#52000000
|
#52000000
|
||||||
0`[J;"
|
0!
|
||||||
#53000000
|
#53000000
|
||||||
1`[J;"
|
1!
|
||||||
b1101 rPs;{
|
b1101 #
|
||||||
b1101 6_+(g
|
b1101 $
|
||||||
#54000000
|
#54000000
|
||||||
0`[J;"
|
0!
|
||||||
#55000000
|
#55000000
|
||||||
1`[J;"
|
1!
|
||||||
b1110 rPs;{
|
b1110 #
|
||||||
b1110 6_+(g
|
b1110 $
|
||||||
#56000000
|
#56000000
|
||||||
0`[J;"
|
0!
|
||||||
#57000000
|
#57000000
|
||||||
1`[J;"
|
1!
|
||||||
b1111 rPs;{
|
b1111 #
|
||||||
b1111 6_+(g
|
b1111 $
|
||||||
#58000000
|
#58000000
|
||||||
0`[J;"
|
0!
|
||||||
#59000000
|
#59000000
|
||||||
1`[J;"
|
1!
|
||||||
b0 rPs;{
|
b0 #
|
||||||
b0 6_+(g
|
b0 $
|
||||||
#60000000
|
#60000000
|
||||||
0`[J;"
|
0!
|
||||||
#61000000
|
#61000000
|
||||||
1`[J;"
|
1!
|
||||||
b1 rPs;{
|
b1 #
|
||||||
b1 6_+(g
|
b1 $
|
||||||
#62000000
|
#62000000
|
||||||
0`[J;"
|
0!
|
||||||
#63000000
|
#63000000
|
||||||
1`[J;"
|
1!
|
||||||
b10 rPs;{
|
b10 #
|
||||||
b10 6_+(g
|
b10 $
|
||||||
#64000000
|
#64000000
|
||||||
0`[J;"
|
0!
|
||||||
#65000000
|
#65000000
|
||||||
1`[J;"
|
1!
|
||||||
b11 rPs;{
|
b11 #
|
||||||
b11 6_+(g
|
b11 $
|
||||||
#66000000
|
#66000000
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 4,
|
pc: 4,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -98,7 +97,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [],
|
base_targets: [],
|
||||||
uninitialized_ios: {},
|
uninitialized_ios: {},
|
||||||
|
|
@ -139,7 +137,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x05,
|
state: 0x05,
|
||||||
last_state: 0x05,
|
last_state: 0x05,
|
||||||
},
|
},
|
||||||
|
|
@ -149,7 +146,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x06,
|
state: 0x06,
|
||||||
last_state: 0x06,
|
last_state: 0x06,
|
||||||
},
|
},
|
||||||
|
|
@ -171,6 +167,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module duplicate_names $end
|
$scope module duplicate_names $end
|
||||||
$var wire 8 7[_7. w $end
|
$var wire 8 ! w $end
|
||||||
$var wire 8 7[_7." w_2 $end
|
$var wire 8 " w_2 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
b101 7[_7.
|
b101 !
|
||||||
b110 7[_7."
|
b110 "
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
|
|
|
||||||
|
|
@ -1,752 +0,0 @@
|
||||||
Simulation {
|
|
||||||
state: State {
|
|
||||||
insns: Insns {
|
|
||||||
state_layout: StateLayout {
|
|
||||||
ty: TypeLayout {
|
|
||||||
small_slots: StatePartLayout<SmallSlots> {
|
|
||||||
len: 1,
|
|
||||||
debug_data: [
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
C,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
big_slots: StatePartLayout<BigSlots> {
|
|
||||||
len: 33,
|
|
||||||
debug_data: [
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out",
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".0",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".1",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".0",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".1",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".0",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".1",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<2>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<10>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
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: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(32), // (0x2) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x2,
|
|
||||||
},
|
|
||||||
1: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(27), // (0x2) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
value: 0x2,
|
|
||||||
},
|
|
||||||
2: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(25), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
src: StatePartIndex<BigSlots>(27), // (0x2) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
},
|
|
||||||
3: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(26), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
4: Shl {
|
|
||||||
dest: StatePartIndex<BigSlots>(28), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(26), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
rhs: 2,
|
|
||||||
},
|
|
||||||
5: Or {
|
|
||||||
dest: StatePartIndex<BigSlots>(29), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(25), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(28), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
6: CastToUInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(30), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
src: StatePartIndex<BigSlots>(29), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
dest_width: 10,
|
|
||||||
},
|
|
||||||
7: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(31), // (0x386) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(30), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
8: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x1) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
value: 0x1,
|
|
||||||
},
|
|
||||||
9: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(18), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
src: StatePartIndex<BigSlots>(20), // (0x1) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
},
|
|
||||||
10: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(19), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
11: Shl {
|
|
||||||
dest: StatePartIndex<BigSlots>(21), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(19), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
rhs: 2,
|
|
||||||
},
|
|
||||||
12: Or {
|
|
||||||
dest: StatePartIndex<BigSlots>(22), // (0x385) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(18), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(21), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
13: CastToUInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(23), // (0x385) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
src: StatePartIndex<BigSlots>(22), // (0x385) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
dest_width: 10,
|
|
||||||
},
|
|
||||||
14: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x385) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(23), // (0x385) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
15: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x1,
|
|
||||||
},
|
|
||||||
16: CmpEq {
|
|
||||||
dest: StatePartIndex<BigSlots>(17), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
lhs: StatePartIndex<BigSlots>(0), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in", ty: UInt<8> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
17: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
value: 0x0,
|
|
||||||
},
|
|
||||||
18: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
|
||||||
},
|
|
||||||
19: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(10), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
20: Shl {
|
|
||||||
dest: StatePartIndex<BigSlots>(12), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(10), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
rhs: 2,
|
|
||||||
},
|
|
||||||
21: Or {
|
|
||||||
dest: StatePartIndex<BigSlots>(13), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: ".0", ty: UInt<2> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(12), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
22: CastToUInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(14), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
src: StatePartIndex<BigSlots>(13), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
dest_width: 10,
|
|
||||||
},
|
|
||||||
23: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(15), // (0x384) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(14), // (0x384) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
},
|
|
||||||
24: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x0,
|
|
||||||
},
|
|
||||||
25: CmpEq {
|
|
||||||
dest: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
lhs: StatePartIndex<BigSlots>(0), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in", ty: UInt<8> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:7:1
|
|
||||||
26: BranchIfZero {
|
|
||||||
target: 28,
|
|
||||||
value: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:8:1
|
|
||||||
27: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(15), // (0x384) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:7:1
|
|
||||||
28: BranchIfNonZero {
|
|
||||||
target: 33,
|
|
||||||
value: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
29: BranchIfZero {
|
|
||||||
target: 31,
|
|
||||||
value: StatePartIndex<BigSlots>(17), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
|
||||||
30: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(24), // (0x385) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
31: BranchIfNonZero {
|
|
||||||
target: 33,
|
|
||||||
value: StatePartIndex<BigSlots>(17), // (0x0) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:11:1
|
|
||||||
32: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(31), // (0x386) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
33: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(5), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
src: StatePartIndex<BigSlots>(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
},
|
|
||||||
34: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(5), // (0x386) SlotDebugData { name: "", ty: UInt<10> },
|
|
||||||
start: 2,
|
|
||||||
len: 8,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:6:1
|
|
||||||
35: AndBigWithSmallImmediate {
|
|
||||||
dest: StatePartIndex<SmallSlots>(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} },
|
|
||||||
lhs: StatePartIndex<BigSlots>(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} },
|
|
||||||
rhs: 0x3,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:12:1
|
|
||||||
36: BranchIfSmallNeImmediate {
|
|
||||||
target: 39,
|
|
||||||
lhs: StatePartIndex<SmallSlots>(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} },
|
|
||||||
rhs: 0x0,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:13:1
|
|
||||||
37: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:14:1
|
|
||||||
38: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:12:1
|
|
||||||
39: BranchIfSmallNeImmediate {
|
|
||||||
target: 42,
|
|
||||||
lhs: StatePartIndex<SmallSlots>(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} },
|
|
||||||
rhs: 0x1,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:15:1
|
|
||||||
40: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:16:1
|
|
||||||
41: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:12:1
|
|
||||||
42: BranchIfSmallNeImmediate {
|
|
||||||
target: 45,
|
|
||||||
lhs: StatePartIndex<SmallSlots>(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} },
|
|
||||||
rhs: 0x2,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:17:1
|
|
||||||
43: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(32), // (0x2) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:18:1
|
|
||||||
44: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
45: Return,
|
|
||||||
],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
pc: 45,
|
|
||||||
memory_write_log: [],
|
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
small_slots: StatePart {
|
|
||||||
value: [
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
big_slots: StatePart {
|
|
||||||
value: [
|
|
||||||
2,
|
|
||||||
225,
|
|
||||||
2 (modified),
|
|
||||||
225 (modified),
|
|
||||||
902,
|
|
||||||
902,
|
|
||||||
225,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
225,
|
|
||||||
0,
|
|
||||||
900,
|
|
||||||
900,
|
|
||||||
900,
|
|
||||||
900,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
225,
|
|
||||||
1,
|
|
||||||
900,
|
|
||||||
901,
|
|
||||||
901,
|
|
||||||
901,
|
|
||||||
2,
|
|
||||||
225,
|
|
||||||
2,
|
|
||||||
900,
|
|
||||||
902,
|
|
||||||
902,
|
|
||||||
902,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
sim_only_slots: StatePart {
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
io: Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
},
|
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
|
||||||
base_targets: [
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.which_in,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.data_in,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.which_out,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.data_out,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.enum_out,
|
|
||||||
],
|
|
||||||
uninitialized_ios: {},
|
|
||||||
io_targets: {
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.data_in,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.data_out,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.enum_out,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.which_in,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::enum_with_simple_body,
|
|
||||||
instantiated: Module {
|
|
||||||
name: enum_with_simple_body,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.which_out,
|
|
||||||
},
|
|
||||||
did_initial_settle: true,
|
|
||||||
clocks_for_past: {},
|
|
||||||
},
|
|
||||||
extern_modules: [],
|
|
||||||
trace_decls: TraceModule {
|
|
||||||
name: "enum_with_simple_body",
|
|
||||||
children: [
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "which_in",
|
|
||||||
child: TraceUInt {
|
|
||||||
location: TraceScalarId(0),
|
|
||||||
name: "which_in",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "data_in",
|
|
||||||
child: TraceUInt {
|
|
||||||
location: TraceScalarId(1),
|
|
||||||
name: "data_in",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "which_out",
|
|
||||||
child: TraceUInt {
|
|
||||||
location: TraceScalarId(2),
|
|
||||||
name: "which_out",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "data_out",
|
|
||||||
child: TraceUInt {
|
|
||||||
location: TraceScalarId(3),
|
|
||||||
name: "data_out",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "enum_out",
|
|
||||||
child: TraceEnumWithFields {
|
|
||||||
name: "enum_out",
|
|
||||||
discriminant: TraceEnumDiscriminant {
|
|
||||||
location: TraceScalarId(4),
|
|
||||||
name: "$tag",
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
non_empty_fields: [
|
|
||||||
TraceUInt {
|
|
||||||
location: TraceScalarId(5),
|
|
||||||
name: "A",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceUInt {
|
|
||||||
location: TraceScalarId(6),
|
|
||||||
name: "B",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceUInt {
|
|
||||||
location: TraceScalarId(7),
|
|
||||||
name: "C",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
traces: [
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(0),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(0),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x02,
|
|
||||||
last_state: 0x02,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(1),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(1),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe1,
|
|
||||||
last_state: 0xb4,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(2),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(2),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x02,
|
|
||||||
last_state: 0x02,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(3),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(3),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe1,
|
|
||||||
last_state: 0xb4,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(4),
|
|
||||||
kind: EnumDiscriminant {
|
|
||||||
index: StatePartIndex<SmallSlots>(0),
|
|
||||||
ty: Enum {
|
|
||||||
A(UInt<8>),
|
|
||||||
B(UInt<8>),
|
|
||||||
C(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
|
||||||
last_state: 0x2,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(5),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(6),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe1,
|
|
||||||
last_state: 0xb4,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(6),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(6),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe1,
|
|
||||||
last_state: 0xb4,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(7),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(6),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe1,
|
|
||||||
last_state: 0xb4,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
trace_memories: {},
|
|
||||||
trace_writers: [
|
|
||||||
Running(
|
|
||||||
VcdWriter {
|
|
||||||
finished_init: true,
|
|
||||||
timescale: 1 ps,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 18 μs,
|
|
||||||
events: {},
|
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
asserts: [],
|
|
||||||
..
|
|
||||||
}
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
$timescale 1 ps $end
|
|
||||||
$scope module enum_with_simple_body $end
|
|
||||||
$var wire 8 J&-ne which_in $end
|
|
||||||
$var wire 8 \7mo/ data_in $end
|
|
||||||
$var wire 8 ,`>ir which_out $end
|
|
||||||
$var wire 8 0_gMP data_out $end
|
|
||||||
$scope struct enum_out $end
|
|
||||||
$var string 1 kFH/w \$tag $end
|
|
||||||
$var wire 8 |EI_= A $end
|
|
||||||
$var wire 8 !pRd4 B $end
|
|
||||||
$var wire 8 &RAbd C $end
|
|
||||||
$upscope $end
|
|
||||||
$upscope $end
|
|
||||||
$enddefinitions $end
|
|
||||||
$dumpvars
|
|
||||||
b0 J&-ne
|
|
||||||
b0 \7mo/
|
|
||||||
b0 ,`>ir
|
|
||||||
b0 0_gMP
|
|
||||||
sA\x20(0) kFH/w
|
|
||||||
b0 |EI_=
|
|
||||||
b0 !pRd4
|
|
||||||
b0 &RAbd
|
|
||||||
$end
|
|
||||||
#1000000
|
|
||||||
b101101 \7mo/
|
|
||||||
b101101 0_gMP
|
|
||||||
b101101 |EI_=
|
|
||||||
b101101 !pRd4
|
|
||||||
b101101 &RAbd
|
|
||||||
#2000000
|
|
||||||
b1011010 \7mo/
|
|
||||||
b1011010 0_gMP
|
|
||||||
b1011010 |EI_=
|
|
||||||
b1011010 !pRd4
|
|
||||||
b1011010 &RAbd
|
|
||||||
#3000000
|
|
||||||
b10000111 \7mo/
|
|
||||||
b10000111 0_gMP
|
|
||||||
b10000111 |EI_=
|
|
||||||
b10000111 !pRd4
|
|
||||||
b10000111 &RAbd
|
|
||||||
#4000000
|
|
||||||
b10110100 \7mo/
|
|
||||||
b10110100 0_gMP
|
|
||||||
b10110100 |EI_=
|
|
||||||
b10110100 !pRd4
|
|
||||||
b10110100 &RAbd
|
|
||||||
#5000000
|
|
||||||
b11100001 \7mo/
|
|
||||||
b11100001 0_gMP
|
|
||||||
b11100001 |EI_=
|
|
||||||
b11100001 !pRd4
|
|
||||||
b11100001 &RAbd
|
|
||||||
#6000000
|
|
||||||
b1 J&-ne
|
|
||||||
b0 \7mo/
|
|
||||||
b1 ,`>ir
|
|
||||||
b0 0_gMP
|
|
||||||
sB\x20(1) kFH/w
|
|
||||||
b0 |EI_=
|
|
||||||
b0 !pRd4
|
|
||||||
b0 &RAbd
|
|
||||||
#7000000
|
|
||||||
b101101 \7mo/
|
|
||||||
b101101 0_gMP
|
|
||||||
b101101 |EI_=
|
|
||||||
b101101 !pRd4
|
|
||||||
b101101 &RAbd
|
|
||||||
#8000000
|
|
||||||
b1011010 \7mo/
|
|
||||||
b1011010 0_gMP
|
|
||||||
b1011010 |EI_=
|
|
||||||
b1011010 !pRd4
|
|
||||||
b1011010 &RAbd
|
|
||||||
#9000000
|
|
||||||
b10000111 \7mo/
|
|
||||||
b10000111 0_gMP
|
|
||||||
b10000111 |EI_=
|
|
||||||
b10000111 !pRd4
|
|
||||||
b10000111 &RAbd
|
|
||||||
#10000000
|
|
||||||
b10110100 \7mo/
|
|
||||||
b10110100 0_gMP
|
|
||||||
b10110100 |EI_=
|
|
||||||
b10110100 !pRd4
|
|
||||||
b10110100 &RAbd
|
|
||||||
#11000000
|
|
||||||
b11100001 \7mo/
|
|
||||||
b11100001 0_gMP
|
|
||||||
b11100001 |EI_=
|
|
||||||
b11100001 !pRd4
|
|
||||||
b11100001 &RAbd
|
|
||||||
#12000000
|
|
||||||
b10 J&-ne
|
|
||||||
b0 \7mo/
|
|
||||||
b10 ,`>ir
|
|
||||||
b0 0_gMP
|
|
||||||
sC\x20(2) kFH/w
|
|
||||||
b0 |EI_=
|
|
||||||
b0 !pRd4
|
|
||||||
b0 &RAbd
|
|
||||||
#13000000
|
|
||||||
b101101 \7mo/
|
|
||||||
b101101 0_gMP
|
|
||||||
b101101 |EI_=
|
|
||||||
b101101 !pRd4
|
|
||||||
b101101 &RAbd
|
|
||||||
#14000000
|
|
||||||
b1011010 \7mo/
|
|
||||||
b1011010 0_gMP
|
|
||||||
b1011010 |EI_=
|
|
||||||
b1011010 !pRd4
|
|
||||||
b1011010 &RAbd
|
|
||||||
#15000000
|
|
||||||
b10000111 \7mo/
|
|
||||||
b10000111 0_gMP
|
|
||||||
b10000111 |EI_=
|
|
||||||
b10000111 !pRd4
|
|
||||||
b10000111 &RAbd
|
|
||||||
#16000000
|
|
||||||
b10110100 \7mo/
|
|
||||||
b10110100 0_gMP
|
|
||||||
b10110100 |EI_=
|
|
||||||
b10110100 !pRd4
|
|
||||||
b10110100 &RAbd
|
|
||||||
#17000000
|
|
||||||
b11100001 \7mo/
|
|
||||||
b11100001 0_gMP
|
|
||||||
b11100001 |EI_=
|
|
||||||
b11100001 !pRd4
|
|
||||||
b11100001 &RAbd
|
|
||||||
#18000000
|
|
||||||
|
|
@ -1012,179 +1012,174 @@ Simulation {
|
||||||
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
rhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
rhs: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
99: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
|
||||||
src: StatePartIndex<BigSlots>(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
100: Const {
|
99: Const {
|
||||||
dest: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
|
dest: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
|
||||||
value: 0x0,
|
value: 0x0,
|
||||||
},
|
},
|
||||||
101: Copy {
|
100: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
|
src: StatePartIndex<BigSlots>(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:12:1
|
// at: module-XXXXXXXXXX.rs:12:1
|
||||||
102: BranchIfZero {
|
101: BranchIfZero {
|
||||||
target: 110,
|
target: 109,
|
||||||
value: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool },
|
value: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:13:1
|
// at: module-XXXXXXXXXX.rs:13:1
|
||||||
103: BranchIfZero {
|
102: BranchIfZero {
|
||||||
target: 105,
|
target: 104,
|
||||||
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:14:1
|
// at: module-XXXXXXXXXX.rs:14:1
|
||||||
104: Copy {
|
103: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:13:1
|
// at: module-XXXXXXXXXX.rs:13:1
|
||||||
105: BranchIfNonZero {
|
104: BranchIfNonZero {
|
||||||
target: 110,
|
target: 109,
|
||||||
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<BigSlots>(46), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:15:1
|
// at: module-XXXXXXXXXX.rs:15:1
|
||||||
106: BranchIfZero {
|
105: BranchIfZero {
|
||||||
target: 108,
|
target: 107,
|
||||||
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:16:1
|
// at: module-XXXXXXXXXX.rs:16:1
|
||||||
107: Copy {
|
106: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
src: StatePartIndex<BigSlots>(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:15:1
|
// at: module-XXXXXXXXXX.rs:15:1
|
||||||
108: BranchIfNonZero {
|
107: BranchIfNonZero {
|
||||||
target: 110,
|
target: 109,
|
||||||
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<BigSlots>(48), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:17:1
|
// at: module-XXXXXXXXXX.rs:17:1
|
||||||
109: Copy {
|
108: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
src: StatePartIndex<BigSlots>(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
// at: module-XXXXXXXXXX.rs:10:1
|
||||||
110: Copy {
|
109: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
dest: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
111: Copy {
|
110: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
dest: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
||||||
src: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
src: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
},
|
},
|
||||||
112: SliceInt {
|
111: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
dest: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
src: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
src: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
||||||
start: 1,
|
start: 1,
|
||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
113: SliceInt {
|
112: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
src: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
start: 0,
|
start: 0,
|
||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
114: SliceInt {
|
113: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
src: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
start: 1,
|
start: 1,
|
||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
115: Copy {
|
114: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(22), // (0x0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<BigSlots>(22), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
src: StatePartIndex<BigSlots>(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
},
|
},
|
||||||
116: Copy {
|
115: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(16), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(16), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
src: StatePartIndex<BigSlots>(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
},
|
},
|
||||||
117: Copy {
|
116: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(17), // (0x0) SlotDebugData { name: ".1", ty: Bool },
|
dest: StatePartIndex<BigSlots>(17), // (0x0) SlotDebugData { name: ".1", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(22), // (0x0) SlotDebugData { name: "", ty: Bool },
|
src: StatePartIndex<BigSlots>(22), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
// at: module-XXXXXXXXXX.rs:9:1
|
||||||
118: AndBigWithSmallImmediate {
|
117: AndBigWithSmallImmediate {
|
||||||
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
dest: StatePartIndex<SmallSlots>(1), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
||||||
lhs: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
lhs: StatePartIndex<BigSlots>(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
rhs: 0x1,
|
rhs: 0x1,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
119: Copy {
|
118: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
dest: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
||||||
src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
src: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
},
|
},
|
||||||
120: SliceInt {
|
119: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
dest: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
src: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
src: StatePartIndex<BigSlots>(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> },
|
||||||
start: 1,
|
start: 1,
|
||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
121: SliceInt {
|
120: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
start: 0,
|
start: 0,
|
||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
122: SliceInt {
|
121: SliceInt {
|
||||||
dest: StatePartIndex<BigSlots>(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
src: StatePartIndex<BigSlots>(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> },
|
||||||
start: 1,
|
start: 1,
|
||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
123: Copy {
|
122: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(14), // (0x0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<BigSlots>(14), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
src: StatePartIndex<BigSlots>(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
},
|
},
|
||||||
124: Copy {
|
123: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> },
|
dest: StatePartIndex<BigSlots>(8), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> },
|
||||||
src: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
src: StatePartIndex<BigSlots>(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> },
|
||||||
},
|
},
|
||||||
125: Copy {
|
124: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: ".1", ty: Bool },
|
dest: StatePartIndex<BigSlots>(9), // (0x0) SlotDebugData { name: ".1", ty: Bool },
|
||||||
src: StatePartIndex<BigSlots>(14), // (0x0) SlotDebugData { name: "", ty: Bool },
|
src: StatePartIndex<BigSlots>(14), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:8:1
|
// at: module-XXXXXXXXXX.rs:8:1
|
||||||
126: AndBigWithSmallImmediate {
|
125: AndBigWithSmallImmediate {
|
||||||
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
dest: StatePartIndex<SmallSlots>(0), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
||||||
lhs: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
lhs: StatePartIndex<BigSlots>(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} },
|
||||||
rhs: 0x1,
|
rhs: 0x1,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:11:1
|
// at: module-XXXXXXXXXX.rs:11:1
|
||||||
127: BranchIfSmallZero {
|
126: BranchIfSmallZero {
|
||||||
target: 132,
|
target: 131,
|
||||||
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(3), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
128: BranchIfSmallNonZero {
|
127: BranchIfSmallNonZero {
|
||||||
target: 131,
|
target: 130,
|
||||||
value: StatePartIndex<SmallSlots>(5), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
value: StatePartIndex<SmallSlots>(5), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
},
|
},
|
||||||
129: Copy {
|
128: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
src: StatePartIndex<BigSlots>(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
},
|
},
|
||||||
130: Branch {
|
129: Branch {
|
||||||
target: 132,
|
target: 131,
|
||||||
},
|
},
|
||||||
131: Copy {
|
130: Copy {
|
||||||
dest: StatePartIndex<BigSlots>(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
dest: StatePartIndex<BigSlots>(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
src: StatePartIndex<BigSlots>(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>})} },
|
||||||
},
|
},
|
||||||
132: XorSmallImmediate {
|
131: XorSmallImmediate {
|
||||||
dest: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
dest: StatePartIndex<SmallSlots>(2), // (0x0 0) SlotDebugData { name: "", ty: Bool },
|
||||||
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
lhs: StatePartIndex<SmallSlots>(4), // (0x1 1) SlotDebugData { name: "", ty: Bool },
|
||||||
rhs: 0x1,
|
rhs: 0x1,
|
||||||
},
|
},
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
133: Return,
|
132: Return,
|
||||||
],
|
],
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
pc: 133,
|
pc: 132,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -1325,7 +1320,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -1748,7 +1742,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1757,7 +1750,6 @@ Simulation {
|
||||||
kind: BigSyncReset {
|
kind: BigSyncReset {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1766,7 +1758,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1776,7 +1767,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<2>,
|
ty: UInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1786,7 +1776,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0xf,
|
state: 0xf,
|
||||||
last_state: 0xf,
|
last_state: 0xf,
|
||||||
},
|
},
|
||||||
|
|
@ -1796,7 +1785,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: UInt<2>,
|
ty: UInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1806,7 +1794,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf,
|
state: 0xf,
|
||||||
last_state: 0xf,
|
last_state: 0xf,
|
||||||
},
|
},
|
||||||
|
|
@ -1819,7 +1806,6 @@ Simulation {
|
||||||
HdlSome(Bundle {0: UInt<1>, 1: Bool}),
|
HdlSome(Bundle {0: UInt<1>, 1: Bool}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1829,7 +1815,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
ty: UInt<1>,
|
ty: UInt<1>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1838,7 +1823,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1851,7 +1835,6 @@ Simulation {
|
||||||
HdlSome(Bundle {0: UInt<1>, 1: Bool}),
|
HdlSome(Bundle {0: UInt<1>, 1: Bool}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1861,7 +1844,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(16),
|
index: StatePartIndex<BigSlots>(16),
|
||||||
ty: UInt<1>,
|
ty: UInt<1>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1870,7 +1852,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(17),
|
index: StatePartIndex<BigSlots>(17),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1884,7 +1865,6 @@ Simulation {
|
||||||
C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>}),
|
C(Bundle {a: Array<UInt<1>, 2>, b: SInt<2>}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1894,7 +1874,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(27),
|
index: StatePartIndex<BigSlots>(27),
|
||||||
ty: UInt<1>,
|
ty: UInt<1>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1903,7 +1882,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(28),
|
index: StatePartIndex<BigSlots>(28),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1913,7 +1891,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(34),
|
index: StatePartIndex<BigSlots>(34),
|
||||||
ty: UInt<1>,
|
ty: UInt<1>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1923,7 +1900,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(35),
|
index: StatePartIndex<BigSlots>(35),
|
||||||
ty: UInt<1>,
|
ty: UInt<1>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1933,7 +1909,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(36),
|
index: StatePartIndex<BigSlots>(36),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x3,
|
state: 0x3,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -1957,6 +1932,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,126 +1,126 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module enums $end
|
$scope module enums $end
|
||||||
$scope struct cd $end
|
$scope struct cd $end
|
||||||
$var wire 1 0n\U< clk $end
|
$var wire 1 ! clk $end
|
||||||
$var wire 1 a?A!) rst $end
|
$var wire 1 " rst $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 1 #ZQY# en $end
|
$var wire 1 # en $end
|
||||||
$var wire 2 8?II+ which_in $end
|
$var wire 2 $ which_in $end
|
||||||
$var wire 4 OO,N+ data_in $end
|
$var wire 4 % data_in $end
|
||||||
$var wire 2 yr2gr which_out $end
|
$var wire 2 & which_out $end
|
||||||
$var wire 4 q_O;Y data_out $end
|
$var wire 4 ' data_out $end
|
||||||
$scope struct b_out $end
|
$scope struct b_out $end
|
||||||
$var string 1 7L1gf \$tag $end
|
$var string 1 ( \$tag $end
|
||||||
$scope struct HdlSome $end
|
$scope struct HdlSome $end
|
||||||
$var wire 1 EO?Ju \0 $end
|
$var wire 1 ) \0 $end
|
||||||
$var wire 1 cGtNN \1 $end
|
$var wire 1 * \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct b2_out $end
|
$scope struct b2_out $end
|
||||||
$var string 1 dqd@B \$tag $end
|
$var string 1 + \$tag $end
|
||||||
$scope struct HdlSome $end
|
$scope struct HdlSome $end
|
||||||
$var wire 1 (FG:I \0 $end
|
$var wire 1 , \0 $end
|
||||||
$var wire 1 dzy-= \1 $end
|
$var wire 1 - \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct the_reg $end
|
$scope struct the_reg $end
|
||||||
$var string 1 J#9uO \$tag $end
|
$var string 1 . \$tag $end
|
||||||
$scope struct B $end
|
$scope struct B $end
|
||||||
$var reg 1 ca2Gh \0 $end
|
$var reg 1 / \0 $end
|
||||||
$var reg 1 f)r)? \1 $end
|
$var reg 1 0 \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct C $end
|
$scope struct C $end
|
||||||
$scope struct a $end
|
$scope struct a $end
|
||||||
$var reg 1 ;BepJ \[0] $end
|
$var reg 1 1 \[0] $end
|
||||||
$var reg 1 J~2;e \[1] $end
|
$var reg 1 2 \[1] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var reg 2 w\b)K b $end
|
$var reg 2 3 b $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
00n\U<
|
0!
|
||||||
1a?A!)
|
1"
|
||||||
0#ZQY#
|
0#
|
||||||
b0 8?II+
|
b0 $
|
||||||
b0 OO,N+
|
b0 %
|
||||||
b0 yr2gr
|
b0 &
|
||||||
b0 q_O;Y
|
b0 '
|
||||||
sHdlNone\x20(0) 7L1gf
|
sHdlNone\x20(0) (
|
||||||
0EO?Ju
|
0)
|
||||||
0cGtNN
|
0*
|
||||||
sHdlNone\x20(0) dqd@B
|
sHdlNone\x20(0) +
|
||||||
0(FG:I
|
0,
|
||||||
0dzy-=
|
0-
|
||||||
sA\x20(0) J#9uO
|
sA\x20(0) .
|
||||||
0ca2Gh
|
0/
|
||||||
0f)r)?
|
00
|
||||||
0;BepJ
|
01
|
||||||
0J~2;e
|
02
|
||||||
b0 w\b)K
|
b0 3
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
10n\U<
|
1!
|
||||||
#1100000
|
#1100000
|
||||||
0a?A!)
|
0"
|
||||||
#2000000
|
#2000000
|
||||||
00n\U<
|
0!
|
||||||
#3000000
|
#3000000
|
||||||
10n\U<
|
1!
|
||||||
#4000000
|
#4000000
|
||||||
1#ZQY#
|
1#
|
||||||
b1 8?II+
|
b1 $
|
||||||
00n\U<
|
0!
|
||||||
#5000000
|
#5000000
|
||||||
10n\U<
|
1!
|
||||||
b1 yr2gr
|
b1 &
|
||||||
sHdlSome\x20(1) 7L1gf
|
sHdlSome\x20(1) (
|
||||||
sHdlSome\x20(1) dqd@B
|
sHdlSome\x20(1) +
|
||||||
sB\x20(1) J#9uO
|
sB\x20(1) .
|
||||||
#6000000
|
#6000000
|
||||||
0#ZQY#
|
0#
|
||||||
b0 8?II+
|
b0 $
|
||||||
00n\U<
|
0!
|
||||||
#7000000
|
#7000000
|
||||||
10n\U<
|
1!
|
||||||
#8000000
|
#8000000
|
||||||
1#ZQY#
|
1#
|
||||||
b1 8?II+
|
b1 $
|
||||||
b1111 OO,N+
|
b1111 %
|
||||||
00n\U<
|
0!
|
||||||
#9000000
|
#9000000
|
||||||
10n\U<
|
1!
|
||||||
b11 q_O;Y
|
b11 '
|
||||||
1EO?Ju
|
1)
|
||||||
1cGtNN
|
1*
|
||||||
1(FG:I
|
1,
|
||||||
1dzy-=
|
1-
|
||||||
1ca2Gh
|
1/
|
||||||
1f)r)?
|
10
|
||||||
1;BepJ
|
11
|
||||||
1J~2;e
|
12
|
||||||
#10000000
|
#10000000
|
||||||
00n\U<
|
0!
|
||||||
#11000000
|
#11000000
|
||||||
10n\U<
|
1!
|
||||||
#12000000
|
#12000000
|
||||||
b10 8?II+
|
b10 $
|
||||||
00n\U<
|
0!
|
||||||
#13000000
|
#13000000
|
||||||
10n\U<
|
1!
|
||||||
b10 yr2gr
|
b10 &
|
||||||
b1111 q_O;Y
|
b1111 '
|
||||||
sHdlNone\x20(0) 7L1gf
|
sHdlNone\x20(0) (
|
||||||
0EO?Ju
|
0)
|
||||||
0cGtNN
|
0*
|
||||||
sHdlNone\x20(0) dqd@B
|
sHdlNone\x20(0) +
|
||||||
0(FG:I
|
0,
|
||||||
0dzy-=
|
0-
|
||||||
sC\x20(2) J#9uO
|
sC\x20(2) .
|
||||||
b11 w\b)K
|
b11 3
|
||||||
#14000000
|
#14000000
|
||||||
00n\U<
|
0!
|
||||||
#15000000
|
#15000000
|
||||||
10n\U<
|
1!
|
||||||
#16000000
|
#16000000
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 0,
|
pc: 0,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -68,7 +67,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -223,7 +221,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -232,7 +229,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -263,6 +259,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,52 +1,52 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module extern_module $end
|
$scope module extern_module $end
|
||||||
$var wire 1 `MLd_ i $end
|
$var wire 1 ! i $end
|
||||||
$var wire 1 ^;OnJ o $end
|
$var wire 1 " o $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
0`MLd_
|
0!
|
||||||
0^;OnJ
|
0"
|
||||||
$end
|
$end
|
||||||
1^;OnJ
|
1"
|
||||||
#500000
|
#500000
|
||||||
#1500000
|
#1500000
|
||||||
0^;OnJ
|
0"
|
||||||
#2500000
|
#2500000
|
||||||
1^;OnJ
|
1"
|
||||||
#3500000
|
#3500000
|
||||||
0^;OnJ
|
0"
|
||||||
#4500000
|
#4500000
|
||||||
1^;OnJ
|
1"
|
||||||
#5500000
|
#5500000
|
||||||
0^;OnJ
|
0"
|
||||||
#6500000
|
#6500000
|
||||||
1^;OnJ
|
1"
|
||||||
#7500000
|
#7500000
|
||||||
0^;OnJ
|
0"
|
||||||
#8500000
|
#8500000
|
||||||
1^;OnJ
|
1"
|
||||||
#9500000
|
#9500000
|
||||||
0^;OnJ
|
0"
|
||||||
#10000000
|
#10000000
|
||||||
1`MLd_
|
1!
|
||||||
#10500000
|
#10500000
|
||||||
#11500000
|
#11500000
|
||||||
1^;OnJ
|
1"
|
||||||
#12500000
|
#12500000
|
||||||
0^;OnJ
|
0"
|
||||||
#13500000
|
#13500000
|
||||||
1^;OnJ
|
1"
|
||||||
#14500000
|
#14500000
|
||||||
0^;OnJ
|
0"
|
||||||
#15500000
|
#15500000
|
||||||
1^;OnJ
|
1"
|
||||||
#16500000
|
#16500000
|
||||||
0^;OnJ
|
0"
|
||||||
#17500000
|
#17500000
|
||||||
1^;OnJ
|
1"
|
||||||
#18500000
|
#18500000
|
||||||
0^;OnJ
|
0"
|
||||||
#19500000
|
#19500000
|
||||||
1^;OnJ
|
1"
|
||||||
#20000000
|
#20000000
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 0,
|
pc: 0,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -58,7 +57,7 @@ Simulation {
|
||||||
big_slots: StatePart {
|
big_slots: StatePart {
|
||||||
value: [
|
value: [
|
||||||
0,
|
0,
|
||||||
1 (modified),
|
1,
|
||||||
101,
|
101,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -73,7 +72,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -282,7 +280,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -291,7 +288,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -301,7 +297,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x65,
|
state: 0x65,
|
||||||
last_state: 0x65,
|
last_state: 0x65,
|
||||||
},
|
},
|
||||||
|
|
@ -418,6 +413,5 @@ Simulation {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,151 +1,151 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module extern_module2 $end
|
$scope module extern_module2 $end
|
||||||
$var wire 1 oHT(x en $end
|
$var wire 1 ! en $end
|
||||||
$var wire 1 nHT-: clk $end
|
$var wire 1 " clk $end
|
||||||
$var wire 8 0:wF& o $end
|
$var wire 8 # o $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
1oHT(x
|
1!
|
||||||
0nHT-:
|
0"
|
||||||
b0 0:wF&
|
b0 #
|
||||||
$end
|
$end
|
||||||
b1001000 0:wF&
|
b1001000 #
|
||||||
#1000000
|
#1000000
|
||||||
1nHT-:
|
1"
|
||||||
b1100101 0:wF&
|
b1100101 #
|
||||||
#2000000
|
#2000000
|
||||||
0nHT-:
|
0"
|
||||||
#3000000
|
#3000000
|
||||||
1nHT-:
|
1"
|
||||||
b1101100 0:wF&
|
b1101100 #
|
||||||
#4000000
|
#4000000
|
||||||
0nHT-:
|
0"
|
||||||
#5000000
|
#5000000
|
||||||
1nHT-:
|
1"
|
||||||
#6000000
|
#6000000
|
||||||
0nHT-:
|
0"
|
||||||
#7000000
|
#7000000
|
||||||
1nHT-:
|
1"
|
||||||
b1101111 0:wF&
|
b1101111 #
|
||||||
#8000000
|
#8000000
|
||||||
0nHT-:
|
0"
|
||||||
#9000000
|
#9000000
|
||||||
1nHT-:
|
1"
|
||||||
b101100 0:wF&
|
b101100 #
|
||||||
#10000000
|
#10000000
|
||||||
0oHT(x
|
0!
|
||||||
0nHT-:
|
0"
|
||||||
#11000000
|
#11000000
|
||||||
1nHT-:
|
1"
|
||||||
#12000000
|
#12000000
|
||||||
0nHT-:
|
0"
|
||||||
#13000000
|
#13000000
|
||||||
1nHT-:
|
1"
|
||||||
#14000000
|
#14000000
|
||||||
0nHT-:
|
0"
|
||||||
#15000000
|
#15000000
|
||||||
1nHT-:
|
1"
|
||||||
#16000000
|
#16000000
|
||||||
0nHT-:
|
0"
|
||||||
#17000000
|
#17000000
|
||||||
1nHT-:
|
1"
|
||||||
#18000000
|
#18000000
|
||||||
0nHT-:
|
0"
|
||||||
#19000000
|
#19000000
|
||||||
1nHT-:
|
1"
|
||||||
#20000000
|
#20000000
|
||||||
1oHT(x
|
1!
|
||||||
0nHT-:
|
0"
|
||||||
#21000000
|
#21000000
|
||||||
1nHT-:
|
1"
|
||||||
b100000 0:wF&
|
b100000 #
|
||||||
#22000000
|
#22000000
|
||||||
0nHT-:
|
0"
|
||||||
#23000000
|
#23000000
|
||||||
1nHT-:
|
1"
|
||||||
b1010111 0:wF&
|
b1010111 #
|
||||||
#24000000
|
#24000000
|
||||||
0nHT-:
|
0"
|
||||||
#25000000
|
#25000000
|
||||||
1nHT-:
|
1"
|
||||||
b1101111 0:wF&
|
b1101111 #
|
||||||
#26000000
|
#26000000
|
||||||
0nHT-:
|
0"
|
||||||
#27000000
|
#27000000
|
||||||
1nHT-:
|
1"
|
||||||
b1110010 0:wF&
|
b1110010 #
|
||||||
#28000000
|
#28000000
|
||||||
0nHT-:
|
0"
|
||||||
#29000000
|
#29000000
|
||||||
1nHT-:
|
1"
|
||||||
b1101100 0:wF&
|
b1101100 #
|
||||||
#30000000
|
#30000000
|
||||||
0oHT(x
|
0!
|
||||||
0nHT-:
|
0"
|
||||||
#31000000
|
#31000000
|
||||||
1nHT-:
|
1"
|
||||||
#32000000
|
#32000000
|
||||||
0nHT-:
|
0"
|
||||||
#33000000
|
#33000000
|
||||||
1nHT-:
|
1"
|
||||||
#34000000
|
#34000000
|
||||||
0nHT-:
|
0"
|
||||||
#35000000
|
#35000000
|
||||||
1nHT-:
|
1"
|
||||||
#36000000
|
#36000000
|
||||||
0nHT-:
|
0"
|
||||||
#37000000
|
#37000000
|
||||||
1nHT-:
|
1"
|
||||||
#38000000
|
#38000000
|
||||||
0nHT-:
|
0"
|
||||||
#39000000
|
#39000000
|
||||||
1nHT-:
|
1"
|
||||||
#40000000
|
#40000000
|
||||||
1oHT(x
|
1!
|
||||||
0nHT-:
|
0"
|
||||||
#41000000
|
#41000000
|
||||||
1nHT-:
|
1"
|
||||||
b1100100 0:wF&
|
b1100100 #
|
||||||
#42000000
|
#42000000
|
||||||
0nHT-:
|
0"
|
||||||
#43000000
|
#43000000
|
||||||
1nHT-:
|
1"
|
||||||
b100001 0:wF&
|
b100001 #
|
||||||
#44000000
|
#44000000
|
||||||
0nHT-:
|
0"
|
||||||
#45000000
|
#45000000
|
||||||
1nHT-:
|
1"
|
||||||
b1010 0:wF&
|
b1010 #
|
||||||
#46000000
|
#46000000
|
||||||
0nHT-:
|
0"
|
||||||
#47000000
|
#47000000
|
||||||
1nHT-:
|
1"
|
||||||
b1001000 0:wF&
|
b1001000 #
|
||||||
#48000000
|
#48000000
|
||||||
0nHT-:
|
0"
|
||||||
#49000000
|
#49000000
|
||||||
1nHT-:
|
1"
|
||||||
b1100101 0:wF&
|
b1100101 #
|
||||||
#50000000
|
#50000000
|
||||||
0oHT(x
|
0!
|
||||||
0nHT-:
|
0"
|
||||||
#51000000
|
#51000000
|
||||||
1nHT-:
|
1"
|
||||||
#52000000
|
#52000000
|
||||||
0nHT-:
|
0"
|
||||||
#53000000
|
#53000000
|
||||||
1nHT-:
|
1"
|
||||||
#54000000
|
#54000000
|
||||||
0nHT-:
|
0"
|
||||||
#55000000
|
#55000000
|
||||||
1nHT-:
|
1"
|
||||||
#56000000
|
#56000000
|
||||||
0nHT-:
|
0"
|
||||||
#57000000
|
#57000000
|
||||||
1nHT-:
|
1"
|
||||||
#58000000
|
#58000000
|
||||||
0nHT-:
|
0"
|
||||||
#59000000
|
#59000000
|
||||||
1nHT-:
|
1"
|
||||||
#60000000
|
#60000000
|
||||||
|
|
|
||||||
|
|
@ -1,712 +0,0 @@
|
||||||
Simulation {
|
|
||||||
state: State {
|
|
||||||
insns: Insns {
|
|
||||||
state_layout: StateLayout {
|
|
||||||
ty: TypeLayout {
|
|
||||||
small_slots: StatePartLayout<SmallSlots> {
|
|
||||||
len: 2,
|
|
||||||
debug_data: [
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
big_slots: StatePartLayout<BigSlots> {
|
|
||||||
len: 33,
|
|
||||||
debug_data: [
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(last_connect: last_connect).last_connect::inp",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(Array<Bool, 4>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "[0]",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "[1]",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "[2]",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "[3]",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<5>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<4>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Bool,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(last_connect: last_connect).last_connect::out",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<9>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<9>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "InstantiatedModule(last_connect: last_connect).last_connect::w",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".0",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: ".1",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<1>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<9>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<9>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<9>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
SlotDebugData {
|
|
||||||
name: "",
|
|
||||||
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: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(32), // (0x3) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x3,
|
|
||||||
},
|
|
||||||
1: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(31), // (0x2) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x2,
|
|
||||||
},
|
|
||||||
2: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(30), // (0x1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x1,
|
|
||||||
},
|
|
||||||
3: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(29), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x0,
|
|
||||||
},
|
|
||||||
4: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(28), // (0x4) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
value: 0x4,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:8:1
|
|
||||||
5: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(28), // (0x4) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
6: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
value: 0x1,
|
|
||||||
},
|
|
||||||
7: Const {
|
|
||||||
dest: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
value: 0x0,
|
|
||||||
},
|
|
||||||
8: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(18), // (0x0) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:4:1
|
|
||||||
9: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(15), // (0x7) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::out", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(19), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
10: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(5), // (0x1f) SlotDebugData { name: "", ty: UInt<5> },
|
|
||||||
src: StatePartIndex<BigSlots>(0), // (0x1f) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::inp", ty: Enum {HdlNone, HdlSome(Array<Bool, 4>)} },
|
|
||||||
},
|
|
||||||
11: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(6), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
src: StatePartIndex<BigSlots>(5), // (0x1f) SlotDebugData { name: "", ty: UInt<5> },
|
|
||||||
start: 1,
|
|
||||||
len: 4,
|
|
||||||
},
|
|
||||||
12: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
start: 0,
|
|
||||||
len: 1,
|
|
||||||
},
|
|
||||||
13: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(8), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
},
|
|
||||||
14: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
start: 1,
|
|
||||||
len: 1,
|
|
||||||
},
|
|
||||||
15: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(10), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
},
|
|
||||||
16: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(11), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
start: 2,
|
|
||||||
len: 1,
|
|
||||||
},
|
|
||||||
17: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(12), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(11), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
},
|
|
||||||
18: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(13), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
src: StatePartIndex<BigSlots>(6), // (0xf) SlotDebugData { name: "", ty: UInt<4> },
|
|
||||||
start: 3,
|
|
||||||
len: 1,
|
|
||||||
},
|
|
||||||
19: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(14), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(13), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
},
|
|
||||||
20: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(1), // (0x1) SlotDebugData { name: "[0]", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(8), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
21: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "[1]", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(10), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
22: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(3), // (0x1) SlotDebugData { name: "[2]", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(12), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
23: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(4), // (0x1) SlotDebugData { name: "[3]", ty: Bool },
|
|
||||||
src: StatePartIndex<BigSlots>(14), // (0x1) SlotDebugData { name: "", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
24: BranchIfZero {
|
|
||||||
target: 26,
|
|
||||||
value: StatePartIndex<BigSlots>(1), // (0x1) SlotDebugData { name: "[0]", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
|
||||||
25: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(29), // (0x0) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
26: BranchIfZero {
|
|
||||||
target: 28,
|
|
||||||
value: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "[1]", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
|
||||||
27: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(30), // (0x1) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
28: BranchIfZero {
|
|
||||||
target: 30,
|
|
||||||
value: StatePartIndex<BigSlots>(3), // (0x1) SlotDebugData { name: "[2]", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
|
||||||
29: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(31), // (0x2) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:9:1
|
|
||||||
30: BranchIfZero {
|
|
||||||
target: 32,
|
|
||||||
value: StatePartIndex<BigSlots>(4), // (0x1) SlotDebugData { name: "[3]", ty: Bool },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:10:1
|
|
||||||
31: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(32), // (0x3) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
32: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(21), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> },
|
|
||||||
src: StatePartIndex<BigSlots>(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> },
|
|
||||||
},
|
|
||||||
33: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(22), // (0x3) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(20), // (0x3) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::w", ty: UInt<8> },
|
|
||||||
},
|
|
||||||
34: Shl {
|
|
||||||
dest: StatePartIndex<BigSlots>(24), // (0x6) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(22), // (0x3) SlotDebugData { name: ".1", ty: UInt<8> },
|
|
||||||
rhs: 1,
|
|
||||||
},
|
|
||||||
35: Or {
|
|
||||||
dest: StatePartIndex<BigSlots>(25), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
lhs: StatePartIndex<BigSlots>(21), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> },
|
|
||||||
rhs: StatePartIndex<BigSlots>(24), // (0x6) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
},
|
|
||||||
36: CastToUInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(26), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
src: StatePartIndex<BigSlots>(25), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
dest_width: 9,
|
|
||||||
},
|
|
||||||
37: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(27), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(26), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:2:1
|
|
||||||
38: AndBigWithSmallImmediate {
|
|
||||||
dest: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
|
||||||
lhs: StatePartIndex<BigSlots>(0), // (0x1f) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::inp", ty: Enum {HdlNone, HdlSome(Array<Bool, 4>)} },
|
|
||||||
rhs: 0x1,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:5:1
|
|
||||||
39: BranchIfSmallNeImmediate {
|
|
||||||
target: 41,
|
|
||||||
lhs: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
|
||||||
rhs: 0x1,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:7:1
|
|
||||||
40: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(15), // (0x7) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::out", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
src: StatePartIndex<BigSlots>(27), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:3:1
|
|
||||||
41: AndBigWithSmallImmediate {
|
|
||||||
dest: StatePartIndex<SmallSlots>(1), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
|
|
||||||
lhs: StatePartIndex<BigSlots>(15), // (0x7) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::out", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
rhs: 0x1,
|
|
||||||
},
|
|
||||||
// at: module-XXXXXXXXXX.rs:1:1
|
|
||||||
42: Copy {
|
|
||||||
dest: StatePartIndex<BigSlots>(16), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
src: StatePartIndex<BigSlots>(15), // (0x7) SlotDebugData { name: "InstantiatedModule(last_connect: last_connect).last_connect::out", ty: Enum {HdlNone, HdlSome(UInt<8>)} },
|
|
||||||
},
|
|
||||||
43: SliceInt {
|
|
||||||
dest: StatePartIndex<BigSlots>(17), // (0x3) SlotDebugData { name: "", ty: UInt<8> },
|
|
||||||
src: StatePartIndex<BigSlots>(16), // (0x7) SlotDebugData { name: "", ty: UInt<9> },
|
|
||||||
start: 1,
|
|
||||||
len: 8,
|
|
||||||
},
|
|
||||||
44: Return,
|
|
||||||
],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
pc: 44,
|
|
||||||
memory_write_log: [],
|
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
small_slots: StatePart {
|
|
||||||
value: [
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
big_slots: StatePart {
|
|
||||||
value: [
|
|
||||||
31,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
31,
|
|
||||||
15,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
7 (modified),
|
|
||||||
7,
|
|
||||||
3,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
6,
|
|
||||||
7,
|
|
||||||
7,
|
|
||||||
7,
|
|
||||||
4,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
sim_only_slots: StatePart {
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
io: Instance {
|
|
||||||
name: <simulator>::last_connect,
|
|
||||||
instantiated: Module {
|
|
||||||
name: last_connect,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
},
|
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
|
||||||
base_targets: [
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::last_connect,
|
|
||||||
instantiated: Module {
|
|
||||||
name: last_connect,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.inp,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::last_connect,
|
|
||||||
instantiated: Module {
|
|
||||||
name: last_connect,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.out,
|
|
||||||
],
|
|
||||||
uninitialized_ios: {},
|
|
||||||
io_targets: {
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::last_connect,
|
|
||||||
instantiated: Module {
|
|
||||||
name: last_connect,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.inp,
|
|
||||||
Instance {
|
|
||||||
name: <simulator>::last_connect,
|
|
||||||
instantiated: Module {
|
|
||||||
name: last_connect,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
}.out,
|
|
||||||
},
|
|
||||||
did_initial_settle: true,
|
|
||||||
clocks_for_past: {},
|
|
||||||
},
|
|
||||||
extern_modules: [],
|
|
||||||
trace_decls: TraceModule {
|
|
||||||
name: "last_connect",
|
|
||||||
children: [
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "inp",
|
|
||||||
child: TraceEnumWithFields {
|
|
||||||
name: "inp",
|
|
||||||
discriminant: TraceEnumDiscriminant {
|
|
||||||
location: TraceScalarId(0),
|
|
||||||
name: "$tag",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(Array<Bool, 4>),
|
|
||||||
},
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
non_empty_fields: [
|
|
||||||
TraceArray {
|
|
||||||
name: "HdlSome",
|
|
||||||
elements: [
|
|
||||||
TraceBool {
|
|
||||||
location: TraceScalarId(1),
|
|
||||||
name: "[0]",
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceBool {
|
|
||||||
location: TraceScalarId(2),
|
|
||||||
name: "[1]",
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceBool {
|
|
||||||
location: TraceScalarId(3),
|
|
||||||
name: "[2]",
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceBool {
|
|
||||||
location: TraceScalarId(4),
|
|
||||||
name: "[3]",
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ty: Array<Bool, 4>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(Array<Bool, 4>),
|
|
||||||
},
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(Array<Bool, 4>),
|
|
||||||
},
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
TraceModuleIO {
|
|
||||||
name: "out",
|
|
||||||
child: TraceEnumWithFields {
|
|
||||||
name: "out",
|
|
||||||
discriminant: TraceEnumDiscriminant {
|
|
||||||
location: TraceScalarId(5),
|
|
||||||
name: "$tag",
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
non_empty_fields: [
|
|
||||||
TraceUInt {
|
|
||||||
location: TraceScalarId(6),
|
|
||||||
name: "HdlSome",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Source,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
flow: Sink,
|
|
||||||
},
|
|
||||||
TraceWire {
|
|
||||||
name: "w",
|
|
||||||
child: TraceUInt {
|
|
||||||
location: TraceScalarId(7),
|
|
||||||
name: "w",
|
|
||||||
ty: UInt<8>,
|
|
||||||
flow: Duplex,
|
|
||||||
},
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
traces: [
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(0),
|
|
||||||
kind: EnumDiscriminant {
|
|
||||||
index: StatePartIndex<SmallSlots>(0),
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(Array<Bool, 4>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x1,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(1),
|
|
||||||
kind: BigBool {
|
|
||||||
index: StatePartIndex<BigSlots>(1),
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x1,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(2),
|
|
||||||
kind: BigBool {
|
|
||||||
index: StatePartIndex<BigSlots>(2),
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x1,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(3),
|
|
||||||
kind: BigBool {
|
|
||||||
index: StatePartIndex<BigSlots>(3),
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x1,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(4),
|
|
||||||
kind: BigBool {
|
|
||||||
index: StatePartIndex<BigSlots>(4),
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x0,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(5),
|
|
||||||
kind: EnumDiscriminant {
|
|
||||||
index: StatePartIndex<SmallSlots>(1),
|
|
||||||
ty: Enum {
|
|
||||||
HdlNone,
|
|
||||||
HdlSome(UInt<8>),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
|
||||||
last_state: 0x1,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(6),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(17),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x03,
|
|
||||||
last_state: 0x02,
|
|
||||||
},
|
|
||||||
SimTrace {
|
|
||||||
id: TraceScalarId(7),
|
|
||||||
kind: BigUInt {
|
|
||||||
index: StatePartIndex<BigSlots>(20),
|
|
||||||
ty: UInt<8>,
|
|
||||||
},
|
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x03,
|
|
||||||
last_state: 0x02,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
trace_memories: {},
|
|
||||||
trace_writers: [
|
|
||||||
Running(
|
|
||||||
VcdWriter {
|
|
||||||
finished_init: true,
|
|
||||||
timescale: 1 ps,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
clocks_triggered: [],
|
|
||||||
event_queue: EventQueue(EventQueueData {
|
|
||||||
instant: 17 μs,
|
|
||||||
events: {},
|
|
||||||
}),
|
|
||||||
waiting_sensitivity_sets_by_address: {},
|
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
|
||||||
asserts: [],
|
|
||||||
..
|
|
||||||
}
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
$timescale 1 ps $end
|
|
||||||
$scope module last_connect $end
|
|
||||||
$scope struct inp $end
|
|
||||||
$var string 1 !C&}* \$tag $end
|
|
||||||
$scope struct HdlSome $end
|
|
||||||
$var wire 1 D_viZ \[0] $end
|
|
||||||
$var wire 1 b5gFK \[1] $end
|
|
||||||
$var wire 1 xUBRH \[2] $end
|
|
||||||
$var wire 1 Gp7Xm \[3] $end
|
|
||||||
$upscope $end
|
|
||||||
$upscope $end
|
|
||||||
$scope struct out $end
|
|
||||||
$var string 1 ^Z_p3 \$tag $end
|
|
||||||
$var wire 8 rz~), HdlSome $end
|
|
||||||
$upscope $end
|
|
||||||
$var wire 8 dlea> w $end
|
|
||||||
$upscope $end
|
|
||||||
$enddefinitions $end
|
|
||||||
$dumpvars
|
|
||||||
sHdlNone\x20(0) !C&}*
|
|
||||||
0D_viZ
|
|
||||||
0b5gFK
|
|
||||||
0xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
sHdlNone\x20(0) ^Z_p3
|
|
||||||
b0 rz~),
|
|
||||||
b100 dlea>
|
|
||||||
$end
|
|
||||||
#1000000
|
|
||||||
sHdlSome\x20(1) !C&}*
|
|
||||||
sHdlSome\x20(1) ^Z_p3
|
|
||||||
b100 rz~),
|
|
||||||
#2000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#3000000
|
|
||||||
1xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b10 rz~),
|
|
||||||
b10 dlea>
|
|
||||||
#4000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#5000000
|
|
||||||
1b5gFK
|
|
||||||
0xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b1 rz~),
|
|
||||||
b1 dlea>
|
|
||||||
#6000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#7000000
|
|
||||||
1xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b10 rz~),
|
|
||||||
b10 dlea>
|
|
||||||
#8000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#9000000
|
|
||||||
1D_viZ
|
|
||||||
0b5gFK
|
|
||||||
0xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b0 rz~),
|
|
||||||
b0 dlea>
|
|
||||||
#10000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#11000000
|
|
||||||
1xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b10 rz~),
|
|
||||||
b10 dlea>
|
|
||||||
#12000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#13000000
|
|
||||||
1b5gFK
|
|
||||||
0xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b1 rz~),
|
|
||||||
b1 dlea>
|
|
||||||
#14000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#15000000
|
|
||||||
1xUBRH
|
|
||||||
0Gp7Xm
|
|
||||||
b10 rz~),
|
|
||||||
b10 dlea>
|
|
||||||
#16000000
|
|
||||||
1Gp7Xm
|
|
||||||
b11 rz~),
|
|
||||||
b11 dlea>
|
|
||||||
#17000000
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -494,7 +494,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 41,
|
pc: 41,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [
|
value: [
|
||||||
MemoryData {
|
MemoryData {
|
||||||
|
|
@ -580,7 +579,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -1170,7 +1168,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1179,7 +1176,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1188,7 +1184,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1198,7 +1193,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xb0,
|
state: 0xb0,
|
||||||
last_state: 0xb0,
|
last_state: 0xb0,
|
||||||
},
|
},
|
||||||
|
|
@ -1208,7 +1202,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
ty: SInt<8>,
|
ty: SInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xc0,
|
state: 0xc0,
|
||||||
last_state: 0xc0,
|
last_state: 0xc0,
|
||||||
},
|
},
|
||||||
|
|
@ -1218,7 +1211,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1227,7 +1219,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1236,7 +1227,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(7),
|
index: StatePartIndex<BigSlots>(7),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1246,7 +1236,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xd0,
|
state: 0xd0,
|
||||||
last_state: 0xd0,
|
last_state: 0xd0,
|
||||||
},
|
},
|
||||||
|
|
@ -1256,7 +1245,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
ty: SInt<8>,
|
ty: SInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe0,
|
state: 0xe0,
|
||||||
last_state: 0xe0,
|
last_state: 0xe0,
|
||||||
},
|
},
|
||||||
|
|
@ -1265,7 +1253,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(10),
|
index: StatePartIndex<BigSlots>(10),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1274,7 +1261,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(11),
|
index: StatePartIndex<BigSlots>(11),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1284,7 +1270,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(12),
|
index: StatePartIndex<BigSlots>(12),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1293,7 +1278,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(13),
|
index: StatePartIndex<BigSlots>(13),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1302,7 +1286,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(14),
|
index: StatePartIndex<BigSlots>(14),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1312,7 +1295,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(15),
|
index: StatePartIndex<BigSlots>(15),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xb0,
|
state: 0xb0,
|
||||||
last_state: 0xb0,
|
last_state: 0xb0,
|
||||||
},
|
},
|
||||||
|
|
@ -1322,7 +1304,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(16),
|
index: StatePartIndex<BigSlots>(16),
|
||||||
ty: SInt<8>,
|
ty: SInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xc0,
|
state: 0xc0,
|
||||||
last_state: 0xc0,
|
last_state: 0xc0,
|
||||||
},
|
},
|
||||||
|
|
@ -1332,7 +1313,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(17),
|
index: StatePartIndex<BigSlots>(17),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -1341,7 +1321,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(18),
|
index: StatePartIndex<BigSlots>(18),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1350,7 +1329,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(19),
|
index: StatePartIndex<BigSlots>(19),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1360,7 +1338,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(20),
|
index: StatePartIndex<BigSlots>(20),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xd0,
|
state: 0xd0,
|
||||||
last_state: 0xd0,
|
last_state: 0xd0,
|
||||||
},
|
},
|
||||||
|
|
@ -1370,7 +1347,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(21),
|
index: StatePartIndex<BigSlots>(21),
|
||||||
ty: SInt<8>,
|
ty: SInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xe0,
|
state: 0xe0,
|
||||||
last_state: 0xe0,
|
last_state: 0xe0,
|
||||||
},
|
},
|
||||||
|
|
@ -1379,7 +1355,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(22),
|
index: StatePartIndex<BigSlots>(22),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1388,7 +1363,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(23),
|
index: StatePartIndex<BigSlots>(23),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x1,
|
state: 0x1,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1652,6 +1626,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,408 +1,408 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module memories $end
|
$scope module memories $end
|
||||||
$scope struct r $end
|
$scope struct r $end
|
||||||
$var wire 4 z&0Qk addr $end
|
$var wire 4 ! addr $end
|
||||||
$var wire 1 o.T)# en $end
|
$var wire 1 " en $end
|
||||||
$var wire 1 :XNoK clk $end
|
$var wire 1 # clk $end
|
||||||
$scope struct data $end
|
$scope struct data $end
|
||||||
$var wire 8 Cq]A% \0 $end
|
$var wire 8 $ \0 $end
|
||||||
$var wire 8 avKNj \1 $end
|
$var wire 8 % \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct w $end
|
$scope struct w $end
|
||||||
$var wire 4 p<O.M addr $end
|
$var wire 4 & addr $end
|
||||||
$var wire 1 #9)l8 en $end
|
$var wire 1 ' en $end
|
||||||
$var wire 1 QX!^| clk $end
|
$var wire 1 ( clk $end
|
||||||
$scope struct data $end
|
$scope struct data $end
|
||||||
$var wire 8 G"IXQ \0 $end
|
$var wire 8 ) \0 $end
|
||||||
$var wire 8 h\t:E \1 $end
|
$var wire 8 * \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mask $end
|
$scope struct mask $end
|
||||||
$var wire 1 FCuNz \0 $end
|
$var wire 1 + \0 $end
|
||||||
$var wire 1 /Y7%J \1 $end
|
$var wire 1 , \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$scope struct contents $end
|
$scope struct contents $end
|
||||||
$scope struct \[0] $end
|
$scope struct \[0] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 4d[cL \0 $end
|
$var reg 8 9 \0 $end
|
||||||
$var reg 8 {qEUV \1 $end
|
$var reg 8 I \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[1] $end
|
$scope struct \[1] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 c`NPR \0 $end
|
$var reg 8 : \0 $end
|
||||||
$var reg 8 vK:33 \1 $end
|
$var reg 8 J \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[2] $end
|
$scope struct \[2] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ihYp_ \0 $end
|
$var reg 8 ; \0 $end
|
||||||
$var reg 8 QZb%P \1 $end
|
$var reg 8 K \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[3] $end
|
$scope struct \[3] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ,O%<$ \0 $end
|
$var reg 8 < \0 $end
|
||||||
$var reg 8 @?uSf \1 $end
|
$var reg 8 L \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[4] $end
|
$scope struct \[4] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 N[IF& \0 $end
|
$var reg 8 = \0 $end
|
||||||
$var reg 8 Zf9lw \1 $end
|
$var reg 8 M \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[5] $end
|
$scope struct \[5] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 dr6lq \0 $end
|
$var reg 8 > \0 $end
|
||||||
$var reg 8 fc"UR \1 $end
|
$var reg 8 N \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[6] $end
|
$scope struct \[6] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 xpw5\ \0 $end
|
$var reg 8 ? \0 $end
|
||||||
$var reg 8 dd$?K \1 $end
|
$var reg 8 O \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[7] $end
|
$scope struct \[7] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 vH;}2 \0 $end
|
$var reg 8 @ \0 $end
|
||||||
$var reg 8 ILB?4 \1 $end
|
$var reg 8 P \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[8] $end
|
$scope struct \[8] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 /X4v> \0 $end
|
$var reg 8 A \0 $end
|
||||||
$var reg 8 &V*EE \1 $end
|
$var reg 8 Q \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[9] $end
|
$scope struct \[9] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 IczZe \0 $end
|
$var reg 8 B \0 $end
|
||||||
$var reg 8 unX>R \1 $end
|
$var reg 8 R \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[10] $end
|
$scope struct \[10] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 0hTyY \0 $end
|
$var reg 8 C \0 $end
|
||||||
$var reg 8 9K_w) \1 $end
|
$var reg 8 S \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[11] $end
|
$scope struct \[11] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 +C/Sz \0 $end
|
$var reg 8 D \0 $end
|
||||||
$var reg 8 }Y{:o \1 $end
|
$var reg 8 T \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[12] $end
|
$scope struct \[12] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 S6-5u \0 $end
|
$var reg 8 E \0 $end
|
||||||
$var reg 8 9q6)w \1 $end
|
$var reg 8 U \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[13] $end
|
$scope struct \[13] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 !c<w* \0 $end
|
$var reg 8 F \0 $end
|
||||||
$var reg 8 Ve@)M \1 $end
|
$var reg 8 V \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[14] $end
|
$scope struct \[14] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 OiF9* \0 $end
|
$var reg 8 G \0 $end
|
||||||
$var reg 8 Ylyz~ \1 $end
|
$var reg 8 W \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[15] $end
|
$scope struct \[15] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ?+m9D \0 $end
|
$var reg 8 H \0 $end
|
||||||
$var reg 8 A6sb~ \1 $end
|
$var reg 8 X \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct r0 $end
|
$scope struct r0 $end
|
||||||
$var wire 4 ="2wN addr $end
|
$var wire 4 - addr $end
|
||||||
$var wire 1 jy78F en $end
|
$var wire 1 . en $end
|
||||||
$var wire 1 \o>8T clk $end
|
$var wire 1 / clk $end
|
||||||
$scope struct data $end
|
$scope struct data $end
|
||||||
$var wire 8 \k#l \0 $end
|
$var wire 8 0 \0 $end
|
||||||
$var wire 8 olx7O \1 $end
|
$var wire 8 1 \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct w1 $end
|
$scope struct w1 $end
|
||||||
$var wire 4 H,W!J addr $end
|
$var wire 4 2 addr $end
|
||||||
$var wire 1 "7?3I en $end
|
$var wire 1 3 en $end
|
||||||
$var wire 1 DC/;" clk $end
|
$var wire 1 4 clk $end
|
||||||
$scope struct data $end
|
$scope struct data $end
|
||||||
$var wire 8 0DrV' \0 $end
|
$var wire 8 5 \0 $end
|
||||||
$var wire 8 wa!Cx \1 $end
|
$var wire 8 6 \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mask $end
|
$scope struct mask $end
|
||||||
$var wire 1 u^b&R \0 $end
|
$var wire 1 7 \0 $end
|
||||||
$var wire 1 Ic\|v \1 $end
|
$var wire 1 8 \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
b1 4d[cL
|
b1 9
|
||||||
b100011 {qEUV
|
b100011 I
|
||||||
b1 c`NPR
|
b1 :
|
||||||
b100011 vK:33
|
b100011 J
|
||||||
b1 ihYp_
|
b1 ;
|
||||||
b100011 QZb%P
|
b100011 K
|
||||||
b1 ,O%<$
|
b1 <
|
||||||
b100011 @?uSf
|
b100011 L
|
||||||
b1 N[IF&
|
b1 =
|
||||||
b100011 Zf9lw
|
b100011 M
|
||||||
b1 dr6lq
|
b1 >
|
||||||
b100011 fc"UR
|
b100011 N
|
||||||
b1 xpw5\
|
b1 ?
|
||||||
b100011 dd$?K
|
b100011 O
|
||||||
b1 vH;}2
|
b1 @
|
||||||
b100011 ILB?4
|
b100011 P
|
||||||
b1 /X4v>
|
b1 A
|
||||||
b100011 &V*EE
|
b100011 Q
|
||||||
b1 IczZe
|
b1 B
|
||||||
b100011 unX>R
|
b100011 R
|
||||||
b1 0hTyY
|
b1 C
|
||||||
b100011 9K_w)
|
b100011 S
|
||||||
b1 +C/Sz
|
b1 D
|
||||||
b100011 }Y{:o
|
b100011 T
|
||||||
b1 S6-5u
|
b1 E
|
||||||
b100011 9q6)w
|
b100011 U
|
||||||
b1 !c<w*
|
b1 F
|
||||||
b100011 Ve@)M
|
b100011 V
|
||||||
b1 OiF9*
|
b1 G
|
||||||
b100011 Ylyz~
|
b100011 W
|
||||||
b1 ?+m9D
|
b1 H
|
||||||
b100011 A6sb~
|
b100011 X
|
||||||
b0 z&0Qk
|
b0 !
|
||||||
0o.T)#
|
0"
|
||||||
0:XNoK
|
0#
|
||||||
b0 Cq]A%
|
b0 $
|
||||||
b0 avKNj
|
b0 %
|
||||||
b0 p<O.M
|
b0 &
|
||||||
0#9)l8
|
0'
|
||||||
0QX!^|
|
0(
|
||||||
b0 G"IXQ
|
b0 )
|
||||||
b0 h\t:E
|
b0 *
|
||||||
0FCuNz
|
0+
|
||||||
0/Y7%J
|
0,
|
||||||
b0 ="2wN
|
b0 -
|
||||||
0jy78F
|
0.
|
||||||
0\o>8T
|
0/
|
||||||
b0 \k#l
|
b0 0
|
||||||
b0 olx7O
|
b0 1
|
||||||
b0 H,W!J
|
b0 2
|
||||||
0"7?3I
|
03
|
||||||
0DC/;"
|
04
|
||||||
b0 0DrV'
|
b0 5
|
||||||
b0 wa!Cx
|
b0 6
|
||||||
0u^b&R
|
07
|
||||||
0Ic\|v
|
08
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#2000000
|
#2000000
|
||||||
1o.T)#
|
1"
|
||||||
0:XNoK
|
0#
|
||||||
b1 Cq]A%
|
b1 $
|
||||||
b100011 avKNj
|
b100011 %
|
||||||
1#9)l8
|
1'
|
||||||
0QX!^|
|
0(
|
||||||
b10000 G"IXQ
|
b10000 )
|
||||||
b100000 h\t:E
|
b100000 *
|
||||||
1FCuNz
|
1+
|
||||||
1/Y7%J
|
1,
|
||||||
1jy78F
|
1.
|
||||||
0\o>8T
|
0/
|
||||||
b1 \k#l
|
b1 0
|
||||||
b100011 olx7O
|
b100011 1
|
||||||
1"7?3I
|
13
|
||||||
0DC/;"
|
04
|
||||||
b10000 0DrV'
|
b10000 5
|
||||||
b100000 wa!Cx
|
b100000 6
|
||||||
1u^b&R
|
17
|
||||||
1Ic\|v
|
18
|
||||||
#3000000
|
#3000000
|
||||||
b10000 4d[cL
|
b10000 9
|
||||||
b100000 {qEUV
|
b100000 I
|
||||||
1:XNoK
|
1#
|
||||||
b10000 Cq]A%
|
b10000 $
|
||||||
b100000 avKNj
|
b100000 %
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
b10000 \k#l
|
b10000 0
|
||||||
b100000 olx7O
|
b100000 1
|
||||||
1DC/;"
|
14
|
||||||
#4000000
|
#4000000
|
||||||
0:XNoK
|
0#
|
||||||
0QX!^|
|
0(
|
||||||
b110000 G"IXQ
|
b110000 )
|
||||||
b1000000 h\t:E
|
b1000000 *
|
||||||
0FCuNz
|
0+
|
||||||
0\o>8T
|
0/
|
||||||
0DC/;"
|
04
|
||||||
b110000 0DrV'
|
b110000 5
|
||||||
b1000000 wa!Cx
|
b1000000 6
|
||||||
0u^b&R
|
07
|
||||||
#5000000
|
#5000000
|
||||||
b10000 4d[cL
|
b10000 9
|
||||||
b1000000 {qEUV
|
b1000000 I
|
||||||
1:XNoK
|
1#
|
||||||
b1000000 avKNj
|
b1000000 %
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
b1000000 olx7O
|
b1000000 1
|
||||||
1DC/;"
|
14
|
||||||
#6000000
|
#6000000
|
||||||
0:XNoK
|
0#
|
||||||
0QX!^|
|
0(
|
||||||
b1010000 G"IXQ
|
b1010000 )
|
||||||
b1100000 h\t:E
|
b1100000 *
|
||||||
1FCuNz
|
1+
|
||||||
0/Y7%J
|
0,
|
||||||
0\o>8T
|
0/
|
||||||
0DC/;"
|
04
|
||||||
b1010000 0DrV'
|
b1010000 5
|
||||||
b1100000 wa!Cx
|
b1100000 6
|
||||||
1u^b&R
|
17
|
||||||
0Ic\|v
|
08
|
||||||
#7000000
|
#7000000
|
||||||
b1010000 4d[cL
|
b1010000 9
|
||||||
b1000000 {qEUV
|
b1000000 I
|
||||||
1:XNoK
|
1#
|
||||||
b1010000 Cq]A%
|
b1010000 $
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
b1010000 \k#l
|
b1010000 0
|
||||||
1DC/;"
|
14
|
||||||
#8000000
|
#8000000
|
||||||
0:XNoK
|
0#
|
||||||
0QX!^|
|
0(
|
||||||
b1110000 G"IXQ
|
b1110000 )
|
||||||
b10000000 h\t:E
|
b10000000 *
|
||||||
0FCuNz
|
0+
|
||||||
0\o>8T
|
0/
|
||||||
0DC/;"
|
04
|
||||||
b1110000 0DrV'
|
b1110000 5
|
||||||
b10000000 wa!Cx
|
b10000000 6
|
||||||
0u^b&R
|
07
|
||||||
#9000000
|
#9000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#10000000
|
#10000000
|
||||||
0:XNoK
|
0#
|
||||||
0#9)l8
|
0'
|
||||||
0QX!^|
|
0(
|
||||||
b10010000 G"IXQ
|
b10010000 )
|
||||||
b10100000 h\t:E
|
b10100000 *
|
||||||
0\o>8T
|
0/
|
||||||
0"7?3I
|
03
|
||||||
0DC/;"
|
04
|
||||||
b10010000 0DrV'
|
b10010000 5
|
||||||
b10100000 wa!Cx
|
b10100000 6
|
||||||
#11000000
|
#11000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#12000000
|
#12000000
|
||||||
0:XNoK
|
0#
|
||||||
b1 p<O.M
|
b1 &
|
||||||
1#9)l8
|
1'
|
||||||
0QX!^|
|
0(
|
||||||
1FCuNz
|
1+
|
||||||
1/Y7%J
|
1,
|
||||||
0\o>8T
|
0/
|
||||||
b1 H,W!J
|
b1 2
|
||||||
1"7?3I
|
13
|
||||||
0DC/;"
|
04
|
||||||
1u^b&R
|
17
|
||||||
1Ic\|v
|
18
|
||||||
#13000000
|
#13000000
|
||||||
b10010000 c`NPR
|
b10010000 :
|
||||||
b10100000 vK:33
|
b10100000 J
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#14000000
|
#14000000
|
||||||
0:XNoK
|
0#
|
||||||
b10 p<O.M
|
b10 &
|
||||||
0QX!^|
|
0(
|
||||||
b10110000 G"IXQ
|
b10110000 )
|
||||||
b11000000 h\t:E
|
b11000000 *
|
||||||
0\o>8T
|
0/
|
||||||
b10 H,W!J
|
b10 2
|
||||||
0DC/;"
|
04
|
||||||
b10110000 0DrV'
|
b10110000 5
|
||||||
b11000000 wa!Cx
|
b11000000 6
|
||||||
#15000000
|
#15000000
|
||||||
b10110000 ihYp_
|
b10110000 ;
|
||||||
b11000000 QZb%P
|
b11000000 K
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#16000000
|
#16000000
|
||||||
0:XNoK
|
0#
|
||||||
0#9)l8
|
0'
|
||||||
0QX!^|
|
0(
|
||||||
b11010000 G"IXQ
|
b11010000 )
|
||||||
b11100000 h\t:E
|
b11100000 *
|
||||||
0\o>8T
|
0/
|
||||||
0"7?3I
|
03
|
||||||
0DC/;"
|
04
|
||||||
b11010000 0DrV'
|
b11010000 5
|
||||||
b11100000 wa!Cx
|
b11100000 6
|
||||||
#17000000
|
#17000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#18000000
|
#18000000
|
||||||
b1 z&0Qk
|
b1 !
|
||||||
0:XNoK
|
0#
|
||||||
b10010000 Cq]A%
|
b10010000 $
|
||||||
b10100000 avKNj
|
b10100000 %
|
||||||
0QX!^|
|
0(
|
||||||
b1 ="2wN
|
b1 -
|
||||||
0\o>8T
|
0/
|
||||||
b10010000 \k#l
|
b10010000 0
|
||||||
b10100000 olx7O
|
b10100000 1
|
||||||
0DC/;"
|
04
|
||||||
#19000000
|
#19000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#20000000
|
#20000000
|
||||||
b10 z&0Qk
|
b10 !
|
||||||
0:XNoK
|
0#
|
||||||
b10110000 Cq]A%
|
b10110000 $
|
||||||
b11000000 avKNj
|
b11000000 %
|
||||||
0QX!^|
|
0(
|
||||||
b10 ="2wN
|
b10 -
|
||||||
0\o>8T
|
0/
|
||||||
b10110000 \k#l
|
b10110000 0
|
||||||
b11000000 olx7O
|
b11000000 1
|
||||||
0DC/;"
|
04
|
||||||
#21000000
|
#21000000
|
||||||
1:XNoK
|
1#
|
||||||
1QX!^|
|
1(
|
||||||
1\o>8T
|
1/
|
||||||
1DC/;"
|
14
|
||||||
#22000000
|
#22000000
|
||||||
0:XNoK
|
0#
|
||||||
0QX!^|
|
0(
|
||||||
0\o>8T
|
0/
|
||||||
0DC/;"
|
04
|
||||||
|
|
|
||||||
|
|
@ -526,7 +526,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 52,
|
pc: 52,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [
|
value: [
|
||||||
MemoryData {
|
MemoryData {
|
||||||
|
|
@ -608,7 +607,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -945,7 +943,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -954,7 +951,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -963,7 +959,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -973,7 +968,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<2>,
|
ty: UInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -982,7 +976,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -992,7 +985,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: UInt<2>,
|
ty: UInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: false,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1001,7 +993,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1011,7 +1002,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(7),
|
index: StatePartIndex<BigSlots>(7),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1020,7 +1010,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1029,7 +1018,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -1042,7 +1030,6 @@ Simulation {
|
||||||
HdlSome(Bool),
|
HdlSome(Bool),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1051,7 +1038,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(16),
|
index: StatePartIndex<BigSlots>(16),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1060,7 +1046,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(11),
|
index: StatePartIndex<BigSlots>(11),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1073,7 +1058,6 @@ Simulation {
|
||||||
HdlSome(Bool),
|
HdlSome(Bool),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1082,7 +1066,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(19),
|
index: StatePartIndex<BigSlots>(19),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1091,7 +1074,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(13),
|
index: StatePartIndex<BigSlots>(13),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -1287,6 +1269,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,363 +1,363 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module memories2 $end
|
$scope module memories2 $end
|
||||||
$scope struct rw $end
|
$scope struct rw $end
|
||||||
$var wire 3 xkkG> addr $end
|
$var wire 3 ! addr $end
|
||||||
$var wire 1 HoA{1 en $end
|
$var wire 1 " en $end
|
||||||
$var wire 1 C*2BQ clk $end
|
$var wire 1 # clk $end
|
||||||
$var wire 2 ueF!x rdata $end
|
$var wire 2 $ rdata $end
|
||||||
$var wire 1 m\l/p wmode $end
|
$var wire 1 % wmode $end
|
||||||
$var wire 2 WmjEh wdata $end
|
$var wire 2 & wdata $end
|
||||||
$var wire 1 +3E@H wmask $end
|
$var wire 1 ' wmask $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$scope struct contents $end
|
$scope struct contents $end
|
||||||
$scope struct \[0] $end
|
$scope struct \[0] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 ujd9u \$tag $end
|
$var string 1 1 \$tag $end
|
||||||
$var reg 1 *5lV# HdlSome $end
|
$var reg 1 6 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[1] $end
|
$scope struct \[1] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 *qL|n \$tag $end
|
$var string 1 2 \$tag $end
|
||||||
$var reg 1 ^/FDC HdlSome $end
|
$var reg 1 7 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[2] $end
|
$scope struct \[2] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 r*7|@ \$tag $end
|
$var string 1 3 \$tag $end
|
||||||
$var reg 1 YMY"3 HdlSome $end
|
$var reg 1 8 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[3] $end
|
$scope struct \[3] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 jj/6F \$tag $end
|
$var string 1 4 \$tag $end
|
||||||
$var reg 1 S+Uy} HdlSome $end
|
$var reg 1 9 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct \[4] $end
|
$scope struct \[4] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 H72IP \$tag $end
|
$var string 1 5 \$tag $end
|
||||||
$var reg 1 vH{({ HdlSome $end
|
$var reg 1 : HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct rw0 $end
|
$scope struct rw0 $end
|
||||||
$var wire 3 uabMI addr $end
|
$var wire 3 ( addr $end
|
||||||
$var wire 1 LEn[l en $end
|
$var wire 1 ) en $end
|
||||||
$var wire 1 OpH)U clk $end
|
$var wire 1 * clk $end
|
||||||
$scope struct rdata $end
|
$scope struct rdata $end
|
||||||
$var string 1 [}rcZ \$tag $end
|
$var string 1 + \$tag $end
|
||||||
$var wire 1 5f=Y~ HdlSome $end
|
$var wire 1 , HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 1 6c_9_ wmode $end
|
$var wire 1 - wmode $end
|
||||||
$scope struct wdata $end
|
$scope struct wdata $end
|
||||||
$var string 1 $hfRN \$tag $end
|
$var string 1 . \$tag $end
|
||||||
$var wire 1 rop,b HdlSome $end
|
$var wire 1 / HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$var wire 1 Ly=US wmask $end
|
$var wire 1 0 wmask $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
sHdlSome\x20(1) ujd9u
|
sHdlSome\x20(1) 1
|
||||||
1*5lV#
|
16
|
||||||
sHdlSome\x20(1) *qL|n
|
sHdlSome\x20(1) 2
|
||||||
1^/FDC
|
17
|
||||||
sHdlSome\x20(1) r*7|@
|
sHdlSome\x20(1) 3
|
||||||
1YMY"3
|
18
|
||||||
sHdlSome\x20(1) jj/6F
|
sHdlSome\x20(1) 4
|
||||||
1S+Uy}
|
19
|
||||||
sHdlSome\x20(1) H72IP
|
sHdlSome\x20(1) 5
|
||||||
1vH{({
|
1:
|
||||||
b0 xkkG>
|
b0 !
|
||||||
0HoA{1
|
0"
|
||||||
0C*2BQ
|
0#
|
||||||
b0 ueF!x
|
b0 $
|
||||||
0m\l/p
|
0%
|
||||||
b0 WmjEh
|
b0 &
|
||||||
0+3E@H
|
0'
|
||||||
b0 uabMI
|
b0 (
|
||||||
0LEn[l
|
0)
|
||||||
0OpH)U
|
0*
|
||||||
sHdlNone\x20(0) [}rcZ
|
sHdlNone\x20(0) +
|
||||||
05f=Y~
|
0,
|
||||||
06c_9_
|
0-
|
||||||
sHdlNone\x20(0) $hfRN
|
sHdlNone\x20(0) .
|
||||||
0rop,b
|
0/
|
||||||
0Ly=US
|
00
|
||||||
$end
|
$end
|
||||||
#250000
|
#250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#500000
|
#500000
|
||||||
#750000
|
#750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#1000000
|
#1000000
|
||||||
1HoA{1
|
1"
|
||||||
1LEn[l
|
1)
|
||||||
#1250000
|
#1250000
|
||||||
1C*2BQ
|
1#
|
||||||
b11 ueF!x
|
b11 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlSome\x20(1) [}rcZ
|
sHdlSome\x20(1) +
|
||||||
15f=Y~
|
1,
|
||||||
#1500000
|
#1500000
|
||||||
#1750000
|
#1750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#2000000
|
#2000000
|
||||||
0HoA{1
|
0"
|
||||||
0LEn[l
|
0)
|
||||||
#2250000
|
#2250000
|
||||||
1C*2BQ
|
1#
|
||||||
b0 ueF!x
|
b0 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlNone\x20(0) [}rcZ
|
sHdlNone\x20(0) +
|
||||||
05f=Y~
|
0,
|
||||||
#2500000
|
#2500000
|
||||||
#2750000
|
#2750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#3000000
|
#3000000
|
||||||
1HoA{1
|
1"
|
||||||
1m\l/p
|
1%
|
||||||
1+3E@H
|
1'
|
||||||
1LEn[l
|
1)
|
||||||
16c_9_
|
1-
|
||||||
1Ly=US
|
10
|
||||||
#3250000
|
#3250000
|
||||||
sHdlNone\x20(0) ujd9u
|
sHdlNone\x20(0) 1
|
||||||
0*5lV#
|
06
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#3500000
|
#3500000
|
||||||
#3750000
|
#3750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#4000000
|
#4000000
|
||||||
0m\l/p
|
0%
|
||||||
0+3E@H
|
0'
|
||||||
06c_9_
|
0-
|
||||||
0Ly=US
|
00
|
||||||
#4250000
|
#4250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#4500000
|
#4500000
|
||||||
#4750000
|
#4750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#5000000
|
#5000000
|
||||||
1m\l/p
|
1%
|
||||||
b11 WmjEh
|
b11 &
|
||||||
16c_9_
|
1-
|
||||||
sHdlSome\x20(1) $hfRN
|
sHdlSome\x20(1) .
|
||||||
1rop,b
|
1/
|
||||||
#5250000
|
#5250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#5500000
|
#5500000
|
||||||
#5750000
|
#5750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#6000000
|
#6000000
|
||||||
b1 xkkG>
|
b1 !
|
||||||
b1 WmjEh
|
b1 &
|
||||||
1+3E@H
|
1'
|
||||||
b1 uabMI
|
b1 (
|
||||||
0rop,b
|
0/
|
||||||
1Ly=US
|
10
|
||||||
#6250000
|
#6250000
|
||||||
sHdlSome\x20(1) *qL|n
|
sHdlSome\x20(1) 2
|
||||||
0^/FDC
|
07
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#6500000
|
#6500000
|
||||||
#6750000
|
#6750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#7000000
|
#7000000
|
||||||
b10 xkkG>
|
b10 !
|
||||||
b10 WmjEh
|
b10 &
|
||||||
b10 uabMI
|
b10 (
|
||||||
sHdlNone\x20(0) $hfRN
|
sHdlNone\x20(0) .
|
||||||
#7250000
|
#7250000
|
||||||
sHdlNone\x20(0) r*7|@
|
sHdlNone\x20(0) 3
|
||||||
0YMY"3
|
08
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#7500000
|
#7500000
|
||||||
#7750000
|
#7750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#8000000
|
#8000000
|
||||||
b11 xkkG>
|
b11 !
|
||||||
b11 WmjEh
|
b11 &
|
||||||
b11 uabMI
|
b11 (
|
||||||
sHdlSome\x20(1) $hfRN
|
sHdlSome\x20(1) .
|
||||||
1rop,b
|
1/
|
||||||
#8250000
|
#8250000
|
||||||
sHdlSome\x20(1) jj/6F
|
sHdlSome\x20(1) 4
|
||||||
1S+Uy}
|
19
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#8500000
|
#8500000
|
||||||
#8750000
|
#8750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#9000000
|
#9000000
|
||||||
b100 xkkG>
|
b100 !
|
||||||
b10 WmjEh
|
b10 &
|
||||||
b100 uabMI
|
b100 (
|
||||||
sHdlNone\x20(0) $hfRN
|
sHdlNone\x20(0) .
|
||||||
0rop,b
|
0/
|
||||||
#9250000
|
#9250000
|
||||||
sHdlNone\x20(0) H72IP
|
sHdlNone\x20(0) 5
|
||||||
0vH{({
|
0:
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#9500000
|
#9500000
|
||||||
#9750000
|
#9750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#10000000
|
#10000000
|
||||||
b101 xkkG>
|
b101 !
|
||||||
b1 WmjEh
|
b1 &
|
||||||
b101 uabMI
|
b101 (
|
||||||
sHdlSome\x20(1) $hfRN
|
sHdlSome\x20(1) .
|
||||||
#10250000
|
#10250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#10500000
|
#10500000
|
||||||
#10750000
|
#10750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#11000000
|
#11000000
|
||||||
b110 xkkG>
|
b110 !
|
||||||
b110 uabMI
|
b110 (
|
||||||
#11250000
|
#11250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#11500000
|
#11500000
|
||||||
#11750000
|
#11750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#12000000
|
#12000000
|
||||||
b111 xkkG>
|
b111 !
|
||||||
b111 uabMI
|
b111 (
|
||||||
#12250000
|
#12250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#12500000
|
#12500000
|
||||||
#12750000
|
#12750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#13000000
|
#13000000
|
||||||
0m\l/p
|
0%
|
||||||
b0 WmjEh
|
b0 &
|
||||||
0+3E@H
|
0'
|
||||||
06c_9_
|
0-
|
||||||
sHdlNone\x20(0) $hfRN
|
sHdlNone\x20(0) .
|
||||||
0Ly=US
|
00
|
||||||
#13250000
|
#13250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#13500000
|
#13500000
|
||||||
#13750000
|
#13750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#14000000
|
#14000000
|
||||||
b110 xkkG>
|
b110 !
|
||||||
b110 uabMI
|
b110 (
|
||||||
#14250000
|
#14250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#14500000
|
#14500000
|
||||||
#14750000
|
#14750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#15000000
|
#15000000
|
||||||
b101 xkkG>
|
b101 !
|
||||||
b101 uabMI
|
b101 (
|
||||||
#15250000
|
#15250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#15500000
|
#15500000
|
||||||
#15750000
|
#15750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#16000000
|
#16000000
|
||||||
b100 xkkG>
|
b100 !
|
||||||
b100 uabMI
|
b100 (
|
||||||
#16250000
|
#16250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#16500000
|
#16500000
|
||||||
#16750000
|
#16750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#17000000
|
#17000000
|
||||||
b11 xkkG>
|
b11 !
|
||||||
b11 uabMI
|
b11 (
|
||||||
#17250000
|
#17250000
|
||||||
1C*2BQ
|
1#
|
||||||
b11 ueF!x
|
b11 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlSome\x20(1) [}rcZ
|
sHdlSome\x20(1) +
|
||||||
15f=Y~
|
1,
|
||||||
#17500000
|
#17500000
|
||||||
#17750000
|
#17750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#18000000
|
#18000000
|
||||||
b10 xkkG>
|
b10 !
|
||||||
b10 uabMI
|
b10 (
|
||||||
#18250000
|
#18250000
|
||||||
1C*2BQ
|
1#
|
||||||
b0 ueF!x
|
b0 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlNone\x20(0) [}rcZ
|
sHdlNone\x20(0) +
|
||||||
05f=Y~
|
0,
|
||||||
#18500000
|
#18500000
|
||||||
#18750000
|
#18750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#19000000
|
#19000000
|
||||||
b0 xkkG>
|
b0 !
|
||||||
b0 uabMI
|
b0 (
|
||||||
#19250000
|
#19250000
|
||||||
1C*2BQ
|
1#
|
||||||
1OpH)U
|
1*
|
||||||
#19500000
|
#19500000
|
||||||
#19750000
|
#19750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#20000000
|
#20000000
|
||||||
b1 xkkG>
|
b1 !
|
||||||
b1 uabMI
|
b1 (
|
||||||
#20250000
|
#20250000
|
||||||
1C*2BQ
|
1#
|
||||||
b1 ueF!x
|
b1 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlSome\x20(1) [}rcZ
|
sHdlSome\x20(1) +
|
||||||
#20500000
|
#20500000
|
||||||
#20750000
|
#20750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#21000000
|
#21000000
|
||||||
b0 xkkG>
|
b0 !
|
||||||
0HoA{1
|
0"
|
||||||
b0 uabMI
|
b0 (
|
||||||
0LEn[l
|
0)
|
||||||
#21250000
|
#21250000
|
||||||
1C*2BQ
|
1#
|
||||||
b0 ueF!x
|
b0 $
|
||||||
1OpH)U
|
1*
|
||||||
sHdlNone\x20(0) [}rcZ
|
sHdlNone\x20(0) +
|
||||||
#21500000
|
#21500000
|
||||||
#21750000
|
#21750000
|
||||||
0C*2BQ
|
0#
|
||||||
0OpH)U
|
0*
|
||||||
#22000000
|
#22000000
|
||||||
|
|
|
||||||
|
|
@ -1336,7 +1336,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 129,
|
pc: 129,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [
|
value: [
|
||||||
MemoryData {
|
MemoryData {
|
||||||
|
|
@ -1496,7 +1495,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -2393,7 +2391,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2402,7 +2399,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2411,7 +2407,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -2421,7 +2416,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2431,7 +2425,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2441,7 +2434,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2451,7 +2443,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2461,7 +2452,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(7),
|
index: StatePartIndex<BigSlots>(7),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2471,7 +2461,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2481,7 +2470,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2491,7 +2479,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(10),
|
index: StatePartIndex<BigSlots>(10),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2501,7 +2488,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(11),
|
index: StatePartIndex<BigSlots>(11),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2510,7 +2496,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(12),
|
index: StatePartIndex<BigSlots>(12),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2519,7 +2504,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(13),
|
index: StatePartIndex<BigSlots>(13),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -2529,7 +2513,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(14),
|
index: StatePartIndex<BigSlots>(14),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2539,7 +2522,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(15),
|
index: StatePartIndex<BigSlots>(15),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2549,7 +2531,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(16),
|
index: StatePartIndex<BigSlots>(16),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2559,7 +2540,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(17),
|
index: StatePartIndex<BigSlots>(17),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2569,7 +2549,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(18),
|
index: StatePartIndex<BigSlots>(18),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2579,7 +2558,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(19),
|
index: StatePartIndex<BigSlots>(19),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2589,7 +2567,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(20),
|
index: StatePartIndex<BigSlots>(20),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2599,7 +2576,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(21),
|
index: StatePartIndex<BigSlots>(21),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2608,7 +2584,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(22),
|
index: StatePartIndex<BigSlots>(22),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2617,7 +2592,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(23),
|
index: StatePartIndex<BigSlots>(23),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2626,7 +2600,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(24),
|
index: StatePartIndex<BigSlots>(24),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2635,7 +2608,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(25),
|
index: StatePartIndex<BigSlots>(25),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2644,7 +2616,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(26),
|
index: StatePartIndex<BigSlots>(26),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2653,7 +2624,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(27),
|
index: StatePartIndex<BigSlots>(27),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2662,7 +2632,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(28),
|
index: StatePartIndex<BigSlots>(28),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2671,7 +2640,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(29),
|
index: StatePartIndex<BigSlots>(29),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2681,7 +2649,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(30),
|
index: StatePartIndex<BigSlots>(30),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2690,7 +2657,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(31),
|
index: StatePartIndex<BigSlots>(31),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2699,7 +2665,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(32),
|
index: StatePartIndex<BigSlots>(32),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -2709,7 +2674,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(33),
|
index: StatePartIndex<BigSlots>(33),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2719,7 +2683,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(34),
|
index: StatePartIndex<BigSlots>(34),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2729,7 +2692,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(35),
|
index: StatePartIndex<BigSlots>(35),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2739,7 +2701,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(36),
|
index: StatePartIndex<BigSlots>(36),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2749,7 +2710,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(37),
|
index: StatePartIndex<BigSlots>(37),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2759,7 +2719,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(38),
|
index: StatePartIndex<BigSlots>(38),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2769,7 +2728,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(39),
|
index: StatePartIndex<BigSlots>(39),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2779,7 +2737,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(40),
|
index: StatePartIndex<BigSlots>(40),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2789,7 +2746,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(57),
|
index: StatePartIndex<BigSlots>(57),
|
||||||
ty: UInt<3>,
|
ty: UInt<3>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2798,7 +2754,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(58),
|
index: StatePartIndex<BigSlots>(58),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2807,7 +2762,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(59),
|
index: StatePartIndex<BigSlots>(59),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x1,
|
last_state: 0x1,
|
||||||
},
|
},
|
||||||
|
|
@ -2817,7 +2771,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(60),
|
index: StatePartIndex<BigSlots>(60),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2827,7 +2780,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(61),
|
index: StatePartIndex<BigSlots>(61),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2837,7 +2789,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(62),
|
index: StatePartIndex<BigSlots>(62),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2847,7 +2798,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(63),
|
index: StatePartIndex<BigSlots>(63),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2857,7 +2807,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(64),
|
index: StatePartIndex<BigSlots>(64),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2867,7 +2816,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(65),
|
index: StatePartIndex<BigSlots>(65),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2877,7 +2825,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(66),
|
index: StatePartIndex<BigSlots>(66),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2887,7 +2834,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(67),
|
index: StatePartIndex<BigSlots>(67),
|
||||||
ty: UInt<8>,
|
ty: UInt<8>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x00,
|
state: 0x00,
|
||||||
last_state: 0x00,
|
last_state: 0x00,
|
||||||
},
|
},
|
||||||
|
|
@ -2896,7 +2842,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(68),
|
index: StatePartIndex<BigSlots>(68),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2905,7 +2850,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(69),
|
index: StatePartIndex<BigSlots>(69),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2914,7 +2858,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(70),
|
index: StatePartIndex<BigSlots>(70),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2923,7 +2866,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(71),
|
index: StatePartIndex<BigSlots>(71),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2932,7 +2874,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(72),
|
index: StatePartIndex<BigSlots>(72),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2941,7 +2882,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(73),
|
index: StatePartIndex<BigSlots>(73),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2950,7 +2890,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(74),
|
index: StatePartIndex<BigSlots>(74),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -2959,7 +2898,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(75),
|
index: StatePartIndex<BigSlots>(75),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -3347,6 +3285,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -187,7 +187,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 17,
|
pc: 17,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
|
@ -226,7 +225,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -447,7 +445,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xa,
|
state: 0xa,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -457,7 +454,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -467,7 +463,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -477,7 +472,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(3),
|
index: StatePartIndex<BigSlots>(3),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf,
|
state: 0xf,
|
||||||
last_state: 0xe,
|
last_state: 0xe,
|
||||||
},
|
},
|
||||||
|
|
@ -487,7 +481,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(8),
|
index: StatePartIndex<BigSlots>(8),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xa,
|
state: 0xa,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -497,7 +490,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(9),
|
index: StatePartIndex<BigSlots>(9),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -507,7 +499,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(10),
|
index: StatePartIndex<BigSlots>(10),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -517,7 +508,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(11),
|
index: StatePartIndex<BigSlots>(11),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf,
|
state: 0xf,
|
||||||
last_state: 0xe,
|
last_state: 0xe,
|
||||||
},
|
},
|
||||||
|
|
@ -527,7 +517,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(4),
|
index: StatePartIndex<BigSlots>(4),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xa,
|
state: 0xa,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -537,7 +526,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(5),
|
index: StatePartIndex<BigSlots>(5),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x3,
|
last_state: 0x3,
|
||||||
},
|
},
|
||||||
|
|
@ -547,7 +535,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(6),
|
index: StatePartIndex<BigSlots>(6),
|
||||||
ty: SInt<2>,
|
ty: SInt<2>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x2,
|
state: 0x2,
|
||||||
last_state: 0x2,
|
last_state: 0x2,
|
||||||
},
|
},
|
||||||
|
|
@ -557,7 +544,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(7),
|
index: StatePartIndex<BigSlots>(7),
|
||||||
ty: UInt<4>,
|
ty: UInt<4>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0xf,
|
state: 0xf,
|
||||||
last_state: 0xe,
|
last_state: 0xe,
|
||||||
},
|
},
|
||||||
|
|
@ -579,6 +565,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
@ -1,34 +1,47 @@
|
||||||
$timescale 1 ps $end
|
$timescale 1 ps $end
|
||||||
$scope module mod1 $end
|
$scope module mod1 $end
|
||||||
$scope struct o $end
|
$scope struct o $end
|
||||||
$var wire 4 avK(^ i $end
|
$var wire 4 ! i $end
|
||||||
$var wire 2 Q2~aG o $end
|
$var wire 2 " o $end
|
||||||
$var wire 2 DXK'| i2 $end
|
$var wire 2 # i2 $end
|
||||||
$var wire 4 cPuix o2 $end
|
$var wire 4 $ o2 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope module child $end
|
$scope struct child $end
|
||||||
$var wire 4 ($5K7 i $end
|
$var wire 4 ) i $end
|
||||||
$var wire 2 %6Wv" o $end
|
$var wire 2 * o $end
|
||||||
$var wire 2 +|-AU i2 $end
|
$var wire 2 + i2 $end
|
||||||
$var wire 4 Hw?%j o2 $end
|
$var wire 4 , o2 $end
|
||||||
|
$upscope $end
|
||||||
|
$scope module mod1_child $end
|
||||||
|
$var wire 4 % i $end
|
||||||
|
$var wire 2 & o $end
|
||||||
|
$var wire 2 ' i2 $end
|
||||||
|
$var wire 4 ( o2 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
$dumpvars
|
$dumpvars
|
||||||
b11 avK(^
|
b11 !
|
||||||
b11 Q2~aG
|
b11 "
|
||||||
b10 DXK'|
|
b10 #
|
||||||
b1110 cPuix
|
b1110 $
|
||||||
b11 ($5K7
|
b11 %
|
||||||
b11 %6Wv"
|
b11 &
|
||||||
b10 +|-AU
|
b10 '
|
||||||
b1110 Hw?%j
|
b1110 (
|
||||||
|
b11 )
|
||||||
|
b11 *
|
||||||
|
b10 +
|
||||||
|
b1110 ,
|
||||||
$end
|
$end
|
||||||
#1000000
|
#1000000
|
||||||
b1010 avK(^
|
b1010 !
|
||||||
b10 Q2~aG
|
b10 "
|
||||||
b1111 cPuix
|
b1111 $
|
||||||
b1010 ($5K7
|
b1010 %
|
||||||
b10 %6Wv"
|
b10 &
|
||||||
b1111 Hw?%j
|
b1111 (
|
||||||
|
b1010 )
|
||||||
|
b10 *
|
||||||
|
b1111 ,
|
||||||
#2000000
|
#2000000
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,6 @@ Simulation {
|
||||||
},
|
},
|
||||||
pc: 16,
|
pc: 16,
|
||||||
memory_write_log: [],
|
memory_write_log: [],
|
||||||
assert_failed_log: [],
|
|
||||||
memories: StatePart {
|
memories: StatePart {
|
||||||
value: [
|
value: [
|
||||||
MemoryData {
|
MemoryData {
|
||||||
|
|
@ -216,7 +215,6 @@ Simulation {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
global_io: {},
|
|
||||||
main_module: SimulationModuleState {
|
main_module: SimulationModuleState {
|
||||||
base_targets: [
|
base_targets: [
|
||||||
Instance {
|
Instance {
|
||||||
|
|
@ -375,7 +373,6 @@ Simulation {
|
||||||
["a","b"],
|
["a","b"],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: PhantomConst,
|
state: PhantomConst,
|
||||||
last_state: PhantomConst,
|
last_state: PhantomConst,
|
||||||
},
|
},
|
||||||
|
|
@ -386,7 +383,6 @@ Simulation {
|
||||||
["a","b"],
|
["a","b"],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: PhantomConst,
|
state: PhantomConst,
|
||||||
last_state: PhantomConst,
|
last_state: PhantomConst,
|
||||||
},
|
},
|
||||||
|
|
@ -396,7 +392,6 @@ Simulation {
|
||||||
index: StatePartIndex<BigSlots>(0),
|
index: StatePartIndex<BigSlots>(0),
|
||||||
ty: UInt<0>,
|
ty: UInt<0>,
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -405,7 +400,6 @@ Simulation {
|
||||||
kind: BigBool {
|
kind: BigBool {
|
||||||
index: StatePartIndex<BigSlots>(1),
|
index: StatePartIndex<BigSlots>(1),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -414,7 +408,6 @@ Simulation {
|
||||||
kind: BigClock {
|
kind: BigClock {
|
||||||
index: StatePartIndex<BigSlots>(2),
|
index: StatePartIndex<BigSlots>(2),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: 0x0,
|
state: 0x0,
|
||||||
last_state: 0x0,
|
last_state: 0x0,
|
||||||
},
|
},
|
||||||
|
|
@ -425,7 +418,6 @@ Simulation {
|
||||||
"mem_element",
|
"mem_element",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
maybe_changed: true,
|
|
||||||
state: PhantomConst,
|
state: PhantomConst,
|
||||||
last_state: PhantomConst,
|
last_state: PhantomConst,
|
||||||
},
|
},
|
||||||
|
|
@ -529,6 +521,5 @@ Simulation {
|
||||||
}),
|
}),
|
||||||
waiting_sensitivity_sets_by_address: {},
|
waiting_sensitivity_sets_by_address: {},
|
||||||
waiting_sensitivity_sets_by_compiled_value: {},
|
waiting_sensitivity_sets_by_compiled_value: {},
|
||||||
asserts: [],
|
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue