ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at · logs at
peteut has quit [Ping timeout: 272 seconds]
peteut has joined #nmigen
peteut has quit [Ping timeout: 246 seconds]
peteut has joined #nmigen
peteut has quit [Ping timeout: 272 seconds]
peteut has joined #nmigen
<_whitenotifier-3> [nmigen-soc] whitequark reviewed pull request #9 commit -
<_whitenotifier-3> [nmigen/nmigen] whitequark pushed 2 commits to master [+0/-0/±2]
<_whitenotifier-3> [nmigen/nmigen] whitequark 8947096 - back.pysim: accept write_vcd(vcd_file=None).
<_whitenotifier-3> [nmigen/nmigen] whitequark 57b08db - cli: update use of deprecated code.
<_whitenotifier-3> [nmigen] whitequark closed issue #319: Running `simulate` without specifying a VCD file yields an unhelpful error message (AttributeError: 'NoneType' object has no attribute 'register_var') -
<_whitenotifier-3> [nmigen] Success. 82.24% (+0.06%) compared to 38aa9fb -
<_whitenotifier-3> [nmigen] Success. Coverage not affected when comparing 38aa9fb...57b08db -
<_whitenotifier-3> [nmigen] Success. Absolute coverage decreased by -0.06, only covered lines were removed -
hell__ has joined #nmigen
Asu has joined #nmigen
<_whitenotifier-3> [nmigen-soc] jfng reviewed pull request #9 commit -
<_whitenotifier-3> [nmigen-soc] jfng synchronize pull request #9: wishbone.bus: add Arbiter. -
<_whitenotifier-3> [nmigen-soc] codecov[bot] edited a comment on pull request #9: wishbone.bus: add Arbiter. -
<_whitenotifier-3> [nmigen-soc] codecov[bot] edited a comment on pull request #9: wishbone.bus: add Arbiter. -
<_whitenotifier-3> [nmigen-soc] jfng closed pull request #9: wishbone.bus: add Arbiter. -
<_whitenotifier-3> [nmigen/nmigen-soc] jfng pushed 1 commit to master [+0/-0/±2]
<_whitenotifier-3> [nmigen/nmigen-soc] jfng 967a65f - wishbone.bus: add Arbiter.
<_whitenotifier-3> [nmigen-soc] jfng commented on pull request #9: wishbone.bus: add Arbiter. -
<_whitenotifier-3> [nmigen-soc] Success. 99.63% (+0.04%) compared to f8f8982 -
<_whitenotifier-3> [nmigen-soc] Success. 100% of diff hit (target 99.59%) -
<_whitenotifier-3> [nmigen-soc] whitequark reviewed pull request #9 commit -
Asu has quit [Remote host closed the connection]
Asu has joined #nmigen
Asu has quit [Remote host closed the connection]
Asu has joined #nmigen
peteut has quit [Ping timeout: 272 seconds]
peteut has joined #nmigen
<ZirconiumX> How do you request all LEDs in a platform? Having trouble finding where platform.request is
<whitequark> you request them in a loop until you run out, basically.
<whitequark> take a look at nmigen-boards blinky
<whitequark> that's, um, not very elegant, but so far i only needed that once, and no one else complained.
<ZirconiumX> Ah, okay
<Sarayan> btw, what's nmigen-soc in practice?
<Sarayan> it looks intriguing
<ZirconiumX> "tools for building SoCs", like Wishbone interfaces and a register bus
<Sarayan> yeah, but that's kinda vague. There's a general target wishlist of contents?
<whitequark> yes
<whitequark> in general, "SoC" means "transaction initiators and targets connected with memory-like buses". this is kind of vague, but I think that's the essence of a SoC
<whitequark> it doesn't necessarily have to have a CPU
<Sarayan> I'd agree, yes
<Sarayan> even if cpus are useful building blocks
<Sarayan> but so's a fully feature serial, or whatev;
<whitequark> so... nmigen-soc is supposed to contain memory-like buses (think axi4, wishbone, and so on) plus peripherals hanging off them
<whitequark> arbiters, decoders, and so on
<ZirconiumX> I think I've found a fundamental problem with trying to teach nMigen: people think one of the V-languages is going to be "more useful" and then proceed to repeatedly shoot themselves in the foot
<ZirconiumX> My friend got a DE10-Nano, and decided that they could learn nMigen later and wanted to get stuff done with Verilog
<ZirconiumX> So far, said friend has done `reg [0:23] foo` (I don't know the technical term for this error, but yeah)
<whitequark> wrong bit order
<whitequark> hmmm
<whitequark> do you think this relates to the relative lack of educational materials for nmigen?
<ZirconiumX> They tried to use negative-edge logic
<whitequark> or do you think it'll persist regardless of it?
<whitequark> there's a certain truth to V-languages being "more useful" in the sense that learning them lets you contribute to many more existing codebases, or learn from them
<ZirconiumX> Potentially the latter? Essentially when people think FPGAs they think of the V-langs
<ZirconiumX> And overcoming that is going to be...tricky
<ZirconiumX> The worst part is that I look at these beginner mistakes (including things like trying to infer a combinational single-port memory) are all things that nMigen - if not avoids, then makes difficult
<ZirconiumX> e.g. you *can* do negative edge logic when you want to, but it defaults to positive edge
<whitequark> yeah
<whitequark> and it nudges you against using e.g. ripple counters as dividers
<ZirconiumX> While also simultaneously easing the pain of expressing finite-state machines
<ZirconiumX> <-- here's their code after about 24 hours of switching their FPGA on
<ZirconiumX> Including hardware-in-the-loop debugging!
* ZirconiumX sighs
<ZirconiumX> You've managed to create a beginner-friendly language that beginners avoid
<whitequark> i didn't create it (even the syntax alone is a work by multiple people), but yes
<whitequark> kind of unfortunate
<emily> _whitelogger: nmigen seems like it's inherently less capable
<emily> whitequark:
<emily> because it doesn't have 10-valued logic or ten different kinds of statements
<emily> or a billion vendor extensions
<emily> it is inherently less capable -- e.g. no x -- but it's easy to mistake much of Verilog/VHDL's accidental complexity for inherent
<awygle> for me the two drivers of the perception that nmigen isn't as useful as verilog/vhdl are 1) i'm not gonna get hired to write nmigen and 2) being a python dsl makes it feel inherently less serious
<emily> I was scared off FPGAs for years by the perception that they were truly as arcane as the V-languages are
<emily> also
<emily> nmigen only supports stuff that actually works with modern FPGAs
<whitequark> emily: it's almost exactly as capable as *synthesizable* Verilog
<emily> whereas beginners -- me included -- love to try doing stuff that Verilog "supports" and that doesn't work
<whitequark> right
<whitequark> awygle: interesting
<whitequark> would you say (2) also applies to say, Clash?
<awygle> which one is clash?
<whitequark> (Clash works differently but that probably doesn't count in a first impression)
* hell__ is still afraid of FPGAs
<whitequark> the Haskell one:
<whitequark> or Chisel.
<whitequark> (the Scala one:
<ZirconiumX> Or Spinal
<ZirconiumX> The other Scala one
<emily> Clash isn't an eDSL
<emily> Lava is the closer comparison there
<awygle> i would say no, partly because i perceive Haskell as more serious than Python, and partly because Clash seems less like Haskell than nMigen is like Python (although i don't actually know haskell so)
<whitequark> yes, that's why I said it works differently
<emily> Clash is an actual (subset-of-)Haskell compiler
<awygle> i somehow _know_ that clash is not an eDSL
<emily> Clash is actually much more like Haskell than nMigen is like Python in that sense
<awygle> either because of marketing
<awygle> or just being around in the scene too long
<whitequark> amusingly, you could get MyHDL, which is a Clash-like thing for Python
<emily> although it's true that you can't "reuse" existing Haskell or Python code on the FPGA in practice
<emily> so not HLS
<whitequark> and it's arguably less serious
<whitequark> because it doesn't have quasiquoting
<emily> amusingly if nmigen was an ocaml eDSL it would have higher status, I guess :P
<emily> and then the beginners would want to learn it, but be unable to!
<awygle> Python is to me probably the second lowest tier of programming language (for a bunch of reasons which are probably worth interrogating in another context)
<whitequark> oh I see what you mean now
<emily> yeah python is terrible. even whitequark admits that
<whitequark> what do you mean "even".
Asu has quit [Ping timeout: 268 seconds]
<emily> you write everything in python!
<whitequark> i literally never thought python was good
* ZirconiumX snickers
<awygle> i'm not sold on eDSLs for FPGAs generally, and i hate python, so nmigen has a steep hill to climb
<whitequark> the first thing i did in python was a python compiler and it was immediately obvious python isn't good
<emily> imo you either need an eDSL or sufficiently elaborate metaprogramming
<emily> the latter ends up being a general purpose language to its own end
<ZirconiumX> And the former converges to the latter
<whitequark> yup
<awygle> couple that with the fact that nothing's quite ready (nobody's fault, just how these things go) and i doubt i'd recommend it to anybody, even a beginner, right now
<emily> you can have it either be an accidental one like C++ templates or whatever, or make your meta-language a "real" language from the get-go by making an eDSL
<whitequark> i don't recommend nmigen to beginners myself, currently
<awygle> i mean, rust has complex metaprogramming and it's not an eDSL
<whitequark> a few beginners (Sarayan for example) did pick it up with great success
<whitequark> but i'm not expecting that to be the rule
<emily> Rust's trait and macro systems are the kind of "ad-hoc" metaprogramming system I'm talking about
<ZirconiumX> However, nothing stops us from making it more beginner-friendly, right?
<emily> proc macros are much more natural because you get to use real Rust
<awygle> i will agree that macro_rules! is fairly ad hoc, or feels that way
<emily> note: I'm a big fan of traits/typeclasses, don't get me wrong
<awygle> i don't think traits are, if anything i find traits insufficiently ad hoc
<emily> but there's still an extent to which, if you want to "metaprogram" some Rust code, you don't just write some Rust code to do it
<emily> you have to deal with an extra, slightly second-class meta layer and manually glue stuff together
<awygle> i guess i don't see that as a goal
<awygle> you're at a different meta-level
<awygle> it should be different
<emily> in HDLs, your runtime domain is much less capable, so you have to do stuff at compile/meta time much more often. so you run into the need for flexible metaprogramming more often
<ZirconiumX> I still need to figure out how to get nMigen to simulate under PyPy...
<awygle> mmm i don't know that i agree your runtime domain is less capable, either
<ZirconiumX> Maybe it's just that I'm struggling with Python environments
<awygle> it's just different
<emily> well, nmigen does fulfil the property of the meta-layer and the base-layer being distinctly different
<emily> in that nMigen eDSL code looks very different from normal Python code
<emily> but is programmed with normal Python code
<awygle> does it? doesn't feel that way to me, nmigen feels like "python+rituals"
<emily> I mean, for simple expressions?
<awygle> it all blends together until you understand how it works
<emily> as soon as control flow happens everything is wildly different
<emily> assignment statements have their own different syntax and aren't ordered
<ZirconiumX> I've only ever used Python's with-statement for file I/O, not to program in
<emily> it's embedded in python, but the structure and semantics are nothing like python
<emily> and it doesn't try to act like python at all
<emily> it just uses python to drive things
<whitequark> (assignments are ordered, which matters if you assign to the same bit repeatedly)
<awygle> i kind of agree with you and kind of don't lol
<awygle> it looks like "weird python"
<emily> kind of like how tensorflow is a python API for dealing with differentiable computation graphs
<emily> with no concrete syntax for those computation graphs
<awygle> it's still obviously python though
<awygle> so it just feels weird
<awygle> and there's not enough of a line separating "weird" and "normal" python for someone who doesn't really know what's going on to confidently say "i am describing hardware right now. and now i am writing python which does not describe hardware except in a meta sense."
<whitequark> hmmm
<whitequark> that's true
<whitequark> for example, value casting means there isn't strict separation between python arithmetics and nmigen arithmetics
<whitequark> i tried very hard to make sure there won't be any gotchas arising from that, but it's still potentially confusing
<awygle> i've been halfway thinking this for a while, but i _think_ i would like it better if (if possible) you could do `with m.d.sync: <normal python syntax as much as possible>`. then anything inside that context manager is hardware.
<awygle> i might be wrong about that, but that's kind of where i find myself drifting
<whitequark> awygle: that's just myhdl
<awygle> oh lol
<awygle> did not know that
<whitequark> well not quite, but close
<whitequark> the problem is, what happens if you put a loop inside `with m.d.sync`?
<whitequark> ok, let's go back a bit
<whitequark> the problem with your specific idea is that it's impossible
<whitequark> you can't use a with statement to modify the way if statements inside work, for example
<awygle> right, i know that
<whitequark> myhdl bypasses this by requiring you to define a function
<whitequark> which you can ask the interpreter for source of
<whitequark> then it parses that function and assigns its own arbitrary meaning to python syntax
<emily> awygle: I agree with you wrt nmigen mixes the levels in some ways I find uncomfortable
<emily> personally I want the levels to be as structurally similar to each other as possible, but also distinctly layered and differentiated
<whitequark> the problem is that you can't use quasiquoting that way because there's no suitable python syntax to hijack
<emily> why is there no hardware programming language that satisfies my incredibly specific technical aesthetics?? it is a tragedy :p
<whitequark> you can't do*
<emily> yeah python is not a great edsl host.
<emily> fwiw I hear Scala isn't either, nothing I've heard about Chisel has been very good...
<whitequark> so, you've seen adamgreig's FSM based IP stack thingy?
<whitequark> you can't do it in MyHDL as far as I know
<emily> apparently Chisel's output is as unreadable as Clash's too
<ZirconiumX> I have a few syntax things of my own, but they're kinda whatever. Mostly they're about trying to contain the rightward lean that nMigen seems to result in
<whitequark> the rightward drift of nMigen is really unfortunate, I agree
<awygle> Oh you mean physically on the page
<ZirconiumX> I find they come up most in FSMs
<awygle> I was confused briefly lol
<emily> no, no, you're thinking of ZipCPU
<ZirconiumX> So much for making the joke subtle
<ZirconiumX> *ahem*
<awygle> Lulz
<emily> it would be less bad if it was easier to factor out nmigen definitions
<emily> I mean, functions work
<awygle> I was just confused! I thought you meant something like "you have to live on the bleeding edge"
<emily> but you end up having to pass a lot around or just stuffing everything into class fields
<awygle> Nmigen feels very module focused to me, if that makes sense
<awygle> Like I could write a leaf node of the circuit in nmigen no problem! But as soon as I have to glue bits together to make a bigger thing I find it challenging and boilerplatey
<whitequark> yes, I also feel that
<whitequark> we can improve it, though
<awygle> I feel bad about the direction this conversation has taken.... My intent here is not to indiscriminately shit on nmigen, it's a great piece of work
<ZirconiumX> It would be nice if e.g. "with m.FSM(): with m.State('...'):" could have an FSM object be a submodule or whatever and then `with fsm_name.State("...")`
<whitequark> no, I think such conversations can be very useful
<awygle> Yeah I mentioned that too and I think wq said it was doable?
<ZirconiumX> But I know that FSM is kinda a stack internally
<ZirconiumX> Well, nMigen itself is a stack internally
<whitequark> awygle: i'm not sure `with fsm_name.State()` makes a lot of sense
<hell__> such conversations are kind of like brainstorming, which is pretty good
<adamgreig> fwiw i came to migen with very very little verilog experience but years of python and found it hugely more productive and easier to learn, even back then
<whitequark> if you make nested FSMs then "interleaving" them lexically seems unlikely to produce the results you want
<ZirconiumX> I'm the one you meant to reply to there,wq
<whitequark> er
<whitequark> yeah
<adamgreig> i recommend it to beginners but also encounter people thinking learning verilog first will be more useful somehow
<emily> 23:14 <awygle> Like I could write a leaf node of the circuit in nmigen no problem! But as soon as I have to glue bits together to make a bigger thing I find it challenging and boilerplatey
<adamgreig> i think people expect verilog to be less bad
<awygle> adamgreig: interesting, can you elaborate on what you found better in nmigen compared to verilog?
<emily> this is something I feel Lava, Clash, maybe Chisel have a strong advantage to nMigen in
<emily> you have proper typed signals
<emily> and can plug things together based on defined input and outputs
<emily> rather than the "soup of random stuff, some internal, some inputs, some outputs, who really knows the types or directionality" you often have with nmigen, it's much less structured
<whitequark> nmigen definitely needs proper typed signals but i'm not sure how it'd help plugging things together in terms of boilerplate
<adamgreig> awygle: the metaprogramming and syntax being in python was probably a big thing, i took to metaprogramming the circuit very quickly in ways that just don't seem possible in verilog
<whitequark> it'd make it much easier to write this boilerplate, yes
<awygle> I wonder sometimes if I'm just traumatized by software languages all being bad. I don't run into any of the things people say are so difficult about verilog because I successfully internalized the rituals required to avoid them.
<emily> whitequark: not boilerplate but ease of writing and correctness
<emily> it's hard to tell how to plug two components together in nmigen
<emily> whereas types tell you how to plug things together, that's kinda what they do
<whitequark> right
<whitequark> I think flowgraph stuff should help with plugging things together
<emily> like, I have a UART in clash where tx and rx are function types that convert a signal of undifferentiated bits into structured packets and back
<emily> and you can literally compose them together to make cat
<whitequark> but it's only a part of the story
<awygle> I think that's a python problem tho
<whitequark> ^ also that
<emily> nMigen can't express things like that at all
<whitequark> it's hard in python in general
<awygle> You're never going to see types all the places you would see them in e.g. Rust
<awygle> So context is hard
<whitequark> awygle: you kind of will actually
<whitequark> that's the plan, to use python types
<whitequark> type annotations*
<emily> awygle: you clearly haven't seen the horrors of mypy
<emily> it can express much more than mortal type systems ought to be able to
<emily> it's not, like, sound, and the design is a total mess, but you can encode a lot
<emily> it has had sufficient amounts of PhD-energy put into it
<emily> whitequark: would you still be interested in typing annotations for as much as nmigen as practical btw? I might dust off that branch at some point if so
<emily> not towards an end-user-type-encoding eye so much as just getting the basic interfaces typed
<awygle> I meant see, physically. But maybe you did too, I haven't actually used python typing
<whitequark> emily: yes, but we really should brainstorm the interfaces first
<whitequark> in general, my priority is typed elaboratable ports
<emily> I mean
<emily> You can just make Value etc. not have type arguments to begin with
<emily> and then make the types more specific as you decide how to richly-type them
<emily> it'd help at least get the skeleton structure of the typing down
<adamgreig> what benefit does having ports typed being?
<adamgreig> bring*
<awygle> Directions!
<whitequark> yup! right now you can just reach out into any module and fiddle with any signal. there is no meaningful encapsulation
<awygle> With semantics! That are visible! And not just explosions when you try to elaborate!
<emily> and semantics :)
* emily hi5s awygle
<whitequark> awygle: hey, that one is just a bug
<adamgreig> what sort of semantics?
<whitequark> people don't usually connect instances together, so it wasn't found earlier
<adamgreig> like, i don't find myself connecting outputs to outputs ever, because if i need to look at the submodule to see what its signals are called, i immediately also see if they are in/out and what they do
<awygle> The bad error message is a bug. The fact that you can't see whether something is an input or an output without looking to see if you're assigning it is not.
<adamgreig> how do you know its name to connect to it, and presumably its function, but not its direction?
<whitequark> awygle: you misunderstand. when i fix the bug, it won't explode. that's *worse*.
<adamgreig> i can totally see the advantage of better encapsulation and expressing design intent wrt "these are ports for the outside world"
<adamgreig> rather than just "here are some attributes of my class, i will probably use them when i elaborate myself, please connect to them"
<ZirconiumX> I've reached the point where public pins are defined in __init__ and absolutely everything else private is in elaborate
<whitequark> ZirconiumX: that's how I write my code too
<whitequark> there is a drawback, in that you can't easily probe private signals in e.g. unit tests then
<adamgreig> right, same, my __init__ defines all the in/out signals, captures constructor args, and then elaborate (and methods called by elaborate) create any private signals
<adamgreig> the docstring for __init__ says what the signals are, and for me at least i need to know what the signal is doing as much as i need to know if it's an input or an output
<emily> ZirconiumX: yes, but then you can't split elaborate up
<emily> well I guess you can just do like, nested functions
<emily> but then you're back to rightward drift
<awygle> adamgreig: the docstring is not mandatory, for one thing
<emily> tbh just using self._foo for internal pins would be a start
<whitequark> (type annotations won't be mandatory for nmigen.compat reasons)
<adamgreig> awygle: yea but the extra information in it is required to use the module, even if you had annotated types saying which signals were in/out
<emily> I don't think the existing nMigen/Glasgow stuff follows that convention
<ZirconiumX> I mean, I have managed to split elaborate up quite nicely; a lot of private signals can be hidden in the function that uses them
<awygle> see how we're all describing conventions here? none of this is enforced, currently
<adamgreig> the type system won't encode what the signal actually is used for, i imagine?
<whitequark> emily: it should
<awygle> which i find troubling
<whitequark> awygle: i agree completely
<emily> "welcome to python"
<whitequark> this is just something i inherited from migen
<awygle> ^
<adamgreig> emily: if you assign signals to self in elaborate(), other things can't get at them anyway, since the attributes don't exist until elaboration time
<emily> mypy does actually enforce things though
<emily> I mean, except insofar as the type system is unsound and you can break it
<emily> but that doesn't stop people using Java, so
<awygle> it's so hard in these discussions to not back up a meta-level
<awygle> for me, at least, because that's what i do when confronted with problems
<emily> oh mood
<whitequark> i think that's fine and can be very productive
<whitequark> i'll be quite happy to discuss the drawbacks of essentially anything in nmigen that you don't like and how i can fix them
<awygle> my instinct here is to take nmigen, and slice it up into a suite of libraries for creating HDLs
<whitequark> ideally not in four conversations at once while i'm really tired, though
<awygle> yeah agreed, i'm at work on a deadline and really shouldn't be doing this either
<whitequark> heh
<awygle> shall we agree to table?
<awygle> err, american table. suspend.
<adamgreig> interesting irc conversions while you're busy with something else are the worst :p
<adamgreig> conversations*..
<whitequark> sure
<whitequark> no rush here, really
<awygle> yep, only the slow march of entropy leading inevitably to my death :)
<whitequark> ouch
<awygle> sorry
<awygle> that was meant to be lighthearted
* zignig hands awygle the happy fun ball.
<whitequark> hits a bit close to home tbh
<awygle> yeah this is something i talk about in therapy a lot actually >_> whoops. my bad.