Skip to content

Commit

Permalink
Add component attributes to builder (#1927)
Browse files Browse the repository at this point in the history
* Attempt at generalizing attributes

* Add component attribute support to builder

* update invoke.py in test/

* typo fix in docs

* Attempt to add backwrd compatability
  • Loading branch information
nathanielnrn authored Feb 19, 2024
1 parent 0992141 commit 41bb3fe
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 5 deletions.
6 changes: 6 additions & 0 deletions calyx-py/calyx/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __init__(
self.prog = prog
self.component: ast.Component = ast.Component(
name,
attributes = [],
inputs=[],
outputs=[],
structs=cells,
Expand Down Expand Up @@ -112,6 +113,11 @@ def output(self, name: str, size: int) -> ExprBuilder:
self.component.outputs.append(ast.PortDef(ast.CompVar(name), size))
return self.this()[name]

def attribute(self, name: str, value: int) -> None:
"""Declare an attribute on the component.
"""
self.component.attributes.append(ast.CompAttribute(name, value))

def this(self) -> ThisBuilder:
"""Get a handle to the component's `this` cell.
Expand Down
24 changes: 21 additions & 3 deletions calyx-py/calyx/py_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def doc(self) -> str:
@dataclass
class Component:
name: str
attributes : list[Attribute]
inputs: list[PortDef]
outputs: list[PortDef]
wires: list[Structure]
Expand All @@ -59,11 +60,13 @@ def __init__(
outputs: list[PortDef],
structs: list[Structure],
controls: Control,
attributes: Optional[list[CompAttribute]] = None,
latency: Optional[int] = None,
):
self.name = name
self.attributes = attributes
self.inputs = inputs
self.outputs = outputs
self.name = name
self.controls = controls
self.latency = latency

Expand All @@ -86,15 +89,30 @@ def doc(self) -> str:
ins = ", ".join([s.doc() for s in self.inputs])
outs = ", ".join([s.doc() for s in self.outputs])
latency_annotation = (
f"static<{self.latency}> " if self.latency is not None else ""
f"static<{self.latency}> " if self.latency is not None else ""
)
signature = f"{latency_annotation}component {self.name}({ins}) -> ({outs})"
attribute_annotation = f"<{', '.join([f'{a.doc()}' for a in self.attributes])}>" if self.attributes else ""
signature = f"{latency_annotation}component {self.name}{attribute_annotation}({ins}) -> ({outs})"
cells = block("cells", [c.doc() for c in self.cells])
wires = block("wires", [w.doc() for w in self.wires])
controls = block("control", [self.controls.doc()])
return block(signature, [cells, wires, controls])


#Attribute
@dataclass
class Attribute(Emittable):
pass

@dataclass
class CompAttribute(Attribute):
name: str
value: int

def doc(self) -> str:
return f"\"{self.name}\"={self.value}"


# Ports
@dataclass
class Port(Emittable):
Expand Down
7 changes: 6 additions & 1 deletion calyx-py/test/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@

# Create the component.
main_component = Component(
name="main", inputs=[], outputs=[], structs=cells + wires, controls=controls
name="main",
attributes=[],
inputs=[],
outputs=[],
structs=cells + wires,
controls=controls,
)

# Create the Calyx program.
Expand Down
7 changes: 6 additions & 1 deletion calyx-py/test/if.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@
controls = If(CompPort(lt, "out"), cond, Enable(true), Enable(false))

main_component = Component(
name="main", inputs=[], outputs=[], structs=cells + wires, controls=controls
name="main",
attributes=[],
inputs=[],
outputs=[],
structs=cells + wires,
controls=controls,
)

# Create the Calyx program.
Expand Down
2 changes: 2 additions & 0 deletions calyx-py/test/invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

foo_component = Component(
name="foo",
attributes=[],
inputs=[PortDef(CompVar("a"), 32)],
outputs=[PortDef(CompVar("out"), 32)],
structs=foo_cells + foo_wires,
Expand Down Expand Up @@ -83,6 +84,7 @@

main_component = Component(
name="main",
attributes=[],
inputs=[],
outputs=[],
structs=cells + wires,
Expand Down
15 changes: 15 additions & 0 deletions docs/builder/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ def add_my_component(prog):

Note that it's possible to [create a handle][hndl] to input and output ports.

### Defining Component Attributes

Components can be given attributes. Similar to ports, just specify the name of the attribute and its value.
Note that `attribute(name, value)` does not return a handle to the attribute.

```python
my_component.attribute("my_attribute", 1)
```

Will create a component that looks like:

```
component my_component<"my_attribute"=1>(...) -> (...) {
```

### Multi-Component Designs

Calyx supports [multi-component designs][multi]. The [top-level example][top] demonstrates how to construct multi-component designs using the library.
Expand Down

0 comments on commit 41bb3fe

Please sign in to comment.