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 · play https://amaranth-lang.org/play/ · code https://github.com/amaranth-lang · logs https://libera.catirclogs.org/amaranth-lang · Matrix #amaranth-lang:matrix.org
d_olex__ has joined #amaranth-lang
d_olex_ has quit [Ping timeout: 260 seconds]
jjsuperpower_ has joined #amaranth-lang
Degi has quit [Ping timeout: 248 seconds]
Degi has joined #amaranth-lang
urja has quit [Read error: Connection reset by peer]
urja has joined #amaranth-lang
jjsuperpower_ has quit [Ping timeout: 272 seconds]
indy_ has joined #amaranth-lang
indy_ has left #amaranth-lang [Leaving]
<_whitenotifier-4> [amaranth] whitequark opened issue #1614: Use `publication` to avoid leaking private implementation details - https://github.com/amaranth-lang/amaranth/issues/1614
vegard_e[m] has quit [Quit: Idle timeout reached: 172800s]
frgo has joined #amaranth-lang
frgo has quit [Remote host closed the connection]
frgo has joined #amaranth-lang
frgo has quit [Client Quit]
conventia[m] has joined #amaranth-lang
<conventia[m]> FSM's use strings for state names, but when simulating, `ctx.get(fsm.state)` returns a number. Is there any way to know which string is which number?
<whitequark[cis]> try fsm.encoding
<conventia[m]> Are there docs for the FSM interface? I haven't found them.
<conventia[m]> Ah, read that already. Thanks.
<whitequark[cis]> the FSM object was never really designed properly and it doesn't fit too well into the language as it is today
<conventia[m]> Would you avoid using it?
<whitequark[cis]> which is why i haven't explicitly documented it at the time
<whitequark[cis]> there are no specific plans right now to deprecate or modify it (and if there were, there'd be a deprecation period)
<whitequark[cis]> it's just one of those things i still need to clean up on the road to 1.0
<conventia[m]> Well, I definitely enjoy Amaranth better than Verilog. 😛
<whitequark[cis]> happy to hear that ^^
<conventia[m]> Oh, I was wondering if it's possible/recommended to remove the default `sync` clock domain from Elaboratable's which are intended to be entirely combinational?
<whitequark[cis]> sync is not actually added by default or something
<whitequark[cis]> it's just a convention
<conventia[m]> Oh, I guess I misunderstood. I assumed that m.d.foo += a.eq(~b) would result in an error, but it just creates a foo clock domain.
ydnatag[m] has joined #amaranth-lang
<ydnatag[m]> <conventia[m]> "Well, I definitely enjoy..." <- I not only enjoy Amaranth more than Verilog, I feel myself more productive using it. And I'm not the only one that feels that, the first and second places of the fpga hackaton organized by nokia were the only two teams using amaranth
<whitequark[cis]> ydnatag: oh that's wild, i've never heard of it
<conventia[m]> I guess I was curious if there was a way to make m.d.sync += ... be an error instead of just creating a sync domain.
<whitequark[cis]> conventia: it doesn't actually create a new domain
<whitequark[cis]> "creating a clock domain" and "placing logic into a clock domain" are two different operations; the former is done by assignment of a `ClockDomain` object to `m.domains`, the latter is done by assignment of statements to `m.d.<x>`
<whitequark[cis]> most modules do not define any clock domains, they merely place logic into a well-known or predefined or otherwise communicated domain by its name. the actual binding of logic to clock domains doesn't happen until the end of elaboration
<conventia[m]> Ok, so is there a way of restricting logic being placed into a clock domain such that I get a syntax error rather than a phantom domain that I wasn't expecting due to a typo?
<whitequark[cis]> in a word: no. it also can't be a syntax error because clock domains are late-bound
<whitequark[cis]> what you can do however is to reject it during elaboration
<whitequark[cis]> are you using a platform from amaranth-boards?
<conventia[m]> Yeah, icebreaker currently.
<whitequark[cis]> hm. that should already be giving you an error on a missing domain
<whitequark[cis]> let me see what's going on here
<conventia[m]> It does.
<whitequark[cis]> okay, is your question essentially "can you get the error earlier in the build"?
<conventia[m]> My original question was motivated by wanting to write/test a combinational only Elaboratable, which would then be part of a larger design which had a clock domain.
<conventia[m]> I.e. if I write an adder and typo m.d.sync += ... when I really meant m.d.comb += ... can get detect that somehow?
<whitequark[cis]> no, we don't currently have any way to do this. it's possible using internal APIs, but not in a convenient way
<conventia[m]> Not a big deal. 🙂
<whitequark[cis]> it's a reasonable ask to be able to assert that your hierarchy only has certain domains
<whitequark[cis]> ydnatag: i'm super curious about the FPGA hackathon, is there anything more i can read?
<whitequark[cis]> i know Kuznia Rdzeni from Coreblocks and i've talked to some folks there, but i know nothing about the other team
<ydnatag[m]> <whitequark[cis]> "ydnatag: i'm super curious about..." <- I dont know if there is or not more information availablr, but I was in the Malagana team, i have the tasks and user guides
<whitequark[cis]> conventia: there's a clock domain redesign on the horizon, which might introduce a way to introspect the clock domains of a design tree
<whitequark[cis]> ydnatag: i would be curious about that, but i'm even more interested in feedback re: the language. what worked well? what didn't? what things would you like to see improved? which things do you think are good as they are?
<conventia[m]> I look forward to it.
<ydnatag[m]> Hmm good questions... the best thing i think i is using all python stuff to generate hdl and being able to mix comb and sync logic in the same code block are the best features. Of course that interfaces connections and other features i'm missing are amazing too.
<ydnatag[m]> At work, I'm using an old version of amaranth previous to the simulation refactor so I can't tell you how good or bad it is. I'm currently generating verilog and testing it with cocotb because it is what i know and I dont have the time to port all the tests we have
<ydnatag[m]> All the io lib refactor added recently solves mostly all the issues i had
<ydnatag[m]> As i said some days ago, i had issues with amaranth and synplify pro using memory initialization, it would be great to have a verilog backend instead of using yosys but i can imagine how painful it is
<ydnatag[m]> I'm really happy with the language, I want to congratulate you for the work you did. Amaranth is a game changer for my daily work
<whitequark[cis]> thank you, this makes me really happy to hear
<whitequark[cis]> a lot of people seem to be using Amaranth without ever talking about it to me, which can be demotivating. ironically, if I wrote worse code I'd hear from more people, right
<whitequark[cis]> a better verilog backend of some sort is definitely on the roadmap, i was one of the early adopters and enthusiasts of yosys (and i still use it extensively) but while that decision has mostly paid off okay the project has matured enough that it really does need a verilog backend of its own
<ydnatag[m]> I'm spreading amaranth here in Argentina. I know at least 3 companies using it. And other 2 in Spain
<whitequark[cis]> very nice
<ydnatag[m]> So, i know it is being used in production, in really big projects
<whitequark[cis]> re: new simulator, if you like cocobt, I think you'll love it, because I've tried to take all the best parts of cocotb and then fix the footguns nobody seems to bother much about
<whitequark[cis]> e.g. things like "you are waiting on a clock in a testbench process simulating some module, and someone asserts a reset"
<ydnatag[m]> I know I should give it a try. But I also have the problem that I need to move all my code to use the new amaranth to do the migration and that would take time
<whitequark[cis]> if your code is currently warning-free, you should be able to upgrade 0.4 to 0.5 and have everything work
<whitequark[cis]> it will give deprecation warnings, but it should all execute and run
<ydnatag[m]> whitequark[cis]: Do you have an example of a complex simulation using it? I'm really interested on it and would love to use it, but i need to convince people to migrate to it
<whitequark[cis]> here is a test for the glasgow quad SPI controller: https://github.com/GlasgowEmbedded/glasgow/blob/main/software/tests/gateware/test_qspi.py
<whitequark[cis]> it includes a behavioral model of an SPI flash, in single/dual/quad modes
<whitequark[cis]> this test actually checks the entire chain, from the requester (testbench) through the QSPI controller and IO pads to the simulated flash and back
<whitequark[cis]> so it verifies that the DDR buffers used internally in the implementation work
<whitequark[cis]> the flash model itself is also not dependent on the controller clock, it runs off SCK and CS#
<whitequark[cis]> here's a similar test but for an SWD (the debug interface) controller: https://github.com/GlasgowEmbedded/glasgow/blob/main/software/tests/gateware/test_swd.py
<whitequark[cis]> so there's no yield stuff anymore like in the old simulator, you write behavioral Python code with async functions. everything's integrated with the Amaranth data model so you get actual structures and enums and such when you read values
<ydnatag[m]> Looks great. I'm really used to 'cocotb.fork' and 'cocotb.join'. Is there something similar? Because it helps me to divide the problem and solve interfaces independently (for example, do some axi transactions at the same time consume the data from a stream interface)
<whitequark[cis]> not yet, right now you add two testbenches instead
<whitequark[cis]> what we will probably add eventually is a way to spawn several async functions in parallel and wait for the result
<whitequark[cis]> so instead of fork/join you'd have await ctx.gather(reader, writer) and the two run concurrently
<ydnatag[m]> whitequark[cis]: Is that currently supported? I think it is exactly what i need for the 90% of the test cases i have
<whitequark[cis]> (the problem with plain fork is that it doesn't play well with scoping, and it's easy to get "runaway" tasks that don't terminate when they should...)
<whitequark[cis]> no, there is currently no ctx.gather API. it could be added relatively easily though
<whitequark[cis]> the underlying simulator engine doesn't care a lot if you add tasks at the start or later, it is just a question of designing a robust API
<ydnatag[m]> It would be great to solve that because that would allow to develop system and integration tests easily... at least for me that I've been using cocotb for a long tine
<whitequark[cis]> yeah I agree, in most of my complex designs I'm hitting the issue that I have to separate my "input" and "output" stream sequences into two pieces, and it's unnatural
zyp[m] has joined #amaranth-lang
<zyp[m]> that's what I was doing last time I voiced a need for this too
<whitequark[cis]> actually, to clarify, I think ctx.gather is still not good enough of an API and what would be ideal are Trio's "nurseries" or asyncio's "task groups" which are the same thing under a diff name
<zyp[m]> yeah, I was about to say, doing a context manager style task group might be a better approach
<whitequark[cis]> if you're up for it, i think an RFC for that would be great
<whitequark[cis]> btw, do you want to update #77 so it gets merged?
<zyp[m]> I know, I will
<zyp[m]> actually, I'll stop making excuses and do it now
<whitequark[cis]> (please feel free to open a tracking issue also)
<_whitenotifier-4> [amaranth] zyp opened issue #1615: Tracking issue for RFC 77: Stream port name conventions - https://github.com/amaranth-lang/amaranth/issues/1615
<whitequark[cis]> thanks!
<_whitenotifier-4> [rfcs] whitequark closed pull request #77: RFC #77: Stream port name conventions. - https://github.com/amaranth-lang/rfcs/pull/77
<_whitenotifier-4> [amaranth-lang/rfcs] whitequark pushed 3 commits to main [+2/-0/±1] https://github.com/amaranth-lang/rfcs/compare/ac8b977c3bda...89716e338b63
<_whitenotifier-4> [amaranth-lang/rfcs] zyp 5eaa985 - RFC #77: Stream port name conventions.
<_whitenotifier-4> [amaranth-lang/rfcs] zyp ebe1694 - RFC #77: Final touches.
<_whitenotifier-4> [amaranth-lang/rfcs] whitequark 89716e3 - RFC #77: Stream port name conventions
<_whitenotifier-4> [amaranth-lang/amaranth-lang.github.io] whitequark pushed 1 commit to main [+1/-0/±61] https://github.com/amaranth-lang/amaranth-lang.github.io/compare/9b9b0d62e959...c4254bb31c79
<_whitenotifier-4> [amaranth-lang/amaranth-lang.github.io] whitequark c4254bb - Deploying to main from @ amaranth-lang/rfcs@89716e338b636f01c664da2fb711c4f5d96d2bcc 🚀
<_whitenotifier-4> [amaranth] whitequark closed issue #1541: Simulation performance degradation on Amaranth 0.5.x - https://github.com/amaranth-lang/amaranth/issues/1541
<_whitenotifier-4> [amaranth] whitequark commented on issue #1541: Simulation performance degradation on Amaranth 0.5.x - https://github.com/amaranth-lang/amaranth/issues/1541#issuecomment-3063989354
<zyp[m]> Catherine: so one issue is that the natural way to handle exceptions in a task group is to use an `ExceptionGroup`, and that was added in python 3.11 (along with `asyncio.TaskGroup`)
<zyp[m]> and AIUI Amaranth policy is to support all currently supported python versions
<whitequark[cis]> we will not be using anything from asyncio
<whitequark[cis]> it would be a mechanism that you call via the simulator context, structured similarly to trio/asyncio
<whitequark[cis]> but using actual literal asyncio isn't something we can reasonably do, and we probably shouldn't even if we could
<zyp[m]> exception groups is a python feature, not part of asyncio
<whitequark[cis]> oh, sorry, i partially misread what you wrote
<zyp[m]> we won't be using anything from asyncio, but IME the TaskGroup semantics are pretty reasonable
<whitequark[cis]> the biggest issues with asyncio IME revolve around cancellation, which we... unfortunately do need
<whitequark[cis]> i think what we can do is to add nurseries, but leave exception semantics undefined
<whitequark[cis]> if you hit an unhandled exception it terminates the entire simulation, like right now
<whitequark[cis]> this leaves the path open for adding ExceptionGroup later while also freeing us from having to come up with and implementing cancellation semantics even to cover use cases where you might not even want to handle errors at all
<whitequark[cis]> if you really do need to handle an exception in a spawned task, yeah, you're in for some ugly code
<whitequark[cis]> but using the ExceptionGroup polyfill is ... not going to be much better. easily worse
<zyp[m]> true
<zyp[m]> I figure cancellation is useful to have in any case, e.g. for temporary monitor functions
<zyp[m]> e.g. a timeout monitor could be implemented like this: https://paste.jvnv.net/view/f3A5v
<whitequark[cis]> i don't think i will have the resources to investigate the correctness of a cancellation semantic, or the willingness to commit to a specific one
<whitequark[cis]> the two options i see for task spawning is "no cancellation but task spawning soon" vs "cancellation and task spawning in years"
<zyp[m]> hmm, can we have background tasks, that we simply drop when the group is done, analogous to background testbenches?
<zyp[m]> it's still a form of cancellation, but less complex when we don't tell it and let it act on it
<whitequark[cis]> yes that's reasonable (since there's no exception propagation, the task just disappears)
<zyp[m]> so a timeout monitor then becomes https://paste.jvnv.net/view/8OM2S
<whitequark[cis]> yep that works
<whitequark[cis]> this has the caveat that you cannot have an expected timeout
<whitequark[cis]> well, not implementing it the naive way
<zyp[m]> how do you feel about ctx.group() and group.start()?
<whitequark[cis]> no real preference at the time, these names work for a start
<whitequark[cis]> it's possible other names would work better but we can hash that out once we have the RFC and prototype
<zyp[m]> yeah, the usual bikeshedding