<d1b2>
<vipqualitypost> i'm not a super strong with python. would something like this work? class AlchitryIOPlatform(AlchitryCuPlatform, AlchitryAuPlatform):
<d1b2>
<vipqualitypost> and just extend both the base platforms?
<d1b2>
<vipqualitypost> no because then things like attr is broken because how would it know what use
<whitequark>
no, that, is not legal
<d1b2>
<vipqualitypost> ok maybe I just do like AlchitryIOCuPlatform etc and just have one for each
<whitequark>
you have to do it the other way around
<whitequark>
ie CuPlatform inheriting from IO mixin
<d1b2>
<vipqualitypost> oh
<d1b2>
<vipqualitypost> I was thinking to inherit from the CuPlatform so that I can use conn for generic pin numbering since that is the same for the io board.
<d1b2>
<vipqualitypost> doesn't CuPlatform inherit from IO make problesm if you are not using the IO shield then?
<d1b2>
<vipqualitypost> sorry I mean that if I use the "conn" in resources, I can use the generic pinout from both the Cu and Au board connectors
<whitequark>
can you do it for just Cu and then we can look at it in review maybe?
<d1b2>
<vipqualitypost> yes, I'll write something up and open a pr
<d1b2>
<vegard_e> I guess the problem would be similar for the colorlight sodimm form factor modules
<zyp[m]>
there's at least three different ones with different fpgas (ecp5-25, ecp5-45 and xc7a50) and a carrier board would take either
<d1b2>
<vipqualitypost> was that a problem already solved?
<d1b2>
<vipqualitypost> or just an existing issue with how to handle that
<d1b2>
<vipqualitypost> also: if attr is not provided on the resource, what is the default? i can't tell
<zyp[m]>
I'm not sure it's solved yet, but there's open PRs #148 and #184 attempting to add them
<zyp[m]>
looks pretty unsolved TBH
<d1b2>
<vipqualitypost> at least the two ecp5 are like similar family
<d1b2>
<vipqualitypost> this question of support from two different vendors seems tricky
<d1b2>
<vipqualitypost> i'll read through the prs
<zyp[m]>
the way I see it, there ought to be a clean and convenient way to compose modular platforms
<d1b2>
<vipqualitypost> true but realistically (especially outside the space of dev kits) how often do hardware share carriers between vendors? anyone making a real product i would imagine would stick to at least just one toolchain
<d1b2>
<vipqualitypost> so i agree but also i don't know if it's worth effort to try and fix the issue since the configs are one-and-done in a way.
<zyp[m]>
the colorlight boards aren't devkits, they're designed to be driver boards for LED matrix displays
<d1b2>
<vipqualitypost> oh!
<d1b2>
<vipqualitypost> i always thought the name was curious.. ha. makes sense
<zyp[m]>
but in any case, when you have a modular system, it makes sense to define each part of it as a separate reusable component
<d1b2>
<vipqualitypost> agreed
<d1b2>
<vipqualitypost> maybe connector should be changed from number to letter, then you just prefix the connector pin with the connector bank?
<d1b2>
<vipqualitypost> this way you can reference across connectors e.g. b1 b2 a3 a8
<d1b2>
<vipqualitypost> instead of right now "conn_name", [index] which is just composed of loose pins
<zyp[m]>
let's say I've got some resource on a common PMOD, if I stick that into a syzygy to PMOD adapter, mount that on a carrier card with a syzygy connector and then plug some fpga module into the carrier card, I'd like to be able to compose that from four known components
<zyp[m]>
especially if I didn't design any of those four components myself
<d1b2>
<vipqualitypost> sorry, not super familar with github- closed my original PR because it was built on main which made making the additional pr for the IO board tricky. everything should be ok now
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 246 seconds]
Degi_ is now known as Degi
toshywoshy has quit [Read error: Connection reset by peer]
toshywoshy has joined #amaranth-lang
<Chips4MakersakaS>
Will travelling today and likely won't make to IRC meeting.
<fl4shk[m]>
what happens in Amaranth if there's a latch? Does the backend have an effect on formal in this department?
<fl4shk[m]>
I would think so
<fl4shk[m]>
but I'm very confused as to why there's not a latch detected in my crossbar switch otherwise
<whitequark>
so, how would your design end up with a latch, normally?
<whitequark>
the frontend will infer it
<whitequark>
Amaranth is a frontend that never infers latches, it doesn't have code for it
<whitequark>
it just creates $dff cells
<fl4shk[m]>
oh
<whitequark>
if you don't assign a comb wire, it remains at its reset value
<fl4shk[m]>
oh great
<whitequark>
w = Signal(reset=<whatever is here>)
<fl4shk[m]>
that's exactly what I need
<fl4shk[m]>
That explains it then
<whitequark>
which is why it works that way :)
<fl4shk[m]>
That's great, thanks
<fl4shk[m]>
I'll just revert back to my previous code for my crossbar then
<whitequark>
the only problematic case you might hit is of a combinatorial loop
<whitequark>
where a comb variable bit depends on that exact bit
<whitequark>
this is not currently caught, though either yosys or nextpnr will yell at you if you try to synthesize it, in most cases
<fl4shk[m]>
I really just wanted signals I don't drive to be set to zero
<whitequark>
amaranth will catch this itself later this year
<whitequark>
ah yeah, that's the stock behavior.
<fl4shk[m]>
only in certain combinatorial paths
<whitequark>
it is almost time for our scheduled Monday meeting, I will need a few minutes to prepare though
<whitequark>
see you at 17:05 UTC or such
<fl4shk[m]>
it looks like my `Assert` is getting an error though
<fl4shk[m]>
oh, wait a minute, I get it
<whitequark>
okay, I'm back
<whitequark>
we have two RFCs on today's agenda. we won't be voting on them just yet as no implementation is available, but we are going to be discussing them
<whitequark>
the first item is the interfaces RFC, again, and this time it's not a draft anymore, meaning that I think it's broadly complete: https://github.com/amaranth-lang/rfcs/pull/2
<whitequark>
the changes from the previous Monday are: new dimensions property of members; splitting of apply into create_members and create; new Component class
<whitequark>
I would also like to discuss naming questions
<whitequark>
actually, no, a few people are missing, so those will be for the next Monday
<whitequark>
okay; looking forward to your feedback on the additions!
<whitequark>
galibert agg FL4SHK jfng zyp
<zyp[m]>
dimensions looks useful, and I expect those will then also work for connecting sub-interfaces like connect(m, interconnect.ports[3], foo.bus)
<whitequark>
yeah
<whitequark>
though usually you'll not address them like that because the interconnect will only count the interfaces in elaborate
<whitequark>
this is useful when you have an external component or a fixed number of ports
<galibert[m]>
hi
<cr1901>
I finally read the RFC yesterday in full; yea dimensions are a natural extension, tho I don't know if I'll personally use them.
<whitequark>
they're somewhat niche
<fl4shk[m]>
They may be niche, but I'll be using them
<jfng[m]>
what is an argument for ignoring a name conflict in Component.init ? it seems like overriding a dict entry would be quite serious ?
<fl4shk[m]>
anyone making an interconnect benefits from dimensions
<whitequark>
FL4SHK: take a look at the existing Arbiter class in -soc
<zyp[m]>
for an interconnect, you'll probably rather instance port interfaces dynamically than having them as part of the interconnect signature
<whitequark>
^ that
<whitequark>
jfng: it is not a good argument honestly
<whitequark>
oh, sorry, that was unclear
<whitequark>
I meant that it would just not assign the attribute if one was already assigned
<whitequark>
but this trains people to put `super().__init__` in the tail position in the constructor... which as galibert mentioned is kind of bad
<whitequark>
so I think it should probably be super().__init__ in the head position + if for some reason this is already assigned at that point, a hard error
<whitequark>
delete the attribute if you really need to get rid of it or something
<josuah>
then it is more explicit in the code
<jfng[m]>
not assigning the new attribute, seems OK ? like if it's there, it's either because we're actually using it, and if it breaks because e.g. it's not a signal, then it will be visible elsewhere
<fl4shk[m]>
zyp[m]: what exactly do you mean by this?
<jfng[m]>
agreed that an early super().init is easier, but i don't have a strong preference
<josuah>
fl4shk[m]: I think something about using dimensions to specify the total number of childs, vs using a helper function to add new childs one by one
<fl4shk[m]>
I looked at this earlier
<whitequark>
it depends on the type of interconnect
<fl4shk[m]>
I guess I'm just trying to be as general as possible
<josuah>
the name "forward" feels like an action, I would have guessed that it performs the connection as in: .forward(source, destination)
<josuah>
is there any other use-case where one would want to have the forwarded interface polarity without connecting it?
<whitequark>
if you have sth with a fixed geometry like a mesh or a torus, you might go for a .bus[0..4]
<whitequark>
* if you have sth with a fixed geometry like a mesh or a torus, you might go for a .bus[0..3]
<fl4shk[m]>
I prefer to not assume the interconnect itself isn't a submodule
<whitequark>
hm? the Arbiter above is a submodule
<fl4shk[m]>
s/isn't/is
<fl4shk[m]>
whitequark: right, yes
<zyp[m]>
in last week's meeting, it was mentioned that for optional signals on e.g. a wishbone interface you could have a method to add dummy signals to be able to hook it to an opposing component with a more full featured interface
<galibert[m]>
Would it be sane to think of a way to sequence Elaboratable/Component setup?
<whitequark>
josuah: ah good point. re use cases, the idea here is to have combinators rather than fixed function helpers to avoid a situation where you have two functions that do almost exactly the same thing
<whitequark>
forwarded or forwarding is an option
<zyp[m]>
if I understand it correctly that's not going to work with Component, as the signature will be frozen once it's constructed
<cr1901>
zyp[m]: Yea, this is also my question
<cr1901>
Additionally, there
<cr1901>
"For example, a signature ... could return ... attributes indicating which optional features of the bus are enabled."
<whitequark>
zyp: good point. I think we could move the freeze call from `create_members` to `create`
<whitequark>
this is actually how it's implemented in my prototype
<cr1901>
And there's the ability to add dummy signals _and_ the ability to change a signature
<cr1901>
(to connect a less featured interface to a more featureful one)
<cr1901>
How do all of these interact?
<whitequark>
I guess create_members is a building block and isn't expected to be called directly except when create is overridden
<zyp[m]>
Catherine: wouldn't `Component.__init__` still call both?
<whitequark>
so it's not an issue
<whitequark>
zyp: nope, since the object (self) already exists
<whitequark>
oh, you mean on the sub-interface
<zyp[m]>
yes, but the sub-interface objects doesn't
<whitequark>
yeah you're right, I missed the mark fundamentally here
<zyp[m]>
the problem isn't that the Component itself will be frozen, but that the sub-interfaces would be
<zyp[m]>
because those are what you'd like to mutate
<whitequark>
so conceptually, you only need to freeze the thing once you are making decisions based on what's inside, i.e. once you add some attributes (elaboration doesn't count) based on introspection
<whitequark>
I think we can limit the use of freeze to just that
<whitequark>
as long as almost all of your logic lives in elaborate you won't need to freeze anything then
<whitequark>
though, hm, no, what lives in .elaborate does matter... since you could mutate the signatures even there
<whitequark>
I guess connect has to call freeze then
<galibert[m]>
Could a series of method called on elaboratables grouped in succession on every elaboratable available at a point in time?
<zyp[m]>
the other solution I can see is to not mutate the interface, but instead have a method/attribute that returns a gasket
<galibert[m]>
I mean something like "before_interface_creation()", "create_interface()", "after_interface_creation()"
<galibert[m]>
create_interface, for components, would do the create/create_members
<whitequark>
galibert: I'm rather strongly opposed to that because of the combinatorial nightmare it'll create
<galibert[m]>
would it?
<whitequark>
if you've ever worked with any system featuring "hooks" or "run levels" you've seen it
<whitequark>
inevitably you need a new phase squeezed between two other phases
<whitequark>
if we're going to go for a dependency graph approach it needs to be expressed as a, well, graph
<whitequark>
but I don't think we need that
<galibert[m]>
Well, mame sequences devices bringup that way, it mostly works
<whitequark>
there is some degree of friction with sequencing in -soc, I want to see how our existing abstractions serve us before doing anything too drastic
<galibert[m]>
the idea was to allow methods that change the (future) signature, with a method that can be used as "ok, they're done, prepare the signature now"
<whitequark>
it's an inversion of .freeze, yes
<galibert[m]>
don't want to inverse freeze, just to delay when it happens
<whitequark>
I mean inversion like in inversion of control
<galibert[m]>
ah ok
<zyp[m]>
is freeze actually useful?
<whitequark>
good question
<whitequark>
if we provide introspection and mutation and allow people to generate code based on introspection, then we need freeze
<whitequark>
but we could get rid of mutation instead
<whitequark>
imo, the easiest way to decide is to finish the interfaces RFC prototype and then implement wishbone on top of it, and see how we can handle the optional features
<whitequark>
then rip things out as seems well
<galibert[m]>
not sure you need freeze. You can just say they get to keep all 256 pieces if they do something stupid
<josuah>
is there a typo in here or did I discover something new from Python?
<whitequark>
you can also just use Verilog then :p
<zyp[m]>
at what point do we need a signature to be frozen? just connect()?
<whitequark>
zyp: any time someone takes decisions based on how .signature() looks
<zyp[m]>
and when we're on the topic of guarding against stupid stuff, should we do anything about guarding against double connect()?
<whitequark>
josuah: a typo
<jfng[m]>
also, i think that the "chicken and egg" issues that may arise in amaranth-soc are in parts of the codebase that would be directly affected by an interface rewrite
<cr1901>
I think I need to see an example using freeze, as I don't write introspection-heavy code (because I'm not good at it).
<whitequark>
zyp: good question. we don't guard against double assignment in plain code. I think we could introduce a warning that covers both
<whitequark>
I don't think this should be an error
<cr1901>
Guide-level explanation is great, but no example of freeze
<galibert[m]>
Do you mean connect(a, b, c) is not equivalent to connect(a, b) connect(a, c) ?
<galibert[m]>
(sprinkle m everywhere)
<whitequark>
no, like `m.d.comb += connect(a,b), connect(a,b)
<whitequark>
* no, like `m.d.comb += connect(a,b), connect(a,b)`
<whitequark>
* connect(a,b), connect(a,b)\`
<whitequark>
* connect(a,b), connect(a,b)`
<whitequark>
whatever we do for double connect we should also do for double eq, for the same reasons
<galibert[m]>
is there a way to distinguish connect(a, b)*2 from (a, b) + (a, c)?
<whitequark>
uh, the former doesn't have c at all?
<galibert[m]>
unless c=b
<whitequark>
they result in completely different netlists so no issue distinguishing them
<whitequark>
well sure
<galibert[m]>
you mean for the implementation the difference is obvious? If yes, perfect
<zyp[m]>
I was thinking about the difference between connect(m, a, b, c) vs connect(m, a, b); connect(m, a, c)
<whitequark>
so semantically connect(a,b),connect(a,b) is the same as `connect(a,b)~
<whitequark>
s//`/, s//`/, s/~/`/
<whitequark>
meaning it won't break your design if you do that
<whitequark>
but it might be indicative of a typo elsewhere, hence a warning being an option
<zyp[m]>
since the former is legal under certain conditions, but I assume we don't have the same checks for the latter
<whitequark>
zyp: warnings are cross-cutting and violate abstraction boundaries, I think when/if we add a warning it'll look at the list of eq/connect statements or something
<whitequark>
instead of looking at the netlist directly
<whitequark>
are we all in agreement on the 'meat' of the RFC?
<whitequark>
the basic functionality?
<whitequark>
agg expressed some doubts about the core functionality earlier
<zyp[m]>
I like it
<fl4shk[m]>
I like it
<galibert[m]>
I think we're at the point where we have to actually play with it
<whitequark>
I have like half of the implementation cooked up :)
<whitequark>
it's surprisingly diagnostic heavy
<cr1901>
No complaints about core functionality, worried about how to handle "the wishbone problem"
<jfng[m]>
it seems nice, i especially like the new Component class
<jfng[m]>
but i'd really need to use it, in order to wrap my head around it
<whitequark>
14 different diagnostics and it's not quite done yet
<whitequark>
cr1901: yeah we're not merging it until we figure that part out
<whitequark>
okay, looks like there's an unanimous consensus that we need the implementation
<galibert[m]>
I don't like the new component class, I'd like it to just be elaboratable, but I can live with either
<cr1901>
If you have a complete impl, I'd still be interested in playing with it just to see how I'd handle "the wishbone problem" (and then you can tell me what I did wrong :P)
<whitequark>
galibert: noted, I'll add it into the alternatives section
<cr1901>
Yes, I need to play w/ an impl to give more constructive feedback. Even if that means the impl breaks and I have to change my core
<fl4shk[m]>
Same here
<galibert[m]>
mostly because eventually everything should end up a component, and why losing the elaboratable class in practice? I mean, the method is going to stay named elaborate
<whitequark>
a Module is also an Elaboratable
<galibert[m]>
forgot what a Module is
<josuah>
galibert[m]: Could you point me where is Component class referred? I feel stupid but cannot find it in 0002-interfaces.md
<galibert[m]>
cr1901 technically, a comb signal takes reset value at Module creation, and the select doesn't change it
<adamgreig[m]>
I think the only doubt I had was around the "enforced .signature that gets auto applied to all elaboratables" but that's quite outdated now, I'll review the updated rfc but overall I'm very excited to see the draft impl and try it out
<whitequark>
I wasn't sure what to do about that but I think if we really want it we can easily introduce it in 2 release cycles
<whitequark>
which shouldn't be a huge problem
<galibert[m]>
I'm surprised Module is an Elaboratable, it just blows what I understand Elaboratable to be, but whatever :-)
<adamgreig[m]>
I think it might well make sense, but I was worried about the module's signature/interface being fixed in the initialiser and not able to be changed between initialisation and elaboration
<adamgreig[m]>
for things like a bus mux where you create it and then you connect a bunch of things later with methods. but in those cases I don't think the interface needs to actually change, since it's probably just the "output" side
<galibert[m]>
adamgreig: it's more like a thing with a bunch of options and you want to avoid a bunch of keywords in the constructor
<whitequark>
adamgreig: that was never the plan; the signature would get checked during elaboration
<whitequark>
and not after initialization
<whitequark>
but I think that wasn't clearly communicated
<cr1901>
galibert[m]: I didn't say the reset value changes, I said "select will change the value that the comb signal is driven by"
<adamgreig[m]>
yea, I don't think this is a live concern, it came up a few weeks ago when that detail wasn't clear
<galibert[m]>
Catherine: the problem was when freeze happened
<galibert[m]>
cr1901: I didn't say that either. It's just that there's no special case for "unhandled case in a switch". The reset value is the default, but if the comb was set to something before the switch then the something is the new default case
<whitequark>
(there's nothing special about switch either)
<galibert[m]>
nope, it's the usual "last assign wins"
<galibert[m]>
last enabled assign wins to be fully pedantic
<cr1901>
"Well, it actually took the value I assigned instead of the reset value of the Signal" <-- unconditional last assignment
<galibert[m]>
ok, people are going to be waiting for me, need to move, later nice people
<whitequark>
yeah the time is up
<whitequark>
thanks for everyone! and I guess we'll get to the CSR RFC next Monday
<jfng[m]>
i can work on a prototype in the meantime, it's not a blocker
<whitequark>
yep!
<josuah>
thank you for the long-term effort involved for putting this up everyone!
<fl4shk[m]>
I am really looking forward to using this
tannewt_ has quit [Ping timeout: 255 seconds]
tannewt_ has joined #amaranth-lang
zyp[m] has quit [Ping timeout: 255 seconds]
galibert[m] has quit [Ping timeout: 255 seconds]
fl4shk[m] has quit [Ping timeout: 255 seconds]
robtaylor has quit [Ping timeout: 255 seconds]
<cr1901>
whitequark: Do you have the git SHA of the interface RFC from _before_ the change you made 6 hours ago? I want to compare/contrast, but looks like you rebased and force pushed
<d1b2>
<miek__> it was e59ee8a102eadc9e9331d9aa9b0c50bc46db85b0 - before/after SHAs for any force-push are shown in the PR, plus a "Compare" link