<whitequark[cis]>
since the previous meeting the following changes were made: transpose was renamed back to forward due to more practical experience (and in particular working with multidimensional arrays; Interface is no longer empty as Interface.__init__ now has the logic for creating Interface instance attributes; Component now pulls annotations from the entire MRO (all base classes) and not just the very first class in the MRO;
<whitequark[cis]>
Signature.flipped was removed
<whitequark[cis]>
I believe that the RFC is now ready for approval. does anyone have any final comments?
<Chips4MakersakaS>
Not me.
<cr1901>
renamed back to forward?
<cr1901>
RFC says flipped*
<whitequark[cis]>
err, flipped, not forward
<cr1901>
(The RFC also references forward at the end still)
<galibert[m]>
I've started playing with the implementation, well, it just works
<cr1901>
Otherwise, looks fine
<cr1901>
flipped has grown on me, and there is parity with Signature.flip()
<whitequark[cis]>
all right. in this case, please respond with your preferred disposition: merge or close
<galibert[m]>
merge, and merge the PR while you're at it
<Chips4MakersakaS>
merge
<cr1901>
merge
<whitequark[cis]>
galibert: the PR isn't complete; it misses reference and guide level documentation
<jfng[m]>
Signature.flipped was removed bc it was redundant with isinstance(sig, FlippedSignature) ?
<galibert[m]>
Ah yeah true
<whitequark[cis]>
jfng: yes
<cr1901>
My only question is: if two base classes define the same annotation, where can I learn about the MRO rules about which one takes priority?
<whitequark[cis]>
"MRO" is "method resolution order"
<whitequark[cis]>
so in the Python documentation for that
<cr1901>
yes, that __mro__ magic attribute. I just didn't know the name
<galibert[m]>
Catherine: is it "first one wins", "last one wins" or "assert on collision"?
<Wanda[cis]>
there were also the multidimensional array index order changes, I think?
<whitequark[cis]>
galibert: I don't know what's the first or last here
<cr1901>
Might be complex rules, I just wanted a hint for future me if/when I need it.
<galibert[m]>
Classes in the mro order
<whitequark[cis]>
galibert: the idea is that annotations follow the same priority rules as methods or attributes
<whitequark[cis]>
(there is actually an implementation bug related to this right now)
<galibert[m]>
I'm wondering, is there a use case for priority in contrast to stopping on collision?
<galibert[m]>
Shadowing wihout noticing could be annoying
<cr1901>
Mixins maybe?
<galibert[m]>
unless the colliding parts have identical signatures, but then the priority order doesn't really matter
<whitequark[cis]>
there are five more RFCs on the agenda and we've spent 1/3 of our time already, so we should move on
zyp[m] has joined #amaranth-lang
<zyp[m]>
<whitequark[cis]> "all right. in this case, please..." <- merge from me as well
<galibert[m]>
cr1901: can you use a mixin if some of the interface is shadowed by something with a different signature?
<galibert[m]>
Catherine: Ok
<jfng[m]>
merge
<adamgreig[m]>
also merge
jjsuperpower has quit [Ping timeout: 245 seconds]
<whitequark[cis]>
okay, RFC #2: disposition is to merge 🎉
<zyp[m]>
#18 is also a merge from me, looks like a simple and obvious improvement
<adamgreig[m]>
I like this. only thought is how bad the load time hit of just having all the classes imported into vendor would be, vs the getattr stuff
<galibert[m]>
merge from me. It's simpler, it's probably future-proof
<adamgreig[m]>
but it's not really material to the rfc anyway I think, just an implementation detail
<adamgreig[m]>
would you still have to rename the actual platform classes when vendors change name, or do we just stick with the name it had on release?
<whitequark[cis]>
adamgreig: please read the reference-level explanatino
<whitequark[cis]>
it specifically goes into how you would avoid imports
<adamgreig[m]>
I did
<adamgreig[m]>
I'm asking how bad the hit is from just doing the imports, which is simpler and less magical
<whitequark[cis]>
the actual import goes into __getattr__
<whitequark[cis]>
ohh
<adamgreig[m]>
but I don't think that really matters from the rfc's point of view, whether you use the module getattr or just import seems like an implementation detail anyway
<whitequark[cis]>
essentially yeah
<cr1901>
merge
<whitequark[cis]>
I expect the vendor platform classes to get bigger and more complex as we add things like PLLs to them
<adamgreig[m]>
would you keep Xilinx7SeriesPlatform and never rename it AMD7SeriesPlatform or whatever, then?
<cr1901>
Is there much overhead for having aliases?
<adamgreig[m]>
I like the smaller import statements, but I don't understand why you'd go from "from amaranth.vendor.siliconblue_ice40 import SiliconBlueIce40Platform" to "from amaranth.vendor.lattice_ice40 import SiliconBlueIce40Platform"
<adamgreig[m]>
or in other words: if you keep the class name unchanged when the brand renames, can't you just also keep the module name the same?
<galibert[m]>
You mean from amaranth.vendor import SiliconBlueIce40Platform ?
<adamgreig[m]>
no, sorry, I mean in the current situation where we're renaming things but import from submodules inside vendor
<whitequark[cis]>
historically we would go from vendor.machxo2 to machxo2_3l and I can see going to something like machxo2_3_3l which gets absurd
<adamgreig[m]>
that's more about refining the available platforms than vendors changing names, right?
<whitequark[cis]>
the vendor name changes are also something I'd like to handle
<whitequark[cis]>
Xilinx doesn't exist anymore just like Altera doesn't, and we don't have an AlteraPlatform
<adamgreig[m]>
should we be renaming eg LatticeECP5Platform to just ECP5Platform and so forth?
<whitequark[cis]>
well what would you rename XilinxPlatform to?
<whitequark[cis]>
it handles every Xilinx device
<whitequark[cis]>
s/Xilinx/AMD/
<jfng[m]>
whitequark[cis]: i feel this kind of undermines the motivation behind RFC 18
<adamgreig[m]>
I guess that's what I'm getting at. I don't understand the brand-name motivation in the RFC, since we're still keeping brand names in the classes
<cr1901>
Why the lack of parity between Lattice (need a device family) and Xilinx (handles everything)? Is it historical baggage, or intentional?
<adamgreig[m]>
but I do follow the second motivation around reorganising the modules, and additionally I like the shorter simpler imports
<jfng[m]>
we'd still keep the old vendor names, or deprecate them towards their new name
<whitequark[cis]>
@cr1901: Lattice bought other companies with their FPGA series, Xilinx did not
<whitequark[cis]>
adamgreig: oh, it's easier to change a class name than a module name when refactoring
<whitequark[cis]>
that's the only motivation re: brand names
<Wanda[cis]>
cr1901: someone went ahead and unified all Xilinx devices into common code; that did not (yet) happen for Lattice MachXO* + ECP5
<Wanda[cis]>
that + the fact that Lattice ICE40 is not really a Lattice FPGA like ECP5 and MachXO* are, and it shows in the technical details
<whitequark[cis]>
but even with the unification you would have a XO+ECP5 and iCE40 split
<whitequark[cis]>
jfng: I think we've never removed a vendor name yet, I don't see why we have to
<galibert[m]>
Somebody has issues with me participating to this meeting
<Wanda[cis]>
also the Xilinx stuff is an argument for the RFC, given that we already had a merge of three different platforms from three different modules into one
<Wanda[cis]>
there used to be a Xilinx7SeriesPlatform and so on
<whitequark[cis]>
oh yeah
<adamgreig[m]>
there still is, right? it's just an alias now
<whitequark[cis]>
no we removed the alias
<adamgreig[m]>
anyway regardless of the motivation, the proposed change seems good to me
<jfng[m]>
i meant that we'd rename XilinxPlatform to AMDPlatform anyway
<jfng[m]>
but if this RFC makes it easier because module names no longer matter, then that's a win i guess
<whitequark[cis]>
yes, it does make refactoring downstream code easier
<whitequark[cis]>
module names can clash with variable names for example
<whitequark[cis]>
so you can't do blind s/xilinx/amd/
<whitequark[cis]>
this is likely to break some things unrelated to XilinxPlatform
<whitequark[cis]>
adamgreig: ^ this is the part of the RFC related to brand names: the annoyance of refactoring module names including those
<adamgreig[m]>
fair enough
<whitequark[cis]>
please respond with your disposition on RFC #18: merge or close
<zyp[m]>
I got to go -- I glanced through everything on the agenda and the rest also looks like easy merges for me
<cr1901>
merge
<jfng[m]>
better than having to keep the original shapecastable around
<whitequark[cis]>
the idea behind having ValueCastable.shape() as opposed to the already possible Value.cast(value_castable).shape() is that you get the high level shape-castable object
<whitequark[cis]>
something like this is pretty much required for usability of RFC #15
<Chips4MakersakaS>
merge
<galibert[m]>
Should Value.cast(value_castable).shape() return the ShapeCastable too?
<whitequark[cis]>
FWFT and non-FWFT FIFOs have incompatible interfaces which is only indicated in their runtime properties
<whitequark[cis]>
no one I'm aware of actually wants to use non-FWFT FIFOs in a design and they exist in first place as a weird historical accident related to Migen
<cr1901>
Really? FWFT has a read_en signal?
<cr1901>
Actually ignore that q
<whitequark[cis]>
um, all of the FIFOs have the same set of signals
<jfng[m]>
wasn't FWFT needed for bram inference on some platforms, i don't remember
<adamgreig[m]>
merge from me, I've never needed non-fwft and can't really see why you'd want it either, and one could always copy the old non-fwft code out if you really did
<galibert[m]>
If non-fwft suddenly becomes useful enough to be needed in the lib, it should come back with a different class name
<whitequark[cis]>
agreed
<jfng[m]>
jfng[m]: oh no, that's SyncFIFOBuffered
<jfng[m]>
merge
<galibert[m]>
Merge
<cr1901>
merge
<crzwdjk>
merge
<Chips4MakersakaS>
I follow consensus on this one.
<cr1901>
whitequark[cis]: Yea I haven't really used the FIFOs in amaranth, only in Verilog (where the difference between FWFT and not-FWFT included "whether a read_en signal is present".
<whitequark[cis]>
how would you use a FIFO without a read_en signal?
<cr1901>
There's no need for me to have non-FWFT if read_en is present even on FWFT
<galibert[m]>
You need a signal to either tell the fifo to do a read, or that a read has been done
<jfng[m]>
it's useful if you want to peek at the read data without consuming it
<adamgreig[m]>
I have to run but I'm +1 on #21 too
<cr1901>
read_en presents the data, take consumes the data
<cr1901>
It's really not important to point out the contradictions in my memory, the point is merge
<whitequark[cis]>
okay, that distinction does not exist on Amaranth. read_en is always enabled for FWFT FIFOs effectively
<cr1901>
ack
<whitequark[cis]>
(and for non-FWFT it would be enabled except on first word)
<whitequark[cis]>
this is essentially designed to avoid another MarkupSafe fiasco and have some leeway for backporting tracing changes to older releases while also not committing to a full backport branch
<Chips4MakersakaS>
merge
<cr1901>
Will minor releases be back-compat once major becomes > 0?
<cr1901>
Otherwise merge
<galibert[m]>
I have a feeling that 0.4 is major in the first place
<whitequark[cis]>
0.4 is major
<cr1901>
Change Amaranth versioning from major.minor <-- you bumped the minor part
<whitequark[cis]>
cr1901: yes, and there will probably never be Amaranth 2
<cr1901>
right, fair
<galibert[m]>
then it should be 1.0 (or 4.0 even :-) ), no?
<whitequark[cis]>
galibert: not how semver works
<cr1901>
"Anything goes" before 1.0. Rust and Amaranth are more principled
<whitequark[cis]>
incrementing x in x.y or 0.x allows for breaking changes
<galibert[m]>
prediction: you'll still be at 0.x in five years
<whitequark[cis]>
galibert: nah, the plan is to get to 1.0 in about two
<cr1901>
Anyways, merge. Just wanted clarification.
<galibert[m]>
trust me, I co-maintain a project that is at 0.257 iirc
<whitequark[cis]>
and in five I would like to be doing something else entirely with my life
<whitequark[cis]>
well I would not trust you to get to 1.0 in that case :p
<whitequark[cis]>
jfng: there is an unresolved question here for you
<cr1901>
Just go towards version "e"
<cr1901>
e/10*
<galibert[m]>
LaTeX went towards version pi, it didn't help
<galibert[m]>
(or maybe TeX itself, not sure anymore)
<whitequark[cis]>
TeX
<crzwdjk>
I vote merge, it seems like a minimum reasonable change
<crzwdjk>
Also projects can always strip off a leading digit from the version like emacs did at some point
<cr1901>
^Uhhh, what? ._.
<crzwdjk>
emacs version were 1.1, 1.2 ... 1.12, 13, 14, ...
<jfng[m]>
i'm okay for doing this in -soc, iff the backporting effort is moderate
<galibert[m]>
It's not todays meeting, but I'd vote for -soc having a lot more releases
<jfng[m]>
merge
<galibert[m]>
also, merge
<jfng[m]>
galibert[m]: well, 1 would be infinitely more than 0, i guess !
<whitequark[cis]>
thanks. disposition on RFC #21: merge
<whitequark[cis]>
that's all! thank you everyone
<crzwdjk>
Thanks, whitequark[cis]
<galibert[m]>
Maybe one day someone will read my rfc ;-)
<galibert[m]>
(yeah yeah yeah waiting for after the 0.4 release, makes a lot of sense too)
<Chips4MakersakaS>
TY, but in 5 years I think you (@Catherine) will be BDFL and be paid by the Amaranth foundation... :)
<galibert[m]>
I suspect she'll hate the 'D' aspect though
<whitequark[cis]>
I am vocally opposed to ever being a BDFL of anything
<crzwdjk>
And maybe, just maybe, the langauge will stay small and reach a steady state, with everything else being in libraries.
<galibert[m]>
Catherine: sometimes you end up being the 800-pound gorilla without meaning to though. It can even been pleasing to being able to solve stupid blockages through the application of what ends up very minimal force
<galibert[m]>
Just being that one means people take the time to think again rather than knee-jerk, and you can end up with a nice resolution
<whitequark[cis]>
did you know that I've never wanted to design languages? I wanted to use them, but what I wanted to use did not exist
<galibert[m]>
And then you went and designed what we also wanted to use :-)
<galibert[m]>
A data.Struct derivative, when seen under gtkwave, loses the individual members (e.g. it records the global signal as one value) when using Simulator. Is that sanely fixable?
<galibert[m]>
hmmm, that's in fact a general ValueCastable issue, right?
<whitequark[cis]>
mhm, yes
<galibert[m]>
you need some kind of entry point that's similar to a decoder but can output multiple named traces
<whitequark[cis]>
yes
<whitequark[cis]>
that's the needs-rfc bit
<galibert[m]>
indeed
<galibert[m]>
that also could be a generalization of the decoder concept, you pass either a function that goes value -> representation, or a pair with a list of trace names and a function that goes value -> tuple (list?) of representations
<whitequark[cis]>
I was thinking about replacing the function with a class, which could potentially also maintain state
<galibert[m]>
that's another possible way. I was thinking of a case like fp32 with a decoder that does both 32'h and floating point representation on two independant traces, in a case where they're not struct-ed somehow
<galibert[m]>
a lambda seemed sufficient, lighter than creating a derivative call of some Decoder interface
<galibert[m]>
s/call/class/
<whitequark[cis]>
what happens if the return value changes
<whitequark[cis]>
* if the structure of the return value, * value changes?
<whitequark[cis]>
how do you emit the list of traces without having the init state ready yet?
<whitequark[cis]>
how do you correlate names to traces without calling random code?
<whitequark[cis]>
this still does not let you keep formatter state
<galibert[m]>
lambda can keep state by calling into an object (say, your view for instance)
<whitequark[cis]>
sure, you can build a rube goldberg machine out of bare python datatypes that does the same thing I want to do but worse and in a more confusing, harder to use, harder to document way. why?
<whitequark[cis]>
ah, there's another consideration I should mention
<whitequark[cis]>
ideally CXXRTL would not call back into Python for formatting
<whitequark[cis]>
so aside from that lambda, there would need to be another one
<galibert[m]>
ah yeah, and the generated verilog should probably be a packed struct
<galibert[m]>
which is the exact same issue
<whitequark[cis]>
no
<whitequark[cis]>
there are no plans to alter the generated verilog
<galibert[m]>
oh? I thought you'd have wanted that for debugging easyness
<whitequark[cis]>
sorry, I should be more clear: it's not feasible until the new IR lands, so it won't be a part of addressing this issue
<whitequark[cis]>
right now we don't have a lot of control over the generated Verilog at all
<whitequark[cis]>
and the dream of using Yosys to make the problem easier has not really come true due to how bad write_verilog is in Yosys
<galibert[m]>
oh ok
<galibert[m]>
well, it seems to be an horribly hard problem in the first place
<cr1901>
_IIRC_ (emphasis), wq offered a PR to make write_verilog's output better, but AFAIK Claire never merged it b/c of nontrivial potential to break subtly in difficult to find ways.
<cr1901>
Also wq: do you have any medium term plans (next 6 months) to update boneless to be up to date w/ amaranth?
<whitequark[cis]>
cr1901: I would not have merged it myself considering the issues brought up (this wasn't a conflict of opinions or anything like that; my PR was not technically good enough)
* cr1901
nods
<whitequark[cis]>
cr1901: yeah sure, it will go really well with the data structure library updates I think
<cr1901>
Cool, I'd love to experiment w/ boneless again (and maybe even get the simulator up to date). There's some control-plane stuff I could do w/ it (serial port multiplexor, bespoke terminal emulator) where RISCV is too big, so I'd either use a 6502 soft-core or boneless
<cr1901>
IIRC term emulator was a motivation for boneless too
<whitequark[cis]>
yes
<galibert[m]>
Did you write a llvm backend for boneless in a fit of insanity?
<galibert[m]>
Also, you should use a 8051 core just to make Foone drink
<crzwdjk>
Ooh, it would be cool to see boneless revived
<crzwdjk>
Also with interfaces and (hopefully soon) streams, it would be nice to see amaranth-stdio updated and expanded
<whitequark[cis]>
boneless is not really a good fit for LLVM; neither is 8051
<whitequark[cis]>
crzwdjk: yes, that is the idea with streams
<galibert[m]>
8051 is not a good fit for anything not severely legacy :-)
<galibert[m]>
Catherine: the 16-bits thing or other issues?
<whitequark[cis]>
LLVM thinks the stack is basically free, for one
<galibert[m]>
ouch
<galibert[m]>
"Ten tricks your embedded system hates"
<cr1901>
There's a globalisel pass that the 6502 LLVM backend (!!) that apparently makes the codegen not abysmal.
<crzwdjk>
Ah, another reason LLVM in not the perfect solution for every compiler problem
<crzwdjk>
cr1901: is there a 6502 core written in amaranth?
<galibert[m]>
crzwdjk: I'm writing one right now to test rfc#2
<cr1901>
I think galibert[m] is doing one. I might do a 65c02 one
<cr1901>
or if galibert[m] adds the "c" insns, I'll use his
<galibert[m]>
I'm doing to original for now, but I want the others too
<crzwdjk>
Cool, I would love to see it when it's done. Might be useful for my terminal.
<cr1901>
I need to buy a spare c02 and make a test harness, so I can run it in lockstep in simulation w/ my design
<cr1901>
Thankfully modern ones run at 3.3V, so that's easy to interface
<crzwdjk>
How big would a 6502 be, relative to an ice40 fpga? Or boneless for that matter?
<galibert[m]>
no idea, honestly
<gatecat>
don't have an exact breakdown but I managed to get the entire MiST NES core to fit in an ice40up5k a few years ago
<gatecat>
I think it's less than 1k LUTs for the 6502 part
jjsuperpower has joined #amaranth-lang
<crzwdjk>
Oh, that's pretty encouraging then, also cool that a whole NES can fit on a pretty small fpga.