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
<mcc111[m]> Oh, hm
<cr1901> Interesting. I've touched Amaranth code for the first time in 3 years, and I had to make minimal changes for the code to at least compile. (Unintentionally?) Good migration story :P?
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 240 seconds]
Degi_ is now known as Degi
pbsds has quit [Ping timeout: 240 seconds]
<mcc111[m]> <cr1901> "m.d.comb += ClockSignal("neg_clk..." <- ClockDomain/ClockSignal are in the standard library? But also undocumented?
pbsds has joined #amaranth-lang
cyrozap has quit [Quit: ZNC 1.8.2+deb3.1 - https://znc.in]
<cr1901> Looks like that's correct
cyrozap has joined #amaranth-lang
cyrozap has quit [Client Quit]
<mcc111[m]> I guess i'm still … I have this clock signal M, and I need to create two dividers, one of which produces M/4 frequency and one that produces M/256 frequency (I'm doing i2s). And without posedge/negedge I'm struggling with how to do this, unless I do posedge/negedge manually in logic (keep a 1-frame delayed copy of the clock signal, and check for ~last & current— in my last project I had a custom class named Edger that did this).
<mcc111[m]> And in channel I've been recommended ClockDomain, ClockSignal, and EnableInserter as classes that might solve my problem, but they're all undocumented so I don't know how to go from "the class exists" to "I know how to use this". How is it y'all know how these work? Did you just read Amaranth's source?
cyrozap has joined #amaranth-lang
<cr1901> Because they're holdovers from migen and haven't changed significantly since then
<cr1901> Can't speak for other ppl, but that's the main reason I know how to use them
<whitequark[cis]> mcc111: usually by looking at others' code or asking here
<whitequark[cis]> anyway, to use EnableInserter, you go from m.submodules.foo = Foo() to m.submodules.foo = EnableInserter(en)(Foo())
<whitequark[cis]> these are functors (in a C++ sense) to which you give the strobe signal
<whitequark[cis]> there isn't much to use.
cyrozap has quit [Ping timeout: 264 seconds]
<mcc111[m]> Okay… so like, the PixelClkDiv class you wrote in the Pocket sample code. I could replace PixelClockDiv(ratio=8) with EnableInserter(strobe_signal(PixelClockDiv(ratio=8)) and the m.d.sync internal to that PixelClkDiv would only tick forward on the strobe signal high ?
<tpw_rules> it's EnableInserter(strobe_signal)(PixelClockDiv(ratio=8))
<tpw_rules> (also how do you all get like the "double monospace" text)
<mcc111[m]> that was a typo, yeah. and the monospace is the backtick, it's markdown
<cr1901> EnableInserter() returns something you can call like a function, hence the second set of parens
<mcc111[m]> I was going to ask how I go from there to but I think I can generate a strobe at the same time I generate the clock (it's a kinda weird clock)
<mcc111[m]> Okay I'll… experiment with this. Hm.
<cr1901> "foo = EnableInserter(strobe_signal); foo(PixelClockDiv(ratio=8))" would do the same
<whitequark[cis]> mcc111: I think if you put `PixelClockDiv` into `EnableInserter` it won't generate the strobe in the right way (it will be delayed)
<whitequark[cis]> s/delayed/too long/
<whitequark[cis]> check it on the waveforms
<mcc111[m]> oh. you're right
charlottia has quit [Quit: Idle timeout reached: 172800s]
_whitelogger has joined #amaranth-lang
<cr1901> Does amaranth.lib.enum support the function syntax for enums (or any way to programmatically set enum variant names)? https://docs.python.org/3/library/enum.html
<whitequark[cis]> looks like it doesn't, which is a bug
<whitequark[cis]> can you file that please?
<_whitenotifier-f> [amaranth] cr1901 opened issue #910: `amaranth.lib.enum` does not support functional syntax - https://github.com/amaranth-lang/amaranth/issues/910
cyrozap has joined #amaranth-lang
cyrozap has quit [Quit: ZNC 1.8.2+deb3.1 - https://znc.in]
cyrozap has joined #amaranth-lang
cyrozap has quit [Quit: ZNC 1.8.2+deb3.1 - https://znc.in]
cyrozap has joined #amaranth-lang
notgull has quit [Ping timeout: 260 seconds]
notgull has joined #amaranth-lang
<cr1901> Are start/stop considered public members of Slice (for the purposes of unit testing some code that generated a StructLayout)?
nak has quit [Ping timeout: 255 seconds]
nak has joined #amaranth-lang
<whitequark[cis]> yeah
nyanotech has quit [Remote host closed the connection]
nyanotech has joined #amaranth-lang
MuddassirAli[m] has quit [Quit: Idle timeout reached: 172800s]
nak has quit [Ping timeout: 240 seconds]
nak has joined #amaranth-lang
<galibert[m]> There’s a PR for amaranth-lang for a generic clock-divider enable generator
pbsds has quit [Ping timeout: 240 seconds]
pbsds has joined #amaranth-lang
Wanda[cis] has joined #amaranth-lang
<Wanda[cis]> ummm.
<Wanda[cis]> that's... an interesting interaction
<Wanda[cis]> I thiiiink it's a regression in 54d5c4c047f0d8dd010a599dc1fccbeafe026995 (RFC 9 implementation)
<Wanda[cis]> no, it's an even earlier behavior, hm
<Wanda[cis]> it seems it never worked
<Wanda[cis]> so: reset documentation says it only accepts int or enum value, and this was true pre-0c4fda92fecb0f6b1a3dce8960f8d13459c7eef1
<Wanda[cis]> in 0c4fda92fecb0f6b1a3dce8960f8d13459c7eef1 (part of RFC 4 implementation), support for const-castable expressions was nominally added, except... there isn't a test for it, and the code in fact does not actually work because of a bug
<Wanda[cis]> and 54d5c4c047f0d8dd010a599dc1fccbeafe026995 introduces another bug to the already-broken code
<galibert[m]> Impressive
<mcc111[m]> It seems to me if it doesn't accept Const, that's unergonomic, but if there's a good reason it doesn't accept Const, the error message should be changed
<Wanda[cis]> I'm reasonably sure it's a bug and I'm just finishing up the PR for it
<Wanda[cis]> hm, actually
<mcc111[m]> 👍
<Wanda[cis]> wanna file the issue?
<mcc111[m]> Would that help?
<Wanda[cis]> yeah
<mcc111[m]> ok
<mcc111[m]> While I'm writing that here is another question... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/cRVvPAmVNMITlGWEPhZdKtxE>)
<Wanda[cis]> ... yeah
<Wanda[cis]> the second does add extra wiring
<_whitenotifier-f> [amaranth] mcclure opened issue #911: Signal reset cannot be set to a const value - https://github.com/amaranth-lang/amaranth/issues/911
<mcc111[m]> I dialed 911
<mcc111[m]> Wanda[cis]: Good to know
<mcc111[m]> Are there ever circumstances where preventing a signal from asserting under "unnecessary" circumstances would waste power?
<Wanda[cis]> I had plans to add a yosys optimization that'd clean this up
<mcc111[m]> s/waste/*save*/
<Wanda[cis]> but uh
<Wanda[cis]> ... let's not speak of that
<Wanda[cis]> oops, too late, I dissociated
<Wanda[cis]> I do not recommend having yosys pass trauma btw
<Wanda[cis]> <mcc111[m]> "Are there ever circumstances..." <- actually yes, if you're explicitly optimizing for power
<mcc111[m]> Wanda[cis]: Okay.
<mcc111[m]> If optimizing for power consumption is *a* goal, not the primary goal but a goal, at what point in the skill curve should I start thinking about this?
<Wanda[cis]> specifically where you have a bunch of power-hungry logic the result of which is rarely used
<Wanda[cis]> (a multiplier or something)
<Wanda[cis]> then you may want to keep the inputs at all-0 when you're not actively using it
<Wanda[cis]> this, of course, comes at an area and delay cost
<galibert[m]> Do you? I thought that in cmos it’s changing level that has a cost, whatever the level is
<Wanda[cis]> it's not the specific value that's important, it's not changing it every cycle
<Wanda[cis]> ... actually yeah, just not changing the inputs from the last "useful" value would be good too
<Wanda[cis]> but this may or may not be feasible depending on how your ALU is constructed
<Wanda[cis]> mcc111[m]: > <@mcc111:matrix.org> Okay.
<Wanda[cis]> > If optimizing for power consumption is *a* goal, not the primary goal but a goal, at what point in the skill curve should I start thinking about this?
<Wanda[cis]> quite late, I'd say; it's something you really shouldn't be bothering with unless you have good reason, and it's tricky to get right without good power estimation tools
<galibert[m]> Also in fpga land there’s too much you just don’t control
<_whitenotifier-f> [amaranth] wanda-phi opened pull request #912: ast: fix const-castable expression handling in `Signal(reset=)`. - https://github.com/amaranth-lang/amaranth/pull/912
<Wanda[cis]> ... oh right, first PR, no auto-CI for me
<Wanda[cis]> bleh
<mcc111[m]> <galibert[m]> "Do you? I thought that in..." <- hm, i guess what i'm trying to figure out is, if i have an "intermediate" value which is only needed sometimes is it better (power wise) to comb it so it's calculated every cycle, comb it so it's calculated but zero on frames it isn't needed, or sync it so it's changed only at appropriate moments
<mcc111[m]> or "just don't think about it"
<galibert[m]> Just don’t think about it
<galibert[m]> Also comb doesn’t exist
<mcc111[m]> oh
<mcc111[m]> that's good, right?
<galibert[m]> It’s all agglomerated into whatever sync or I/O at the end of the chain. Any intermediate value you create may or may not physically exist in the end
<mcc111[m]> In amaranth, if I say
<mcc111[m]> `self.rotate1_counter + (self.rotate2_counter == 3)`
<mcc111[m]> In this context, does `self.rotate2_counter == 3` act like the binary number 0 or 1?
<Wanda[cis]> yeah
<galibert[m]> It’s a Signal(unsigned(1))
<mcc111[m]> Good
<galibert[m]> (not exactly, you can’t eq it, but you get the idea)
<Wanda[cis]> audgen_osc_wave is a plain list or something, right?
<Wanda[cis]> wrap it in Array
<Wanda[cis]> like this: Array(audgen_osc_wave)[ ...... ]
<mcc111[m]> This means, effectively, it is a series of 5 square waves, each half the frequency of the previous
<mcc111[m]> Explanation: audgen_osc_wave is a 5-bit timer which is incrementing on a certain schedule
<mcc111[m]> I want to select one of these 5 waves, based on a particular bit of state
<mcc111[m]> Cool
<Wanda[cis]> oh wait
<Wanda[cis]> it's a signal?
<Wanda[cis]> nevermind then
<Wanda[cis]> use audgen_osc_wave.bit_select(...) instead
<mcc111[m]> It's a signal
<mcc111[m]> Also ok
<Wanda[cis]> s//`/, s/.../..., 1/, s//`/
<galibert[m]> You forgot the parenthesis though
<mcc111[m]> parenthesis?
<galibert[m]> Add has higher precedence that ==
<galibert[m]> Than
<mcc111[m]> ohhh yeah geez
<mcc111[m]> I hastily rewrote that statement to remove a Mux
<galibert[m]> That’s the kind of mistake that takes hours to debug :-)
<mcc111[m]> yeah
<mcc111[m]> scratches head in .bit_select(x, 1), x should be 0 == lsb, correct?
<Wanda[cis]> correct
<mcc111[m]> So I realize I actually want to index in msb->lsb order, not lsb->msb order, because of what I'm doing
<mcc111[m]> I want the result of the "index" expression to be in the range 0-5 inclusive
<galibert[m]> You mean 0-4?
<mcc111[m]> yyyyyes.
<mcc111[m]> 0-5 noninclusive D:
<Wanda[cis]> audgen_osc_wave.bit_select( (4-(self.rotate1_counter + (self.rotate2_counter == 3))).as_unsigned() , 1 )
<mcc111[m]> oh, that makes sense
<galibert[m]> Wanda: is that going to be efficient? Or is she going to get a pair of adders instead of pure luts?
<Wanda[cis]> meow?
<galibert[m]> (mcc, I assumed she from the pp, correct me if I'm wrong)
<Wanda[cis]> oh hm
<Wanda[cis]> ... reminds me of a different optimization I wanted to do, heh
<Wanda[cis]> but in this case
<galibert[m]> sorry
<galibert[m]> maybe :-)
<Wanda[cis]> everything is small enough that yosys should just blast it to LUTs
<galibert[m]> ok, good
* cr1901 heard a cat meow
<mcc111[m]> (For the record my preferred pronouns are she/her.)
<mcc111[m]> I wound up writing it into a temporary 4-signal because it's just more readable.
<galibert[m]> (good, if the obvious one is the correct one I won't fuck up)
jjsuperpower has joined #amaranth-lang
sporniket has joined #amaranth-lang
<sporniket> Hello, just a little notice about my poc displaying using the HDMI port of the colorlight i9 fully written with amaranth (especially for mcc111[m] that seemed interested about it).
<sporniket> The code is now in a good enough shape and I even made a release https://github.com/sporniket/the-cradle-colorlight-i9-ecp5-amaranth-hdl/releases/tag/v0.1.0
<sporniket> (good enough because I use some combination of Signals as ClockDomain and there was that discussion yesterday about how doing that is going to bite later if left as is.)
<sporniket> The TMDS encoder is located in my library project https://github.com/sporniket/amaranth-stuff, along some other modules used in the demo, that also serves to specify the amaranth/amaranth-boards version to use.
<mcc111[m]> Ahh that's real exciting
<sporniket> I have to switch to other projects for now but hope to switch back to this before the end of the year.
<sporniket> Hope this will help you :)
sporniket has quit [Quit: Client closed]
<cr1901> Is it possible to quash the UnusedElaboratable warning (it's noise in pytest)?
<cr1901> Like, no shit I'm not using all elaboratables during a test lol
<cr1901> from amaranth.hdl.ir import UnusedElaboratable; UnusedElaboratable._MustUse__silence = True <-- I do not encourage this, but it does work
<cr1901> Good ol' Hyrum's Law strikes again :D.
<galibert[m]> Why do you create them if you don’t add them to another module?
<cr1901> I'm not creating them. pytest is as part of test discovery, and then I'm using the "-k" option to filter out/only run one test
<galibert[m]> Oh
<adamgreig[m]> cr1901: yea, there's a magic comment you can put in the test file, but I'm away from my computer so can't find it atm...
<adamgreig[m]> But iirc some amaranth tests have it
<cr1901> # amaranth: UnusedElaboratable=no
<cr1901> Although that's not actually working for me
<cr1901> (unless it's ignored on test failure)
<adamgreig[m]> Hm, I've definitely had it work for pytest stuff in this exact scenario, I'll see if I can find it in a bit
sugarbeet has quit [Ping timeout: 244 seconds]
sugarbeet has joined #amaranth-lang
<cr1901> Well, the only hits for you specifically for UnusedElaboratable=no are your copy of the amaranth source
jfng[m] has joined #amaranth-lang
<jfng[m]> <cr1901> "Is it possible to quash the..." <- you can use `Fragment.get(dut, platform=None)`