<gatin00b[m]>
That would be handled by amaranth ast parser which is not most optimal.
<charlottia>
It will, probably(tm), but sometimes things like that can get surprising. You can compare the output size (in terms of cells used) to be sure.
<gatin00b[m]>
This is, Amaranth's ast might not optimize it, but the synthesis tool is likely to do it.
omnitechnomancer has joined #amaranth-lang
<omnitechnomancer>
What is the intelligent thing expected?
<gatin00b[m]>
Considering the constant, the some_complex_expression would not get evaluated.
<omnitechnomancer>
The synthesis tool should manage to optimise away some_comppex_expression then because the or 1 will make it have no effect.
<gatin00b[m]>
Yes, but Amaranth might still evaluate it as part of AST evaluation.
<gatin00b[m]>
I'd wildly guess, the clock ain't running?
<mcc111[m]>
omnitechnomancer: Uh… running the program
<mcc111[m]>
gatin00b[m]: If I simply run `m.d.sync += self.count.eq(self.count + 1)` and don't bother with the with:s, it works fine
<mcc111[m]>
mcc111[m]: I'm running it on a FPGA connected to 16 LEDs, the LED corresponding to the number "Count" is always lit. So it's very easy to tell what values count is taken
<charlottia>
Fwiw it's a very good idea to start simulation testing very soon! Otherwise things like this will become undebuggable. (see https://amaranth-lang.org/docs/amaranth/latest/start.html for a quick example, down at "Testing a counter".)
<mcc111[m]>
This is a pretty simple case— would running in a simulation help?
<charlottia>
Yes -- it'll tell you if that line is having its desired effect, or if the issue is elsewhere.
<gatin00b[m]>
Well, if simulation works while FPGA doesn't, that cues on what we should be debugging
<charlottia>
If you can share more context (from the "doesn't work" example), that might help, but otherwise perhaps you can find it yourself through simtesting.
<omnitechnomancer>
Is `am.C` something new? I don't recognise it
<charlottia>
(In this case I unconditionally create the Signals in __init__, and then replace them with platform-requested resources in elaborate)
<omnitechnomancer>
I think I'd tend to just pass the result of the request to things which need it and if they get one hook them up to the signals, but not actually do the requests below top level
<omnitechnomancer>
But I have not made any large designs
<charlottia>
(you need to do plenty of platform-specific stuff in the design, because elaborate() is the only time a given elaboratable actually knows what platform it's being built for. None could be considered the simulator platform, in this respect. If you wanted to, at this point, you could then replace it with your mock Platform.)
<charlottia>
omnitechnomancer: That's a nice way to keep what a design is actually requesting clear!
<mcc111[m]>
<charlottia> "Yes." <- Doesn't that defeat the purpose of the platform object if instead of calling its methods you're just building case statements every tiem?
<omnitechnomancer>
Indeed, it also makes it easier to mock things for a given elaboratable when doing simulation or formal
<mcc111[m]>
charlottia: I would like for my mock Platform to only exist in the simulator, because that's the only time it's used
<charlottia>
The platform isn't for you, it's for Amaranth, if that makes sense?
<charlottia>
It doesn't (shouldn't) know about your design.
<mcc111[m]>
actually unless it's necessary I'd rather my design proper not know the simulator exists at all…?
<mcc111[m]>
charlottia: I'm definitely using it, though
<omnitechnomancer>
Actually that brings a question to mind, does Amaranth deal with piping the signals from requested IOs up to the top level module?
<charlottia>
Yep!
<charlottia>
(well, Amaranth/yosys, somewhere.)
<charlottia>
mcc111[m]: I think it really should!
<omnitechnomancer>
At some level you require a simulation test bench that will have to know the simulator exists
<omnitechnomancer>
And in general it is easier to make the elaboratables not request resources directly as it makes plumbing them together more clear and lets you do simulation
<charlottia>
Mhm! At some point you'll need to switch on the platform, whether it's at the top level or elsewhere, but the point is that they are not trying to abstract over the difference you might be wanting them to here?
<mcc111[m]>
omnitechnomancer: What if I need to simulate the resources? :/
<charlottia>
(You may want to add your own layer of abstraction, which does the platform switching.)
<mcc111[m]>
Alternately, what if eliminating those parts of the design eliminates whatever it is I'm trying to debug in the first place?
<charlottia>
If you've replaced them with like-for-like shapes, then it won't.
<charlottia>
(Unless the problem is indeed in hardware.)
<charlottia>
Now you have a Signal called button_ffwd which, on the real hardware, is transparently connected to the input.
<omnitechnomancer>
The resource request returns an object with a bunch of signals in it, that is actually all you need for simulation, you can drive signals in your simulation process. The actual request process is not necessary
<charlottia>
But on sim, it's just a Signal which you can toggle in your bench.
<mcc111[m]>
This is a lot of clutter
<omnitechnomancer>
The reason I don't think things below the top level should be requesting resources is that the resources will be different on different boards/platforms anyway, so you can have a top-level specific to one case and just pass the relevant signals down
<mcc111[m]>
But I want to simulate the board
<mcc111[m]>
This is not written to run on more than one board
<charlottia>
omnitechnomancer: I don't super agree but I have very different experience to you!
<omnitechnomancer>
(or attach to signals created by init yourself)
<charlottia>
(that was re: omni)
<charlottia>
mcc111[m]: You can simulate the whole board!
<charlottia>
The increment never actually goes anywhere in that module, if I'm not missing anything.
<mcc111[m]>
I made it into the simulator and I unfortunately don't understand what I'm looking at :( most of my signals are not listed on the left hand side like the last time I tried to run the simulator, and the one value I can see (the counter I wanted to monitor, thankfully) is… simultaneously 0 and 1?
<gatin00b[m]>
@charlotte, no, you are right
<charlottia>
(\$2 does the actual count + 1, that's assigned to \$1, but \$1 never goes anywhere. \count$next stays as count or 0.)
<charlottia>
mcc111[m]: Not simultaneously -- that's a two-digit representation.
<charlottia>
(it needs two hex digits to represent a 6-bit value)
<charlottia>
Yes, it's incrementing. But I would really not say Amaranth bug yet, heh.
<mcc111[m]>
I think the question is not "Amaranth bug?" but rather "Should I file an issue?"
<charlottia>
(Is the version you have pushed the latest?)
<mcc111[m]>
The version I have pushed is the latest other than my simulator code. Would it help to push the simulator code?
<charlottia>
I think we should try to extract to to a minimal example first, to see if there is an issue.
<charlottia>
Yes! I think so.
<mcc111[m]>
okay, one second. You will not like what I did.
<charlottia>
:D I like the sound of that.
<mcc111[m]>
Okay, reload the branch on github, and that is the most current issue.
<mcc111[m]>
Since in the test branch removing the Elif and putting two Ifs fixed the problem, I am going to try it in the "Functional" branch now.
<charlottia>
Thanks! Having a look.
<charlottia>
(Wow, yep, that is beautifully cursed. Nice one!)
<mcc111[m]>
The code is not fully commented, but if it helps to understand, the intent is to run over every single one of the 16 LEDs, and light every single one in turn, BUT 12 of the 16 LEDs only light on 1 out of every 4 cycles they have the opportunity to run.
<mcc111[m]>
In addition, there is a complex "grid" signal, which I have not wired in to do anything yet because just refactoring the Counter class to add more features broke the basic "light every light" code.
<charlottia>
It's eliminating the second case, I guess because it thinks the first is always true.
<mcc111[m]>
Is that in a situation where, in fact, the first case is always false?
<mcc111[m]>
would using Elif instead of a second If result in different calls to Yosys, such that Yosys has the opportunity to make the mistake instead of Amaranth?
<charlottia>
It probably makes two different processes in that case, yeah. Let's see.
<charlottia>
(Indeed, it's going to be, since they can't form part of the same switch.)
<charlottia>
Double-checking if there's anything known here ..
<gatin00b[m]>
charlotte: isn't the rtlil generated by amaranth?
<charlottia>
Yes. But the RTLIL looks correct.
<charlottia>
Oh, actually. Hmmmm.
<gatin00b[m]>
But running on the FPGA, it wasn't working either. not just the verilg backend
<charlottia>
Mhm!
<gatin00b[m]>
Though, you have better observability on this than I have (and likely less sleep deprived)
<charlottia>
But the bug isn't in the Verilog backend -- it's in the optimization.
<charlottia>
I am only moderately sleep deprived ^_^
<charlottia>
We're doing a switch 2'10, case 2'-1, and that case is always being taken. It should not.
<mcc111[m]>
So the bug is in Amaranth then?
<charlottia>
I can confirm too that putting that RTLIL straight into Verilog does not reproduce the error; it's correct.
<charlottia>
No, the bug is in a Yosys optimization pass.
<charlottia>
(If you like I can chase this further and file the issue/open the PR/whatever. Or I'm happy to leave it to you if you'd prefer.)
<mcc111[m]>
Hm.
<mcc111[m]>
If the bug is in Amaranth, then I am happy to write it with the information I have linked above.
<mcc111[m]>
However if the bug is in Yosys, then I do not think I could adequately describe it to them, and it would be great if you could write it. If there's anything I could put together to make that easier I could do so?
<charlottia>
Understood! I'll verify for sure, 100%. The question is whether the match of 2'-1 against 2'10 should succeed per RTLIL semantics. If it should succeed, it's an Amaranth bug. If not, it's a Yosys one.
<charlottia>
Checking ...
<charlottia>
(I have verified that the optimization pass is what reduces it, and not, say, the Verilog backend.)
<mcc111[m]>
Thanks!
<charlottia>
Yeah, okay. I can't really see how this could be correct behavior from Yosys. I'll verify it's still happening on Yosys HEAD, but unless further digging reveals there's some weird definition of "don't care" (that match is essentially saying "10" matches the regexp /^.1$/), I'm ~80% confident it's a Yosys optimization pass bug.
<mcc111[m]>
Fascinating D: D: thank you so much for the help.
<charlottia>
You're very welcome! Thanks for bearing with my attitude!
<mcc111[m]>
incidentally, with the elif replaced with a ` with m.If((~observe_condition) & single_shot_condition): # FIXME elif would be better`, I can turn on the grid code and the design now fails to work in a FASCINATING way, but a way which is much more likely to be my fault!
<charlottia>
!!! Yaaaaaay :D :D :D
<mcc111[m]>
also, probably this IS the correct time to get the simulator working, so maybe tomorrow I'll be back with some questions about why the signals I expect to exist are not shown in the signal viewer.
<charlottia>
Right! Also, to quickly answer that: you can force additional signals to be shown in the VCD; if you add the signals to traces=[...] in the call to write_vcd.
<charlottia>
<charlottia> "Yeah, okay. I can't really see..." <- (Confirmed yosys HEAD doesn't help this.)
<mcc111[m]>
charlottia: great, thank you
<charlottia>
(Have confirmed PROC_CLEAN removes those two cases, and a further PROC_CLEAN then removes the now-empty switch altogether. My confidence this is in fact a bug has risen to 90%.)
<charlottia>
(It's not doing what I initially thought, which was considering the first case true: it's actually eliminating them both instead.)
<mcc111[m]>
Hey weird question: what's the bit width of C(0)
<mcc111[m]>
<charlottia> "You can ask for a zero-length..." <- I was talking to someone who says that breaks Yosys. Though since I can't imagine what he expected that to do I'm not sure how you'd tell it was broken…
<mcc111[m]>
> <@charlotte:hrzn.ee> You can ask for a zero-length, though: `C(0, 0)`.
<mcc111[m]>
* I was talking to someone who says 0-length signals break Yosys. Though since I can't imagine what he expected that to do I'm not sure how you'd tell it was broken…
<Wanda[cis]>
<mcc111[m]> "I was talking to someone who..." <- they... shouldn't
<Wanda[cis]>
I spent a bunch of effort to make sure they're correctly handled, at least in normal synth paths
<whitequark[cis]>
<mcc111[m]> "I was talking to someone who..." <- that might be me; and me & Wanda spent a significant amount of effort making sure they don't do that. in any case, zero-length expressions are legal in Amaranth
<mcc111[m]>
ok
<whitequark[cis]>
oh that's a lot of backlog
<galibert[m]>
What do they mean ? Is it just to make it easier to do generics-ish ?
<whitequark[cis]>
what is the bug exactly? I'd like to see a reproducer without reading hours of interleaved chat logs
<whitequark[cis]>
galibert[m]: yes
<galibert[m]>
Like return void?
<galibert[m]>
Ok
<galibert[m]>
Makes sense
<galibert[m]>
Catherine: there’s a yosys bug unrelated to zero-width signals Charlotte tracked down
<galibert[m]>
And there’s a remark on mastodon about yosys and weirdly sized signals
<mcc111[m]>
Aside from the strange thing I'm doing with Platform, is the bench() here the correct way to represent "do nothing for 32 ticks, flutter signal debug_button_0 on and off for 32 ticks, do nothing for 32 ticks"? I'm getting confusing results in the simulator with debug_button_0 apparently never changing and nothing having any effect
<mcc111[m]>
can post more information but just want to make sure i'm not doing something totally incorrect
<whitequark[cis]>
btw, you don't need to do platform_override; you can doSimulator(Fragment.get(dut, SimPlatform()))
<mcc111[m]>
doesn't seem to be specific documentation of the Simulator object
<whitequark[cis]>
there's not a lot of documentation on the simulator because the current model (implemented based on and compatible with Migen) is fundamentally broken in a subtle way and needs to be completely redone
<whitequark[cis]>
but this isn't happening very quickly either due to various reasons
<mcc111[m]>
whitequark[cis]: Okay. SimPlatform is a builtin thing in amaranth namespace or you're suggesting I create the object there?
<mcc111[m]>
> <@whitequark:matrix.org> btw, you don't need to do `platform_override`; you can do`Simulator(Fragment.get(dut, SimPlatform()))`
<mcc111[m]>
* Okay. SimPlatform is a builtin thing in amaranth namespace or you're suggesting I pass in my own object there?
<whitequark[cis]>
SimPlatform is just what I'm suggesting you call your simulation platform file for disambiguation
<whitequark[cis]>
since Platform is pretty generic
<mcc111[m]>
ok, thanks. does/should that object inherit from anything?
<mcc111[m]>
* ok, thanks. should my class inherit from anything specific or implement anything other than that one function, do you think?
<mcc111[m]>
* ok, thanks. should my class inherit from anything specific or implement anything other than that one request function, do you think?
<whitequark[cis]>
nope, the implementation is good
<whitequark[cis]>
there will be something upstream that simplifies it eventually, but what you have is perfectly fine
<mcc111[m]>
ok. let me test some more and then i'll have some more questions
<mcc111[m]>
<Wanda[cis]> "yes" <- It looks like the zero width bug whatever it is has since been fixed
<whitequark[cis]>
yeah, I think I did fix it back then
<mcc111[m]>
has anyone ever tried using amaranth with the python3 typing system?
<whitequark[cis]>
a few people do
<whitequark[cis]>
however it's not really designed for it, and I've never been particularly happy with how verbose or obtuse the Python typing is, especially on the lowest versions we support (3.8)
<mcc111[m]>
This is what I get in gtkwave, button0 stays 0 the whole time and the _overflow variable I am using for debounce stays 1 (it is active low for these purposes)
<zyp[m]>
you need a yield after line 27
<galibert[m]>
IIRC (phone only) it’s yield Step()
<whitequark[cis]>
no, that part is correct
<whitequark[cis]>
there's also no Step
<galibert[m]>
And yield mumble.eq(…) does not advance time
<mcc111[m]>
Okay. Inside the for range, because that advances time. Got it
<galibert[m]>
Read-yield does not advance time either fwiw
<mcc111[m]>
Read yield?
<galibert[m]>
Catherine : how do you advance time with multiple domains btw (or it’s a don’t fo that with the current version of the sim) ?
<mcc111[m]>
Is there a way to get gtkwave to remember a set of "show me these signals" in the right side pane from run to run? every time I open a new .vcd file I have to click on them all separate
<galibert[m]>
I mean pip —user install . In the git clones of everything amaranth*
<whitequark[cis]>
mcc111: or is that the page that's not giving you the answers?
<mcc111[m]>
whitequark[cis]: So the other scripts I saw were just using the [tool.pdm.scripts] manually? No magic
<mcc111[m]>
No magic is fine
<whitequark[cis]>
there is no magic
<mcc111[m]>
That's fine
<whitequark[cis]>
what do you expect the magic to do?
<galibert[m]>
Don’t do that unless you really know what you’re doing and are ready do deal with the 256 pieces
<whitequark[cis]>
I think what galibert is saying is completely unrelated to your question
<galibert[m]>
It is
<galibert[m]>
(Completely unrelated )
<mcc111[m]>
whitequark[cis]: I got confused and somehow thought pdm had designated one of the py files as a root and was just automatically discovering function names based on them being in the namespace of that py file
<mcc111[m]>
One more question… is there a way in the gtkwave interface to tell it to group together a group of 1-bit signals and display them as a Number?
<mcc111[m]>
I did find this tutorial, uh, coincidentally written for nmigen/amaranth, on how to inject numbers into the gtkwave trace, which is neat, but was curious if gtkwave had such a feature built in https://libre-soc.org/docs/gtkwave_tutorial/
<whitequark[cis]>
libre-soc.org is not actually using nmigen/amaranth, though they are saying they do
<mcc111[m]>
it's already doing uh… nearly what i want
<mcc111[m]>
oh
<whitequark[cis]>
what they did is they forked the project and then used trademark lawyers to attempt and force me to change the name
<mcc111[m]>
oh
<mcc111[m]>
that's who that was
<whitequark[cis]>
their attempt failed (https://github.com/nmigen still belongs to me), but I consider the name far too burned at this point and changed it myself
<whitequark[cis]>
well, no, libre-soc.org is one disgruntled developer who got banned from the channel after he tried to rather aggressively backseat-drive the development
<galibert[m]>
Also Amaranth is much easier to say
<whitequark[cis]>
(banned for being a total asshole, it's in the logs if you're interested)
<whitequark[cis]>
he has a license for the trademark from Sebastien Bourdeauducq, who paid the lawyers (and lost probably something like $10k on the whole thing)
<galibert[m]>
Catherine: is it funny drama or just dumbassery?
<whitequark[cis]>
it's really funny in retrospect to watch them flail and fail, though at the time it was very stressful
<whitequark[cis]>
galibert: just dumbassery
<galibert[m]>
Bah, not interesting to look at then
<whitequark[cis]>
mcc111: in practical terms it means what libre-soc calls "nmigen" has no real relation to amaranth and seeing as i don't think they do much real development, it's probably diverging slightly from amaranth 0.2 and not getting any updates beyond that
Bluefoxicy has quit [Ping timeout: 246 seconds]
Bluefoxicy_ has joined #amaranth-lang
Bluefoxicy_ is now known as Bluefoxicy
<galibert[m]>
Is my sentence on yield moving around for you too or is it just my iOS client that’s drunk ?
<whitequark[cis]>
moving around?
<galibert[m]>
It’s advancing in the history to stay as roughly my second to last sentence
<whitequark[cis]>
that might be because you had a network issue and it never got sent
<whitequark[cis]>
does it have a red (!) next to it?
<galibert[m]>
No
<galibert[m]>
Pretty sure mcc read it since it used the exact terms « advance time » afterwards
<galibert[m]>
Bah whatever
<galibert[m]>
Seems to have stopped now
GenTooMan has quit [Ping timeout: 246 seconds]
<mcc111[m]>
Sorry, back… quite a lot of water just got spilled on my electronics table
<mcc111[m]>
So given that information, my question: Apparently the trace files gtkwave opens support placing custom strings into the traces at certain points (as well as, interestingly but not as interestingly, specifying trace colors in the trace file). Is any of this functionality exposed in Amaranth's current simulator?
<whitequark[cis]>
> Apparently the trace files gtkwave opens support placing custom strings into the traces at certain points
<mcc111[m]>
So known way to do this is give string names to an enum?
<whitequark[cis]>
you can use Signal(formatter=...) where ... is a function turning an int (signal value) into text
<mcc111[m]>
oh, that's very cool
<whitequark[cis]>
yeah!
<galibert[m]>
Is it called at every time step or on value change?
<whitequark[cis]>
unspecified
<galibert[m]>
One could do…. Interesting things with such power
<whitequark[cis]>
which will then break as the simulator is upgraded
<whitequark[cis]>
unless you mean something other than "relying on unspecified behavior"
<galibert[m]>
Well, I was thinking connecting a prefetch/ir register to a disassembler table, which should not break
<whitequark[cis]>
oh yes
<whitequark[cis]>
I've done that
<whitequark[cis]>
it's actually one of the motivating cases for the feature
<galibert[m]>
I see that
<whitequark[cis]>
if you want you can just pipe it to an external disassembler or something
<whitequark[cis]>
(this works much better for RISC)
<galibert[m]>
There may not be enough state un one register (thinking z80 prefixes) but one can collate all the information in a virtual bigger one at zero cost
<whitequark[cis]>
yes
<galibert[m]>
Virtual as in not stored anywhere
_whitenotifier-9 has quit [Ping timeout: 246 seconds]
<mcc111[m]>
I now understand the simulator well enough I was able to identify the bug by studying traces neo_bullets.png
<crzwdjk>
The simulator is your friend, much easier than debugging with actual hardware in most cases
<mcc111[m]>
the one thing that confuses me is that it shows four modules for my design (correctly) and which module the signal winds up in in gtkwave is very, very mysterious and surprising to me
<mcc111[m]>
The one thing I don't understand is why some traces show up in gtkwave automatically and some require being in the traces= list
GenTooMan has joined #amaranth-lang
FFY00 has joined #amaranth-lang
GenTooMan has quit [Ping timeout: 246 seconds]
GenTooMan has joined #amaranth-lang
<mcc111[m]>
*staring at the python operator precedence list*
<mcc111[m]>
`(~x) & (~y)`
<mcc111[m]>
The parenthesis here are unnecessary. Right?