1
0
Fork 0

firrtl: don't generate as many duplicate wires when compiling expressions

This commit is contained in:
Jacob Lifshay 2026-06-01 20:53:22 -07:00
parent 1880ed682f
commit 6902aea3a6
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
2 changed files with 652 additions and 601 deletions

View file

@ -2,17 +2,12 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
use crate::{ use crate::{
annotations::{ annotations::{Annotation, TargetedAnnotation},
Annotation, BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation,
DocStringAnnotation, DontTouchAnnotation, SVAttributeAnnotation, TargetedAnnotation,
},
array::Array,
build::{ToArgs, WriteArgs}, build::{ToArgs, WriteArgs},
bundle::{Bundle, BundleField, BundleType}, bundle::{BundleField, BundleType},
clock::Clock, enum_::{EnumType, EnumVariant},
enum_::{Enum, EnumType, EnumVariant},
expr::{ expr::{
CastBitsTo, Expr, ExprEnum, ToExpr, ValueType, ExprEnum,
ops::{self, VariantAccess}, ops::{self, VariantAccess},
target::{ target::{
Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement,
@ -20,29 +15,28 @@ use crate::{
}, },
}, },
formal::FormalKind, formal::FormalKind,
int::{Bool, DynSize, IntType, SIntValue, UInt, UIntValue}, int::IntType,
intern::{Intern, Interned}, intern::{Intern, Interned},
memory::{Mem, PortKind, PortName, ReadUnderWrite}, memory::{PortKind, PortName},
module::{ module::{
AnnotatedModuleIO, Block, ExternModuleBody, ExternModuleParameter, AnnotatedModuleIO, Block, ExternModuleBody, ExternModuleParameter,
ExternModuleParameterValue, Module, ModuleBody, ModuleIO, NameId, NameOptId, ExternModuleParameterValue, ModuleBody, ModuleIO, NameId, NameOptId, NormalModuleBody,
NormalModuleBody, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg,
StmtMatch, StmtReg, StmtWire, StmtWire,
transform::{ transform::{
simplify_enums::{SimplifyEnumsError, SimplifyEnumsKind, simplify_enums}, simplify_enums::{SimplifyEnumsError, SimplifyEnumsKind, simplify_enums},
simplify_memories::simplify_memories, simplify_memories::simplify_memories,
}, },
}, },
reset::{AsyncReset, Reset, ResetType, SyncReset}, prelude::*,
source_location::SourceLocation, reset::ResetType,
ty::{CanonicalType, OpaqueSimValueSize, Type}, ty::OpaqueSimValueSize,
util::{ util::{
BitSliceWriteWithBase, DebugAsRawString, GenericConstBool, HashMap, HashSet, BitSliceWriteWithBase, DebugAsRawString, GenericConstBool, HashMap, HashSet,
const_str_array_is_strictly_ascending, const_str_array_is_strictly_ascending,
}, },
vendor::xilinx::XilinxAnnotation, vendor::xilinx::XilinxAnnotation,
}; };
use bitvec::slice::BitSlice;
use clap::value_parser; use clap::value_parser;
use num_traits::Signed; use num_traits::Signed;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -378,6 +372,107 @@ impl<K, V> DefinitionsMap<K, V> {
} }
} }
#[derive(Default)]
struct BlockDefinitionsCache {
array_literal_exprs:
RefCell<HashMap<(ops::ArrayLiteral<CanonicalType, DynSize>, bool), String>>,
bundle_literal_exprs: RefCell<HashMap<(ops::BundleLiteral, bool), String>>,
uninit_exprs: RefCell<HashMap<(ops::Uninit, bool), String>>,
cast_bundle_to_bits_exprs: RefCell<HashMap<(String, Bundle), String>>,
cast_enum_to_bits_exprs: RefCell<HashMap<(String, Enum), String>>,
cast_array_to_bits_exprs: RefCell<HashMap<(String, Array), String>>,
cast_bits_to_bundle_exprs: RefCell<HashMap<(String, Bundle), String>>,
cast_bits_to_enum_exprs: RefCell<HashMap<(String, Enum), String>>,
cast_bits_to_array_exprs: RefCell<HashMap<(String, Array), String>>,
cast_bits_to_phantom_const_exprs: RefCell<HashMap<(String, PhantomConst), String>>,
}
struct BlockDefinitionsState<'a> {
rc_definitions: RcDefinitions,
parent: &'a BlockDefinitions<'a>,
cache: BlockDefinitionsCache,
}
struct BlockDefinitions<'a> {
state: Option<BlockDefinitionsState<'a>>,
}
impl<'a> BlockDefinitions<'a> {
fn new(parent: &'a BlockDefinitions<'a>) -> Self {
Self {
state: Some(BlockDefinitionsState {
rc_definitions: RcDefinitions::default(),
parent,
cache: Default::default(),
}),
}
}
fn none() -> Self {
Self { state: None }
}
fn get_or_write_definition<K: Hash + Eq>(
&mut self,
key: K,
field: impl Fn(&BlockDefinitionsCache) -> &RefCell<HashMap<K, String>>,
write_definition: impl FnOnce(BlockDefinitionsWriter<'_, '_>, &K) -> Result<String>,
) -> Result<String> {
let state = self.state.as_ref().expect("should be some");
let mut cur_state = state;
loop {
let field = field(&cur_state.cache).borrow();
if let Some(retval) = field.get(&key) {
return Ok(retval.clone());
}
let Some(parent_state) = &cur_state.parent.state else {
break;
};
cur_state = parent_state;
}
let retval = write_definition(BlockDefinitionsWriter { definitions: self }, &key)?;
Ok(field(&self.state.as_ref().expect("should be some").cache)
.borrow_mut()
.entry(key)
.or_insert(retval)
.clone())
}
fn write_out(&mut self, indent: Indent<'_>, out: &mut String) {
self.state
.as_ref()
.expect("should be some")
.rc_definitions
.write_and_clear(indent, out);
}
}
struct BlockDefinitionsWriter<'a, 'b> {
definitions: &'b mut BlockDefinitions<'a>,
}
impl BlockDefinitionsWriter<'_, '_> {
fn add_definition_line(&mut self, v: impl fmt::Display) {
self.definitions
.state
.as_ref()
.expect("should be some")
.rc_definitions
.add_definition_line(v);
}
}
impl<'a> std::ops::Deref for BlockDefinitionsWriter<'a, '_> {
type Target = BlockDefinitions<'a>;
fn deref(&self) -> &Self::Target {
&self.definitions
}
}
impl std::ops::DerefMut for BlockDefinitionsWriter<'_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.definitions
}
}
struct EnumDef { struct EnumDef {
variants: RefCell<Namespace>, variants: RefCell<Namespace>,
body: String, body: String,
@ -498,16 +593,13 @@ impl TypeState {
struct ModuleState { struct ModuleState {
ns: Namespace, ns: Namespace,
definitions: RcDefinitions,
match_arm_values: HashMap<VariantAccess<CanonicalType>, Ident>, match_arm_values: HashMap<VariantAccess<CanonicalType>, Ident>,
} }
impl Default for ModuleState { impl Default for ModuleState {
fn default() -> Self { fn default() -> Self {
let definitions = RcDefinitions::default();
Self { Self {
ns: Default::default(), ns: Default::default(),
definitions,
match_arm_values: Default::default(), match_arm_values: Default::default(),
} }
} }
@ -876,7 +968,7 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
value: Expr<FromTy>, value: Expr<FromTy>,
to_ty: ToTy, to_ty: ToTy,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
let from_ty = value.ty(); let from_ty = value.ty();
@ -911,7 +1003,7 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
firrtl_cast_fn: Option<&str>, firrtl_cast_fn: Option<&str>,
value: Expr<FromTy>, value: Expr<FromTy>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
let value = self.expr(Expr::canonical(value), definitions, const_ty)?; let value = self.expr(Expr::canonical(value), definitions, const_ty)?;
@ -925,7 +1017,7 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
base: Expr<T>, base: Expr<T>,
range: Range<usize>, range: Range<usize>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
let base_width = base.ty().width(); let base_width = base.ty().width();
@ -943,28 +1035,40 @@ impl<'a> Exporter<'a> {
fn array_literal_expr( fn array_literal_expr(
&mut self, &mut self,
expr: ops::ArrayLiteral<CanonicalType, DynSize>, expr: ops::ArrayLiteral<CanonicalType, DynSize>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(expr, const_ty),
|c| &c.array_literal_exprs,
|mut definitions, &(expr, const_ty)| {
let ident = self.module.ns.make_new("_array_literal_expr"); let ident = self.module.ns.make_new("_array_literal_expr");
let ty_str = self.type_state.ty(expr.ty())?; let ty_str = self.type_state.ty(expr.ty())?;
let const_ = if const_ty { "const " } else { "" }; let const_ = if const_ty { "const " } else { "" };
definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_str}")); definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_str}"));
for (index, element) in expr.element_values().into_iter().enumerate() { for (index, element) in expr.element_values().into_iter().enumerate() {
let element = self.expr(Expr::canonical(element), definitions, const_ty)?; let element =
definitions.add_definition_line(format_args!("connect {ident}[{index}], {element}")); self.expr(Expr::canonical(element), &mut definitions, const_ty)?;
definitions
.add_definition_line(format_args!("connect {ident}[{index}], {element}"));
} }
if expr.element_values().is_empty() { if expr.element_values().is_empty() {
definitions.add_definition_line(format_args!("invalidate {ident}")); definitions.add_definition_line(format_args!("invalidate {ident}"));
} }
Ok(ident.to_string()) Ok(ident.to_string())
},
)
} }
fn bundle_literal_expr( fn bundle_literal_expr(
&mut self, &mut self,
expr: ops::BundleLiteral<Bundle>, expr: ops::BundleLiteral<Bundle>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(expr, const_ty),
|c| &c.bundle_literal_exprs,
|mut definitions, &(expr, const_ty)| {
let ident = self.module.ns.make_new("_bundle_literal_expr"); let ident = self.module.ns.make_new("_bundle_literal_expr");
let ty = expr.ty(); let ty = expr.ty();
let (ty_ident, bundle_ns) = self.type_state.bundle_def(ty)?; let (ty_ident, bundle_ns) = self.type_state.bundle_def(ty)?;
@ -981,23 +1085,32 @@ impl<'a> Exporter<'a> {
{ {
debug_assert!( debug_assert!(
!flipped, !flipped,
"can't have bundle literal with flipped field -- this should have been caught in BundleLiteral::new_unchecked" "can't have bundle literal with flipped field -- \
this should have been caught in BundleLiteral::new_unchecked"
); );
let name = bundle_ns.borrow_mut().get(name); let name = bundle_ns.borrow_mut().get(name);
let field_value = self.expr(Expr::canonical(field_value), definitions, const_ty)?; let field_value =
definitions.add_definition_line(format_args!("connect {ident}.{name}, {field_value}")); self.expr(Expr::canonical(field_value), &mut definitions, const_ty)?;
definitions
.add_definition_line(format_args!("connect {ident}.{name}, {field_value}"));
} }
if ty.fields().is_empty() { if ty.fields().is_empty() {
definitions.add_definition_line(format_args!("invalidate {ident}")); definitions.add_definition_line(format_args!("invalidate {ident}"));
} }
Ok(ident.to_string()) Ok(ident.to_string())
},
)
} }
fn uninit_expr( fn uninit_expr(
&mut self, &mut self,
expr: ops::Uninit, expr: ops::Uninit,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(expr, const_ty),
|c| &c.uninit_exprs,
|mut definitions, &(expr, const_ty)| {
let ident = self.module.ns.make_new("_uninit_expr"); let ident = self.module.ns.make_new("_uninit_expr");
let ty = expr.ty(); let ty = expr.ty();
let ty_ident = self.type_state.ty(ty)?; let ty_ident = self.type_state.ty(ty)?;
@ -1005,11 +1118,13 @@ impl<'a> Exporter<'a> {
definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}")); definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}"));
definitions.add_definition_line(format_args!("invalidate {ident}")); definitions.add_definition_line(format_args!("invalidate {ident}"));
Ok(ident.to_string()) Ok(ident.to_string())
},
)
} }
fn enum_literal_expr( fn enum_literal_expr(
&mut self, &mut self,
expr: ops::EnumLiteral<Enum>, expr: ops::EnumLiteral<Enum>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
let variant_expr = expr let variant_expr = expr
@ -1022,9 +1137,13 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
value_str: String, value_str: String,
ty: Bundle, ty: Bundle,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_bundle_to_bits_exprs,
|mut definitions, &(ref value_str, ty)| {
if ty.fields().is_empty() { if ty.fields().is_empty() {
return Ok("UInt<0>(0)".into()); return Ok("UInt<0>(0)".into());
} }
@ -1033,7 +1152,7 @@ impl<'a> Exporter<'a> {
return self.expr_cast_to_bits( return self.expr_cast_to_bits(
format!("{value_str}.{field_ident}"), format!("{value_str}.{field_ident}"),
field.ty, field.ty,
definitions, &mut definitions,
extra_indent, extra_indent,
); );
} }
@ -1062,7 +1181,7 @@ impl<'a> Exporter<'a> {
let field_bits = self.expr_cast_to_bits( let field_bits = self.expr_cast_to_bits(
format!("{value_str}.{field_ident}"), format!("{value_str}.{field_ident}"),
field.ty, field.ty,
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
@ -1080,16 +1199,24 @@ impl<'a> Exporter<'a> {
ty.type_properties().bit_width ty.type_properties().bit_width
)); ));
let cat_expr = cat_expr.expect("bundle already checked to have fields"); let cat_expr = cat_expr.expect("bundle already checked to have fields");
definitions.add_definition_line(format_args!("{extra_indent}connect {retval}, {cat_expr}")); definitions.add_definition_line(format_args!(
"{extra_indent}connect {retval}, {cat_expr}"
));
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_enum_to_bits( fn expr_cast_enum_to_bits(
&mut self, &mut self,
value_str: String, value_str: String,
ty: Enum, ty: Enum,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_enum_to_bits_exprs,
|mut definitions, &(ref value_str, ty)| {
if ty.variants().is_empty() { if ty.variants().is_empty() {
return Ok("UInt<0>(0)".into()); return Ok("UInt<0>(0)".into());
} }
@ -1114,11 +1241,12 @@ impl<'a> Exporter<'a> {
let variant_bits = self.expr_cast_to_bits( let variant_bits = self.expr_cast_to_bits(
variant_value.to_string(), variant_value.to_string(),
variant_ty, variant_ty,
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
"{extra_indent}connect {retval}, pad(cat({variant_bits}, UInt<{}>({variant_index})), {})", "{extra_indent}connect {retval}, \
pad(cat({variant_bits}, UInt<{}>({variant_index})), {})",
ty.discriminant_bit_width(), ty.discriminant_bit_width(),
ty.type_properties().bit_width, ty.type_properties().bit_width,
)); ));
@ -1135,22 +1263,28 @@ impl<'a> Exporter<'a> {
} }
} }
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_array_to_bits( fn expr_cast_array_to_bits(
&mut self, &mut self,
value_str: String, value_str: String,
ty: Array, ty: Array,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_array_to_bits_exprs,
|mut definitions, &(ref value_str, ty)| {
if ty.is_empty() { if ty.is_empty() {
return Ok("UInt<0>(0)".into()); return Ok("UInt<0>(0)".into());
} }
if ty.len() == 1 { if ty.len() == 1 {
return self.expr_cast_to_bits( return self.expr_cast_to_bits(
value_str + "[0]", value_str.clone() + "[0]",
ty.element(), ty.element(),
definitions, &mut definitions,
extra_indent, extra_indent,
); );
} }
@ -1165,7 +1299,7 @@ impl<'a> Exporter<'a> {
let element_bits = self.expr_cast_to_bits( let element_bits = self.expr_cast_to_bits(
format!("{value_str}[{index}]"), format!("{value_str}[{index}]"),
ty.element(), ty.element(),
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
@ -1183,14 +1317,18 @@ impl<'a> Exporter<'a> {
ty.type_properties().bit_width ty.type_properties().bit_width
)); ));
let cat_expr = cat_expr.expect("array already checked to have elements"); let cat_expr = cat_expr.expect("array already checked to have elements");
definitions.add_definition_line(format_args!("{extra_indent}connect {retval}, {cat_expr}")); definitions.add_definition_line(format_args!(
"{extra_indent}connect {retval}, {cat_expr}"
));
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_to_bits( fn expr_cast_to_bits(
&mut self, &mut self,
value_str: String, value_str: String,
ty: CanonicalType, ty: CanonicalType,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
match ty.unwrap_transparent_types() { match ty.unwrap_transparent_types() {
@ -1219,14 +1357,20 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
value_str: String, value_str: String,
ty: Bundle, ty: Bundle,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_bits_to_bundle_exprs,
|mut definitions, &(ref value_str, ty)| {
let (ty_ident, _) = self.type_state.bundle_def(ty)?; let (ty_ident, _) = self.type_state.bundle_def(ty)?;
let retval = self.module.ns.make_new("_cast_bits_to_bundle_expr"); let retval = self.module.ns.make_new("_cast_bits_to_bundle_expr");
definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); definitions
.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}"));
if ty.fields().is_empty() { if ty.fields().is_empty() {
definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); definitions
.add_definition_line(format_args!("{extra_indent}invalidate {retval}"));
return Ok(retval.to_string()); return Ok(retval.to_string());
} }
let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map( let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map(
@ -1260,9 +1404,12 @@ impl<'a> Exporter<'a> {
.type_state .type_state
.get_bundle_field(flattened_bundle_ty, field.name)?; .get_bundle_field(flattened_bundle_ty, field.name)?;
let field_ident = self.type_state.get_bundle_field(ty, field.name)?; let field_ident = self.type_state.get_bundle_field(ty, field.name)?;
if let Some(field_bit_width_minus_one) = field.ty.bit_width().checked_sub(1usize) { if let Some(field_bit_width_minus_one) =
field.ty.bit_width().checked_sub(1usize)
{
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
"{extra_indent}connect {flattened_ident}.{flattened_field_ident}, bits({value_str}, {}, {field_offset})", "{extra_indent}connect {flattened_ident}.{flattened_field_ident}, \
bits({value_str}, {}, {field_offset})",
field_offset + field_bit_width_minus_one field_offset + field_bit_width_minus_one
)); ));
} else { } else {
@ -1273,7 +1420,7 @@ impl<'a> Exporter<'a> {
let field_value = self.expr_cast_bits_to( let field_value = self.expr_cast_bits_to(
format!("{flattened_ident}.{flattened_field_ident}"), format!("{flattened_ident}.{flattened_field_ident}"),
field.ty, field.ty,
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
@ -1281,26 +1428,38 @@ impl<'a> Exporter<'a> {
)); ));
} }
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_bits_to_enum( fn expr_cast_bits_to_enum(
&mut self, &mut self,
value_str: String, value_str: String,
ty: Enum, ty: Enum,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_bits_to_enum_exprs,
|mut definitions, &(ref value_str, ty)| {
let (ty_ident, enum_def) = self.type_state.enum_def(ty)?; let (ty_ident, enum_def) = self.type_state.enum_def(ty)?;
let retval = self.module.ns.make_new("_cast_bits_to_enum_expr"); let retval = self.module.ns.make_new("_cast_bits_to_enum_expr");
definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); definitions
.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}"));
if ty.variants().is_empty() { if ty.variants().is_empty() {
definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); definitions
.add_definition_line(format_args!("{extra_indent}invalidate {retval}"));
return Ok(retval.to_string()); return Ok(retval.to_string());
} }
if let [variant] = *ty.variants() { if let [variant] = *ty.variants() {
let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?;
if let Some(variant_ty) = variant.ty { if let Some(variant_ty) = variant.ty {
let variant_value = let variant_value = self.expr_cast_bits_to(
self.expr_cast_bits_to(value_str, variant_ty, definitions, extra_indent)?; value_str.clone(),
variant_ty,
&mut definitions,
extra_indent,
)?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
"{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})", "{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})",
enum_def.body enum_def.body
@ -1329,15 +1488,18 @@ impl<'a> Exporter<'a> {
}; };
for (variant_index, variant) in ty.variants().into_iter().enumerate() { for (variant_index, variant) in ty.variants().into_iter().enumerate() {
let when_cond = format!( let when_cond = format!(
"eq(UInt<{discriminant_bit_width}>({variant_index}), tail({value_str}, {body_bit_width}))" "eq(UInt<{discriminant_bit_width}>({variant_index}), \
tail({value_str}, {body_bit_width}))"
); );
if variant_index == ty.variants().len() - 1 { if variant_index == ty.variants().len() - 1 {
definitions.add_definition_line(format_args!("{extra_indent}else:")); definitions.add_definition_line(format_args!("{extra_indent}else:"));
} else if variant_index == 0 { } else if variant_index == 0 {
definitions.add_definition_line(format_args!("{extra_indent}when {when_cond}:"));
} else {
definitions definitions
.add_definition_line(format_args!("{extra_indent}else when {when_cond}:")); .add_definition_line(format_args!("{extra_indent}when {when_cond}:"));
} else {
definitions.add_definition_line(format_args!(
"{extra_indent}else when {when_cond}:"
));
} }
let when_pushed_indent = extra_indent.push(); let when_pushed_indent = extra_indent.push();
let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?;
@ -1345,7 +1507,7 @@ impl<'a> Exporter<'a> {
let variant_value = self.expr_cast_bits_to( let variant_value = self.expr_cast_bits_to(
body_value.clone(), body_value.clone(),
variant_ty, variant_ty,
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
@ -1361,20 +1523,28 @@ impl<'a> Exporter<'a> {
drop(when_pushed_indent); drop(when_pushed_indent);
} }
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_bits_to_array( fn expr_cast_bits_to_array(
&mut self, &mut self,
value_str: String, value_str: String,
ty: Array, ty: Array,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_bits_to_array_exprs,
|mut definitions, &(ref value_str, ty)| {
let retval = self.module.ns.make_new("_cast_bits_to_array_expr"); let retval = self.module.ns.make_new("_cast_bits_to_array_expr");
let array_ty = self.type_state.ty(ty)?; let array_ty = self.type_state.ty(ty)?;
definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {array_ty}")); definitions
.add_definition_line(format_args!("{extra_indent}wire {retval}: {array_ty}"));
let element_bit_width = ty.element().bit_width(); let element_bit_width = ty.element().bit_width();
if ty.is_empty() || element_bit_width == 0 { if ty.is_empty() || element_bit_width == 0 {
definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); definitions
.add_definition_line(format_args!("{extra_indent}invalidate {retval}"));
return Ok(retval.to_string()); return Ok(retval.to_string());
} }
let flattened_ident = self let flattened_ident = self
@ -1387,14 +1557,15 @@ impl<'a> Exporter<'a> {
)); ));
for index in 0..ty.len() { for index in 0..ty.len() {
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
"{extra_indent}connect {flattened_ident}[{index}], bits({value_str}, {}, {})", "{extra_indent}connect {flattened_ident}[{index}], \
bits({value_str}, {}, {})",
element_bit_width * index + element_bit_width - 1, element_bit_width * index + element_bit_width - 1,
element_bit_width * index, element_bit_width * index,
)); ));
let element_value = self.expr_cast_bits_to( let element_value = self.expr_cast_bits_to(
format!("{flattened_ident}[{index}]"), format!("{flattened_ident}[{index}]"),
ty.element(), ty.element(),
definitions, &mut definitions,
extra_indent, extra_indent,
)?; )?;
definitions.add_definition_line(format_args!( definitions.add_definition_line(format_args!(
@ -1402,12 +1573,14 @@ impl<'a> Exporter<'a> {
)); ));
} }
Ok(retval.to_string()) Ok(retval.to_string())
},
)
} }
fn expr_cast_bits_to( fn expr_cast_bits_to(
&mut self, &mut self,
value_str: String, value_str: String,
ty: CanonicalType, ty: CanonicalType,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
extra_indent: Indent<'_>, extra_indent: Indent<'_>,
) -> Result<String> { ) -> Result<String> {
match ty.unwrap_transparent_types() { match ty.unwrap_transparent_types() {
@ -1427,12 +1600,18 @@ impl<'a> Exporter<'a> {
CanonicalType::AsyncReset(_) => Ok(format!("asAsyncReset({value_str})")), CanonicalType::AsyncReset(_) => Ok(format!("asAsyncReset({value_str})")),
CanonicalType::SyncReset(_) => Ok(value_str), CanonicalType::SyncReset(_) => Ok(value_str),
CanonicalType::Reset(_) => unreachable!("Reset is not bit castable to"), CanonicalType::Reset(_) => unreachable!("Reset is not bit castable to"),
CanonicalType::PhantomConst(_) => { CanonicalType::PhantomConst(ty) => definitions.get_or_write_definition(
(value_str, ty),
|c| &c.cast_bits_to_phantom_const_exprs,
|mut definitions, &(ref _value_str, _ty)| {
let retval = self.module.ns.make_new("_cast_bits_to_phantom_const_expr"); let retval = self.module.ns.make_new("_cast_bits_to_phantom_const_expr");
definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {{}}")); definitions
definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); .add_definition_line(format_args!("{extra_indent}wire {retval}: {{}}"));
return Ok(retval.to_string()); definitions
} .add_definition_line(format_args!("{extra_indent}invalidate {retval}"));
Ok(retval.to_string())
},
),
CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()),
CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"),
} }
@ -1441,7 +1620,7 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
func: &str, func: &str,
arg: Expr<T>, arg: Expr<T>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
Ok(format!( Ok(format!(
@ -1454,7 +1633,7 @@ impl<'a> Exporter<'a> {
func: &str, func: &str,
lhs: Expr<Lhs>, lhs: Expr<Lhs>,
rhs: Expr<Rhs>, rhs: Expr<Rhs>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
Ok(format!( Ok(format!(
@ -1466,7 +1645,7 @@ impl<'a> Exporter<'a> {
fn expr( fn expr(
&mut self, &mut self,
expr: Expr<CanonicalType>, expr: Expr<CanonicalType>,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
const_ty: bool, const_ty: bool,
) -> Result<String> { ) -> Result<String> {
match *Expr::expr_enum(expr) { match *Expr::expr_enum(expr) {
@ -2062,7 +2241,7 @@ impl<'a> Exporter<'a> {
&mut self, &mut self,
stmt_reg: StmtReg<R>, stmt_reg: StmtReg<R>,
module_name: Ident, module_name: Ident,
definitions: &RcDefinitions, definitions: &mut BlockDefinitions<'_>,
body: &mut String, body: &mut String,
) -> Result<()> { ) -> Result<()> {
let StmtReg { annotations, reg } = stmt_reg; let StmtReg { annotations, reg } = stmt_reg;
@ -2095,10 +2274,10 @@ impl<'a> Exporter<'a> {
module: Interned<Module<Bundle>>, module: Interned<Module<Bundle>>,
block: Block, block: Block,
_block_indent: &PushIndent<'_>, _block_indent: &PushIndent<'_>,
definitions: Option<RcDefinitions>, parent_definitions: &BlockDefinitions,
) -> Result<String> { ) -> Result<String> {
let indent = self.indent; let indent = self.indent;
let definitions = definitions.unwrap_or_default(); let mut definitions = BlockDefinitions::new(parent_definitions);
let mut body = String::new(); let mut body = String::new();
let mut out = String::new(); let mut out = String::new();
let Block { memories, stmts } = block; let Block { memories, stmts } = block;
@ -2122,8 +2301,8 @@ impl<'a> Exporter<'a> {
) )
.unwrap(); .unwrap();
} }
let lhs = self.expr(lhs, &definitions, false)?; let lhs = self.expr(lhs, &mut definitions, false)?;
let rhs = self.expr(rhs, &definitions, false)?; let rhs = self.expr(rhs, &mut definitions, false)?;
writeln!( writeln!(
body, body,
"{indent}connect {lhs}, {rhs}{}", "{indent}connect {lhs}, {rhs}{}",
@ -2139,9 +2318,9 @@ impl<'a> Exporter<'a> {
text, text,
source_location, source_location,
}) => { }) => {
let clk = self.expr(Expr::canonical(clk), &definitions, false)?; let clk = self.expr(Expr::canonical(clk), &mut definitions, false)?;
let pred = self.expr(Expr::canonical(pred), &definitions, false)?; let pred = self.expr(Expr::canonical(pred), &mut definitions, false)?;
let en = self.expr(Expr::canonical(en), &definitions, false)?; let en = self.expr(Expr::canonical(en), &mut definitions, false)?;
let kind = match kind { let kind = match kind {
FormalKind::Assert => "assert", FormalKind::Assert => "assert",
FormalKind::Assume => "assume", FormalKind::Assume => "assume",
@ -2166,7 +2345,7 @@ impl<'a> Exporter<'a> {
let mut when = "when"; let mut when = "when";
let mut pushed_indent; let mut pushed_indent;
loop { loop {
let cond_str = self.expr(Expr::canonical(cond), &definitions, false)?; let cond_str = self.expr(Expr::canonical(cond), &mut definitions, false)?;
writeln!( writeln!(
body, body,
"{indent}{when} {cond_str}:{}", "{indent}{when} {cond_str}:{}",
@ -2175,7 +2354,7 @@ impl<'a> Exporter<'a> {
.unwrap(); .unwrap();
pushed_indent = indent.push(); pushed_indent = indent.push();
let then_block_str = let then_block_str =
self.block(module, then_block, &pushed_indent, None)?; self.block(module, then_block, &pushed_indent, &definitions)?;
if !then_block_str.is_empty() { if !then_block_str.is_empty() {
body.push_str(&then_block_str); body.push_str(&then_block_str);
} else { } else {
@ -2193,7 +2372,8 @@ impl<'a> Exporter<'a> {
break; break;
} }
} }
let else_block = self.block(module, else_block, &pushed_indent, None)?; let else_block =
self.block(module, else_block, &pushed_indent, &definitions)?;
drop(pushed_indent); drop(pushed_indent);
if !else_block.is_empty() { if !else_block.is_empty() {
writeln!(body, "{indent}else:").unwrap(); writeln!(body, "{indent}else:").unwrap();
@ -2208,7 +2388,7 @@ impl<'a> Exporter<'a> {
writeln!( writeln!(
body, body,
"{indent}match {}:{}", "{indent}match {}:{}",
self.expr(Expr::canonical(expr), &definitions, false)?, self.expr(Expr::canonical(expr), &mut definitions, false)?,
FileInfo::new(source_location), FileInfo::new(source_location),
) )
.unwrap(); .unwrap();
@ -2236,7 +2416,8 @@ impl<'a> Exporter<'a> {
}; };
body.push_str(":\n"); body.push_str(":\n");
let match_arm_indent = indent.push(); let match_arm_indent = indent.push();
let block = self.block(module, match_arm_block, &match_arm_indent, None)?; let block =
self.block(module, match_arm_block, &match_arm_indent, &definitions)?;
if !block.is_empty() { if !block.is_empty() {
body.push_str(&block); body.push_str(&block);
} else { } else {
@ -2261,13 +2442,13 @@ impl<'a> Exporter<'a> {
.unwrap(); .unwrap();
} }
Stmt::Declaration(StmtDeclaration::Reg(stmt_reg)) => { Stmt::Declaration(StmtDeclaration::Reg(stmt_reg)) => {
self.stmt_reg(stmt_reg, module_name, &definitions, &mut body)?; self.stmt_reg(stmt_reg, module_name, &mut definitions, &mut body)?;
} }
Stmt::Declaration(StmtDeclaration::RegSync(stmt_reg)) => { Stmt::Declaration(StmtDeclaration::RegSync(stmt_reg)) => {
self.stmt_reg(stmt_reg, module_name, &definitions, &mut body)?; self.stmt_reg(stmt_reg, module_name, &mut definitions, &mut body)?;
} }
Stmt::Declaration(StmtDeclaration::RegAsync(stmt_reg)) => { Stmt::Declaration(StmtDeclaration::RegAsync(stmt_reg)) => {
self.stmt_reg(stmt_reg, module_name, &definitions, &mut body)?; self.stmt_reg(stmt_reg, module_name, &mut definitions, &mut body)?;
} }
Stmt::Declaration(StmtDeclaration::Instance(StmtInstance { Stmt::Declaration(StmtDeclaration::Instance(StmtInstance {
annotations, annotations,
@ -2286,7 +2467,7 @@ impl<'a> Exporter<'a> {
.unwrap(); .unwrap();
} }
} }
definitions.write_and_clear(indent, &mut out); definitions.write_out(indent, &mut out);
out.push_str(&body); out.push_str(&body);
body.clear(); body.clear();
} }
@ -2366,7 +2547,7 @@ impl<'a> Exporter<'a> {
module, module,
top_block, top_block,
&module_indent, &module_indent,
Some(self.module.definitions.clone()), &BlockDefinitions::none(),
)?); )?);
"module" "module"
} }

View file

@ -808,40 +808,8 @@ circuit check_enum_cmp_eq:
connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2) 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 _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[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
wire _cast_bits_to_array_expr_2: UInt<1>[3] connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(lhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0]
connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(lhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1]
connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(lhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2]
wire _cast_bits_to_array_expr_3: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(rhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0]
connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(rhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1]
connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(rhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2]
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1])
wire _cast_bits_to_array_expr_4: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(lhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0]
connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(lhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1]
connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(lhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2]
wire _cast_bits_to_array_expr_5: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(rhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0]
connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(rhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1]
connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(rhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2]
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[2])
wire _cast_array_to_bits_expr: UInt<1>[3] 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[0], _array_literal_expr[0]
connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
@ -901,40 +869,8 @@ circuit check_enum_cmp_eq:
connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2) 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 _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[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
wire _cast_bits_to_array_expr_2: UInt<1>[3] connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(lhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0]
connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(lhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1]
connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(lhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2]
wire _cast_bits_to_array_expr_3: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(rhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0]
connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(rhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1]
connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(rhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2]
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1])
wire _cast_bits_to_array_expr_4: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(lhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0]
connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(lhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1]
connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(lhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2]
wire _cast_bits_to_array_expr_5: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(rhs.body, 2, 0), 0, 0)
connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0]
connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(rhs.body, 2, 0), 1, 1)
connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1]
connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(rhs.body, 2, 0), 2, 2)
connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2]
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[2])
wire _cast_array_to_bits_expr: UInt<1>[3] 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[0], _array_literal_expr[0]
connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
@ -993,40 +929,8 @@ circuit check_enum_cmp_eq:
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_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 _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[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0])
wire _cast_bits_to_array_expr_2: UInt<1>[3] connect _array_literal_expr[1], eq(_cast_bits_to_array_expr[1], _cast_bits_to_array_expr_1[1])
wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] connect _array_literal_expr[2], eq(_cast_bits_to_array_expr[2], _cast_bits_to_array_expr_1[2])
connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0)
connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0]
connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1)
connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1]
connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2)
connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2]
wire _cast_bits_to_array_expr_3: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0)
connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0]
connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1)
connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1]
connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2)
connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2]
connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1])
wire _cast_bits_to_array_expr_4: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0)
connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0]
connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1)
connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1]
connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2)
connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2]
wire _cast_bits_to_array_expr_5: UInt<1>[3]
wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3]
connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0)
connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0]
connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1)
connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1]
connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2)
connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2]
connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[2])
wire _cast_array_to_bits_expr: UInt<1>[3] 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[0], _array_literal_expr[0]
connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
@ -3925,21 +3829,10 @@ 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_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr.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)
@ -3961,18 +3854,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_2: Ty8 wire _cast_bits_to_bundle_expr_1: Ty8
wire _cast_bits_to_bundle_expr_flattened_2: Ty9 wire _cast_bits_to_bundle_expr_flattened_1: Ty9
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 0, 0), 0, 0)
wire _cast_bits_to_enum_expr_2: Ty3 wire _cast_bits_to_enum_expr_1: 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_1.tag, 0)):
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone) connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlNone)
else: else:
connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlSome)
connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2 connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_enum_expr_1
connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_flattened_1.body, UInt<0>(0)
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1] connect __connect_variant_body_3, _cast_bits_to_bundle_expr_1 @[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
@ -4001,18 +3894,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_3: Ty4 wire _cast_bits_to_bundle_expr_2: Ty4
wire _cast_bits_to_bundle_expr_flattened_3: Ty7 wire _cast_bits_to_bundle_expr_flattened_2: Ty7
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i1.body, 1, 0), 0, 0)
wire _cast_bits_to_enum_expr_3: Ty3 wire _cast_bits_to_enum_expr_2: 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_2.tag, 0)):
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone) connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone)
else: else:
connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome)
connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3 connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2
connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_flattened_2.body, bits(bits(i1.body, 1, 0), 1, 1)
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
match _cast_bits_to_bundle_expr_3.tag: @[module-XXXXXXXXXX.rs 9:1] match _cast_bits_to_bundle_expr_2.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)
@ -4020,21 +3913,10 @@ 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_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_2.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)
@ -4056,18 +3938,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_5: Ty8 wire _cast_bits_to_bundle_expr_3: Ty8
wire _cast_bits_to_bundle_expr_flattened_5: Ty9 wire _cast_bits_to_bundle_expr_flattened_3: Ty9
connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 0, 0), 0, 0)
wire _cast_bits_to_enum_expr_5: Ty3 wire _cast_bits_to_enum_expr_3: Ty3
when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_5.tag, 0)): when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)):
connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlNone) connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone)
else: else:
connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome)
connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_enum_expr_5 connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3
connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_flattened_3.body, UInt<0>(0)
connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1] connect __connect_variant_body_7, _cast_bits_to_bundle_expr_3 @[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
@ -4134,16 +4016,10 @@ 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_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr.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)
@ -4159,13 +4035,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_2: Ty4 wire _cast_bits_to_bundle_expr_1: Ty4
wire _cast_bits_to_bundle_expr_flattened_2: Ty4 wire _cast_bits_to_bundle_expr_flattened_1: Ty4
connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 0, 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_1.tag, _cast_bits_to_bundle_expr_flattened_1.tag
connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_flattened_1.body, UInt<0>(0)
connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body
connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1] connect __connect_variant_body_3, _cast_bits_to_bundle_expr_1 @[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
@ -4187,29 +4063,23 @@ 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_3: Ty2 wire _cast_bits_to_bundle_expr_2: Ty2
wire _cast_bits_to_bundle_expr_flattened_3: Ty2 wire _cast_bits_to_bundle_expr_flattened_2: Ty2
connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i1.body, 1, 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_2.tag, _cast_bits_to_bundle_expr_flattened_2.tag
connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_flattened_2.body, bits(bits(i1.body, 1, 0), 1, 1)
connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body
when eq(_cast_bits_to_bundle_expr_3.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1] when eq(_cast_bits_to_bundle_expr_2.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_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_2.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)
@ -4225,13 +4095,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_5: Ty4 wire _cast_bits_to_bundle_expr_3: Ty4
wire _cast_bits_to_bundle_expr_flattened_5: Ty4 wire _cast_bits_to_bundle_expr_flattened_3: Ty4
connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 0, 0), 0, 0)
connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_bundle_expr_flattened_5.tag connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_bundle_expr_flattened_3.tag
connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_flattened_3.body, UInt<0>(0)
connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body
connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1] connect __connect_variant_body_7, _cast_bits_to_bundle_expr_3 @[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