Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dfc2a68
WIP area profiler heuristic from Yosys
Sep 22, 2025
e9c7687
Better readme with Yosys info
Sep 22, 2025
2d79725
Merge remote-tracking branch 'origin/main' into area-profiler/heuristic
Oct 6, 2025
014eefe
created AreaExtract
Oct 26, 2025
bba6794
README and rhai script
Oct 26, 2025
7bd52bb
Updated profiler to parse CDF
Oct 26, 2025
e857b99
Merge remote-tracking branch 'origin/main' into area-profiler/AreaExt…
Oct 26, 2025
a9274a6
Insta tests for fud2
Oct 26, 2025
e477cf3
Formatted code
Oct 26, 2025
23603c1
Formatted code
Oct 26, 2025
8938475
Removed all previous iterations of area extraction code, and updated …
Dec 1, 2025
439d810
Resolved Ayaka's comments
Dec 1, 2025
268f636
Merge remote-tracking branch 'origin/main' into area-profiler/AreaExt…
Dec 1, 2025
6faad23
oops deleted a little too much!
Dec 1, 2025
843541f
updated commands and tests
Dec 1, 2025
773f2a8
Reviewed insta
Dec 1, 2025
3088ce5
fixed python formatting
Dec 1, 2025
2cf0d81
Added test cases
Dec 3, 2025
7b2c8ff
Merge remote-tracking branch 'origin/main' into area-profiler/AreaExt…
Dec 3, 2025
253597a
Add AreaExtract to Dockerfile?
ayakayorihiro Dec 4, 2025
d0b99ed
Delete graph.pdf
pedropontesgarcia Dec 4, 2025
31dd84a
Merge branch 'main' into area-profiler/AreaExtract
ayakayorihiro Dec 11, 2025
b28639f
Use older version of type aliasing
ayakayorihiro Jan 5, 2026
2e9b8b1
Fixing format issues
ayakayorihiro Jan 5, 2026
e0e814b
modify dockerfile to trigger ci update?
ayakayorihiro Jan 5, 2026
f85fa58
Add missing json file for yosys test
ayakayorihiro Jan 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fud2/scripts/synth-verilog-to-report.rhai
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ fn synth_setup(e) {
e.rsrc("synth.tcl");

// Python scripts for parsing reports for visualization and extracting JSON summary
e.rule("parse-rpt", "synthrep viz -t flamegraph -f $in > $out");
e.rule("parse-rpt", "synthrep viz -f $in > $out");
e.rule("extract-util-json", "synthrep summary -m utilization > $out");
e.rule("extract-hierarchy-json", "synthrep summary -m hierarchy > $out");
e.rule("extract-hierarchy-json", "aext vivado out/hierarchical_utilization_placed.rpt > $out");
}

fn flamegraph_setup(e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

flamegraph-script = /test/calyx/non-existent.script
create-visuals-script = $calyx-base/tools/profiler/create-visuals.sh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

build main.sv: copy /input.ext
build device.xdc: copy $device_xdc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

build main.sv: copy /input.ext
build device.xdc: copy $device_xdc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

build main.sv: copy /input.ext
build device.xdc: copy $device_xdc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

build main.sv: copy /input.ext
build device.xdc: copy $device_xdc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-util-json
command = synthrep summary -m utilization > $out
rule extract-hierarchy-json
command = synthrep summary -m hierarchy > $out
command = aext vivado out/hierarchical_utilization_placed.rpt > $out

build main.sv: copy /input.ext
build device.xdc: copy $device_xdc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ device_xdc = default.xdc
build default.xdc: get-rsrc
build synth.tcl: get-rsrc
rule parse-rpt
command = synthrep viz -t flamegraph -f $in > $out
command = synthrep viz -f $in > $out
rule extract-rpt
command = synthrep summary > $out
flamegraph-script = /test/calyx/non-existent.script
Expand Down
Binary file added graph.pdf
Binary file not shown.
12 changes: 12 additions & 0 deletions runt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,15 @@ cmd = """
fud2 axi-wrapped.futil --from calyx --to verilog-noverify -o axi-wrapped.v 2> /dev/null && \
fud2 axi-wrapped.v --from verilog-noverify --to cocotb-axi --set sim.data=${dirname}/../vectorized-add.data 2> /dev/null
"""


##### AreaExtract Tests ######
[[tests]]
name = "AreaExtract tests for Vivado input"
paths = [ "tools/AreaExtract/tests/vivado/*.rpt" ]
cmd = "aext vivado {}"

[[tests]]
name = "AreaExtract tests for Yosys input"
paths = [ "tools/AreaExtract/tests/yosys/*.il" ]
cmd = "aext yosys {} tools/AreaExtract/tests/yosys/inline.json"
4 changes: 4 additions & 0 deletions tools/AreaExtract/AreaExtract/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""AreaExtract is a tool to extract area information from synthesis data
and compile it in a Common Data Format."""

__version__ = "0.1.0"
Empty file.
82 changes: 82 additions & 0 deletions tools/AreaExtract/AreaExtract/bin/extract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import argparse
import json
from pathlib import Path

from AreaExtract.lib.parse.vivado import rpt_to_design_with_metadata
from AreaExtract.lib.parse.yosys import il_to_design_with_metadata
from AreaExtract.lib.plot.plot import save_plot


def main():
parser = argparse.ArgumentParser(
description=(
"Parse FPGA synthesis reports into a Common Data Format.\n\n"
"Supported origins:\n"
" - Vivado: single hierarchical .rpt file\n"
" - Yosys: .il (intermediate language) and .json (stat) file\n\n"
"Supported outputs:\n"
" - CDF: JSON serialization of the Common Data Format.\n"
" - Visualizations: HTML hierarchical area-only visualizations."
),
formatter_class=argparse.RawTextHelpFormatter,
)
subparsers = parser.add_subparsers(dest="origin", required=True)
vivado = subparsers.add_parser(
"vivado",
help="parse a Vivado utilization .rpt file",
)
vivado.add_argument(
"rpt",
type=Path,
help="path to Vivado utilization report (.rpt)",
)
yosys = subparsers.add_parser(
"yosys",
help="parse Yosys IL and stat JSON files",
)
yosys.add_argument(
"il",
type=Path,
help="path to Yosys IL file (.il)",
)
yosys.add_argument(
"json",
type=Path,
help="path to Yosys stat file (.json)",
)
parser.add_argument(
"-o",
"--output",
type=Path,
help="optional output file for JSON (defaults to stdout)",
)
parser.add_argument(
"-v",
"--visual",
type=Path,
help="save visualizations to folder (not done by default)",
)
parser.add_argument(
"-c",
"--column",
type=Path,
help="column to visualize (defaults to 'ff' for Vivado, 'width' for Yosys)",
)
args = parser.parse_args()
if args.origin == "vivado":
design = rpt_to_design_with_metadata(args.rpt)
elif args.origin == "yosys":
design = il_to_design_with_metadata(args.il, args.json)
else:
parser.error("unknown origin")
json_str = json.dumps(design, default=lambda o: o.__dict__, indent=2)
if args.visual:
save_plot(design, args.visual, args.column)
if args.output:
args.output.write_text(json_str)
else:
print(json_str)


if __name__ == "__main__":
main()
Empty file.
75 changes: 75 additions & 0 deletions tools/AreaExtract/AreaExtract/lib/cdf/cdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from dataclasses import dataclass


@dataclass
class VivadoRsrc:
"""
Vivado resources for a cell.
"""

lut: int
llut: int
lutram: int
srl: int
ff: int
ramb36: int
ramb18: int
uram: int
dsp: int

def __getitem__(self, item):
return getattr(self, item)


type YosysRsrc = dict[str, int]
"""
Yosys resources for a cell, mapping resource name (e.g. "width") to integer value.
"""


type Rsrc = VivadoRsrc | YosysRsrc
"""
Map representing resources used by a cell.
"""


@dataclass
class Cell:
"""
Cell with resources.
"""

# Unqualified cell name.
name: str
# Cell type.
type: str
# Whether the cell was generated in synthesis.
generated: bool
# Cell resources.
rsrc: Rsrc


@dataclass
class Metadata:
"""
Design metadata.
"""

# Origin of the design (Vivado, Yosys).
origin: str


type Design = dict[str, Cell]
"""
Design with qualified cell names and associated cells.
"""


@dataclass
class DesignWithMetadata:
"""
Design with metadata.
"""

design: Design
metadata: Metadata
Empty file.
Loading
Loading