<tpw_rules>
amaranth will handle the FSM reset automatically
<crzwdjk>
If you need to reset it with something that's not the global reset you can also use ResetInserter
<tpw_rules>
as for the switch to init when (valid && !ready && state == STATE_IDLE), you can put an if statement inside the IDLE fsm state to handle that condition
<tpw_rules>
like any other amaranth statement, only the last m.next which matches will be used
<tpw_rules>
(it also follows that if you didn't want to use a resetinserter for whatever reason, you could put the reset logic at the end of every state)
<zyp[m]>
is it possible to only reset the FSM and not all the other state in the module/submodules?
<tpw_rules>
i don't know how
<whitequark[cis]>
not if you use ResetInserter, no
<whitequark[cis]>
(this is something we could fix once scopes land)
<tpw_rules>
to use resetinserter on just the fsm you would indeed have to kick it into a submodule
<tpw_rules>
you could put the reset logic in a python function too, i think that would be reasonably justifiable
<zyp[m]>
I guess you could do something cursed like instancing a second module in the same elaboratable and put only the FSM into that
<whitequark[cis]>
you could do that but it might cause a hierarchy flattening warning if you use certain patterns
<zyp[m]>
ah, because it'd cause driver conflicts otherwise, yeah
<tpw_rules>
does that warning flatten the whole design?
<tpw_rules>
quasi-relatedly, is there hope for, if i construct 1000 of the same Elaboratable class, to emit verilog with one definition and 1000 instantiatons?
<whitequark[cis]>
if you ran Yosys on this input, it would produce, as an intermediate result, exactly the same kind of netlist (in memory)
<whitequark[cis]>
Amaranth simply brings this step closer to the source (necessarily so)
<whitequark[cis]>
tpw_rules: no, only as-needed
<whitequark[cis]>
however, note that with the new IR, what we are doing is flattening the whole design and then hallucinate module boundaries back
<whitequark[cis]>
because this is the only practical approach to problems like "CDC analysis" and "people can use sig[0] to communicate between modules a and b in comb domain and sig[1] to communicate between modules c and d in sync domain"
<tpw_rules>
what do you mean by hallucinate?
<tpw_rules>
i thought the hierarchy preservation was a valuable improvement over migen
<whitequark[cis]>
correct
<whitequark[cis]>
what happens is that hierarchy is erased, the netlist is constructed and processed, and then, during emission, the hierarchy is reconstructed back based on debug information
<tpw_rules>
sounds pretty ambitious
<whitequark[cis]>
this is, interestingly enough, the same thing as what Vivado does if you use -keep_hierarchy
<whitequark[cis]>
tpw_rules: we have most of it working
<whitequark[cis]>
it's actually simpler than the existing scheme in some ways, and for sure more reliable
<iposthuman[m]>
I've seen mention of ResetInserter several times but i don't quite understand how it affects the generator.
<tpw_rules>
that's bringing up horrible memories of trying to SignalTap™ stuff
<whitequark[cis]>
oh yeah, ILA for Amaranth is another item on the long term roadmap
<tpw_rules>
that would be very exciting
<crzwdjk>
iposthuman[m]: ResetInserter(some_signal)(my_submodule) returns a module that gets reset when some_signal is 1
<tpw_rules>
i guess vendor ILAs are unreliable to preserve design behavior?
<tpw_rules>
it's hard to fathom that their engines are so screwed up they can't stash a signal away reliably but i guess it's possible
<whitequark[cis]>
hm? no, why would I even try to use vendor ILAs?
<tpw_rules>
i'm not saying you would, just trying to explain my personal experiences with them
<tpw_rules>
s/explain/understand/
<whitequark[cis]>
there's no Yosys/nextpnr ILA, so Amaranth has to fill it in
<tpw_rules>
i'm just wondering why "take this variable in the verilog and connect it to an ILA" is such a damn hard problem for quartus
<whitequark[cis]>
oh, it's because Quartus isn't a good toolchain
<tpw_rules>
is vivado's better?
<whitequark[cis]>
I've not used it much but I think it is better, yes
<tpw_rules>
like the ILA on quartus is okay, it's just that hooking signals to it is difficult and fraught with trouble
<iposthuman[m]>
Ok i think i understand, but what about the other if statements attempting to control the fsm "outside" of the fsm itself. In my example there is```m.if(x) m.next = "xx"
<iposthuman[m]>
m.Elif(y) m.next = "yy".
<iposthuman[m]>
```In other words how would you modify the next state outside of the fsm's with-states?
<whitequark[cis]>
tpw_rules: wait, were you using `(* keep *)` on signals of interest?
<tpw_rules>
you can't
<tpw_rules>
whitequark[cis]: i ended up having to make an always block to latch them into temporaries, then noprune those temporaries
<tpw_rules>
iposthuman[m]: why not put that if statement into a state?
<whitequark[cis]>
tpw_rules: ok, in Vivado `(*keep*)` is enough
<iposthuman[m]>
Amaranth doesn't like that that verilog code was modifying the next state based some "if" statements. in verilog this is allowed but not Amaranth
<tpw_rules>
whitequark[cis]: but why are they not smart enough to automatically add that to signals selected for ILA :(
<iposthuman[m]>
That was one of my ideas but the fsm would need to be in that state in order to do stuff. yes?
<tpw_rules>
yes
<tpw_rules>
if the logic applies in multiple states, you'll have to duplicate it. judicious use of python local functions would make this cleaner
<iposthuman[m]>
Ah. wouldn
<tpw_rules>
i have internally wished for a reimagining of amaranth FSMs to make this easier before but i'm not really sure how it would look
<zyp[m]>
litescope is easy to use and conceptually pretty simple and a minimal amaranth equivalent shouldn't really be all that much work
<iposthuman[m]>
* Ah. wouldn't that produce larger resource usage?
<tpw_rules>
probably not
<tpw_rules>
zyp[m]: is it hooked up over jtag on intel?
<iposthuman[m]>
* Ah. wouldn't that produce larger resource generation?
<whitequark[cis]>
tpw_rules: yeah me too
<zyp[m]>
tpw_rules: it's memory mapped, and litex has jtag memory bridges, so I expect it can be
<tpw_rules>
iposthuman[m]: likely not. it's just changing the inputs to the circuit, not the circuit itself really
<tpw_rules>
zyp[m]: problem is i was last using it to debug my bus :D
<iposthuman[m]>
Ah, okay.
<zyp[m]>
I've mainly used litescope with ethernet and usb bridges
<tpw_rules>
the cost model for verilog is very different than regular code
<tpw_rules>
litex is not really my favorite either but that's a separate problem
<zyp[m]>
I've recently been wanting a utility to capture ADC streams for debugging, and I guess if I want to capture multiple streams that don't always run in sync, I might as well just do an ILA with RLE
<iposthuman[m]>
Does anyone have, or know of, a ResetInserter being used with an FSM?
<crzwdjk>
I mean I have a module with an FSM inside it, I wrap the module with a ResetInserter. Haven't pushed the code to github yet, but it's pretty straightforward.
<zyp[m]>
I've been turning the simulator racing over in the back of my head for a bit, and have an increasing belief that a way to distinguish «set now» from «set soon» is a viable solution, with a couple of different possible approaches
<zyp[m]>
one is to actually have those as distinct methods or a method argument or whatever, which I guess will somewhat resemble blocking and nonblocking assignments in verilog
<zyp[m]>
another is to have a sort of barrier where writes after the barrier doesn't affect reads before the barrier, which is what a picosecond delay achieves, but which would probably be cleaner if implemented as two different phases at a single simulation timestamp
jfng[m] has quit [Quit: Idle timeout reached: 172800s]
<whitequark[cis]>
I'd like you to evaluate the solution I proposed yesterday before venturing into "let's replicate Verilog"
<whitequark[cis]>
(I'm not going to replicate Verilog)
<whitequark[cis]>
to clarify my position further, I think having testbench processes is an absolute necessity to enable the more complex SoC use cases (right now doing a write on the CSR bus for example is extremely difficult to do in a simulation) and I think that even having these races unresolved isn't a reason to avoid progressing on testbench processes. we could even show a warning if you add more than one at the same time; this would still
<whitequark[cis]>
be a vast improvement over status quo
<zyp[m]>
I agree, I'm of the opinion that both RFC 27 and RFC 36 are good and that the races should be fixed in a new RFC building on those
<zyp[m]>
or to put it differently, that the races doesn't block RFC 27
<whitequark[cis]>
that's good!
<whitequark[cis]>
what do you think of my idea to track def-use relationships between processes?
<zyp[m]>
I need to think it through, will get back to you later on that