<_whitenotifier-1>
[amaranth-lang/amaranth-lang.github.io] whitequark 0112e55 - Deploying to main from @ amaranth-lang/amaranth@ba6a7495a6f0dad3db909fde8035170a859a5df4 🚀
<_whitenotifier-1>
[amaranth-lang/amaranth-lang.github.io] whitequark c7ac112 - Deploying to main from @ amaranth-lang/playground@6a35d492b33da56d56e3e7b71fe596b79fc84011 🚀
buganini has joined #amaranth-lang
buganini has quit [Ping timeout: 252 seconds]
<maikmerten[m]>
hmm... looking for RV32 CPUs that seem to work alright with modern Amaranth, https://github.com/minerva-cpu/minerva looks pretty nice (and generates neatly to Verilog)
<whitequark[cis]>
Minerva is a project jfng worked on in their spare time, so it doesn't always get updated promptly to latest Amaranth
<maikmerten[m]>
(I've known about Amaranth since about 3 days ago, but I think I learned that Record was some tech-debt since deprecated, removed and fired into the sun)
<jfng[m]>
yeah, it's not quite up to date
<galibert[m]>
I think sentinel is up-to-main
<jfng[m]>
minerva's WB arbiter is quite inefficient resource-wise, it exists because it uses a fixed priority policy
<maikmerten[m]>
yeah, also stumbled across sentinel. starring on GitHub
<jfng[m]>
maikmerten[m]: minerva was mostly in the very early days of amaranth, i wouldn't consider it an example of idiomatic amaranth
<maikmerten[m]>
(I'm basically looking for some up-to-date compact RV32 core. I have long-term maleficent plans of having a bare-bones RV32-core do... RV32 emulation, with hardware-assist)
<maikmerten[m]>
jfng[m]: ah, good to know!
<whitequark[cis]>
it's likely possible to upgrade minerva piece-by-piece to amaranth 0.6
<jfng[m]>
i just need 1-2 days and the energy to do it, i think
<maikmerten[m]>
basically, I'm working on a RV32-IM-Zcsr emulator, where parts of what's slow in software can be delegated to specialized memory-mapped devices on FPGA platforms, most importantly the register-file and decoder. It currently works, e.g., on the Cortex-M0+-cores of the RP2040 (achieving ~1600 Dhrystone/s executing RV32-IM), but that's of course all software. Does it make any sense? No. Does it help me getting a better grasp on
<maikmerten[m]>
RISC-V? Yes.
<maikmerten[m]>
(it's currently somewhat cursed C code, need to clean that up a bit and GitHub it)
<whitequark[cis]>
ah interesting!
buganini has joined #amaranth-lang
<maikmerten[m]>
"turn your 133 MHz ARMv6-M core into ca. 12 MHz Motorola 68000 performance-wise"
<maikmerten[m]>
interestingly clock-for-clock, my Zen2 Ryzen isn't really faster executing my emulator (ca. 1600 Dhrystone/s on the 133 MHz Cortex-M0+ vs. ca. 46000 Dhrystone on my ca. 4 GHz Ryzen 4650g). I blame the branchiness of the code (Cortex-M0+ has two pipeline stages, Zen2 ca. 19 stages).
<maikmerten[m]>
however, what's really eating into performance is the decoding step, e.g., assembling the immediate value - and that's easily fixed on FPGA platforms with a very compact peripheral
<maikmerten[m]>
(but I need to make sure I'm not derailing this channel into off-topicness, sorry)
<_whitenotifier-1>
[amaranth] github-merge-queue[bot] created branch gh-readonly-queue/main/pr-1505-0f274291e7e3909a2e3f3783fdecd2c5fd565841 - https://github.com/amaranth-lang/amaranth
<maikmerten[m]>
perhaps more on-topic, trying to understand the project structure: amaranth-soc tries to assemble a collection of SoC-glue like busses, while amaranth-stdio tries to assemble components for I/O-device-cores (sans bus) like UARTs, SPI, I2C etc.?
<_whitenotifier-1>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] c1eb0e5 - Deploying to main from @ amaranth-lang/amaranth@f20f04277225fe714054472e3d6daf930a9b12ef 🚀
<whitequark[cis]>
maikmerten[m]: yes
<maikmerten[m]>
where would, e.g., timers land?
<maikmerten[m]>
(well, that's not quite I/O, so I guess SoC)
lf[m] has joined #amaranth-lang
<lf[m]>
Sry I am curious. So a softcore in the FPGA with some periphery to decode an instruction? Or MCU+FPGA? If softcore: custom instruction for decode. Or some register? Maybe with a bus master to directly fetch the next instruction?
<maikmerten[m]>
I'm thinking of a very simple RV32-I core (without CSRs, interrupts, traps etc.) that is solely responsible to execute one particularly crafted program (the emulator). Some things that are nasty to do in software but that need to be done for the emulator are delegated to specialized peripherals. E.g., there would be a memory mapped peripheral where 32-bit instruction words are written to and the decoded results (immediates,
<maikmerten[m]>
register values, opcode, func3/func7 fields etc.) are available to read directly from.
<maikmerten[m]>
so it would be a specialized SoC that at first would only be a CPU core, some serial I/O and memory and where stepwise "accelerators" are attached to
<maikmerten[m]>
(on microcontrollers such as the RP2040 or my Linux-PC, the "accelerators" are of course pure software)
<lf[m]>
Sounds like a fun project
<maikmerten[m]>
yeah, so I hope :-)
<jfng[m]>
<maikmerten[m]> "where would, e.g., timers land?" <- timers would belong to amaranth-soc
<jfng[m]>
we split peripherals in two parts, a low-level part that interfaces to I/O pads would go to amaranth-stdio, while the upper half that interfaces with eg. AXI or APB goes to amaranth-soc
<jfng[m]>
an UART would therefore have two parts, one in -soc and another in -stdio
<whitequark[cis]>
you can also add a dependency on amaranth-yosys in your pyproject.toml
<whitequark[cis]>
then you don't need to mess with system yosys (only works on x86_64 and amd64)
<maikmerten[m]>
yeah (the help message also mentions this), but I occasionally manually invoke yosys, so I usually end up having it installed anyways
zyp[m] has joined #amaranth-lang
<zyp[m]>
do we currently have anywhere we can hook the checks wiring.connect() does and add additional, to add stricter checks for port members than just matching width?
<whitequark[cis]>
nope, that would need an RFC and some discussion
<whitequark[cis]>
I've been expecting us to need it though
<zyp[m]>
yes, this is related to the stream transformers we've talked about before
<whitequark[cis]>
one issue is that connect isn't directional and not even 1:1 (ie you can give 3 or 4 inputs to it)
<whitequark[cis]>
so some non-directional way of applying the checks would need to be made
<whitequark[cis]>
for example, each interface member is checked against each other interface member, or something like that
<zyp[m]>
the straightforward usecase is packetized streams, i.e. streams with a payload consisting of functionally a struct with a nested payload and first and/or last flags
<zyp[m]>
and I want to disallow connecting a stream outputting a first flag to a stream expecting a last flag, which seems like an easy mistake to do since they've got the same width
<whitequark[cis]>
yep
<zyp[m]>
I'm considering just sticking with first and last as separate port members until we have stream transformers
<whitequark[cis]>
you can't do that
<whitequark[cis]>
or at least, do that and be compatible with amaranth.lib.stream
<whitequark[cis]>
of course you can build your own stream library and do that there
<zyp[m]>
this was written before amaranth.lib.stream
<Wanda[cis]>
hm
<Wanda[cis]>
I should get high and write a RISC-V core
<whitequark[cis]>
heh
<maikmerten[m]>
<Wanda[cis]> "I should get high and write a..." <- I have a wonderfully cursed state-machine to share with you ;-) https://postimg.cc/dDWtChy6
phire has quit [Read error: Connection reset by peer]
phire has joined #amaranth-lang
buganini has quit [Ping timeout: 260 seconds]
<whitequark[cis]>
zyp: would you like to revisit RFC 66 implementation?
<_whitenotifier-1>
[amaranth-lang/amaranth-lang.github.io] whitequark 96b70b5 - Deploying to main from @ amaranth-lang/rfcs@4352e0d663e39ed308fe3aead85867425f137161 🚀
<zyp[m]>
yeah, it's on my todo list, just need to find time
<zyp[m]>
I got another kid recently, so my days have been quite full
<_whitenotifier-1>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] 67c0cb4 - Deploying to main from @ amaranth-lang/amaranth-soc@6cd3e1c01764abe1bab1623aab70e3eaf70a0f7e 🚀
frgo has quit [Read error: Connection reset by peer]
buganini has quit [Ping timeout: 265 seconds]
<zyp[m]>
Catherine: I have some questions on #1497; when you know the «owner» of a signal, is the goal to check that it's used inside the owner, outside the owner or both?
<whitequark[cis]>
for inputs, sampled inside and updated outside; for outputs, vice versa
<zyp[m]>
makes sense
<zyp[m]>
I disagree with «… and these patterns should not be considered a "use" for either signal.», since that pattern might very well be the only use of the input signal of the two
<zyp[m]>
but I agree it should not count as a use of the output signal
<whitequark[cis]>
oh, yeah, that's not very clearly expressed
<zyp[m]>
how do we explicitly ignore a input signal that must be used? i.e. the equivalent of (void)some_unused_variable; in C
<whitequark[cis]>
I edited it since my original intent for that phrase doesn't make the text as a whole any clearer and what you said is more appropriate
<whitequark[cis]>
re explicitly ignore: Signal().eq(unused) maybe
<whitequark[cis]>
s//`m.d.comb += /, s//`/
<zyp[m]>
what can be the owner of a signal? any elaboratable, given the no private API requirement? is the relationship between elaboratables and the Module instances returned by elaborate() already tracked?
<zyp[m]>
I assume the Module can't be the owner, since the signals are usually created earlier
<whitequark[cis]>
any elaboratable, and we have Fragment.origins
<zyp[m]>
and I assume submodules will be treated the same as any external modules
<zyp[m]>
in which case there's a potential pitfall if somebody tries passing a whole interface to a submodule as an argument instead of using connect()
<whitequark[cis]>
there is, yeah
<zyp[m]>
potentially dumb question: is there really value in tracking signal ownership, when we could instead just check that the signal is read in a different fragment than it's driven from?
<whitequark[cis]>
they could both be outside
<whitequark[cis]>
(or both inside, even)
<zyp[m]>
they can't both be inside if they must be different
buganini has joined #amaranth-lang
<whitequark[cis]>
this depends on your definition of "inside"
<whitequark[cis]>
"this specific elaboratable" vs "elaboratable hierarchically within"
<whitequark[cis]>
(you could argue for either of the designs)
<zyp[m]>
but yeah, tracking ownership means that we can also validate that a component doesn't drive any input ports, so that seems a valuable mechanism to have in any case
<zyp[m]>
(and correspondingly that output ports aren't driven from the outside)
buganini has quit [Ping timeout: 260 seconds]
buganini has joined #amaranth-lang
buganini has quit [Ping timeout: 252 seconds]
frgo has joined #amaranth-lang
frgo_ has quit [Read error: Connection reset by peer]
vup has quit [Remote host closed the connection]
whitequark[cis] has quit [Ping timeout: 245 seconds]
whitequark[cis] has joined #amaranth-lang
vup has joined #amaranth-lang
buganini has joined #amaranth-lang
buganini has quit [Ping timeout: 246 seconds]
buganini has joined #amaranth-lang
buganini has quit [Ping timeout: 248 seconds]
buganini has joined #amaranth-lang
buganini has quit [Ping timeout: 245 seconds]
cr1901 has quit [Read error: Connection reset by peer]