Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
04ef3cc
hw: Improve VC parametrization
Lore0599 Dec 16, 2025
ef9073b
hw: Introduce support for reduction operations
Jul 16, 2025
6398a5e
hw: Align reduction to VC support
Lore0599 Nov 21, 2025
6f6564c
hw: Remove complex reduction modules
Lore0599 Mar 2, 2026
bb8ca1c
Initial RTL clenaing
Lore0599 Mar 3, 2026
8a21896
Remove unused cfg parameters
Lore0599 Mar 3, 2026
b80869b
Remove RdLoopBack: now coll only with loopback in the NoC
Lore0599 Mar 4, 2026
7b61924
hw: Add support for reduction interface
Lore0599 Mar 5, 2026
1e52969
Fix bender yml
Lore0599 Mar 6, 2026
7cb41e1
pr: Initial round of review
Lore0599 Mar 16, 2026
acc0fa5
Fix hdr in tb mcast
Lore0599 Mar 16, 2026
8aeeed3
floogen: Generate new collective cfg struct
Lore0599 Mar 17, 2026
c655345
hw: Merge reduction types into floonoc types
Lore0599 Mar 17, 2026
e7e51ac
lint: Initial linting clean
Lore0599 Mar 17, 2026
4a0f564
fllogen: Extend to support generic collective types
Lore0599 Mar 17, 2026
62d552d
floogen: Fix extra user field in collect user
Lore0599 Mar 18, 2026
437f44c
floogen: Improve VC warning
Lore0599 Mar 18, 2026
2947337
floogen: Merge reduction pipeline cfg into general cfg
Lore0599 Mar 18, 2026
f735715
hw; Refactor reduction opcode name
Lore0599 Mar 18, 2026
42c668d
synth: Fix synth wrapper to new module interfaces
Lore0599 Mar 18, 2026
45b29bf
ci: Fix linting
Lore0599 Mar 18, 2026
d663c76
Bump PD
Lore0599 Mar 18, 2026
4c98673
floogen: Implement PR suggestions
Lore0599 Mar 25, 2026
bb213d0
deps: Revert axi fork
fischeti Mar 26, 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
15 changes: 15 additions & 0 deletions Bender.lock
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ packages:
source:
Path: pd
dependencies: []
fpnew:
revision: e5aa6a01b5bbe1675c3aa8872e1203413ded83d1
version: null
source:
Git: https://github.com/pulp-platform/cvfpu.git
dependencies:
- common_cells
- fpu_div_sqrt_mvp
fpu_div_sqrt_mvp:
revision: 86e1f558b3c95e91577c41b2fc452c86b04e85ac
version: 1.0.4
source:
Git: https://github.com/pulp-platform/fpu_div_sqrt_mvp.git
dependencies:
- common_cells
idma:
revision: 28a36e5e07705549e59fc33db96ab681bc1ca88e
version: 0.6.5
Expand Down
11 changes: 9 additions & 2 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ dependencies:
axi_riscv_atomics: 0.8.2
common_cells: 1.39.0
common_verification: 0.2.3
idma: {version: 0.6.2, upstream_name: iDMA}
floo_noc_pd: {path: ./pd, target: "floo_synth"}
idma: { version: 0.6.2, upstream_name: iDMA }
FPnew: { git: "https://github.com/pulp-platform/cvfpu.git", rev: pulp-v0.2.3 }
floo_noc_pd: { path: ./pd, target: "floo_synth" }

export_include_dirs:
- hw/include
Expand All @@ -39,15 +40,18 @@ sources:
- hw/floo_rob_wrapper.sv
- hw/floo_reduction_sync.sv
- hw/floo_route_xymask.sv
- hw/floo_alu.sv
# Level 2
- hw/floo_route_select.sv
- hw/floo_route_comp.sv
- hw/floo_meta_buffer.sv
- hw/floo_reduction_arbiter.sv
- hw/floo_reduction_unit.sv
# Level 3
- hw/floo_output_arbiter.sv
# Level 4
- hw/floo_nw_join.sv
# TODO(lleone): Put back and fis axi_chimney
- hw/floo_axi_chimney.sv
- hw/floo_nw_chimney.sv
- hw/floo_router.sv
Expand All @@ -70,13 +74,15 @@ sources:
- hw/test/axi_reorder_remap_compare.sv
- hw/test/axi_bw_monitor.sv
- hw/test/floo_hbm_model.sv
# - hw/test/floo_reduction_offloads.sv
- hw/test/axi_aw_w_sync.sv
# Level 2
- hw/tb/tb_floo_axi_chimney.sv
- hw/tb/tb_floo_nw_chimney.sv
- hw/tb/tb_floo_router.sv
- hw/tb/tb_floo_rob.sv
- hw/tb/tb_floo_rob_multicast.sv
#- hw/tb/tb_floo_rob_multicast.sv

- target: all(any(floo_test, floo_synth), axi_mesh)
files:
Expand Down Expand Up @@ -109,6 +115,7 @@ sources:
- hw/synth/floo_synth_nw_chimney.sv
- hw/synth/floo_synth_axi_router.sv
- hw/synth/floo_synth_nw_router.sv
- hw/synth/floo_synth_nw_2tiles.sv

- target: floo_deprecated_hw
include_dirs:
Expand Down
99 changes: 99 additions & 0 deletions floogen/examples/collective.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copyright 2025 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Example: full collective support
# - narrow + wide multicast
# - barrier (LSB-AND)
# - narrow reduction: all integer ops (Add, Mul, MinS, MinU, MaxS, MaxU)
# - wide reduction: only Add and Max (selective ops example)

name: nw_mesh_collective
description: "4x4 NW mesh with full collective operation support"
network_type: "narrow-wide"

routing:
route_algo: "XY"
use_id_table: true
collective:
en_narrow_multicast: true
en_wide_multicast: true
en_barrier: true
en_narrow_reduction:
rd_pipeline_depth: 1 # all integer ops, custom hw config
en_wide_reduction: # selective FP ops, default hw config
ops: [Add, Max]
rd_pipeline_depth: 5
cut_offload_intf: true
Comment on lines +18 to +27
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The configuration for collectives seems quite complicated. Potentially, adding some (AI generated) documentation would be nice, but optional.

# decouple_rw: Phys
vc_impl: preempt

protocols:
- name: "narrow_in"
type: "narrow"
protocol: "AXI4"
data_width: 64
addr_width: 48
id_width: 5
user_width:
collective_mask: 48
collective_op: 4
user: 5
- name: "narrow_out"
type: "narrow"
protocol: "AXI4"
data_width: 64
addr_width: 48
id_width: 2
user_width:
collective_mask: 48
collective_op: 4
user: 5
- name: "wide_in"
type: "wide"
protocol: "AXI4"
data_width: 512
addr_width: 48
id_width: 3
user_width:
collective_mask: 48
collective_op: 4
- name: "wide_out"
type: "wide"
protocol: "AXI4"
data_width: 512
addr_width: 48
id_width: 1
user_width:
collective_mask: 48
collective_op: 4

endpoints:
- name: "cluster"
array: [4, 4]
addr_range:
base: 0x2000_0000
size: 0x0004_0000
en_collective: true
mgr_port_protocol:
- "narrow_in"
- "wide_in"
sbr_port_protocol:
- "narrow_out"
- "wide_out"

routers:
- name: "router"
array: [4, 4]
degree: 5

connections:
- src: "cluster"
dst: "router"
src_range:
- [0, 3]
- [0, 3]
dst_range:
- [0, 3]
- [0, 3]
dst_dir: "Eject"
86 changes: 86 additions & 0 deletions floogen/examples/mcast.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright 2025 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Example: narrow + wide multicast only (no reduction, no barrier)

name: nw_mesh_mcast
description: "4x4 NW mesh with narrow and wide multicast support"
network_type: "narrow-wide"

routing:
route_algo: "XY"
use_id_table: true
collective:
en_narrow_multicast: true
en_wide_multicast: true

protocols:
- name: "narrow_in"
type: "narrow"
protocol: "AXI4"
data_width: 64
addr_width: 48
id_width: 5
user_width:
collective_mask: 48
collective_op: 4
user: 5
- name: "narrow_out"
type: "narrow"
protocol: "AXI4"
data_width: 64
addr_width: 48
id_width: 2
user_width:
collective_mask: 48
collective_op: 4
user: 5
- name: "wide_in"
type: "wide"
protocol: "AXI4"
data_width: 512
addr_width: 48
id_width: 3
user_width:
collective_mask: 48
collective_op: 4
- name: "wide_out"
type: "wide"
protocol: "AXI4"
data_width: 512
addr_width: 48
id_width: 1
user_width:
collective_mask: 48
collective_op: 4

endpoints:
- name: "cluster"
array: [4, 4]
addr_range:
base: 0x2000_0000
size: 0x0004_0000
en_collective: true
mgr_port_protocol:
- "narrow_in"
- "wide_in"
sbr_port_protocol:
- "narrow_out"
- "wide_out"

routers:
- name: "router"
array: [4, 4]
degree: 5

connections:
- src: "cluster"
dst: "router"
src_range:
- [0, 3]
- [0, 3]
dst_range:
- [0, 3]
- [0, 3]
dst_dir: "Eject"
12 changes: 6 additions & 6 deletions floogen/model/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ def is_only_mgr(self) -> bool:
"""Return true if the endpoint is only a manager."""
return self.is_mgr() and not self.is_sbr()

def is_multicast_ep(self) -> bool:
"""Return true if the endpoint supports multicast."""
return any([b for b in self.addr_range if b.en_multicast])
def is_collective_ep(self) -> bool:
"""Return true if the endpoint supports collective operations."""
return any([b for b in self.addr_range if b.en_collective])

def get_ni_name(self, name: str) -> str:
"""Return the name of the NI."""
Expand All @@ -118,9 +118,9 @@ def from_desc(cls, desc: EndpointDesc,
def render_ports(self, pkg_name=""):
"""Render the ports of the endpoint."""
ports = []
mcast_prefix = "mcast" if self.is_multicast_ep() else ""
collective_prefix = "collective" if self.is_collective_ep() else ""
for port in self.mgr_ports:
ports += port.render_port(pkg_name, prefix=mcast_prefix)
ports += port.render_port(pkg_name, prefix=collective_prefix)
for port in self.sbr_ports:
ports += port.render_port(pkg_name, prefix=mcast_prefix)
ports += port.render_port(pkg_name, prefix=collective_prefix)
return ports
7 changes: 5 additions & 2 deletions floogen/model/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,14 @@ def wide_name(self, is_reversed=False):
return f"{self.source}_to_{self.dest}_wide"

@classmethod
def render_typedefs(cls, axi_narrow, axi_wide, cfg_n, cfg_w):
def render_typedefs(cls, axi_narrow, axi_wide, cfg_n, cfg_w, vc_num=None, phy_num=None):
"""Render the typedefs of the links."""
string = f"`FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, \
{axi_narrow}, {axi_wide}, {cfg_n}, {cfg_w}, hdr_t)\n\n"
string += "`FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req, rsp, wide)\n"
if vc_num is not None and phy_num is not None:
string += f"`FLOO_TYPEDEF_NW_VIRT_CHAN_LINK_ALL(req, rsp, wide, req, rsp, wide, {vc_num}, {phy_num})\n"
else:
string += "`FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req, rsp, wide)\n"
return string

def declare(self):
Expand Down
29 changes: 17 additions & 12 deletions floogen/model/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import matplotlib.pyplot as plt
from pydantic import BaseModel, ConfigDict, StringConstraints, field_validator, model_validator

from floogen.model.routing import Routing, RouteAlgo, RouteMapRule, RouteRule, RouteMap, RouteTable, RouteMapRuleMcast
from floogen.model.routing import Routing, RouteAlgo, RouteMapRule, RouteRule, RouteMap, RouteTable, RouteMapRuleCollective, WideRwDecouple
from floogen.model.routing import Coord, SimpleId, AddrRange, XYDirections
from floogen.model.graph import Graph
from floogen.model.endpoint import EndpointDesc, Endpoint
Expand Down Expand Up @@ -92,7 +92,7 @@ def validate_protocols(self):
if len(set(prot.data_width for prot in self.protocols if prot.type == "wide")) != 1:
raise ValueError("All `wide` protocols must have the same data width")
# Check that `narrow` and `wide` protocols have the same user width
if not self.routing.en_multicast:
if not self.routing.en_collective:
if len(set(prot.user_width for prot in self.protocols if prot.type == "narrow")) != 1:
raise ValueError("All `narrow` protocols must have the same user width")
if len(set(prot.user_width for prot in self.protocols if prot.type == "wide")) != 1:
Expand Down Expand Up @@ -575,8 +575,8 @@ def gen_routing_info(self):
f"Routing algorithm {self.routing.route_algo} is not supported yet"
)
self.routing.sam = self.gen_sam()
if self.routing.en_multicast:
self.routing.multicast_sam = self.gen_multicast_sam()
if self.routing.en_collective:
self.routing.collective_sam = self.gen_collective_sam()
# Provide the routing info to the network interfaces
for ni in self.graph.get_ni_nodes():
ni.routing = self.routing
Expand Down Expand Up @@ -660,26 +660,26 @@ def gen_sam(self):
rule_name = ni.endpoint.name
if addr_range.desc is not None:
rule_name += f"_{addr_range.desc}"
addr_rule = RouteMapRule(dest=dest, addr_range=addr_range, en_multicast=addr_range.en_multicast, desc=rule_name)
addr_rule = RouteMapRule(dest=dest, addr_range=addr_range, en_collective=addr_range.en_collective, desc=rule_name)
addr_table.append(addr_rule)
return RouteMap(name="sam", rules=addr_table)

def gen_multicast_sam(self):
"""Generate the multicast system address map, which contains additional mask
information."""
def gen_collective_sam(self):
"""Generate the collective system address map, which contains additional mask
information for collective endpoints."""
addr_table = []
for addr_rule in self.routing.sam.rules:
mask_fields = {}
if addr_rule.addr_range.en_multicast:
if addr_rule.addr_range.en_collective:
mask_offset_x = clog2(addr_rule.addr_range.size)
mask_fields = {
"mask_len": (self.routing.num_x_bits, self.routing.num_y_bits),
"mask_offset": (mask_offset_x + self.routing.num_y_bits, mask_offset_x),
"base_id": (addr_rule.dest.x - addr_rule.addr_range.arr_idx[0],
addr_rule.dest.y - addr_rule.addr_range.arr_idx[1]),
}
addr_table.append(RouteMapRuleMcast(**addr_rule.model_dump(), **mask_fields))
return RouteMap(name="mcast_sam", rules=addr_table)
addr_table.append(RouteMapRuleCollective(**addr_rule.model_dump(), **mask_fields))
return RouteMap(name="collective_sam", rules=addr_table)

def render_ports(self, pkg_name=""):
"""Render the ports in the generated code."""
Expand Down Expand Up @@ -707,8 +707,13 @@ def render_link_typedefs(self):
string += AXI4.render_cfg("AxiCfgN", narrow_in_prot, narrow_out_prot)
string += AXI4.render_cfg("AxiCfgW", wide_in_prot, wide_out_prot)

vc_num, phy_num = {
WideRwDecouple.PHYS: (2, 2),
WideRwDecouple.VC: (2, 1),
}.get(self.routing.decouple_rw, (None, None))
string += NarrowWideLink.render_typedefs(
narrow_in_prot.type_name(), wide_in_prot.type_name(), "AxiCfgN", "AxiCfgW"
narrow_in_prot.type_name(), wide_in_prot.type_name(), "AxiCfgN", "AxiCfgW",
vc_num, phy_num
)
else:
in_prot = next((prot for prot in self.protocols if prot.direction == "input"), None)
Expand Down
6 changes: 3 additions & 3 deletions floogen/model/network_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def is_only_mgr(self) -> bool:
"""Return true if the network interface is only a manager."""
return self.endpoint.is_mgr() and not self.endpoint.is_sbr()

def is_multicast_ni(self) -> bool:
"""Return true if the network interface supports multicast."""
return any([b for b in self.addr_range if b.en_multicast])
def is_collective_ni(self) -> bool:
"""Return true if the network interface supports collective operations."""
return any([b for b in self.addr_range if b.en_collective])

def render_enum_name(self) -> str:
"""Render the enum name."""
Expand Down
Loading
Loading