<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] c929f2a - Deploying to main from @ amaranth-lang/amaranth@1b74c2904c246e52586dbb2f081af7ceb4257ffc 🚀
<iposthuman[m]>
Thanks @Catherine for the review, I'll rework the code accordingly.
nyanotech has quit [Remote host closed the connection]
nyanotech has joined #amaranth-lang
toshywoshy has quit [Ping timeout: 256 seconds]
toshywoshy has joined #amaranth-lang
toshywoshy has quit [Read error: Connection reset by peer]
toshywoshy has joined #amaranth-lang
richardeoin has quit [Quit: WeeChat 2.8]
richardeoin has joined #amaranth-lang
frgo has quit [Quit: Leaving...]
FFY00 has quit [Read error: Connection reset by peer]
<jfng[m]>
<whitequark[cis]> "however I think jfng intended to..." <- actually, it seems that i don't have the rights to label PRs in amaranth-lang/rfcs
<jfng[m]>
good evening! it is time for our weekly SoC meeting
<galibert[m]>
good evening
<jfng[m]>
i'm currently working on updating the component metadata API and SoC metadata prototypes with tests/docstrings so they can be proper PRs
<jfng[m]>
i've also updated RFC #30 with monday's feedback, though we will review it next monday
<galibert[m]>
That reminds me I wanted to look at it
smkz has quit [Quit: smkz]
<galibert[m]>
Urrrrrrrrrrrgh
<galibert[m]>
Sorry
<galibert[m]>
I'll guess we'll discuss it monday then
<galibert[m]>
Hope I'll be home early enough
<jfng[m]>
sure, feel free to give feedback either here or on github once you find some time; we don't restrict discussions about PRs/RFCs to meetings
<jfng[m]>
i believe that an implementation of this RFC, with some "real world" amaranth-soc examples will make it easier to grasp
<galibert[m]>
I'm sorry, my initial reaction is to hate it for a bunch of reasons, but that's not constructive
Wanda[cis] has joined #amaranth-lang
<Wanda[cis]>
huh, aren't the meetings supposed to be an hour earlier?
<jfng[m]>
oh, uh yes you're right
<galibert[m]>
Well, I can witness that a meeting did not take place an hour ago :-)
<jfng[m]>
i haven't adjusted my alarm from CEST to CET vs UTC...
<galibert[m]>
Anyway, some of my issues, in no particular order:
<galibert[m]>
as_json calls validate, validate requires an internet access, I don't always have a reliable internet access handy. I don't want to be blocked from using -soc just because I'm on a plane
<jfng[m]>
validate does not require an internet access
<galibert[m]>
or because my employer thinks amaranth-lang is a gaming site
<jfng[m]>
it verifies that the JSON object given as its parameter complies with the schema defined in the `.schema` attribute of an Annotation subclass
<Wanda[cis]>
galibert: those are opaque URLs used as identifiers, they're not actually *accessed* at any point
<jfng[m]>
the schema URL in allows *external tools* to validate annotations
<galibert[m]>
Ah, so you duplicate information and has no way to know it the contents of the file at the url (if it exists) and the .schema contents are identical
<galibert[m]>
s/has/have/
<jfng[m]>
well, the RFC does not specify how we provide the schema that is hosted at an URL
<jfng[m]>
also, we can't guarantee that the URL points to a domain that actually exists
<jfng[m]>
but if there is a mismatch between the schema and an instance, validation will most likely fail noisily
<galibert[m]>
Next step of fun: there is, afaict, no way to enumerate all the Elaboratable of a given system, and no RFC about adding that either. So there's no official way to get at the metadata information for anything other than the top level elaboratable, at best
<jfng[m]>
this is intentional
<galibert[m]>
Color me flabbergasted
<jfng[m]>
we are only concerned about the interface of a single, top-level, component, not the entire design
<jfng[m]>
for this RFC, the top-level is a blackbox, it is not concerned about its contents
smkz has joined #amaranth-lang
<galibert[m]>
Ok, I don't get it. This rfc is about adding information that is not reachable? I'm missing something there
<jfng[m]>
this RFC is about communicating metadata about a single component using JSON, specifically, its interface and arbitrary information about its behavior, as annotations
<galibert[m]>
communicating to what?
<jfng[m]>
to other tools, or HDLs
<jfng[m]>
for example, you want to know the memory map of a peripheral in order to generate headers for firmware; you want to know the interface of a component to instantiate it in a mixed HDL design, etc
<jfng[m]>
the "motivation" goes over this
<jfng[m]>
section*
<galibert[m]>
But how do you reach the Decoder on the bus of the peripheral without very intimate knowledge of how the peripheral is structured and hope that the adds to the Decoder are not done in the elaborate?
<galibert[m]>
Decoder with has the memory map that is
<jfng[m]>
consider a SoC implemented in say, verilog
<galibert[m]>
Hmmm, if I use amaranth is because I really don't like verilog and avoid it as much as possible, but go on
<jfng[m]>
it has its own build system to generate BSP (C headers, etc etc)
<jfng[m]>
and you want to integrate a peripheral implemented in Amaranth
<jfng[m]>
it's not just about you, this is a likely use case for e.g. companies that want to try out amaranth in their designs
<jfng[m]>
if the requirement is "rewrite everything in Amaranth from scratch", this becomes a hard sell..
<galibert[m]>
I understand what you just said as "if you don't do mixed designs, you have no use for that"
<galibert[m]>
Which I don't think is what you aimed for
<jfng[m]>
mixed HDL is just one use-case
<jfng[m]>
block diagram-based design tools are another
<jfng[m]>
if you know the interface of your components, you can integrate them using a GUI
<galibert[m]>
So your use cases boil down to "single component in amaranth which is going to be used outside of amaranth and is thus at top level". You generate verilog and interface with it and you're done?
<galibert[m]>
I indeed personally have no use for that
<galibert[m]>
(or rtiil instead of amaranth :-) )
<jfng[m]>
component metadata can be very useful, even in a pure Amaranth design
<jfng[m]>
consider, a SoC again, you may use annotations to communicate the memory map, configuration constants (e.g. FIFO depths), safety invariants, etc etc, that may be needed to generate your BSP
<galibert[m]>
Which comes back to my question, how do you reach the Elaboratable that has the information from the top level
<jfng[m]>
you pass that information as annotations ?
<galibert[m]>
annotations on which Elaboratable? The top one?
<galibert[m]>
Because there isn't any other you can reach
<jfng[m]>
the only interface we care about is the one of the top-level component, but users can e.g. pass the annotations of a sub-component to its parent
<galibert[m]>
That's going to be an... interesting .schema there if you start collating sub-information
<jfng[m]>
schemas can reference portions of one-another
<galibert[m]>
s/sub-/subdevice /
<Wanda[cis]>
galibert: yes, that is how it works; complex objects get complex annotations
<Wanda[cis]>
so the thing you seem upset about is that there's no way to just obtain the tree of all Elaboratable within a design
<jfng[m]>
e.g. the schema for MemoryMap annotations references itself:
<galibert[m]>
Wanda: I think that's a problem for any annotation scheme in general
<Wanda[cis]>
fundamentally that'd be a tool to break encapsulation
<Wanda[cis]>
and given the usecase of BSP generation in particular
<Wanda[cis]>
it wouldn't work
<galibert[m]>
Breaking encapsulation would be the point yes. In the same way that writing a vcd breaks encapsulation.
<Wanda[cis]>
you cannot just grab random subcomponent's annotations without context and expect to know anything about the whole design, without understanding how the subcomponent is connected to the design
<Wanda[cis]>
threading the subcomponent annotations through whatever components it is contained within is exactly what allows them to provide context.
<Wanda[cis]>
memory maps have been mentioned
<Wanda[cis]>
there's no reason for a design to contain only one bus
<galibert[m]>
no reason at all indeed
<Wanda[cis]>
you could easily have a big chunk of IP exposing an AXI interface that happens to use some internal helper CPU with some peripherials inside, that are never connected to ourside AXI
<Wanda[cis]>
if you wanted to build a BSP by just literally going through every Elaboratable in the design, you'd have no way of knowing all this internal stuff is actually not part of the main AXI bus
<Wanda[cis]>
and should not be included in the memory map
<galibert[m]>
Of course it should not be included in the memory map of a different bus.... so?
<galibert[m]>
I mean, if you do a simulation you expect to have the signals in all the design if you want to, not the top elaboratable only, and you don't particularly have difficulties to know what bus or whatever you're looking at
<galibert[m]>
You don't want to be required to bring up all interesting signals to the top level and try again if you forgot one
<jfng[m]>
no, and you wouldn't need to
<jfng[m]>
you would just need to attach any relavant information as annotations to the top-level component
<jfng[m]>
doing so, is intentionally left to the user, as we cannot provide a one-size-fits-all solution
Wolfvak_ has joined #amaranth-lang
Wolfvak has quit [Ping timeout: 245 seconds]
<bob_twinkles[m]>
maybe a minor thing but it would be nice to have at least 3rd-level domains (rather than just org.amaranth-lang) -- in particular so people can use *.github.io domains rather than needing to buy a domain to make schemas that are strictly compliant
<galibert[m]>
Ok, I don't see how you approach can in any way be usable, but we'll see. I know I won't use it as I currently understand it, but that's in no way critical. I'll do my own stuff.
<galibert[m]>
s/you/your/
<jfng[m]>
bob_twinkles[m]: agreed, also some large organizations may also want to use them
<jfng[m]>
galibert[m]: maybe seeing it being used to describe an actual SoC peripheral will help
<galibert[m]>
maybe
<bob_twinkles[m]>
i guess this RFC is meant only to define the syntax of annotations, not provide a way to give them semantics?
<Wanda[cis]>
that'd be the job of whatever RFC is defining the particular annotation
<Wanda[cis]>
well, except org.amaranth-lang.component, which is defined here
<jfng[m]>
<bob_twinkles[m]> "specifying ports as signed or..." <- width and signedness is enough for simple `Shape`s
<jfng[m]>
if a port uses a `ShapeCastable` (e.g. a `StructLayout`), this information is lost
<bob_twinkles[m]>
in that case, why include signedness? AFAIK the only impact of that attribute is how arithmetic operations are treated so it feels like a strange half-measure
<bob_twinkles[m]>
defining how to serialize a ShapeCastable might be out of scope for this RFC
<bob_twinkles[m]>
but maybe something like `shape: { width: xxx, [signed: true/false], [castable: { id: "for dispatch", arbitrary content } }`
<bob_twinkles[m]>
(hopefully that super rough sketch makes sense)
<bob_twinkles[m]>
rather than putting width, signed directly in the port
<jfng[m]>
iirc, Catherine suggested signedness because it was useful when interfacing DSP-like components, but i forgot the details; i'm fine with it because it is a small, non intrusive addition
<jfng[m]>
<bob_twinkles[m]> "but maybe something like `shape:..." <- i'd prefer adding an "annotations" property to port objects, as it is consistent with interfaces while allowing arbitrary information
<jfng[m]>
but you have a point, i think; when you have a port with a `StructLayout`, and you pass that information as an annotation, the "signed" property of the port does not make sense
<bob_twinkles[m]>
yeah keeping that consistent would be nice
<bob_twinkles[m]>
it lets us punt the issue if serializing *Layouts and gives a natural place for signedness information to go
<bob_twinkles[m]>
and maybe reset? I can see people wanting a way to express "don't care" for resets, though I know Amaranth generally tries to keep the state of signals well-defined at all times -- but especially if the intention is to enable interop with other HDLs, a bus may not have a well-defined PoR reset value on its data/address lines (or maybe it should, I'm a mostly-novice hardware designer and that's a foot gun)
<jfng[m]>
but we don't support reset-less ports, no
<bob_twinkles[m]>
makes sense
<bob_twinkles[m]>
I'm very excited to see people do some real metaprogramming with this =)
jjsuperpower has joined #amaranth-lang
<whitequark[cis]>
<bob_twinkles[m]> "rather than putting width, ..." <- basically all HDLs we care about here (Verilog, VHDL, Amaranth) can mark ports as signed, so it seems odd to intentionally ignore this information
<whitequark[cis]>
more importantly, I think it would be rather unfortunate if we could not roundtrip an interface through annotations and not even get the same Shape back
<whitequark[cis]>
the main case where I expect this to actually matter is DSP use cases, which are not that common but get pretty annoying if signedness info is lost
<whitequark[cis]>
<bob_twinkles[m]> "maybe a minor thing but it would..." <- Ah yeah, we can make it so that the domain of schema, however long it is, is a prefix for the name of the annotation
<whitequark[cis]>
the reset value for ports is also the initial value, or value that should be assigned there if the port is not connected
<whitequark[cis]>
actually we have an open issue for renaming "reset" to "init" or something; it might be worth it to do it in the schema upfront (or maybe not, it is versioned after all)
<bob_twinkles[m]>
i see, thank you
<whitequark[cis]>
<jfng[m]> "but you have a point, i think..." <- we could actually have things that should be sign-extended yet are shape-castable; there's nothing that stops you from having a newtype (a transparent wrapper) over some signed number
<whitequark[cis]>
I agree in principle that we should probably eventually support adding metadata to ports, and that this metadata should come from their custom shape-castable
<whitequark[cis]>
when discussing this with JF I proposed leaving this to a later RFC
olivier_galibert has quit [Quit: Idle timeout reached: 172800s]
<cr1901>
https://github.com/cr1901/sentinel Okay, it's not 100% ready, but I'm at the point where I'm okay w/ it being public. I've been working on a RISC-V CPU the past few months in Amaranth. It implements the I and Zcsr spec, as well as machine mode. And I've managed to get a SoC w/ UART, timer, and GPIO to fit on icestick _just barely_ because lofty told me the magic command to make abc9 optimize well
<cr1901>
(and working interrupts)
<cr1901>
Core passes RISCOF and RISC-V Formal as well
WilliamDJones[m] has quit [Quit: Idle timeout reached: 172800s]
<jfng[m]>
very cool
<jfng[m]>
congrats !
<whitequark[cis]>
nice!
<whitequark[cis]>
no license?
<cr1901>
jfng[m]: Tyvm. I attempt to use wishbone.Interface in examples/attosoc.py. If you have any feedback on how to make it better I'd love to hear when you have time.
<cr1901>
whitequark[cis]: I didn't think about it, tbh. Probably MIT license.