<whitequark[cis]>
lyxicon: thanks for your comments! we do need feedback in the design process of this feature from people with industry DSP experience, so this very much helps
mcc111[m] has joined #amaranth-lang
<mcc111[m]>
Possibly-weird question: is there any sense in which subtracting a constant value is more, or less, expensive than adding a constant value?
<whitequark[cis]>
two's complement means the two operations are the same
<whitequark[cis]>
or rather, wraparound arithmetics does, of which two's complement is one kind of
<mcc111[m]>
i guess i was wondering if there's any sense in which in hdls adding a large value is more expensive than adding a small value
<mcc111[m]>
if it is constant. i know how to make an adder but i don't know if you can cheat if you're adding a constant
<whitequark[cis]>
adding a large value can actually be cheaper
<whitequark[cis]>
since you don't need to drag the carry chain to all the low bits
<mcc111[m]>
since if we're in 2's compliment, then subtracting one is essentially a large value
<mcc111[m]>
s/a/adding/
<whitequark[cis]>
but in this case "large" means "with lots of trailing 0's"
<mcc111[m]>
ok
<whitequark[cis]>
meanwhile neither 1 nor 1111..1 have lots of trailing zeroes
<mcc111[m]>
yeah
<mcc111[m]>
Next absurd question: Is there in any sense a cost difference between rotating and shifting, or in general some version of rotate/shift equivalent to "i don't care what you put for the rotated-in bit"
galibert[m] has joined #amaranth-lang
<galibert[m]>
Fixed or variable?
<mcc111[m]>
Fixed. Say I have a register I'm "consuming" 1 bit at a time and then shifting it each time I consume a bit so the new bit is at the [0] position. As far as I know that's the "best" way to iterate over a large binary string in hdl. What's the best practice if I am in some other way counting how many bits I've consumed, and therefore I don't care what happens when I've cycled every bit in the register out?
<whitequark[cis]>
shifting always by 1 position (whether you feed anything back or not) is essentially free
<galibert[m]>
Fixed is muxing between the current bit and the previous using the do I shift now bit
<whitequark[cis]>
(it's probably going to be mapped to a DFFE on a modern FPGA and not a mux)
<galibert[m]>
If you shift in zeroes, it’s muxing between current and zero on the bottom bit which is less expensive in theory but not significantly so
<galibert[m]>
Catherine: depends on how many enable lines you have but you’re usually correct
<whitequark[cis]>
i know that mcc is working with massive (100s+ of bits) shift registers
<galibert[m]>
Cv only has two enable lines per lab tile and dedicated looping routing
<whitequark[cis]>
so that would probably qualify as a global signal all on its own
<galibert[m]>
So the tradeoff is not 100% obvious
<whitequark[cis]>
usually the toolchain can make an informed decision about whether to map something to enables or to a mux
<galibert[m]>
Hopefully:-)
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
tarmoo has joined #amaranth-lang
<mcc111[m]>
Ok thanks
tarmoo has quit [Client Quit]
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
lf has quit [Ping timeout: 264 seconds]
lf_ has joined #amaranth-lang
lyxicon has quit [Ping timeout: 250 seconds]
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
Degi has quit [Ping timeout: 264 seconds]
Degi has joined #amaranth-lang
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
nyanotech has quit [Remote host closed the connection]
nyanotech has joined #amaranth-lang
tarmoo has joined #amaranth-lang
tarmoo has quit [Remote host closed the connection]
nelgau has joined #amaranth-lang
nelgau has quit [Read error: Connection reset by peer]
nelgau has joined #amaranth-lang
skipwich has quit [Quit: DISCONNECT]
skipwich has joined #amaranth-lang
nelgau_ has joined #amaranth-lang
nelgau has quit [Read error: Connection reset by peer]
nelgau_ has quit [Read error: Connection reset by peer]
nelgau has joined #amaranth-lang
nelgau has quit [Read error: Connection reset by peer]
nelgau has joined #amaranth-lang
nelgau has quit [Read error: Connection reset by peer]
<cr1901>
In addition, native takes 12m22s... so ~87-90% of native. Not bad at all
<cr1901>
Not really ready for inclusion, but it works.
notgull has quit [Ping timeout: 260 seconds]
tarmoo has joined #amaranth-lang
tarmoo has quit [Client Quit]
phire has quit [Ping timeout: 260 seconds]
<cr1901>
I probably won't be here for the meeting- did not sleep well at all and need some (I'm on nite owl time a bit lately). Assuming #36, #40, #41 are being discussed, #36 and #40 look fine, and I'll catch up w/ new feedback for #41.
<whitequark[cis]>
good evening everyone, it is time for our regularly scheduled Amaranth language meeting
<whitequark[cis]>
who is attending?
<zyp[m]>
I'm here
zyp[m] has joined #amaranth-lang
jfng[m] has joined #amaranth-lang
<jfng[m]>
o/
Chips4MakersakaS has joined #amaranth-lang
<Chips4MakersakaS>
o/
* anuejn
is here
<anuejn>
although I will not make it for the whole meeting :/
<whitequark[cis]>
all right. today we have three RFCs on the agenda, though we may only have time for two
<whitequark[cis]>
please respond with your comments or proposed disposition: merge or close
<whitequark[cis]>
re: unresolved question, it does seem useful to have Memory.width, mainly because it is something that is important for many synthesis targets in and of itself, eg for BRAM inference you care whether your memory is bigger than 16/18 bits
<whitequark[cis]>
so I think we should probably keep it as a read only accessor, delegating to Shape.cast(self.shape).width
<whitequark[cis]>
and document as such
<Wanda[cis]>
it's going to be a merge from me
<Wanda[cis]>
though there are some details I'm still thinking about
<Wanda[cis]>
granularity is an interesting question
<whitequark[cis]>
I am 100% on board with extending this to FIFOs too
<Wanda[cis]>
though this may be more of future possibilities stuff
<Wanda[cis]>
... okay, I think the RFC is good as is tbh
<anuejn>
merge for me
<whitequark[cis]>
for granularity, I wanted conservative treatment that we can extend later, because I think it is bad if you can easily tear a eg record apart
<galibert[m]>
Hi
<whitequark[cis]>
I think it would also work if you required an ArrayLayout if you specify granularity, but zyp opposed that for a reason I don't quite recall
<Wanda[cis]>
hm
<Wanda[cis]>
interdependencies?
<whitequark[cis]>
galibert: hi. just so we're clear: when you don't respond to roll call I don't put your RFCs on the agenda, because I think RFCs should not be discussed *in absentia*
<galibert[m]>
Catherine: Sure, no problem with that
<Wanda[cis]>
also, I have to leave rather quickly now; what are the other RFCs on the agenda so I can have a quick look?
<Chips4MakersakaS>
From the other side 32-bit processors most of the time expect to use 8-bit granularity.
<galibert[m]>
I just arrived in any case
<jfng[m]>
merge
<whitequark[cis]>
Wanda: 41
<whitequark[cis]>
I think it needs discussion rather than voting, at this time
<whitequark[cis]>
Wanda: > We'd end up with a bunch of special casing for lib.data that's not necessarily even correct. (about RFC 40's granularity treatment)
<Wanda[cis]>
oh.
<Wanda[cis]>
I see
<zyp[m]>
I'm not opposed to allowing granularity to work with lib.data shapes
<whitequark[cis]>
I'm happy just making whoever is putting structured data into FIFOs to do some manual conversions for granularity
<whitequark[cis]>
either for the time being or indefinitely
<Wanda[cis]>
memories, not FIFOs
<Wanda[cis]>
FIFOs have no meaningful granularity, right?
<Chips4MakersakaS>
So is it supposed that CPU cached would still use width specification and not shape ?
<Chips4MakersakaS>
* caches
<galibert[m]>
cpu caches transfer whole lanes usually, no?
<zyp[m]>
I figure the most general noncontroversial lib.data support would be to require that no fields in a layout spans a granularity boundary
<Wanda[cis]>
okay I don't think I can come quickly to any conclusion on RFC 41
<Wanda[cis]>
so uh
<Wanda[cis]>
I'll be leaving now
<zyp[m]>
RFC 41 has a bunch of open discussion points
<jfng[m]>
@galibert:matrix.org they may access their internal memories with a smaller data width, for efficiency reasons
<whitequark[cis]>
Chips4Makers (aka Staf Verhaegen): memories and FIFOs would probably use structured data as a shape when you're working with DSP for example, or shuffling pixels around
<whitequark[cis]>
for something as general purpose as a cache I expect you would just have unsigned(x) shap[e
<whitequark[cis]>
s//`/, s//`/, s/shap[e/shape/
<galibert[m]>
jfng: you'd put a cache between an internal memory (which usually works at core clock speed) and the execution core?
<whitequark[cis]>
zyp[m]: this can still be unsound sometimes, like when you're transferring tagged enums
<Chips4MakersakaS>
Typically these caches are 32-bit or 64-bit but need to have 8-bit granularity during write if you want to avoid read-modify-write cycles.
<whitequark[cis]>
it's unclear how much we should or could enforce here but I do think that just slapping granularity on top of arbitrary data is wrong
<whitequark[cis]>
I don't know what is right
<Chips4MakersakaS>
How to specify WritePort then ?
<jfng[m]>
Chips4MakersakaS: ^
<whitequark[cis]>
Chips4Makers (aka Staf Verhaegen): you can still use granularity if the type of your memory is just `unsigned(32)` like it is currently
<zyp[m]>
whitequark[cis]: I'm happy to only allow granularity on plain unsigneds for now
<whitequark[cis]>
ie there is no reduction in functionality
<Chips4MakersakaS>
Sure but there is mismatch between using shape for Memory and width for WritePort.
<Chips4MakersakaS>
No ?
<whitequark[cis]>
no, we always use shape, it's just that your granularity cannot be smaller than the entire width unless your shape is unsigned(x)
<jfng[m]>
and support for granularity with ArrayLayout shapes would be added in a later RFC ?
<zyp[m]>
we could add ArrayLayout now, and leave structs for later if anybody wants it
<zyp[m]>
I'm happy either way
<jfng[m]>
arraylayout support would look good with the proposed syntax for initializing memories, so i'm in favor of it
<zyp[m]>
I mean granularity support for ArrayLayout
<jfng[m]>
yeah, i was expressing preference
<zyp[m]>
okay, then my disposition is merge with addition of granularity support for ArrayLayout
<whitequark[cis]>
I'm happy with that
<Chips4MakersakaS>
and unsigned(x)
<Chips4MakersakaS>
Also happy with that.
<galibert[m]>
unsigned (x) is already in there I think
<zyp[m]>
it is
<galibert[m]>
"WritePort.init() raises an exception if granularity is specified and shape is not an unsigned Shape"
<Chips4MakersakaS>
> unsigned (x) is already in there I think
<Chips4MakersakaS>
Yeah, sorry overlooked.
<Chips4MakersakaS>
* > unsigned (x) is already in there I think
<Chips4MakersakaS>
Yeah, sorry overlooked.
<whitequark[cis]>
all right, disposition on RFC 40: merge, incorporating support for specifying granularity for ArrayLayout
<whitequark[cis]>
actually, hold on
<zyp[m]>
and we're also keeping Memory.width then?
<whitequark[cis]>
I think we can't do that, memory lives in hdl and hdl can't depend on lib
<whitequark[cis]>
I had an idea to put memory in amaranth.lib.mem or something but until we do that I think we can't add support for lib.data types there
<whitequark[cis]>
and yeah, keeping Memory.width as a read only wrapper
<whitequark[cis]>
we could do a deprecation cycle for width= setter but I think it's not worth the hassle
<zyp[m]>
whitequark[cis]: setter? as in the `Memory.width` attribute or the constructor argument?
<whitequark[cis]>
attribute
<whitequark[cis]>
right now nothing stops you from changing width of an existing memory
<zyp[m]>
hmm, I looked at the code, and that's the sort of thing that's possible but not a very good idea
<galibert[m]>
Catherine: that's cursed
<whitequark[cis]>
yes
<whitequark[cis]>
which is why I think we should just remove that
<whitequark[cis]>
same for depth, it could go in the same implementation PR
<zyp[m]>
agreed
<galibert[m]>
yeah, hope nobody noticed :-)
<whitequark[cis]>
since that would break assumptions in the init setter
<jfng[m]>
i don't think this would need a deprecation cycle, as changing width is really not an intended use-case; and quite cursed imo
<jfng[m]>
so just putting it in a read-only property should do it
<whitequark[cis]>
you can even do that with signals
<whitequark[cis]>
and amaranth makes use of it internally
<whitequark[cis]>
(in the FSM generator)
<whitequark[cis]>
it doesn't even have to, I guess I just felt particularly cursed that day. someone should refactor it to not do that, it is trivial in context (maintain a map of an ongoing signal for every required state and then set them all when you exit the scope)
<jfng[m]>
uhh, i guess the keyword here is "internally", right ?
<whitequark[cis]>
it's not really a legitimate use of the api even internally
<whitequark[cis]>
however nothing prevents you from doing it externally too, right now
<whitequark[cis]>
Signal.shape is a publicly writable property
<whitequark[cis]>
ok, we are almost out of time, I will now conclude the meeting
<whitequark[cis]>
thank you everyone, it was a very productive one
<_whitenotifier-3>
[amaranth-lang/amaranth-lang.github.io] whitequark c049efd - Deploying to main from @ amaranth-lang/rfcs@e019bdb8d425485df6c719ea2d1574515e3b59e4 🚀
<_whitenotifier-e>
[amaranth-lang/amaranth-lang.github.io] whitequark 99d935b - Deploying to main from @ amaranth-lang/rfcs@e10875bca9bf43e43f422da60fdac2bc5086bc23 🚀
<_whitenotifier-3>
[amaranth-lang/amaranth-lang.github.io] github-merge-queue[bot] 4c1d9fc - Deploying to main from @ amaranth-lang/amaranth@0ea2aa6b69eb94deed1285da2532e272dd897743 🚀