<whitequark>
that is: if we have reset_less signals at all, then once the domain with those signals comes out of reset, it can find itself with nondeterminitic values in those registers, but it would be at least some state reachable from power on
<awygle>
In theory you can have a register which has value 0 at power on, but which resets to 1
<whitequark>
yes, you can have that in the sense that you can synthesize it
<whitequark>
what i'm saying is that this has an effect of making the power-on reset state special in a second distinct way
<awygle>
Yes it does. As I said we may find it undesirable
<whitequark>
right
<whitequark>
my "i don't think they are" would be more correctly phrased as "they are, and so is ResetInserter() caused reset"
<awygle>
Offhand isn't that how AsyncFFSynchronizer works?
<whitequark>
oh?
<awygle>
Oh I guess not necessarily actually
futarisIRCcloud has joined #nmigen
grant72 has quit [Quit: Connection closed for inactivity]
<whitequark>
how do you call an operator that's like bitwise but it's not pairwise
<whitequark>
e.g. value slicing
<whitequark>
bit vector? bit collection?
<awygle>
bit vector
<whitequark>
hmm
<whitequark>
i'm not entirely sure because nmigen values *do* behave like python collections
<_whitenotifier-9>
[nmigen] whitequark opened issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfGyO
cr1901_modern1 has joined #nmigen
electronic_eel has quit [Remote host closed the connection]
cr1901_modern has quit [Ping timeout: 246 seconds]
electronic_eel has joined #nmigen
<_whitenotifier-9>
[nmigen] whitequark opened issue #380: Emit a diagnostic when parentheses are omitted in logical expressions with comparisons - https://git.io/JfGya
* zignig
is looking for a minimal button deboucer in nmigen, has anyone seen one ?
<zignig>
*debouncer
<Sarayan>
add a riscv core and write it in Rust and compile it? ;-)
<zignig>
Sarayan: perhaps , I am working on some tooling. I have a nmigen_board templater and a Boneless SOC working.
<zignig>
I just need buttons and switches for completeness.
<whitequark>
it's just a single timer
<zignig>
whitequark: hey.
<zignig>
whitequark: after spending time pestering you for things about boneless, I have spent some time building some tooling.
<whitequark>
hi
<Sarayan>
It was not supposed to be taken seriously damnit :-)
<zignig>
it's nearly working, it templates nmigen_boards and I have a working boneless SOC.
<zignig>
Sarayan: sorry, how about BLBLBLBLBLBBL! BLAG!
<whitequark>
zignig: i'm not sure what you're doing with those templates. in general, i try to avoid generating python code if i can avoid it
<whitequark>
is it supposed to be human editable?
<zignig>
nope , it's a initial generation tool, for making a base repository.
<whitequark>
ah ok
<whitequark>
seems fine then
<zignig>
nice ;) ; about 2 more days of coding (I am on a roll) and it may be ready.
<zignig>
Sarayan: what are _you_ working on at the moment ?
* zignig
finds vimself with lots of free time for now.
cr1901_modern1 has quit [Quit: Leaving.]
cr1901_modern has joined #nmigen
futarisIRCcloud has joined #nmigen
<_whitenotifier-9>
[nmigen] whitequark opened issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfGQv
alexhw has quit [Ping timeout: 272 seconds]
<_whitenotifier-9>
[nmigen] ZirconiumX commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfGhq
* zignig
has changed m-labs to nmigen in the updated readme, whoops; old doc.
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfGje
<ZirconiumX>
whitequark: you might want to proof-read your comment a little, you have "However, if it turns out that everyone intuitively understands v.extend(signed(32)) the same way you do," without a followup
<whitequark>
uh, moment
<whitequark>
fixed
<_whitenotifier-9>
[nmigen] whitequark edited a comment on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfGje
<_whitenotifier-9>
[nmigen] ZirconiumX commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZe2
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZep
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZvB
<_whitenotifier-9>
[nmigen] awygle commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZv0
<ZirconiumX>
I feel like I've accidentally destroyed the type system of nMigen and I'm not sure how to feel about that
<_whitenotifier-9>
[nmigen] awygle edited a comment on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZv0
<awygle>
lol what'd you do?
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZv2
<ZirconiumX>
awygle: Well, if things are considered signed/unsigned at point of use, it makes little sense - to me - for the language to distinguish signedness at declaration
<awygle>
i agree with that
<ZirconiumX>
I have literally never used the signed keyword in Verilog other than in tests
<awygle>
i agree with that too
<whitequark>
i have
<whitequark>
i won't do it again because it's so horrendously broken
<awygle>
i kind of think about it like assembly - there's no "signed register", there's ADD and ADDU
<whitequark>
working signed arithmetics has been a design goal of original Migen, and nMigen too
<ZirconiumX>
And I can appreciate that, but...I just don't use it
<_whitenotifier-9>
[nmigen] programmerjake commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZvy
<ZirconiumX>
I dunno, maybe I have a limited perspective here
<whitequark>
it's rarely useful other than in DSP code
<awygle>
working signed arithmetics doesn't necessarily require a signed signal type
<whitequark>
hmm
<whitequark>
having signed signals is an artifact of having signed shapes
<awygle>
i do see how it might be very convenient though. this feels a lot like the various rust discussions around integer conversion lol
<whitequark>
and signed shapes are necessary if you're not ready to do something like `+` and `add_signed` as separate functions
<ZirconiumX>
whitequark: So, why doesn't the workaround syntax of `[:width]` for truncation guarantee a value with width `width`?
<whitequark>
because [:width] works like python collections do
<whitequark>
>>> (0,0,0,0)[:5]
<whitequark>
try it
<whitequark>
plus if you're truncating the sign bits you get an unsigned value which is obnoxious
<Sarayan>
well, sign-extension is nice to have, and so is partially or fully signed multiplication
<_whitenotifier-9>
[nmigen] whitequark commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZvA
<whitequark>
you also probably need it for DSP inference?
<Sarayan>
probably
<whitequark>
ZirconiumX: awygle: really, the main argument in favor of signed shapes isn't even any of this
<whitequark>
it's just that currently nMigen promises that all intermediate results (anything you compute without assigning to a Signal) match exactly what Python would compute
<awygle>
mmmmm
<whitequark>
which is how it justifies the fact that it overloads all the numeric operators
<whitequark>
similarly to how it justifies the fact that it overloads the collection operators by acting like a proper collection
<Sarayan>
btw, something I'm going to eventually need, if there a way to build flags like V on addition using + or do you have to do (part of?) the addition by hand
<ZirconiumX>
<whitequark> because [:width] works like python collections do <-- is this actually a problem in practice? Thinking of generic code, something which is less than width would be extended as necessary
<Sarayan>
V = carry between the two top bits xor carry out of the top bit
<ZirconiumX>
But then don't you just need to examine those bits?
<whitequark>
Sarayan: you can grab the carry out with Cat()
<whitequark>
Cat(r, co).eq(a + b + ci)
<whitequark>
ZirconiumX: I don't know, but it seemed like a notable omission to me
<Sarayan>
Didn't know about Cat, would have used an intermediate signal, very nice
<Sarayan>
but V also needs the carry between bit 30 and 31 say
<whitequark>
yeah you compute that one manually
<Sarayan>
Won't that make mapping on the fpga carry chains unreliable?
<Sarayan>
but I guess it's just not there in the $add mofules
<whitequark>
there's a trick
<Sarayan>
modules
<whitequark>
nop
<ZirconiumX>
Notable, perhaps, but the extension of values means that it shouldn't matter in practice. I dunno, I don't consider it a problem yet
<whitequark>
Sarayan: Verilog has a similar construct that's like {msb, ..., lsb}. MyHDL implements *that* on top of Python, for example
<whitequark>
but... you can't legally do tht
<whitequark>
either your values violate Python invariants for sequences, or you end up with msb at index 0
<Sarayan>
how come your paste works then?
<Sarayan>
(does it?)
<whitequark>
if you use a pattern like "001" then it works the same way. "lsb ... msb"
<whitequark>
so Case("001") and Case(0b100) are the same thing
<Sarayan>
ohhhh, two gotchas neutralizing each other
<whitequark>
it makes more sense if you think of nmigen values as *primarily* bit sequences
<whitequark>
like all other sequences we write those left to right
<whitequark>
and then the "gotcha" is that we write numbers right to left contrary to everything else
<Sarayan>
I love the 68000, fuck lsb first, etc :-)
<Sarayan>
in fact (n)migen is racist against arabs
<Sarayan>
or, well, the arabic language
<Sarayan>
(but yeah, it's complicated)
<ZirconiumX>
It uses Arabic numerals though :P
<whitequark>
i *think* actually if you wrote your python scripts in arabic then the orders would actually match
<_whitenotifier-9>
[nmigen] programmerjake commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZfV
<whitequark>
since both the numbers and the sequences would be RTL
<Sarayan>
yeah
<Sarayan>
you'd even get assignments in lambdas I'm sure ;-)
<_whitenotifier-9>
[nmigen] whitequark commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZfo
<ZirconiumX>
A signed shape `.to_signed` is a no-op, right? I have a very dumb idea.
<whitequark>
yeah, <signed value>.as_signed() is a complete no-op
<awygle>
wow step out for a minute and we're writing in arabic
<Sarayan>
?naem uoy cibara ni
<_whitenotifier-9>
[nmigen] programmerjake commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZfF
<_whitenotifier-9>
[nmigen] ZirconiumX commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZfN
<ZirconiumX>
I feel unclean for writing this suggestion
<agg>
ZirconiumX: what happens if the user doesn't call .as_signed() or .as_unsigned() afterwards? it just keeps the shape of the original input?
<ZirconiumX>
"If possible we can mitigate the gotcha of sign_extend on an unsigned value returning unsigned by linting on it not having an explicit signedness."
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZfj
<ZirconiumX>
I covered that ;)
<agg>
a = Signal(signed(8)); b = Signal(unsigned(8)); x = a.zero_extend(16); y = b.sign_extend(16);
<agg>
so those ^ "normal" usages would all do the expected thing without warning?
<agg>
why not write "a.as_signed().sign_extend(16)" and refuse to sign_extend an unsigned?
<agg>
I see wq beat me to that latter point on gh
<whitequark>
yeah
<agg>
certainly having sign_extend() and zero_extend() seem very clear in what they'll do to the input, and my assumption would be that they don't change the type of the output
<agg>
but it's probably always wrong to sign_extend an unsigned or zero_extend a signed, right?
<ZirconiumX>
Okay, so it seems like the right behaviour here should be to error on sign-extending an unsigned value, or zero-extending a signed value
<whitequark>
i'm thinking of it this way:
<agg>
(thank goodness trunc() is unambiguous)
<agg>
ZirconiumX: of course at that point you could just have extend() ;)
<whitequark>
suppose we had .sign_extend() that could work on unsigned values, then we'd need to add a lint to catch this case
<whitequark>
what would the lint tell you to do if it's a false positive? it'd tell you to do .as_signed().sign_extend()
<whitequark>
so we might as well just require that in first place
<agg>
agreed
<agg>
but if sign_extend requires a signed input, and zero_extend requires an unsigned input, can we just have extend() and do the relevant operation depending on input type?
<ZirconiumX>
<agg> a.as_signed().extend(16); b.as_unsigned().extend(16); <-- I'm not happy with the semantic overload here.
<agg>
that's fair
<agg>
i do like the clarity of zero_extend and sign_extend
<agg>
having them only accept the relevant input type seems fine when it's so quick to swap it
<_whitenotifier-9>
[nmigen] ZirconiumX commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZJ3
<whitequark>
how often do you want to be generic over signedness?
<_whitenotifier-9>
[nmigen] ZirconiumX edited a comment on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZfN
<agg>
i don't remember wanting to be generic over it
<ZirconiumX>
But you are, if the behaviour of .extend depends on signedness
<agg>
but what if you want to be generic over signedness? you'll have to do if x.is_signed(): x.sign_extend(n); else: x.zero_extend(n)
<agg>
could we have all three?
<ZirconiumX>
And so in this case the argument of sign/zero extend would ignore the signedness of the shape
<ZirconiumX>
That should be a lint, right?
<ZirconiumX>
e.g. sign_extend(signed(32)) is a bit meaningless
<agg>
it would be such an unhelpful lint if it fired depending on runtime type
<agg>
I mean, in code deliberately generic over type
<whitequark>
yep
<ZirconiumX>
I was referring to passing an explicit signedness object to sign/zero extend
<ZirconiumX>
Mm, I guess it would get annoying
<whitequark>
a shape is more than the sum of its two fieldsd
<agg>
seems like sign_extend and zero_extend could both take just a width, not a shape
<agg>
and error if operating on inputs that are the wrong type
<ZirconiumX>
The point of taking a shape is, for example, to cast to the inferred shape of an enum
<whitequark>
yeah but maybe that's a bad idea in first place
<whitequark>
what would you sign extend to a enum's shape?
<whitequark>
and why?
<ZirconiumX>
Fair point.
<whitequark>
you can of course always do .sign_extend(Shape.cast(SomeEnum).width) anyway
<whitequark>
which isn't that bad.
<agg>
yea, that doesn't seem that steep a price to pay for a very rare use case
<agg>
likewise if you are writing code that's intentionally generic over signed/unsigned it's not that hard to wrap zero_extend and sign_extend
<ZirconiumX>
This sounds like Prop 1 with some bikeshedding about function names
<agg>
you can just write your own extend() method that checks the type and calls the relevant operation
<agg>
ZirconiumX: the key difference is prop1 just has extend(n) which is zero/sign depending on type
<whitequark>
i mean, arguably, you can just write your own .sign_extend(), because it lowers to a Cat() and Repl() anyway
<whitequark>
the point of having these on values is that it would prevent people from writing their own, buggier versions
<whitequark>
but
<ZirconiumX>
I think that in itself is a good reason
<whitequark>
`x.sign_extend(y) if x.shape().signed else x.zero_extend(y)` is really hard to screw up
<whitequark>
(incidentally, one thing we could make .truncate do is to emit a formal assertion that all the truncated bits were the same)
chipmuenk has quit [Ping timeout: 244 seconds]
<agg>
and if someone wanted to just ignore the higher bits they should be using the slice/index operations?
chipmuenk has joined #nmigen
<whitequark>
if someone wants to just ignore the higher bits they shouldn't be using *arithmetic casts*, yes
<agg>
makes sense
<whitequark>
if sign/zero extend doesn't lose information, why should truncate?
<ZirconiumX>
It...seems we have a consensus?
<ZirconiumX>
Or at least, something worth treating as another proposition?
<_whitenotifier-9>
[nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZUf
<whitequark>
yup
<awygle>
i am a bit iffy on the formal assertion bit
<awygle>
but ok
<awygle>
i guess to drop bits you use .bit_slice(n) or whatever
<whitequark>
[:n]
<awygle>
(which maybe would be a good thing for the assertion to mention, if that's possible, in simulation)
<whitequark>
i'm not completely certain about the assertion yet
<whitequark>
i don't think we have the infra to report simulation errors with source locations
<whitequark>
and it's not clear how to build it yet
<_whitenotifier-9>
[nmigen] whitequark commented on issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfZUb
<_whitenotifier-9>
[nmigen] whitequark closed issue #379: Emit a diagnostic if a `reset_less` signal is found driven from comb domain - https://git.io/JfGyO