<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] f8ddfdd - Deploying to main from @ amaranth-lang/amaranth@57748a66a657cdec8399a3edfa628fe5e0c7d050 🚀
trabucayre has quit [Read error: Connection reset by peer]
trabucayre has joined #amaranth-lang
mobius has quit [Ping timeout: 256 seconds]
mobius has joined #amaranth-lang
ebb has quit [Remote host closed the connection]
jn has quit [Read error: Connection reset by peer]
_catircservices has quit [Ping timeout: 276 seconds]
galibert[m] has quit [Ping timeout: 276 seconds]
whitequark[cis] has quit [Ping timeout: 276 seconds]
<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] c1ea33b - Deploying to main from @ amaranth-lang/amaranth@8b48af6de8bed90873add0d23f7006d2c96c3143 🚀
cr1901_ is now known as cr1901
<_whitenotifier-b>
[amaranth] whitequark opened pull request #971: lib.wiring: in `is_compliant(sig, obj)`, check that `obj` is an interface object with that signature - https://github.com/amaranth-lang/amaranth/pull/971
<cr1901>
So it's "drop-in replacement" for me. My experience not representative.
<whitequark[cis]>
that's actually quite common
<whitequark[cis]>
it is intended to be representative
<whitequark[cis]>
thanks for checking!
<whitequark[cis]>
@room: it is 1700 UTC on Monday, which is the time for our regularly scheduled Amaranth meeting
<whitequark[cis]>
today we have quite a lot on the agenda; who is attending?
zyp[m] has joined #amaranth-lang
<zyp[m]>
o/
<cr1901>
Well, I'm already here lol
johnsel[m] has joined #amaranth-lang
<johnsel[m]>
uh-oh she did it again
<Wanda[cis]>
meow
* whitequark[cis]
facepalm
<galibert[m]>
As a preliminary, and just to be clear, I 100% agree that rfcs/discussions in the path of 0.4 have priority and my rfcs are not in that category
zbrown23[m] has joined #amaranth-lang
<zbrown23[m]>
uh oh
Chips4MakersakaS has joined #amaranth-lang
<Chips4MakersakaS>
o/
<whitequark[cis]>
1bitSquared people: please leave the discussion of the @-room fiasco until after we've had the meeting please. thank you for understanding
<whitequark[cis]>
at the time enum support was added to Amaranth, it (or Migen) had basically no enum support anywhere, so it was done in a fairly sketchy way, basically treating enums as slightly extended integers
<galibert[m]>
I find it annoying that <= and friends are not supported to check whether an enum value is within a block, but given that's how pythons own enum do it, well, that's that
<whitequark[cis]>
in fact, Python distinguishes between int-like enums and non-int-like enums
<whitequark[cis]>
I mean, you can use IntEnum for your enums
<galibert[m]>
But I want the type checking :-)
<whitequark[cis]>
you could also define le and friends on your enums where you want range comparisons, with any semantics you like
<whitequark[cis]>
it seems presumptious to assume that all enums anyone would ever write form fully ordered sets
<galibert[m]>
Well, python enums are fully ordered sets afaik
<galibert[m]>
anyway, the argument "follow python practice" is unexcapable
<whitequark[cis]>
er? didn't you note yourself that Python enums do not support numeric comparisons?
<galibert[m]>
s/unexcapable/unescapable/
<galibert[m]>
yeah, but they are fully ordered anyway
<galibert[m]>
they just pretend :-)
<whitequark[cis]>
that's literally what "fully ordered" means: supports numeric comparisons
<galibert[m]>
anyway, my disposition is merge
<cr1901>
At least enum.Enum doesn't force you into using auto(). Being able to choose each enum member's value is valuable, even if I only need equality comp
<galibert[m]>
I'll need to do a rfc for auto starting at 0 at some point
<cr1901>
(some values micro-optimize better than others)
<whitequark[cis]>
does class X(Enum, start=0): not work?
<galibert[m]>
(ideally you'd leave the micro-optimizations to the synth, but that doesn't exist)
<galibert[m]>
I.. don't think it does? Didn't Wanda try it?
<zyp[m]>
whitequark[cis]: I tried it, it does not
<galibert[m]>
Ah zyp, sorry
<Wanda[cis]>
hm
<whitequark[cis]>
indeed, it does not
<zyp[m]>
but it should be possible to make it work
<cr1901>
(also, synth will convert certain enums to one-hot if it can, regardless of the bespoke values you chose for each variant value)
<Wanda[cis]>
... actually why does this not work
<galibert[m]>
Hmm, I didn't want to trigger a nerd-sniping
<zyp[m]>
let's leave start=0 for later? are there any other points we haven't discussed yet?
<whitequark[cis]>
sure, let's leave that for later
<zyp[m]>
I see there's a point under unresolved questions about method forwarding
<Wanda[cis]>
that's actually a quite important point
<Wanda[cis]>
as in, the RFC is completely different in that variant
<Wanda[cis]>
and it's a variant I'd like to discuss
<whitequark[cis]>
that variant being what?
<Wanda[cis]>
hm, maybe not completely, but still
<Wanda[cis]>
the variant where instead of having a customizable EnumView subclass, you add methods on the actual enum, and EnumView magically forwards method calls
<whitequark[cis]>
right!
<whitequark[cis]>
so when I proposed that point, it was based on the experience with Signature/FlippedSignature, where it works relatively well, since FlippedSignature is intended to be a Liskov subclass of every signature
<whitequark[cis]>
but EnumView is kind of ... not
<Wanda[cis]>
so, to describe it properly
<whitequark[cis]>
so I'm much less convinced now that this is the right thing to do
<Wanda[cis]>
presumably there are circumstances where you'd want to have custom methods on your enum views
<zyp[m]>
my immediate thought is that that'd bring it more in line with how defining methods on regular python enums works
<Wanda[cis]>
in the RFC and the PR, as is, this can be done by supplying your own EnumView subclass for the enum, and adding methods on it
<galibert[m]>
Wanda: like \_\_lt\_\_ ?
<Wanda[cis]>
the alternative I wish to discuss is that EnumView could instead magically invoke your enum's methods on itself
<cr1901>
How would that be implemented?
<whitequark[cis]>
not really like __lt__, that is actually a special case since it relies on the semantics of the compile-time and runtime values being the sam
<whitequark[cis]>
s//`/, s/,/`,/, s/sam/same/
<Wanda[cis]>
ie. if you define a method on your enum, it'd have to handle being invoked with self being of class EnumView instead of your actual enum
<whitequark[cis]>
cr1901: crimes
<cr1901>
Besides that
<Wanda[cis]>
... very much crimes
<galibert[m]>
Capital crimes
<zyp[m]>
but do we then get a problem where defining a method makes it available on both the shape castable and the value castable?
<whitequark[cis]>
cr1901: you can invoke A's methods on an object of type B by doing simply `A.meth(B())`
<whitequark[cis]>
zyp: we already have that exact problem
<Wanda[cis]>
I don't think __lt__ would quite work, given that it has special lookup rules
<cr1901>
whitequark[cis]: Right, but how does doing B.meth() not give an AttributeError?
<Wanda[cis]>
but yeah
<cr1901>
getattr crimes?
<Wanda[cis]>
cr1901: override `__getattr__`
<whitequark[cis]>
cr1901: `__getattr__`
<Wanda[cis]>
we already do it in FlippedSignature
<Wanda[cis]>
it's... well just look at the code
<cr1901>
ahhh, for some reason I thought __getattr__ was only for members not methods
<cr1901>
ack
<Wanda[cis]>
(I should note that we were giggling like madcatgirls when writing this code)
<galibert[m]>
So the problem is that you'd like Enum to be both a ShapeCastable or a ValueCastable, depending on the context?
<whitequark[cis]>
Wanda: I think the best counterargument I can think of for this is that there are lots of things you can do with the normal enum that you cannot do at all, e.g. "get its value", or if we add a `@property value` then you cannot use normal control flow constructs with that value
<whitequark[cis]>
galibert: no, that's unrelated to this unsolved question
<whitequark[cis]>
(this already has to happen, and works pefrectly fine)
<galibert[m]>
I thought you have the EnumView as the ValueCastable?
<whitequark[cis]>
enum values themselves are ValueCastable too, necessarily
<cr1901>
this already has to happen, and works pefrectly fine <-- also answers zyp[m]'s question?
<whitequark[cis]>
in fact it is the case before this RFC
<whitequark[cis]>
the enum's metaclass is ShapeCastable and the enum itself is ValueCastable
<zyp[m]>
I'm not questioning whether it works, I'm questioning whether the potential for confusion is worth it
<whitequark[cis]>
lib.data has a similar thing going on with data.Struct
<Wanda[cis]>
I.. don't know
<whitequark[cis]>
zyp: this is already the case without this RFC, so why is it a question for this RFC?
<Wanda[cis]>
myself I'm feeling that we're kind of playing fast and loose with Python crimes budget
<whitequark[cis]>
or perhaps you phrased the question poorly
<whitequark[cis]>
whitequark[cis]: Wanda: I want to reiterate this: I am voting against my own proposed amendment to the RFC text with this
<whitequark[cis]>
crimes are fine when they work, but in this case I don't think they do
<whitequark[cis]>
EnumView isn't an LSP subclass of enums themselves
<whitequark[cis]>
it's nothing even close to the LSP subclass
<jfng[m]>
if i understand, if i did `a = Signal(MyEnum, reset=MyEnum.FOO)`, then i wouldn't be able to access `a.reset` without customizing the EnumView ?
<whitequark[cis]>
jfng: just like with `data.View`, yes
<Wanda[cis]>
jfng[m]: correct (and I'll note that this is a general property of custom ValueCastable, and the same happens currently for Struct)
<whitequark[cis]>
just like data.View, EnumView can wrap non-signals
<whitequark[cis]>
so there's no way it can provide in general a.reset
<whitequark[cis]>
in fact, if you use enums together with lib.data, you will often get EnumView of a slice
<jfng[m]>
yeah, and it already felt a bit awkward with lib.data
<cr1901>
Create a custom View that can only wrap signals?
<jfng[m]>
generally speaking, i'm not a fan of calling a `Signal` constructor, and not getting a `Signal` instance as a result
<whitequark[cis]>
you should have raised that objection during discussion of RFC 15
<whitequark[cis]>
it is not relevant to this RFC
<whitequark[cis]>
(I think you might have, but either way, it's not relevant here)
<jfng[m]>
(i did, yes)
<whitequark[cis]>
we're halfway through this meeting so I will ask participants to not retread accepted RFCs
<cr1901>
If it speeds things up: Disposition to merge enum RFC w/o the variant being discussed
<whitequark[cis]>
any other questions? zyp?
<whitequark[cis]>
anyone else?
<zyp[m]>
no, my disposition is also to merge without the forwarding magic
<galibert[m]>
Same
<Wanda[cis]>
(FWIW my opinion is: merge, drop the variant)
<whitequark[cis]>
mine is the same: merge without forwarding magic
<Chips4MakersakaS>
I follow also
<whitequark[cis]>
that's everyone. disposition on RFC 31: merge
<whitequark[cis]>
the next one is not an RFC, but a closely related change to lib.data that in my view doesn't warrant an RFC, but is technically a breaking change, so it goes in this meeting anyway
<whitequark[cis]>
as it stands, lib.data.View is implicitly castable to an integer, e.g. you can do Const(1) + Signal(SomeStruct), which does a thing you almost certainly don't want (only on RHS; you can't do Signal(SomeStruct) + Const(1))
<whitequark[cis]>
in my view this is a bug and an omission in the original lib.data RFC (as our plans for Amaranth's numeric tower were and are evolving), but again, it's technically a breaking change to make it not implicitly castable to integer for arithmetic operations
<galibert[m]>
You can as_value() explicitely if you have a good reason to do that
<whitequark[cis]>
yes, that of course stays
<cr1901>
If it breaks my code, I'll manage to go on somehow
<whitequark[cis]>
I cannot imagine a reason to have structs and unions implicitly castable to integers, it seems like something that would only occur as a result of bugs
<whitequark[cis]>
this PR implements dumping of structure fields in VCDs, but does so by adding a private API which lets the Amaranth core and the Amaranth standard library collude
<whitequark[cis]>
thus far our policy (which was implemented in practice) was to never have any such API and to not privilege the standard library in any way
<whitequark[cis]>
in the interest of expediting the 0.4 release I am proposing to temporarily allow that
<galibert[m]>
That's expected to be "temporary" until something more general can be designed, probably in confunction with cxxrtl-as-sim?
<galibert[m]>
s/confunction/conjunction/
<whitequark[cis]>
yes, something like that
<cr1901>
No complaints, I'll try my best not to apply Hyrum's Law
<whitequark[cis]>
it is not expected to last until after more than 0.5 (it will be considered a blocker for the 0.5 release)
<zyp[m]>
sounds good to me
<galibert[m]>
works
<whitequark[cis]>
cr1901: the current interface is 100% likely to be broken later
<Wanda[cis]>
the interface in this PR is designed to be usable for cxxsim FWIW, though RTLIL backend bits are not included
<Wanda[cis]>
(they will be included when we have the new IR, I think)
<whitequark[cis]>
this has been brought to discussion on the previous meeting
<Wanda[cis]>
(there's also #909 to discuss?)
<whitequark[cis]>
I like the __init_subclass__ addition
<whitequark[cis]>
Wanda: yes, but we're short on time, and #909 is a simple bikeshed that can wait until the next meeting
<cr1901>
I like everything except the need to build schemas by hand, but there's probably a python package to automate that
<whitequark[cis]>
(the outcome of 909 is either nothing or a search-and-replace, it's not a big deal)
<galibert[m]>
I think 30 is misguided on multiple levels, and that a real solution requires some introspection capability on the elaboratable/module tree. I know we disagree, so I'll just abstain
<whitequark[cis]>
galibert: #30 exposes the logical hierarchy of the design (its type) while the elaboratable/module tree are the physical hierarchy of the design (its implementation)
<Chips4MakersakaS>
After reading discussion on Friday it is not clear to me how much this RFC is really fully optional and how much design and tooling will depend on certain annotations being present.
<jfng[m]>
whitequark[cis]: validation of a schema against the metaschema would be done by the `jsonschema` package, though i'm not sure how effective it will be in practice
<whitequark[cis]>
the thing you say you want is not in the same category as the thing provided by #30; indeed, both can coexist
<whitequark[cis]>
(I think we do need some introspection capability on the elaboratable/module tree!)
<whitequark[cis]>
Chips4Makers (aka Staf Verhaegen): it is likely that amaranth-soc will heavily reliant on RFC #30 for essentially all operation
<cr1901>
metaschema?
<jfng[m]>
Chips4MakersakaS: you can just ignore its existence in your own designs, and also when using a component that provides metadata
<whitequark[cis]>
i.e. it is likely that almost every amaranth-soc user will use RFC #30, directly or indirectly, to achieve their goals
<cr1901>
you mean the schema for jsonschema?
<whitequark[cis]>
cr1901: yes
<jfng[m]>
cr1901: the schema that specifies schemas, i.e. the 2020-12 draft of the JSON Schema specification
<cr1901>
wheee... it's schemas all the way down
<Chips4MakersakaS>
Isn't it better to change in rationale Usage of this feature is entirely optional. to presence or not of annotations doesn't impact generated logic?
<jfng[m]>
i chose "usage" as in "adding metadata to your own design" or "using a design that provides metadata"
<jfng[m]>
in both cases, you can simply ignore it
<whitequark[cis]>
(while we are discussing this: anyone else has any concerns besides galibert and Chips4Makers (aka Staf Verhaegen) ?)
<whitequark[cis]>
(@zyp?)
<galibert[m]>
Also, something that's not 100% clear, are the annotations part of the elaboratable or of its signature?
<zyp[m]>
> Reset values are represented by their two's complement. For example, the reset value of Member(Out, signed(2), reset=-1) would be given as 3.
<zyp[m]>
I'm just curious about the rationale for this
<zyp[m]>
* > Reset values are represented by their two's complement. For example, the reset value of Member(Out, signed(2), reset=-1) would be given as 3.
<zyp[m]>
I'm just curious about the rationale for this
<jfng[m]>
galibert[m]: the signature, it must not depend on elaboration
<cr1901>
-1 = 0b11 ==3 unsigned
<whitequark[cis]>
zyp: there needs to be some representation and it can't be a JSON number (because it might be wider than 48 bits)
<cr1901>
Does JSON support negative ints?
<galibert[m]>
And.... you can have a memory map dump in there?
<jfng[m]>
galibert[m]: absolutely
<whitequark[cis]>
cr1901: yes, but only with an implementation-defined range
<whitequark[cis]>
so if you have a reset value of all-ones on a 128-bit bus...
<whitequark[cis]>
half the JSON implementations will choke on it, and the other half will turn it into a float
<cr1901>
ahhh, then you need a string I guess
<whitequark[cis]>
yes, so it's better to say "this is always a string, in decimal"
<galibert[m]>
Catherine: double usually though, right?
<zyp[m]>
they look like numbers to me in the examples
<galibert[m]>
(which is still not enough, at all)
<whitequark[cis]>
galibert: I meant a float as in "some floating point number"
<zyp[m]>
and even if they're strings, why can't they be negative if signed? seems easier to consume
<jfng[m]>
zyp[m]: they are required to be integers, see the `ComponentMetadata` schema
<jfng[m]>
with a minimum of 0, in the case of reset values
<whitequark[cis]>
jfng: they should not be integers, that will break
<galibert[m]>
Isn't the signature frozen at the end of the constructor?
<whitequark[cis]>
they should be strings with a numeric value (whether that's decimal or binary or hex or anything else we pick)
<whitequark[cis]>
zyp: iirc, initially I thought about doing hex, and signed hex is weird, while signed decimal is not really very weird
<jfng[m]>
ah right, due to the aforementioned bit width limitations; ok
<whitequark[cis]>
zyp: I don't have a strong objection to signed decimal in string, especially if we keep the signed flag in the RFC (which I think we should)
<galibert[m]>
Or when the members are created at least?
<whitequark[cis]>
I do have objection to having signed binary or hex in string, mainly that it's hard to read
<whitequark[cis]>
galibert: a signature is not automatically frozen at the end of constructor
<whitequark[cis]>
the idea is that a consumer freezes a signature, whenever it makes a choice that depends on it
<zyp[m]>
whitequark[cis]: I'm not sure two's complement hex is any harder to read than signed hex
<whitequark[cis]>
zyp: you basically never see signed hex anywhere so you don't get used to parsing it
<whitequark[cis]>
meanwhile, can you tell me what is the value of the third bit of some signed hex value?
<zyp[m]>
s/harder/easier/
<galibert[m]>
Ok, what I'm struggling with is Decoder. The constructor of decoder needs to create the bus members to connect to the initiator, or does that happen later, whenever that is?
<galibert[m]>
on m.submodules += decoder maybe?
<whitequark[cis]>
Decoder updates the memory map when you call Decoder.add
<whitequark[cis]>
since the annotation references the actual memory map object, it is updated instantaneously
<whitequark[cis]>
i.e. whenever you serialize the metadata you get the view of the system at that moment
<whitequark[cis]>
actually, it freezes the memory map after that (looking at JF's branch) so that is the last update you can actually make
<galibert[m]>
Wait, you have a non-json object in the annotations?
<whitequark[cis]>
the annotation itself is a Python object that serializes to JSON via a known method
<whitequark[cis]>
it doesn't need to store the JSON
<whitequark[cis]>
it can generate it on the fly from some other metadata
<galibert[m]>
and that's what's your supposed to be able to bring up at higher levels?
<galibert[m]>
and before elaboratable too
<whitequark[cis]>
can you rephrase the question?
<whitequark[cis]>
the intent behind component metadata/annotations is essentially to provide a "type" for the interface of your entire system; to tell the rest of the world (things like BSP generators, debuggers, documentation generators, block diagram editors) how it operates, how you connect to it
<whitequark[cis]>
it says nothing about what is the specific netlist inside of the black box, while saying (ideally) everything there is to know about interacting with the black bo
<whitequark[cis]>
s/bo/box/
<galibert[m]>
If you create a design, you can't reach a Decoder object without knowing too much about the fields of the top level elaboratable. jfng 's answer to that is that the top level elaboratable has to pick up the annotations of whatever submodules are interesting and plonk them in its own annotaitons
<whitequark[cis]>
so whenever you have a wishbone interface, the interface is annotated with everything (every bridge and register) that's connected to it, so that your Rust or Python or C or what you have application can use symbols
<galibert[m]>
Urgh, if you have a top level module which creates a cpu core and half a dozen submodules to connect to the cpu bus, wanting to create the interface documentation for the half dozen modules doesn't mean you want to bring up the bus in the top level module interface
<galibert[m]>
especially since you really don't want other people to muck with the cpu core output raw
<whitequark[cis]>
galibert: that was me thinking about the specific case of a toplevel that doesn't contain its own CPU core
<whitequark[cis]>
sorry, I should've clarified
<whitequark[cis]>
for context, this RFC exists primarily for the case where you are integrating with other HDL, so you make a peripheral in Amaranth for use in eg Verilog, or vice versa
<zyp[m]>
the metadata you generate doesn't have to be from the toplevel component
<jfng[m]>
galibert[m]: then that top-level will probably have its own `Signature` subclass, and you will need to pass it annotations from the signatures of your sub-components
<whitequark[cis]>
this means that the split will likely be at the interface that has a wishbone or whatever you have bus
<jfng[m]>
metadata is constructed bottom-up, not top-down, in this RFC
<whitequark[cis]>
if you are building a self-contained design which has both a core and peripherals, you will need to generate documentation "from the viewpoint" of a CPU, or several CPUs, if you have many (which is increasingly common)
<whitequark[cis]>
imagine a 8-bit and a 32-bit CPU in a design (this happens all the time these days), they would have different docs
<galibert[m]>
Honestly I don't see that particular design flourish outside of internal -soc use
<whitequark[cis]>
so you have to grab the port of the right CPU and dump the metadata from that perspective. you could also have same bitness but different bridging, also very common
<whitequark[cis]>
why not? I think it would be great to have all Amaranth components be automatically usable as e.g. fusesoc modules
<galibert[m]>
But I can be wrong, and I'd have no issue with being wrong
<zyp[m]>
I like the extensability
<whitequark[cis]>
and this metadata should be automatically convertible to both SVD and IP-XACT
<galibert[m]>
I think the code to make it reachable in the first place is going to be rather annoyinh
<galibert[m]>
s/annoyinh/annoying/
<jfng[m]>
also, being able to compile an amaranth design into verilog, then reinstantiating it back into another amaranth design, without losing information
<galibert[m]>
Well, I have some shopping to do, I really need to move. I'll stay on abstain, and I'll let time prove me wrong. I like being proven wrong on that kind of stuff
<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] whitequark 7436f90 - Deploying to main from @ amaranth-lang/rfcs@465d188219097c5a091ddb0db5b0e99a481574b5 🚀
<whitequark[cis]>
actually, I think the extension point should be called view_cls and not view_class, for consistency with the rest of the codebase (we use cls exclusively)
<Chips4MakersakaS>
I'm going to detach myself now from the matrix (e.g. go AFK)
<Wanda[cis]>
hm.
<Wanda[cis]>
we have none in public interfaces AFAICS; the two private ones I could find are __layout_cls and _enum_class (which is going away with the value_repr PR)
<whitequark[cis]>
I think cls is the Python-ism for e.g. the first argument of @classmethod
<whitequark[cis]>
which is why I've been using that everywhere, though you are right, we don't have anything in the public interface (I checked too)
<Wanda[cis]>
shrug I don't really know
<Wanda[cis]>
I'm fine with either
<Wanda[cis]>
though procedurally I think that should be brought up before the RFC is voted on and merged...
<zyp[m]>
this is bikeshedding that I don't much care for, but if I have to pick I'm in favor of cls for consistency
<whitequark[cis]>
we miss things like that all the time and in the past we amended several RFCs for similar (and even bigger) reasons
<whitequark[cis]>
you just open a PR against the merged RFC
<_whitenotifier-b>
[amaranth-lang/amaranth] whitequark 04f9069 - lib.wiring: in `is_compliant(sig, obj)`, check that `obj` is an interface object with that signature.
<_whitenotifier-b>
[amaranth] whitequark closed pull request #971: lib.wiring: in `is_compliant(sig, obj)`, check that `obj` is an interface object with that signature - https://github.com/amaranth-lang/amaranth/pull/971
<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] 61b8e4b - Deploying to main from @ amaranth-lang/amaranth@04f906965a9ebc9173951c96fa0c8b67ef090a79 🚀
<_whitenotifier-b>
[amaranth] github-merge-queue[bot] created branch gh-readonly-queue/main/pr-967-04f906965a9ebc9173951c96fa0c8b67ef090a79 - https://github.com/amaranth-lang/amaranth
<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] e683441 - Deploying to main from @ amaranth-lang/amaranth@4bfe2cde6f7b6806dec4c99dfc161c47307adc29 🚀
<_whitenotifier-b>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] caac714 - Deploying to main from @ amaranth-lang/amaranth@c6000b10972f40d0b1e160a770fe8e8c5d4aad4b 🚀
<whitequark[cis]>
down to only 3 open issues in the milestone (soon to be 2), only two requiring meeting time, and only one potentially requiring an RFC
<whitequark[cis]>
actually i can't count, that's 4, down to 3
cr1901 has quit [Read error: Connection reset by peer]