ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at https://github.com/nmigen · logs at https://freenode.irclog.whitequark.org/nmigen
<whitequark> ugh
<whitequark> writing docs made me realize how much of a misnomer Signal(reset=) is
<whitequark> especially the comination of reset= and reset_less=True
<whitequark> we should rename reset= to init= or something
<anuejn> yup, nice :)
<whitequark> it's one of the more annoying deprecations
<whitequark> that one might even have to stay for a few release cycles
<anuejn> would probably be good
<whitequark> also we should warn on reset_less comb signals
<whitequark> what's the opposite of reset-less?
<whitequark> non-reset-less?
<cr1901_modern> reset-more
<whitequark> sigh. resettable
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
<awygle> init and reset are technically distinct though
<awygle> although we might not want to support that case
<tpw_rules> "reinit_on_reset"?
<whitequark> awygle: i don't think they are
<whitequark> well
<whitequark> there are four cases we can have
<whitequark> 1. a comb signal is never assigned, retains `init` value
<whitequark> 2. a sync signal has `init` value at power on
<whitequark> 3. a sync signal assumes `init` value at domain sync or async reset
<whitequark> 4. a sync signal assumes `init` value at `ResetInserter()` caused reset
<whitequark> treating (2) and (3) seems like it would make some sense in some corner cases but it is actually semantically hazardous
<whitequark> *treating (2) and (3) differently
<whitequark> i think the most concise way i can explain it is that "power on reset state should be reachable"
<whitequark> here are two relevant insightful comments: https://github.com/nmigen/nmigen/issues/270#issuecomment-578783349
<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
<whitequark> and python doesn't have vectors
proteus-guy has quit [Ping timeout: 240 seconds]
proteus-guy has joined #nmigen
Degi has quit [Ping timeout: 260 seconds]
Degi has joined #nmigen
proteus-guy has quit [Ping timeout: 260 seconds]
proteus-guy has joined #nmigen
nengel has quit [Ping timeout: 260 seconds]
nengel has joined #nmigen
____ has joined #nmigen
____ has quit [Quit: Nettalk6 - www.ntalk.de]
SpaceCoaster has quit [*.net *.split]
kbeckmann has quit [*.net *.split]
____ has joined #nmigen
SpaceCoaster has joined #nmigen
kbeckmann has joined #nmigen
chipmuenk has joined #nmigen
chipmuenk has quit [Quit: chipmuenk]
chipmuenk has joined #nmigen
____2 has joined #nmigen
____ has quit [Ping timeout: 240 seconds]
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
Asu has joined #nmigen
Asu has quit [Remote host closed the connection]
Asu has joined #nmigen
<_whitenotifier-9> [nmigen] whitequark opened issue #378: Add shift left/right by constant amount - https://git.io/JfGDc
<_whitenotifier-9> [nmigen] whitequark edited issue #378: Add shift left/right by constant amount - https://git.io/JfGDc
<_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!
<Sarayan> Yeah, that works too
<Sarayan> sometimes it feels like embedded ha become "add an arm core and do it in software"
<Sarayan> has
<zignig> I would like an opinion on a minimal construct...
<whitequark> zignig: try this for a debouncer (untested): https://paste.debian.net/1145089/
<zignig> whitequark: oooh, thanks :)
<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> ZirconiumX: so, it becomes a problem if you're trying to extend something and then stuff it into a Cat() or something like that
<Sarayan> wq: indeed, that shouldn't be too expensive
<Sarayan> (as in, not expensive at all)
<_whitenotifier-9> [nmigen] whitequark commented on issue #381: [RFC] Add a (more) general shape conversion operator - https://git.io/JfZf4
<ZirconiumX> I suppose another question I have is whether my "use case" is right or not.
<Sarayan> I need to remember Cat, it looks extremely useful
<ZirconiumX> meow
<Sarayan> yeah yeah, you look useful too *pets ZX*
<whitequark> Sarayan: the main gotcha is that Cat follows the Python sequence semantics
<whitequark> so it's like Cat(lsb, ..., msb)
<Sarayan> oh fuck yeah, that's a huge gotcha
* ZirconiumX purrs
<ZirconiumX> Sarayan: ^
<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
<agg> a.as_signed().extend(16); b.as_unsigned().extend(16);
<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
thinknok has joined #nmigen
chipmuenk has quit [Quit: chipmuenk]
Asuu has joined #nmigen
Asuu has quit [Client Quit]
Asuu has joined #nmigen
Asu has quit [Ping timeout: 260 seconds]
____2 has quit [Quit: Nettalk6 - www.ntalk.de]
thinknok has quit [Ping timeout: 272 seconds]
<awygle> oh wow i'm failing timing
<awygle> how can i figure out why?
<awygle> (ECP5)
<whitequark> nextpnr?
<awygle> yup
<whitequark> well you're kind of screwed
<awygle> aww
<ZirconiumX> It prints out the longest path as a hint
<whitequark> you can hope that synthesis has left some traces of the HDL names on the critical path
<whitequark> it usually sort of does
<awygle> ERROR: Max frequency for clock '$glbnet$cd_sync_clk100_0__i': 80.81 MHz (FAIL at 100.00 MHz)
<awygle> is all i am currently seeing
<ZirconiumX> nmigen.build?
<whitequark> oh
<whitequark> build with NMIGEN_verbose=1
<awygle> oh that's a lot more useful. thanks.
<ZirconiumX> Doesn't it write the log to a file you can examine though?
<whitequark> yep
<awygle> turns out SyncFIFO (unbuffered) makes meeting timing challenging, whodathunk
<whitequark> that should have lowered your FIFO buffer to flops
<whitequark> unless it's non-fwft.
<awygle> uhh i think it was fwft
<awygle> that's the default right?
<whitequark> yeah
<whitequark> just use SyncFIFOBuffered
<awygle> then yes they were all fwft
<awygle> SyncFIFOBuffered is _not_ fwft, right? or is it always fwft...
* awygle checks help
<awygle> ah it's always fwft
<awygle> that's easy then
<whitequark> there's only one non-fwft fifo in nmigen.lib and tbh there should probably be 0
<awygle> okay great, it builds and programs! and doesn't at all respond to any of my input but still, progress
<whitequark> neat
Asuu has quit [Ping timeout: 272 seconds]