Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib.wiring: Add path argument to Component constructor #1517

Closed
wants to merge 1 commit into from

Conversation

rroohhh
Copy link
Contributor

@rroohhh rroohhh commented Sep 20, 2024

No description provided.

@whitequark
Copy link
Member

This is clearly new functionality that would normally require an RFC. What's the use case?

@rroohhh
Copy link
Contributor Author

rroohhh commented Sep 20, 2024

Ah okay, I was expecting RFC being only used for bigger features. My motivation is mainly nicer naming for the "ports" of programmatically created Components. For example something like this:

#!/usr/bin/env python3

from amaranth import Module
from amaranth.lib import wiring, stream
from amaranth.back.verilog import convert

class A(wiring.Component):
    stream: wiring.In(stream.Signature(1))

    def __init__(self, name):
        super().__init__(path=[name])

    def elaborate(self, _):
        return Module()

m = Module()

ports = []
for dir in ["north", "south"]:
    a = m.submodules[f"{dir}_a"] = A(name=dir)
    ports.append(a.stream.ready)
    ports.append(a.stream.valid)
    ports.append(a.stream.p)

print(convert(m, ports=ports))

generates

module top(north__stream__valid, north__stream__payload, south__stream__ready, south__stream__valid, south__stream__payload, north__stream__ready);
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:48" *)
  input north__stream__payload;
  wire north__stream__payload;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:50" *)
  input north__stream__ready;
  wire north__stream__ready;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:49" *)
  input north__stream__valid;
  wire north__stream__valid;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:48" *)
  input south__stream__payload;
  wire south__stream__payload;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:50" *)
  input south__stream__ready;
  wire south__stream__ready;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:49" *)
  input south__stream__valid;
  wire south__stream__valid;
endmodule

And without this it creates

module top(stream__valid, stream__payload, \stream__ready$3 , \stream__valid$4 , \stream__payload$5 , stream__ready);
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:48" *)
  input stream__payload;
  wire stream__payload;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:48" *)
  input \stream__payload$5 ;
  wire \stream__payload$5 ;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:48" *)
  wire \stream__payload$8 ;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:50" *)
  input stream__ready;
  wire stream__ready;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:50" *)
  input \stream__ready$3 ;
  wire \stream__ready$3 ;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:50" *)
  wire \stream__ready$6 ;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:49" *)
  input stream__valid;
  wire stream__valid;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:49" *)
  input \stream__valid$4 ;
  wire \stream__valid$4 ;
  (* src = "/data/projects/amaranth/amaranth/lib/stream.py:49" *)
  wire \stream__valid$7 ;
  assign \stream__ready$6  = \stream__ready$3 ;
  assign \stream__valid$7  = \stream__valid$4 ;
  assign \stream__payload$8  = \stream__payload$5 ;
endmodule

@whitequark
Copy link
Member

I would suggest grabbing the signatures of the components, adding them to the toplevel, and then connecting them in the toplevel elaborate. The reason a component doesn't have a path argument is because a component stands alone; it is not a part of a bigger interface.

@whitequark
Copy link
Member

Ah okay, I was expecting RFC being only used for bigger features.

A change to the signature of a class every Amaranth program uses is a pretty big change!

@rroohhh
Copy link
Contributor Author

rroohhh commented Sep 20, 2024

Sorry, maybe my example was a bit confusing because of the convert(ports=...).
To be clear, I don't really care about those. In my actual usecase care about the how things are called in the waveform viewer in the middle of the hierarchy.
Here: https://github.com/rroohhh/routey/blob/258940a38bf4edfb5ddce25a2e57d2bc81cd0d1e/memory_mapped_router.py#L334
I add the Components whose path I want to specify, because I want to achieve is, that the wires, etc created here: https://github.com/rroohhh/routey/blob/258940a38bf4edfb5ddce25a2e57d2bc81cd0d1e/memory_mapped_router.py#L260-L264 are named accordingly.

But maybe this is just me misusing this somehow.

@whitequark
Copy link
Member

Sorry, now I'm a lot more confused. Don't you have the components themselves in the hierarchy too?

@rroohhh
Copy link
Contributor Author

rroohhh commented Sep 20, 2024

Yes, I do. But when looking at it in a waveform viewer this requires more non local thinking, because to get readable names, I then have to add some signals from the Crossbar and some signals from where the InputChannels are placed in the hierarchy.
For example compare these two screenshots:
20240920_19h22m04s_grim
20240920_19h22m31s_grim

@whitequark
Copy link
Member

I think this is definitely the wrong thing to expose in the surface-level API; we should probably improve the namer instead.

@rroohhh
Copy link
Contributor Author

rroohhh commented Sep 26, 2024

ill wait for improvements in the namer then

@rroohhh rroohhh closed this Sep 26, 2024
@rroohhh rroohhh deleted the component_signature_path branch September 26, 2024 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants