This commit is contained in:
parent
2a25dd9d7b
commit
d0b406d288
|
@ -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,
|
||||||
|
|
|
@ -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…
Reference in a new issue