From 30a38bc8da427c08c2ba9db159fb1424df288ebe Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 30 Sep 2024 22:31:16 -0700 Subject: [PATCH] fix simplify_enums to properly handle nested enums and connects with different types --- .../src/module/transform/simplify_enums.rs | 693 +++++++++++++----- crates/fayalite/tests/module.rs | 585 ++++++++++++--- 2 files changed, 1028 insertions(+), 250 deletions(-) diff --git a/crates/fayalite/src/module/transform/simplify_enums.rs b/crates/fayalite/src/module/transform/simplify_enums.rs index cf85875..3b3677b 100644 --- a/crates/fayalite/src/module/transform/simplify_enums.rs +++ b/crates/fayalite/src/module/transform/simplify_enums.rs @@ -2,19 +2,20 @@ // See Notices.txt for copyright information use crate::{ array::{Array, ArrayType}, - bundle::{Bundle, BundleType}, + bundle::{Bundle, BundleField, BundleType}, enum_::{Enum, EnumType, EnumVariant}, expr::{ ops::{self, EnumLiteral}, - CastBitsTo, CastToBits, Expr, ExprEnum, HdlPartialEq, ToExpr, + CastBitsTo, CastTo, CastToBits, Expr, ExprEnum, HdlPartialEq, ToExpr, }, hdl, - int::{DynSize, Size, UInt, UIntType}, - intern::{Intern, Interned}, + int::UInt, + intern::{Intern, Interned, Memoize}, memory::{DynPortType, Mem, MemPort}, module::{ transform::visit::{Fold, Folder}, - Block, Module, NameIdGen, ScopedNameId, Stmt, StmtConnect, StmtIf, StmtMatch, StmtWire, + Block, Module, NameId, NameIdGen, ScopedNameId, Stmt, StmtConnect, StmtIf, StmtMatch, + StmtWire, }, source_location::SourceLocation, ty::{CanonicalType, Type}, @@ -47,25 +48,65 @@ impl From for std::io::Error { } } +fn contains_any_enum_types(ty: CanonicalType) -> bool { + #[derive(Copy, Clone, PartialEq, Eq, Hash)] + struct TheMemoize; + impl Memoize for TheMemoize { + type Input = CanonicalType; + type InputOwned = CanonicalType; + type Output = bool; + + fn inner(self, ty: &Self::Input) -> Self::Output { + match *ty { + CanonicalType::Array(array_type) => contains_any_enum_types(array_type.element()), + CanonicalType::Enum(_) => true, + CanonicalType::Bundle(bundle) => bundle + .fields() + .iter() + .any(|field| contains_any_enum_types(field.ty)), + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => false, + } + } + } + TheMemoize.get_owned(ty) +} + #[hdl] -struct TagAndBody { - tag: T, - body: UIntType, +struct TagAndBody { + tag: Tag, + body: Body, } #[derive(Clone, Debug)] enum EnumTypeState { - TagEnumAndBody(TagAndBody), - TagUIntAndBody(TagAndBody), + TagEnumAndBody(TagAndBody), + TagUIntAndBody(TagAndBody), UInt(UInt), Unchanged, } +struct ModuleState { + name_id_gen: NameIdGen, + module_name: NameId, +} + +impl ModuleState { + fn gen_name(&mut self, name: &str) -> ScopedNameId { + ScopedNameId(self.module_name, self.name_id_gen.gen(name.intern())) + } +} + struct State { enum_types: HashMap, replacement_mem_ports: HashMap, Wire>, kind: SimplifyEnumsKind, - name_id_gen: NameIdGen, + module_state_stack: Vec, } impl State { @@ -113,6 +154,377 @@ impl State { self.enum_types.insert(enum_type, retval.clone()); Ok(retval) } + #[hdl] + fn handle_enum_literal( + &mut self, + unfolded_enum_type: Enum, + variant_index: usize, + folded_variant_value: Option>, + ) -> Result, SimplifyEnumsError> { + Ok( + match self.get_or_make_enum_type_state(unfolded_enum_type)? { + EnumTypeState::TagEnumAndBody(TagAndBody { tag, body }) => Expr::canonical( + #[hdl] + TagAndBody { + tag: EnumLiteral::new_by_index(tag, variant_index, None), + body: match folded_variant_value { + Some(variant_value) => variant_value.cast_to_bits().cast_to(body), + None => body.zero().to_expr(), + }, + }, + ), + EnumTypeState::TagUIntAndBody(TagAndBody { tag, body }) => Expr::canonical( + #[hdl] + TagAndBody { + tag: tag.from_int_wrapping(variant_index), + body: match folded_variant_value { + Some(folded_variant_value) => { + folded_variant_value.cast_to_bits().cast_to(body) + } + None => body.zero().to_expr(), + }, + }, + ), + EnumTypeState::UInt(_) => { + let tag = UInt[unfolded_enum_type.discriminant_bit_width()]; + let body = UInt[unfolded_enum_type.type_properties().bit_width - tag.width()]; + Expr::canonical( + (#[hdl] + TagAndBody { + tag: tag.from_int_wrapping(variant_index), + body: match folded_variant_value { + Some(folded_variant_value) => { + folded_variant_value.cast_to_bits().cast_to(body) + } + None => body.zero().to_expr(), + }, + }) + .cast_to_bits(), + ) + } + EnumTypeState::Unchanged => Expr::canonical( + ops::EnumLiteral::new_by_index( + unfolded_enum_type, + variant_index, + folded_variant_value, + ) + .to_expr(), + ), + }, + ) + } + fn handle_variant_access( + &mut self, + unfolded_enum_type: Enum, + folded_base_expr: Expr, + variant_index: usize, + ) -> Result, SimplifyEnumsError> { + let unfolded_variant_type = unfolded_enum_type.variants()[variant_index].ty; + Ok( + match self.get_or_make_enum_type_state(unfolded_enum_type)? { + EnumTypeState::TagEnumAndBody(_) | EnumTypeState::TagUIntAndBody(_) => { + match unfolded_variant_type { + Some(variant_type) => Expr::canonical( + Expr::>::from_canonical( + folded_base_expr, + ) + .body[..variant_type.bit_width()] + .cast_bits_to(variant_type.fold(self)?), + ), + None => Expr::canonical(().to_expr()), + } + } + EnumTypeState::UInt(_) => match unfolded_variant_type { + Some(variant_type) => { + let base_int = Expr::::from_canonical(folded_base_expr); + let variant_type_bit_width = variant_type.bit_width(); + Expr::canonical( + base_int[unfolded_enum_type.discriminant_bit_width()..] + [..variant_type_bit_width] + .cast_bits_to(variant_type.fold(self)?), + ) + } + None => Expr::canonical(().to_expr()), + }, + EnumTypeState::Unchanged => match unfolded_variant_type { + Some(_) => ops::VariantAccess::new_by_index( + Expr::from_canonical(folded_base_expr), + variant_index, + ) + .to_expr(), + None => Expr::canonical(().to_expr()), + }, + }, + ) + } + fn handle_match( + &mut self, + unfolded_enum_type: Enum, + folded_expr: Expr, + source_location: SourceLocation, + folded_blocks: &[Block], + ) -> Result { + match self.get_or_make_enum_type_state(unfolded_enum_type)? { + EnumTypeState::TagEnumAndBody(_) => Ok(StmtMatch { + expr: Expr::>::from_canonical(folded_expr).tag, + source_location, + blocks: folded_blocks.intern(), + } + .into()), + EnumTypeState::TagUIntAndBody(_) => { + let int_tag_expr = Expr::>::from_canonical(folded_expr).tag; + Ok(match_int_tag(int_tag_expr, source_location, &folded_blocks).into()) + } + EnumTypeState::UInt(_) => { + let int_tag_expr = Expr::::from_canonical(folded_expr) + [..unfolded_enum_type.discriminant_bit_width()]; + Ok(match_int_tag(int_tag_expr, source_location, &folded_blocks).into()) + } + EnumTypeState::Unchanged => Ok(StmtMatch { + expr: Expr::from_canonical(folded_expr), + source_location, + blocks: folded_blocks.intern(), + } + .into()), + } + } + fn handle_stmt_connect_array( + &mut self, + unfolded_lhs_ty: Array, + unfolded_rhs_ty: Array, + folded_lhs: Expr, + folded_rhs: Expr, + source_location: SourceLocation, + output_stmts: &mut Vec, + ) -> Result<(), SimplifyEnumsError> { + assert_eq!(unfolded_lhs_ty.len(), unfolded_rhs_ty.len()); + let unfolded_lhs_element_ty = unfolded_lhs_ty.element(); + let unfolded_rhs_element_ty = unfolded_rhs_ty.element(); + for array_index in 0..unfolded_lhs_ty.len() { + self.handle_stmt_connect( + unfolded_lhs_element_ty, + unfolded_rhs_element_ty, + folded_lhs[array_index], + folded_rhs[array_index], + source_location, + output_stmts, + )?; + } + Ok(()) + } + fn handle_stmt_connect_bundle( + &mut self, + unfolded_lhs_ty: Bundle, + unfolded_rhs_ty: Bundle, + folded_lhs: Expr, + folded_rhs: Expr, + source_location: SourceLocation, + output_stmts: &mut Vec, + ) -> Result<(), SimplifyEnumsError> { + let unfolded_lhs_fields = unfolded_lhs_ty.fields(); + let unfolded_rhs_fields = unfolded_rhs_ty.fields(); + assert_eq!(unfolded_lhs_fields.len(), unfolded_rhs_fields.len()); + for ( + field_index, + ( + &BundleField { + name, + flipped, + ty: unfolded_lhs_field_ty, + }, + unfolded_rhs_field, + ), + ) in unfolded_lhs_fields + .iter() + .zip(&unfolded_rhs_fields) + .enumerate() + { + assert_eq!(name, unfolded_rhs_field.name); + assert_eq!(flipped, unfolded_rhs_field.flipped); + let folded_lhs_field = + ops::FieldAccess::new_by_index(folded_lhs, field_index).to_expr(); + let folded_rhs_field = + ops::FieldAccess::new_by_index(folded_rhs, field_index).to_expr(); + if flipped { + // swap lhs/rhs + self.handle_stmt_connect( + unfolded_rhs_field.ty, + unfolded_lhs_field_ty, + folded_rhs_field, + folded_lhs_field, + source_location, + output_stmts, + )?; + } else { + self.handle_stmt_connect( + unfolded_lhs_field_ty, + unfolded_rhs_field.ty, + folded_lhs_field, + folded_rhs_field, + source_location, + output_stmts, + )?; + } + } + Ok(()) + } + fn handle_stmt_connect_enum( + &mut self, + unfolded_lhs_ty: Enum, + unfolded_rhs_ty: Enum, + folded_lhs: Expr, + folded_rhs: Expr, + source_location: SourceLocation, + output_stmts: &mut Vec, + ) -> Result<(), SimplifyEnumsError> { + let unfolded_lhs_variants = unfolded_lhs_ty.variants(); + let unfolded_rhs_variants = unfolded_rhs_ty.variants(); + assert_eq!(unfolded_lhs_variants.len(), unfolded_rhs_variants.len()); + let mut folded_blocks = vec![]; + for ( + variant_index, + ( + &EnumVariant { + name, + ty: unfolded_lhs_variant_ty, + }, + unfolded_rhs_variant, + ), + ) in unfolded_lhs_variants + .iter() + .zip(&unfolded_rhs_variants) + .enumerate() + { + let mut output_stmts = vec![]; + assert_eq!(name, unfolded_rhs_variant.name); + assert_eq!( + unfolded_lhs_variant_ty.is_some(), + unfolded_rhs_variant.ty.is_some() + ); + let folded_variant_value = + if let (Some(unfolded_lhs_variant_ty), Some(unfolded_rhs_variant_ty)) = + (unfolded_lhs_variant_ty, unfolded_rhs_variant.ty) + { + let lhs_wire = Wire::new_unchecked( + self.module_state_stack + .last_mut() + .unwrap() + .gen_name("__connect_variant_body"), + source_location, + unfolded_lhs_variant_ty.fold(self)?, + ); + output_stmts.push( + StmtWire { + annotations: Interned::default(), + wire: lhs_wire, + } + .into(), + ); + let lhs_wire = lhs_wire.to_expr(); + let folded_rhs_variant = + self.handle_variant_access(unfolded_rhs_ty, folded_rhs, variant_index)?; + self.handle_stmt_connect( + unfolded_lhs_variant_ty, + unfolded_rhs_variant_ty, + lhs_wire, + folded_rhs_variant, + source_location, + &mut output_stmts, + )?; + Some(lhs_wire) + } else { + None + }; + output_stmts.push( + StmtConnect { + lhs: folded_lhs, + rhs: self.handle_enum_literal( + unfolded_lhs_ty, + variant_index, + folded_variant_value, + )?, + source_location, + } + .into(), + ); + folded_blocks.push(Block { + memories: Interned::default(), + stmts: Intern::intern_owned(output_stmts), + }); + } + output_stmts.push(self.handle_match( + unfolded_rhs_ty, + folded_rhs, + source_location, + &folded_blocks, + )?); + Ok(()) + } + fn handle_stmt_connect( + &mut self, + unfolded_lhs_ty: CanonicalType, + unfolded_rhs_ty: CanonicalType, + folded_lhs: Expr, + folded_rhs: Expr, + source_location: SourceLocation, + output_stmts: &mut Vec, + ) -> Result<(), SimplifyEnumsError> { + let needs_expansion = unfolded_lhs_ty != unfolded_rhs_ty + && (contains_any_enum_types(unfolded_lhs_ty) + || contains_any_enum_types(unfolded_rhs_ty)); + if !needs_expansion { + output_stmts.push( + StmtConnect { + lhs: folded_lhs, + rhs: folded_rhs, + source_location, + } + .into(), + ); + return Ok(()); + } + println!( + r"handle_stmt_connect( + unfolded_lhs_ty: {unfolded_lhs_ty:?}, + unfolded_rhs_ty: {unfolded_rhs_ty:?}, + folded_lhs: {folded_lhs:?}, + folded_rhs: {folded_rhs:?}, +)" + ); + match unfolded_lhs_ty { + CanonicalType::Array(unfolded_lhs_ty) => self.handle_stmt_connect_array( + unfolded_lhs_ty, + Array::from_canonical(unfolded_rhs_ty), + Expr::from_canonical(folded_lhs), + Expr::from_canonical(folded_rhs), + source_location, + output_stmts, + ), + CanonicalType::Enum(unfolded_lhs_ty) => self.handle_stmt_connect_enum( + unfolded_lhs_ty, + Enum::from_canonical(unfolded_rhs_ty), + folded_lhs, + folded_rhs, + source_location, + output_stmts, + ), + CanonicalType::Bundle(unfolded_lhs_ty) => self.handle_stmt_connect_bundle( + unfolded_lhs_ty, + Bundle::from_canonical(unfolded_rhs_ty), + Expr::from_canonical(folded_lhs), + Expr::from_canonical(folded_rhs), + source_location, + output_stmts, + ), + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => unreachable!(), + } + } } fn connect_port( @@ -183,6 +595,42 @@ fn connect_port( } } +fn match_int_tag( + int_tag_expr: Expr, + source_location: SourceLocation, + folded_blocks: &[Block], +) -> StmtIf { + let mut blocks_iter = folded_blocks.iter().copied().enumerate(); + let (_, last_block) = blocks_iter.next_back().unwrap_or_default(); + let Some((next_to_last_variant_index, next_to_last_block)) = blocks_iter.next_back() else { + return StmtIf { + cond: true.to_expr(), + source_location, + blocks: [last_block, Block::default()], + }; + }; + let mut retval = StmtIf { + cond: int_tag_expr + .cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(next_to_last_variant_index)), + source_location, + blocks: [next_to_last_block, last_block], + }; + for (variant_index, block) in blocks_iter.rev() { + retval = StmtIf { + cond: int_tag_expr.cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(variant_index)), + source_location, + blocks: [ + block, + Block { + memories: Default::default(), + stmts: [Stmt::from(retval)][..].intern(), + }, + ], + }; + } + retval +} + impl Folder for State { type Error = SimplifyEnumsError; @@ -191,96 +639,33 @@ impl Folder for State { } fn fold_module(&mut self, v: Module) -> Result, Self::Error> { - let old_name_id_gen = - std::mem::replace(&mut self.name_id_gen, NameIdGen::for_module(v.canonical())); + self.module_state_stack.push(ModuleState { + name_id_gen: NameIdGen::for_module(v.canonical()), + module_name: v.name_id(), + }); let retval = Fold::default_fold(v, self); - self.name_id_gen = old_name_id_gen; + self.module_state_stack.pop(); retval } fn fold_expr_enum(&mut self, op: ExprEnum) -> Result { match op { - ExprEnum::EnumLiteral(op) => Ok(match self.get_or_make_enum_type_state(op.ty())? { - EnumTypeState::TagEnumAndBody(TagAndBody { tag, body }) => *Expr::expr_enum( - as BundleType>::Builder::default() - .field_tag(EnumLiteral::new_by_index(tag, op.variant_index(), None)) - .field_body(match op.variant_value() { - Some(variant_value) => variant_value.fold(self)?.cast_to_bits(), - None => body.zero().to_expr(), - }) - .to_expr(), - ), - EnumTypeState::TagUIntAndBody(TagAndBody { tag, body }) => *Expr::expr_enum( - as BundleType>::Builder::default() - .field_tag(tag.from_int_wrapping(op.variant_index())) - .field_body(match op.variant_value() { - Some(variant_value) => variant_value.fold(self)?.cast_to_bits(), - None => body.zero().to_expr(), - }) - .to_expr(), - ), - EnumTypeState::UInt(_) => *Expr::expr_enum( - as BundleType>::Builder::default() - .field_tag( - UIntType::new(op.ty().discriminant_bit_width()) - .from_int_wrapping(op.variant_index()), - ) - .field_body(match op.variant_value() { - Some(variant_value) => variant_value.fold(self)?.cast_to_bits(), - None => UIntType::new( - op.ty().type_properties().bit_width - - op.ty().discriminant_bit_width(), - ) - .zero() - .to_expr(), - }) - .cast_to_bits(), - ), - EnumTypeState::Unchanged => ExprEnum::EnumLiteral(ops::EnumLiteral::new_by_index( + ExprEnum::EnumLiteral(op) => { + let folded_variant_value = op.variant_value().map(|v| v.fold(self)).transpose()?; + Ok(*Expr::expr_enum(self.handle_enum_literal( op.ty(), op.variant_index(), - op.variant_value().map(|v| v.fold(self)).transpose()?, - )), - }), - ExprEnum::VariantAccess(op) => Ok( - match self.get_or_make_enum_type_state(Expr::ty(op.base()))? { - EnumTypeState::TagEnumAndBody(_) | EnumTypeState::TagUIntAndBody(_) => { - match op.variant_type() { - Some(variant_type) => *Expr::expr_enum( - Expr::>::from_canonical( - (*Expr::expr_enum(op.base())).fold(self)?.to_expr(), - ) - .body[..variant_type.bit_width()] - .cast_bits_to(variant_type), - ), - None => *Expr::expr_enum(().to_expr()), - } - } - EnumTypeState::UInt(_) => match op.variant_type() { - Some(variant_type) => { - let base_int = Expr::::from_canonical( - (*Expr::expr_enum(op.base())).fold(self)?.to_expr(), - ); - dbg!(base_int); - let base_ty = Expr::ty(op.base()); - let variant_type_bit_width = variant_type.bit_width(); - *Expr::expr_enum( - base_int[base_ty.discriminant_bit_width()..] - [..variant_type_bit_width] - .cast_bits_to(variant_type), - ) - } - None => *Expr::expr_enum(().to_expr()), - }, - EnumTypeState::Unchanged => match op.variant_type() { - Some(_) => ExprEnum::VariantAccess(ops::VariantAccess::new_by_index( - op.base().fold(self)?, - op.variant_index(), - )), - None => *Expr::expr_enum(().to_expr()), - }, - }, - ), + folded_variant_value, + )?)) + } + ExprEnum::VariantAccess(op) => { + let folded_base_expr = Expr::canonical(op.base()).fold(self)?; + Ok(*Expr::expr_enum(self.handle_variant_access( + Expr::ty(op.base()), + folded_base_expr, + op.variant_index(), + )?)) + } ExprEnum::MemPort(mem_port) => Ok( if let Some(&wire) = self.replacement_mem_ports.get(&mem_port) { ExprEnum::Wire(wire) @@ -424,11 +809,15 @@ impl Folder for State { if wire_ty == new_port_ty { continue; } - let wire_name = self.name_id_gen.gen( - (*format!("{}_{}", memory.scoped_name().1 .0, port.port_name())).intern(), - ); let wire = Wire::new_unchecked( - ScopedNameId(memory.scoped_name().0, wire_name), + self.module_state_stack + .last_mut() + .unwrap() + .gen_name(&format!( + "{}_{}", + memory.scoped_name().1 .0, + port.port_name() + )), port.source_location(), wire_ty, ); @@ -471,82 +860,50 @@ impl Folder for State { } fn fold_stmt(&mut self, stmt: Stmt) -> Result { - fn match_int_tag( - state: &mut State, - int_tag_expr: Expr, - source_location: SourceLocation, - blocks: Interned<[Block]>, - ) -> Result { - let mut blocks_iter = blocks.iter().copied().enumerate(); - let (_, last_block) = blocks_iter.next_back().unwrap_or_default(); - let Some((next_to_last_variant_index, next_to_last_block)) = blocks_iter.next_back() - else { - return Ok(StmtIf { - cond: true.to_expr(), - source_location, - blocks: [last_block.fold(state)?, Block::default()], - }); - }; - let mut retval = StmtIf { - cond: int_tag_expr - .cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(next_to_last_variant_index)), - source_location, - blocks: [next_to_last_block.fold(state)?, last_block.fold(state)?], - }; - for (variant_index, block) in blocks_iter.rev() { - retval = StmtIf { - cond: int_tag_expr - .cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(variant_index)), - source_location, - blocks: [ - block.fold(state)?, - Block { - memories: Default::default(), - stmts: [Stmt::from(retval)][..].intern(), - }, - ], - }; - } - Ok(retval) - } match stmt { Stmt::Match(StmtMatch { expr, source_location, blocks, - }) => match self.get_or_make_enum_type_state(Expr::ty(expr))? { - EnumTypeState::TagEnumAndBody(_) => Ok(StmtMatch { - expr: Expr::>::from_canonical( - Expr::canonical(expr).fold(self)?, - ) - .tag, - source_location, - blocks: blocks.fold(self)?, - } - .into()), - EnumTypeState::TagUIntAndBody(_) => { - let int_tag_expr = Expr::>::from_canonical( - Expr::canonical(expr).fold(self)?, - ) - .tag; - Ok(match_int_tag(self, int_tag_expr, source_location, blocks)?.into()) - } - EnumTypeState::UInt(_) => { - let int_tag_expr = - Expr::::from_canonical(Expr::canonical(expr).fold(self)?) - [..Expr::ty(expr).discriminant_bit_width()]; - Ok(match_int_tag(self, int_tag_expr, source_location, blocks)?.into()) - } - EnumTypeState::Unchanged => Ok(StmtMatch { - expr: expr.fold(self)?, - source_location, - blocks: blocks.fold(self)?, - } - .into()), - }, - Stmt::Connect(_) | Stmt::Formal(_) | Stmt::If(_) | Stmt::Declaration(_) => { - stmt.default_fold(self) + }) => { + let folded_expr = Expr::canonical(expr).fold(self)?; + let folded_blocks = blocks.fold(self)?; + self.handle_match(Expr::ty(expr), folded_expr, source_location, &folded_blocks) } + Stmt::Connect(StmtConnect { + lhs, + rhs, + source_location, + }) => { + let folded_lhs = lhs.fold(self)?; + let folded_rhs = rhs.fold(self)?; + let mut output_stmts = vec![]; + self.handle_stmt_connect( + Expr::ty(lhs), + Expr::ty(rhs), + folded_lhs, + folded_rhs, + source_location, + &mut output_stmts, + )?; + if output_stmts.len() == 1 { + Ok(output_stmts.pop().unwrap()) + } else { + Ok(StmtIf { + cond: true.to_expr(), + source_location, + blocks: [ + Block { + memories: Interned::default(), + stmts: Intern::intern_owned(output_stmts), + }, + Block::default(), + ], + } + .into()) + } + } + Stmt::Formal(_) | Stmt::If(_) | Stmt::Declaration(_) => stmt.default_fold(self), } } @@ -618,6 +975,6 @@ pub fn simplify_enums( enum_types: HashMap::new(), replacement_mem_ports: HashMap::new(), kind, - name_id_gen: NameIdGen::default(), + module_state_stack: vec![], }) } diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index cddf808..9d5a898 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -514,7 +514,6 @@ circuit check_enum_literals: type Ty1 = {tag: Ty0, body: UInt<8>} type Ty2 = {|A, B, C|} type Ty3 = {tag: Ty2, body: UInt<8>} - type Ty4 = {tag: Ty2, body: UInt<3>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty1 @[module-XXXXXXXXXX.rs 3:1] @@ -534,7 +533,7 @@ circuit check_enum_literals: connect _bundle_literal_expr_2.body, i connect o2, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: - wire _bundle_literal_expr_3: Ty4 + wire _bundle_literal_expr_3: Ty3 connect _bundle_literal_expr_3.tag, {|A, B, C|}(C) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) @@ -546,7 +545,7 @@ circuit check_enum_literals: connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) - connect _bundle_literal_expr_3.body, _cast_to_bits_expr + connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr, 8) connect o2, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 10:1] ", }; @@ -559,7 +558,6 @@ circuit check_enum_literals: circuit check_enum_literals: type Ty0 = {tag: UInt<1>, body: UInt<8>} type Ty1 = {tag: UInt<2>, body: UInt<8>} - type Ty2 = {tag: UInt<2>, body: UInt<3>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty0 @[module-XXXXXXXXXX.rs 3:1] @@ -579,7 +577,7 @@ circuit check_enum_literals: connect _bundle_literal_expr_2.body, i connect o2, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: - wire _bundle_literal_expr_3: Ty2 + wire _bundle_literal_expr_3: Ty1 connect _bundle_literal_expr_3.tag, UInt<2>(0h2) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) @@ -591,7 +589,7 @@ circuit check_enum_literals: connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) - connect _bundle_literal_expr_3.body, _cast_to_bits_expr + connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr, 8) connect o2, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 10:1] ", }; @@ -604,7 +602,6 @@ circuit check_enum_literals: circuit check_enum_literals: type Ty0 = {tag: UInt<1>, body: UInt<8>} type Ty1 = {tag: UInt<2>, body: UInt<8>} - type Ty2 = {tag: UInt<2>, body: UInt<3>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: UInt<9> @[module-XXXXXXXXXX.rs 3:1] @@ -639,7 +636,7 @@ circuit check_enum_literals: connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) connect o2, _cast_to_bits_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: - wire _bundle_literal_expr_3: Ty2 + wire _bundle_literal_expr_3: Ty1 connect _bundle_literal_expr_3.tag, UInt<2>(0h2) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) @@ -651,11 +648,11 @@ circuit check_enum_literals: connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr_3: UInt<3> connect _cast_to_bits_expr_3, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) - connect _bundle_literal_expr_3.body, _cast_to_bits_expr_3 - wire _cast_bundle_to_bits_expr_3: Ty2 + connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr_3, 8) + wire _cast_bundle_to_bits_expr_3: Ty1 connect _cast_bundle_to_bits_expr_3.tag, _bundle_literal_expr_3.tag connect _cast_bundle_to_bits_expr_3.body, _bundle_literal_expr_3.body - wire _cast_to_bits_expr_4: UInt<5> + wire _cast_to_bits_expr_4: UInt<10> connect _cast_to_bits_expr_4, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) connect o2, _cast_to_bits_expr_4 @[module-XXXXXXXXXX.rs 10:1] ", @@ -3245,48 +3242,25 @@ pub enum OneOfThree { #[hdl_module(outline_generated)] pub fn check_enum_connect_any() { #[hdl] - let index: UInt<2> = m.input(); + let swap: Bool = m.input(); #[hdl] - let i0: OneOfThree, HdlOption>, Bool> = m.input(); + let i1: OneOfThree, HdlOption>, HdlOption<()>> = m.input(); #[hdl] - let i1: OneOfThree, HdlOption>, Bool> = m.input(); + let i2: OneOfThree, HdlOption>, HdlOption<()>> = m.input(); #[hdl] - let i2: OneOfThree, HdlOption>, Bool> = m.input(); + let o1: OneOfThree, HdlOption>, HdlOption<()>> = m.output(); #[hdl] - let i3: OneOfThree, HdlOption>, Bool> = m.input(); + let o2: OneOfThree, HdlOption>, HdlOption<()>> = m.output(); #[hdl] - let o0: OneOfThree, HdlOption>, Bool> = m.output(); - #[hdl] - let o1: OneOfThree, HdlOption>, Bool> = m.output(); - #[hdl] - let o2: OneOfThree, HdlOption>, Bool> = m.output(); - #[hdl] - let o3: OneOfThree, HdlOption>, Bool> = m.output(); - #[hdl] - if index.cmp_eq(0u8) { - connect_any(o0, i0); + if swap { + connect_any(o1, i2); + connect_any(o2, i1); + } else { connect_any(o1, i1); connect_any(o2, i2); - connect_any(o3, i3); - } else if index.cmp_eq(1u8) { - connect_any(o0, i1); - connect_any(o1, i2); - connect_any(o2, i3); - connect_any(o3, i0); - } else if index.cmp_eq(2u8) { - connect_any(o0, i2); - connect_any(o1, i3); - connect_any(o2, i0); - connect_any(o3, i1); - } else { - connect_any(o0, i3); - connect_any(o1, i0); - connect_any(o2, i1); - connect_any(o3, i2); } } -#[cfg(todo)] #[test] fn test_enum_connect_any() { let _n = SourceLocation::normalize_files_for_tests(); @@ -3297,44 +3271,24 @@ fn test_enum_connect_any() { m => "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 circuit check_enum_connect_any: - type Ty0 = {|HdlNone, HdlSome: SInt<0>|} - type Ty1 = {|A: UInt<0>, B: Ty0, C: UInt<1>|} - type Ty2 = {|HdlNone, HdlSome: SInt<1>|} - type Ty3 = {|A: UInt<1>, B: Ty2, C: UInt<1>|} + type Ty0 = {|HdlNone, HdlSome: SInt<1>|} + type Ty1 = {} + type Ty2 = {|HdlNone, HdlSome: Ty1|} + type Ty3 = {|A: UInt<1>, B: Ty0, C: Ty2|} type Ty4 = {|HdlNone, HdlSome: SInt<2>|} - type Ty5 = {|A: UInt<2>, B: Ty4, C: UInt<1>|} - type Ty6 = {|HdlNone, HdlSome: SInt<3>|} - type Ty7 = {|A: UInt<3>, B: Ty6, C: UInt<1>|} + type Ty5 = {|A: UInt<2>, B: Ty4, C: Ty2|} module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] - input index: UInt<2> @[module-XXXXXXXXXX.rs 2:1] - input i0: Ty1 @[module-XXXXXXXXXX.rs 3:1] - input i1: Ty3 @[module-XXXXXXXXXX.rs 4:1] - input i2: Ty5 @[module-XXXXXXXXXX.rs 5:1] - input i3: Ty7 @[module-XXXXXXXXXX.rs 6:1] - output o0: Ty1 @[module-XXXXXXXXXX.rs 7:1] - output o1: Ty3 @[module-XXXXXXXXXX.rs 8:1] - output o2: Ty5 @[module-XXXXXXXXXX.rs 9:1] - output o3: Ty7 @[module-XXXXXXXXXX.rs 10:1] - when eq(index, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 11:1] - connect o0, i0 @[module-XXXXXXXXXX.rs 12:1] - connect o1, i1 @[module-XXXXXXXXXX.rs 13:1] - connect o2, i2 @[module-XXXXXXXXXX.rs 14:1] - connect o3, i3 @[module-XXXXXXXXXX.rs 15:1] - else when eq(index, UInt<8>(0h1)): @[module-XXXXXXXXXX.rs 16:1] - connect o0, i1 @[module-XXXXXXXXXX.rs 17:1] - connect o1, i2 @[module-XXXXXXXXXX.rs 18:1] - connect o2, i3 @[module-XXXXXXXXXX.rs 19:1] - connect o3, i0 @[module-XXXXXXXXXX.rs 20:1] - else when eq(index, UInt<8>(0h2)): @[module-XXXXXXXXXX.rs 21:1] - connect o0, i2 @[module-XXXXXXXXXX.rs 22:1] - connect o1, i3 @[module-XXXXXXXXXX.rs 23:1] - connect o2, i0 @[module-XXXXXXXXXX.rs 24:1] - connect o3, i1 @[module-XXXXXXXXXX.rs 25:1] + input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] + input i1: Ty3 @[module-XXXXXXXXXX.rs 3:1] + input i2: Ty5 @[module-XXXXXXXXXX.rs 4:1] + output o1: Ty3 @[module-XXXXXXXXXX.rs 5:1] + output o2: Ty5 @[module-XXXXXXXXXX.rs 6:1] + when swap: @[module-XXXXXXXXXX.rs 7:1] + connect o1, i2 @[module-XXXXXXXXXX.rs 8:1] + connect o2, i1 @[module-XXXXXXXXXX.rs 9:1] else: - connect o0, i3 @[module-XXXXXXXXXX.rs 26:1] - connect o1, i0 @[module-XXXXXXXXXX.rs 27:1] - connect o2, i1 @[module-XXXXXXXXXX.rs 28:1] - connect o3, i2 @[module-XXXXXXXXXX.rs 29:1] + connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] + connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] ", }; // FIXME: simplify_enums is broken when connecting enums that contain @@ -3347,20 +3301,487 @@ circuit check_enum_connect_any: #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => - "/test/check_enum_connect_any.fir": r"TODO", + "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 +circuit check_enum_connect_any: + type Ty0 = {|A, B, C|} + type Ty1 = {tag: Ty0, body: UInt<2>} + type Ty2 = {tag: Ty0, body: UInt<3>} + type Ty3 = {|HdlNone, HdlSome|} + type Ty4 = {tag: Ty3, body: UInt<1>} + type Ty5 = {tag: Ty3, body: UInt<2>} + type Ty6 = {tag: UInt<1>, body: UInt<2>} + type Ty7 = {tag: UInt<1>, body: UInt<1>} + type Ty8 = {tag: Ty3, body: UInt<0>} + type Ty9 = {tag: UInt<1>, body: UInt<0>} + module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] + input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] + input i1: Ty1 @[module-XXXXXXXXXX.rs 3:1] + input i2: Ty2 @[module-XXXXXXXXXX.rs 4:1] + output o1: Ty1 @[module-XXXXXXXXXX.rs 5:1] + output o2: Ty2 @[module-XXXXXXXXXX.rs 6:1] + when swap: @[module-XXXXXXXXXX.rs 7:1] + match i2.tag: @[module-XXXXXXXXXX.rs 8:1] + A: + wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] + connect __connect_variant_body, bits(i2.body, 1, 0) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr: Ty1 + connect _bundle_literal_expr.tag, {|A, B, C|}(A) + connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) + connect o1, _bundle_literal_expr @[module-XXXXXXXXXX.rs 8:1] + B: + wire __connect_variant_body_1: Ty4 @[module-XXXXXXXXXX.rs 8:1] + wire _cast_bits_to_bundle_expr: Ty5 + wire _cast_bits_to_bundle_expr_flattened: Ty6 + connect _cast_bits_to_bundle_expr_flattened.tag, bits(bits(i2.body, 2, 0), 0, 0) + wire _cast_bits_to_enum_expr: Ty3 + when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened.tag, 0)): + connect _cast_bits_to_enum_expr, {|HdlNone, HdlSome|}(HdlNone) + else: + connect _cast_bits_to_enum_expr, {|HdlNone, HdlSome|}(HdlSome) + connect _cast_bits_to_bundle_expr.tag, _cast_bits_to_enum_expr + connect _cast_bits_to_bundle_expr_flattened.body, bits(bits(i2.body, 2, 0), 2, 1) + connect _cast_bits_to_bundle_expr.body, _cast_bits_to_bundle_expr_flattened.body + match _cast_bits_to_bundle_expr.tag: @[module-XXXXXXXXXX.rs 8:1] + HdlNone: + wire _bundle_literal_expr_1: Ty4 + connect _bundle_literal_expr_1.tag, {|HdlNone, HdlSome|}(HdlNone) + connect _bundle_literal_expr_1.body, UInt<1>(0h0) + 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 __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_2: Ty4 + connect _bundle_literal_expr_2.tag, {|HdlNone, HdlSome|}(HdlSome) + connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) + connect __connect_variant_body_1, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_3: Ty1 + connect _bundle_literal_expr_3.tag, {|A, B, C|}(B) + wire _cast_bundle_to_bits_expr: Ty7 + wire _cast_enum_to_bits_expr: UInt<1> + match __connect_variant_body_1.tag: + HdlNone: + connect _cast_enum_to_bits_expr, UInt<1>(0) + HdlSome: + connect _cast_enum_to_bits_expr, UInt<1>(1) + connect _cast_bundle_to_bits_expr.tag, _cast_enum_to_bits_expr + connect _cast_bundle_to_bits_expr.body, __connect_variant_body_1.body + wire _cast_to_bits_expr: UInt<2> + connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) + connect _bundle_literal_expr_3.body, _cast_to_bits_expr + 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) + 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] + wire _bundle_literal_expr_4: Ty1 + connect _bundle_literal_expr_4.tag, {|A, B, C|}(C) + wire _cast_bundle_to_bits_expr_1: Ty9 + wire _cast_enum_to_bits_expr_1: UInt<1> + match __connect_variant_body_3.tag: + HdlNone: + connect _cast_enum_to_bits_expr_1, UInt<1>(0) + HdlSome: + connect _cast_enum_to_bits_expr_1, UInt<1>(1) + connect _cast_bundle_to_bits_expr_1.tag, _cast_enum_to_bits_expr_1 + connect _cast_bundle_to_bits_expr_1.body, __connect_variant_body_3.body + wire _cast_to_bits_expr_1: UInt<1> + connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) + connect _bundle_literal_expr_4.body, pad(_cast_to_bits_expr_1, 2) + connect o1, _bundle_literal_expr_4 @[module-XXXXXXXXXX.rs 8:1] + match i1.tag: @[module-XXXXXXXXXX.rs 9:1] + A: + wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] + connect __connect_variant_body_4, bits(i1.body, 0, 0) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_5: Ty2 + connect _bundle_literal_expr_5.tag, {|A, B, C|}(A) + connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) + 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) + 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] + HdlNone: + wire _bundle_literal_expr_6: Ty5 + connect _bundle_literal_expr_6.tag, {|HdlNone, HdlSome|}(HdlNone) + connect _bundle_literal_expr_6.body, UInt<2>(0h0) + 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 __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_7: Ty5 + connect _bundle_literal_expr_7.tag, {|HdlNone, HdlSome|}(HdlSome) + connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6) + connect __connect_variant_body_5, _bundle_literal_expr_7 @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_8: Ty2 + connect _bundle_literal_expr_8.tag, {|A, B, C|}(B) + wire _cast_bundle_to_bits_expr_2: Ty6 + wire _cast_enum_to_bits_expr_2: UInt<1> + match __connect_variant_body_5.tag: + HdlNone: + connect _cast_enum_to_bits_expr_2, UInt<1>(0) + HdlSome: + connect _cast_enum_to_bits_expr_2, UInt<1>(1) + connect _cast_bundle_to_bits_expr_2.tag, _cast_enum_to_bits_expr_2 + connect _cast_bundle_to_bits_expr_2.body, __connect_variant_body_5.body + wire _cast_to_bits_expr_2: UInt<3> + connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) + connect _bundle_literal_expr_8.body, _cast_to_bits_expr_2 + 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) + 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] + wire _bundle_literal_expr_9: Ty2 + connect _bundle_literal_expr_9.tag, {|A, B, C|}(C) + wire _cast_bundle_to_bits_expr_3: Ty9 + wire _cast_enum_to_bits_expr_3: UInt<1> + match __connect_variant_body_7.tag: + HdlNone: + connect _cast_enum_to_bits_expr_3, UInt<1>(0) + HdlSome: + connect _cast_enum_to_bits_expr_3, UInt<1>(1) + connect _cast_bundle_to_bits_expr_3.tag, _cast_enum_to_bits_expr_3 + connect _cast_bundle_to_bits_expr_3.body, __connect_variant_body_7.body + wire _cast_to_bits_expr_3: UInt<1> + connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) + connect _bundle_literal_expr_9.body, pad(_cast_to_bits_expr_3, 3) + connect o2, _bundle_literal_expr_9 @[module-XXXXXXXXXX.rs 9:1] + else: + connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] + connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] +", }; let m = simplify_enums(orig_m, SimplifyEnumsKind::ReplaceWithBundleOfUInts).unwrap(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => - "/test/check_enum_connect_any.fir": r"TODO", - }; + "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 +circuit check_enum_connect_any: + type Ty0 = {tag: UInt<2>, body: UInt<2>} + type Ty1 = {tag: UInt<2>, body: UInt<3>} + type Ty2 = {tag: UInt<1>, body: UInt<1>} + type Ty3 = {tag: UInt<1>, body: UInt<2>} + type Ty4 = {tag: UInt<1>, body: UInt<0>} + module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] + input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] + input i1: Ty0 @[module-XXXXXXXXXX.rs 3:1] + input i2: Ty1 @[module-XXXXXXXXXX.rs 4:1] + output o1: Ty0 @[module-XXXXXXXXXX.rs 5:1] + output o2: Ty1 @[module-XXXXXXXXXX.rs 6:1] + when swap: @[module-XXXXXXXXXX.rs 7:1] + when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 8:1] + wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] + connect __connect_variant_body, bits(i2.body, 1, 0) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr: Ty0 + connect _bundle_literal_expr.tag, UInt<2>(0h0) + connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) + connect o1, _bundle_literal_expr @[module-XXXXXXXXXX.rs 8:1] + else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 8:1] + wire __connect_variant_body_1: Ty2 @[module-XXXXXXXXXX.rs 8:1] + wire _cast_bits_to_bundle_expr: Ty3 + wire _cast_bits_to_bundle_expr_flattened: Ty3 + connect _cast_bits_to_bundle_expr_flattened.tag, bits(bits(i2.body, 2, 0), 0, 0) + connect _cast_bits_to_bundle_expr.tag, _cast_bits_to_bundle_expr_flattened.tag + connect _cast_bits_to_bundle_expr_flattened.body, bits(bits(i2.body, 2, 0), 2, 1) + connect _cast_bits_to_bundle_expr.body, _cast_bits_to_bundle_expr_flattened.body + when eq(_cast_bits_to_bundle_expr.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_1: Ty2 + connect _bundle_literal_expr_1.tag, UInt<1>(0h0) + connect _bundle_literal_expr_1.body, UInt<1>(0h0) + 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 __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_2: Ty2 + connect _bundle_literal_expr_2.tag, UInt<1>(0h1) + connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) + connect __connect_variant_body_1, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_3: Ty0 + connect _bundle_literal_expr_3.tag, UInt<2>(0h1) + wire _cast_bundle_to_bits_expr: Ty2 + connect _cast_bundle_to_bits_expr.tag, __connect_variant_body_1.tag + connect _cast_bundle_to_bits_expr.body, __connect_variant_body_1.body + wire _cast_to_bits_expr: UInt<2> + connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) + connect _bundle_literal_expr_3.body, _cast_to_bits_expr + 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 _bundle_literal_expr_4: Ty0 + connect _bundle_literal_expr_4.tag, UInt<2>(0h2) + wire _cast_bundle_to_bits_expr_1: Ty4 + connect _cast_bundle_to_bits_expr_1.tag, __connect_variant_body_3.tag + connect _cast_bundle_to_bits_expr_1.body, __connect_variant_body_3.body + wire _cast_to_bits_expr_1: UInt<1> + connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) + connect _bundle_literal_expr_4.body, pad(_cast_to_bits_expr_1, 2) + connect o1, _bundle_literal_expr_4 @[module-XXXXXXXXXX.rs 8:1] + when eq(i1.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 9:1] + wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] + connect __connect_variant_body_4, bits(i1.body, 0, 0) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_5: Ty1 + connect _bundle_literal_expr_5.tag, UInt<2>(0h0) + connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) + 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 _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 __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_7: Ty3 + connect _bundle_literal_expr_7.tag, UInt<1>(0h1) + connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6) + connect __connect_variant_body_5, _bundle_literal_expr_7 @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_8: Ty1 + connect _bundle_literal_expr_8.tag, UInt<2>(0h1) + wire _cast_bundle_to_bits_expr_2: Ty3 + connect _cast_bundle_to_bits_expr_2.tag, __connect_variant_body_5.tag + connect _cast_bundle_to_bits_expr_2.body, __connect_variant_body_5.body + wire _cast_to_bits_expr_2: UInt<3> + connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) + connect _bundle_literal_expr_8.body, _cast_to_bits_expr_2 + 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 _bundle_literal_expr_9: Ty1 + connect _bundle_literal_expr_9.tag, UInt<2>(0h2) + wire _cast_bundle_to_bits_expr_3: Ty4 + connect _cast_bundle_to_bits_expr_3.tag, __connect_variant_body_7.tag + connect _cast_bundle_to_bits_expr_3.body, __connect_variant_body_7.body + wire _cast_to_bits_expr_3: UInt<1> + connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) + connect _bundle_literal_expr_9.body, pad(_cast_to_bits_expr_3, 3) + connect o2, _bundle_literal_expr_9 @[module-XXXXXXXXXX.rs 9:1] + else: + connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] + connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] +", + } let m = simplify_enums(orig_m, SimplifyEnumsKind::ReplaceWithUInt).unwrap(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => - "/test/check_enum_connect_any.fir": r"TODO", + "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 +circuit check_enum_connect_any: + type Ty0 = {tag: UInt<2>, body: UInt<2>} + type Ty1 = {tag: UInt<1>, body: UInt<1>} + type Ty2 = {tag: UInt<2>, body: UInt<3>} + type Ty3 = {tag: UInt<1>, body: UInt<2>} + module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] + input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] + input i1: UInt<4> @[module-XXXXXXXXXX.rs 3:1] + input i2: UInt<5> @[module-XXXXXXXXXX.rs 4:1] + output o1: UInt<4> @[module-XXXXXXXXXX.rs 5:1] + output o2: UInt<5> @[module-XXXXXXXXXX.rs 6:1] + when swap: @[module-XXXXXXXXXX.rs 7:1] + when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 8:1] + wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] + connect __connect_variant_body, bits(bits(i2, 4, 2), 1, 0) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr: Ty0 + connect _bundle_literal_expr.tag, UInt<2>(0h0) + connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) + wire _cast_bundle_to_bits_expr: Ty0 + connect _cast_bundle_to_bits_expr.tag, _bundle_literal_expr.tag + connect _cast_bundle_to_bits_expr.body, _bundle_literal_expr.body + wire _cast_to_bits_expr: UInt<4> + connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) + connect o1, _cast_to_bits_expr @[module-XXXXXXXXXX.rs 8:1] + else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 8:1] + wire __connect_variant_body_1: UInt<2> @[module-XXXXXXXXXX.rs 8:1] + when eq(bits(bits(bits(i2, 4, 2), 2, 0), 0, 0), UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_1: Ty1 + connect _bundle_literal_expr_1.tag, UInt<1>(0h0) + connect _bundle_literal_expr_1.body, UInt<1>(0h0) + wire _cast_bundle_to_bits_expr_1: Ty1 + connect _cast_bundle_to_bits_expr_1.tag, _bundle_literal_expr_1.tag + connect _cast_bundle_to_bits_expr_1.body, _bundle_literal_expr_1.body + wire _cast_to_bits_expr_1: UInt<2> + connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) + connect __connect_variant_body_1, _cast_to_bits_expr_1 @[module-XXXXXXXXXX.rs 8:1] + else: + wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1] + connect __connect_variant_body_2, asSInt(bits(bits(bits(bits(i2, 4, 2), 2, 0), 2, 1), 1, 0)) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_2: Ty1 + connect _bundle_literal_expr_2.tag, UInt<1>(0h1) + connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) + wire _cast_bundle_to_bits_expr_2: Ty1 + connect _cast_bundle_to_bits_expr_2.tag, _bundle_literal_expr_2.tag + connect _cast_bundle_to_bits_expr_2.body, _bundle_literal_expr_2.body + wire _cast_to_bits_expr_2: UInt<2> + connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) + connect __connect_variant_body_1, _cast_to_bits_expr_2 @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_3: Ty0 + connect _bundle_literal_expr_3.tag, UInt<2>(0h1) + connect _bundle_literal_expr_3.body, __connect_variant_body_1 + wire _cast_bundle_to_bits_expr_3: Ty0 + connect _cast_bundle_to_bits_expr_3.tag, _bundle_literal_expr_3.tag + connect _cast_bundle_to_bits_expr_3.body, _bundle_literal_expr_3.body + wire _cast_to_bits_expr_3: UInt<4> + connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) + connect o1, _cast_to_bits_expr_3 @[module-XXXXXXXXXX.rs 8:1] + else: + wire __connect_variant_body_3: UInt<1> @[module-XXXXXXXXXX.rs 8:1] + connect __connect_variant_body_3, bits(bits(i2, 4, 2), 0, 0) @[module-XXXXXXXXXX.rs 8:1] + wire _bundle_literal_expr_4: Ty0 + connect _bundle_literal_expr_4.tag, UInt<2>(0h2) + connect _bundle_literal_expr_4.body, pad(__connect_variant_body_3, 2) + wire _cast_bundle_to_bits_expr_4: Ty0 + connect _cast_bundle_to_bits_expr_4.tag, _bundle_literal_expr_4.tag + connect _cast_bundle_to_bits_expr_4.body, _bundle_literal_expr_4.body + wire _cast_to_bits_expr_4: UInt<4> + connect _cast_to_bits_expr_4, cat(_cast_bundle_to_bits_expr_4.body, _cast_bundle_to_bits_expr_4.tag) + connect o1, _cast_to_bits_expr_4 @[module-XXXXXXXXXX.rs 8:1] + when eq(bits(i1, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 9:1] + wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] + connect __connect_variant_body_4, bits(bits(i1, 3, 2), 0, 0) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_5: Ty2 + connect _bundle_literal_expr_5.tag, UInt<2>(0h0) + connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) + wire _cast_bundle_to_bits_expr_5: Ty2 + connect _cast_bundle_to_bits_expr_5.tag, _bundle_literal_expr_5.tag + connect _cast_bundle_to_bits_expr_5.body, _bundle_literal_expr_5.body + wire _cast_to_bits_expr_5: UInt<5> + connect _cast_to_bits_expr_5, cat(_cast_bundle_to_bits_expr_5.body, _cast_bundle_to_bits_expr_5.tag) + connect o2, _cast_to_bits_expr_5 @[module-XXXXXXXXXX.rs 9:1] + else when eq(bits(i1, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 9:1] + wire __connect_variant_body_5: UInt<3> @[module-XXXXXXXXXX.rs 9:1] + when eq(bits(bits(bits(i1, 3, 2), 1, 0), 0, 0), 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) + wire _cast_bundle_to_bits_expr_6: Ty3 + connect _cast_bundle_to_bits_expr_6.tag, _bundle_literal_expr_6.tag + connect _cast_bundle_to_bits_expr_6.body, _bundle_literal_expr_6.body + wire _cast_to_bits_expr_6: UInt<3> + connect _cast_to_bits_expr_6, cat(_cast_bundle_to_bits_expr_6.body, _cast_bundle_to_bits_expr_6.tag) + connect __connect_variant_body_5, _cast_to_bits_expr_6 @[module-XXXXXXXXXX.rs 9:1] + else: + wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1] + connect __connect_variant_body_6, asSInt(bits(bits(bits(bits(i1, 3, 2), 1, 0), 1, 1), 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) + wire _cast_bundle_to_bits_expr_7: Ty3 + connect _cast_bundle_to_bits_expr_7.tag, _bundle_literal_expr_7.tag + connect _cast_bundle_to_bits_expr_7.body, _bundle_literal_expr_7.body + wire _cast_to_bits_expr_7: UInt<3> + connect _cast_to_bits_expr_7, cat(_cast_bundle_to_bits_expr_7.body, _cast_bundle_to_bits_expr_7.tag) + connect __connect_variant_body_5, _cast_to_bits_expr_7 @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_8: Ty2 + connect _bundle_literal_expr_8.tag, UInt<2>(0h1) + connect _bundle_literal_expr_8.body, __connect_variant_body_5 + wire _cast_bundle_to_bits_expr_8: Ty2 + connect _cast_bundle_to_bits_expr_8.tag, _bundle_literal_expr_8.tag + connect _cast_bundle_to_bits_expr_8.body, _bundle_literal_expr_8.body + wire _cast_to_bits_expr_8: UInt<5> + connect _cast_to_bits_expr_8, cat(_cast_bundle_to_bits_expr_8.body, _cast_bundle_to_bits_expr_8.tag) + connect o2, _cast_to_bits_expr_8 @[module-XXXXXXXXXX.rs 9:1] + else: + wire __connect_variant_body_7: UInt<1> @[module-XXXXXXXXXX.rs 9:1] + connect __connect_variant_body_7, bits(bits(i1, 3, 2), 0, 0) @[module-XXXXXXXXXX.rs 9:1] + wire _bundle_literal_expr_9: Ty2 + connect _bundle_literal_expr_9.tag, UInt<2>(0h2) + connect _bundle_literal_expr_9.body, pad(__connect_variant_body_7, 3) + wire _cast_bundle_to_bits_expr_9: Ty2 + connect _cast_bundle_to_bits_expr_9.tag, _bundle_literal_expr_9.tag + connect _cast_bundle_to_bits_expr_9.body, _bundle_literal_expr_9.body + wire _cast_to_bits_expr_9: UInt<5> + connect _cast_to_bits_expr_9, cat(_cast_bundle_to_bits_expr_9.body, _cast_bundle_to_bits_expr_9.tag) + connect o2, _cast_to_bits_expr_9 @[module-XXXXXXXXXX.rs 9:1] + else: + connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] + connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] +", }; }