-
Notifications
You must be signed in to change notification settings - Fork 185
Description
I have a design with a top-level module that has a submodule it shares some signals with, about like the following:
class Foo(Elaboratable):
def elaborate(self, platform):
m = Module()
m.submodules.bar = bar = Bar()
m.submodules.led = led = io.Buffer("o", platform.request("led", 0, dir="-"))
m.d.comb += led.o.eq(bar.baz)
return m
class Bar(Elaboratable):
def __init__(self):
self.baz = Signal()
def elaborate(self, platform):
m = Module()
return mThis is simple enough, but now I'd like to add an Instance as a submodule within bar. Among other IO, this instance has a bidirectional inout port, so I've gone ahead and connected an IOPort to it:
class Bar(Elaboratable):
def __init__(self):
self.baz = Signal()
def elaborate(self, platform):
m = Module()
m.submodules += Instance(
"io", "qux", IOPort(1),
...
)
return mMy question is - if foo is my design's top-level module, what's the most idiomatic way to connect pins obtained via platform.request to my Instance within bar?
Ideally, I'd like to be able to assign the IOPort to some signal that's an attribute of Bar, and then use.eq to connect that to my top-level IO. However, the IOPort class has no .eq() method, so I'm not able to do this. If the signal didn't have to be bidirectional, I could pass a Signal instead of an IOPort in the Instance call and then use .eq(), but unfortunately this signal must be an inout.
Possible solutions I've thought of:
- Calling
platform.requestinBar.elaborate, and taking the pins and passing them to the instance. I can see this being confusing, since it would move some top-level wiring out ofFoo.elaborate, which I feel is the natural place for it. - Passing the IO pins to
Bar's constructor. This doesn't feel right either, as it kind of violates Amaranth's signals-are-members-of-their-modules paradigm.
I'm using Amaranth 0.5.0 on Ubuntu 22.04, if that matters at all. Thank you!