<_whitenotifier-7>
[nmigen/nmigen-boards] whitequark pushed 1 commit to master [+0/-0/±9] https://git.io/JG4CD
<_whitenotifier-7>
[nmigen/nmigen-boards] StephanvanSchaik 08b1b95 - [breaking-change] Factor out VGAResource.
someone--else has joined #nmigen
Sarayan has quit [Quit: ssl test]
bvernoux has joined #nmigen
nak has quit [Ping timeout: 272 seconds]
someone--else has quit [Quit: Connection closed]
cr19011 has joined #nmigen
cr1901 has quit [Read error: Connection reset by peer]
_whitelogger has joined #nmigen
bvernoux1 has joined #nmigen
lf_ has quit [Ping timeout: 268 seconds]
bvernoux has quit [Ping timeout: 268 seconds]
lf has joined #nmigen
alanvgreen_ has joined #nmigen
alanvgreen has quit [*.net *.split]
nyanotech has quit [*.net *.split]
alanvgreen_ is now known as alanvgreen
nyanotech has joined #nmigen
<vup>
is there a way to prevent the down propagation of `ClockDomain`s?
<whitequark[m]>
nope
<vup>
hmm
<whitequark[m]>
the scoping of clock domains is not ideal
<vup>
well I am trying to kind of fix that :) But I still need to "compile" to nmigen somehow...
<whitequark[m]>
from?
<vup>
whatever name this thing has I am writing :)
<vup>
The goal is mainly two things:
bvernoux has joined #nmigen
<vup>
Have a `create` and `finalize` method for each Elaboratable-equivalent, such that you can easily collect things like ILA probes
<vup>
and making all ClockDomains local and non-late bound
<whitequark[m]>
hm
<whitequark[m]>
this is somewhat troublesome
<vup>
In what way?
<whitequark[m]>
it effectively forks the language around issues that could and, perhaps, should be fixed upstream
<whitequark[m]>
collecting ILA probes is definitely something that should live upstream
<whitequark[m]>
there is an existing mechanism for that but it's pretty bad
<whitequark[m]>
changing the way clock domains work would be a major breaking change, so can't just fix that; adding a way to scope them more locally is reasonable and would benefit pure nmigen consumers as well
<vup>
Yeah, I am open to try and get this all done upstream some day
bvernoux1 has quit [Ping timeout: 272 seconds]
<vup>
I don't really see it as a fork of the language per se and more like a thin wrapper that helps me write the things I need right now
<vup>
I don't intend to promote it as a alternative for nmigen or anything.
someone--else has joined #nmigen
<vup>
I see it more as a testbed for ideas, that would be nice to have upstream someday
<whitequark[m]>
instrumentation probes is really something we should be handling better
<whitequark[m]>
the finalization process in migen made it almost impossible to do them correctly
<whitequark[m]>
(you'd get them dropped silently in ways not easy to avoid)
<vup>
interesting, the migen finalization process seems pretty similar to what I am currently doing, but I don't remember using it ever honestly
<whitequark[m]>
basically, to have reliable ILA probe injection, you would have to run migen finalization to fixed point
<whitequark[m]>
which is not done
<whitequark[m]>
it's just run in an unspecified order
<whitequark[m]>
nmigen makes that explicit through the elaborate() calls
<vup>
I see, I decided against iteration to fixed point with what I am doing aswell. Instead you add your probes to a list in a module higher up in the hierarchy, which then adds the logic for them in its `finalize` method. So if you try to add a probe and it would be dropped because there is no module higher up in the hierarchy to add them to, you get a elaboration time error.
<whitequark[m]>
why do you need `finalize` then?
<whitequark[m]>
you can do this with just `Fragment.get` for your subfragments
<vup>
Well to do something after all my submodules were `create`d and `finalize`d
<whitequark[m]>
i don't understand the mechanism
<whitequark[m]>
what does `create` do that `__init__` doesn't?
<vup>
create can add submodules
<vup>
__init__ doesn't
<vup>
because __init__ does not yet know where in the hierarchy the module will end up
<whitequark[m]>
hm
<whitequark[m]>
okay, this is definitely not something that will go upstream
<whitequark[m]>
what i was thinking of is something more declarative in nature. associating a dictionary of arbitrary user stuff with modules, inherited by fragments
<whitequark[m]>
so you declare any class, say ILAProbe, and then you can collect them throughout the fragment hierarchy
<whitequark[m]>
essentially fragment metadata
<vup>
ah
<vup>
yeah
<vup>
this is what we currently do basically
<vup>
but for some reason its pretty messy
<whitequark[m]>
howos?
<whitequark[m]>
* howso?
<vup>
the messiest part is tracking which module belongs to which series of fragments / wrapper modules
<whitequark[m]>
where do you use this tracking?
<vup>
to get back the elaboratable instance from a given fragment
<whitequark[m]>
to?
<vup>
well to implement the metadata
<vup>
instead of adding the metadata to the fragment, we add the metadata to the elaboratable and the trace back the fragment to the elaboratable
<whitequark[m]>
would there be a mess if this mechanism was upstream?
<vup>
probably less so, depends on how the upstream mechanism would look like
<vup>
right now we have a way to add python methods to Elaboratables, which access registers defined in the gateware
<vup>
via some CSR mechanism
<vup>
and AXI for example
<vup>
what is very nice is, that for writing these, autocompletion works, because the attributes on `self` actually exists (even if they have a different type that what they actually would be)
<vup>
(if this is not clear, the function annotated with @driver_method is something that gets packaged up into a python "header" and you can then call it at runtime to interact with registers defined in the gateware)
<whitequark[m]>
okay, that makes sense
<whitequark[m]>
how does this interact with the metadata mechanism?
<vup>
well instead of defining the method on the elaboratable itself we would have to add it as metadata to collect it somewhere, right?
<whitequark[m]>
why?
<vup>
how do we collect it otherwise?
<whitequark[m]>
oh, i see
<whitequark[m]>
there is still a way to do this with a decorator, i think
<vup>
interesting, how?
<whitequark[m]>
the fundamental disconnect here is that `f.add_metadata` is a good low-level mechanism but actual code uses `Module`
<whitequark[m]>
there needs to be something that bridges between the implementation (fragment) interface and the language interface
<vup>
yeah
<whitequark[m]>
the lack of a clear good solution for this disconnect is why this mechanism still does not exist
<whitequark[m]>
whatever it is, it should support decorators like you're describing
<whitequark[m]>
i'll think about it
bvernoux has quit [Quit: Leaving]
bvernoux has joined #nmigen
<vup>
Also another thing which this metadata mechanism lacks is something like scoping. (Or maybe this also belongs to the disconnect :)
<whitequark[m]>
scoping, hm
<whitequark[m]>
like what?
<vup>
It would be nice for example to be able to have something like "trigger group" for all ILA probes defined in some submodule
<whitequark[m]>
you get the fragment while iterating metadata, right?
<vup>
yes
<whitequark[m]>
would that be enough?
<vup>
Honestly I don't know.
<vup>
I don't see yet, how I would integrate this with a API like `m.submodules += ILATriggerOn(trigger)(some_submodule)`
<whitequark[m]>
hm
<whitequark[m]>
that doesn't seem like the right interface for configuring a trigger
<vup>
hm, why?
<whitequark[m]>
the way i see it, a trigger is a part of a probe
<vup>
my thinking is, there is some "interesting" external symptom, which is described by `trigger` having a posedge, and you want to get insight into the `ILAProbes`of `some_submodule` when this symptom occurs, because you think its caused by `some_submodule`
<whitequark[m]>
ohh, so triggers are bound to probes externally in the design
<whitequark[m]>
this is a conceptually very complicated scheme but it is not unreasonable
<whitequark[m]>
do you envision some sort of interface, perhaps a CLI, for configuring trigger-probe association?
<whitequark[m]>
or at least listing triggers and probes in the design?
<vup>
I mean yes, that would be nice
<whitequark[m]>
in that case, triggers can be added as simple submodules (and not have them done as wrappers), and the trigger-probe association would be done by the code that emits the ILA logic itself
<whitequark[m]>
that code could be fed a dict from trigger names to probe globs or something
<whitequark[m]>
you get the general idea
<vup>
Hmm right
<vup>
thats a pretty good idea :)
<whitequark[m]>
thank u :3
<vup>
Hmm but I can think of cases, where I might want something like this defined in the design. Maybe not for ILA probes, but for example for registers. I might want to say, the registers in this submodule should start at `$SOMEADDRESS`
<whitequark[m]>
have you seen what is done in nmigen-soc?
<whitequark[m]>
in short, i expect SoC stuff to be plumbed through explicitly, so it would not use the metadata mechanism
<whitequark[m]>
this makes more sense for several reasons, mostly that it is not inherently tied to hierarchy/elaboration/netlists
<vup>
Yeah, I want to avoid plumbing it through explicitly
<whitequark[m]>
doing it explicitly has the benefit of not having the problem you're describing
<vup>
for sure
<whitequark[m]>
plumbing ILA probes implicitly would be a massive pain
<whitequark[m]>
however, SoC stuff is inherently more structured, at least if you want to generate BSPs automatically
<whitequark[m]>
this structure can be exploited to make explicit connections flow
cr19011 is now known as cr1901
Lilian has joined #nmigen
<whitequark[m]>
ideally nmigen-soc would be usable. it is not
Lilian has quit [Client Quit]
Lilian has joined #nmigen
<whitequark[m]>
it would be nice to have you use it and give feedback on the design
<whitequark[m]>
but there are more pressing needs than nmigen-soc right now :(
<vup>
hmm I mean there are currently 300+ registers defined in the codebase, plumbing those through would be pretty annoying I think
<whitequark[m]>
there would be a DSL for defining registers
<whitequark[m]>
that's the main missing part currently
<whitequark[m]>
so, hm
<vup>
But you would need to plumb the soc bus connection through manually even with the DSL, right?
<whitequark[m]>
sure
<whitequark[m]>
this makes things such as arbiters and decoders, as well as designs with many various buses, as easy to construct as simpler designs
<whitequark[m]>
same underlying reasoning as e.g. explicit plumbing through of `platform`, explicit `elaborate` method and so on
<vup>
Hmm yeah makes sense
<whitequark[m]>
in my view, implicit plumbing should be reserved for things that truly lack unifying structure
<whitequark[m]>
i.e. where having it done explicitly provides nothing but annoyance
<whitequark[m]>
in other cases, explicit plumbing can be designed in a way that integrates into and enhances user code, rather than merely clutters it
<vup>
I guess the main thing I miss from the explicit plumbing is the ability to jump in the hierarchy
<whitequark[m]>
have wrappers unaware of intermediate buses?
<vup>
Not having to pass something through 5 modules where it is not used just to get it where I need it
<whitequark[m]>
yes, this is true
<whitequark[m]>
but consider: this comes at the cost of not being able to look at the interface of a module and tell what buses it exposes
<vup>
True
<vup>
But honestly I have not needed that yet
<whitequark[m]>
yes
<vup>
We currently generate a python "header" and a small repl scripts, so just tabbing through the hierarchy in the repl was always enough
<vup>
But I can see where this would be nice
<whitequark[m]>
when designing nmigen-soc i have to think ahead, because the decisions made early in a project will be baked into designs that get increasingly more complex
<whitequark[m]>
this does not mean eschewing implicit connections completely but they need to be well justified
<whitequark[m]>
think of these things similarly to thread-local variables in software
<whitequark[m]>
they are essential to some things, but they add this bit of implicit context that really bites you with its implicitness in some cases, which become terrifyingly hard to do correctly then
<whitequark[m]>
fibers, thread pools, and the like
<vup>
Of course, I am not trying to say that nmigen-soc is not well designed, I would argue its probably designed a lot better that whatever we came up with. But currently it seems to me that using nmigen-soc would only bring more "boilerplate" and not really a lot of benifit
<whitequark[m]>
yes
<vup>
(for our usecase)
<whitequark[m]>
it would make sense mainly for the benefit of nmigen-soc, in this case
<whitequark[m]>
which of course is not your responsibility
<whitequark[m]>
mainly i offer it as an upstream mechanism that will be maintained and evolved together with the core language implementation, where necessary
<whitequark[m]>
whether the cost of boilerplate is worth that is up to you
<whitequark[m]>
this is of course all in the future
<vup>
Makes sense.
<vup>
I think for now, we will play around a bit with the two phase `create` and `finalize` thing, I probably have not been bitten enough by thread-local variables to be as careful with this approach as you are, but maybe that will change :)
<vup>
(maybe I also wrote too much flutter and got too hooked on the idea of looking up / adding metadata / state using your position in the module tree)
<whitequark[m]>
interesting
<whitequark[m]>
Flutter might be something to look into
<vup>
Heh, I took a lot of inspiration from it. The `create`, `finalize` + looking up things in the hierarchy tree via some `context` thing is not much more than a weird mix of the flutter layout algorithm and the general flutter widget architecture
<whitequark[m]>
one issue here is that nmigen's hierarchy was not designed for that or intended to be used that way
<vup>
Where do you see the possibility for issues there?
<whitequark[m]>
scoping is one you've encountered
emeb_mac has joined #nmigen
<vup>
hmm yeah, but this is mostly a problem with `ClockDomain`s currently, right? And you agreed that the scoping there is currently not ideal.
<whitequark[m]>
manifestation of systemic problem
<whitequark[m]>
the other important one is unnamed fragments
<vup>
I don't see the problem with unnamed fragments?
<whitequark[m]>
well, the interface for working with them is awkward
<vup>
hmm I don't see how this would be more important here vs the adding of metadata
pftbest has quit [Read error: Connection reset by peer]
pftbest has joined #nmigen
Stary has quit [Changing host]
Stary has joined #nmigen
nak has joined #nmigen
nak has quit [Quit: Bye]
nak has joined #nmigen
nak has quit [Client Quit]
nak has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
pftbest has quit [Ping timeout: 272 seconds]
bvernoux has quit [Quit: Leaving]
esden has quit [Read error: Connection reset by peer]
tannewt has quit [Read error: Connection reset by peer]
esden has joined #nmigen
tannewt has joined #nmigen
lf has quit [Ping timeout: 252 seconds]
lf_ has joined #nmigen
<_whitenotifier-7>
[nmigen] rroohhh commented on issue #342: Separate `Record` into `PackedStruct` and `Interface` components - https://git.io/JGRiP
<_whitenotifier-7>
[nmigen] rroohhh edited a comment on issue #342: Separate `Record` into `PackedStruct` and `Interface` components - https://git.io/JGRiP
<_whitenotifier-7>
[nmigen] rroohhh edited a comment on issue #342: Separate `Record` into `PackedStruct` and `Interface` components - https://git.io/JGRiP
<_whitenotifier-7>
[nmigen] rroohhh edited a comment on issue #342: Separate `Record` into `PackedStruct` and `Interface` components - https://git.io/JGRiP