ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at · logs at
_florent_ has joined #nmigen
jfng has joined #nmigen
awygle has joined #nmigen
ZirconiumX has joined #nmigen
<_whitenotifier-3> [nmigen] awygle opened issue #315: FSM with transition to nonexistent state should not elaborate -
<_whitenotifier-3> [nmigen] whitequark labeled issue #315: FSM with transition to nonexistent state should not elaborate -
<_whitenotifier-3> [nmigen] whitequark commented on issue #315: FSM with transition to nonexistent state should not elaborate -
<awygle> is TSTriple a thing in nmigen? even if by another name? i can't seem to find it in the source, suspecting it got overtaken by events
<whitequark> it is not
<whitequark> it's replaced by the new platform layer
<whitequark> if you just want a record with i,o,oe for simulation, try
<awygle> and in synthesis i talk to uh, a "resource"?
<awygle> which contains... one or more pins?
<ZirconiumX> It seems like the milestones got lost in the conversion to the new repo
<whitequark> ZirconiumX: hm, I think they should've been migrated
<whitequark> awygle: yep!
<whitequark> note that Pin() is a bit of a misnomer, it's really a bus
<whitequark> (but most Pin instances are 1-bit wide, hence the name)
<whitequark> let me try to recap it, and then I'll add some docs...
<whitequark> awygle: imagine something like a paralell flash
<whitequark> it has an address bus (input), strobes (input), ready (output), data bus (bidi)
<whitequark> resources are described from the FPGA perspective, so there is an address bus (20-bit, output), strobes (many 1-bit, output), ready (1-bit, input), data bus (16-bit, bidi)
<whitequark> so it'd look something like this in the platform file:
<whitequark> Resource("pflash", 0, Subsignal("cs", PinsN("U8", dir="o")), Subsignal("we", PinsN("P5", dir="o")), Subsignal("a", Pins("R2 M6 N4 T1 N6 R7 V6 U7 R8 V7 R6 U6 T6 T8 R1 P4 P2 L1 U1 R5", dir="o")), Subsignal("d", Pins("K5 L3 K3 L6 M3 M1 L4 M2 V4 T5 U4 V5 V1 T3 U3 R3", dir="io")),
<whitequark> ),er
<whitequark> awygle: the idea is that you describe and use an external device in a similar way to how you'd describe and use an Instance of some FPGA block
<whitequark> when you do platform.request("pflash", 0), you get a structure with cs, we, a, d fields, each of which is a Pin
<whitequark> a Pin always has an uniform format; that is, if that Pin has an output capability, it has a .o field
<whitequark> if it has dir="o", then it won't have i or oe fields
<whitequark> if it has dir="io", then it will
<whitequark> this means that e.g. input from open drain pins (dir="oe") and from normal input pins (dir="i") can be handled the same way
<whitequark> there's more. this layer also handles XDR input (that is, registered, DDR, QDR+ I/O)
<whitequark> you still have the Pin() you request, but it additionally has i_clk and o_clk
<whitequark> and in the DDR+ case, it has, instead of i, i0, i1, i2, etc
<whitequark> the platform re-registers the input when necessary so all those signals are already in your domain
<whitequark> does this make sense?
<awygle> sorry, had a meeting
<awygle> what is the difference between Pins and PinsN?
<awygle> how do i communicate "this is a DDR Pin"? when you say "registered", do you mean "a register is packed into the IOB" or "this comes in synchronous to an external clock and needs to be synchronized into the domain"?
<awygle> other than those three, yes, it makes sense
<ZirconiumX> awygle: PinsN is negative-true
<ZirconiumX> Or equivalently negated/inverted
<awygle> oh, i see. does that affect output as well? i.e. writing a 1 to "cs" in the above example puts a 0 on the line?
<ZirconiumX> Yep
<ZirconiumX> awygle: As for DDR, there's the DiffPairs resource and you can give it an attribute
<whitequark> the idea with the resource layer is that all pins use logical directions
<whitequark> er
<whitequark> DDR doesn't have anything to do with diffpairs?
<ZirconiumX> ...Okay, sorry
<ZirconiumX> I got mixed up
<whitequark> awygle: "registered" means "a register is instantiated at a defined phase relationship and probably packed into IOB"
<whitequark> not all platforms have IOB registers, eg some Cyclone FPGAs don't
<whitequark> the gearboxing decision for any given pin is made at the point of *use*, not the point of *definition*
<whitequark> that is, the board file describes electrical behavior of pins
<whitequark> logic polarity, differential vs single ended, direction
<whitequark> things you can't really change
<whitequark> your actual gateware decides how exactly to instantiate it
<whitequark> for example, it can downgrade dir="io" to dir="o"
<whitequark> similarly, it can request xdr=0 (comb), xdr=1 (sync), xdr=2 (ddr)
<whitequark> this is because in some cases you have to use DDR for reasons other than using a DDR protocol
<whitequark> such as trying to align the phase correctly
<awygle> okay, so this is when you call `platform.request()`?
<whitequark> yep
<awygle> and by "xdr" you mean "this is sampled x times per clock edge"? so like a 7:1 SERDES would be xdr=7?
<whitequark> correct
<whitequark> right now those aren't actually supported in platforms that have them because the phase relationship in different SERDES blocks differs, and there's no way to communicate that via Pin
<whitequark> but I do plan to support those
<awygle> ah, i see
<awygle> and for a module which needs to communicate to an I/O pin, i can either take a Pin instead of a Signal for the `self.field` in the constructor, or make three Signals for i, o, oe, and hook them up at the top level?
<whitequark> the idiomatic approach as I see it is to take a Pin or a Record of Pins in the constructor in that case
<awygle> can i use a Pin for simulation?
<awygle> (suspect answer is "yes")
<whitequark> sure, it's just a bunch of signals
<whitequark> there is no magic to it, like there wasn't any for TSTriple
<awygle> tbf there is some magic :p it's just in the platform layer sounds like, rather than Pin proper
<whitequark> yes
<whitequark> the platform layer does have a bunch
<whitequark> it's mostly just indirection, but I do agree it's kinda opaque
<awygle> okay, thank you, i understand now (well, moreso :p)
<awygle> i do have one other question, if you have a moment. last night i wrote this code: . this is obviously invalid, because i assign to outside of an FSM context, but is there a way to make something like this work? (in this instance I rewrote the state machine so that it included both RX and TX)
<whitequark> mhm, yes, this is one of the more problematic cases
<whitequark> right now the FSM syntax isn't flexible enough and I agree it should ideally be improved
<awygle> fair 'nough, i've already commented on that issue lol
<awygle> oh, is there a convenient utility way to do the rising/falling edge detection i've done there? i was looking for a .rose() equivalent or something, didn't find it, and just did it "the verilog way"
<whitequark> there's Rose(signal)
<whitequark> and Fell()
<whitequark> they're in nmigen.formal but they simply generate some logic, there's nothing inherently formal-specific in them
<whitequark> maybe they should be moved
<awygle> ahh, okay
<awygle> i look forward to trying out nmigen.formal
<whitequark> :D
<awygle> i am starting to get to the point where most nmigen design decisions make sense to me, but every time i have to learn a new concept my brain still feels like it's physically rejecting understanding. pretty sure that's a "me problem" and i have to unlearn stuff
<whitequark> it could be, but i also do make mistakes
<whitequark> for example, initially I insisted there will be no x (without unsafe opt-ins)
<whitequark> turns out it's literally impossible
<whitequark> even on ice40, the initial value of BRAM output register is undefined
<awygle> oh sure. and once i'm confident i understand what's going on, if i think it's the wrong thing, i'll let you know :p. just gotta figure it out first so i'm not bringing you useless complaints, i'm sure you get enough of those
<whitequark> not really, so far the feedback has been very good
<whitequark> in general that is, yours too
<whitequark> I'll dedicate Q1 2020 to writing docs so it should solve many of the problems that currently exist
<whitequark> with teaching nmigen
<awygle> that would be swell
<awygle> as part of those docs perhaps, i'd also enjoy reading about why certain choices were made. for instance, the context managers used throughout, that kind of thing
<awygle> "x looks like x because y"
<whitequark> yes, absolutely
<whitequark> design rationales are an important part of documentation
<awygle> glad you agree (sadly not everyone does)
<whitequark> understanding why something is designed the way it is helps people use it correctly
<whitequark> cf. "idiomatic code"
<whitequark> personally, i can't really use something that i don't understand the rationale for
<whitequark> both because i refuse, and because, even if i force myself to do it, i usually miss something important
<whitequark> this comes up a lot with silicon
<whitequark> "this decision looks stupid" (proceeds to make a faulty design)
<awygle> yep
<whitequark> last came up ... yesterday
<awygle> heh, i read that note
<awygle> nice and weird
<whitequark> goddamn cursed is what it is :p
<whitequark> i bet their 8051 IP doesn't let you adjust reset vector
<whitequark> or IVT location
<awygle> i really want to use one of those 3 cent padauk MCUs in a project
<awygle> just to have done it
<whitequark> aren't they like PICs but worse?
<whitequark> ISA wise
<whitequark> I've seen a bunch of devices from like holtek or nuvoton which look like someone looked at a PIC and then made a parody ISA
<awygle> they're basically PICs with the serial numbers filed off yeah
<whitequark> lol
<whitequark> are they actually compatible on binary level?
<awygle> i don't believe so
<awygle> fortunately somebody else did the SDCC port so i haven't needed to care at that level
<whitequark> right
<awygle> i was surprised to learn that even padauk no longer sells DIPs
<whitequark> my favorite refrain when talking about cursed IC choices with people new to electronics is "pins are very expensive"
<awygle> true
<whitequark> so much weird shit is driven apparently solely by the desire to minimize the number of pins and/or leadframe size
<whitequark> WLCSP: the ultimate in minimizing leadframe size :p
<awygle> although i saw somebody give you "BGA substrate is expensive" as an explanation for those terrible Lime LGAs, and i don't buy that
<whitequark> i love that you refuse to call them "QFNs"
<whitequark> re BGA substrate... every time i flip over a BGA, i marvel at how fine the traces are
<whitequark> and how many layers it probably has
<whitequark> i should file down one of those to see how many it actually is
<whitequark> 4/4 design rules are expensive enough, i can't imagine how expensive is whatever process they use for those?
<whitequark> 2/2?
<awygle> automotive ones are even cooler, they appear to be polyimide PCBs
<whitequark> pcbway can apparently make 16 layer flex PCB
<whitequark> i'm not sure what's "flex" about it by this point, other than offering this capability being quite a flex
<awygle> lmao
<whitequark> oh, 8 layers
<whitequark> not 16
<whitequark> still
<whitequark> 2 layer ones are quite rigid already, they're just not very brittle
<whitequark> there is no way you can twist it into a knot, like the icon on suggests
<awygle> that just looks like it's bent slightly in the middle? maybe we're seeing different icons somehow
<whitequark> the b&w one to the left of "Flexible PCBs
<whitequark> "
<awygle> imo the proper way to do flex circuits is to crease them like origami
<awygle> ohh i see, yes, that is indeed impossible
<whitequark> re origami: isn't that what rigid-flex is for?
<whitequark> well not exactly but
<awygle> mm, kind of. that's not really what i was thinking of but i see the connection
<whitequark> how'd you crease them? do something with ground planes?
<whitequark> like puncture them in a sort of dashed line
<awygle> based on how hard it is to find an image of this it's apparently not nearly as common as i thought
<awygle> something like is done here, where it folds back on itself with a one-time crease that is not intended to be re-opened
<whitequark> oh i see, so it's just a fold
<awygle> yes. a sharp fold, close to 0 radius of curvature. the resulting angle can be whatever but usually it's 180 or 90.
<whitequark> my laptop has a bunch of those
<awygle> indeed, quite common in laptops, especially for screens
<whitequark> those aren't flex pcbs though, no?
<whitequark> on the pic
<awygle> no, that specific example is FFC
<whitequark> i forget what's the precise name but it's not polyimide
<whitequark> oh right, it's FFC versus FPC?
<whitequark> confusing nomenclature
<awygle> i couldn't find a picture of an FPC creased like that
<awygle> but i know i've seen it
<whitequark> i did see it
<whitequark> you know what's cursed?
<whitequark> my laptop has USB3 on one side connected via a ... hang on
<awygle> oh so many things :p
<whitequark> oh nevermind, so
<awygle> don't we have ~the same laptop? i bought mine largely on your recommendation
<whitequark> USB3 on the right side is connected via a flex PCB
<whitequark> which i think is at least 3 layer
<whitequark> it seems like some sort of stripline structure
<awygle> oo, cool
<whitequark> but whatever it is, it's certainly shitty enough that they had to put a redriver on the tiny PCB with the connectors
<whitequark> and apparently there are USB redrivers made specifically for this purpose?
<whitequark> my memory is a bit hazy but the entire thing struck me as extremely cursed
<whitequark> that flex PCB only has 90° folds
<whitequark> probably because if you fold a transmission line 180° with zero curvature, the bits ain't gonna stay inside
<awygle> i still know basically nothing about USB (although that's likely to change soon) but novel t-line geometries are Extremely My Shit
<whitequark> USB3 SS pairs are basically "I can't believe it's not PCIe"
<whitequark> i mean their LTSSM is literally PCIe LTSSM except with more cursed shit added
<awygle> isn't everything these days?
<whitequark> there's a few new power management states or something
<whitequark> but otherwise it is obviously based on PCIe directly
* awygle reminds the room at large that MIPI M-PHY is just PCIe L1 and MIPI UniPro is just PCIe L2 if it was multi-drop
<whitequark> if it was *what*
<whitequark> i'm sorry but multidrop pcie is extremely cursed
<whitequark> how do you even do that?
<awygle> it's not clear to me that you can
<awygle> it is clear to me that no one does
<awygle> but nonetheless, the data link layer supports it
<whitequark> ...