whitequark[cis] changed the topic of #amaranth-lang to: Amaranth hardware definition language · weekly meetings: Amaranth each Mon 1700 UTC, Amaranth SoC each Fri 1700 UTC · code https://github.com/amaranth-lang · logs https://libera.irclog.whitequark.org/amaranth-lang · Matrix #amaranth-lang:matrix.org
zyp[m] has quit [Quit: Idle timeout reached: 172800s]
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 260 seconds]
Degi_ is now known as Degi
<_whitenotifier> [amaranth] charlottia reviewed pull request #865 commit - https://github.com/amaranth-lang/amaranth/pull/865#discussion_r1299550444
jjsuperpower has quit [Remote host closed the connection]
jjsuperpower has joined #amaranth-lang
jjsuperpower has quit [Ping timeout: 252 seconds]
<_whitenotifier> [amaranth] whitequark commented on issue #807: Constructing a `signed(0)`-shaped Const fails with `ValueError`. - https://github.com/amaranth-lang/amaranth/issues/807#issuecomment-1685707370
FFY00 has joined #amaranth-lang
skipwich has quit [Quit: DISCONNECT]
skipwich has joined #amaranth-lang
daglem[m] has joined #amaranth-lang
<daglem[m]> I just came across this; dropping a link here in case it could be interesting to you: <https://www.infineon.com/cms/en/product/microcontroller/32-bit-psoc-arm-cortex-microcontroller/psoc-4-32-bit-arm-cortex-m0-mcu/psoc-4200/>
<galibert[m]> Picked one at random, price was E5.5 fwiw
jjsuperpower has joined #amaranth-lang
Bluefoxicy has quit [Quit: ZNC - http://znc.in]
Bluefoxicy has joined #amaranth-lang
<cr1901> That's really cool- "microcontroller w/ custom peripheral attached to the internal bus"
<whitequark[cis]> good evening everyone, it is the time for our weekly meeting
jfng[m] has joined #amaranth-lang
<jfng[m]> o/
adamgreig[m] has joined #amaranth-lang
<adamgreig[m]> o/
<cr1901> o/
Chips4MakersakaS has joined #amaranth-lang
<Chips4MakersakaS> o/
<galibert[m]> o/
<whitequark[cis]> the first item is RFC #2 Interface definition library: https://github.com/amaranth-lang/rfcs/pull/2
<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 🎉
<jfng[m]> congrats!
<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
<galibert[m]> merge
<cr1901> Still merge from me.
<adamgreig[m]> merge
<jfng[m]> merge
<crzwdjk> merge
<whitequark[cis]> okay, great!
<whitequark[cis]> disposition for RFC #18: merge
<galibert[m]> yay
<jfng[m]> nice one
<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?
<crzwdjk> RFC 22 seems reasonable, merge
<galibert[m]> merge in any case
<adamgreig[m]> merge
<whitequark[cis]> disposition for RFC #22: merge
<jfng[m]> merge
<jfng[m]> it was originally extracted from wishbone.Arbiter in -soc, iirc
<cr1901> merge. That was easy lol.
<jfng[m]> but scheduler come in many kinds, and i don't think we should try to standardize them
<jfng[m]> lest we limit ourselves to the simplest ones
<whitequark[cis]> the implementation in the wishbone arbiter is less than 10 lines
<galibert[m]> I have in my todo list to make wishbone.Arbiter to handle both RR and priority
<jfng[m]> whitequark[cis]: also
<crzwdjk> Merge, I assume stuff like this will eventually live in third party packages as the amaranth ecosystem grows.
<galibert[m]> Merge
<whitequark[cis]> disposition for RFC #19: merge
<whitequark[cis]> oh, Staf didn't vote yet
<adamgreig[m]> merge
<Chips4MakersakaS> merge
<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
<whitequark[cis]> (other than level)
<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]> disposition on RFC #20: merge
<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?
<galibert[m]> that's why I was talking pair
<galibert[m]> decoder = (["hex", "fp32"], lambda v: (..., ...))
<whitequark[cis]> oh, I misread what you wrote
<whitequark[cis]> it's not enough to pass a list of traces
<whitequark[cis]> traces have types and display properties
<whitequark[cis]> e.g. it would be quite useful to be able to set traces to display as hex, bin, ascii, arbitrary string
<galibert[m]> "hex:32'h", "fp32:s" ?
<whitequark[cis]> no
<whitequark[cis]> we have more than enough stringly typed parts of the language already, no need to introduce more
<galibert[m]> am.traces.hex("hex", 32), am.traces.str("fp32") ?
<galibert[m]> (bikeshedded into oblivion)
<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.
<_whitenotifier> [amaranth] daquintero commented on issue #718: Make a release with fixed jinja2 dependency - https://github.com/amaranth-lang/amaranth/issues/718#issuecomment-1687181838