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
<_whitenotifier> [amaranth] whitequark commented on issue #1020: cannot open build_top.sh: No such file - https://github.com/amaranth-lang/amaranth/issues/1020#issuecomment-1880237951
<_whitenotifier> [amaranth] whitequark commented on issue #1019: `Signal(range(0))` raises `SyntaxWarning` - https://github.com/amaranth-lang/amaranth/issues/1019#issuecomment-1880249965
lf_ has joined #amaranth-lang
lf has quit [Ping timeout: 268 seconds]
iamzim has joined #amaranth-lang
iamzim has left #amaranth-lang [#amaranth-lang]
nates93[m] has quit [Quit: Idle timeout reached: 172800s]
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 276 seconds]
Degi_ is now known as Degi
notgull has joined #amaranth-lang
nyanotech has quit [Quit: meow!]
nyanotech has joined #amaranth-lang
notgull has quit [Ping timeout: 268 seconds]
feldim2425 has quit [Quit: ZNC 1.8.2+deb2build5 - https://znc.in]
feldim2425 has joined #amaranth-lang
mwk has quit [Remote host closed the connection]
mwk has joined #amaranth-lang
Hoernchen has quit [Ping timeout: 268 seconds]
Hoernchen_ has joined #amaranth-lang
Hoernchen has joined #amaranth-lang
Hoernchen_ has quit [Ping timeout: 268 seconds]
Hoernchen_ has joined #amaranth-lang
Hoernchen has quit [Ping timeout: 264 seconds]
Hoernchen has joined #amaranth-lang
Hoernchen_ has quit [Ping timeout: 264 seconds]
zyp[m] has joined #amaranth-lang
<zyp[m]> is there a meeting today?
<whitequark[cis]> yes
<whitequark[cis]> I was about to begin it
<whitequark[cis]> good evening everyone, it is the time for our regularly scheduled Amaranth meeting
<whitequark[cis]> who is attending?
<zyp[m]> I'm present
Chips4MakersakaS has joined #amaranth-lang
<Chips4MakersakaS> o/
<cr1901> Sorta present
jfng[m] has joined #amaranth-lang
<jfng[m]> o/
<whitequark[cis]> galibert?
<whitequark[cis]> some of his RFCs are on the agenda, but I also don't think we should discuss them without him
<whitequark[cis]> looks like the answer is no, going to move ahead without those then
<whitequark[cis]> the first RFC on the agenda is one that's important to resolve as early as possible
<whitequark[cis]> RFC #39 "Change semantics of no-argument m.Case()" https://github.com/wanda-phi/rfcs/blob/empty-case/text/0039-empty-case.md
<cr1901> merge*infinity
<cr1901> This is parity with how disjunction works (empty OR is false)
<whitequark[cis]> I think the text is self-explanatory. this was a breaking change in the first place, which was a mistake, and I'd like to fix this in 0.4.1 rather than going thru the usual deprecation cycle
<galibert[m]> Oh sorry I’m here now
<galibert[m]> Didn’t see the time pass
<whitequark[cis]> okay, good
<jfng[m]> whitequark[cis]: makes sense, merge
<zyp[m]> #39 makes sense to me, merge
<galibert[m]> I’d go for hard error personally
<galibert[m]> Since it can’t be anything else than an error
<whitequark[cis]> it can occur in generated code where you do m.Case(*args):
<Chips4MakersakaS> Also merge from me.
<galibert[m]> Ah, ok then
<whitequark[cis]> an empty set of cases is a perfectly valid set of cases to match against
<whitequark[cis]> ok, disposition on RFC #39: merge
<galibert[m]> That’s the kind of “generated” code that makes sense
<Wanda[cis]> oh meow, meeting
<Wanda[cis]> ... merge on me from that one
<Wanda[cis]> er
<Wanda[cis]> or something
<galibert[m]> Meowrge?
<whitequark[cis]> heh
<whitequark[cis]> all right. as galibert has pointed out that we have a long backlog for a while, after this RFC, we will go through them in the oldest-to-newest order
<whitequark[cis]> the next one on the agenda is RFC #17: "Remove log2_int" https://github.com/jfng/amaranth-rfcs/blob/remove-log2-int/text/0000-remove-log2-int.md
<cr1901> merge
<Wanda[cis]> hm.
<Wanda[cis]> I'm not sure about ceil_log2(0)
<jfng[m]> iirc, there was a desire to prototype it first and check if it worked well with `amaranth.lib`, before deciding
<galibert[m]> Bits-to-store(n) = ceil_log2(n+1) right?
<whitequark[cis]> galibert[m]: yes, that's how I understand it
<whitequark[cis]> I like ceil_log2 and exact_log2 by the way
<zyp[m]> it'd be reasonable for ceil_log2(0) to return 0 for the same reason that ceil_log2(3) returns 2
<whitequark[cis]> I think that's a good improvement over the status quo
<Wanda[cis]> also bits-to-store(range(n)) == ceil_log2(n)
<galibert[m]> Can we do a Signal(range(0)) ? I think so, and that could mean ceil_log2(0) should be zero
<zyp[m]> agreed
<Wanda[cis]> yes, and this is exactly why I brought this up
<Wanda[cis]> I'd say merge, except change ceil_log2(0) to return 0
<zyp[m]> my vote is also merge with that change
<galibert[m]> Same
<Chips4MakersakaS> I concur
<jfng[m]> i guess `ceil_log2(0) == 0` is consistent with
<jfng[m]> > returns the integer log2 of the smallest power-of-2 greater than or equal to n
<jfng[m]> i agree with the change
<Wanda[cis]> mhm
<Wanda[cis]> just "raises a ValueError if n is lesser than or equal to 0." needs changing
<Wanda[cis]> and "ceil_log2(n), where n is assumed to be any positive integer"
<whitequark[cis]> disposition on RFC #17: merge, with changes
<whitequark[cis]> the next item on the agenda is RFC #26: Strobe generator https://github.com/galibert/amaranth-rfcs/blob/strobegen/text/0026-strobegen.md
<galibert[m]> IIRC, on variant to drop and add tests at a minimum right?
<whitequark[cis]> I have a major objection to this RFC as written, which is that I do not think strobe generation is a topic that warrants three different classes with a complex set of tradeoffs attached to them; this will be difficult to teach and to use, and I expect most people to misuse the API
<galibert[m]> One not on
<whitequark[cis]> I don't have detailed feedback on it past that because I expect any change that simplifies the API to have a major effect on the API shape and contract
<cr1901> Are you against strobe generation in stdlib period?
<galibert[m]> Counterpoint: I’ve seen a number of crappy implementations of people who clearly had no clue about tradeoffs
<whitequark[cis]> cr1901: I don't know. I am against this particular API, which I think will be a liability to add; I don't know if a better general API is feasible or whether we should have a documentation page where we explain how to write strobe generators
<zyp[m]> I feel that strobe generation is something that's hard to make a generic enough core for
<whitequark[cis]> adding this to the standard library may or may not be overfitting on a few use cases, which right now I don't know which side it falls on
<cr1901> Honestly, I think if CRC got into stdlib, then strobegen should be able to get in, or neither should be in the stdlib. Or more concrete boundaries besides "what vibes with wq" should be in place.
<whitequark[cis]> we do not currently have many "utility" things in the standard library; we have implementations of algorithms where you have essentially one correct implementation, and we have things that vary between platforms
<whitequark[cis]> cr1901: see the message right above
<whitequark[cis]> for CRC, there was no question that the proposed implementation is essentially the sole correct one. if the strobe generator reached the same high bar I'd have no objection to having it
<whitequark[cis]> I think GrayEncoder/GrayDecoder even are stretching it, because some of the choices they make are pretty unorthodox by today's standards (they should have probably been internal classes, but oh well)
<whitequark[cis]> (ideally we would have those as just functions, since that's the shape they fit the best, not submodules)
<cr1901> I don't have a good answer; undecided
<whitequark[cis]> I'm hesitant to add a module that represents somebody's subjective decision on "this is the only right API" in large part because I've added a lot of these guided by the same principle and many of them turned out to be things to deprecate later
<whitequark[cis]> for the same reason I've avoided adding such utility classes to the stdlib (via the RFC process or otherwise)
<whitequark[cis]> I think any such addition needs many people's perspectives, which is why the RFC process is so valuable to me
<Chips4MakersakaS> Is the main use case for StrobeGenerator to use in EnableInserter() ?
<cr1901> FWIW, I changed my mind about CRC being in for consistency, but it's too late now. I'm more prone to allowing the to-be-discussed fixed point in b/c it's a datatype, not an algorithm).
<Wanda[cis]> I agree that this is something with many tradeoffs and details
<whitequark[cis]> CRC could have lived in a separate amaranth-crc repo under the same organization umbrella, but that seems to have essentially no practical benefit over being in the stdlib
<Wanda[cis]> the RFC also feels quite underspecified
<whitequark[cis]> (and the downside is that such associated projects tend to bitrot, at least this is what happened in rust-lang/* and that was pretty sad)
<galibert[m]> There's tradeoffs for everything, including for crc for the matter. If the criteria for stdlib is "best possible tradeoff ever", stdlib will be empty
<Wanda[cis]> which hides a bunch of the complexity as well
<galibert[m]> Wanda: there is an associated PR, you may be interested to have a look
<Wanda[cis]> it speaks of frequencies, not clock ratios
<Wanda[cis]> without specifying what a frequency is
<Wanda[cis]> and just how hard it's going to try to match the frequency
<whitequark[cis]> galibert[m]: the criteria for stdlib are:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/HThBapbQHmikNRwSFrAQgVVF>)
<Wanda[cis]> and by "what a frequency is" I mean: int or float, what units
<whitequark[cis]> fixnums fall under the "interoperability" criterion
<Wanda[cis]> also a non-obvious choice is which way to round the resulting frequency
<whitequark[cis]> crc would fall under "one correct implementation" criterion
<galibert[m]> Catherine: I think you need somewhere for "good practices to resolve problem <x>"
<whitequark[cis]> Gray counters do not quite clear the "one correct implementation" criterion because they do a bunch extraneous things, so I'd like to have them removed from the public API or updated to be a function instead
<whitequark[cis]> galibert: "good practices" are famously difficult to define
<cr1901> They are very useful for multi-bit CDCs if your application can user them
<galibert[m]> I mean, libc's qsort is really, really useful, and it's a pile of tradeoffs
<whitequark[cis]> ask ten people what good practices are for things so old as C or C++ and you get eleven different answers
<whitequark[cis]> galibert[m]: you might enjoy the journey that the standard library sort algorithm underwent in Rust
<whitequark[cis]> cr1901: yes, but the current primitive is actually not easy to use in that manner
<zyp[m]> I'm not opposed to having a strobe generator, but what feature set should a complete generic implementation have? strobe phase? fractional division/dithering?
<whitequark[cis]> a different implementation based on Gray counters but not being quite as difficult to misuse would be better to have instead
<galibert[m]> It was probably interesting, but I suspect there was no doubt some library sort was needed
* cr1901 nods re: Gray counter
<whitequark[cis]> (and we actually have practical issues due to this, where our own AsyncFIFO has issues around resets)
<Chips4MakersakaS> To me it would make sense to have standardized lower slower clock generation from a faster clock that is also in sync. But to me the most useful would be if it could also automatically generate multicycle paths statements for STA. Otherwise you loose big advantage of the slower clock.
<whitequark[cis]> I agree with Chips4Makers (aka Staf Verhaegen) that this will be quite useful and I will also point out that this provides a rationale for such a primitive to be in the standard library: it needs to vary between platforms
<whitequark[cis]> though depending on the implementation, it could also be a method on the platform object, potentially (I don't know exactly what the tradeoff there is)
<galibert[m]> I'm not saying the generator implementation is the best ever (even if I would love to see something better on one criteria or another, because I would learn something), but i think that is amaranth wants to be attractive it needs to provide more than a very nice core. Python won on its libraries
<whitequark[cis]> galibert: I think Rust would actually be fine with a sort outside of the standard library
<whitequark[cis]> it has plenty of seemingly extremely basic things on crates.io, some which are more basic than sort (a never type for example)
<galibert[m]> well, it has crates.io, amaranth doesn't
<zyp[m]> amaranth has pypi, strictly speaking
<galibert[m]> if you don't have strong links to support libraries, you're going to have a discoverability problem
<whitequark[cis]> we should probably have a way to discover Amaranth libraries, yes
<galibert[m]> there's -soc, which is nice but missing cpu cores, not sure what's in -stdio, and all the rest is "unofficial" and quite hard to find out
<whitequark[cis]> -stdio is currently pretty empty but about to stop being empty soon™
<cr1901> (Don't suggest a package manager, don't suggest a package manager...)
<Wanda[cis]> galibert[m]: Python won on its libraries, yes, but its standard library and "battereis included" philosophy famously did not turn out well at all in the end
<whitequark[cis]> no, the package manager for Amarnath is pip/pdm/etc, and the repository is pypi
<Wanda[cis]> s/battereis/batteries/
<galibert[m]> so if strobegen's (for instance) place isn't in a discoverable (like a standard lib), there is no point. I just have it in my projects, no problems there
<cr1901> Okay real suggestion re: discoverability- it's probably possible to make a PDM plugin that aids in discovering amaranth code off PyPi
<whitequark[cis]> why a PDM plugin? a web frontend seems to make much more sense
<jfng[m]> galibert[m]: cpu cores wouldn't belong in -soc, i think (though that's a bit out of topic rn)
<cr1901> whitequark[cis]: Just the first thing I thought of
<whitequark[cis]> I think we need to go back on topic
<whitequark[cis]> there are two related but distinct questions at hand
<whitequark[cis]> 1. should Amaranth standard library be "batteries included"?
<whitequark[cis]> 2. is Amaranth standard library the right place for "good practices"?
<galibert[m]> jfng: open to discussion, just to show that minerva and cr1901's and whichever else are not trivial to know about, and whether they interact correctly with -soc is even less clear
<whitequark[cis]> for (1), the answer is clearly no simply because we barely have enough staff to maintain the existing codebase
<galibert[m]> Catherine: agree with those two points
<whitequark[cis]> so "it can be useful to some nontrivial amount of people" is not a criterion for adding to the stdlib
<whitequark[cis]> for (2), it is less clear, my chief objection to this is that "good practices" are famously incredibly subjective and attempting to agree on them is also famously inflammatory
<galibert[m]> yeah, more like "good enough practices you can use when there's only 24 hours in a day"
<cr1901> I merge to close as "too contentious, but there's a valid convo to be had about findability and improving non-std code"
<whitequark[cis]> the core Amaranth language and the existing standard library components make an enormous effort to either (a) defer to Python, (b) do the sole feasible thing, or (c) not impose requirements on the designer
<cr1901> I vote to close*... phew
crzwdjk has quit [Ping timeout: 252 seconds]
<whitequark[cis]> I 100% agree that we have a discoverability problem and need to solve it
<jfng[m]> i think that providing idiomatic code/"good practices" shouldn't be limited to just stdlib, and that should be the bar for any repo in the amaranth-lang org
<jfng[m]> at some point, we could have an awesome-amaranth like repo somewhere, to showcase community work
<cr1901> jfng[m]: To add to that, a strobegen package can evolve at it's own pace, becoming "stdlib-level quality" without needing to be in stdlib via contribs and ppl discussing use cases
<whitequark[cis]> honestly, we could start with a landing page
<jfng[m]> and/or also, at some point we would have a newsletter with spotlights
<whitequark[cis]> we have a logo now at least, so that's great
<whitequark[cis]> jfng[m]: this has been planned for like half a year by me, but did not concur with ChipFlow priorities so it didn't happen
<_whitenotifier> [rfcs] whitequark commented on pull request #39: Add RFC for no-argument `m.Case()` semantic change. - https://github.com/amaranth-lang/rfcs/pull/39#issuecomment-1881574221
<Chips4MakersakaS> I also prefer to keep amaranth itself tidy and clean. From the other side I think it is a minority of people that will use only amarnath and not amaranth-soc. So for most people amaranth-soc is part of the Amaranth experience.
<_whitenotifier-3> [rfcs] whitequark commented on pull request #17: RFC: remove the `log2_int(n, need_pow2=True)` function. - https://github.com/amaranth-lang/rfcs/pull/17#issuecomment-1881575563
<zyp[m]> on discoverability: I wonder if we could get a Programming Language :: Amaranth or similar classifier into pypi
<cr1901> Well, only 3 RFCs discussed today, but honestly RFC 26 went better than I expected
<whitequark[cis]> zyp[m]: oh, very possibly
<galibert[m]> problem with both -soc and -stdio is that they both, at least in theory, have a limited perimeter
<whitequark[cis]> (we really do need a landing page first, though...)
<galibert[m]> (plus I always forget what's stdio is supposed to be in the first place...)
<whitequark[cis]> -soc is things that are memory mapped, -stdio is for IO cores with streams
<_whitenotifier-3> [rfcs] whitequark commented on pull request #26: RFC for Strobe Generator - https://github.com/amaranth-lang/rfcs/pull/26#issuecomment-1881579040
<whitequark[cis]> for the next meeting, I expect we will continue discussing RFC #26 after finishing discussing #30, which blocks a good amount of other work
<whitequark[cis]> and then proceed from oldest to newest as before
<galibert[m]> #30 is important indeed
<key2> talking about crc, the other day I gave it a try with a 32 bit crc, and at some points I wanted to CRC 5 bytes (4+1) and I didn't figure out if that CRC implementation was able to mask the amount of bits/bytes we input, if it's not the case, then it's not ideal :)
<galibert[m]> #12 (the oldest actually :-) ) is complicated and almost more questions than answers, it will require a lot of discussion and refinement
<whitequark[cis]> I think adamgreig should be able to answer that most easily
<whitequark[cis]> galibert: oh, for some reason that wasn't marked as nominated so I didn't get it in my filtered list
<whitequark[cis]> I fixed that just now
<_whitenotifier-3> [amaranth] wanda-phi opened issue #1021: Tracking issue for RFC 39: Change semantics of no-argument `m.Case()` - https://github.com/amaranth-lang/amaranth/issues/1021
<galibert[m]> Catherine: better handle the less complicated/more blocking ones before #12 in any case
<zyp[m]> of mine, I think #40 can be done first, is much simpler than the other two
<_whitenotifier-3> [amaranth-lang/rfcs] wanda-phi 252fac8 - Add RFC for no-argument `m.Case()` semantic change.
<_whitenotifier> [amaranth-lang/rfcs] whitequark pushed 2 commits to main [+2/-0/±0] https://github.com/amaranth-lang/rfcs/compare/14e0a6163a3f...766729269669
<_whitenotifier-3> [rfcs] whitequark closed pull request #39: Add RFC for no-argument `m.Case()` semantic change. - https://github.com/amaranth-lang/rfcs/pull/39
<_whitenotifier> [amaranth-lang/rfcs] whitequark 7667292 - Add RFC for no-argument `m.Case()` semantic change. (#39)
<_whitenotifier-3> [rfcs] whitequark commented on pull request #39: Add RFC for no-argument `m.Case()` semantic change. - https://github.com/amaranth-lang/rfcs/pull/39#issuecomment-1881587728
<_whitenotifier-3> [amaranth-lang/amaranth-lang.github.io] whitequark pushed 1 commit to main [+1/-0/±27] https://github.com/amaranth-lang/amaranth-lang.github.io/compare/1ad09b5f3a74...b5b4d9a29bd5
<_whitenotifier> [amaranth-lang/amaranth-lang.github.io] whitequark b5b4d9a - Deploying to main from @ amaranth-lang/rfcs@766729269669de7847f69b51f732fb95a3215063 🚀
<galibert[m]> zyp: #41 could run afoul of both "there are multiple ways to implement fixed point with different tradeoffs" and "there are hardwware dependencies of things like the structure of available multipliers, if any"
adamgreig[m] has joined #amaranth-lang
<adamgreig[m]> <key2> "talking about crc, the other day..." <- No, there's no mask. You can compute a crc32 byte at a time in 5 clock cycles, but it can't do 4 bytes in one clock cycle and 1 byte the next
<whitequark[cis]> for multiplication, we have synthesizable multiply already in the standard library, which is not useful in most cases but is kept for simulation (like in CXXRTL)
<adamgreig[m]> It's in the RFC as a possible extension point but it's a lot more logic
<Wanda[cis]> is there already an implementation for #17 or should I just do one when I have time?
<whitequark[cis]> so I don't think hardware matters for the * operator on the fixed point class
<whitequark[cis]> (any more than it matters for the * operator on the Value class)
<whitequark[cis]> as for the tradeoffs, that is one of my concerns
<adamgreig[m]> If you just want 5 bytes though, it can do that as 5 one-byte operations no problem
<cr1901> I used multiply by a constant recently for Celsius to Fahrenheit conversion (see in the logs here somewhere...)
<whitequark[cis]> that's another use case for having an "inefficient" (non-DSP-mapped) multiply
<whitequark[cis]> another use case is toolchains that actually infer multipliers from * in Verilo
<whitequark[cis]> s/*/\*/, s/Verilo/Verilog/
<zyp[m]> I recently implemented a PI controller using an inferred fixedpoint multiplier
<jfng[m]> Wanda[cis]: no, feel free to go ahead
<galibert[m]> Anyway, need to go, see you later all
<whitequark[cis]> later
<cr1901> which family?
<cr1901> (My C2F experiments were... ice40 I _think_. But the actual code I have deployed with C2F is Spartan3A)
<zyp[m]> I'm using ecp5
<key2> @adamgreig[m] but in this case it's a 8bit CRC that I would need. most of the words i send are 32bit. the last one could be 8 16 24 or 32. How would I do that with your implementation ?
<whitequark[cis]> calculate the tail separately?
<whitequark[cis]> it really depends on how many cycles you have available
<whitequark[cis]> <zyp[m]> "https://paste.jvnv.net/view/..."; <- this is very clean
<whitequark[cis]> I love seeing streams, data structures, and fixpoint numbers come together
<adamgreig[m]> key2: if you have the cycles to spare, do it byte at a time, 4 cycles for your 32 bit word and fewer at the end, otherwise you might need to implement a crc block that can do multiple input word widths
<key2> while feeling the bytes in the crc engine, I do not have spare time. only at tail I could have some spare time. but i think that even if I had 2 CRC engines (32 + 8 bits) I can not chain the init value from one to the other as it's determined at generation time from a parameter
<key2> so yeah it would require another implementation in my case.
<zyp[m]> I think once we get streams in amaranth and are adding a stream interface to the crc engine, it'd make sense to add byte lane support as well
<zyp[m]> but it'd be good to have a standard way of expressing byte lanes first
<key2> right
<key2> But in this particular case, I would think that CRC has more its place in stdlib rather than -hdl.
<key2> and other cores such as 8b10b or error correction..
<whitequark[cis]> I wonder if we should have amaranth-coding
<whitequark[cis]> there are so many of these codes, and I'm not sure it's such a good idea to tie their evolution to that of the language
<whitequark[cis]> 8b10b alone has two incompatible variants
<whitequark[cis]> I think having PRBS in the stdlib is probably reasonable given that it's very similar to CRC, but maybe line codes should be shipped separately
<whitequark[cis]> PRBS8/PRBS32 aren't ever going to change, nor are CRC variants appear regularly
<whitequark[cis]> but I can see so many tradeoffs for line codes and the space for implementations is pretty significant
<key2> I don't know if "coding" is the right word. but there are a lot of those that are neither a core, nor the language itself. they are redundantly used everywhere..
<key2> also where would you place a cordic or a fft ?
<key2> what about a FIR / IIR...
<whitequark[cis]> we don't have the staffing to maintain CORDIC, FFT, FIR/IIR in the core stdlib
<whitequark[cis]> so it simply cannot be in the stdlib today
<whitequark[cis]> I think amaranth-coding for line codes is one additional offshoot library we could have, amaranth-dsp another
<whitequark[cis]> I would need a very good lead committed to maintaining DSP for quite a while to consider blessing a specific DSP library though
<whitequark[cis]> this is less true of line codes but still broadly applicable
<key2> yes that makes sense
<key2> but imho FP should be in the -hdl to make sure everyone use the same
<whitequark[cis]> that is the way it's planned, yes