<Wanda[cis]>
it depends on whether you're in a process or a testbench
<Wanda[cis]>
according to RFC 36, in a process, sim.set only sets the "next" value of a signal
<Wanda[cis]>
it doesn't affect the "current" value, which is the one you get via sim.get
<Wanda[cis]>
the actual setting of "current" to "next" will happen on the next delta cycle, which (from the point of view of your process) can only happen by awaiting a trigger object
<Wanda[cis]>
but in a testbench, any command implicitly causes delta cycles to happen until the whole design settles (ie. all "current" are equal to "next")
<Wanda[cis]>
(this is the same as in the current yield-based interface, too)
<Wanda[cis]>
if amendment #64 is accepted, .get in a process disappears completely and the question becomes moot for it, since the only way to get values is by awaiting trigger objects and they always involve delta cycles
<cr1901>
In the new async-based interface, do I have to rearrange the code block (sim.tick before the rest), or just do a text replacement?
<cr1901>
(Just to avoid an XY problem: it's not clear to me why it's e.g. "await sim.tick(); sim.set(stream.ready, 0)" in that order to indicate "the data has been taken", when in the old yield-based interface, you'd do "yield stream.ready.eq(0); yield" in that order to indicate "data has been taken"
<cr1901>
(stream_recv seems to be a building block for something that can be used as a testbench, seeing as you don't pass stream_recv to either add_process or add_testbench.)
sorear has quit [Ping timeout: 240 seconds]
sorear has joined #amaranth-lang
notgull has joined #amaranth-lang
notgull has quit [Ping timeout: 256 seconds]
indy_ has quit [Ping timeout: 255 seconds]
indy has joined #amaranth-lang
frgo has quit [Remote host closed the connection]
frgo has joined #amaranth-lang
<whitequark[cis]>
i hate altera so much
<whitequark[cis]>
wanda is currently crying loudly due to altera
galibert[m] has joined #amaranth-lang
<galibert[m]>
What did Altera do?
<whitequark[cis]>
built quartus
<Wanda[cis]>
to be fair the crying was due to Altera and yosys
<galibert[m]>
Ok, what did quartus do, beside existing? :-)
<whitequark[cis]>
the worst toolchain of each i've used, including gowin
<whitequark[cis]>
ok, maybe quicklogic is worse
<galibert[m]>
huhuhu
notgull has joined #amaranth-lang
<whitequark[cis]>
to be fair, if you're using the secret quicklogic toolchain they only give you when you complain that the FOSS one doesn't work that actually uses synplify and neocad or whatever it was they use for pnr, quicklogic is fine
frgo has quit [Read error: Connection reset by peer]
frgo has joined #amaranth-lang
notgull has quit [Ping timeout: 260 seconds]
<whitequark[cis]>
i should be paid hazard rates for looking, touching, or in any way interacting with altera
<tpw_rules>
what went wrong? presumably with the io port stuff
<whitequark[cis]>
useioff
<galibert[m]>
my experience is that useioff=1 is the actual default
<cr1901>
So, next week should be back to normal, but I don't have much feedback for this meeting, so: merge the lib.coding removal, and refrain from the other 2 RFCs
<whitequark[cis]>
recorded
<cr1901>
Tyvm
<whitequark[cis]>
note to everyone (in the European timezones): due to the DST change, the meeting is a hour from now
<whitequark[cis]>
zyp: see the comment I just left
<zyp[m]>
looks reasonable
<tpw_rules>
is there a reference for the guidelines for standard library inclusion? i know there have been debates but i don't know if it's been codified yet. any which way i don't think lib.coding meets it
<whitequark[cis]>
in case of lib.coding, it would fit the guideline (3), if it was actually nice to use
<tpw_rules>
maybe it can come back once functions are a thing
<whitequark[cis]>
yeah. someone could write a well motivated and researched RFC for those (wink)
<tpw_rules>
idk if research and experience are my strong suits :D
eldiem7 has joined #amaranth-lang
ktemkin_ has joined #amaranth-lang
Bluefoxicy_ has joined #amaranth-lang
mindw0rk_ has joined #amaranth-lang
nyaanotech has joined #amaranth-lang
Bluefoxicy has quit [Ping timeout: 268 seconds]
josuah has quit [Ping timeout: 268 seconds]
eldiem has quit [Ping timeout: 268 seconds]
mindw0rk has quit [Read error: Connection reset by peer]
zyp[m] has quit [Ping timeout: 268 seconds]
nyanotech has quit [Ping timeout: 268 seconds]
ktemkin has quit [Ping timeout: 268 seconds]
ktemkin_ is now known as ktemkin
eldiem7 is now known as eldiem
zyp[m]1 has joined #amaranth-lang
Bluefoxicy_ is now known as Bluefoxicy
mindw0rk_ is now known as mindw0rk
<cr1901>
What does it mean to say "processes cannot advance simulation"? Simulation is advanced by awaiting a trigger object, correct? The example processes are awaiting trigger objects by async for sim.changed, or "await sim.posedge" (ddr io buffer)
<cr1901>
So it sounds like processes are advancing simulation because they are awaiting trigger objects
<whitequark[cis]>
that's a typographical error
<whitequark[cis]>
what is meant is that they cannot advance simulation time
<whitequark[cis]>
which has some subtle conceptual and implementation benefits but may be relaxed later if it turns out that the drawbacks (not being able to implement a delay line within a process, for example) aren't worth it
<cr1901>
When does simulation time advance, and what makes it (internally to the sim impl) so that processes can't advance simulation time, but testbenches can?
<cr1901>
Under what conditions* does simulation time advance*?
<cr1901>
FWIW, I understand at a high level what e.g. the adder process is doing
<whitequark[cis]>
sim.delay() or via sim.add_clock when setting up the simulator
<whitequark[cis]>
as for "what makes it so that processes can't advance time": it's just an error to try and use sim.delay()
<cr1901>
Does tick() internally call sim.delay()?
<whitequark[cis]>
no
<whitequark[cis]>
(add_clock is equivalent to calling sim.delay(); sim.set() in a loop, it's a little faster though)
<cr1901>
Okay, I think my issue is understanding the difference between sim.tick() and sim.tick().repeat()/until(). Processes can call sim.tick(), according to the RFC. It seems that only sim.tick().repeat()/until() actually advance time?
<whitequark[cis]>
no
<whitequark[cis]>
there is example implementation code for sim.tick().until()/sim.tick().repeat() which should clarify this
<cr1901>
Ack. My "refrain" for 36 addendum should be treated as "I think the RFC is probably fine, but I did not have time/do not have bandwidth to grok the changes." I will probably only really get the RFC once I start porting over my simulations.
<cr1901>
I do genuinely need add_process functionality for certain TBs, so :P...
<whitequark[cis]>
good evening everyone, it is the time for our Amaranth core language meeting
<whitequark[cis]>
it was motivated by attempting to implement and use helper functions for streams in a pair of concurrent testbenches and discovering that it is essentially impossible to do soundly (the existing semantics for add_testbench, not specifically defined anywhere, was basically actively trying to break your testbenches)
<whitequark[cis]>
please respond with your comments or proposed disposition: merge or close
<tpw_rules>
i'm with cr1901 and abstain. i haven't had experience/time to study the design or understand the problem
<zyp[m]1>
I'm not 100% sold on sim.set() in a testbench blocking and running processes, but that's mostly from an implementation perspective, API wise it's fine and in line with sim.get() also not being async
<tpw_rules>
and assume the proposed solution is probably okay
<whitequark[cis]>
zyp: that's already how things work
<whitequark[cis]>
oh, you mean blocking as in it not having await?
<zyp[m]1>
yeah, I think it's fine, it just feels like a weird reentrancy thing
<whitequark[cis]>
that's kind of the point for this strict separation between processes and testbenches
<whitequark[cis]>
processes are pure functions (from inputs to outputs, or from inputs+state to outputs+state), so it's always OK to run them in a "blocking" way
<zyp[m]1>
yeah, I get that
<whitequark[cis]>
right, okay
<zyp[m]1>
overall I'm happy with the amendment in any case and vote merge
<tpw_rules>
"The function passed to add_process() must be idempotent" does this mean it could be called twice? and nonlocal users should be slapped?
<Wanda[cis]>
I feel we may want .get in processes at some point anyway, but that's a future problem
<Wanda[cis]>
merge
<whitequark[cis]>
tpw_rules: that's a notion of idempotence that's on the Amaranth simulation level, not on Python level
<whitequark[cis]>
it is already expected that it will be idempotent on Python level though, as sim.reset() will call the function again
<cr1901>
It's weird to me that sim.set() doesn't wait until the next clock tick before setting the value. I'm used to "schedule these changes to happen and then advance sim time"
<_whitenotifier-6>
[amaranth-lang/rfcs] wanda-phi 855f666 - Add an RFC for `lib.coding` removal.
<_whitenotifier-6>
[amaranth-lang/amaranth-lang.github.io] whitequark b511fb6 - Deploying to main from @ amaranth-lang/rfcs@91085031719e87026ca73fbf68eec232835db8be 🚀
<whitequark[cis]>
cr1901: the reason this was changed is explained in the `add_testbench` RFC
<cr1901>
the stream_send/recv functions seem to be "advance sim time, and then on the trailing edge of the clock, do the changes"
<zyp[m]1>
the addition of .sample() effectively moves the distinction between now/next from the write to the read of a signal
<whitequark[cis]>
cr1901: the stream send/recv functions do not do anything on the trailing edge of a clock
<whitequark[cis]>
the do things exactly at the posedge, in two stages: first all .sample() operations are done, then all sim.set() operations are done
<cr1901>
sorry, I didn't mean negedge
<cr1901>
I got as far as porting my testbenches to accommodate RFC 27
<zyp[m]1>
the way I see it, the original problem was «how do we distinguish between setting a signal now and setting a signal so it's visible at the next tick?», and this amendment answers that by «we don't, we instead add .sample() to distinguish between what the signal is now and what the signal was at the last tick»
<cr1901>
whitequark[cis]: My real question: Why is there no tick after "sim.set(stream.ready, 0)" or "sim.set(stream.valid, 0)"?
<cr1901>
in the stream_recv/send functions
<whitequark[cis]>
zyp: pretty much
<whitequark[cis]>
cr1901: (a) because there isn't any need for it; (b) because otherwise you could only read from a stream on 50% of cycles with back-to-back reads
<whitequark[cis]>
in fact, RFC 27, RFC 36, and this amendment all build up to being able to read from a stream or FIFO continuously
<whitequark[cis]>
it's remarkable just how poorly suited the Migen simulator interface was to such a seemingly simple problem
<cr1901>
mmmm, I'm gonna upgrade my refrain to merge
<whitequark[cis]>
disposition on amendment PR 64 to RFC 36: merge
<_whitenotifier-5>
[amaranth-lang/rfcs] whitequark 066020f - RFC #36: Amend with a concrete concurrency model.
<_whitenotifier-5>
[amaranth-lang/rfcs] whitequark ecfcd6f - PR #64: Amend RFC #36 with a concrete concurrency model
<_whitenotifier-6>
[amaranth-lang/amaranth-lang.github.io] whitequark 11e9117 - Deploying to main from @ amaranth-lang/rfcs@ecfcd6fea138cf7afba32824001aa7e5b84dfc79 🚀
<whitequark[cis]>
please respond with your comments or proposed disposition: merge or close
<whitequark[cis]>
although, closing this would delay the 0.5 release until a new RFC is proposed that fixes the existing technical design debt
<jfng[m]>
are unions considered out of scope of this RFC ?
<Wanda[cis]>
they are covered by Format.Struct
<zyp[m]1>
a union is just a struct where only one field is actually valid at a time
<whitequark[cis]>
and, in our implementation, it's not possible to know which if you're looking only at the union
<whitequark[cis]>
(except in the very narrow case where all fields are structs that have the exact same leading member that contains the tag, or something similar to it)
<jfng[m]>
so even in say, a waveform viewer, it is up to the user to know whether a given field comes from an union or a struct
<jfng[m]>
i guess that's fine
<zyp[m]1>
I'm not very familiar with RTLIL; what does the RTLIL parts of the RFC achieve? I guess that's how cxxrtl gets told how to log those signals?
<zyp[m]1>
whereas the VCD part concerns pysim?
<whitequark[cis]>
zyp: it basically means that if you get verilog output and look at the vcd dump from simulating that in verilator or the like, the vcd output makes sense
<whitequark[cis]>
RTLIL is a means to an end
<zyp[m]1>
right, yeah
<whitequark[cis]>
CXXRTL largely doesn't discriminate between Verilog and Amaranth input (it treats enums exactly the same for example), though for structs it might get some additional smarts (which may then be backported to the Yosys SV frontend by someone motivatede)
<Chips4MakersakaS>
I don't have much debug output and signal formatting experience; so I also refrain and leave decision to others.
<jfng[m]>
merge
<tpw_rules>
i guess it would be wrong coupling to have format recognize lib.data so we don't need more types?
<whitequark[cis]>
merge
<zyp[m]1>
merge
<zyp[m]1>
tpw_rules: yes, and it wouldn't be reusable
<whitequark[cis]>
tpw_rules: this is what's happening right now, and yes, it would be a forbidden coupling
<tpw_rules>
ok. merge
<whitequark[cis]>
also the design is frankly subpar, I cranked something out very quickly just to get 0.4 out
<zyp[m]1>
this allows any ShapeCastable to use Format.Struct to emit multiple traces
<whitequark[cis]>
yep
<zyp[m]1>
(although I'd guess a ShapeCastable that benefits from that could likely benefit from inheriting from data.StructLayout anyway)
<tpw_rules>
yeah my idea was it should just inherit or return a StructLayout and have that be formatted
<whitequark[cis]>
it's still a problem in that it creates weird dependency chains between hdl, lib, and the rest
<tpw_rules>
yes
<whitequark[cis]>
we do do look at lib.wiring in back already, which is likely unavoidable but we should at least not make it worse
<tpw_rules>
and of course with the RFC anyone who inherited from StructLayout would get a format impl which did the right thing already
<whitequark[cis]>
disposition on RFC 65: merge
<jfng[m]>
it would be useful in a VCD to have access to the "full" value of a struct in addition to its individual fields, also in cases of a nested struct
<jfng[m]>
though i don't know if this is doable, if e.g. the knowledge that a value is an union is lost in Format
<whitequark[cis]>
the meeting is now over! amazingly, we did it on time
<Wanda[cis]>
there's actually a usecase for using Format.Struct yourself, which is computed fields
<Wanda[cis]>
like if you want to make a virtual field that's a concatenation of two disjoint fields
<Wanda[cis]>
or something
<tpw_rules>
sure, you could still synthesize a StructLayout which had that
<tpw_rules>
to return from format
<jfng[m]>
maybe this could be done in the waveform viewer itself, like "make a virtual signal that concatenate those signals"
<zyp[m]1>
it could also be useful to use it to make multiple representations of the same value
<Wanda[cis]>
jfng[m]: > <@jfng:matrix.org> it would be useful in a VCD to have access to the "full" value of a struct in addition to its individual fields, also in cases of a nested struct
<Wanda[cis]>
we literally have it in the RFC though?
<Wanda[cis]>
> though i don't know if this is doable, if e.g. the knowledge that a value is an union is lost in Format
<zyp[m]1>
jfng[m]: I think making a waveform viewer is out of scope here :)
<whitequark[cis]>
oh, we actually did not resolve all unresolved questions on the last RFC
<whitequark[cis]>
there are 3. (1) Bikeshed on exact formatted display. (2) Do we need a FormatLike? (3) When structs are nested, should the intermediate structs get their own wires / VCD traces?
<whitequark[cis]>
FormatLike would be a class like ShapeLike, essentially just for typing purposes
<jfng[m]>
(2) can we add it later if we indeed end up needing it in user code ?
<tpw_rules>
FormatLike seems weird and not that pythonic
<whitequark[cis]>
(1) frankly doesn't need to be in the RFC at all, it's a minor change to update it
<zyp[m]1>
I'm not sure much user code would take FormatLike arguments, so it doesn't seem overly important, but I'm not opposed to it
<whitequark[cis]>
(2) we can add it later
<whitequark[cis]>
and it's not hard to write it out manually
<tpw_rules>
(1), can it just be JSON or is here not the right place to say that
<whitequark[cis]>
i don't think it can due to escaping
<Wanda[cis]>
it cannot literally be JSON because we cannot require downstream format to be JSON
<whitequark[cis]>
you'd need to reserve space for the biggest encodable JSON
<zyp[m]1>
and 3: yes, probably
<whitequark[cis]>
also that
<jfng[m]>
(3) may be useful, when trying to find matches between what you see in e.g. a memory dump and a VCD
<zyp[m]1>
I figure any ValueCastable that formats as Format.Struct should also be available as a raw value, even if it's nested in another struct
<Wanda[cis]>
alright then
<Wanda[cis]>
(1) and (2) will be arbitrarily decided by implementation, (3) will be "yes"
<whitequark[cis]>
actually @zyp's request is for a stronger property
<zyp[m]1>
let me restate that: I figure any ValueCastable should also be available as a raw value, even when it's nested in a struct.
<Wanda[cis]>
so you'd want an enum-shaped signal to be two traces?
<zyp[m]1>
so if you've got like a = Signal(StructLayout({'b': StructLayout({'c': Enum(…)})})), I'd expect traces for a, a.b and a.b.c, where the former two are raw values and the third has both a raw value and a name
<whitequark[cis]>
the reasonable implementation desugars to the use of $sformatf in the Verilog export, but that requires a new Yosys cell with all the associated headache
<_whitenotifier-5>
[amaranth-lang/amaranth-lang.github.io] whitequark a8201ff - Deploying to main from @ amaranth-lang/rfcs@465657c8ee67ce6ea99a4fe807eca2c7e8809de6 🚀
<whitequark[cis]>
and a month of waiting before the next release
<zyp[m]1>
what do you mean now? that a fixedpoint formatter would?
<whitequark[cis]>
yeah, translating arbitrary Format() to a value (like for a string trace) requires a new Yosys cell
<whitequark[cis]>
we do have it in mind but it's not a priority
<zyp[m]1>
fair, but that's a bit orthogonal to what we're discussing now
<whitequark[cis]>
what?
<zyp[m]1>
this were a discussion on whether we should present both the raw and the formatted value, not on the feasability of formatting the value in the first place
<whitequark[cis]>
well, if we can't format it in general, we shouldn't be trying to present both; that seems obvious to me
<zyp[m]1>
I don't expect fixedpoint to be done for 0.5 anyway, so I don't see how a fixedpoint formatter could be holding up 0.5
<whitequark[cis]>
65 isn't just about fixed point though
<zyp[m]1>
and if we could theoretically have such formatters in the future, it seems reasonable enough to be able to have a discussion now on whether it makes sense to present both the raw and the formatted value
<whitequark[cis]>
tbh if we're talking "several months in the future", I'm leaning towards "you only ever get raw values in verilog export unless you use the RTL debugger and the CXXRTL protocol, in which case you get full formatting support"
<whitequark[cis]>
and it's just a per-trace choice you can make
<whitequark[cis]>
like whether you get hex or formatted
<whitequark[cis]>
and then pysim can also use the CXXRTL debugger protocol