diff --git a/crates/fayalite/src/firrtl.rs b/crates/fayalite/src/firrtl.rs index 51aa040..e2f33ae 100644 --- a/crates/fayalite/src/firrtl.rs +++ b/crates/fayalite/src/firrtl.rs @@ -2,17 +2,12 @@ // See Notices.txt for copyright information #![allow(clippy::type_complexity)] use crate::{ - annotations::{ - Annotation, BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation, - DocStringAnnotation, DontTouchAnnotation, SVAttributeAnnotation, TargetedAnnotation, - }, - array::Array, + annotations::{Annotation, TargetedAnnotation}, build::{ToArgs, WriteArgs}, - bundle::{Bundle, BundleField, BundleType}, - clock::Clock, - enum_::{Enum, EnumType, EnumVariant}, + bundle::{BundleField, BundleType}, + enum_::{EnumType, EnumVariant}, expr::{ - CastBitsTo, Expr, ExprEnum, ToExpr, ValueType, + ExprEnum, ops::{self, VariantAccess}, target::{ Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, @@ -20,29 +15,28 @@ use crate::{ }, }, formal::FormalKind, - int::{Bool, DynSize, IntType, SIntValue, UInt, UIntValue}, + int::IntType, intern::{Intern, Interned}, - memory::{Mem, PortKind, PortName, ReadUnderWrite}, + memory::{PortKind, PortName}, module::{ AnnotatedModuleIO, Block, ExternModuleBody, ExternModuleParameter, - ExternModuleParameterValue, Module, ModuleBody, ModuleIO, NameId, NameOptId, - NormalModuleBody, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, - StmtMatch, StmtReg, StmtWire, + ExternModuleParameterValue, ModuleBody, ModuleIO, NameId, NameOptId, NormalModuleBody, + Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, + StmtWire, transform::{ simplify_enums::{SimplifyEnumsError, SimplifyEnumsKind, simplify_enums}, simplify_memories::simplify_memories, }, }, - reset::{AsyncReset, Reset, ResetType, SyncReset}, - source_location::SourceLocation, - ty::{CanonicalType, OpaqueSimValueSize, Type}, + prelude::*, + reset::ResetType, + ty::OpaqueSimValueSize, util::{ BitSliceWriteWithBase, DebugAsRawString, GenericConstBool, HashMap, HashSet, const_str_array_is_strictly_ascending, }, vendor::xilinx::XilinxAnnotation, }; -use bitvec::slice::BitSlice; use clap::value_parser; use num_traits::Signed; use serde::{Deserialize, Serialize}; @@ -378,6 +372,107 @@ impl DefinitionsMap { } } +#[derive(Default)] +struct BlockDefinitionsCache { + array_literal_exprs: + RefCell, bool), String>>, + bundle_literal_exprs: RefCell>, + uninit_exprs: RefCell>, + cast_bundle_to_bits_exprs: RefCell>, + cast_enum_to_bits_exprs: RefCell>, + cast_array_to_bits_exprs: RefCell>, + cast_bits_to_bundle_exprs: RefCell>, + cast_bits_to_enum_exprs: RefCell>, + cast_bits_to_array_exprs: RefCell>, + cast_bits_to_phantom_const_exprs: RefCell>, +} + +struct BlockDefinitionsState<'a> { + rc_definitions: RcDefinitions, + parent: &'a BlockDefinitions<'a>, + cache: BlockDefinitionsCache, +} + +struct BlockDefinitions<'a> { + state: Option>, +} + +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( + &mut self, + key: K, + field: impl Fn(&BlockDefinitionsCache) -> &RefCell>, + write_definition: impl FnOnce(BlockDefinitionsWriter<'_, '_>, &K) -> Result, + ) -> Result { + 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 { variants: RefCell, body: String, @@ -498,16 +593,13 @@ impl TypeState { struct ModuleState { ns: Namespace, - definitions: RcDefinitions, match_arm_values: HashMap, Ident>, } impl Default for ModuleState { fn default() -> Self { - let definitions = RcDefinitions::default(); Self { ns: Default::default(), - definitions, match_arm_values: Default::default(), } } @@ -876,7 +968,7 @@ impl<'a> Exporter<'a> { &mut self, value: Expr, to_ty: ToTy, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { let from_ty = value.ty(); @@ -911,7 +1003,7 @@ impl<'a> Exporter<'a> { &mut self, firrtl_cast_fn: Option<&str>, value: Expr, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { let value = self.expr(Expr::canonical(value), definitions, const_ty)?; @@ -925,7 +1017,7 @@ impl<'a> Exporter<'a> { &mut self, base: Expr, range: Range, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { let base_width = base.ty().width(); @@ -943,73 +1035,96 @@ impl<'a> Exporter<'a> { fn array_literal_expr( &mut self, expr: ops::ArrayLiteral, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { - let ident = self.module.ns.make_new("_array_literal_expr"); - let ty_str = self.type_state.ty(expr.ty())?; - let const_ = if const_ty { "const " } else { "" }; - definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_str}")); - for (index, element) in expr.element_values().into_iter().enumerate() { - let element = self.expr(Expr::canonical(element), definitions, const_ty)?; - definitions.add_definition_line(format_args!("connect {ident}[{index}], {element}")); - } - if expr.element_values().is_empty() { - definitions.add_definition_line(format_args!("invalidate {ident}")); - } - Ok(ident.to_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 ty_str = self.type_state.ty(expr.ty())?; + let const_ = if const_ty { "const " } else { "" }; + definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_str}")); + for (index, element) in expr.element_values().into_iter().enumerate() { + let 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() { + definitions.add_definition_line(format_args!("invalidate {ident}")); + } + Ok(ident.to_string()) + }, + ) } fn bundle_literal_expr( &mut self, expr: ops::BundleLiteral, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { - let ident = self.module.ns.make_new("_bundle_literal_expr"); - let ty = expr.ty(); - let (ty_ident, bundle_ns) = self.type_state.bundle_def(ty)?; - let const_ = if const_ty { "const " } else { "" }; - definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}")); - for ( - field_value, - BundleField { - name, - flipped, - ty: _, + 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 ty = expr.ty(); + let (ty_ident, bundle_ns) = self.type_state.bundle_def(ty)?; + let const_ = if const_ty { "const " } else { "" }; + definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}")); + for ( + field_value, + BundleField { + name, + flipped, + ty: _, + }, + ) in expr.field_values().into_iter().zip(ty.fields()) + { + debug_assert!( + !flipped, + "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 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() { + definitions.add_definition_line(format_args!("invalidate {ident}")); + } + Ok(ident.to_string()) }, - ) in expr.field_values().into_iter().zip(ty.fields()) - { - debug_assert!( - !flipped, - "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 field_value = self.expr(Expr::canonical(field_value), definitions, const_ty)?; - definitions.add_definition_line(format_args!("connect {ident}.{name}, {field_value}")); - } - if ty.fields().is_empty() { - definitions.add_definition_line(format_args!("invalidate {ident}")); - } - Ok(ident.to_string()) + ) } fn uninit_expr( &mut self, expr: ops::Uninit, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { - let ident = self.module.ns.make_new("_uninit_expr"); - let ty = expr.ty(); - let ty_ident = self.type_state.ty(ty)?; - let const_ = if const_ty { "const " } else { "" }; - definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}")); - definitions.add_definition_line(format_args!("invalidate {ident}")); - Ok(ident.to_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 ty = expr.ty(); + let ty_ident = self.type_state.ty(ty)?; + let const_ = if const_ty { "const " } else { "" }; + definitions.add_definition_line(format_args!("wire {ident}: {const_}{ty_ident}")); + definitions.add_definition_line(format_args!("invalidate {ident}")); + Ok(ident.to_string()) + }, + ) } fn enum_literal_expr( &mut self, expr: ops::EnumLiteral, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { let variant_expr = expr @@ -1022,175 +1137,198 @@ impl<'a> Exporter<'a> { &mut self, value_str: String, ty: Bundle, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - if ty.fields().is_empty() { - return Ok("UInt<0>(0)".into()); - } - if let [field] = *ty.fields() { - let field_ident = self.type_state.get_bundle_field(ty, field.name)?; - return self.expr_cast_to_bits( - format!("{value_str}.{field_ident}"), - field.ty, - definitions, - extra_indent, - ); - } - let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map( - |&BundleField { - name, - flipped: _, - ty: field_ty, - }| BundleField { - name, - flipped: false, - ty: UInt[field_ty.bit_width()].canonical(), + 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() { + return Ok("UInt<0>(0)".into()); + } + if let [field] = *ty.fields() { + let field_ident = self.type_state.get_bundle_field(ty, field.name)?; + return self.expr_cast_to_bits( + format!("{value_str}.{field_ident}"), + field.ty, + &mut definitions, + extra_indent, + ); + } + let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map( + |&BundleField { + name, + flipped: _, + ty: field_ty, + }| BundleField { + name, + flipped: false, + ty: UInt[field_ty.bit_width()].canonical(), + }, + ))); + let (flattened_ty_ident, _) = self.type_state.bundle_def(flattened_bundle_ty)?; + let ident = self.module.ns.make_new("_cast_bundle_to_bits_expr"); + definitions.add_definition_line(format_args!( + "{extra_indent}wire {ident}: {flattened_ty_ident}" + )); + let mut cat_expr = None; + for field in ty.fields() { + let field_ident = self.type_state.get_bundle_field(ty, field.name)?; + let flattened_field_ident = self + .type_state + .get_bundle_field(flattened_bundle_ty, field.name)?; + let field_bits = self.expr_cast_to_bits( + format!("{value_str}.{field_ident}"), + field.ty, + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {ident}.{flattened_field_ident}, {field_bits}" + )); + cat_expr = Some(if let Some(cat_expr) = cat_expr { + format!("cat({ident}.{flattened_field_ident}, {cat_expr})") + } else { + format!("{ident}.{flattened_field_ident}") + }); + } + let retval = self.module.ns.make_new("_cast_to_bits_expr"); + definitions.add_definition_line(format_args!( + "{extra_indent}wire {retval}: UInt<{}>", + ty.type_properties().bit_width + )); + let cat_expr = cat_expr.expect("bundle already checked to have fields"); + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {cat_expr}" + )); + Ok(retval.to_string()) }, - ))); - let (flattened_ty_ident, _) = self.type_state.bundle_def(flattened_bundle_ty)?; - let ident = self.module.ns.make_new("_cast_bundle_to_bits_expr"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {ident}: {flattened_ty_ident}" - )); - let mut cat_expr = None; - for field in ty.fields() { - let field_ident = self.type_state.get_bundle_field(ty, field.name)?; - let flattened_field_ident = self - .type_state - .get_bundle_field(flattened_bundle_ty, field.name)?; - let field_bits = self.expr_cast_to_bits( - format!("{value_str}.{field_ident}"), - field.ty, - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {ident}.{flattened_field_ident}, {field_bits}" - )); - cat_expr = Some(if let Some(cat_expr) = cat_expr { - format!("cat({ident}.{flattened_field_ident}, {cat_expr})") - } else { - format!("{ident}.{flattened_field_ident}") - }); - } - let retval = self.module.ns.make_new("_cast_to_bits_expr"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {retval}: UInt<{}>", - ty.type_properties().bit_width - )); - let cat_expr = cat_expr.expect("bundle already checked to have fields"); - definitions.add_definition_line(format_args!("{extra_indent}connect {retval}, {cat_expr}")); - Ok(retval.to_string()) + ) } fn expr_cast_enum_to_bits( &mut self, value_str: String, ty: Enum, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - if ty.variants().is_empty() { - return Ok("UInt<0>(0)".into()); - } - let retval = self.module.ns.make_new("_cast_enum_to_bits_expr"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {retval}: UInt<{}>", - ty.type_properties().bit_width - )); - definitions.add_definition_line(format_args!("{extra_indent}match {value_str}:")); - let _match_arms_indent = extra_indent.push(); - for (variant_index, variant) in ty.variants().into_iter().enumerate() { - if let Some(variant_ty) = variant.ty { - let variant_value = self - .module - .ns - .make_new(&format!("_cast_enum_to_bits_expr_{}", variant.name)); + 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() { + return Ok("UInt<0>(0)".into()); + } + let retval = self.module.ns.make_new("_cast_enum_to_bits_expr"); definitions.add_definition_line(format_args!( - "{extra_indent}{}({variant_value}):", - self.type_state.get_enum_variant(ty, variant.name)?, + "{extra_indent}wire {retval}: UInt<{}>", + ty.type_properties().bit_width )); - let _match_arm_indent = extra_indent.push(); - let variant_bits = self.expr_cast_to_bits( - variant_value.to_string(), - variant_ty, - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, pad(cat({variant_bits}, UInt<{}>({variant_index})), {})", - ty.discriminant_bit_width(), - ty.type_properties().bit_width, - )); - } else { - definitions.add_definition_line(format_args!( - "{extra_indent}{}:", - self.type_state.get_enum_variant(ty, variant.name)?, - )); - let _match_arm_indent = extra_indent.push(); - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, UInt<{}>({variant_index})", - ty.type_properties().bit_width, - )); - } - } - Ok(retval.to_string()) + definitions.add_definition_line(format_args!("{extra_indent}match {value_str}:")); + let _match_arms_indent = extra_indent.push(); + for (variant_index, variant) in ty.variants().into_iter().enumerate() { + if let Some(variant_ty) = variant.ty { + let variant_value = self + .module + .ns + .make_new(&format!("_cast_enum_to_bits_expr_{}", variant.name)); + definitions.add_definition_line(format_args!( + "{extra_indent}{}({variant_value}):", + self.type_state.get_enum_variant(ty, variant.name)?, + )); + let _match_arm_indent = extra_indent.push(); + let variant_bits = self.expr_cast_to_bits( + variant_value.to_string(), + variant_ty, + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, \ + pad(cat({variant_bits}, UInt<{}>({variant_index})), {})", + ty.discriminant_bit_width(), + ty.type_properties().bit_width, + )); + } else { + definitions.add_definition_line(format_args!( + "{extra_indent}{}:", + self.type_state.get_enum_variant(ty, variant.name)?, + )); + let _match_arm_indent = extra_indent.push(); + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, UInt<{}>({variant_index})", + ty.type_properties().bit_width, + )); + } + } + Ok(retval.to_string()) + }, + ) } fn expr_cast_array_to_bits( &mut self, value_str: String, ty: Array, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - if ty.is_empty() { - return Ok("UInt<0>(0)".into()); - } - if ty.len() == 1 { - return self.expr_cast_to_bits( - value_str + "[0]", - ty.element(), - definitions, - extra_indent, - ); - } - let element_width = ty.element().bit_width(); - let ident = self.module.ns.make_new("_cast_array_to_bits_expr"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {ident}: UInt<{element_width}>[{}]", - ty.len(), - )); - let mut cat_expr = None; - for index in 0..ty.len() { - let element_bits = self.expr_cast_to_bits( - format!("{value_str}[{index}]"), - ty.element(), - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {ident}[{index}], {element_bits}" - )); - cat_expr = Some(if let Some(cat_expr) = cat_expr { - format!("cat({ident}[{index}], {cat_expr})") - } else { - format!("{ident}[{index}]") - }); - } - let retval = self.module.ns.make_new("_cast_to_bits_expr"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {retval}: UInt<{}>", - ty.type_properties().bit_width - )); - let cat_expr = cat_expr.expect("array already checked to have elements"); - definitions.add_definition_line(format_args!("{extra_indent}connect {retval}, {cat_expr}")); - Ok(retval.to_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() { + return Ok("UInt<0>(0)".into()); + } + if ty.len() == 1 { + return self.expr_cast_to_bits( + value_str.clone() + "[0]", + ty.element(), + &mut definitions, + extra_indent, + ); + } + let element_width = ty.element().bit_width(); + let ident = self.module.ns.make_new("_cast_array_to_bits_expr"); + definitions.add_definition_line(format_args!( + "{extra_indent}wire {ident}: UInt<{element_width}>[{}]", + ty.len(), + )); + let mut cat_expr = None; + for index in 0..ty.len() { + let element_bits = self.expr_cast_to_bits( + format!("{value_str}[{index}]"), + ty.element(), + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {ident}[{index}], {element_bits}" + )); + cat_expr = Some(if let Some(cat_expr) = cat_expr { + format!("cat({ident}[{index}], {cat_expr})") + } else { + format!("{ident}[{index}]") + }); + } + let retval = self.module.ns.make_new("_cast_to_bits_expr"); + definitions.add_definition_line(format_args!( + "{extra_indent}wire {retval}: UInt<{}>", + ty.type_properties().bit_width + )); + let cat_expr = cat_expr.expect("array already checked to have elements"); + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {cat_expr}" + )); + Ok(retval.to_string()) + }, + ) } fn expr_cast_to_bits( &mut self, value_str: String, ty: CanonicalType, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { match ty.unwrap_transparent_types() { @@ -1219,195 +1357,230 @@ impl<'a> Exporter<'a> { &mut self, value_str: String, ty: Bundle, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - let (ty_ident, _) = self.type_state.bundle_def(ty)?; - let retval = self.module.ns.make_new("_cast_bits_to_bundle_expr"); - definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); - if ty.fields().is_empty() { - definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); - return Ok(retval.to_string()); - } - let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map( - |&BundleField { - name, - flipped: _, - ty: field_ty, - }| BundleField { - name, - flipped: false, - ty: UInt[field_ty.bit_width()].canonical(), - }, - ))); - let (flattened_ty_ident, _) = self.type_state.bundle_def(flattened_bundle_ty)?; - let flattened_ident = self - .module - .ns - .make_new("_cast_bits_to_bundle_expr_flattened"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {flattened_ident}: {flattened_ty_ident}" - )); - for ( - field, - OpaqueSimValueSize { - bit_width: field_offset, - sim_only_values_len: _, - }, - ) in ty.fields().into_iter().zip(ty.field_offsets()) - { - let flattened_field_ident = self - .type_state - .get_bundle_field(flattened_bundle_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) { + 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 retval = self.module.ns.make_new("_cast_bits_to_bundle_expr"); + definitions + .add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); + if ty.fields().is_empty() { + definitions + .add_definition_line(format_args!("{extra_indent}invalidate {retval}")); + return Ok(retval.to_string()); + } + let flattened_bundle_ty = Bundle::new(Interned::from_iter(ty.fields().iter().map( + |&BundleField { + name, + flipped: _, + ty: field_ty, + }| BundleField { + name, + flipped: false, + ty: UInt[field_ty.bit_width()].canonical(), + }, + ))); + let (flattened_ty_ident, _) = self.type_state.bundle_def(flattened_bundle_ty)?; + let flattened_ident = self + .module + .ns + .make_new("_cast_bits_to_bundle_expr_flattened"); definitions.add_definition_line(format_args!( - "{extra_indent}connect {flattened_ident}.{flattened_field_ident}, bits({value_str}, {}, {field_offset})", - field_offset + field_bit_width_minus_one + "{extra_indent}wire {flattened_ident}: {flattened_ty_ident}" )); - } else { - definitions.add_definition_line(format_args!( + for ( + field, + OpaqueSimValueSize { + bit_width: field_offset, + sim_only_values_len: _, + }, + ) in ty.fields().into_iter().zip(ty.field_offsets()) + { + let flattened_field_ident = self + .type_state + .get_bundle_field(flattened_bundle_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) + { + definitions.add_definition_line(format_args!( + "{extra_indent}connect {flattened_ident}.{flattened_field_ident}, \ + bits({value_str}, {}, {field_offset})", + field_offset + field_bit_width_minus_one + )); + } else { + definitions.add_definition_line(format_args!( "{extra_indent}connect {flattened_ident}.{flattened_field_ident}, UInt<0>(0)" )); - } - let field_value = self.expr_cast_bits_to( - format!("{flattened_ident}.{flattened_field_ident}"), - field.ty, - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}.{field_ident}, {field_value}" - )); - } - Ok(retval.to_string()) + } + let field_value = self.expr_cast_bits_to( + format!("{flattened_ident}.{flattened_field_ident}"), + field.ty, + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}.{field_ident}, {field_value}" + )); + } + Ok(retval.to_string()) + }, + ) } fn expr_cast_bits_to_enum( &mut self, value_str: String, ty: Enum, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - let (ty_ident, enum_def) = self.type_state.enum_def(ty)?; - let retval = self.module.ns.make_new("_cast_bits_to_enum_expr"); - definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); - if ty.variants().is_empty() { - definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); - return Ok(retval.to_string()); - } - if let [variant] = *ty.variants() { - let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; - if let Some(variant_ty) = variant.ty { - let variant_value = - self.expr_cast_bits_to(value_str, variant_ty, definitions, extra_indent)?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})", - enum_def.body - )); - } else { - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, {}({enum_variant})", - enum_def.body - )); - } - return Ok(retval.to_string()); - } - let discriminant_bit_width = ty.discriminant_bit_width(); - let body_bit_width = ty.type_properties().bit_width - discriminant_bit_width; - let body_ident = self.module.ns.make_new("_cast_bits_to_enum_expr_body"); - let body_value = if body_bit_width != 0 { - definitions.add_definition_line(format_args!( - "{extra_indent}wire {body_ident}: UInt<{body_bit_width}>" - )); - definitions.add_definition_line(format_args!( - "{extra_indent}connect {body_ident}, head({value_str}, {body_bit_width})" - )); - body_ident.to_string() - } else { - "UInt<0>(0)".into() - }; - for (variant_index, variant) in ty.variants().into_iter().enumerate() { - let when_cond = format!( - "eq(UInt<{discriminant_bit_width}>({variant_index}), tail({value_str}, {body_bit_width}))" - ); - if variant_index == ty.variants().len() - 1 { - definitions.add_definition_line(format_args!("{extra_indent}else:")); - } else if variant_index == 0 { - definitions.add_definition_line(format_args!("{extra_indent}when {when_cond}:")); - } else { + 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 retval = self.module.ns.make_new("_cast_bits_to_enum_expr"); definitions - .add_definition_line(format_args!("{extra_indent}else when {when_cond}:")); - } - let when_pushed_indent = extra_indent.push(); - let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; - if let Some(variant_ty) = variant.ty { - let variant_value = self.expr_cast_bits_to( - body_value.clone(), - variant_ty, - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})", - enum_def.body - )); - } else { - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}, {}({enum_variant})", - enum_def.body - )); - } - drop(when_pushed_indent); - } - Ok(retval.to_string()) + .add_definition_line(format_args!("{extra_indent}wire {retval}: {ty_ident}")); + if ty.variants().is_empty() { + definitions + .add_definition_line(format_args!("{extra_indent}invalidate {retval}")); + return Ok(retval.to_string()); + } + if let [variant] = *ty.variants() { + let enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; + if let Some(variant_ty) = variant.ty { + let variant_value = self.expr_cast_bits_to( + value_str.clone(), + variant_ty, + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})", + enum_def.body + )); + } else { + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {}({enum_variant})", + enum_def.body + )); + } + return Ok(retval.to_string()); + } + let discriminant_bit_width = ty.discriminant_bit_width(); + let body_bit_width = ty.type_properties().bit_width - discriminant_bit_width; + let body_ident = self.module.ns.make_new("_cast_bits_to_enum_expr_body"); + let body_value = if body_bit_width != 0 { + definitions.add_definition_line(format_args!( + "{extra_indent}wire {body_ident}: UInt<{body_bit_width}>" + )); + definitions.add_definition_line(format_args!( + "{extra_indent}connect {body_ident}, head({value_str}, {body_bit_width})" + )); + body_ident.to_string() + } else { + "UInt<0>(0)".into() + }; + for (variant_index, variant) in ty.variants().into_iter().enumerate() { + let when_cond = format!( + "eq(UInt<{discriminant_bit_width}>({variant_index}), \ + tail({value_str}, {body_bit_width}))" + ); + if variant_index == ty.variants().len() - 1 { + definitions.add_definition_line(format_args!("{extra_indent}else:")); + } else if variant_index == 0 { + definitions + .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 enum_variant = self.type_state.get_enum_variant(ty, variant.name)?; + if let Some(variant_ty) = variant.ty { + let variant_value = self.expr_cast_bits_to( + body_value.clone(), + variant_ty, + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {}({enum_variant}, {variant_value})", + enum_def.body + )); + } else { + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}, {}({enum_variant})", + enum_def.body + )); + } + drop(when_pushed_indent); + } + Ok(retval.to_string()) + }, + ) } fn expr_cast_bits_to_array( &mut self, value_str: String, ty: Array, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { - let retval = self.module.ns.make_new("_cast_bits_to_array_expr"); - let array_ty = self.type_state.ty(ty)?; - definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {array_ty}")); - let element_bit_width = ty.element().bit_width(); - if ty.is_empty() || element_bit_width == 0 { - definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); - return Ok(retval.to_string()); - } - let flattened_ident = self - .module - .ns - .make_new("_cast_bits_to_array_expr_flattened"); - definitions.add_definition_line(format_args!( - "{extra_indent}wire {flattened_ident}: UInt<{element_bit_width}>[{}]", - ty.len(), - )); - for index in 0..ty.len() { - definitions.add_definition_line(format_args!( - "{extra_indent}connect {flattened_ident}[{index}], bits({value_str}, {}, {})", - element_bit_width * index + element_bit_width - 1, - element_bit_width * index, - )); - let element_value = self.expr_cast_bits_to( - format!("{flattened_ident}[{index}]"), - ty.element(), - definitions, - extra_indent, - )?; - definitions.add_definition_line(format_args!( - "{extra_indent}connect {retval}[{index}], {element_value}" - )); - } - Ok(retval.to_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 array_ty = self.type_state.ty(ty)?; + definitions + .add_definition_line(format_args!("{extra_indent}wire {retval}: {array_ty}")); + let element_bit_width = ty.element().bit_width(); + if ty.is_empty() || element_bit_width == 0 { + definitions + .add_definition_line(format_args!("{extra_indent}invalidate {retval}")); + return Ok(retval.to_string()); + } + let flattened_ident = self + .module + .ns + .make_new("_cast_bits_to_array_expr_flattened"); + definitions.add_definition_line(format_args!( + "{extra_indent}wire {flattened_ident}: UInt<{element_bit_width}>[{}]", + ty.len(), + )); + for index in 0..ty.len() { + definitions.add_definition_line(format_args!( + "{extra_indent}connect {flattened_ident}[{index}], \ + bits({value_str}, {}, {})", + element_bit_width * index + element_bit_width - 1, + element_bit_width * index, + )); + let element_value = self.expr_cast_bits_to( + format!("{flattened_ident}[{index}]"), + ty.element(), + &mut definitions, + extra_indent, + )?; + definitions.add_definition_line(format_args!( + "{extra_indent}connect {retval}[{index}], {element_value}" + )); + } + Ok(retval.to_string()) + }, + ) } fn expr_cast_bits_to( &mut self, value_str: String, ty: CanonicalType, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, extra_indent: Indent<'_>, ) -> Result { match ty.unwrap_transparent_types() { @@ -1427,12 +1600,18 @@ impl<'a> Exporter<'a> { CanonicalType::AsyncReset(_) => Ok(format!("asAsyncReset({value_str})")), CanonicalType::SyncReset(_) => Ok(value_str), CanonicalType::Reset(_) => unreachable!("Reset is not bit castable to"), - CanonicalType::PhantomConst(_) => { - let retval = self.module.ns.make_new("_cast_bits_to_phantom_const_expr"); - definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {{}}")); - definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); - return Ok(retval.to_string()); - } + 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"); + definitions + .add_definition_line(format_args!("{extra_indent}wire {retval}: {{}}")); + definitions + .add_definition_line(format_args!("{extra_indent}invalidate {retval}")); + Ok(retval.to_string()) + }, + ), CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), } @@ -1441,7 +1620,7 @@ impl<'a> Exporter<'a> { &mut self, func: &str, arg: Expr, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { Ok(format!( @@ -1454,7 +1633,7 @@ impl<'a> Exporter<'a> { func: &str, lhs: Expr, rhs: Expr, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { Ok(format!( @@ -1466,7 +1645,7 @@ impl<'a> Exporter<'a> { fn expr( &mut self, expr: Expr, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, const_ty: bool, ) -> Result { match *Expr::expr_enum(expr) { @@ -2062,7 +2241,7 @@ impl<'a> Exporter<'a> { &mut self, stmt_reg: StmtReg, module_name: Ident, - definitions: &RcDefinitions, + definitions: &mut BlockDefinitions<'_>, body: &mut String, ) -> Result<()> { let StmtReg { annotations, reg } = stmt_reg; @@ -2095,10 +2274,10 @@ impl<'a> Exporter<'a> { module: Interned>, block: Block, _block_indent: &PushIndent<'_>, - definitions: Option, + parent_definitions: &BlockDefinitions, ) -> Result { let indent = self.indent; - let definitions = definitions.unwrap_or_default(); + let mut definitions = BlockDefinitions::new(parent_definitions); let mut body = String::new(); let mut out = String::new(); let Block { memories, stmts } = block; @@ -2122,8 +2301,8 @@ impl<'a> Exporter<'a> { ) .unwrap(); } - let lhs = self.expr(lhs, &definitions, false)?; - let rhs = self.expr(rhs, &definitions, false)?; + let lhs = self.expr(lhs, &mut definitions, false)?; + let rhs = self.expr(rhs, &mut definitions, false)?; writeln!( body, "{indent}connect {lhs}, {rhs}{}", @@ -2139,9 +2318,9 @@ impl<'a> Exporter<'a> { text, source_location, }) => { - let clk = self.expr(Expr::canonical(clk), &definitions, false)?; - let pred = self.expr(Expr::canonical(pred), &definitions, false)?; - let en = self.expr(Expr::canonical(en), &definitions, false)?; + let clk = self.expr(Expr::canonical(clk), &mut definitions, false)?; + let pred = self.expr(Expr::canonical(pred), &mut definitions, false)?; + let en = self.expr(Expr::canonical(en), &mut definitions, false)?; let kind = match kind { FormalKind::Assert => "assert", FormalKind::Assume => "assume", @@ -2166,7 +2345,7 @@ impl<'a> Exporter<'a> { let mut when = "when"; let mut pushed_indent; loop { - let cond_str = self.expr(Expr::canonical(cond), &definitions, false)?; + let cond_str = self.expr(Expr::canonical(cond), &mut definitions, false)?; writeln!( body, "{indent}{when} {cond_str}:{}", @@ -2175,7 +2354,7 @@ impl<'a> Exporter<'a> { .unwrap(); pushed_indent = indent.push(); 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() { body.push_str(&then_block_str); } else { @@ -2193,7 +2372,8 @@ impl<'a> Exporter<'a> { 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); if !else_block.is_empty() { writeln!(body, "{indent}else:").unwrap(); @@ -2208,7 +2388,7 @@ impl<'a> Exporter<'a> { writeln!( body, "{indent}match {}:{}", - self.expr(Expr::canonical(expr), &definitions, false)?, + self.expr(Expr::canonical(expr), &mut definitions, false)?, FileInfo::new(source_location), ) .unwrap(); @@ -2236,7 +2416,8 @@ impl<'a> Exporter<'a> { }; body.push_str(":\n"); 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() { body.push_str(&block); } else { @@ -2261,13 +2442,13 @@ impl<'a> Exporter<'a> { .unwrap(); } 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)) => { - 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)) => { - 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 { annotations, @@ -2286,7 +2467,7 @@ impl<'a> Exporter<'a> { .unwrap(); } } - definitions.write_and_clear(indent, &mut out); + definitions.write_out(indent, &mut out); out.push_str(&body); body.clear(); } @@ -2366,7 +2547,7 @@ impl<'a> Exporter<'a> { module, top_block, &module_indent, - Some(self.module.definitions.clone()), + &BlockDefinitions::none(), )?); "module" } diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 9dc0107..5c62933 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -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_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]) - wire _cast_bits_to_array_expr_2: UInt<1>[3] - wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] - 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]) + 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] @@ -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_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]) - wire _cast_bits_to_array_expr_2: UInt<1>[3] - wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] - 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]) + 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] @@ -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_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]) - wire _cast_bits_to_array_expr_2: UInt<1>[3] - wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] - 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]) + 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] @@ -3925,21 +3829,10 @@ circuit check_enum_connect_any: connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1] HdlSome: 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: ; lhs: SInt<1> ; 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 connect _bundle_literal_expr_2.tag, {|HdlNone, HdlSome|}(HdlSome) 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] C: 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_flattened_2: Ty9 - connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0) - wire _cast_bits_to_enum_expr_2: Ty3 - when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_2.tag, 0)): - connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone) + wire _cast_bits_to_bundle_expr_1: Ty8 + wire _cast_bits_to_bundle_expr_flattened_1: Ty9 + connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 0, 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_2, {|HdlNone, HdlSome|}(HdlSome) - connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2 - connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0) - 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_2 @[module-XXXXXXXXXX.rs 8:1] + 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, UInt<0>(0) + 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_1 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_4: Ty1 connect _bundle_literal_expr_4.tag, {|A, B, C|}(C) 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] B: 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_flattened_3: Ty7 - connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0) - wire _cast_bits_to_enum_expr_3: Ty3 - when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)): - connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone) + wire _cast_bits_to_bundle_expr_2: Ty4 + wire _cast_bits_to_bundle_expr_flattened_2: Ty7 + connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i1.body, 1, 0), 0, 0) + wire _cast_bits_to_enum_expr_2: Ty3 + when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_2.tag, 0)): + connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone) else: - connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome) - connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3 - connect _cast_bits_to_bundle_expr_flattened_3.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 - match _cast_bits_to_bundle_expr_3.tag: @[module-XXXXXXXXXX.rs 9:1] + connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome) + connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2 + connect _cast_bits_to_bundle_expr_flattened_2.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 + match _cast_bits_to_bundle_expr_2.tag: @[module-XXXXXXXXXX.rs 9:1] HdlNone: wire _bundle_literal_expr_6: Ty5 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] HdlSome: 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: ; lhs: SInt<2> ; 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 connect _bundle_literal_expr_7.tag, {|HdlNone, HdlSome|}(HdlSome) 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] C: 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_flattened_5: Ty9 - connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0) - wire _cast_bits_to_enum_expr_5: Ty3 - when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_5.tag, 0)): - connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlNone) + wire _cast_bits_to_bundle_expr_3: Ty8 + wire _cast_bits_to_bundle_expr_flattened_3: Ty9 + connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 0, 0), 0, 0) + wire _cast_bits_to_enum_expr_3: Ty3 + when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)): + connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone) else: - connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlSome) - connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_enum_expr_5 - connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0) - 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_5 @[module-XXXXXXXXXX.rs 9:1] + connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome) + connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3 + connect _cast_bits_to_bundle_expr_flattened_3.body, UInt<0>(0) + 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_3 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_9: Ty2 connect _bundle_literal_expr_9.tag, {|A, B, C|}(C) 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] else: 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: ; lhs: SInt<1> ; 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 connect _bundle_literal_expr_2.tag, UInt<1>(0h1) 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] else: 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_flattened_2: Ty4 - connect _cast_bits_to_bundle_expr_flattened_2.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_flattened_2.body, UInt<0>(0) - 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_2 @[module-XXXXXXXXXX.rs 8:1] + wire _cast_bits_to_bundle_expr_1: Ty4 + wire _cast_bits_to_bundle_expr_flattened_1: Ty4 + connect _cast_bits_to_bundle_expr_flattened_1.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_flattened_1.body, UInt<0>(0) + 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_1 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_4: Ty0 connect _bundle_literal_expr_4.tag, UInt<2>(0h2) 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] 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 _cast_bits_to_bundle_expr_3: Ty2 - wire _cast_bits_to_bundle_expr_flattened_3: Ty2 - connect _cast_bits_to_bundle_expr_flattened_3.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_flattened_3.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 - when eq(_cast_bits_to_bundle_expr_3.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1] + wire _cast_bits_to_bundle_expr_2: Ty2 + wire _cast_bits_to_bundle_expr_flattened_2: Ty2 + connect _cast_bits_to_bundle_expr_flattened_2.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_flattened_2.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 + when eq(_cast_bits_to_bundle_expr_2.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_6: Ty3 connect _bundle_literal_expr_6.tag, UInt<1>(0h0) connect _bundle_literal_expr_6.body, UInt<2>(0h0) connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1] else: 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: ; lhs: SInt<2> ; 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 connect _bundle_literal_expr_7.tag, UInt<1>(0h1) 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] else: 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_flattened_5: Ty4 - connect _cast_bits_to_bundle_expr_flattened_5.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_flattened_5.body, UInt<0>(0) - 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_5 @[module-XXXXXXXXXX.rs 9:1] + wire _cast_bits_to_bundle_expr_3: Ty4 + wire _cast_bits_to_bundle_expr_flattened_3: Ty4 + connect _cast_bits_to_bundle_expr_flattened_3.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_flattened_3.body, UInt<0>(0) + 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_3 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_9: Ty1 connect _bundle_literal_expr_9.tag, UInt<2>(0h2) wire _cast_bundle_to_bits_expr_3: Ty4