whitequark changed the topic of #amaranth-lang to: Amaranth hardware definition language · weekly meetings on Mondays at 1700 UTC · code https://github.com/amaranth-lang · logs https://libera.irclog.whitequark.org/amaranth-lang
<josuah> from first looking at it, Amaranth did look complicated to me
<josuah> I had a bit of trouble to understand where the execution starts
<josuah> this shows how much verilog biased me toward thinking HDLs write programs
<josuah> I was wondering why += was everywhere instead of having a more conventional approach like verilog using '=' assignments
<josuah> but for a program that generates RTL, the real operation going on si really += which aggregates multiple unrelated logic circuit into a big array
<josuah> a big array that is going to be placed and mapped to blocks on a silicon die or FPGA fabric
<josuah> what a plot twist! even though I was well aware of Verilog's biased approach, I was still much under its bias
<josuah> and then looking at amaranth code suddenly made sense!
<josuah> feeling like a much thinner abstraction over HDL than Verilog-like languages
<josuah> s/HDL/RTL/
lf has quit [Ping timeout: 246 seconds]
lf has joined #amaranth-lang
<_whitenotifier-9> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/yosys/compare/f395f1b4f277...a68f7a8d3803
<_whitenotifier-9> [YoWASP/yosys] whitequark a68f7a8 - Update dependencies.
<d1b2> <OmniTechnoMancer> The += is more a consequence of how clock domains are dealt with
bl0x has joined #amaranth-lang
bl0x_ has quit [Ping timeout: 248 seconds]
cr1901_ has joined #amaranth-lang
cr1901 has quit [Ping timeout: 248 seconds]
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 255 seconds]
Degi_ is now known as Degi
bl0x has quit [Ping timeout: 255 seconds]
bl0x_ has joined #amaranth-lang
<whitequark> josuah: yeah. that's something I'm explaining in the language guide, have you seen it?
<d1b2> <Darius> I would be interested in reading that..
<d1b2> <Darius> thanks!
bl0x_ has quit [Ping timeout: 252 seconds]
bl0x has joined #amaranth-lang
<d1b2> <Olivier Galibert> Is there a way to know if sync has an enable inserted of it, and if yes get the base clock domain and the enable separately? The issue is how to generate 1-tick wide strobes in the StrobeGenerator even if the clock domain is gated, for instance if you cascade generators
<josuah> whitequark: the language guide was a good part of that cluestick
<whitequark> ah good
<whitequark> Olivier: there's an issue for EnableSignal() https://github.com/amaranth-lang/amaranth/issues/285
<whitequark> but I think you probably should let gating be
<whitequark> there's a chapter in the manual waiting to be written on this...
<d1b2> <Olivier Galibert> that means you can't cascade generators though. Not 100% it would be useful tbh
<d1b2> <Olivier Galibert> It's irrelevant for my case but you may be interested to know that a cyclonev has roughly a hundred clock enables/gates, one for each clock dispatch network. At they point they seem to have decided it was important
<d1b2> <Olivier Galibert> But yeah, there's some conceptual issue in there that are not entirely clear. An "enable" signal for me is a series of 1-clock-wide pulses that decide which edges of a global fast clock you actually want to do stuff on. Which is very nice because CDC is annoying. And amaranth rules because with EnableInserter it allows to do that transparently code-wise for a clock domain and have a module work on a reduced clock without
<d1b2> changing the code. It just breaks down if, among other things, the module generates a new enable signal (it could be generate vsync from hsync for instance) because the enable width is going to be one reduced-clock tick long, which is more than one. There somehow somewhere needs to be a way to generate a pulse train that's actually pulses, bonus point if you can do it transparently without code change with and without a reduced clock
<d1b2> <Olivier Galibert> It's a little different than the instance issue, but turns around the same "enables are different"
<d1b2> <Olivier Galibert> I'll do an issue for future reference
<_whitenotifier-9> [amaranth] galibert opened issue #749: Request: Reliable and standard methodology for generating enable signals - https://github.com/amaranth-lang/amaranth/issues/749
<whitequark> thanks!
<d1b2> <Olivier Galibert> 'welcome 🙂
<d1b2> <Olivier Galibert> not sure what the answer should be, but heh
<d1b2> <Olivier Galibert> Still learning my way around the language, but I keep liking it, at least we have some of the advances in software languages coming to hardware
<d1b2> <Olivier Galibert> Abstraction is good damnit 🙂
<whitequark> it is handy
<d1b2> <Olivier Galibert> I have a neboulous feeling that amaranth should know/accept that some clock domains can be compatible, e.g. their phase will always be correct one w.r.t another so that there's no metastability risk. Clock vs. clock + enable, perhaps edges of a clock, perhaps multiple output of one pll with correct divider/phase parameters. And if it's the case, allow writing to the same register on those different domains. But I'm not sure
<d1b2> whether it actually makes sense hardware-wise, not entirely convinced
dave_ has joined #amaranth-lang
<whitequark> you're basically suggesting that Amaranth should replicate a part of the P&R tool timing engine
<d1b2> <Olivier Galibert> Hmmmmm... no?
<d1b2> <Olivier Galibert> Just a way for the module to explicitely say "those two clock signals are compatible". Why is not amaranth's problem, and if you lie you get to keep all 256 pieces
<d1b2> <Olivier Galibert> And that EnableInserter generates a compatible domain, obviously
<d1b2> <Olivier Galibert> But I'm not sure if would work out nicely at the P&R level afterwards, so I'm really not sure
daveberkeley has joined #amaranth-lang
daveberkeley has quit [Client Quit]
daveberkeley has joined #amaranth-lang
dave_ has quit [Quit: Leaving]
<d1b2> <Olivier Galibert> not even sure it would be that useful, except when trying to directly convert schematics using multiple-phase clocks (the via6522 has three phases for instance)
<d1b2> <Olivier Galibert> they sometimes do a thing like "bring the line to 1 on one phase, then optionally bring it down on the next one". Precharge-based pull-up simulation
<d1b2> <Olivier Galibert> but amaranth has no reason to be a language to transcribe nmos/latch schematics
<whitequark> EnableInserter doesn't actually create a new domain
<d1b2> <Olivier Galibert> Ah, interesting
<d1b2> <Olivier Galibert> But that's an implementation detail, right? Semantically, it does?
<whitequark> no I wouldn't say so
<whitequark> well, it depends on what you mean by "new domain"
<whitequark> that's... another manual chapter waiting to be written
<d1b2> <Olivier Galibert> huhuhu
<d1b2> <Olivier Galibert> I'm not entirely sure what I mean either
<adamgreig[m]> There's a lot of use cases for enableinserter which aren't around making a new slow clock by gating only some edges, which look less like making a new clock domain I guess
<whitequark> ^ yes
daveberkeley has quit [Quit: Client closed]
<d1b2> <Olivier Galibert> if you have one clock domain with say a 2Mhz clock, then do two opposite pulse trains to split even/odd clocks into two EnableInserter-ed domains pclk and nclk, can you write to the same register from both in a submodule?
<d1b2> <Olivier Galibert> For me a clock domain is something that decides when things actually happen in a m.d.mumble, and with the property that writes to a signal cannot be done some different domains (which is what characterizes them as different too)
<d1b2> <Olivier Galibert> but I so may be missing stuff there 🙂
<whitequark> arguably, a clock domain is something that requires CDC between it and other clock domains
<whitequark> this is not the only possible definition, of course
<whitequark> there is the concept of "control set", which unambiguously maps to what you are talking about
<whitequark> i.e. same clock/reset/enable
<d1b2> <Olivier Galibert> Yeah, while we know there are domains as in m.d that may not need a CDC
<d1b2> <Olivier Galibert> that essentially what I meant by "compatible"
<d1b2> <Olivier Galibert> honestly, not sure it's worth it as a concept though
<whitequark> "control set" is an existing concept used by tools in this space
<whitequark> so what EnableInserter() does is it rebinds the implicit control set
<whitequark> instead of `old_enable`, it turns that into `old_enable&new_enable`
<whitequark> and ResetInserter() turns old_reset (which by default is cd.rst) into old_reset|new_reset
<d1b2> <Olivier Galibert> makes sense
<d1b2> <Olivier Galibert> control set = clock + enable + reset then?
<d1b2> <Olivier Galibert> more like tuple, but heh
<_whitenotifier-9> [amaranth] VioletEternity opened issue #750: Installation instructions suggest deprecated pip commands that will stop working after pip 25.0 - https://github.com/amaranth-lang/amaranth/issues/750
sauce has quit [Quit: sauce]
<_whitenotifier-9> [runtime] whitequark opened issue #1: /tmp needs to be mounted by the runtime itself - https://github.com/YoWASP/runtime/issues/1
sauce has joined #amaranth-lang
ydnatag has quit [Quit: Connection closed for inactivity]
bl0x has quit [Ping timeout: 246 seconds]
bl0x has joined #amaranth-lang
cr1901_ is now known as cr1901
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/runtime/compare/d1dc4248fd9d...e3b34ea1eb5b
<_whitenotifier-9> [YoWASP/runtime] whitequark e3b34ea - Document the YOWASP_CACHE_DIR environment variable.
<_whitenotifier-9> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/yosys/compare/a68f7a8d3803...b9bb59f502a1
<_whitenotifier-9> [YoWASP/yosys] whitequark b9bb59f - Add reference to yowasp-runtime documentation.
<_whitenotifier-9> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/yosys/compare/b9bb59f502a1...70d1eecb6bb5
<_whitenotifier-9> [YoWASP/yosys] whitequark 70d1eec - Add reference to yowasp-runtime documentation.
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/runtime/compare/e3b34ea1eb5b...91217098e47e
<_whitenotifier-9> [YoWASP/runtime] whitequark 9121709 - Fix default cache directory on Windows in documentation.
bl0x has quit [Ping timeout: 255 seconds]
bl0x has joined #amaranth-lang
bl0x_ has joined #amaranth-lang
bl0x has quit [Ping timeout: 255 seconds]
<vup> tannewt: your design reminds me of how anuejn and I were generating python "driver" code for our soc-like infrastructure: https://github.com/apertus-open-source-cinema/naps/blob/43ae6c110c5d9f969ca9f9794cabb68218a32805/naps/cores/cmv12k/s7_phy.py#L74
<vup> Definitely a lot of fun to work with.
<vup> In the end this build a .zip containing the bitstream and all the python driver code, and running the zip with python programs the bitstream throws you into a repl that allows you to interact with the design hierarchy, read / write all your registers and call your driver scripts.
<tannewt> nice! let me look
<whitequark> we should have that upstream in -soc
<whitequark> for sure
<whitequark> so with a JTAG to AXI/Wishbone
<tannewt> vup, you have to call `handle_read` and `handle_write` correct? I was using data descriptiors to use `__get__` and `__set__`
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 1 commit to develop [+12/-5/±4] https://github.com/YoWASP/runtime/compare/91217098e47e...aa13f8b4bc2c
<_whitenotifier-9> [YoWASP/runtime] whitequark aa13f8b - [autorelease] Add YOWASP_MOUNT configuration environment variable.
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 3 commits to release [+12/-5/±6] https://github.com/YoWASP/runtime/compare/d1dc4248fd9d...aa13f8b4bc2c
<_whitenotifier-9> [YoWASP/runtime] whitequark e3b34ea - Document the YOWASP_CACHE_DIR environment variable.
<_whitenotifier-9> [YoWASP/runtime] whitequark 9121709 - Fix default cache directory on Windows in documentation.
<_whitenotifier-9> [YoWASP/runtime] whitequark aa13f8b - [autorelease] Add YOWASP_MOUNT configuration environment variable.
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 1 commit to develop [+3/-0/±2] https://github.com/YoWASP/runtime/compare/aa13f8b4bc2c...dff2930d209c
<_whitenotifier-9> [YoWASP/runtime] whitequark dff2930 - [autorelease] Mount /tmp to a fresh temporary directory.
<_whitenotifier-9> [runtime] whitequark closed issue #1: /tmp needs to be mounted by the runtime itself - https://github.com/YoWASP/runtime/issues/1
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/runtime/compare/dff2930d209c...21779e8e0370
<_whitenotifier-9> [YoWASP/runtime] whitequark 21779e8 - [autorelease] Fix release job.
<_whitenotifier-9> [YoWASP/runtime] whitequark pushed 2 commits to release [+3/-0/±3] https://github.com/YoWASP/runtime/compare/aa13f8b4bc2c...21779e8e0370
<_whitenotifier-9> [YoWASP/runtime] whitequark dff2930 - [autorelease] Mount /tmp to a fresh temporary directory.
<_whitenotifier-9> [YoWASP/runtime] whitequark 21779e8 - [autorelease] Fix release job.
<_whitenotifier-9> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1] https://github.com/YoWASP/yosys/compare/70d1eecb6bb5...3013c8ec0701
<_whitenotifier-9> [YoWASP/yosys] whitequark 3013c8e - Require yowasp-runtime~=1.12.
<_whitenotifier-9> [amaranth-lang/amaranth] whitequark pushed 1 commit to main [+0/-0/±1] https://github.com/amaranth-lang/amaranth/compare/7e3e10e73336...ca77de5ed3ae
<_whitenotifier-9> [amaranth-lang/amaranth] whitequark ca77de5 - docs/install: update deprecated pip syntax.
<_whitenotifier-9> [amaranth] whitequark closed issue #750: Installation instructions suggest deprecated pip commands that will stop working after pip 25.0 - https://github.com/amaranth-lang/amaranth/issues/750
<_whitenotifier-9> [amaranth-lang/amaranth-lang.github.io] whitequark pushed 1 commit to main [+0/-0/±29] https://github.com/amaranth-lang/amaranth-lang.github.io/compare/3fafc7a662f5...77d63636db10
<_whitenotifier-9> [amaranth-lang/amaranth-lang.github.io] whitequark 77d6363 - Deploying to main from @ amaranth-lang/amaranth@ca77de5ed3ae19ef241f07bc56765f414db4d968 🚀
<_whitenotifier-9> [amaranth] whitequark commented on issue #745: WARNING: Generating metadata for package amaranth produced metadata for project name unknown. Fix your #egg=amaranth fragments. - https://github.com/amaranth-lang/amaranth/issues/745#issuecomment-1433705940
<_whitenotifier-9> [amaranth] whitequark commented on issue #711: _convert_fragment() has polynomial time complexity as signals are added to design - https://github.com/amaranth-lang/amaranth/issues/711#issuecomment-1433709343
<vup> (This is called platform in our code). When a design is elaborated, anything that is a subclass of Peripheral (https://github.com/apertus-open-source-cinema/naps/blob/main/naps/soc/peripheral.py) is collected and given to this bus implementation, which then generates the gateware that routes reads and writes from a bus-specific bus master to the peripherals based on their address. The logic for reads and writes of a Peripheral are determined by the
<vup> The way it works is, that the board you are using provides a "Bus" implementation.
<vup> tannewt: its actually a lot more involved, handle_read and handle_write are parts of our (handrolled) bus agnostic "register" abstraction.
<vup> Peripheral itself and the bus implementation inserts the peripheral specific implementation by inserting the handle_read and handle_write calls gated by the address that is read / written to the gateware. This makes it possible to implement some useful custom logic, like PulseReg, which is a Peripheral, that when written to generats a exactly one clock cycle long pulse.
<vup> Each bus implementation is paired with a MemoryAccessor, which is responsible for actually accessing the physical FPGA. This could for example be using JTAG or on the Zynq, the "Bus" connects to one of the AXI master ports of the ARM cpu and the MemoryAccessor mmap's the corrects region of /dev/mem. (https://github.com/apertus-open-source-cinema/naps/blob/main/naps/soc/platform/jtag/memory_accessor_openocd.py)
<vup> Finally this MemoryAccessor is then used with a generated python object hierarchy, that just mirrors the amaranth design hierarchy of modules and submodules with properties added for each Peripheral that was part of the original design hierarchy added to the generated object, that when accessed or is written to reads / writes to the correct address using the MemoryAccessor.
<_whitenotifier-9> [amaranth] whitequark commented on issue #711: _convert_fragment() has polynomial time complexity as signals are added to design - https://github.com/amaranth-lang/amaranth/issues/711#issuecomment-1433730112
<tannewt> vup: that sounds awesome! I think I managed to do it without needing a separate heirarchy
<tannewt> the peripherals are passed the abstract "address range" on construction and its used by the data descriptors when read and written
<tannewt> I think I did have to special case for the generation though because registration happens on __get__
<tannewt> I *love* the abstract bus
<tannewt> I've wanted to port circuitpython to the zynq to be able to connect to fpga peripherals too
<whitequark> oh right I promised that I'd upload the Interfaces RFC draft
<_whitenotifier-9> [rfcs] whitequark created branch interfaces - https://github.com/amaranth-lang/rfcs
<_whitenotifier-9> [amaranth-lang/rfcs] whitequark pushed 1 commit to interfaces [+1/-0/±0] https://github.com/amaranth-lang/rfcs/commit/68d10d5b1ac7
<_whitenotifier-9> [amaranth-lang/rfcs] whitequark 68d10d5 - RFC: Interface definition library.
<_whitenotifier-9> [rfcs] whitequark opened pull request #2: RFC: Interface definition library - https://github.com/amaranth-lang/rfcs/pull/2
<_whitenotifier-9> [rfcs] whitequark edited pull request #2: Interface definition library - https://github.com/amaranth-lang/rfcs/pull/2
<_whitenotifier-9> [rfcs] whitequark edited pull request #2: Interface definition library - https://github.com/amaranth-lang/rfcs/pull/2
<whitequark> nelgau: published
<_whitenotifier-9> [amaranth-lang/amaranth] whitequark deleted branch issue-732
<_whitenotifier-9> [amaranth] whitequark deleted branch issue-732 - https://github.com/amaranth-lang/amaranth
<_whitenotifier-9> [amaranth] miek commented on issue #745: WARNING: Generating metadata for package amaranth produced metadata for project name unknown. Fix your #egg=amaranth fragments. - https://github.com/amaranth-lang/amaranth/issues/745#issuecomment-1433772421
<_whitenotifier-9> [amaranth] whitequark commented on issue #745: WARNING: Generating metadata for package amaranth produced metadata for project name unknown. Fix your #egg=amaranth fragments. - https://github.com/amaranth-lang/amaranth/issues/745#issuecomment-1433773405
<_whitenotifier-9> [amaranth-lang/amaranth] whitequark pushed 1 commit to main [+0/-0/±1] https://github.com/amaranth-lang/amaranth/compare/ca77de5ed3ae...12a81f24bd7b
<_whitenotifier-9> [amaranth-lang/amaranth] whitequark 12a81f2 - docs/install: pip>=23.0 is required.
<_whitenotifier-9> [amaranth] whitequark closed issue #745: WARNING: Generating metadata for package amaranth produced metadata for project name unknown. Fix your #egg=amaranth fragments. - https://github.com/amaranth-lang/amaranth/issues/745
<_whitenotifier-9> [amaranth-lang/amaranth-lang.github.io] whitequark pushed 1 commit to main [+0/-0/±29] https://github.com/amaranth-lang/amaranth-lang.github.io/compare/77d63636db10...04193a9b2370
<_whitenotifier-9> [amaranth-lang/amaranth-lang.github.io] whitequark 04193a9 - Deploying to main from @ amaranth-lang/amaranth@12a81f24bd7b435d2089cd522aece4c1c9733dbd 🚀
<_whitenotifier-9> [amaranth] whitequark commented on issue #682: Using Enum as FSM state does not respect the Enum value - https://github.com/amaranth-lang/amaranth/issues/682#issuecomment-1433789190
<_whitenotifier-9> [amaranth] whitequark commented on issue #692: Remove the Migen compatibility layer - https://github.com/amaranth-lang/amaranth/issues/692#issuecomment-1433791116
bl0x_ has quit [Ping timeout: 248 seconds]
bl0x has joined #amaranth-lang
TD--Linux is now known as TD-Linux