Compare commits
	
		
			3 commits
		
	
	
		
			d089095667
			...
			d0b406d288
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d0b406d288 | |||
| 2a25dd9d7b | |||
| 6e0b6c000d | 
					 7 changed files with 191 additions and 26 deletions
				
			
		|  | @ -118,10 +118,35 @@ pub struct CustomFirrtlAnnotation { | ||||||
|     pub additional_fields: CustomFirrtlAnnotationFields, |     pub additional_fields: CustomFirrtlAnnotationFields, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] | ||||||
|  | pub struct SVAttributeAnnotation { | ||||||
|  |     pub text: Interned<str>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] | ||||||
|  | pub struct BlackBoxInlineAnnotation { | ||||||
|  |     pub path: Interned<str>, | ||||||
|  |     pub text: Interned<str>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] | ||||||
|  | pub struct BlackBoxPathAnnotation { | ||||||
|  |     pub path: Interned<str>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] | ||||||
|  | pub struct DocStringAnnotation { | ||||||
|  |     pub text: Interned<str>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Clone, PartialEq, Eq, Hash, Debug)] | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | ||||||
| #[non_exhaustive] | #[non_exhaustive] | ||||||
| pub enum Annotation { | pub enum Annotation { | ||||||
|     DontTouch, |     DontTouch, | ||||||
|  |     SVAttribute(SVAttributeAnnotation), | ||||||
|  |     BlackBoxInline(BlackBoxInlineAnnotation), | ||||||
|  |     BlackBoxPath(BlackBoxPathAnnotation), | ||||||
|  |     DocString(DocStringAnnotation), | ||||||
|     CustomFirrtl(CustomFirrtlAnnotation), |     CustomFirrtl(CustomFirrtlAnnotation), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,10 @@ | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| #![allow(clippy::type_complexity)] | #![allow(clippy::type_complexity)] | ||||||
| use crate::{ | use crate::{ | ||||||
|     annotations::CustomFirrtlAnnotation, |     annotations::{ | ||||||
|  |         Annotation, BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation, | ||||||
|  |         DocStringAnnotation, SVAttributeAnnotation, | ||||||
|  |     }, | ||||||
|     array::Array, |     array::Array, | ||||||
|     bundle::{Bundle, BundleField, BundleType}, |     bundle::{Bundle, BundleField, BundleType}, | ||||||
|     clock::Clock, |     clock::Clock, | ||||||
|  | @ -665,6 +668,17 @@ enum AnnotationData { | ||||||
|     }, |     }, | ||||||
|     #[serde(rename = "firrtl.transforms.DontTouchAnnotation")] |     #[serde(rename = "firrtl.transforms.DontTouchAnnotation")] | ||||||
|     DontTouch, |     DontTouch, | ||||||
|  |     #[serde(rename = "firrtl.AttributeAnnotation")] | ||||||
|  |     AttributeAnnotation { description: Interned<str> }, | ||||||
|  |     #[serde(rename = "firrtl.transforms.BlackBoxInlineAnno")] | ||||||
|  |     BlackBoxInlineAnno { | ||||||
|  |         name: Interned<str>, | ||||||
|  |         text: Interned<str>, | ||||||
|  |     }, | ||||||
|  |     #[serde(rename = "firrtl.transforms.BlackBoxPathAnno")] | ||||||
|  |     BlackBoxPathAnno { path: Interned<str> }, | ||||||
|  |     #[serde(rename = "firrtl.DocStringAnnotation")] | ||||||
|  |     DocStringAnnotation { description: Interned<str> }, | ||||||
|     #[allow(dead_code)] |     #[allow(dead_code)] | ||||||
|     #[serde(untagged)] |     #[serde(untagged)] | ||||||
|     Other { |     Other { | ||||||
|  | @ -675,7 +689,7 @@ enum AnnotationData { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Serialize)] | #[derive(Serialize)] | ||||||
| struct Annotation { | struct FirrtlAnnotation { | ||||||
|     #[serde(flatten)] |     #[serde(flatten)] | ||||||
|     data: AnnotationData, |     data: AnnotationData, | ||||||
|     target: AnnotationTarget, |     target: AnnotationTarget, | ||||||
|  | @ -690,7 +704,7 @@ struct Exporter<'a> { | ||||||
|     module: ModuleState, |     module: ModuleState, | ||||||
|     type_state: TypeState, |     type_state: TypeState, | ||||||
|     circuit_name: Ident, |     circuit_name: Ident, | ||||||
|     annotations: Vec<Annotation>, |     annotations: Vec<FirrtlAnnotation>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct PushIndent<'a> { | struct PushIndent<'a> { | ||||||
|  | @ -1770,7 +1784,7 @@ impl<'a> Exporter<'a> { | ||||||
|             memory_name.0.to_string(), |             memory_name.0.to_string(), | ||||||
|             contents, |             contents, | ||||||
|         )?; |         )?; | ||||||
|         self.annotations.push(Annotation { |         self.annotations.push(FirrtlAnnotation { | ||||||
|             data: AnnotationData::MemoryFileInline { |             data: AnnotationData::MemoryFileInline { | ||||||
|                 filename, |                 filename, | ||||||
|                 hex_or_binary, |                 hex_or_binary, | ||||||
|  | @ -1789,14 +1803,25 @@ impl<'a> Exporter<'a> { | ||||||
|         }); |         }); | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn annotation( |     fn annotation(&mut self, path: AnnotationTargetPath, annotation: &Annotation) { | ||||||
|         &mut self, |  | ||||||
|         path: AnnotationTargetPath, |  | ||||||
|         annotation: &crate::annotations::Annotation, |  | ||||||
|     ) { |  | ||||||
|         let data = match annotation { |         let data = match annotation { | ||||||
|             crate::annotations::Annotation::DontTouch => AnnotationData::DontTouch, |             Annotation::DontTouch => AnnotationData::DontTouch, | ||||||
|             crate::annotations::Annotation::CustomFirrtl(CustomFirrtlAnnotation { |             Annotation::SVAttribute(SVAttributeAnnotation { text }) => { | ||||||
|  |                 AnnotationData::AttributeAnnotation { description: *text } | ||||||
|  |             } | ||||||
|  |             Annotation::BlackBoxInline(BlackBoxInlineAnnotation { path, text }) => { | ||||||
|  |                 AnnotationData::BlackBoxInlineAnno { | ||||||
|  |                     name: *path, | ||||||
|  |                     text: *text, | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             Annotation::BlackBoxPath(BlackBoxPathAnnotation { path }) => { | ||||||
|  |                 AnnotationData::BlackBoxPathAnno { path: *path } | ||||||
|  |             } | ||||||
|  |             Annotation::DocString(DocStringAnnotation { text }) => { | ||||||
|  |                 AnnotationData::DocStringAnnotation { description: *text } | ||||||
|  |             } | ||||||
|  |             Annotation::CustomFirrtl(CustomFirrtlAnnotation { | ||||||
|                 class, |                 class, | ||||||
|                 additional_fields, |                 additional_fields, | ||||||
|             }) => AnnotationData::Other { |             }) => AnnotationData::Other { | ||||||
|  | @ -1804,7 +1829,7 @@ impl<'a> Exporter<'a> { | ||||||
|                 additional_fields: (*additional_fields).into(), |                 additional_fields: (*additional_fields).into(), | ||||||
|             }, |             }, | ||||||
|         }; |         }; | ||||||
|         self.annotations.push(Annotation { |         self.annotations.push(FirrtlAnnotation { | ||||||
|             data, |             data, | ||||||
|             target: AnnotationTarget { |             target: AnnotationTarget { | ||||||
|                 circuit: self.circuit_name, |                 circuit: self.circuit_name, | ||||||
|  |  | ||||||
|  | @ -2272,7 +2272,8 @@ pub fn annotate<T: Type>(target: Expr<T>, annotations: impl IntoAnnotations) { | ||||||
|             .body |             .body | ||||||
|             .annotations_map |             .annotations_map | ||||||
|             .entry(decl) |             .entry(decl) | ||||||
|             .or_default(); |             .or_default() | ||||||
|  |             .extend(annotations); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -483,14 +483,6 @@ impl State { | ||||||
|             ); |             ); | ||||||
|             return Ok(()); |             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 { |         match unfolded_lhs_ty { | ||||||
|             CanonicalType::Array(unfolded_lhs_ty) => self.handle_stmt_connect_array( |             CanonicalType::Array(unfolded_lhs_ty) => self.handle_stmt_connect_array( | ||||||
|                 unfolded_lhs_ty, |                 unfolded_lhs_ty, | ||||||
|  | @ -535,11 +527,11 @@ fn connect_port( | ||||||
| ) { | ) { | ||||||
|     if Expr::ty(lhs) == Expr::ty(rhs) { |     if Expr::ty(lhs) == Expr::ty(rhs) { | ||||||
|         stmts.push( |         stmts.push( | ||||||
|             dbg!(StmtConnect { |             StmtConnect { | ||||||
|                 lhs, |                 lhs, | ||||||
|                 rhs, |                 rhs, | ||||||
|                 source_location, |                 source_location, | ||||||
|             }) |             } | ||||||
|             .into(), |             .into(), | ||||||
|         ); |         ); | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|  | @ -2,7 +2,10 @@ | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| #![allow(clippy::multiple_bound_locations)] | #![allow(clippy::multiple_bound_locations)] | ||||||
| use crate::{ | use crate::{ | ||||||
|     annotations::{Annotation, CustomFirrtlAnnotation, TargetedAnnotation}, |     annotations::{ | ||||||
|  |         Annotation, BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation, | ||||||
|  |         DocStringAnnotation, SVAttributeAnnotation, TargetedAnnotation, | ||||||
|  |     }, | ||||||
|     array::ArrayType, |     array::ArrayType, | ||||||
|     bundle::{Bundle, BundleField, BundleType}, |     bundle::{Bundle, BundleField, BundleType}, | ||||||
|     clock::Clock, |     clock::Clock, | ||||||
|  |  | ||||||
|  | @ -1,8 +1,15 @@ | ||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later
 | // SPDX-License-Identifier: LGPL-3.0-or-later
 | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| use fayalite::{ | use fayalite::{ | ||||||
|     annotations::CustomFirrtlAnnotation, assert_export_firrtl, firrtl::ExportOptions, |     annotations::{ | ||||||
|     intern::Intern, module::transform::simplify_enums::SimplifyEnumsKind, prelude::*, |         BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation, | ||||||
|  |         DocStringAnnotation, SVAttributeAnnotation, | ||||||
|  |     }, | ||||||
|  |     assert_export_firrtl, | ||||||
|  |     firrtl::ExportOptions, | ||||||
|  |     intern::Intern, | ||||||
|  |     module::transform::simplify_enums::SimplifyEnumsKind, | ||||||
|  |     prelude::*, | ||||||
|     ty::StaticType, |     ty::StaticType, | ||||||
| }; | }; | ||||||
| use serde_json::json; | use serde_json::json; | ||||||
|  | @ -3058,6 +3065,14 @@ pub fn check_annotations() { | ||||||
|         .try_into() |         .try_into() | ||||||
|         .unwrap(), |         .unwrap(), | ||||||
|     })); |     })); | ||||||
|  |     m.annotate_module(Annotation::DocString(DocStringAnnotation { | ||||||
|  |         text: r"This module is used as a test that fayalite's firrtl
 | ||||||
|  | backend properly emits annotations. | ||||||
|  | 
 | ||||||
|  | Testing... | ||||||
|  | " | ||||||
|  |         .intern(), | ||||||
|  |     })); | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     let raddr: UInt<8> = m.input(); |     let raddr: UInt<8> = m.input(); | ||||||
|     annotate(raddr, Annotation::DontTouch); |     annotate(raddr, Annotation::DontTouch); | ||||||
|  | @ -3139,6 +3154,40 @@ pub fn check_annotations() { | ||||||
|     connect(write_port.clk, clk); |     connect(write_port.clk, clk); | ||||||
|     connect(write_port.data, wdata); |     connect(write_port.data, wdata); | ||||||
|     connect(write_port.mask, wmask); |     connect(write_port.mask, wmask); | ||||||
|  |     #[hdl_module(extern)] | ||||||
|  |     fn black_box1() { | ||||||
|  |         m.verilog_name("BlackBox1"); | ||||||
|  |         m.annotate_module(Annotation::BlackBoxInline(BlackBoxInlineAnnotation { | ||||||
|  |             path: "black_box1.v".intern(), | ||||||
|  |             text: r"(* blackbox *)
 | ||||||
|  | module BlackBox1(); | ||||||
|  | endmodule | ||||||
|  | " | ||||||
|  |             .intern(), | ||||||
|  |         })); | ||||||
|  |     } | ||||||
|  |     #[hdl] | ||||||
|  |     let black_box1_instance = instance(black_box1()); | ||||||
|  |     annotate(black_box1_instance, Annotation::DontTouch); | ||||||
|  |     #[hdl_module(extern)] | ||||||
|  |     fn black_box2() { | ||||||
|  |         m.verilog_name("BlackBox2"); | ||||||
|  |         m.annotate_module(Annotation::BlackBoxPath(BlackBoxPathAnnotation { | ||||||
|  |             path: "black_box2.v".intern(), | ||||||
|  |         })); | ||||||
|  |     } | ||||||
|  |     #[hdl] | ||||||
|  |     let black_box2_instance = instance(black_box2()); | ||||||
|  |     annotate(black_box2_instance, Annotation::DontTouch); | ||||||
|  |     #[hdl] | ||||||
|  |     let a_wire: (SInt<1>, Bool) = wire(); | ||||||
|  |     annotate( | ||||||
|  |         a_wire.1, | ||||||
|  |         Annotation::SVAttribute(SVAttributeAnnotation { | ||||||
|  |             text: "custom_sv_attr = \"abc\"".intern(), | ||||||
|  |         }), | ||||||
|  |     ); | ||||||
|  |     connect(a_wire, (0_hdl_i1, false)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
|  | @ -3156,6 +3205,11 @@ circuit check_annotations: %[[ | ||||||
|     "bar": "a nice module!", |     "bar": "a nice module!", | ||||||
|     "target": "~check_annotations|check_annotations" |     "target": "~check_annotations|check_annotations" | ||||||
|   }, |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.DocStringAnnotation", | ||||||
|  |     "description": "This module is used as a test that fayalite's firrtl\nbackend properly emits annotations.\n\nTesting...\n", | ||||||
|  |     "target": "~check_annotations|check_annotations" | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     "class": "firrtl.transforms.DontTouchAnnotation", |     "class": "firrtl.transforms.DontTouchAnnotation", | ||||||
|     "target": "~check_annotations|check_annotations>raddr" |     "target": "~check_annotations|check_annotations>raddr" | ||||||
|  | @ -3196,10 +3250,35 @@ circuit check_annotations: %[[ | ||||||
|     "class": "some.annotation.Class", |     "class": "some.annotation.Class", | ||||||
|     "baz": "first mask bit", |     "baz": "first mask bit", | ||||||
|     "target": "~check_annotations|check_annotations>mem.w1.data[0]" |     "target": "~check_annotations|check_annotations>mem.w1.data[0]" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.transforms.DontTouchAnnotation", | ||||||
|  |     "target": "~check_annotations|check_annotations>black_box1_instance" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.transforms.DontTouchAnnotation", | ||||||
|  |     "target": "~check_annotations|check_annotations>black_box2_instance" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.AttributeAnnotation", | ||||||
|  |     "description": "custom_sv_attr = \"abc\"", | ||||||
|  |     "target": "~check_annotations|check_annotations>a_wire.1" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.transforms.BlackBoxInlineAnno", | ||||||
|  |     "name": "black_box1.v", | ||||||
|  |     "text": "(* blackbox *)\nmodule BlackBox1();\nendmodule\n", | ||||||
|  |     "target": "~check_annotations|black_box1" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "class": "firrtl.transforms.BlackBoxPathAnno", | ||||||
|  |     "path": "black_box2.v", | ||||||
|  |     "target": "~check_annotations|black_box2" | ||||||
|   } |   } | ||||||
| ]] | ]] | ||||||
|     type Ty0 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<4>[2], mask: UInt<1>[2]} |     type Ty0 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<4>[2], mask: UInt<1>[2]} | ||||||
|     type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<4>[2]} |     type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<4>[2]} | ||||||
|  |     type Ty2 = {`0`: SInt<1>, `1`: UInt<1>} | ||||||
|     module check_annotations: @[module-XXXXXXXXXX.rs 1:1] |     module check_annotations: @[module-XXXXXXXXXX.rs 1:1] | ||||||
|         input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] |         input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] | ||||||
|         output rdata: UInt<4>[2] @[module-XXXXXXXXXX.rs 3:1] |         output rdata: UInt<4>[2] @[module-XXXXXXXXXX.rs 3:1] | ||||||
|  | @ -3224,6 +3303,17 @@ circuit check_annotations: %[[ | ||||||
|         connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] |         connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] | ||||||
|         connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] |         connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] | ||||||
|         connect `mem`.w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] |         connect `mem`.w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] | ||||||
|  |         inst black_box1_instance of black_box1 @[module-XXXXXXXXXX.rs 21:1] | ||||||
|  |         inst black_box2_instance of black_box2 @[module-XXXXXXXXXX.rs 23:1] | ||||||
|  |         wire a_wire: Ty2 @[module-XXXXXXXXXX.rs 24:1] | ||||||
|  |         wire _bundle_literal_expr: Ty2 | ||||||
|  |         connect _bundle_literal_expr.`0`, SInt<1>(0h0) | ||||||
|  |         connect _bundle_literal_expr.`1`, UInt<1>(0h0) | ||||||
|  |         connect a_wire, _bundle_literal_expr @[module-XXXXXXXXXX.rs 25:1] | ||||||
|  |     extmodule black_box1: @[module-XXXXXXXXXX.rs 20:1] | ||||||
|  |         defname = BlackBox1 | ||||||
|  |     extmodule black_box2: @[module-XXXXXXXXXX.rs 22:1] | ||||||
|  |         defname = BlackBox2 | ||||||
| "#,
 | "#,
 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1164,9 +1164,38 @@ | ||||||
|             "data": { |             "data": { | ||||||
|                 "$kind": "Enum", |                 "$kind": "Enum", | ||||||
|                 "DontTouch": null, |                 "DontTouch": null, | ||||||
|  |                 "SVAttribute": "Visible", | ||||||
|  |                 "BlackBoxInline": "Visible", | ||||||
|  |                 "BlackBoxPath": "Visible", | ||||||
|  |                 "DocString": "Visible", | ||||||
|                 "CustomFirrtl": "Visible" |                 "CustomFirrtl": "Visible" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "SVAttributeAnnotation": { | ||||||
|  |             "data": { | ||||||
|  |                 "$kind": "Struct", | ||||||
|  |                 "text": "Visible" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "BlackBoxInlineAnnotation": { | ||||||
|  |             "data": { | ||||||
|  |                 "$kind": "Struct", | ||||||
|  |                 "path": "Visible", | ||||||
|  |                 "text": "Visible" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "BlackBoxPathAnnotation": { | ||||||
|  |             "data": { | ||||||
|  |                 "$kind": "Struct", | ||||||
|  |                 "path": "Visible" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "DocStringAnnotation": { | ||||||
|  |             "data": { | ||||||
|  |                 "$kind": "Struct", | ||||||
|  |                 "text": "Visible" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "CustomFirrtlAnnotation": { |         "CustomFirrtlAnnotation": { | ||||||
|             "data": { |             "data": { | ||||||
|                 "$kind": "Opaque" |                 "$kind": "Opaque" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue