ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at · logs at · IRC meetings each Monday at 1800 UTC · next meeting TBD
<_whitenotifier> [YoWASP/nextpnr] whitequark pushed 1 commit to develop [+0/-0/±2]
<_whitenotifier> [YoWASP/nextpnr] whitequark d9adbdb - Update dependencies.
lf has quit [Ping timeout: 260 seconds]
lf has joined #nmigen
<_whitenotifier> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1]
<_whitenotifier> [YoWASP/yosys] whitequark a2c7f01 - Update dependencies.
<smkz> what is EnableInserter and is it something i should use or not?
<tpw_rules> it lets you put an enable pin on some logic
<tpw_rules> i've never needed it
<mwk> smkz: take a module with a clock, take a clock enable signal, get an equivalent module with the clock enable applied everywhere the clock is used
<tpw_rules> ^
<mwk> it's done by recursively descending the AST and inserting clock enable at every endpoint though; not by actually gating the clock
<mwk> so it has the slightly annoying property of not working when manual instantiation of sync primitives is involved
<whitequark> that's an implementation detail, there is an open issue for introducing EnableSignal
<whitequark> which would fix that problem
<whitequark> that said, it will never actually gate the clock
<mwk> heh, would be nice to actually have first-class support for clock gating in yosys
<mwk> but yea, not happening anytime soon
<whitequark> yeah
<mwk> ... is clock gating one of those things that could be easy and portable if verilog actually had support for it
<whitequark> verilog technically does
<mwk> if I see `assign gated_clk = clk & ce` one more time I'm going to flip a table
<whitequark> in cxxrtl, i think i can recognize that idiom and turn it into a clock gate
<whitequark> i'm not yet sure though
<whitequark> and maybe it should not be done in cxxrtl
<mwk> I mean it's an invalid idiom in the first place
<mwk> if we ever recognize it, it should be to shout THIS IS NOT SUPPOSED TO BE DONE LIKE THIS, FIX IT
<whitequark> oh, right
<whitequark> i forgot it should be a latch
<whitequark> ... should it
<mwk> latch and a gate, I think? I don't remember, something like it
<whitequark> sigh
<mwk> plus of course this doesn't really work either if you want it to be in sync with the original clock
<whitequark> right, that's what i was thinking about
<whitequark> there was some sort of aggravating idiom where you'd use blocking assignment in a clocked always block
<mwk> like, the latch-gate is correct, as long as you don't care about the result being synchronous
<whitequark> but i can't recall it
<mwk> well yeah, getting simulation behavior is one thing, getting it synthesized correctly (and understood by timing analyzer down the line) is another
<mwk> hence I think doing it right would require new first-class primitives in yosys, which would effectively map to BUFGCE or whatever
<d1b2> <dub_dub_11> BUFGCE is global buffer with clock enable right? Do the tools actually use that to gate the clock rather than all the FFs, if you use EnableInserter? (Presumably doing so would save a lot of power from driving the clock tree)
<d1b2> <dub_dub_11> Or equivalently if you had in Verilog always@(posedge clk) begin if(enable) begin Logic end end
<whitequark> no, the tools very much do *not* do that
<whitequark> EnableInserter essentially turns DFFs into DFFEs (if this is deemed useful)
<d1b2> <dub_dub_11> Ah ok
<d1b2> <dub_dub_11> And the pnr won't recognise if every FF driven by a clock has the same enable signal, and gate the clock?
<whitequark> nope
<whitequark> and it should not, since that would change timings in ways you might not want
<whitequark> also, many FPGAs only have one BUFGCE in first place
<whitequark> (I'm not sure which Xilinx devices have only one but it's something I've noticed before)
<d1b2> <dub_dub_11> Oh okay
<d1b2> <dub_dub_11> I didn't realise it was actually a seperate resource either
<d1b2> <dub_dub_11> I thought it was like an input buffer where there can be different versions using the same primitive
<whitequark> it is also like that
<whitequark> there's a bunch of different cells that map to BUFG*, and the exact BUFG* that is present in your device varies from chip to chip
<d1b2> <dub_dub_11> Uh huh
<d1b2> <dub_dub_11> And is there usually a few BUFGs (but not with the CE)?
<whitequark> ask mwk
<mwk> it's, as usual, complicated
<mwk> before ultrascale, there is really no such primitive as BUFG/BUFGCE; there's BUFGMUX [on spartan] or BUFGCTRL [on virtex], which have BUFG/BUFGCE as special case uses, and it's all the same resource
<mwk> the number of those varies, but expect 8-32
<mwk> there is definitely no xilinx FPGA with only a single BUFGCE though; perhaps there is such a xilinx CPLD, I don't know
<mwk> and ultrascale... complicates things in multiple ways, having the clock enable part done in leafs instead, so while you still describe BUFG/BUFGCE to the toolchain, it doesn't really correspond to physical resources anymore, the buffers are kinda generated on the fly in the P&R stage
<mwk> and also it's the one that has multiple global buffer types; some are actual hardware BUGCEs, some are BUFGs without any clock gating, some are BUFGCTRL with lotsa features; the leaf clock-enables are in addition to that
<mwk> and then there's versal which complicates it even more by adding /2, /4 and /8 clock dividers on leafs, but eh
<whitequark> mwk: hang on, why does xilinx pnr tell me that it has BUFGCE 1/1 or something like that
<whitequark> it is just lying for some reason?
<mwk> huh
<mwk> what chip?
<whitequark> lemme try to reproduce
electronic_eel has quit [Ping timeout: 260 seconds]
electronic_eel has joined #nmigen
<_whitenotifier> [nmigen/nmigen-boards] whitequark pushed 1 commit to master [+0/-0/±1]
<_whitenotifier> [nmigen/nmigen-boards] whitequark 5c8c8ca - arty_s7: fix blinky built-in test.
<mwk> spartan7, eh? 16 BUFGCTRLs on the smallest device, 32 BUFGCTRLs on the others
<whitequark> no, that was just a bug i found
<whitequark> i don't think i've ever built anything for s7, my vivado is too old
<whitequark> mwk: wtf, no idea where i even took that
<whitequark> you are obviously right
<whitequark> i must have mixed it up with something else. my bad. sorry for misinformation dub_dub_11
emeb has left #nmigen [#nmigen]
<mwk> there are definitely non-xilinx fpgas with 1 of whatever the equivalent of BUFGCE is
<whitequark> yes, but i even checked ecp5
<whitequark> and that has... more than 1
<mwk> so we'd need resource management in yosys to choose upgrade-worthy ones
<mwk> if any
<whitequark> tbh resource management in yosys would be neat
<whitequark> if costly to maintain, perhaps
<mwk> but also: changing FF enables to clock gating can only happen for FFs with enable priority over reset
<sorear> what would "resource management" look like?
<mwk> or async resets
<mwk> sorear: well first of all we'd need a bigass database of FPGAs and their resource counts
<whitequark> which FPGAs have enable over reset?
<mwk> then we'd need some framework for passes to know how much headroom they have for a given resource
<mwk> taking into account weird stuff like resources being splittable, hierarchical designs (if you use a resource in module instantiated 10 times in hierarchy, it costs 10 times more etc)
<mwk> and also pre-instantiated primitives
<mwk> and then we'd need some heuristics
<mwk> ... and then there are annoying rules like "using a blockram with 32-bit width on spartan 3e actually also takes up a multiplier slot because input muxes are shared"
<whitequark> uhm
<whitequark> it what
<mwk> high 16 data bits of memory write port are also multiplier inputs for co-located MULT18X18*
<whitequark> sounds aggravating
<d1b2> <dub_dub_11> Ah np I had a scroll through the UG and found the bit about V5/7 series having one type of global clock resource and as always learnt lots along the way
<mwk> yep
<mwk> so anyway, yeah, resource management needs to happen
<mwk> ... at some point
<d1b2> <dub_dub_11> Also yes that sounds extremely aggravating
<mwk> but it's not trivial by any means
<whitequark> i feel like we should sort out the situation where i merge the most yosys PRs
<whitequark> first
<mwk> well it'd be easier if the, uh, event hadn't happened
<whitequark> that is indeed true
<mwk> I very much hope it's normalized soon
<whitequark> i am quite tempted to go to a certain country and break a few facial bones of a certain person
<mwk> same
<d1b2> <dub_dub_11> Oh no
<whitequark> anyway, at least we have a new maintainer for the verilog frontend
<mwk> I hoped to spend some effort on yosys this fall, but instead got myself trapped in a big screwup of uni work
<whitequark> for... a few months at least
<whitequark> probably not sufficient to replace the frontend with something sane, but maybe enough to make it less aggravating, and freeing me from the necessity to read that code for a while
<mwk> ... at this point either I get adhd meds and stabilize the situation or just quit that damn place
<mwk> I've had enough of being a fucking mess
<whitequark> from personal experience, i would recommend both, though it's up to you of course
<mwk> *shrug* the main problem wit that is that I tend to actually enjoy it when I'm not trapped in an anxiety/procrastination combo of having to actually prepare the classes
<whitequark> i see
<mwk> but yeah, it's not sustainable in the current configuration, something has to give
<mwk> and yeah, the new frontend maintainer is... well, an unexpected boon in shitty times
<mwk> at least for a while
<whitequark> i'm really impressed that he actually manages to understand it
<whitequark> no matter how much effort i sunk into it, i can not make sense out of genrtlil
<whitequark> save for the simplest parts
<whitequark> what sorcery is that!
<mwk> I... kinda think I understood it enough to make some simple fixes to it some time ago?
<mwk> but given the small surface of stuff I touched I'm probably very wrong about it
<whitequark> i mean, i understood it enough to shoehorn the $print cell in
<whitequark> but Zachary is fixing things like constant function expansion and some cursed memory-related width inference... stuff
<whitequark> in both of these cases i could not even identify the root cause
<mwk> ... right, memory changes
<mwk> gods, I need to get that branch finished and merged
<mwk> I shudder to think what will happen if I rebase it now, I haven't touched it for a month or two
<whitequark> there's been barely any changes for a month or two i think
<mwk> there were verilog frontend changes and lots of cxxrtl changes; my branch touches both
<whitequark> oh
<mwk> CONFLICT (content): Merge conflict in backends/cxxrtl/
<mwk> how surprising
<whitequark> that one is almost certainly benign
<mwk> nope
<whitequark> oh? what did i change?
<whitequark> i mean, memory code, yes, what in particular (you can just post the diff)
<whitequark> (with conflicts)
<mwk> I changed how signal initialization works
<whitequark> oh...
<whitequark> uh you really ought to rebase once is merged
<mwk> because adding initial memory read port values suddenly means that not just (*init*) on a wire can require an initialization
<whitequark> and i will do that soon, in that case
<whitequark> since that will move all of the signal init values from the class definition to the constructor or a function
<mwk> (it's a parameter on the $memrd cell)
<mwk> hm, alright
<mwk> okay, all the conflicts seem to be related to initial values, not bad
<mwk> oh wait, no
<mwk> fuck me
<mwk> it's just conflicts for the first patch on my branch, out of 11
<whitequark> :s
<mwk> *of course* it's only about initial calues
<mwk> anyway
<mwk> the main problem with getting my branch merged is uhh getting any sort of review for it
<whitequark> can i help?
<whitequark> i'm guessing no, but
<mwk> I mean I can self-approve my bugfixes and minor xilinx improvement, but I'd rather have actual design review for something that throws away a big portion of memory passes and replaces them with all-new stuff
<mwk> whitequark: I'd appreciate reviewing the general design
<whitequark> mwk: ack. let me go through my current backlog (might take a day or two) and i'll see what i can do
<mwk> the current status of the branch is: the data model changes are done, the missing part is the actual match-rams-to-blockrams pass, and transparency inference pass
<mwk> and there's one thing left in the model design that I'm unsure of, which is how to handle transparency
<whitequark> hm i might have useful input on that, actulaly
<mwk> as implemented now, it is: transparency (and write priority) only applies between sync ports that happen to have the exact same clock (same signal and polarity), if you have two clock signals that just so happen to have edges at the same time, we make no guarantees
PyroPeter_ has joined #nmigen
<mwk> also priority and transparency is stored per-port-pair
<whitequark> it would be nice to have it explicit so that e.g. nmigen could be sure exactly when transparency will apply
<mwk> priority can effectively be A first, B first, or undefined; transparency is either "always read old value" or "always read new value"
<mwk> and I'm wondering if I should change it to be "always read old value", "always read new value", "read X"
<whitequark> hm
PyroPeter has quit [Ping timeout: 256 seconds]
PyroPeter_ is now known as PyroPeter
<whitequark> "read X" mapping to "NO_CHANGE"?
<mwk> read X mapping to "do whatever the hardware supports with minimal effort"
<whitequark> what if i select "read X" and make sure that w_en xor r_en?
<whitequark> will that have the NO_CHANGE semantics?
<mwk> if w_en xor r_en, you will have NO_CHANGE semantics anyway
<mwk> transparency explicitely only matters if there is a possibility of collision
<whitequark> i mean, yosys might not know that w_en xor r_en
<mwk> that's what sat solvers are for
<whitequark> i'm trying to *avoid* inference
<whitequark> mhm
<mwk> I don't think it's possible for the body of extant Verilog code
<whitequark> oh certainly
<whitequark> i trust you that you'll consider what is necessary to handle extant verilog
<whitequark> my perspective is doing things for... better inputs
<mwk> the main memory inference pass will have a sat solver, and will use it in multiple scary ways
<whitequark> yes. i'm not trying to avoid it in general. i want to understand if nmigen can avoid it, or otherwise make sure the results have a hard guarantee
<whitequark> and see whether this desire can inform the design
<whitequark> (i do not have a hard requirement that nmigen never touches any sat parts)
<mwk> mhm
<whitequark> (it wouldn't make sense since it will often produce verilog anyways)
<mwk> so the main purposes of sat are as follows
<mwk> 1) you can have two write ports where one has priority over the other because it follows it in the same verilog block; sat can determine the enables are disjoint and drop the priority, allowing mapping to blockrams without defined write port priority (ie. most of them)
<mwk> 2) xilinx (and vendors that cribbed from them), allows you to have two configurations of r_en and w_en: either they are disjoint (NO_CHANGE), or w_en always implies r_en (READ_FIRST, WRITE_FIRST)
<mwk> before we merge a read port and a write port into a read/write port, we have to make sure one of the cases applies
<mwk> 2) is the main unavoidable part, it's simply not possible to infer a xilinx blockram with rw port without verifying this condition
<mwk> we could, in theory, require verilog code that makes the condition obvious, and somehow propagate that info from the frontend, but good luck with it
<whitequark> yep
<whitequark> ok, so neither of those really applies to nmigen, since it emits $memwr/$memrw explicitly
<mwk> 2) does
<whitequark> oh, there's no parameter?
<mwk> how would you write nmigen code that gets synthd to a single rw port?
<whitequark> mem.read_write_port() # does not exist yet
<mwk> and how does r_en/w_en work on this port?
<mwk> are they two independent signals? if so, we're back to square one
<whitequark> if i was doing it, i would go with two independent signals but also a parameter that specifies behavior during a conflict
<whitequark> this might not be optimal, of course
<mwk> and what would be the description?
<mwk> if it's "transparent" or "read old value", you still need sat to verify that user cannot do w_en without r_en
<whitequark> can you explain why?
<whitequark> i thought you didn't
<mwk> because that's how xilinx blockram works
<whitequark> oh, right
Degi_ has joined #nmigen
<whitequark> ok, so it is not so much "sat to infer memory" as much as "sat to map memory to xilinx"
<mwk> en=0 means w_en=0,r_en=0; en=1,we=0 means w_en=0,r_en=1; en=1,we=1 means w_en=1,r_en=1
<mwk> yes
<whitequark> that's still kind of gross but it seems unavoidable
<mwk> and ecp5 and anlogic and gowin because of course nobody actually designs fpgas themselves
Degi has quit [Ping timeout: 240 seconds]
Degi_ is now known as Degi
<whitequark> naturally
<whitequark> ... what does ice40 spram do
<mwk> hmm
<mwk> according to my notes, no defined behavior on read/write conflict
<whitequark> amazing
<mwk> but indepenedent enables at least
<mwk> and here's the other problem
<mwk> we *need* to consider three options
<mwk> read old value, transparent, X
<mwk> because that's in practice what vendors give you
<mwk> read old value is the annoying one, because you cannot implement it if the vendor cannot
<whitequark> you could probably duplicate the RAM?
<whitequark> i think?
<mwk> how?
<mwk> if all you have is SDP blockram like ice40?
<mwk> you could cheat and make one port use falling edge, but *it's a giant fucking can of worms*
<whitequark> would the same trick work as what people use to do multiple write ports out of SDP RAMs?
<mwk> (oh btw old intel parts do exactly that, latch address on rising edge, actually perform write on falling edge)
<mwk> (yes, in hardware)
<mwk> (always)
<mwk> (well, old altera parts really)
<whitequark> that reminds me of ultraram somehow
<mwk> ultraram is less insane because at least you cannot observe that
<mwk> given that it only has one clock
<mwk> but old altera parts do it on *dual clocked* memory
<mwk> but anyway
<mwk> maybe there's a way around it, maybe not
<mwk> but I'm pretty certain there's no non-obnoxious way around it
<whitequark> i'm in despair! EDA has left me in despair
<mwk> which is why we don't want to be marking RAMs as "read old value" unless we really mean it
<mwk> then, there's the "transparent" option
<whitequark> ok, makes sense
<mwk> which has the advantage of actually being somewhat sanely emulatable if it's not supported in hardware
<mwk> address comparator, mux, some registers, done
<mwk> so at least it's always feasible
<mwk> but still — it'd be better to avoid it if not actually necessary
<whitequark> yeah
<mwk> which is why there *must* be the "don't care" option
<mwk> the only question is how to deal with it
<whitequark> what are the options?
<mwk> how to store it, how to infer it from Verilog, etc.
<mwk> well, first thing, we could have it infered in the Big Pass
<mwk> using, of course, SAT
<mwk> r_en exclusive with w_en? done. always r_addr != w_addr? done. have an explicit mux that muxes 'x in case of conflict? done.
<mwk> of course, this is obnoxious, but honestly not that different from the SATing that already needs to happen
<mwk> second is to extend the model to have it as an explicit option along with the current "read old value" and "transparent" options
<mwk> needs two bitmasks instead of one, but eh
<mwk> and for Verilog, have a separate pass that recognizes "read value doesn't matter if that port is writing" patterns and marks it
<mwk> also when I said that there are three options ("read old", "transparent" aka "read new", "don't care")? I lied.
<mwk> hello intel memories again
<mwk> they have the wonderful "read new value, except the byte lanes which are not covered by byte enable are undefined" fourth option
<mwk> ... which I'm tempted to just forget about and pretend they're either option 2 or option 3 depending on whether the BEs are all identical
<whitequark> hang on
<whitequark> read byte enables?
<whitequark> or... write byte enables?
<mwk> write byte enables
<whitequark> right.
<whitequark> that sounds insane.
<mwk> oh right
<mwk> and this is the case where you *cannot* emulate transparency
<mwk> because transparency would presumably have the current valid value of the non-BEd bytes on the output, and there's no way to obtain it
<mwk> ... okay I'm now extra convinced that we *need* the "don't care" mode and also that it needs to be the default
<whitequark> wait, intel doesn't have a "read old" option?
<mwk> nope
<whitequark> uhh
<mwk> well let me check again in notes
<mwk> okay, it does
<mwk> when the read and write happen on *different* ports
<mwk> it's always "read old"
<mwk> when the read and write collide on *same* port, it's "read new except non-BEs, fuck those"
<whitequark> who thought this is a good idea
<mwk> .. do you see why I want to just beat this problem with a sat solver into submission
<whitequark> so... on intel, you would have to map a non-transparent rw port to two different physical ports, right?
<whitequark> can your architecture do that?
<mwk> a specifically read-old-value rw port, yes
<whitequark> ok, good
<whitequark> i agree re don't care being the default
<mwk> read-old-value is not the only possible option other than transparency, you know
<whitequark> yeah
<mwk> and yeah, my architecture can do that
<whitequark> (don't care) since with unrelated ports the collision behavior is inherently don't care
<mwk> I basically have a backtracking algorithm assigning ports to hw ports
<whitequark> it only makes sense that it would be the default for related ports
<mwk> this is also why I decided $memrdwr is a supremely bad idea
<whitequark> for nmigen i suppose i would not do anything like detecting the port domain, and instead use explicit groups
<mwk> with shenanigans like these, there's no way for the upstream to know when it's actually OK to merge a read port with a write port
<whitequark> yes
<whitequark> agreed
<whitequark> that's horrifying, but i agree
<whitequark> i'm glad i learned this now so i don't have to rip read_write_port out of nmigen later
<whitequark> so... does this answer your question re transparency?
<mwk> I think so
<mwk> as in, I'm now pretty much convinced the model needs to include the three transparency options
<mwk> and while inference of "don't care" will be necessary with "read first" being the naïve default for Verilog code, we can and should just emit "don't care" ports directly in nmigen
<mwk> are we on the same page here?
<whitequark> nmigen's contract is that it doesn't have x
<mwk> yes, that's the big problem here
<whitequark> i think it would be also "read first" by default (ie with default, absent, transparency parameter)
<whitequark> hm
<mwk> as long as you're fine with never infering a blockram on ice40
<whitequark> i mean it infers blockrams now so not being able to do it after the PR is a regression
<mwk> now the default is transparent
<whitequark> oh, right
<whitequark> so "write first" by default
<mwk> yes
<mwk> which is... well, at least always implementable, if sometimes inefficient
<whitequark> yes, so that was a lucky choice for a default (i can't claim to have understood all of this intricacy back then)
<whitequark> wait, ice40 blockrams don't support read first?
<mwk> I've read the available documentation multiple times and they have absolutely no mention of what happens on a read/write conflict
<mwk> maybe it's read first, maybe it's write first, maybe it's nasal demons
<mwk> are you willing to check it and assume it'll always be right?
<whitequark> ok
<whitequark> i am not, and i'll bet everyone who knew left lattice a long time ago
<mwk> ... or siliconblue for that matter
<whitequark> ... though i do want to check it
<whitequark> what does the sim model do?
<mwk> ... same
<mwk> hm, no idea
<mwk> my notes don't mention anything and I don't remember checking
<whitequark> where does that live anyway
<whitequark> ... why does icecube LSE have references to quicklogic?!
<mwk> wut
<whitequark> LSE/data/nbexpand.acd
<mwk> ... they all just sleep in the same bed don't they
<mwk> anyway, some other data points
<mwk> ecp5 has (according to documentation) undefined behavior on inter-port conflicts (within a port, you get same three choices as xilinx)
<mwk> so the same problem here unless read and write port address happens to be the same
<mwk> anyway... I'm sorry
<mwk> I really like the "no X ever" stance in nmigen, but it... just doesn't appear to match the reality of FPGA blockrams
<whitequark> I mean, I'm willing to change it when toolchains stop conflating three completely unrelated things as X
<whitequark> but not before
<whitequark> I'm fine with inefficient transparency logic being emitted though
<mwk> if you really want to avoid UB, the closest thing is transparent port by default
<whitequark> yep, that's what I'll keep doing, then
<mwk> with the new approach at least it's no longer incompatible with a read enable
<whitequark> wtf is ice8
<mwk> and of course you can always hope the sat solver logic in yosys will be able to change it to a "don't care" port
<whitequark> yep
<whitequark> fine with that
<mwk> but IMO it'd be good to at least have a "don't care" option, even if it has to come with a big fat warning
<mwk> and isn't properly simulated
<mwk> I mean, it's either that or manually instantiating vendor primitives
<mwk> and of course, "don't care" remains the only viable option for different clock domains
<whitequark> yes, something like an unsafe opt-in is going to happen at one point
<whitequark> but it won't be the default, and it will be some time until we get that
<whitequark> same as for e.g. full case
<mwk> right
<whitequark> mwk: if(Time_Collision_Detected & Address_Collision_Detected)
<whitequark> RDATA <= 16'hXXXX;
<whitequark> from SB_RAM model
<mwk> mhm, sounds rather undefined
<whitequark> it also writes a message to a log
<whitequark> so, yeah, read X is the native ice40 mode
<mwk> thanks for confirmation
<whitequark> still curious wtf the hardware actually does
<whitequark> but it might be tricky to actually check that
<whitequark> if there's a setup/hold violation
<whitequark> can't think of a way to get good data
<whitequark> i need to somehow de-embed the RAM out of the rest of FPGA and my testbench
<whitequark> and see what kind of phase difference results in old/new value
<whitequark> which seems like more pain than i'm ready right now
<whitequark> *ready for
<mwk> I'll probably have a lot of fun with stuff like that for xilinx at some point
<mwk> fun fact: the bitstream actually contains trimming values for strobe delays in every blockram config
<whitequark> fun or "fun" ?
<whitequark> wow
<whitequark> how configurable are they?
<mwk> it actually differs between device grades sometimes
<whitequark> like what resolution?
<mwk> NFI
<mwk> 3 or 4 bits
<mwk> have no idea how it corresponds to time units
<whitequark> that seems like a massive pain to bin devices to
<mwk> oh it's not
<mwk> it depends on the operating *voltage*
<whitequark> ah
<whitequark> makes sense
<whitequark> similar to ecp5-5g?
<mwk> yeah
<mwk> I've specifically observed this for spartan 6, which I have almost completely fuzzed, and which has a hilariously broken low-power version
<mwk> like... just.... read the data sheets and look at the so-called "low power devices", then laugh at the completely shit timings or just complete feature brokenness
<mwk> they took the spartan 6 chips, applied voltage to it way below the original spec to create a low power version, then documented which shit broke
<whitequark> hm, i can't find "low power" in ds162 or ds160
<whitequark> oh
<whitequark> wtf
<mwk> "yeah uh the DCM just kind of shits itself sometimes but we added auto-reset circuitry, it's fine, right?"
<whitequark> uhhhh
<d1b2> <Darius> fixed(*) in software!
<mwk> whitequark: also while we're on the topic of xilinx, have you looked at ?
emeb_mac has quit [Quit: Leaving.]
<whitequark> mwk: just did. i will give it another look, but essentially LGTM
<whitequark> added to 0.3 milestone
<_whitenotifier> [nmigen] whitequark commented on pull request #547: vendor.lattice_machxo_2_3l: fix sdc generation -
Bertl_oO is now known as Bertl_zZ
<_whitenotifier> [YoWASP/nextpnr] whitequark pushed 1 commit to develop [+1/-1/±1]
<_whitenotifier> [YoWASP/nextpnr] whitequark 9465899 - Update boost and eigen.
esden has quit [Ping timeout: 264 seconds]
tannewt has quit [Ping timeout: 260 seconds]
tannewt has joined #nmigen
esden has joined #nmigen
<_whitenotifier> [YoWASP/yosys] whitequark pushed 1 commit to develop [+1/-0/±2]
<_whitenotifier> [YoWASP/yosys] whitequark 1802f7b - Use getopt with argument permutation, like GNU getopt.
jeanthom has joined #nmigen
<_whitenotifier> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1]
<_whitenotifier> [YoWASP/yosys] whitequark 1400cf5 - Fix caching so that it actually checks WASM binary digest.
<_whitenotifier> [YoWASP/nextpnr] whitequark pushed 1 commit to develop [+0/-0/±2]
<_whitenotifier> [YoWASP/nextpnr] whitequark a69d7f3 - Fix caching so that it actually checks WASM binary digest.
<whitequark> well that's an embarrassing bug
jeanthom has quit [Ping timeout: 264 seconds]
jeanthom has joined #nmigen
<_whitenotifier> [YoWASP/yosys] whitequark pushed 7 commits to release [+1/-0/±8]
<_whitenotifier> [YoWASP/yosys] whitequark cb7ac71 - Update dependencies.
<_whitenotifier> [YoWASP/yosys] whitequark 5fd917d - Update dependencies.
<_whitenotifier> [YoWASP/yosys] whitequark 3ef7a0d - Update dependencies.
<_whitenotifier> [YoWASP/yosys] ... and 4 more commits.
<_whitenotifier> [YoWASP/nextpnr] whitequark pushed 4 commits to release [+1/-1/±6]
<_whitenotifier> [YoWASP/nextpnr] whitequark e36feaf - Update dependencies.
<_whitenotifier> [YoWASP/nextpnr] whitequark d9adbdb - Update dependencies.
<_whitenotifier> [YoWASP/nextpnr] whitequark 9465899 - Update boost and eigen.
<_whitenotifier> [YoWASP/nextpnr] whitequark a69d7f3 - Fix caching so that it actually checks WASM binary digest.
jeanthom has quit [Ping timeout: 246 seconds]
korken89 has joined #nmigen
feldim2425_ has joined #nmigen
feldim2425 has quit [Ping timeout: 260 seconds]
feldim2425_ is now known as feldim2425
nfbraun has joined #nmigen
Bertl_zZ is now known as Bertl
<korken89> Thanks for the help yesterday agg and kbeckmann ! Got it working today: :D
<daveshah> nice!
feldim2425 has quit [Ping timeout: 260 seconds]
<agg> :D
<agg> more fun awaits when you need to get the ddr3 clocks going I guess
<agg> are you generating the 25/50/100/150MHz clock domains all from the PLL?
<korken89> Yeah
<agg> (btw I am @adamgreig)
<korken89> Ahhhhhhh
<korken89> Hahaha hello adam xD
<agg> my sneaky(?) freenode disguise
<korken89> Worked wonders on me!
<korken89> I'm running an example from kbeckmann
<korken89> That I rewrote
feldim2425 has joined #nmigen
korken89 has quit [Remote host closed the connection]
<kbeckmann> korken89: nice to hear that it works!
FFY00 has quit [Remote host closed the connection]
FFY00 has joined #nmigen
FFY00 has quit [Remote host closed the connection]
FFY00 has joined #nmigen
FFY00 has quit [Remote host closed the connection]
FFY00 has joined #nmigen
emeb has joined #nmigen
feldim2425 has quit [Quit: ZNC 1.8.x-git-91-b00cc309 -]
feldim2425 has joined #nmigen
FFY00 has quit [Read error: Connection reset by peer]
FFY00 has joined #nmigen
FFY00 has quit [Remote host closed the connection]
FFY00 has joined #nmigen
<lkcl> agg: adamgreig as in "followingrobot with the STM32F102" adamgreig?
<lkcl> frickin loved that project.
<agg> guilty as charged
<lkcl> totally cool :)
<lkcl> i tried driving a 640x480 camera with the same STM32F103, it alllmost worked.
<agg> when did you come across that project? it was a school project from 2008 or so, so it's been a while...
FFY00 has quit [Ping timeout: 268 seconds]
FFY00 has joined #nmigen
jeanthom has joined #nmigen
Bertl is now known as Bertl_oO
FFY00 has quit [Remote host closed the connection]
FFY00 has joined #nmigen
FFY00 has quit [Read error: Connection reset by peer]
FFY00 has joined #nmigen
FFY00 has quit [Quit: dd if=/dev/urandom of=/dev/sda]
FFY00 has joined #nmigen
korken89 has joined #nmigen
lkcl has quit [Ping timeout: 268 seconds]
lkcl has joined #nmigen
<_whitenotifier> [nmigen] cestrauss commented on issue #565: cxxsim: random garbage in memory traces -
emeb_mac has joined #nmigen
<tpw_rules> what sort of guarantees are there, if any, that verilog.generate() will output the same file given the same input?
<tpw_rules> it seems like it does, but i don't know if that's expected
<tpw_rules> (the same == identical byte wise)
<_whitenotifier> [nmigen] whitequark commented on issue #565: cxxsim: random garbage in memory traces -
<whitequark> tpw_rules: it should be idempotent, but it can (and in practice, will) vary with environment, e.g. yosys version
<whitequark> so, if two consecutive calls, or two calls with different hash seed, don't return the same input, that's a bug
<whitequark> but the rest is out of my hands
<tpw_rules> okay, that's about what i expected. thanks for clarifying
<tpw_rules> turns out what i fed to it sometimes had an unlucky hash seed :)
<whitequark> yep, nmigen internally uses OrderedDict pervasively
Felkin has joined #nmigen
jeanthom has quit [Ping timeout: 256 seconds]
<Felkin> Yo yo, I've a question - as far as I can tell, nmigen doesn't currently have any sort of primitives for instantiating xilinx's DSP48E1s, right? Are there any plans to try and abstract them away a little? I have this super specific plan I have in mind, will start really trying it on my board mid-late jan, but wanted to get a sense of how much has to
<Felkin> be done.
<Felkin> To be more specific, I have this rather novel idea of designing a CORDIC core that makes extremely heavy use of a DSP, but here I am actually going to focus heavily on what the final PnR result is. The amount of logic elements in a LUT combined with a DSP cell at the bottom can actually lead to some very cool design.
<d1b2> <dub_dub_11> Your best bet for now is probably using Instance to insert a Verilog instantiation
<mwk> Felkin: if you want to go target-specific, just instantiate the raw primitive; if you don't, use the usual arithmetic opcodes and hope for the best in dsp inference
<mwk> write a closer wrapper if you want
<Felkin> Okey, will likely take the Instance route then, forgot those existed. It's very important for me to keep the DSPs as actual objects at language-level. I'm thinking of two papers in mind right now. One is about CORDIC+DSP hybrid architecture and another is using these as sort of almost cuda core-like primitives to outline a methodology for designing
<Felkin> accelerators. I had asked about CORDIC here a week or 2 back and did end up writing a python implementation for some image processing task. I quickly noticed that it could actually be very doable to make an HLS-like jump from the pure python program to an nmigen implementation. But it all banks on a hyper efficient implementation with the DSP so
<Felkin> need to go rly low lvl.
SpaceCoaster has quit [Quit: ZNC 1.7.2+deb3 -]
SpaceCoaster has joined #nmigen
korken89 has quit [Remote host closed the connection]
<Felkin> Anyways thanks for the advice, will come back to bug you more once I start trying to actually implement the thing.
Felkin has quit [Remote host closed the connection]