ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at · logs at
<awygle> yes
<awygle> "io"
<awygle> will give you pin.i, pin.o, and pin.oe
<Vinalon> oh, 'oe' is 'output enable'?
<awygle> where oe is the tristate control ("output enable")
<Vinalon> cool, thanks!
<whitequark> awygle: the serializers do have very strange limitations on them that i hit in nmigen
<whitequark> er, nvm, too much backlog i missed
<awygle> :)
Vinalon has quit [Remote host closed the connection]
Vinalon has joined #nmigen
<ZirconiumX> 5839 SB_LUT4s, 992 SB_CARRYs. This is gonna be fun
Degi_ has joined #nmigen
Degi has quit [Ping timeout: 264 seconds]
Degi_ is now known as Degi
Vinalon has quit [Ping timeout: 264 seconds]
Vinalon has joined #nmigen
Vinalon has quit [Ping timeout: 240 seconds]
Vinalon has joined #nmigen
<ktemkin> achievement unlocked: wasted four hours probing signals because I typed the wrong clock domain name
<ktemkin> (wouldn't have been four hours except that I tested the design first on a board where the two conflated domains shared a clock; and then was confused why it didn't work on another design; and my brain latched onto "what's different in the hardware, here?")
Vinalon has quit [Ping timeout: 256 seconds]
Vinalon has joined #nmigen
Asu has joined #nmigen
____ has joined #nmigen
<Degi> Ooof
Vinalon has quit [Ping timeout: 258 seconds]
Vinalon has joined #nmigen
Vinalon has quit [Ping timeout: 264 seconds]
adamgreig is now known as agg
FFY00 has quit [Ping timeout: 260 seconds]
FFY00 has joined #nmigen
thinknok has joined #nmigen
thinknok has quit [Client Quit]
thinknok has joined #nmigen
proteus-guy has quit [Ping timeout: 265 seconds]
proteus-guy has joined #nmigen
thinknok has quit [Ping timeout: 265 seconds]
thinknok has joined #nmigen
Vinalon has joined #nmigen
____ has quit [Quit: Nettalk6 -]
<_whitenotifier-3> [nmigen] rroohhh opened issue #350: Ability to use do_program without do_build -
<ZirconiumX> tpw_rules: So as it turns out, having 16 64-bit subtractors in your critical path is a bad idea. Who'd have guessed? /s
<Vinalon> Is it possible to do a logical right-shift on a signed value without changing its Shape or casting it with 'as_unsigned()'?
<Vinalon> maybe by calling a method like __rshift__ instead of using the >> operator?
<Vinalon> or is it best to just use 'as_unsigned()' since it looks like that ... maybe sets a property in the yosys IL?
<ZirconiumX> Right shift will change the shape of a signal, but nMigen will then adjust it to whatever is needed
<ZirconiumX> I think .as_unsigned() >> is about as explicit as you get
<MadHacker> sig = Cat(0,yourSignal[0:30])?
<MadHacker> (might have the wrong slice there)
<MadHacker> Oh, right shift, so Cat(slice[1:30],0) more.
<whitequark> that will change the shape
<whitequark> the output of concat and slice operators is unsigned
<_whitenotifier-3> [nmigen] whitequark commented on issue #350: Ability to use do_program without do_build -
<Vinalon> huh, good to know; thanks
<whitequark> it might make sense to have .as(shape) on Values
<Degi> Hm is there a reason why const * signal doesnt work but signal * const does?
<whitequark> seems like a bug, can you file an MCVE?
<Degi> Hmm wait it seems to be something else.
<Degi> Using bit_select(signal * int, int) doesnt work but word_select(signal, int) does, where the error is "Cannot stop slice 12 bits into 8-bit value"
<whitequark> okay, my response is the same here
<ZirconiumX> Today's gotcha: "-x" produces a carry chain because Yosys lowers it to "0-x"
<whitequark> how else can you lower -x?
<whitequark> I mean, without a carry chain
<ZirconiumX> Mmm.
<ZirconiumX> It's frustrating mostly because I need a single bit from "x & -x" and this produces a 64-bit carry chain
<whitequark> that's just how 2's complement works, no?
<ZirconiumX> Yeah, I guess
<ZirconiumX> I don't actually think there's any better way to extract the least-significant bit
<ZirconiumX> *LS set bit
<whitequark> LS set bit?
<whitequark> are you making something like FF1?
<ZirconiumX> I don't need the bit index, though
<whitequark> but... if you just need the bit itself... isn't this x.reduce_or()?
<ZirconiumX> That tells me "if" there's a set bit, not "where" there's a set bit
<whitequark> oh, you want ff1 but with one-hot output
<whitequark> basically, you want a priority selector
<ZirconiumX> Which is `x & -x`
<ZirconiumX> But doesn't a priority network effectively replicate a carry chain in this instance?
<ZirconiumX> e.g. bit 2 must be 0 if any bits are set before it
<whitequark> yes, I did not understand your requirements, now I do and I agree that's the best way to do it
<ZirconiumX> It doesn't make much sense to me to encode it to a bit index as a pure FF1 to then immediately use a shift to get it back to one-hot
<ZirconiumX> Thus the directly one-hot output
<ZirconiumX> At the cost of flops
<whitequark> yes, sure
<whitequark> I actually needed this primitive recently for something
<whitequark> so, thanks for mentioning it, very useful
<ZirconiumX> yw
<Sarayan> can't you log2() it?
<ZirconiumX> ZirconiumX> It doesn't make much sense to me to encode it to a bit index as a pure FF1 to then immediately use a shift to get it back to one-hot
<ZirconiumX> log2 finds the bit index
<ZirconiumX> I then need to get it back to one-hot
<Sarayan> clear all bits on the left half if any bit is set on the right half?
<ZirconiumX> That's what I'm (manually) rewriting my code to do
<ZirconiumX> So I have 32 32-bit subtractors instead of 16 64-bit subtractors
<Sarayan> urgh
<ZirconiumX> That was my reaction too, since I don't know how to do it any more cleanly
<Sarayan> well, tell me if it makes sense: for every bit pair, and the left one with the inverse of the right one, output the or of the two
<Degi> whitequark: Should I post the MCVE as a bug report on nmigen?
<Degi> And is there something like a default platform?
<Sarayan> then for every pair of pairs, and individually the left pair if the right one or is 1, output the or of the or output of the two pairs
<Sarayan> etc, recursively
<Sarayan> log2(n) steps
<Sarayan> e.g. you build a "clear left" signal and apply it in parallel
<ZirconiumX> Sarayan: So basically you've just created a look-ahead carry in logic :P
<Sarayan> possibly, I don't know how these things work
<whitequark> Degi: yes, please post a bug report
<whitequark> re default platform: there isn't
<whitequark> such a thing would not make a lot of sene
<whitequark> *sense
<whitequark> for example, not all of our platforms even have the same input format for the netlist
<ZirconiumX> Yosys takes RTLIL, while Quartus takes Verilog, for example
<whitequark> yup
<whitequark> and different tools take different flavors of Verilog, too
<ZirconiumX> Would simulation with e.g. cxxrtl get a platform?
<whitequark> Quartus needs a workaround applied
<ZirconiumX> Because it sucks
<whitequark> hey, we're doing EDA here. all of our tools suck, almost by definition
<ZirconiumX> No, it sucks even by EDA standards
<whitequark> nMigen is the (wannabe?) C89 of HDLs! do you think I like C89? :p
<whitequark> ha
<whitequark> okay fair
<Degi> Hm do unused signals get ignored and lead to no used gates at the end?
<ZirconiumX> Unless you count taking a minute to build blinky as "reasonable"
<ZirconiumX> Unused signals are kept at reset value
<ZirconiumX> If they're never driven they'll likely become constant drivers
<ZirconiumX> If they're never used they'll get pruned entirely
<Degi> Neat okay
<whitequark> s/likely//
<whitequark> there's explicit code to do that
<Degi> Hm okay signal * int vs int * signal doesnt make a difference but bit_select vs word_select does. Issue almost done
<_whitenotifier-3> [nmigen] x44203 opened issue #351: bit_select and word_select behave differently -
<ZirconiumX> The one thing I dislike about VS Code is that the language server completely fails to analyse nMigen's stuff
<whitequark> hm
<whitequark> can we fix that?
<ZirconiumX> I think it would be a bit painful to do
<ZirconiumX> e.g. VS Code has problems with docstrings
<whitequark> that seems pretty bad
<ZirconiumX> Though I think it's just entirely failing to find where nMigen is actually installed
<ZirconiumX> Which is not great either
<ZirconiumX> e.g. "from nmigen import *" gives me a *lot* of code errors because it can't find any of the nMigen prelude
<ZirconiumX> (is prelude the right term in Python?)
<whitequark> it's not a Python term, but it is what it is called in nMigen
<awygle> Re: default platform, there's an issue about simulating with platform effects which I'd argue is related
<whitequark> yes
<whitequark> that's why the simultaor doesn't currently inherently mandate a platform
<awygle> Which ironically probably harms the most common case. But there's no obviously good solution currently.
<whitequark> oh?
<whitequark> which common case?
<awygle> "I want to generally check that this thing works but I'm depending on e.g. platform.default_clk_freq or something so I can't simulate it (without adding a bespoke simulation path to the module)"
<awygle> Maybe it's just me that keeps hitting this kind of thing lol
<whitequark> hm
<whitequark> but you usually don't want to use platform.default_clk_freq anyway
<whitequark> for example, say you have a 1 us delay and your default clk is 100 MHz
<whitequark> good luck waiting for your sim to finish
<whitequark> glasgow has a special hack for that case IIRC
<whitequark> this might change somewhat with cxxrtl
<awygle> Sure. I just want to be able to set a "sim platform clock" outside the module rather than inside it
<awygle> Or whatever. Maybe it's a pin. I want to be able to construct a testbench platform I guess.
<whitequark> yes, that is a valid request
<whitequark> and that's why there's no simulation platform! you can elaborate with whatever platform you decide is needed
<whitequark> with cxxrtl i think you could eventually even test with vendor IO primitive libs
<awygle> Which would be great
<ZirconiumX> Sarayan: One note is that if targeting, say, LUT4s, it's more like log4(n)
<_whitenotifier-3> [nmigen] rroohhh commented on issue #350: Ability to use do_program without do_build -
<_whitenotifier-3> [nmigen] whitequark commented on issue #350: Ability to use do_program without do_build -
<Vinalon> Is "Cat( bits[ a:b ], bits[ c:d ], ...)" the best way to unpack non-contiguous bitfields from one signal into another?
<ZirconiumX> Yep
<whitequark> you can use a Record
<whitequark> packing/unpacking bitfields is just about the only thing Record is actually *good* at
<_whitenotifier-3> [nmigen] rroohhh commented on issue #350: Ability to use do_program without do_build -
<Vinalon> neat, thanks
<_whitenotifier-3> [nmigen] rroohhh edited a comment on issue #350: Ability to use do_program without do_build -
samlittlewood_ has quit [Quit: samlittlewood_]
<ZirconiumX> I'm gonna try using a fairly simple "Nth output bit = Nth input bit & ~input[:N].bool()" and hope the synthesis tool reuses terms
<whitequark> wouldn't the carry chain be faster?
<whitequark> since it's using dedicated routing
<whitequark> oh, do you want to parallelize it?
<ZirconiumX> Yeah
<whitequark> sounds reasonable. if that fails you could also use a fold
<whitequark> reduce() in python
<ZirconiumX> With the hope that the synthesis tool turns it into ~log(N)
<_whitenotifier-3> [nmigen] whitequark commented on issue #350: Ability to use do_program without do_build -
<awygle> ~log(N) should mean exp(N), cmv
<whitequark> i don't get it
<awygle> ~ as negation. the opposite of log is exp
<awygle> it wasn't what you'd call... a _good_ joke
<whitequark> oh
<awygle> wq, nmigen got rid of "act" for FSMs as present in migen, was there a reason for that or it just fell away with the stack-based context-manager approach
<whitequark> "act" became "with m.State", no?
<_whitenotifier-3> [nmigen] rroohhh commented on issue #350: Ability to use do_program without do_build -
<_whitenotifier-3> [nmigen] rroohhh closed issue #350: Ability to use do_program without do_build -
<awygle> yes, i'm just wondering if that was because of an inherent issue with "act" that required it to be rewritten in such a way
<awygle> basically, "if i revive the notion of 'act' in my HSM thingy i'm writing will i be setting myself up for failure"
<whitequark> I don't think anything besides the name changed?
<whitequark> oh
<whitequark> do you mean the inability to append statements to existing states is something you dislike?
<awygle> it might turn out to be, i mostly wanted to get insight on what the differences _are_ (that being one major one that i'd forgotten about)
<whitequark> there should be no other differences
<awygle> this is motivated by Record seeming like a good idea :p
<awygle> mk, cool
<vup> one problem with VS Code (and probably any IDE) and nmigen is that autocompletion doesn't work for Record fields, but that is probably hard to fix without generating something like pyi stub files
<whitequark> awygle: we could perhaps allow that again
<whitequark> I'm not strongly opposed to it, it just seemed like a more reasonable default course of action
<awygle> whitequark: i'm going to be generating HSMs at a lower level than the nmigen FSM DSL, because i want to be able to store states and stuff like that, so it doesn't particularly affect my immediate plans
<whitequark> awygle: what do you think about coordinating to improve the FSM DSL?
<awygle> whitequark: i would love to do that, and my current shenanigans are viewed at least partially as a prototyping effort
<whitequark> gotcha, good luck with the prototype
<awygle> thanks
<whitequark> I would be happy to incorporate your findings upstream
<awygle> i am having a lot of fun
<awygle> i hope it turns out to be useful lol
<whitequark> the current FSM syntax really is very limiting, and the implementation is kind of crummy too
<whitequark> for one, FSMs should be first class objects (but still not submodules!)
<awygle> agreed
<whitequark> emily has been talking a bunch about how the "" thing is really inconsisstent, and I agree there
<awygle> i also
<whitequark> right. so, FSMs were designed before enums, and I think we can actually make it generate an enum internally
<whitequark> and then lean on Python for most of the rest
<whitequark> like mapping names to state values and so on
<awygle> how do enums currently work in nmigen?
<awygle> or do they?
<whitequark> they totally do
<awygle> i was wondering in a vague way how to get a nice vcd output with real state names lol
<whitequark> you can literally just use an enum
<awygle> sweet
<ZirconiumX> Praise be
<whitequark> for built-in FSMs there is some code that does it without a enum
<whitequark> but also
<whitequark> for any signal you can specify Signal(decoder=lambda value: ...)
<awygle> oooooooo awesome
Vinalon_ has joined #nmigen
<awygle> damn wq, you do excellent work :D
<whitequark> this will even embed a mapping into generated RTLIL if you're matching on that signal
<whitequark> and it'll end up in verilog as comments
<whitequark> if yosys had first-class enums in RTLIL i would use those, but alas
Vinalon has quit [Ping timeout: 265 seconds]
<awygle> alas and alack, a lack
<whitequark> if you use pysim, you can stick an entire RISC disassembler into the decoder
<whitequark> boneless does that
<whitequark> you actually see the instructions in VCD files
<ZirconiumX> Holy shit, wow
<awygle> my brain autocompleted RISC-V and then had a nearly-audible cache flush when it hit "boneless"
<whitequark> lmao
<whitequark> this is a bit like the filter feature of gtkwave
<whitequark> but ... the filter feature of gtkwave also kind of suck
<awygle> i love gtkwave, but i also kind of... don't love gtkwave
<whitequark> (the VCD files that use decoders do rely on gtkwave-specific features)
<whitequark> yes
<whitequark> exactly
* ZirconiumX wonders if a chessboard displayed in GTKWave is more or less impressive
<whitequark> it's really fast, and it does the job, but also, uuugh
<whitequark> for a first of its kind OSS tool i guess that's ok
<awygle> one of my "i am tired of doing what i'm supposed to do so i'm gonna do something else instead" projects was rendering waveforms using a deferred rendering shader thingy on the GPU
<whitequark> but we really need something less uuugh
<whitequark> azonenberg did that
<whitequark> pulseview sooooort of does that i think
<awygle> yeah but azonenberg's is a bit different because it does analysis in a compute shader
<whitequark> pulseview does it pretty badly unfortunately
<awygle> mine was pure rendering
<awygle> under the continued intention of someday producing an interactive simulator
<awygle> (also mine was vulkan but that's irrelevant except that it was fun)
<tpw_rules> is there a way to make a Resource with Subsignals that are just regular old signals? in one case the Resource hooks up to the platform pins but in another case it needs to come from somewhere else so i'd like to make a fake Resource
<Vinalon_> Does the 'Arbiter' class in 'nmigen_soc' work by forwarding the 'cyc' signal to a different subordinate bus on each clock tick, or am I reading that wrong?
<Vinalon_> oh...sorry, that was terrible timing. D'you mean for simulating a Resource when there is no platform?
<tpw_rules> i guess?
<whitequark> Vinalon_: (arbiter) that's the basic idea, but it is slightly more complex than that
<whitequark> tpw_rules: do you need it to be available via .request or not?
<tpw_rules> in the second case i have to do verilog.convert so i'm not actually sure what the Plarform would be
<tpw_rules> that was the hope, so i could set it up in the top module and then request it somewhere in the core like before
<whitequark> hm
<Vinalon_> I've used 'dummy' classes with signals that have the same name/shape as the Resource, like 'o'/'i'/'oe' for an i/o pin...but then you have to instantiate a class instead of calling '.request'
<whitequark> there's no "generic Verilog" platform currently because there's no generic Verilog
<whitequark> but
<whitequark> maybe it's time to compromise on that somewhat and make `vendor.generic`
<whitequark> that would use `inout` signals instead of instantiating io buffers
<whitequark> regarding 'dummy' classes
<whitequark> take a look at
<whitequark> that's what Resources actually use internally
<tpw_rules> is that even a reasonable design pattern? say i make a UART deal deep in the core somewhere. should it just do platform.request("uart") or should i bring the signals all the way out to the top and hook them to the platform there?
<whitequark> you can do either, really
<whitequark> it depends on what you want from your design
<whitequark> for example if you are making a one off then requesting signals from wherever is basically fine
<whitequark> but if you are making something more flexible you probably want one place to configure all your peripherals from
<Vinalon_> speaking of, is there a good way to access the pin numbers associated with Connector resources?
<Degi> Like package pin numbers?
<Vinalon_> well, the values that get populated in board files
<whitequark> hmmm
<whitequark> no, there's no backwards mapping
<whitequark> wasn't a design goal, but we can change that
<Vinalon_> like the icestick has, `Connector("pmod", 0, "78 79 80 81 - - 87 88 90 91 - -")`; it sounds like you can't easily write logic to get Pin objects for each wire on the PMOD connector?
<Vinalon_> instead you'd have to manually append them to the resources array?
<Degi> Cant you do Pins("pmod:4") for example to get 81?
<Degi> I think its "pmod_0:4"
<Vinalon_> oh, can you? I guess I didn't look too closely at how it decodes names, thanks
<whitequark> oh, I misunderstood what you want
<Degi> For example I have something like platform.add_resources([Resource("uartrx", 0, Pins("J_30:7", dir="i"), Attrs(IO_TYPE="LVCMOS12"))])
<Degi> Then you can get the pin by doing platform.request("uartrx").i that gives you the signa
<Degi> l
<Degi> (I think the number after J_30 is 1-indexed)
<Vinalon_> ohhhkay, so you can get the pin numbers associated with a connector, but it doesn't automatically set them up as IO pins or anything?
<Vinalon_> that makes sense, thanks. I don't think I quite understood what I wanted to ask, either
<ZirconiumX> 9110ps (iCE40HX) before with `bb & -bb`, 3515ps afterwards with the .bool() stuff
<ZirconiumX> And area is way down too
<ZirconiumX> Took a while to get implemented due to getting distracted, but I'm glad this worked out
<Degi> How do you measure the time?
<ZirconiumX> Which actually means this still holds iCE40 timing. Or, well, would if it fit on the chip
<ZirconiumX> Degi: `sta` from the Yosys `eddie/sta` branch
<ZirconiumX> Run it post-synthesis
<Degi> So it is theoretical timing?
<cr1901_modern> Is the CEInserter decorator still in nmigen?
<ZirconiumX> Theoretical, yeah
<ZirconiumX> cr1901_modern: I think it's EnableInserter
<cr1901_modern> works for me
<Degi> Where can I find that branch?
<Degi> Nvm found itr
<ZirconiumX> Degi: Well, kinda theoretical. It's using the worst-case logic timings, so it's like an upper bound
<Degi> Hm yes thats what I wanted to know. I think theoretical models usually do that. You dont want your design randomly failing lol
samlittlewood has joined #nmigen
<ZirconiumX> Essentially if you can't meet timing with `sta` (which assumes *zero* routing delay), you're not getting far with nextpnr
<Degi> How would I get sta from there? Do I need to download the git repo and build the whole thing?
<ZirconiumX> Yes
<ZirconiumX> I actually have a frankenbranch which is essentially "the version of Yosys I use for my stuff" which has a lot of experimental patches in there
<ZirconiumX> With things like Intel synthesis support and Gowin ABC9
<ZirconiumX> *sane Intel synthesis support
<ZirconiumX> ..Question: how cursed is it to simulate a stack by recursive module instantiation?
<ZirconiumX> Which requires instantiating module X as a submodule for module X
<ZirconiumX> Up to a limit, anyway
<whitequark> why not?
thinknok has quit [Ping timeout: 265 seconds]
<ZirconiumX> The idea being that it essentially unrolls the entire thing into a new instance
<ZirconiumX> I don't know how that would be done sequentially
<ZirconiumX> (which would be nice for area's sake >.>)
<ZirconiumX> The problem is that I'd need very, *very* wide memories
<ZirconiumX> Or else expend cycles spilling state to stack
<whitequark> recursive submodules should work just fine
samlittlewood has quit [Remote host closed the connection]
<ktemkin> wrote this line in a little section of (synthesized) test code, and my brain is just wriggling at how weird this construct feels:
<ktemkin> usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0)
<ktemkin> part of my brain is just "you're setting a signal from an environment variable? what abstraction barriers have you transgressed?"
samlittlewood has joined #nmigen
<whitequark> strangely, i think you can do the exact same thing in verilog
<daveshah> Yes, you can
<daveshah> (SystemVerilog at least)
<whitequark> i remember reading bout it but i can't find the ystem tak
<whitequark> system task
<ktemkin> I assume you're talking about DPI, which has a similar brain-feeling, except it feels -unclean- at the same time >.>
<daveshah> Yeah, I was thinking about DPI
<daveshah> (this doesn't work in Yosys atm as string DPI arguments aren't supported)
<ktemkin> (there might be a system task that'd work, but I don't remember one off the top of my head)
cr1901_modern has quit [Read error: Connection reset by peer]
<whitequark> hm, you're right, you have to use DPI
<whitequark> I must be misremembering
samlittlewood has quit [Remote host closed the connection]
cr1901_modern has joined #nmigen
samlittlewood has joined #nmigen
Asu has quit [Quit: Konversation terminated!]
<_whitenotifier-3> [nmigen] whitequark commented on issue #351: bit_select and word_select behave differently -
samlittlewood has quit [Remote host closed the connection]
samlittlewood has joined #nmigen
samlittlewood has quit [Client Quit]
<ZirconiumX> I have officially broken out `eval` to do code templating
samlittlewood has joined #nmigen
<whitequark> welcome to the club
<whitequark> that said... do you actually need that with nmigen?
<ZirconiumX> <-- I have code that looks like this (but repeated 16 times instead of 4)
<ZirconiumX> Where the only difference is the direction
<ZirconiumX> And I don't know of a better way to do it
<ktemkin> one thing that might help might be to bundle your signals up e.g. by name, in a dict
<ktemkin> but without any restructuring, you can grab locals by name with locals() and your local object properties with getattr()
<awygle> one thing I do like about python is how abusable it is in those kinds of ways
* whitequark stares at ktemkin and awygle
* whitequark stares at the medical ethanol canister
<whitequark> ZirconiumX: are you sure you can't factor those out into a function?
<whitequark> like ktemkin says, yeah
<whitequark> {"south": (south, south_lsb, slide_south), ...}
<whitequark> then loop over the dict
<awygle> Look, if you're gonna abandon everything good about language design from the last two decades, you might as well go all the way
<whitequark> hey, python has lexical scope!
<ZirconiumX> This is probably quite cursed
<awygle> I thought python specifically didn't have lexical scope
<whitequark> closures! memory safety!
<whitequark> hm, how so?
<awygle> Mm I think I just misremembered
<whitequark> ZirconiumX: slghtly cursed
<ZirconiumX> Abusing introspection for fun and profit
<whitequark> oh wait, i missed local()
<whitequark> locals()*
<whitequark> that is *very* cursed
<ktemkin> it's not as cursed as it would be if you were modifying the locals dict
<ktemkin> just following it and prodding it's objects is relatively milquetoast
<ZirconiumX> There's very specifically a warning about that in the docs
<ktemkin> *its objects
<ktemkin> "if you're gonna abandon everything good about language design from the last two decades" <-- for one-offs made for the hell of it, there's something cathartic about not having to care what's a good idea
<awygle> ktemkin displaying her scars there, re: "milquetoast"
<whitequark> i don't think i've ever used locals()
<ZirconiumX> This might be worse if we were using, say, Lua
<ktemkin> locals() is kind of like eating something that's been dropped on the ground; eval() is like reaching down and eating a handful of dirt
<ZirconiumX> I mean, building the dict is the sanest approach, but also requires the most typing
<whitequark> ktemkin: hey, pysim uses eval in a reasonable way.
<whitequark> i actually wrote it with lambdas first but it was too stupidly slow for that
<ZirconiumX> Kinda missing generalised shift and/or rotate right about now...
<whitequark> generalized?
<ZirconiumX> x << N if N > 0 else x >> -N
<ZirconiumX> where N is constexpr
<whitequark> ah, hm
<whitequark> you can implement those yourself, right?
<ZirconiumX> Short enough to write a lambda function for, but yeah
<whitequark> for rotates, it's also a very small patch upstream
<whitequark> since we decided to provide only const rotates, it just needs to lower to Cat()
<ZirconiumX> (meow)
<whitequark> heh
<ZirconiumX> I feel like I'm going to end up adding a bunch of small bit tricks to nMigen
<whitequark> sure, why not
* ZirconiumX wonders at what point it becomes "there's a builtin for that: the HDL"
<whitequark> i'm not sure if i'll accept all of them, but i'll take a look at all of them
<ZirconiumX> Would I catch rotate by variable by checking if the RHS is a Value, or is that not enough?
<whitequark> I would do `isinstance(rhs, int)`
<ZirconiumX> Do you think just rotate left is enough?
<ZirconiumX> Or would you want rotate right too?
<whitequark> I would do both, like we have both shifts
<whitequark> I would expect most uses of rotates to be for things like CPUs or crypto algorithms where you want both
<Degi> Hmm maybe a medical ethanol canister was involved in the creation of that code?
<ZirconiumX> ...I'm having problems formulating this in terms of Cat() because I'm used to formulating it in terms of shifts...
<whitequark> what code?
<ZirconiumX> Degi: ^
<Degi> I was referencing the thing whitequark said 57 min ago
<Degi> whitequark: What do you mean with that the codegen for word_select appears broken too? Is it still usable as in the
<Degi> description of it?
<whitequark> your code compiles to a nop
<whitequark> take a look at the verilog or rtlil
<_whitenotifier-3> [nmigen] ZirconiumX opened pull request #352: Add rotate by constant -
<ZirconiumX> Here're rotates, whitequark
<anuejn> whitequark: is it intendet that calls to with do_build=False fail if the toolchain is not installed?
<whitequark> hm
<whitequark> that's an oversight
<whitequark> there's an annoying corner case where you actually do need yosys to run .prepare()
<anuejn> hm... but could we then just require yosys to do prepare?
<anuejn> should i file an issue?
<whitequark> the problem is that the yosys dependency is implicit in emit_debug_verilog
<whitequark> I... guess we can just explicitly require yosys, yeah
<_whitenotifier-3> [nmigen] codecov[bot] commented on pull request #352: Add rotate by constant -
<_whitenotifier-3> [nmigen] codecov[bot] edited a comment on pull request #352: Add rotate by constant -
<anuejn> nice :)
<_whitenotifier-3> [nmigen] codecov[bot] edited a comment on pull request #352: Add rotate by constant -
<whitequark> the toolchain_env_var check is also an issue there
<whitequark> because if you're not doing the build, you might as well not have the environment vars set
<whitequark> let me fix tht
<_whitenotifier-3> [nmigen] codecov[bot] edited a comment on pull request #352: Add rotate by constant -
<anuejn> yup thats what i have actually hit :)
<anuejn> thanks
<whitequark> is it?
<anuejn> what if the filename starts with ./..
<whitequark> normpath should handle that
<anuejn> ah thanks, sorry
<whitequark> this check is a sanity check, not a security check, because you're running an arbitrary shell script anyway
<whitequark> it just makes sure that you didn't have a weird relative path by accient from some other code
<anuejn> yeah ok
<awygle> why do languages provide else
<awygle> isn't it just syntactic sugar for if !<expr>
<awygle> sounds like it belongs in the stdlib to me
<ZirconiumX> "because typing the same expression but inverted is annoying and painful"
cr1901_modern1 has joined #nmigen
<whitequark> awygle: may i introduce you to: old versions of cmake