floogen 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- floogen/__init__.py +3 -0
- floogen/cli.py +266 -0
- floogen/config_parser.py +116 -0
- floogen/examples/axi_mesh_id.yml +69 -0
- floogen/examples/axi_mesh_src.yml +69 -0
- floogen/examples/axi_mesh_xy.yml +69 -0
- floogen/examples/collective.yml +99 -0
- floogen/examples/mcast.yml +86 -0
- floogen/examples/nw_mesh_id.yml +86 -0
- floogen/examples/nw_mesh_src.yml +86 -0
- floogen/examples/nw_mesh_xy.yml +86 -0
- floogen/examples/occamy_mesh_src.yml +119 -0
- floogen/examples/occamy_mesh_xy.yml +125 -0
- floogen/examples/occamy_tree.yml +106 -0
- floogen/examples/single_cluster.yml +96 -0
- floogen/examples/terapool.yml +130 -0
- floogen/model/__init__.py +3 -0
- floogen/model/connection.py +64 -0
- floogen/model/endpoint.py +126 -0
- floogen/model/graph.py +310 -0
- floogen/model/link.py +180 -0
- floogen/model/network.py +801 -0
- floogen/model/network_interface.py +98 -0
- floogen/model/protocol.py +167 -0
- floogen/model/router.py +103 -0
- floogen/model/routing.py +948 -0
- floogen/query.py +73 -0
- floogen/templates/floo_addrmap.rdl.mako +19 -0
- floogen/templates/floo_axi_chimney.sv.mako +63 -0
- floogen/templates/floo_axi_router.sv.mako +88 -0
- floogen/templates/floo_axi_tile.sv.mako +133 -0
- floogen/templates/floo_noc.sv.mako +27 -0
- floogen/templates/floo_noc_pkg.sv.mako +63 -0
- floogen/templates/floo_nw_chimney.sv.mako +111 -0
- floogen/templates/floo_nw_router.sv.mako +124 -0
- floogen/utils.py +303 -0
- floogen-0.8.0.dist-info/METADATA +72 -0
- floogen-0.8.0.dist-info/RECORD +41 -0
- floogen-0.8.0.dist-info/WHEEL +4 -0
- floogen-0.8.0.dist-info/entry_points.txt +3 -0
- floogen-0.8.0.dist-info/licenses/LICENSE-APACHE +201 -0
floogen/__init__.py
ADDED
floogen/cli.py
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2023 ETH Zurich and University of Bologna.
|
|
3
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
#
|
|
6
|
+
# Author: Tim Fischer <fischeti@iis.ee.ethz.ch>
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from importlib.resources import files
|
|
11
|
+
|
|
12
|
+
from mako.template import Template
|
|
13
|
+
|
|
14
|
+
from floogen.config_parser import parse_config
|
|
15
|
+
from floogen.query import handle_query
|
|
16
|
+
from floogen.model.network import Network
|
|
17
|
+
from floogen.utils import verible_format
|
|
18
|
+
|
|
19
|
+
tpl_dir = files("floogen") / "templates"
|
|
20
|
+
|
|
21
|
+
def render_template(context: dict, tpl: Path,
|
|
22
|
+
outdir: Path = None, file_name: str = None,
|
|
23
|
+
format_output: bool=False, verible_fmt_bin: str = None,
|
|
24
|
+
verible_fmt_args: str = None):
|
|
25
|
+
"""Render a template, format if requested and write to file or print to stdout."""
|
|
26
|
+
if not tpl.exists():
|
|
27
|
+
# Search in the internal template directory if the template exists there
|
|
28
|
+
if (tpl_dir / tpl.name).exists():
|
|
29
|
+
tpl = tpl_dir / tpl.name
|
|
30
|
+
else:
|
|
31
|
+
raise FileNotFoundError(f"Template not found: {tpl}")
|
|
32
|
+
rendered = Template(filename=str(tpl.resolve())).render(**context)
|
|
33
|
+
if format_output:
|
|
34
|
+
rendered = verible_format(rendered, verible_fmt_bin, verible_fmt_args)
|
|
35
|
+
if outdir:
|
|
36
|
+
outdir.mkdir(parents=True, exist_ok=True)
|
|
37
|
+
if file_name:
|
|
38
|
+
outfile = outdir / file_name
|
|
39
|
+
else:
|
|
40
|
+
outfile = outdir / tpl.stem
|
|
41
|
+
with open(outfile, "w+", encoding="utf-8") as f:
|
|
42
|
+
f.write(rendered)
|
|
43
|
+
else:
|
|
44
|
+
print(rendered)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
48
|
+
"""Parse the command line arguments."""
|
|
49
|
+
|
|
50
|
+
# Parser that holds all common options
|
|
51
|
+
common = argparse.ArgumentParser(add_help=False)
|
|
52
|
+
common.add_argument(
|
|
53
|
+
"-c", "--config", type=Path, required=True,
|
|
54
|
+
help="Path to the configuration file."
|
|
55
|
+
)
|
|
56
|
+
common.add_argument(
|
|
57
|
+
"-o", "--outdir", type=Path, required=False,
|
|
58
|
+
help=(
|
|
59
|
+
"Path to the output directory of the generated output files. "
|
|
60
|
+
"If not specified, the files are printed to stdout."
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Parser for SystemVerilog formatting options
|
|
65
|
+
sv_format = argparse.ArgumentParser(add_help=False)
|
|
66
|
+
sv_format.add_argument(
|
|
67
|
+
"--no-format",
|
|
68
|
+
dest="no_format",
|
|
69
|
+
action="store_true",
|
|
70
|
+
help="Do not format the output.",
|
|
71
|
+
)
|
|
72
|
+
sv_format.add_argument(
|
|
73
|
+
"--verible-fmt-bin",
|
|
74
|
+
type=str,
|
|
75
|
+
default=None,
|
|
76
|
+
help="Overwrite default `verible-verilog-format` binary.",
|
|
77
|
+
)
|
|
78
|
+
sv_format.add_argument(
|
|
79
|
+
"--verible-fmt-args",
|
|
80
|
+
type=str,
|
|
81
|
+
default=None,
|
|
82
|
+
help="Additional arguments to pass to `verible-verilog-format`.",
|
|
83
|
+
)
|
|
84
|
+
sv_format.add_argument(
|
|
85
|
+
"--name",
|
|
86
|
+
type=str,
|
|
87
|
+
default=None,
|
|
88
|
+
help="Override the module/package name and prefix for generated files."
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Top-level parser
|
|
92
|
+
parser = argparse.ArgumentParser(
|
|
93
|
+
description="FlooGen: A Network-on-Chip Generator for FlooNoC",
|
|
94
|
+
add_help=True,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
98
|
+
|
|
99
|
+
# floogen rtl -> pkg + top
|
|
100
|
+
subparsers.add_parser(
|
|
101
|
+
"rtl",
|
|
102
|
+
parents=[common, sv_format],
|
|
103
|
+
add_help=True,
|
|
104
|
+
help="Generate both the NoC package and top-module.",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# floogen pkg
|
|
108
|
+
subparsers.add_parser(
|
|
109
|
+
"pkg",
|
|
110
|
+
parents=[common, sv_format],
|
|
111
|
+
add_help=True,
|
|
112
|
+
help="Generate the NoC package.",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# floogen top
|
|
116
|
+
subparsers.add_parser(
|
|
117
|
+
"top",
|
|
118
|
+
parents=[common, sv_format],
|
|
119
|
+
add_help=True,
|
|
120
|
+
help="Generate the NoC top-module.",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# floogen rdl
|
|
124
|
+
p_rdl = subparsers.add_parser(
|
|
125
|
+
"rdl",
|
|
126
|
+
parents=[common],
|
|
127
|
+
add_help=True,
|
|
128
|
+
help="Generate the SystemRDL of all endpoint address regions.",
|
|
129
|
+
)
|
|
130
|
+
p_rdl.add_argument(
|
|
131
|
+
"--as-mem",
|
|
132
|
+
dest="as_mem",
|
|
133
|
+
action="store_true",
|
|
134
|
+
default=False,
|
|
135
|
+
help="Add memory blocks for address regions without 'rdl_name' declared.",
|
|
136
|
+
)
|
|
137
|
+
p_rdl.add_argument(
|
|
138
|
+
"--memwidth",
|
|
139
|
+
dest="memwidth",
|
|
140
|
+
type=int,
|
|
141
|
+
default=8,
|
|
142
|
+
help="Use the memory width of the RDL address region as the width of the memory block.",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# floogen templates <template1> <template2> ...
|
|
146
|
+
p_templates = subparsers.add_parser(
|
|
147
|
+
"template",
|
|
148
|
+
parents=[common, sv_format],
|
|
149
|
+
add_help=True,
|
|
150
|
+
help="Render custom (external) templates.",
|
|
151
|
+
)
|
|
152
|
+
p_templates.add_argument(
|
|
153
|
+
"template",
|
|
154
|
+
type=Path,
|
|
155
|
+
nargs="+",
|
|
156
|
+
help="Path to external template to render. Multiple templates can be specified.",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# floogen visualize
|
|
160
|
+
subparsers.add_parser(
|
|
161
|
+
"visualize",
|
|
162
|
+
parents=[common],
|
|
163
|
+
add_help=True,
|
|
164
|
+
help="Visualize the network graph.",
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# floogen query <key>
|
|
168
|
+
p_query = subparsers.add_parser(
|
|
169
|
+
"query",
|
|
170
|
+
parents=[common],
|
|
171
|
+
add_help=True,
|
|
172
|
+
help="Query a specific key in the configuration.",
|
|
173
|
+
)
|
|
174
|
+
p_query.add_argument(
|
|
175
|
+
"query",
|
|
176
|
+
type=str,
|
|
177
|
+
help="Key to query in the configuration.",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return parser
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def main():
|
|
184
|
+
"""Generates the network."""
|
|
185
|
+
|
|
186
|
+
parser = build_parser()
|
|
187
|
+
args = parser.parse_args()
|
|
188
|
+
|
|
189
|
+
if args.command is None:
|
|
190
|
+
parser.print_help()
|
|
191
|
+
return 0
|
|
192
|
+
|
|
193
|
+
network = parse_config(Network, args.config)
|
|
194
|
+
|
|
195
|
+
network.create_network()
|
|
196
|
+
network.compile_network()
|
|
197
|
+
network.gen_routing_info()
|
|
198
|
+
|
|
199
|
+
# The general context to pass to all templates
|
|
200
|
+
context = {"noc": network}
|
|
201
|
+
|
|
202
|
+
# Additional render arguments
|
|
203
|
+
render_kwargs = {"outdir": args.outdir}
|
|
204
|
+
|
|
205
|
+
# Command specific render arguments
|
|
206
|
+
match args.command:
|
|
207
|
+
case "rtl" | "pkg" | "top" | "template":
|
|
208
|
+
render_kwargs["format_output"] = not args.no_format
|
|
209
|
+
render_kwargs["verible_fmt_bin"] = args.verible_fmt_bin
|
|
210
|
+
render_kwargs["verible_fmt_args"] = args.verible_fmt_args
|
|
211
|
+
context["name"] = args.name or network.name
|
|
212
|
+
pkg_file_name = f"floo_{args.name or network.name}_noc_pkg.sv"
|
|
213
|
+
top_file_name = f"floo_{args.name or network.name}_noc.sv"
|
|
214
|
+
case "rdl":
|
|
215
|
+
rdl_file_name = f"{network.name}_addrmap.rdl"
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
match args.command:
|
|
219
|
+
case "rtl":
|
|
220
|
+
render_template(context,
|
|
221
|
+
tpl=tpl_dir / "floo_noc_pkg.sv.mako",
|
|
222
|
+
file_name=pkg_file_name,
|
|
223
|
+
**render_kwargs,
|
|
224
|
+
)
|
|
225
|
+
render_template(context,
|
|
226
|
+
tpl=tpl_dir / "floo_noc.sv.mako",
|
|
227
|
+
file_name=top_file_name,
|
|
228
|
+
**render_kwargs,
|
|
229
|
+
)
|
|
230
|
+
case "pkg":
|
|
231
|
+
render_template(context,
|
|
232
|
+
tpl=tpl_dir / "floo_noc_pkg.sv.mako",
|
|
233
|
+
file_name=pkg_file_name,
|
|
234
|
+
**render_kwargs,
|
|
235
|
+
)
|
|
236
|
+
case "top":
|
|
237
|
+
render_template(context,
|
|
238
|
+
tpl=tpl_dir / "floo_noc.sv.mako",
|
|
239
|
+
file_name=top_file_name,
|
|
240
|
+
**render_kwargs,
|
|
241
|
+
)
|
|
242
|
+
case "rdl":
|
|
243
|
+
context["rdl_as_mem"] = args.as_mem
|
|
244
|
+
context["rdl_memwidth"] = args.memwidth
|
|
245
|
+
render_template(context,
|
|
246
|
+
tpl=tpl_dir / "floo_addrmap.rdl.mako",
|
|
247
|
+
file_name=rdl_file_name,
|
|
248
|
+
**render_kwargs,
|
|
249
|
+
)
|
|
250
|
+
case "template":
|
|
251
|
+
for tpl in args.template:
|
|
252
|
+
render_template(context,
|
|
253
|
+
tpl=tpl,
|
|
254
|
+
**render_kwargs,
|
|
255
|
+
)
|
|
256
|
+
case "visualize":
|
|
257
|
+
if args.outdir:
|
|
258
|
+
network.visualize(filename=args.outdir / (network.name + ".pdf"))
|
|
259
|
+
else:
|
|
260
|
+
network.visualize(savefig=False)
|
|
261
|
+
case "query":
|
|
262
|
+
handle_query(network, args.query)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
if __name__ == "__main__":
|
|
266
|
+
main()
|
floogen/config_parser.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright 2023 ETH Zurich and University of Bologna.
|
|
3
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
#
|
|
6
|
+
# Author: Tim Fischer <fischeti@iis.ee.ethz.ch>
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import logging
|
|
10
|
+
from typing import List, Union, Tuple, Mapping, TypeVar
|
|
11
|
+
|
|
12
|
+
from pydantic import ValidationError, BaseModel
|
|
13
|
+
|
|
14
|
+
from ruamel.yaml.comments import CommentedMap
|
|
15
|
+
from ruamel.yaml import YAMLError
|
|
16
|
+
import ruamel.yaml
|
|
17
|
+
|
|
18
|
+
import click
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger("padrick.ConfigParser")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_error_context(config_file: Path, line, column, context_before=4, context_after=4):
|
|
24
|
+
"""Retrieves the context surrounding an error in a configuration file."""
|
|
25
|
+
lines_to_return = []
|
|
26
|
+
with config_file.open() as file:
|
|
27
|
+
for line_idx, line in enumerate(file.readlines()):
|
|
28
|
+
if line_idx + 1 == line:
|
|
29
|
+
lines_to_return.append(line)
|
|
30
|
+
lines_to_return.append(click.style(column * " " + "^\n", blink=True, fg="yellow"))
|
|
31
|
+
elif line_idx + 1 >= line - context_before and line_idx + 1 <= line + context_after:
|
|
32
|
+
lines_to_return.append(line)
|
|
33
|
+
return "".join(lines_to_return)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_human_readable_error_path(config_data: dict, error_location: List[Union[str, int]]):
|
|
37
|
+
"""Transforms a list of path segments into a human readable string."""
|
|
38
|
+
transformed_path_segments = []
|
|
39
|
+
node = config_data
|
|
40
|
+
for path_segment in error_location:
|
|
41
|
+
try:
|
|
42
|
+
node = node[path_segment]
|
|
43
|
+
except KeyError:
|
|
44
|
+
transformed_path_segments.append(path_segment)
|
|
45
|
+
break
|
|
46
|
+
if isinstance(path_segment, int):
|
|
47
|
+
transformed_path_segments.append(node.get("name", path_segment))
|
|
48
|
+
else:
|
|
49
|
+
transformed_path_segments.append(path_segment)
|
|
50
|
+
return "->".join(transformed_path_segments)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_file_location(
|
|
54
|
+
config_data: CommentedMap, error_location: List[Union[str, int]]
|
|
55
|
+
) -> Tuple[Tuple[int, int], Mapping]:
|
|
56
|
+
"""Retrieves the location of an error in a configuration file."""
|
|
57
|
+
node = config_data
|
|
58
|
+
location = (node.lc.line + 1, node.lc.col)
|
|
59
|
+
subtree = node
|
|
60
|
+
for path_segment in error_location:
|
|
61
|
+
try:
|
|
62
|
+
location = (node.lc.data[path_segment][0] + 1, node.lc.data[path_segment][1])
|
|
63
|
+
node = node[path_segment]
|
|
64
|
+
if isinstance(node, Mapping):
|
|
65
|
+
subtree = node
|
|
66
|
+
except KeyError:
|
|
67
|
+
break
|
|
68
|
+
return location, subtree
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
T = TypeVar("T", bound=BaseModel)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def parse_config(cls: T, config_file: Path) -> Union[T, None]:
|
|
75
|
+
"""Parses a configuration file and returns a validated model."""
|
|
76
|
+
with config_file.open() as file:
|
|
77
|
+
try:
|
|
78
|
+
yaml = ruamel.yaml.YAML(typ="rt")
|
|
79
|
+
# enable support for !include directives (see pyyaml-include package)
|
|
80
|
+
# if not include_base_dir:
|
|
81
|
+
# include_base_dir = config_file.parent
|
|
82
|
+
# if not ignore_includes:
|
|
83
|
+
# include_constructor = YamlIncludeConstructor(base_dir=str(include_base_dir))
|
|
84
|
+
# else:
|
|
85
|
+
# include_constructor = IgnoreIncludeConstructor
|
|
86
|
+
# yaml.register_class(include_constructor)
|
|
87
|
+
config_data = yaml.load(file)
|
|
88
|
+
# config_data = ruamel.yaml.load(file, Loader=ruamel.yaml.RoundTripLoader)
|
|
89
|
+
except YAMLError as e:
|
|
90
|
+
logger.error("Error while parsing config_file:\n %s", e)
|
|
91
|
+
return None
|
|
92
|
+
try:
|
|
93
|
+
model = cls.model_validate(config_data)
|
|
94
|
+
return model
|
|
95
|
+
except ValidationError as e:
|
|
96
|
+
logger.error(
|
|
97
|
+
"Encountered %s validation errors while parsing the configuration file:",
|
|
98
|
+
len(e.errors()),
|
|
99
|
+
)
|
|
100
|
+
for error in e.errors():
|
|
101
|
+
if error["type"] == "extra":
|
|
102
|
+
error[
|
|
103
|
+
"msg"
|
|
104
|
+
] = f'Unknown field {error["loc"][-1]}. \
|
|
105
|
+
Did you mispell the field name?'
|
|
106
|
+
if error["type"] == "missing":
|
|
107
|
+
error["msg"] = f'Missing field \'{error["loc"][-1]}\''
|
|
108
|
+
else:
|
|
109
|
+
error["msg"] = f'{error["msg"]} (field \'{error["loc"][-1]}\')'
|
|
110
|
+
# error_path = get_human_readable_error_path(config_data, error["loc"])
|
|
111
|
+
(line, column), _ = get_file_location(config_data, error["loc"])
|
|
112
|
+
error_context = get_error_context(config_file, line, column, context_after=10)
|
|
113
|
+
logger.error("Line %s, Column %s:", line, column)
|
|
114
|
+
logger.error("...\n%s\n...", error_context)
|
|
115
|
+
logger.error("Error: %s", error["msg"])
|
|
116
|
+
return None
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Copyright 2023 ETH Zurich and University of Bologna.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
name: axi_mesh
|
|
6
|
+
description: "AXI mesh configuration with table-based routing for FlooGen"
|
|
7
|
+
network_type: "axi"
|
|
8
|
+
|
|
9
|
+
routing:
|
|
10
|
+
route_algo: "ID"
|
|
11
|
+
use_id_table: true
|
|
12
|
+
|
|
13
|
+
protocols:
|
|
14
|
+
- name: "axi_in"
|
|
15
|
+
protocol: "AXI4"
|
|
16
|
+
data_width: 64
|
|
17
|
+
addr_width: 48
|
|
18
|
+
id_width: 4
|
|
19
|
+
user_width: 1
|
|
20
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
21
|
+
- name: "axi_out"
|
|
22
|
+
protocol: "AXI4"
|
|
23
|
+
data_width: 64
|
|
24
|
+
addr_width: 48
|
|
25
|
+
id_width: 2
|
|
26
|
+
user_width: 1
|
|
27
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
28
|
+
|
|
29
|
+
endpoints:
|
|
30
|
+
- name: "cluster"
|
|
31
|
+
array: [4, 4]
|
|
32
|
+
addr_range:
|
|
33
|
+
base: 0x0000_0000_0000
|
|
34
|
+
size: 0x0000_0001_0000
|
|
35
|
+
mgr_port_protocol:
|
|
36
|
+
- "axi_in"
|
|
37
|
+
sbr_port_protocol:
|
|
38
|
+
- "axi_out"
|
|
39
|
+
- name: "hbm"
|
|
40
|
+
array: [4]
|
|
41
|
+
addr_range:
|
|
42
|
+
base: 0x0000_8000_0000
|
|
43
|
+
size: 0x0000_0001_0000
|
|
44
|
+
sbr_port_protocol:
|
|
45
|
+
- "axi_out"
|
|
46
|
+
|
|
47
|
+
routers:
|
|
48
|
+
- name: "router"
|
|
49
|
+
array: [4, 4]
|
|
50
|
+
degree: 5
|
|
51
|
+
|
|
52
|
+
connections:
|
|
53
|
+
- src: "cluster"
|
|
54
|
+
dst: "router"
|
|
55
|
+
src_range:
|
|
56
|
+
- [0, 3]
|
|
57
|
+
- [0, 3]
|
|
58
|
+
dst_range:
|
|
59
|
+
- [0, 3]
|
|
60
|
+
- [0, 3]
|
|
61
|
+
dst_dir: "Eject"
|
|
62
|
+
- src: "hbm"
|
|
63
|
+
dst: "router"
|
|
64
|
+
src_range:
|
|
65
|
+
- [0, 3]
|
|
66
|
+
dst_range:
|
|
67
|
+
- [0, 0]
|
|
68
|
+
- [0, 3]
|
|
69
|
+
dst_dir: "West"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Copyright 2023 ETH Zurich and University of Bologna.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
name: axi_mesh
|
|
6
|
+
description: "AXI mesh configuration with source-based routing for FlooGen"
|
|
7
|
+
network_type: "axi"
|
|
8
|
+
|
|
9
|
+
routing:
|
|
10
|
+
route_algo: "SRC"
|
|
11
|
+
use_id_table: true
|
|
12
|
+
|
|
13
|
+
protocols:
|
|
14
|
+
- name: "axi_in"
|
|
15
|
+
protocol: "AXI4"
|
|
16
|
+
data_width: 64
|
|
17
|
+
addr_width: 48
|
|
18
|
+
id_width: 4
|
|
19
|
+
user_width: 1
|
|
20
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
21
|
+
- name: "axi_out"
|
|
22
|
+
protocol: "AXI4"
|
|
23
|
+
data_width: 64
|
|
24
|
+
addr_width: 48
|
|
25
|
+
id_width: 2
|
|
26
|
+
user_width: 1
|
|
27
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
28
|
+
|
|
29
|
+
endpoints:
|
|
30
|
+
- name: "cluster"
|
|
31
|
+
array: [4, 4]
|
|
32
|
+
addr_range:
|
|
33
|
+
base: 0x0000_0000_0000
|
|
34
|
+
size: 0x0000_0001_0000
|
|
35
|
+
mgr_port_protocol:
|
|
36
|
+
- "axi_in"
|
|
37
|
+
sbr_port_protocol:
|
|
38
|
+
- "axi_out"
|
|
39
|
+
- name: "hbm"
|
|
40
|
+
array: [4]
|
|
41
|
+
addr_range:
|
|
42
|
+
base: 0x0000_8000_0000
|
|
43
|
+
size: 0x0000_0001_0000
|
|
44
|
+
sbr_port_protocol:
|
|
45
|
+
- "axi_out"
|
|
46
|
+
|
|
47
|
+
routers:
|
|
48
|
+
- name: "router"
|
|
49
|
+
array: [4, 4]
|
|
50
|
+
degree: 5
|
|
51
|
+
|
|
52
|
+
connections:
|
|
53
|
+
- src: "cluster"
|
|
54
|
+
dst: "router"
|
|
55
|
+
src_range:
|
|
56
|
+
- [0, 3]
|
|
57
|
+
- [0, 3]
|
|
58
|
+
dst_range:
|
|
59
|
+
- [0, 3]
|
|
60
|
+
- [0, 3]
|
|
61
|
+
dst_dir: "Eject"
|
|
62
|
+
- src: "hbm"
|
|
63
|
+
dst: "router"
|
|
64
|
+
src_range:
|
|
65
|
+
- [0, 3]
|
|
66
|
+
dst_range:
|
|
67
|
+
- [0, 0]
|
|
68
|
+
- [0, 3]
|
|
69
|
+
dst_dir: "West"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Copyright 2023 ETH Zurich and University of Bologna.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
name: axi_mesh
|
|
6
|
+
description: "AXI mesh configuration with XY routing for FlooGen"
|
|
7
|
+
network_type: "axi"
|
|
8
|
+
|
|
9
|
+
routing:
|
|
10
|
+
route_algo: "XY"
|
|
11
|
+
use_id_table: true
|
|
12
|
+
|
|
13
|
+
protocols:
|
|
14
|
+
- name: "axi_in"
|
|
15
|
+
protocol: "AXI4"
|
|
16
|
+
data_width: 64
|
|
17
|
+
addr_width: 48
|
|
18
|
+
id_width: 4
|
|
19
|
+
user_width: 1
|
|
20
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
21
|
+
- name: "axi_out"
|
|
22
|
+
protocol: "AXI4"
|
|
23
|
+
data_width: 64
|
|
24
|
+
addr_width: 48
|
|
25
|
+
id_width: 2
|
|
26
|
+
user_width: 1
|
|
27
|
+
type_prefix: # prevents `axi_axi` prefix
|
|
28
|
+
|
|
29
|
+
endpoints:
|
|
30
|
+
- name: "cluster"
|
|
31
|
+
array: [4, 4]
|
|
32
|
+
addr_range:
|
|
33
|
+
base: 0x0000_0000_0000
|
|
34
|
+
size: 0x0000_0001_0000
|
|
35
|
+
mgr_port_protocol:
|
|
36
|
+
- "axi_in"
|
|
37
|
+
sbr_port_protocol:
|
|
38
|
+
- "axi_out"
|
|
39
|
+
- name: "hbm"
|
|
40
|
+
array: [4]
|
|
41
|
+
addr_range:
|
|
42
|
+
base: 0x0000_8000_0000
|
|
43
|
+
size: 0x0000_0001_0000
|
|
44
|
+
sbr_port_protocol:
|
|
45
|
+
- "axi_out"
|
|
46
|
+
|
|
47
|
+
routers:
|
|
48
|
+
- name: "router"
|
|
49
|
+
array: [4, 4]
|
|
50
|
+
degree: 5
|
|
51
|
+
|
|
52
|
+
connections:
|
|
53
|
+
- src: "cluster"
|
|
54
|
+
dst: "router"
|
|
55
|
+
src_range:
|
|
56
|
+
- [0, 3]
|
|
57
|
+
- [0, 3]
|
|
58
|
+
dst_range:
|
|
59
|
+
- [0, 3]
|
|
60
|
+
- [0, 3]
|
|
61
|
+
dst_dir: "Eject"
|
|
62
|
+
- src: "hbm"
|
|
63
|
+
dst: "router"
|
|
64
|
+
src_range:
|
|
65
|
+
- [0, 3]
|
|
66
|
+
dst_range:
|
|
67
|
+
- [0, 0]
|
|
68
|
+
- [0, 3]
|
|
69
|
+
dst_dir: "West"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Copyright 2025 ETH Zurich and University of Bologna.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Example: full collective support
|
|
6
|
+
# - narrow + wide multicast
|
|
7
|
+
# - barrier (LSB-AND)
|
|
8
|
+
# - narrow reduction: all integer ops (Add, Mul, MinS, MinU, MaxS, MaxU)
|
|
9
|
+
# - wide reduction: only Add and Max (selective ops example)
|
|
10
|
+
|
|
11
|
+
name: nw_mesh_collective
|
|
12
|
+
description: "4x4 NW mesh with full collective operation support"
|
|
13
|
+
network_type: "narrow-wide"
|
|
14
|
+
|
|
15
|
+
routing:
|
|
16
|
+
route_algo: "XY"
|
|
17
|
+
use_id_table: true
|
|
18
|
+
collective:
|
|
19
|
+
en_narrow_multicast: true
|
|
20
|
+
en_wide_multicast: true
|
|
21
|
+
en_barrier: true
|
|
22
|
+
en_narrow_reduction:
|
|
23
|
+
rd_pipeline_depth: 1 # all integer ops, custom hw config
|
|
24
|
+
en_wide_reduction: # selective FP ops, default hw config
|
|
25
|
+
ops: [Add, Max]
|
|
26
|
+
rd_pipeline_depth: 5
|
|
27
|
+
cut_offload_intf: true
|
|
28
|
+
# decouple_rw: Phys
|
|
29
|
+
vc_impl: preempt
|
|
30
|
+
|
|
31
|
+
protocols:
|
|
32
|
+
- name: "narrow_in"
|
|
33
|
+
type: "narrow"
|
|
34
|
+
protocol: "AXI4"
|
|
35
|
+
data_width: 64
|
|
36
|
+
addr_width: 48
|
|
37
|
+
id_width: 5
|
|
38
|
+
user_width:
|
|
39
|
+
collective_mask: 48
|
|
40
|
+
collective_op: 4
|
|
41
|
+
user: 5
|
|
42
|
+
- name: "narrow_out"
|
|
43
|
+
type: "narrow"
|
|
44
|
+
protocol: "AXI4"
|
|
45
|
+
data_width: 64
|
|
46
|
+
addr_width: 48
|
|
47
|
+
id_width: 2
|
|
48
|
+
user_width:
|
|
49
|
+
collective_mask: 48
|
|
50
|
+
collective_op: 4
|
|
51
|
+
user: 5
|
|
52
|
+
- name: "wide_in"
|
|
53
|
+
type: "wide"
|
|
54
|
+
protocol: "AXI4"
|
|
55
|
+
data_width: 512
|
|
56
|
+
addr_width: 48
|
|
57
|
+
id_width: 3
|
|
58
|
+
user_width:
|
|
59
|
+
collective_mask: 48
|
|
60
|
+
collective_op: 4
|
|
61
|
+
- name: "wide_out"
|
|
62
|
+
type: "wide"
|
|
63
|
+
protocol: "AXI4"
|
|
64
|
+
data_width: 512
|
|
65
|
+
addr_width: 48
|
|
66
|
+
id_width: 1
|
|
67
|
+
user_width:
|
|
68
|
+
collective_mask: 48
|
|
69
|
+
collective_op: 4
|
|
70
|
+
|
|
71
|
+
endpoints:
|
|
72
|
+
- name: "cluster"
|
|
73
|
+
array: [4, 4]
|
|
74
|
+
addr_range:
|
|
75
|
+
base: 0x2000_0000
|
|
76
|
+
size: 0x0004_0000
|
|
77
|
+
en_collective: true
|
|
78
|
+
mgr_port_protocol:
|
|
79
|
+
- "narrow_in"
|
|
80
|
+
- "wide_in"
|
|
81
|
+
sbr_port_protocol:
|
|
82
|
+
- "narrow_out"
|
|
83
|
+
- "wide_out"
|
|
84
|
+
|
|
85
|
+
routers:
|
|
86
|
+
- name: "router"
|
|
87
|
+
array: [4, 4]
|
|
88
|
+
degree: 5
|
|
89
|
+
|
|
90
|
+
connections:
|
|
91
|
+
- src: "cluster"
|
|
92
|
+
dst: "router"
|
|
93
|
+
src_range:
|
|
94
|
+
- [0, 3]
|
|
95
|
+
- [0, 3]
|
|
96
|
+
dst_range:
|
|
97
|
+
- [0, 3]
|
|
98
|
+
- [0, 3]
|
|
99
|
+
dst_dir: "Eject"
|