<RobTaylor[m]>
Hmm. Just noticed that PortLike probably needs some documentation (and probably abstractmethod) for invert as Buffer.elaborate assumes it.
<RobTaylor[m]>
or maybe instead, Buffer elaboration should just raise a TypeError at the top if its not a SingleEndedPort, DifferentialPort or SimulationPort
<RobTaylor[m]>
tbh, kinda feel like buffer elaboration should be defined somehow by the portlike implementation rather than casing on the port type
<whitequark[cis]>
the extension point for buffer elaboration is platform.get_io_buffer; if it was the PortLike implementation, then the SingleEndedPort would have to know about every individual built-in platform, and also somehow know about every platform users can define
<RobTaylor[m]>
makes sense
<whitequark[cis]>
i agree that io.Buffer should perform the match on the PortLike before accessing self._port.invert, although this is only a question of getting a better diagnostic (either way you're getting an exception)
<RobTaylor[m]>
Indeed, a decent diagnostic would have saved me a bit of time =)
<whitequark[cis]>
i have no particularly strong preference between that solution or adding an invert method. the latter would require a (trivial) RFC
<whitequark[cis]>
* i have no particularly strong preference between that solution or adding an invert abstract property to PortLike. the latter would require a (trivial) RFC
<RobTaylor[m]>
i think just checking is fine for now, maybe with a note in the error that if you're defining your own port types, to provide platform.get_io_buffer
<whitequark[cis]>
we should actually start by documenting platform.get_io_buffer, since it somehow slipped through and doesn't appear in the docs at all
<RobTaylor[m]>
+1
<whitequark[cis]>
i have a little bit of time so i think i can go fix that now
<RobTaylor[m]>
<3
<RobTaylor[m]>
thank you :)
<RobTaylor[m]>
Can we do multiple clocks in simulation?
<whitequark[cis]>
yep, it just works
<whitequark[cis]>
(you always could, since amaranth 0.1)
<whitequark[cis]>
once you use multiple clocks, make sure you are using await ctx.tick().sample(...) to get your inputs, even in testbenches
<whitequark[cis]>
it's going to be incredibly easy to get yourself into trouble if you use ctx.get(), even if it usually works at first
<RobTaylor[m]>
thanks, thats good to know
<whitequark[cis]>
really this is always true, but in my experience you hit problems basically immediately in multiclock designs
<whitequark[cis]>
doubly so if you're writing models for external devices
<RobTaylor[m]>
Just having a proper look at SimulationPort/singleendedport. One thing we ended up doing was having a setting for one oe per pin, as it just got messy doing that with multiple bidir ports
<_whitenotifier-4>
[amaranth] github-merge-queue[bot] created branch gh-readonly-queue/main/pr-1611-652dbef0399b73b48a4b56bd5e52e6e69bd2fc5a - https://github.com/amaranth-lang/amaranth
<whitequark[cis]>
we discussed having an option to have one oe per pin at the meeting where the RFC was approved and rejected it
<whitequark[cis]>
this is because you can just slice the port
<whitequark[cis]>
(that being said, nothing stops you from having a OEPerPinBuffer that instantiates an array of io.Buffers or something)
<RobTaylor[m]>
yeah, i think in practice slicing the port introduced complications all up the ip chain, but its a while since i went through that and i there may have been a better way
<whitequark[cis]>
re: SimulationPort, be aware of [this RFC](https://github.com/amaranth-lang/rfcs/pull/78), which we decided to merge but which is waiting on some editorial updates before it can go in
<RobTaylor[m]>
oh, thats useful, nice!
<whitequark[cis]>
i don't think most of the IP chain needs to care at all? in glasgow i do this in the suggested way and it works fine
<whitequark[cis]>
basically what happens is that you pass the "whole" multi-bit port to a constructor of some toplevel thing, which can pass it down to a constructor of something else, etc, until the moment where it gets passed into a QSPIController or something of that nature
<whitequark[cis]>
which is the entity that ends up slicing the port
<RobTaylor[m]>
i'll take a look-see :)
<whitequark[cis]>
the ability to slice and concatenate ports means that you can make the decision to split it basically as early or as late as you want
<_whitenotifier-4>
[amaranth-lang/amaranth-lang.github.io] whitequark 3802bda - Deploying to main from @ amaranth-lang/rfcs@0ff3464a3b0c6d5b95704936f297b427ea6db4a4 🚀
<RobTaylor[m]>
mm, slighly confused by len(self._oe)==width in simulationport
<whitequark[cis]>
consider that SimulationPort has no idea, and cannot possibly have an idea, of how you'll slice it and which buffers you'll instantiate with it
<whitequark[cis]>
imagine SimulationPort as a width-tuple of triples
<whitequark[cis]>
each one corresponds to a virtual input/output buffer of yet unknown configuration
<whitequark[cis]>
or, perhaps a better way to put it: SimulationPort is like an array of pins, each of which has a virtual input buffer and a virtual tristatable output buffer. the signals on SimulationPort are the "outside" part of it; they're what you can probe outside of the ASIC. the signals on the "inside" of it are the ones on io.Buffer and friends
<RobTaylor[m]>
ah, i get it now :)
<RobTaylor[m]>
thank you. That's also a great description to add to the docs =)
<whitequark[cis]>
mm yeah the docs do need improving. I don't particularly like this description though, it's gonna be confusing in different ways
<RobTaylor[m]>
another q.. what's the intent of 'invert' ?
<whitequark[cis]>
in amaranth, the convention is to normalize all control signals to active-high (1 means active) at the boundary of the design
<whitequark[cis]>
so when e.g. instantiating a buffer for an SPI CS#, you would invert the buffer
<whitequark[cis]>
this is incredibly useful in part because there are lots of cases where you need "gateware for exactly [protocol] but something is inverted"
<whitequark[cis]>
and these can now be implemented at the toplevel, without adding endless "invert_whatever" arguments to all IO controllers
widlarizerEmilJT has quit [Quit: Idle timeout reached: 172800s]