forked from libre-chip/fayalite
		
	add ty.uninit()
This commit is contained in:
		
							parent
							
								
									8449854cac
								
							
						
					
					
						commit
						9ad4ec0f39
					
				
					 7 changed files with 119 additions and 1 deletions
				
			
		|  | @ -111,6 +111,7 @@ expr_enum! { | |||
|         BundleLiteral(ops::BundleLiteral), | ||||
|         ArrayLiteral(ops::ArrayLiteral<CanonicalType, DynSize>), | ||||
|         EnumLiteral(ops::EnumLiteral), | ||||
|         Uninit(ops::Uninit), | ||||
|         NotU(ops::NotU), | ||||
|         NotS(ops::NotS), | ||||
|         NotB(ops::NotB), | ||||
|  | @ -697,3 +698,13 @@ pub fn check_match_expr<T: Type>( | |||
|     _check_fn: impl FnOnce(T::MatchVariant, Infallible), | ||||
| ) { | ||||
| } | ||||
| 
 | ||||
| pub trait MakeUninitExpr: Type { | ||||
|     fn uninit(self) -> Expr<Self>; | ||||
| } | ||||
| 
 | ||||
| impl<T: Type> MakeUninitExpr for T { | ||||
|     fn uninit(self) -> Expr<Self> { | ||||
|         ops::Uninit::new(self).to_expr() | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2529,3 +2529,41 @@ impl<T: Type> ToExpr for CastBitsTo<T> { | |||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||||
| pub struct Uninit<T: Type = CanonicalType> { | ||||
|     ty: T, | ||||
| } | ||||
| 
 | ||||
| impl<T: Type> Uninit<T> { | ||||
|     #[track_caller] | ||||
|     pub fn new(ty: T) -> Self { | ||||
|         Self { ty } | ||||
|     } | ||||
|     pub fn ty(self) -> T { | ||||
|         self.ty | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: Type> ToLiteralBits for Uninit<T> { | ||||
|     fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> { | ||||
|         Err(NotALiteralExpr) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl_get_target_none!([T: Type] Uninit<T>); | ||||
| 
 | ||||
| impl<T: Type> ToExpr for Uninit<T> { | ||||
|     type Type = T; | ||||
| 
 | ||||
|     fn to_expr(&self) -> Expr<Self::Type> { | ||||
|         Expr { | ||||
|             __enum: ExprEnum::Uninit(Uninit { | ||||
|                 ty: self.ty.canonical(), | ||||
|             }) | ||||
|             .intern(), | ||||
|             __ty: self.ty, | ||||
|             __flow: Flow::Source, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -912,6 +912,20 @@ impl<'a> Exporter<'a> { | |||
|         } | ||||
|         ident.to_string() | ||||
|     } | ||||
|     fn uninit_expr( | ||||
|         &mut self, | ||||
|         expr: ops::Uninit, | ||||
|         definitions: &RcDefinitions, | ||||
|         const_ty: bool, | ||||
|     ) -> String { | ||||
|         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}")); | ||||
|         ident.to_string() | ||||
|     } | ||||
|     fn enum_literal_expr( | ||||
|         &mut self, | ||||
|         expr: ops::EnumLiteral<Enum>, | ||||
|  | @ -1367,6 +1381,7 @@ impl<'a> Exporter<'a> { | |||
|             ExprEnum::EnumLiteral(enum_literal) => { | ||||
|                 self.enum_literal_expr(enum_literal, definitions, const_ty) | ||||
|             } | ||||
|             ExprEnum::Uninit(uninit) => self.uninit_expr(uninit, definitions, const_ty), | ||||
|             ExprEnum::NotU(expr) => self.expr_unary("not", expr.arg(), definitions, const_ty), | ||||
|             ExprEnum::NotS(expr) => self.expr_unary("not", expr.arg(), definitions, const_ty), | ||||
|             ExprEnum::NotB(expr) => self.expr_unary("not", expr.arg(), definitions, const_ty), | ||||
|  |  | |||
|  | @ -287,6 +287,7 @@ impl Folder for State { | |||
|             | ExprEnum::BoolLiteral(_) | ||||
|             | ExprEnum::BundleLiteral(_) | ||||
|             | ExprEnum::ArrayLiteral(_) | ||||
|             | ExprEnum::Uninit(_) | ||||
|             | ExprEnum::NotU(_) | ||||
|             | ExprEnum::NotS(_) | ||||
|             | ExprEnum::NotB(_) | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ pub use crate::{ | |||
|     cli::Cli, | ||||
|     clock::{Clock, ClockDomain, ToClock}, | ||||
|     enum_::{HdlNone, HdlOption, HdlSome}, | ||||
|     expr::{CastBitsTo, CastTo, CastToBits, Expr, ReduceBits, ToExpr}, | ||||
|     expr::{CastBitsTo, CastTo, CastToBits, Expr, MakeUninitExpr, ReduceBits, ToExpr}, | ||||
|     hdl, hdl_module, | ||||
|     int::{Bool, DynSize, IntCmp, KnownSize, SInt, SIntType, Size, UInt, UIntType}, | ||||
|     memory::{Mem, MemBuilder, ReadUnderWrite}, | ||||
|  |  | |||
|  | @ -3139,3 +3139,46 @@ circuit check_annotations: %[[ | |||
| "#,
 | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #[hdl_module(outline_generated)] | ||||
| pub fn check_uninit<T: Type>(ty: T) { | ||||
|     #[hdl] | ||||
|     let o: T = m.output(ty); | ||||
|     connect(o, ty.uninit()); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_uninit() { | ||||
|     let _n = SourceLocation::normalize_files_for_tests(); | ||||
|     let m = check_uninit((UInt[3], SInt[5], Clock)); | ||||
|     dbg!(m); | ||||
|     #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
 | ||||
|     assert_export_firrtl! { | ||||
|         m => | ||||
|         "/test/check_uninit.fir": r"FIRRTL version 3.2.0
 | ||||
| circuit check_uninit: | ||||
|     type Ty0 = {`0`: UInt<3>, `1`: SInt<5>, `2`: Clock} | ||||
|     module check_uninit: @[module-XXXXXXXXXX.rs 1:1] | ||||
|         output o: Ty0 @[module-XXXXXXXXXX.rs 2:1] | ||||
|         wire _uninit_expr: Ty0 | ||||
|         invalidate _uninit_expr | ||||
|         connect o, _uninit_expr @[module-XXXXXXXXXX.rs 3:1] | ||||
| ",
 | ||||
|     }; | ||||
|     let m = check_uninit(Array[HdlOption[()]][3]); | ||||
|     dbg!(m); | ||||
|     #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
 | ||||
|     assert_export_firrtl! { | ||||
|         m => | ||||
|         "/test/check_uninit_1.fir": r"FIRRTL version 3.2.0
 | ||||
| circuit check_uninit_1: | ||||
|     type Ty0 = {} | ||||
|     type Ty1 = {|HdlNone, HdlSome: Ty0|} | ||||
|     module check_uninit_1: @[module-XXXXXXXXXX.rs 1:1] | ||||
|         output o: Ty1[3] @[module-XXXXXXXXXX.rs 2:1] | ||||
|         wire _uninit_expr: Ty1[3] | ||||
|         invalidate _uninit_expr | ||||
|         connect o, _uninit_expr @[module-XXXXXXXXXX.rs 3:1] | ||||
| ",
 | ||||
|     }; | ||||
| } | ||||
|  |  | |||
|  | @ -283,6 +283,16 @@ | |||
|             "fold_where": "T: Fold<State>", | ||||
|             "visit_where": "T: Visit<State>" | ||||
|         }, | ||||
|         "ops::Uninit": { | ||||
|             "data": { | ||||
|                 "$kind": "Struct", | ||||
|                 "$constructor": "ops::Uninit::new", | ||||
|                 "ty()": "Visible" | ||||
|             }, | ||||
|             "generics": "<T: Type>", | ||||
|             "fold_where": "T: Fold<State>", | ||||
|             "visit_where": "T: Visit<State>" | ||||
|         }, | ||||
|         "ops::NotU": { | ||||
|             "data": { | ||||
|                 "$kind": "Struct", | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue