2020-04-06

<ktemkin> ~~anyway, I’m glad we have this nice, flexible protocol so we can finally cover the most common use cases like *squints at notes* ... wait, does this say “establish a pair of unidirectional connections that act like a UART”?~~
<ktemkin> whitequark: I’m on mobile, I can’t type my joeks fast enough
<ktemkin> oh and sometimes SE0; so there’s thee bit values to worry about
<ktemkin> nice and easy~
<ktemkin> *bit values
<ktemkin> just J and K
<ktemkin> Sarayan: I mean, there’s only two but values to deal with anyway, how hard can it be?
<Sarayan> ktemkin: it's just serial anyway, how complicated can it be?
<ktemkin> if you think about it, it’s just around a thousand LUT4s of constants
<ktemkin> pretty much every time I write any USB anything, I think back to that guy’s vehement assertion and wish I had his level of skill so I could skip all the damned fiddly bits and just bang out that simple USB fsm
<ktemkin> their IBM “customer” lost his mind at the idea of using another chip to do USB, and at their public review in front of a room full of ~300 industry folks screamed about their “incompetence” for not just implementing USB on the FPGA, as “it’s just a simple state machine”
<ktemkin> so I recommend they use a chip like an FTDI; this thing’s a one-off, so it doesn’t even make sense to save the dollar by writing firmware for a USB uC
<ktemkin> and they wanted to get UART data from a PC to an FPGA as part of their final design
<ktemkin> (this was a decade or so ago when I was still university faculty)
<ktemkin> little local business called IBM that had started over there and poisoned the groundwater with PCB solvents
<ktemkin> I was advising a team of university students working on their capstone project; these poor students had a sponsor “customer” at the company down the street
<ktemkin> I wish they’d just have come up with a naming scheme that didn’t ascribe special meaning to words like “transaction” or “transfer”
<ktemkin> it took me two iterations of my usb training just to get out of the habit of arbitrarily calling bundles of bytes in a stream “packets of data”
<ktemkin> try writing a usb analyzer stack and having a sane view of what a packet is
<ktemkin> adamgreig: control transfers have three stages so you can confuse the three parts of them with the three parts of transactions
<ktemkin> if everything didn’t have a start, maybe a middle, and an end, how would you confuse all the protocol levels for it?
<adamgreig> ktemkin: threes?
<ktemkin> usb is obsessed with threes, though
<awygle> reading ktemkin's luna example and realizing how very very little i know about usb...

2020-04-04

<awygle> ktemkin: 9 times out of 10 the problem is i typed "sink.we" instead of "sink_we" and all i need is the line number in my code :shrug:
<ktemkin> if it's not immediately obvious what's wrong with my code, it often becomes so when I look at what part of nmigen got angry at me
<ktemkin> I tend to *like* the exceptions coming from nmigen's internals
<awygle> ktemkin: awesome, i'll keep my eyes open. i want PHY_ful HS so the last bit is fine :P
<ktemkin> awygle: probably won't be ready for general use for another week or two; and then another short bit if you want PHY-less FS
<ktemkin> awygle: yes
<awygle> ktemkin: is your usb stack intended to be general purpose? cuz i uh... could use one >_>
<ktemkin> [by the way, off topic, but my complete lack of creativity has resulted in me taking your suggestion of `usb-protocol`]
<ktemkin> but that's less a phrasing suggestion and more an "idea to get across" suggestion
<ktemkin> maybe replace "hardware description language" with some variant of "behavioral description language"
<ktemkin> I like explaining the idea that nmigen -isn't- a hardware description language: you're not describing behaviors and letting something else fill in the details. Instead, nMigen is a gateware composition toolkit that fundamentally starts by building netlists; and then gives you the python tools you need to construct abstractions from there.
<ktemkin> *interpreter
<ktemkin> but it turns out there are three things with the value "3", and they're all entirely equivalent as far as tcl can tell, but the interpret's tagged them with something you can't interact with that makes some functions behave differently
<ktemkin> so you go and ask for a file handle, and you get "3", and it seems like that's a handle that represents an object in memory
<ktemkin> Xilinx has the "this is a string sometimes, and you have to use it that way, but other times there's a magic thing tied to the object that stores the string, and we're not ever going to make it clear which is which"
<ktemkin> tcl has that "everything is a string, but sometimes we hide other things in those strings" thing
<ktemkin> "everything is a string, but some of the strings are magic, and if you ever try to modify those strings in any way the magic is lost"
<ktemkin> between them and Xilinx, they have invented the singularly most cursed software language ideology I've ever seen: tcl, except some of their functions return Magic Strings, which have an invisible data structure pointer attached to them
<ktemkin> so you had to go and find whatever gods-forsaken tcl script had broken over the Eternities and fix it
<ktemkin> when I last used it, synplify thought it knew better than me; and the flags they had that overrode its heuristics were ignored
<ktemkin> only incidentally while fuzzing bitstream stuff
<ktemkin> whitequark: to be fair, I last used it in 2010-ish, but I assume it looks exactly the same
<ktemkin> hey, don't be harsh; it's not like it's Synplify
<ktemkin> "Please do not forward Espresso questions to UC Berkeley students, faculty, or staff as there is nobody here who can answer them."
<ktemkin> the README is priceless
<ktemkin> I just had to check to see if espresso was older than I am
<ktemkin> I kind of love how jedi has become old
<ktemkin> and I've almost figured out how to draw these things in a sufficiently-dimensional hypercube as to let me start optimizing away whole LUT4s~
<ktemkin> whatever did I go to grad school for?
<ktemkin> a computer? to do -my- k-maps?
<whitequark> ktemkin: these days I would get an SMT solver to write an instruction decoder rather than (ab)using 'x to do it
<ktemkin> something something, galaxy brain: doing k-maps to optimize away all those gates in your LUT4s
<ktemkin> clock domain crossing
<ktemkin> I'm just happy that my simulations mean something; as opposed to the horror days of having xst 'optimize' my RTL into things that shouldn't exist
<ktemkin> tangentially related to the above: one thing I'm very much enjoying about nmigen [vs e.g. verilog] is my increased ability to trust simulation output
<ktemkin> awygle: you can, but there are as many primitives as there are vendors
<ktemkin> awygle: the difference is with something like Verilog, you're speaking a behavioral incantation and trying to coax the synth tool into inferring what you want
<ktemkin> you can still wind up working at the same level of abstraction; just on top of a foundation that's been solidly created underneath you
<ktemkin> awygle: instead of building an abstract behavioral description and inferring down, you wind up creating building blocks with explicitly the implementations you want, and then building -up-
<ktemkin> awygle: generally, I find that's actually one of the strengths of a toolkit like nmigen
<ktemkin> connecting signals from place to place has always been the bane of sanity
<ktemkin> in a cosmic sense, aren't all of our projects insignificant?~
<ktemkin> so it's important to me not to set awkward or ill-advised idioms :)
<ktemkin> yeah, and given the relative dearth of nMigen projects, any significant projects that do exist are inevitably going to wind up referenced as example code
<ktemkin> by the way -- at some point, when I'm a bit further on the LUNA stack, I might ask for your opinions on how I'm using nMigen; if you wind up having the time/drive/spoons to take a look
<ktemkin> mm
<ktemkin> whitequark: is there anything in particular that you think should be taken away from it? I'm not above stealing good ideas in my own implementations :)
<ktemkin> in short: it looks neat, but it also looks like more of an experiment than an application-targeted library; and a few months ago I decided it'd be easier/cleaner to write a from-scratch stack than to try to adapt it
<ktemkin> I didn't get to the point of actually trying it on a board; but when I read the codebase, it looked like it'd been stuck in an "isn't complete enough to do a full enumeration" state for a while
<ktemkin> and it's not particularly complete
<ktemkin> it has a relatively small codebase; but I found it more difficult to follow than it needs to be; and found many of its components are relatively tightly coupled together
<ktemkin> mithro: yep, I have
<mithro> ktemkin: Have you looked at lambdaconcepts USB2.0 core at https://github.com/lambdaconcept/lambdaUSB ?

2020-04-02

<Sarayan> ktemkin: Isn't the best way to bomb-proof your usb host to foone a bunch of crap from alibaba and connect to it? ;-)
<ktemkin> re: earlier: I wish Python's type hints / annotations worked more reasonably

2020-03-26

<ktemkin> check the configuration guide's Table 1; they have some recommended flash sizes with rationales
<ktemkin> multiboot is a thing
<ktemkin> m.submodules += Instance('USRMCLK', i_USRMCLKI=sck_signal, i_USRMCLKTS=0)
<ktemkin> instead of requesting the I/O pin for the clock pin, use something like:
<ktemkin> you'll need to use USRMCLK to drive the SPI CLK
<ktemkin> almost
<ktemkin> you can also come up with gateware that translates from a format you _do_ have comms in to SPI
<ktemkin> that'll work
<ktemkin> it depends on how the relevant board has the flash hooked up
<ktemkin> Degi: yep

2020-03-20

<pdp7> ktemkin: thank for the followup on the nmigen hello world... do you know who I should contact about correcting the tutorial?
<ktemkin> generically, it's the PAR tool's job to figure out how to fan signals out through the logic
<ktemkin> the first two would be "i_", and the last would be "o_", since those are two inputs and an output
<ktemkin> the first three arguments you have are I/O ports
<ktemkin> ah, and yep --- looks like the DIV parameter is named ^
<ktemkin> which are <same name as in verilog> prefixed with "a_"
<ktemkin> oh; and looking at the macro definition, you may also want to provide synth attributes
<ktemkin> yep; provide the same value you'd provide in the Verilog instantiation (which is 0/1/2/3 for dividers of 1/2/4/8, respectively)
<ktemkin> instance input ports get an "i_" prefix; instance output ports get a "o_" prefix, and instance parameters get a "p_" prefix
<ktemkin> in short: the arguments to Instance() are mostly equivalent to the elements in the verilog instantiation; but names are prefixed to specify the port/param types

2020-03-19

<ktemkin> so `ports=(top.led,)` is okay, since that generates a 1-element tuple; but `ports=(top.led)` is equivalent to `ports=top.led`, which is a signal where it expects an iterable of signals
<ktemkin> (it'll take any iterable for ports; and not just lists -- that's just missing the terminal ',' that makes python interpret it as a tuple rather than just a single element)

2020-03-18

<ktemkin> hi ^^
<mithro> ktemkin: Hi!

2020-03-02

<awygle> i'm working on one, and ktemkin linked the one from Luna a while back

2020-02-29

<ktemkin> x[0] would be ‘a’
<ktemkin> e.g. imagine you’re declaring a python list with elements such that `x = [‘a’, ‘b’, ‘c’];`
<ktemkin> s/initialization/declaration
<ktemkin> and that makes sense to me; even if I had to quiet the gateware section of my brain a bunch at first :)
<ktemkin> yeah; that can be surprising — but the rationale is to keep initialization order consistent with python

2020-02-28

<ktemkin> you can create a function that manipulates a module, e.g. adding a state
<ktemkin> depends what you mean by "return a bock"
<ktemkin> anyways, sleep for me now
<ktemkin> yeah; that’s what I’m describing — you have two different modules sharing a read port and then two different ones sharing a write port; both alternate as described above (and thus effectively each gets a read port and a write port at half the clock rate)
<ktemkin> (there's also a good summary of what technologies support async/"comb-domain" read and where here: https://github.com/nmigen/nmigen/issues/14)
<ktemkin> dunno if that's a lucid enough explanation to be helpful; I'm exhausted and about to fall asleep
<ktemkin> [you could also in theory use a combinational read port, but usually this is challenging to efficiently map to real hardware]
<ktemkin> or, if you're e.g. leaving your clock domain and have the timing slack, you can capture those output values on the non-active edge of the clock
<ktemkin> you can provide a validity signal (like a chip select) that indicates when the output can be considered valid, which will be high effectively every other read
<ktemkin> but have the output values always be valid
<ktemkin> to indicate when that output is valid, you have two decent choices and one kinda-icky one: you can register the outputs and incur a one-cycle delay
<ktemkin> your read addresses would alternate between A and B; and then produce an output on the next clock cycle -- so you'd have [A address, B output], followed by [B address, A output], flipping back and forth constantly
<ktemkin> and then the same pipeline with "decode" (provide addresses) as your first stage and "write" as the second, on the write
<ktemkin> on the read side
<ktemkin> it sounds like you have a two-stage pipeline, with “decode” (provide addresses) as your first stage and “read-out” (get data) as your second
<ktemkin> I’m on my phone and not in a good position to respond, but
<ktemkin> (in most designs, those ‘events’ generally only exist in simulation; anyway — in most cases, syntaxes like rising_edge are just hints at what the clock is)
<Sarayan> ktemkin: yeah, but in contrast with verilog/vhdl, it's not an event, it's just a state. The only event is the vlock
<ktemkin> it changed, so you know it rose somewhere between the last clock edge and (a setup time before) the current one
<ktemkin> Sarayan: re: “rise”, that’s just a way of saying a value was e.g 0 one cycle and 1 the next
<ktemkin> you can still use python abstraction to reduce duplication
<ktemkin> you’re better off explicitly thinking of it in terms of the decision tree that it is
<ktemkin> any kind of “sequencing” that’s not on the clock edge would be outside the FSM model (and potentially dangerous territory to start thinking in; since the possibility space explodes combinatorially when you allow things to chain)

2020-02-23

<awygle> ktemkin: could be. it does say Lattice Versa Board in the descriptor, but that might be generic somehow, or it gets updated by diamond
<ktemkin> awygle: is your board one that’s never been configured by Diamond? I suspect the FTDI configuration EEPROM is only burned once Diamond sees the board for the first time
<ktemkin> IIRC, by default, BDBUS[0]/BDBUS[1] are tied to the second UART; so yes, ttyUSB1
<ktemkin> IIRC, it'll be the second interface, and thus ttyUSB1
<ktemkin> and yep, checking the RTLIL or back-generating Verilog seems like the best way to figure out which ones they are, if you don't have good guesses
<adamgreig> yes, what ktemkin said
<ktemkin> I assume you just have a few signals that are declared in Complex Enough Ways that they're not being automatically named by nMigen; in which case, it's probably easiest just to look for signals that are likely your missing ones and then set the name argument in their constructors [e.g. Signal(name="hi")]

2020-02-20

<ktemkin> I could also see that being abused; but for things like bus translators, I think I enjoy that duck typing enables that kind of pattern
<ktemkin> so, either `MyModule(utmi_bus)` -or- `my_adapter = ULPIUnwrapper(ulpi_bus); MyModule(my_adapter)`
<ktemkin> or, I can take a piece of adapter hardware that e.g. converts from ULPI <-> UTMI, and pass that _whole module_ in as the argument
<ktemkin> for example, I might have a USB module that works with a UTMI interface; if it accepts that interface as a constructor argument, it be used in the typical way (e.g. grab the bus from platform.request and pass it in)
<ktemkin> one thing I very much like about accepting I/O in the class constructor is that it allows one to do some interface duck-typing, which can be _very_ nice when working with adapter hardware
<ktemkin> for these purposes, anyways
<ktemkin> I mean, docstrings are just fancy comments
<ktemkin> https://github.com/greatscottgadgets/luna/blob/master/luna/gateware/interface/psram.py#L44 <-- I tend to stick a big header explaining my interface in the class docstring
<ktemkin> [that said, I'm in the phase of sleep deprivation where I keep having to wonder if I'm speaking English intelligibly, so take my thoughts with a grain of salt]
<ktemkin> and thus the thing to think about becomes less "is this an IO element I'm going to connect to, or a parameter I'm going to set on instantiation?" and more a question of what you expect to be resolvable at elaboration time vs a signal that'd exist in the created hardware
<ktemkin> My point is mostly that you'll need to scope what can be passed to each of your arguments anyway; so I don't think it's unreasonable to expect the documentation to specify where a Signal/Value is acceptable
<ktemkin> but e.g. most inputs conceptually reduce to parameters if you tie 'em to a constant
<ktemkin> sometimes it Very Much Is ("I want a memory bank that's <this> big")
<ktemkin> I mean, often the delineation between a Parameter and a piece of I/O isn't all that rigid to begin with
<ktemkin> and there are some particularly nice patterns that come with “pass a bus-like object in as a constructor argument”
<ktemkin> especially while we’re lacking sane semantics for something like .connect(), it doesn’t necessarily make sense to squish everything through Signal-like IO boundaries
<ktemkin> yeah, I don’t view constructor arguments as param-only

2020-02-19

<awygle> i figured i would ping ktemkin as well, as they expressed interest

2020-02-17

<ktemkin> trivial and spi-read, since that’s what’s easy on that platform
<awygle> ktemkin: i mean if you have something i'd love to use it :)
<ktemkin> “currently there are no ILAs targeting nMigen” <— depends what level of “sample internal signals on a trigger event and render them visually” you want to consider an ILA >.>

2020-02-16

<ktemkin> that naming, though
<awygle> echoing ktemkin, no rush no pressure
<ktemkin> s/preferential/preferred
<ktemkin> is there a preferential place to capture things like that, beyond in the issue? (in the issue sucks for collaborative/iterative capture)
<ktemkin> I'd be willing to do that
<ktemkin> no pressure; I'm fine waiting -- just wondering if there's something I could be doing to help in the interim
<whitequark> ktemkin: awygle: there's a bit of an annoyance wrt Stream in that I really need to be working on docs right now
<ktemkin> it seems like what's lacking in that GH issue is identification of any weaknesses of the litex::stream architecture that might be addressed when creating the nmigen one
<ktemkin> what needs to be {investigated, discussed, etc} in order to move the stream abstraction forward?
<ktemkin> Er, Enter key
<ktemkin> what needs to be
<ktemkin> awygle: I saw that discussion; but missed any higher-level discussions that may have preceded it (e.g what's in scope for -stdio, etc.)
<ktemkin> I'm at the point where I keep implementing things in e.g. LUNA where it seems like effort might be better spent on doing something more standard/upstream
<ktemkin> were there plans/discussions/etc for -stdio captured anywhere?
* ktemkin eyes nmigen-stdio somewhat guiltily
<ktemkin> related: I need to stop being bad and just implementing things in my own projects' libraries that maybe should be in {nmigen-*} >.>
<whitequark> ktemkin: the changes in question were treated as bugfixes
<ktemkin> dunno if in practice that was interpreted only as applying to the actual API/ABI and not e.g. to the language specification; as that seems like it'd be way out there
<ktemkin> the language is a bit ambiguous as to what'd require a "teeny" (patch) version bump, but particularly the goal of `user can safely upgrade ruby to a new teeny version without having to rebuild and reinstall already installed libraries` seems like it'd preclude them from both meeting their versioning scheme and making breaking syntax changes in 2.1+
<ktemkin> https://www.ruby-lang.org/en/news/2013/12/21/ruby-version-policy-changes-with-2-1-0/ <-- this is roughly what I interpreted as preventing breaking syntax changes over a patch-version
<ktemkin> I think rather fondly back on ruby; but it's very much become one of those languages that I don't think I'd ever pick up again
<ktemkin> yeah; (I'm saying they didn't actually agree to keep anything compatible until something like 2.1, so I never actually saw them -stop-)
<ktemkin> I drifted away from ruby while 2.0 was either upcoming or very new
<ktemkin> lol, yeah; I think I stopped using ruby _before_ they implemented a coherent concept of patch versions
<whitequark> ktemkin: remember how ruby would change syntax in incompatible ways in patch versions?
* ktemkin goes back to writing python
<ktemkin> thank gods we've learned from our mistakes and modern scripting languages never do things like use the same binary name for multiple incompatible language dialects
<ktemkin> (admittedly, when last I checked was like six years ago, but yeah)
<ktemkin> emily: you'd think that 'embedded linux' folks would know better, but when last I checked, running *openembedded* required /bin/sh to be a symlink to bash
<ktemkin> whitequark: yeah, sorry; that wasn't really a suggestion -- my "~"-terminating statements are meant to be tongue-in-cheek
<whitequark> ktemkin: that works individually but then i wouldn't see what most people trying to use it will

2020-02-15

<ktemkin> life hack: put the blinders back on and `dpkg-reconfigurure dash` your way to `bash` being your `/bin/sh`~
<ktemkin> oh gods; it's 2020 and we're still getting bitten by the "everyone links /bin/sh to bash except debian who links to dash by default" thing?
<ktemkin> though I imagine that'd be tricky to implement without also creating a confusing mechanic, given the way clock domains are created
<ktemkin> hmm -- it might be nice to have a clean idiom for passing around clock attributes (like the frequency of a domain's clock signal); that'd allow for nice, clean declarations like `u = UARTReceiver(baud=115200)`

2020-02-10

<ktemkin> lol, yeah
<ktemkin> led going too fast?
<ktemkin> yeah, it's done in `create_missing_domain`
<ktemkin> I don't think the ClockSignal is created if you create the clock domain yourself; lemme look
<ktemkin> (e.g. if you just use sync without explicitly instantiating a ClockDomain for it)
<ktemkin> if the clock domain is automatically created, it's done so with the board's default clock
<ktemkin> (I say in theory because I'm too impatient to give a project to someone else and then -wait- for it to be soldered)
<ktemkin> the engineer who in theory assembles our prototypes put one of those on my desk like a year ago and was like "I put all these together years ago and no one ever even touched 'em"
<ktemkin> it's kinda cute, despite the weird USB routing
<ktemkin> and it just has so many little usb3 PIPE phys
<ktemkin> cuz I’m only five years late to doing bring up on this lil board:
<ktemkin> oh gods: it's 2020 and I'm considering running an nMigen design on a Cyclone 4; someone bring me to my senses
<ktemkin> and everything's off in that picture because I'm sitting across the room on a laptop because I haven't even made my way over there yet today >.>
<ktemkin> it's an infinite collection of distractions
<ktemkin> part of my problem is that my work area looks like this:
<ktemkin> this is the problem with multi-monitor setups sometimes; I can start typing a message about $A and then wind up distracted by reading $A on the other monitor between sentences
<ktemkin> (I wasn't suggesting applicability for a use case as much as leading to they're polar opposite types of elegance; but apparently I can't string two sentences together without being distracted)
<whitequark> ktemkin: the thing is i'm really low on RAM there so i really want NPOT queues
<ktemkin> I like the general (just make all the index pointers wide enough that they won't overflow in the life-age of the universe and then mask off the top of 'em to find the slice you're looking for, and you have a nice async queue that's super readable)

2020-02-09

<ktemkin> and then all the time-space tradeoffs start seeming roughly equivalent in your head, and then you can't talk to anyone about anything because they don't know what the hell a directed acyclic graph is or why it's relevant to a conversation that up until now seemed like it was about writing PIC assembly
<ktemkin> eventually the different levels of abstraction start feeling samey to you, and saying things like "I need to create this FSM in order to get gateware to do the thing I want" feels pretty much like saying "I'm going to create an application-specific processor with essentially these instructions"
<ktemkin> like, assembly instructions are conceptually the same as little encapsulations of register transfers
<ktemkin> eventually it all just feels like building little chains of computational atoms
<awygle> ktemkin: what you describe as your teaching methodology is exactly what was missing from almost my entire education - "why do we care about this thing? what problem was it created to solve?"
<ktemkin> I got _back_ into FPGA's because of Claire's toolchain
<ktemkin> as long as it's implied that I am perpetually completely overwhelmed and thus should be assumed unreliable, sure
<ktemkin> the way I have it structured, I'd start with a schematic capture tool (leaning towards icestudio) until we get to the point where we're doing synchronous sequential logic
<ktemkin> anyway, the way I taught digital logic involved teaching _why_ we model things synchronously the way we do by leading them up to the problem, and then moving to synchronous logic as a -solution- that made things easier
<ktemkin> (basically started teaching out of an irritation at how badly the faculty were doing it, and eventually the university was just like... fuck, well, if you're not going to stop, we'll give you a faculty position)
<ktemkin> like, I learned to teach by observing everything that my teachers fucked up and resolving not to do that
<ktemkin> no, I agree with "people suck at teaching"
<ktemkin> I actually don't think that particular limitation hurts pedagogically
<ktemkin> honestly, I think most people do pedagogy of this stuff _wrong_
<ktemkin> mhm
<ktemkin> beyond the implications of inference
<ktemkin> not enough to be sure I'm seeing it
<ktemkin> and the latter because at least VHDL often tells you to fuck off; where Verilog is just like "okay, yeah, sure, whatever" and then shoots you in the foot
<ktemkin> the former because I wanted to firmly plant the idea of "I'm thinking about creating networks of parallel logic hardware" before they get to anything that looks like programming
<ktemkin> I've historically started with schematic capture in those courses and then moved to VHDL
<ktemkin> yeah
<ktemkin> I've been trying to think of ways to improve that -- but honestly, a lot of it comes from that most people need to learn via inferential steps; and having to learn the way logic behaves while you learn how Python behaves is already a challenge
<whitequark> ktemkin: hmm, can we improve that?
<ktemkin> yeah; I started thinking about converting some of my old FPGA courses to nMigen and have been gradually realizing that people coming in to it kind of have to be a bit more than _reasonably_ proficient at Python
<ktemkin> probably, yeah
<whitequark> ktemkin: i feel like it'd end up being too fragile and/or too magical
<ktemkin> I wonder if there's a nice way to cleanly create a proxy around your module object
<ktemkin> hmm; I think I might like the pattern of having a nested class inside your module that provides your elaboration helpers
<ktemkin> adamgreig: mhm. for something that's "I'm building exactly one type of thing", what you have is probably nicer
<ktemkin> adamgreig: yep; that'd be one way of doing it
<adamgreig> ktemkin: ah, thanks, I think I understand. In my case it would maybe look like the subclasses defining their fields in a regular python data structure first, and then elaborate() could probably be just a parent class default that turns the python object into the relevant nmigen hdl?
<ktemkin> adamgreig: that's mostly been so whatever is instantiating the relevant object can do things like call methods on an instance to customize the generated code
<ktemkin> adamgreig: when it's made sense (e.g. when building a collection of special-function registers with different behaviors), I've captured descriptions into a collection pre-elaboration; and then expanded the behaviors by strumming along e.g. the FSM abstraction during elaborate()
<adamgreig> ktemkin: i'm not sure i follow, or rather, i don't see how you'd do it except in the context of having a module and being in the FSM context. do you generate the states beforehand and just add them all in elaborate?
<ktemkin> adamgreig: when I've done things like that, I've created the relevant pieces declaratively, and then elaborated them into e.g. the FSM DSL in elaborate(); I'm not sure which feels better
<awygle> whitequark: (as you probably guessed, i was following up on ktemkin's comment) the circuit, i suppose? whatever you're attempting to describe in HDL
<ktemkin> yeah; and there's a "dsl cliff" -- a point after which it stops feeling like you're explicitly building thing _with_ python -- that really limits what can be done semantically to provide convenience
<whitequark> ktemkin: agreed, and i think this ties into the current trouble with factoring out chunks of modules into functions
<ktemkin> whitequark: there's too much cognitive baggage in any syntax that parallels `x.eq(y)`; I'd assume any sane semantics would have to either have to look like `splice(x, y)`, or have some kind of `Bus` object that you added connections to _very_ explicitly
<ktemkin> putting a method on `Record` itself seems like it'd definitely be wrong, anyway
<whitequark> ktemkin: right, i'm in the same place re: semantics
<ktemkin> or even around "I want to naively wire up this record to another one"; if that existed, one could e.g. stack a convenience wrapper around Instance that coalesced groups of signals into records
<whitequark> ktemkin: regarding streams? yeah
<ktemkin> re: plumbing exhaustion: it'd be nice if there was a sane equivalent to `.connect`, though I have no idea what its semantics would be
<ktemkin> (I had meant to check if Diamond actually set the trellis-expected descriptors the first time, and these boards were just never-touched-by-Diamond)
<ktemkin> which made openocd not match them
<ktemkin> I got a couple of boards from Lattice without the expected descriptors programmed

2020-02-06

<ktemkin> which is good, since these things only generally wind up being maintainable (and thus maintained) if they're focused rather than trying to provide Everything Related (TM)