wehnelt[m] has quit [Quit: Idle timeout reached: 172800s]
mindw0rk has quit [Ping timeout: 246 seconds]
mindw0rk has joined #amaranth-lang
notgull has quit [Ping timeout: 244 seconds]
notgull has joined #amaranth-lang
bl0x[m] has joined #amaranth-lang
<bl0x[m]>
@whitequark I won't be able to contribute to https://github.com/amaranth-lang/amaranth-boards/pull/208 for the next couple of weeks. If you'd like to make progress there, please feel free to do so. I'll be away from keyboard.
<whitequark[cis]>
I don't have a board so it's not something I can complete
<Chips4MakersakaS>
<whitequark[cis]> "there are some FPGAs with..." <- Mmm, did plan to do eventually something with my ZynqBerry though and thought about involving Amaranth.
<whitequark[cis]>
it is fine if you are an expert developer
<whitequark[cis]>
if you are a novice, picking Zynq will likely result in misery
<whitequark[cis]>
I am sure you can get ZyngBerry to work with Amaranth and it will probably not even be that much work for you, given your years of experience
<Wanda[cis]>
mmm zynq with amaranth was ... an experience
<Wanda[cis]>
<del>guess who was insane enough to skip bootgen entirely and bootstrap the ARM part herself</del>
<whitequark[cis]>
oh nice
<Wanda[cis]>
it wasn't even that bad
<Wanda[cis]>
though it made me wish we had some system that could collect resource requests for eg. individual AXI ports and create a PL7 singleton instance with appropriate "signal terminators" installed for all unconnected ports
<Wanda[cis]>
like, that seems to be the missing piece to make using it actually nice
<galibert[m]>
Wanda: I want to do the same kind of insanity with the cyclonev but the ddr init code is “interesting “
<whitequark[cis]>
yes, we should have this in the new platform system
<Wanda[cis]>
and it'd have benefits outside of hart processor support too, like resolving the conflict between user gateware wanting to use STARTUP on Xilinx and the XilinxPlatform code using it
<whitequark[cis]>
yes
<whitequark[cis]>
there is an open issue for this iirc
<Wanda[cis]>
galibert: oh yes I didn't get to ddr init code, I just decided that 256kiB of on-chip RAM Should Be Enough For Everyone
<whitequark[cis]>
if someone's looking for a project, picking up a redesign of the platform system is a viable one
<whitequark[cis]>
you haven't replied earlier so I'm not sure why you would be included without that...
<cr1901>
B/c I thought it was a mental list you used of "ppl mostly present at the meetings"
<whitequark[cis]>
it's more a list of people who I expect to be present at meetings (two are my colleagues at ChipFlow for example)
<cr1901>
Aaaaah, I see I see, sorry about that
<whitequark[cis]>
anyway, we have an administrative matter to take care of first
<whitequark[cis]>
Amaranth SoC has grew enough to need its own meeting to discuss its design and RFCs
<whitequark[cis]>
for the last few weeks I've had health issues and wasn't very present but we won't be able to discuss CSRs today due to time constraints
<whitequark[cis]>
my proposals are any of Wed, Thu, Fri, at the same UTC time picked for convenience of international attendees
<galibert[m]>
Hope you’re getting better
<whitequark[cis]>
galibert: thanks
<whitequark[cis]>
JF, your view? any others chiming in?
<whitequark[cis]>
Staf, what is your calendar like?
<Chips4MakersakaS>
Not on Thu.
<whitequark[cis]>
JF: your call between Wed and Fri I think
<jfng[m]>
i have a preference for friday, as the early part of the week already has a few chipflow-related meetings
<cr1901>
FWIW, I prefer Fri, b/c I get a break from meetings (Tues I have meetings unrelated to Amaranth). But chipflow employees take priority
<whitequark[cis]>
ideally we would pick a time that suits everyone, though of course with an open attendance that's not really feasible
<jfng[m]>
in addition, i believe we should put a stronger emphasis on GH comments, as the main medium of discussion
<whitequark[cis]>
I agree with JF
<whitequark[cis]>
I think one thing we are missing right now is a way to tell people "this RFC needs your attention now"
<jfng[m]>
GH comments will let reviewers take the time to get acquainted with RFC contents, and the devil can be in the details
<whitequark[cis]>
a weekly newsletter would be one such way, but it's not something we do (yet)
<galibert[m]>
jfng: I don’t disagree but I find those meetings impressively productive to hash out things
<whitequark[cis]>
I think we need a more organized process in every way
<whitequark[cis]>
for example, real meeting minutes instead of just IRC logs
<whitequark[cis]>
I'll create a repo and a format for these for the next week's meetings
<galibert[m]>
Would someone read them ?
<jfng[m]>
i think so too, but personally i have a very hard time to really suggest anything productive, if i don't have the full context
<jfng[m]>
and i get that by taking the time to read an RFC/PR/etc
<crzwdjk>
I probably would
<whitequark[cis]>
galibert[m]: they are important as a condensed recording of the discussion and conclusions
<whitequark[cis]>
IRC logs are not really readable
<whitequark[cis]>
in addition, meetings can have action items that should be reviewed on the next one
<crzwdjk>
It's good to have a more readable record of what was actually decided in the meetings
<galibert[m]>
I tend to check the matrix log, @Work for me for now
<galibert[m]>
I may be a little too online though
<cr1901>
Will you derive the minutes after-the-meeting from the IRC logs, or expect someone to write them down in real-time?
<Chips4MakersakaS>
For me having an overview issues open and closed would help a lot; don't have much bandwidth for Amaranth stuff.
<Chips4MakersakaS>
* an overview of issues open
<whitequark[cis]>
I think it would probably work best if the person conducting the meeting takes the minutes
<whitequark[cis]>
though this can introduce some delay sadly
<whitequark[cis]>
I would like us to not have a meeting about a meeting right now since Staf is leaving early
<galibert[m]>
I expect to try playing with your implementation starting next week
<whitequark[cis]>
does anyone have questions or comments?
<whitequark[cis]>
we won't be voting on the proposal yet, instead I would like to bring it to everyone's attention again and see if there are any unresolved questions
<whitequark[cis]>
zyp, you had concerns about "forwarding" connections, does the current draft resolve those?
<zyp[m]>
any recent significant changes apart from the name?
<galibert[m]>
Did you stumble on some while implementing?
<zyp[m]>
whitequark[cis]: I'm happy with `forward()`
<whitequark[cis]>
signature.create() cannot create an empty object() to use its dictionary so now there is an empty class Interface that serves the same role
<whitequark[cis]>
you don't have to inherit from it though it would make intent clear if you do
<whitequark[cis]>
(and if we get it annotated with types, the type of `create()` in the base class should be `-> Interface`, so you probably should inherit from it)
<whitequark[cis]>
I've pruned some of the now clearly bad alternatives/questions
<whitequark[cis]>
I've changed the name to something shorter that reads better (it is now lib.wiring)
<whitequark[cis]>
zyp: oh, and I rewrote the spec for `connect()` after actually implementing it
<whitequark[cis]>
in the end, it looks like connect will be well poisted to implement wired-OR or wired-AND buses
<whitequark[cis]>
s//`/, s//`/, s/poisted/poised/
<jfng[m]>
referencing the `.signature` of a `Member` raises a `TypeError`, depending on whether it was instantiated from a shape-castable or a `Signature`
<jfng[m]>
i find the `TypeError` a bit surprising here, why not `AttributeError` ?
<whitequark[cis]>
the Member class is a discriminated union
<whitequark[cis]>
and you are accessing it using the wrong type of the inner value
<whitequark[cis]>
I think there is not much case for using AttributeError for accessing an attribute that exists (it is an existing property) but is invalid to access
<zyp[m]>
ah, there was one point I noticed the other day
<zyp[m]>
> For each given path where all members are port members, the reset values of all members with the same path must match.
<zyp[m]>
is this a good idea?
<whitequark[cis]>
this is done to avoid ever having a situation where you would have reset values "fighting"
<whitequark[cis]>
I think that might be eased to "reset values of all In members must match`
<zyp[m]>
I mean, I get the intent, but it also seems like a way to accidentally make interfaces incompatible
<whitequark[cis]>
s//`/, s//`/, s/`/\"/
<whitequark[cis]>
I think if you want to have an interface that has well defined compatibility you should make a subclass of Signature
<cr1901>
Re: the unresolved q, I like the idea of flatten returning "something" you can iterate/getitem over, rather than have Signature have __iter__ and __getitem__.
<whitequark[cis]>
the use cases for __getitem__ would not be covered by flatten
<whitequark[cis]>
i.e. even if we remove __iter__ it is possible to have a reason for __getitem__ to exist
<whitequark[cis]>
it is unclear to me whether such a reason is there
<zyp[m]>
I think it's useful to be able to iterate both over a given level in the hierarchy and the flattened hierarchy
<whitequark[cis]>
__iter__ would currently yield the flattened hierarchy
<zyp[m]>
that seems less intuitive
<cr1901>
^this
<cr1901>
(well, to me anyway)
<whitequark[cis]>
if you only need to iterate over one given level you can iterate over members
<cr1901>
I wouldn't expect __iter__ to recursively iter- and I see you just got to that
<whitequark[cis]>
the only real use case for __getitem__ is hierarchical access like sig["a", "b", 1]
<jfng[m]>
> Should Signature.__iter__ and Signature.__getitem__ exist, or should they be combined and moved to SignatureMembers[Flipped].flatten?
<jfng[m]>
i'm not sure if single-level iteration is a common use-case
<jfng[m]>
iirc, most times i needed to iterate Records, it was done recursively
<jfng[m]>
otoh, when i needed to, it was because of issues that motivated this RFC
<whitequark[cis]>
what about hierarchical access?
<whitequark[cis]>
in this case it would be for Layout
<jfng[m]>
Layout ?
<whitequark[cis]>
the equivalent of Interface is Record, the equivalent of Signature is Layout
<whitequark[cis]>
Staf, any comments from you before you go?
<jfng[m]>
whitequark[cis]: > signature.__getitem__(*path) looks up a member by its path. The flow of the member is flipped as many times as there are In signatures between the topmost signature and the signature of the member.
<jfng[m]>
isn't that already the case ?
<Chips4MakersakaS>
No, I don't have open q on RFC2
<whitequark[cis]>
thank you
<whitequark[cis]>
jfng: sorry, I'm confused
<whitequark[cis]>
I am asking whether we should keep hierarchical access via __getitem__
<whitequark[cis]>
however it is not a feature that was ever included in hdl.rec
<zyp[m]>
seems like a feature that's maybe easier to add in later if it turns out it's a good idea, than to remove if it turns out that it's not
<whitequark[cis]>
all right, let's axe that
<jfng[m]>
agreed, let's see what happens while we port our respective codebases
<whitequark[cis]>
any additional non-naming comments?
<cr1901>
As for the rest, weak preference for flatten() over __iter__, for parity with members()
<whitequark[cis]>
members is a property, not a method
<whitequark[cis]>
and flatten wasn't actually under question
<jfng[m]>
are there cases where Signature.freeze is called implictly (besides from an upper call in its hierarchy) ?
<whitequark[cis]>
no, but I think that is an omission and it should be called in connect
<whitequark[cis]>
I'm not completely certain though
<whitequark[cis]>
the original case for freeze was "this code, which got passed an interface, is going to compute and store some properties of this interface in a way that is difficult to update"
<jfng[m]>
what's the worse that could happen if e.g. one modifies a component's signature after calling connect ?
<jfng[m]>
is that even likely ?
<whitequark[cis]>
it's up to opinion whether connect does that
<jfng[m]>
i'd do it, imo
<whitequark[cis]>
jfng[m]: > <@jfng:matrix.org> what's the worse that could happen if e.g. one modifies a component's signature after calling connect ?
<whitequark[cis]>
> is that even likely ?
<whitequark[cis]>
you could be calling `elaborate` multiple times with the same gateware
<whitequark[cis]>
e.g. build for several platforms
<whitequark[cis]>
if you add items to signatures inside elaborate then this will be caught
<jfng[m]>
but elaborate wouldn't modify a signature, right ?
<whitequark[cis]>
well... it's arbitrary code
<whitequark[cis]>
so it could
<jfng[m]>
yeah
<jfng[m]>
as long as implicit calls to freeze are documented, i think it's ok
<Chips4MakersakaS>
OK, heading off. CU next time.
<jfng[m]>
(to do it in connect)
<zyp[m]>
is there anything guarding against connecting an interface multiple times? (and should there be?)
<whitequark[cis]>
I think we could do an implicit call to connect() to assert that signatures are really not supposed to be modified after they're connected
<whitequark[cis]>
I think this is good for safety
<whitequark[cis]>
the bugs this would create would be really difficult to find
<whitequark[cis]>
zyp: it is legal to connect an interface multiple times
<whitequark[cis]>
e.g. in a multiplexer
<whitequark[cis]>
doing this twice in a row is an error we should probably flag, but we have no capability to do so at the moment
<whitequark[cis]>
this code is very useful, as it's not easily reproduced any other way
<zyp[m]>
yeah, I can't come up with something that'd be easily detectable as obviously wrong
<whitequark[cis]>
any more comments or questions on semantics?
<cr1901>
None on my end
<jfng[m]>
ok for me
<whitequark[cis]>
any objection to self in signature.flip().foo() being a FlippedSignature (and not whatever the class of self would normally be)?
<zyp[m]>
that seems reasonable as long as everything is sanely proxied
<whitequark[cis]>
FlippedSignature is supposed to be a transparent proxy, but you can also check if a method is being called on a flipped signature (in the rare case it's needed) with type(self) == FlippedSignature or something. or inherit from FlippedSignature and overriding flip
<jfng[m]>
is there a way to retrieve the original class of the FlippedSignature ?
<whitequark[cis]>
.flip() it again
<zyp[m]>
do you still get a FlippedSignature if you call signature.flip().flip() or do you get the original?
<whitequark[cis]>
just answered that :)
<zyp[m]>
:)
<whitequark[cis]>
alright, I think we can spend the last 7 minutes on bikeshedding
<whitequark[cis]>
does anyone have better options than lib.wiring? I was also thinking lib.bus
<whitequark[cis]>
I want it to be short and catchy like lib.data
<whitequark[cis]>
lib.intf is ugly as hell
<cr1901>
lib.bus is nice
<whitequark[cis]>
lib.component is very long and also the fully-qualified lib.component.In doesn't make sense really
<whitequark[cis]>
we're using interfaces more widely than just buses so I'm a bit worried lib.bus would be misleading
<crzwdjk>
I think wiring is fine, and yeah, it's not necessarily a "bus"
<whitequark[cis]>
lib.wiring is in a way opposite to lib.data: lib.data does not talk about wires at all, and lib.wiring is all about wires
<jfng[m]>
> Should amaranth.lib.wiring be called something else, like amaranth.lib.bus or amaranth.lib.component?
<jfng[m]>
`bus` is short, but not every interface is a bus interface; `component` (or module, really) puts too much emphasis on the things being interfaced, rather than the interfaces
<jfng[m]>
* > Should amaranth.lib.wiring be called something else, like amaranth.lib.bus or amaranth.lib.component?
<jfng[m]>
`bus` is short, but not every interface is a bus interface; `component` (or module, really) puts too much emphasis on the things being interfaced, rather than the interfaces
<whitequark[cis]>
good point JF
<crzwdjk>
lib.wiring is how you wire your components together
<jfng[m]>
i like wiring, it is concise
<whitequark[cis]>
amazing, I actually came up with a name (eventually) that no one dislikes
<whitequark[cis]>
unless cr1901 hates it
<whitequark[cis]>
oh zyp did not comment yet
<cr1901>
I like bus better, but I'm not gonna die on that hill
<cr1901>
wiring is fine
<whitequark[cis]>
I guess my point is mostly that bus is not the opposite of data, but wiring is
<whitequark[cis]>
zyp?
<cr1901>
Now, that is fair
<zyp[m]>
I'm not sure I like it, but I don't have a better suggestion
<cr1901>
what about lib.wire :P?
<whitequark[cis]>
I felt meh about it for a while
<whitequark[cis]>
wire.Signature is weird
<whitequark[cis]>
wiring.In is ... ok, wiring.Signature is fine, wiring.connect is perfect, wiring.Interface is fine
<whitequark[cis]>
In and Out will probably be imported on their own anyway
<jfng[m]>
i wouldn't want the bus keyword to already be taken in my namespaces
<whitequark[cis]>
also good point
<whitequark[cis]>
I think we can scratch bus off the list
<whitequark[cis]>
seems no one has better ideas at least, let's go with wiring (this is a draft anyway)
* cr1901
nods
<whitequark[cis]>
I have come up with wiring months ago and I initially discarded it in favor of component
<whitequark[cis]>
but it grew on me and I stopped liking component
<whitequark[cis]>
what about Signature.compatible?
<jfng[m]>
this is a test right ? how about is_compatible ?
<zyp[m]>
how is it called?
<whitequark[cis]>
right now the function that checks if an object is compatible with a given signature is called just compatible
<whitequark[cis]>
so you would have e.g. AXI4Interface.compatible(some_obj)
<whitequark[cis]>
we could do AXI4Interface.is_compatible(some_obj)
<whitequark[cis]>
or AXI4Interface.is_implemented_by(some_obj)
<zyp[m]>
what about when you want to check if two signatures are compatible?
<whitequark[cis]>
==
<whitequark[cis]>
well, actually, not exactly, since you can have a difference in shapes
<jfng[m]>
matches ... ? it may be ambiguous though
<zyp[m]>
I mean, «compatible» could mean that two signatures could be connected together
<jfng[m]>
yeah, but from the name alone idk if its a test, or a factory, etc
<whitequark[cis]>
the check for that is almost identical to an equality check
<zyp[m]>
when checking if an object is compliant to a signature, directions also matters
<whitequark[cis]>
right
<whitequark[cis]>
does is_implemented_by seem better?
<jfng[m]>
complies_with ?
<zyp[m]>
seems less ambiguous
<jfng[m]>
whitequark[cis]: verbose, imo
<zyp[m]>
complies_with gets the subject and object wrong
<jfng[m]>
ah, right
<jfng[m]>
it is backward
<zyp[m]>
but otherwise I like it
<whitequark[cis]>
jfng: I think that check will be rarely used
<whitequark[cis]>
mostly in already verbose error checking code in constructors
<whitequark[cis]>
there and in connect() implicitly
<jfng[m]>
in that case, is_implemented_by is probably fine, as it is explicit
<jfng[m]>
well, zyp's point holds, `object` is compliant with the AXI interface
<jfng[m]>
but here it is backwards
<whitequark[cis]>
it is somewhat less bad because SomeImportantThing.is_property(some_random_thing) is a pattern-ish in Python
<whitequark[cis]>
really in any language where the self is on the left hand side
<cr1901>
is_compliant() works for me
<whitequark[cis]>
AXI4Interface.complies_with(object) is just wrong
<whitequark[cis]>
it says one thing and does another
<crzwdjk>
is_compatible or is_compliant seem fine
<whitequark[cis]>
AXI4Interface.is_compliant(object) is ambiguous but the ambiguity can only be resolved one way
<whitequark[cis]>
an interface cannot be compliant to an object
<jfng[m]>
if it doesn't come up often, i'm fine with anything previously suggested then
<jfng[m]>
with a slight preferecent for `is_implemented_by`
<crzwdjk>
If python allowed question marks in method names, it would be "compatible?()"
<jfng[m]>
s/preferecent/preference/
<whitequark[cis]>
yeah
<whitequark[cis]>
okay, is_compliant it is then
<whitequark[cis]>
this is surprisingly non-violent so far
<whitequark[cis]>
now the final boss: lib.wiring.forward
<cr1901>
I don't have any better ideas
<whitequark[cis]>
I kind of like evert, but it is very... biological
<whitequark[cis]>
and does not fit Amaranth too well
* cr1901
consults a thesaurus
<jfng[m]>
in favor of `forwarded`: python built-ins e.g. `sorted`
<jfng[m]>
against: i don't like it
<zyp[m]>
the only concern I have with that is how it reads if you use it for an internal loopback, e.g. connect(m, forward(self.sink), forward(self.source))
<whitequark[cis]>
that's kind of cursed
<whitequark[cis]>
but ... I think that's a fairly rare thing to do
<zyp[m]>
that's what you'd do in a mux
<cr1901>
transpose*?
<jfng[m]>
whitequark[cis]: way too graphic
<whitequark[cis]>
hm.
<whitequark[cis]>
zyp[m]: oh riiight
<whitequark[cis]>
what do yall think about transpose?
<cr1901>
The analogy to matrices isn't perfect, but I like it better than forward or evert
<zyp[m]>
agreed
<crzwdjk>
That explains better what the operation does, forward kind of explains what it's supposed to be for
<whitequark[cis]>
basically what it does is interface_flip
<whitequark[cis]>
but having two flip operations in one library, when one is already fairly confusing, is a non-starter
<whitequark[cis]>
I think going for transpose and using TransposedInterface for the class name is OK
<whitequark[cis]>
there is no reason we cannot commandeer transpose from its matrix meaning
<jfng[m]>
invert ?
<whitequark[cis]>
no, we have an operator doing that
<whitequark[cis]>
that just seems like it would ~ all bits
<whitequark[cis]>
and I've already removed ~In and ~Out and ~member to avoid further confusion
<whitequark[cis]>
to copy over here: The entire RFC's functionality (sans unresolved questions in the current document, which cover a very minor part of it) was implemented and tested to 100% coverage.