ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at · logs at
Degi_ has joined #nmigen
Degi has quit [Ping timeout: 256 seconds]
Degi_ is now known as Degi
SpaceCoaster has quit [Quit: ZNC 1.6.5+deb1+deb9u2 -]
SpaceCoaster has joined #nmigen
proteus-guy has quit [Ping timeout: 258 seconds]
proteus-guy has joined #nmigen
proteus-guy has quit [Ping timeout: 265 seconds]
proteus-guy has joined #nmigen
proteus-guy has quit [Ping timeout: 260 seconds]
proteus-guy has joined #nmigen
Vinalon has quit [Ping timeout: 260 seconds]
Vinalon has joined #nmigen
_whitelogger has joined #nmigen
rohitksingh has quit [*.net *.split]
Ultrasauce has quit [*.net *.split]
awygle has quit [*.net *.split]
Ultrasauce has joined #nmigen
rohitksingh has joined #nmigen
awygle has joined #nmigen
thinknok has joined #nmigen
Asu has joined #nmigen
thinknok has quit [Ping timeout: 256 seconds]
thinknok has joined #nmigen
proteus-guy has quit [Ping timeout: 256 seconds]
thinknok has quit [Remote host closed the connection]
thinknok has joined #nmigen
Vinalon has quit [Ping timeout: 240 seconds]
proteus-guy has joined #nmigen
<whitequark> Sarayan: glasgow works with nmigen for a while
<whitequark> awygle: nope
<whitequark> what do you expect that to do?
<whitequark> if you want 'x, there is no 'x
<awygle> Just inform the synthesizer
<whitequark> right, so, you want 'x
<whitequark> the problem here is what happens if you're wrong?
<awygle> "Hey buddy there's no need to worry about this case"
<whitequark> if the synthesizer assumes the case is unreachable, you get UB
<whitequark> nMigen promises you won't get UB
<awygle> Sure
<awygle> Reasonable
<whitequark> so there's no way to mark a case as unreachable, currently
<whitequark> however
<whitequark> I was considering something like `m.Case(..., unsafe_unreachable=True): pass`
<whitequark> well
<whitequark> this has to translate to (* full_case *) so not quite that syntax
<awygle> I put in an assert if the platform is formal and pulsed an error line otherwise. I don't need max performance here and that communicates intent
<whitequark> yup, that's what i would suggest if you don't want to eliminate the case
<whitequark> IMO, synthesizer should take into account assert cells
<awygle> That'd be nice
<awygle> Someday
<awygle> Unrelated, when you built your vapor phase system did you pay retail for galden or is there a generic that's more reasonably priced?
<awygle> Or is this one of those "cheap outside the US" things
<whitequark> i got the galden for free from someone on IRC who got it on a trade show
<awygle> Ah OK, thanks
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
<ZirconiumX> whitequark: what would happen if you `pass` inside a m.Case() at the moment?
<whitequark> ZirconiumX: case that does nothing
<ZirconiumX> I suppose that's not exactly equivalent to 'x
<ZirconiumX> "this can't happen" versus "this does nothing"
<ZirconiumX> But doing nothing is at least defined behaviour, right?
<ZirconiumX> So I guess the "safe" option is m.Case(): pass
<awygle> Yup
<whitequark> yep
<Sarayan> hmmmm
<Sarayan> I don't have a serial cable (I think), I wonder if the pi3 can do console over usb
<Sarayan> I don't even know if console over usb is possible
<ZirconiumX> It'd appear as /dev/ttyUSB
<whitequark> linux can do that in principle
<whitequark> no idea if pi specifically can do it
<Sarayan> ZX: USB-A on the desktop, micro-usb on the pi2, that's theorically not how it's supposed to go but the pi3 may be otg
<ZirconiumX> *oh, right*
<daveshah> The schematic shows the micro B port as having the data lines disconnected
<ZirconiumX> I thought you meant Pi3 as host ^.^;;
<Sarayan> I want to torture the kernel of the pi3
<ZirconiumX> I was always taught not to connect two computers by USB >.>
<Sarayan> daveshah: You're looking at the power connector, but there are two other ones, aren't they?
* Sarayan goes pick up his toy
<daveshah> I don't know which pi3
<daveshah> but usually the other ports are after a hub
<daveshah> which I don't think would work in the "wrong direction"
<daveshah> unless there is some magic config register or something
<Sarayan> ah fuck no, they're A too
<Sarayan> I misremenbered
<Sarayan> never saw an A OTG
<daveshah> It can be doable if they are directly connected to the SoC and you can set up the driver appropriately
<daveshah> but the hub makes things quite a bit trickier
<Sarayan> yeah
<Sarayan> if it was otg it could reverse, that's pretty much what otg is, but full-size A never is otg
<whitequark> i mean, people have made worse things with usb than making full-size A OTG
<whitequark> so i wouldn't say "never", but "very unlikely"
<Sarayan> huhuhu, and if the pi3 was fpga-based the discussion would be different :-)
<Sarayan> I don't think there's another pi3 model than b+
<Sarayan> doesn't matter though
Vinalon has joined #nmigen
Asu has left #nmigen ["Konversation terminated!"]
rohitksingh has quit [Ping timeout: 240 seconds]
____ has joined #nmigen
ianloic has joined #nmigen
<ianloic> fairly noob nmigen question: I'm playing with doing auto synthesis so I need to derive a bunch of 48Khz derived signals (eg 1536Khz i2s bit clock) and I'm playing with ice40 based boards which have a 12Mhz clock.
<ianloic> In verilog I just defined some signals I passed around and used `always @(posedge something)`
<ianloic> with nmigen there's the idea of clock domains - should I be using them instead?
<ZirconiumX> ianloic: Generally not
<whitequark> you shouldn't use derived clocks for cases like this either in nmigen or in verilog
<ZirconiumX> I can't quite divide 12MHz by 48KHz, but I think you could do it for a 24MHz iCE40 clock
<whitequark> huh? 48k = 12M / 250
<ZirconiumX> I missed an "in my head"
<whitequark> ah
<ianloic> to get the bit clock IIRC I used `icepll`
<ZirconiumX> You don't need a PLL for this
<whitequark> ianloic: the issue here is that you cannot, in general, read a value produced in one clock domain, in another clock domain, without any precautions
<whitequark> this isn't nmigen-specific; it's just as true in verilog
<ZirconiumX> Anyway, you have a counter that counts up (or down?); every 250 cycles you reset it and have a Signal for when the counter is equal to zero
<whitequark> ^ do that instead
<ZirconiumX> And your 48KHz logic now runs synchronous to your iCE40 clock
<ianloic> and then in `m.d.sync` if it's zero do a thing?
<ZirconiumX> Yep, with m.If or whatever
<ianloic> awesome
<ZirconiumX> 1536KHz is a bit awkward though
<whitequark> you can use a frac-N synthesizer
<tpw_rules> i've always thought so but haven't been able to check; are tools smart enough to relax timing for all the logic run on that enable?
<ZirconiumX> tpw_rules: no, they can't
<whitequark> tpw_rules: you can't do that, in general
<tpw_rules> why not?
<ianloic> how should I write my modules so that they run at predictable frequencies regardless of the underlying clock frequency of the device?
<tpw_rules> pass in a clock rate to the constructor and calculate constants appropriately
<ZirconiumX> ianloic: in general you have to depend on the underlying clock
<ianloic> can I parameterize it somehow?
<ZirconiumX> Though there's platform.default_clock which I *think* tells you the frequency of the device you're on
<ZirconiumX> (in hz)
<ianloic> *nod*
<whitequark> ianloic: sure, you're writing ordinary python code
<whitequark> pass it to __init__
<whitequark> use it in elaborate()
chipmuenk has joined #nmigen
<ianloic> @ZirconiumX: platform.default_clock went away
<ZirconiumX> ianloic: But you're going to have to accept some level of imperfection. On an iCE40 you generally get 12/24/48MHz frequency because of SB_HFOSC, but what about a Cyclone V which defaults to 50MHz?
<ZirconiumX> Do you accept a 50kHz audio clock?
<ianloic> aha platform.default_clk_frequency
<ianloic> if I can adjust the size of the counter I use I should be able to get fairly close I think
<whitequark> ZirconiumX: you can use a frac-N synthesizer to get closer to the desired freq, at the cost of some jitter
<ianloic> @whitequark do you have a pointer to frac-N synthesizers?
<whitequark> ianloic: do you know how fixed point arithmetics works?
<ianloic> somewhat
<ianloic> like using 8 bits for the fractional part of a number and 8 for the integer part and putting them in a 16 bit value
<ZirconiumX> This seems like something that would be useful in nmigen.lib
<whitequark> yup
<whitequark> (to ianloic)
<ianloic> (and we just do regular maths on it because division is commutative etc)
<ZirconiumX> (though don't do division in an FPGA if you can avoid it)
<ZirconiumX> Or, at least combinational division
<ianloic> (at least regular addition and subtraction)
<whitequark> so, the problem with getting 48 kHz from 50 MHz is that it is not evenly divisible by the former
<whitequark> that is, if you try to divide 50 MHz by 1041, you get 48030.73 kHz instead of 48000.00 kHz
<whitequark> in other words, during each period of the derived clock, you accumulate some error
<whitequark> if you add more bits to your counter after the fractional point, you can track this error, so that the average frequency of the derived clock is closer to your desired one
<whitequark> of course, no individual period would be exactly 1/48000 s; you would get some that are slightly longer and some that are slightly shorter
<ianloic> and there's still going to be error but you can be a whole lot closer if you're tracking the error
<whitequark> precisely
<whitequark> you can get the long-term error arbitrarily small with enough bits in the counter, i think
<whitequark> but given that ordinary crystals are something like ±20 ppm at best, it makes no sense to try and do better than that in most designs
<tpw_rules> ooh, so i'm now a frac-N pll developer
<ianloic> I think the phase accumulator I built to generate audio waves at various frequencies is a similar idea
<whitequark> yep
<awygle> ZirconiumX has a point, is something like that in scope for nmigen.lib?
<whitequark> awygle: ZirconiumX: not sure, if it's general enough, yes
<whitequark> but i think frac-N synthesizers is an entire area on their own
<whitequark> so it's not like an async FIFO where virtually everyone really uses one design
<ZirconiumX> One could make that argument about, say, hash tables, but writing your own is tedious
<whitequark> the reason hash tables are in standard libraries is that associative arrays are a pervasive data structure you see in almost every program
<whitequark> so even though there is a lot of subtlety there, you really kinda have to pick at least some
<whitequark> it's like sorting algorithms
<whitequark> whereas frac-N synthesis is not uncommon but certainly not something nearly every design needs
<ZirconiumX> I've yet to write a design that uses CDC now that I know how little I need it
<ZirconiumX> I've never actually touched the FIFOs in nmigen.lib
<ZirconiumX> So I wouldn't say CDC primitives are "something nearly every design needs"
<tpw_rules> good fifos are great
<whitequark> the reason CDC primitives are in nmigen.lib is different!
<tpw_rules> i'm very glad they're there
<ZirconiumX> I'm not saying they shouldn't be
<whitequark> specifically, the reason for CDC primitives in nmigen.lib is that you can't put them elsewhere
<whitequark> because they have to integrate with the vendor code
<whitequark> there are three kinds of code that should live in stdlib: (1) something that can't be put elsewhere, (2) something that is so pervasive that not providing it is a major usability issue, (3) something that is less pervasive but so uncontroversial that you might as well provide an implementation for everyone already
<whitequark> in C, stdint.h is (1), qsort is (2), and printf is (3)
<ianloic> what's the idea for distribution of community maintained libraries for nmigen? PyPI?
<whitequark> (tbh the split between (2) and (3) is fuzzy and often debatable)
<whitequark> sure
____ has quit [Quit: Nettalk6 -]
rohitksingh has joined #nmigen
chipmuenk has quit [Quit: chipmuenk]
thinknok has quit [Ping timeout: 260 seconds]
<ianloic> my brain is failing me right now - I blame the preschoolers whining next to me.
<ianloic> whitequark: I'm struggling to actually design the fractional-N synth. the idea is that the counter is a fixed point value?
<ianloic> and each master clock cycle it increments by 1.0
<ianloic> but then when it exceeds the period instead of zeroing it you just subtract the fixed point period value?
<tpw_rules> each cycle it increments by the fraction
<tpw_rules> then when it overflows, you pulse the clock a cycle later
<ianloic> what's the best way to notice overflow? add into a wider value and compare?
<ianloic> in a CPU I'd add and an overflow flag would be set
futarisIRCcloud has joined #nmigen
<Vinalon> with addition/subtraction, I think you can calculate overflow by comparing the most significant bits of the inputs and the result.
<Vinalon> for subtraction, (MSb[a] != MSb[b]) & (MSb[a] != MSb[result])
<Vinalon> and for addition, (MSb[a] == MSb[b]) & (MSb[a] != MSb[result])
<Vinalon> I might have that wrong, but I think it should work for a-b and a+b?
<ianloic> I think I can just test that the accumulator is less than my increment
<ianloic> (famous last words)
<ZirconiumX> ianloic: yeah, uh, try to avoid comparisons where possible
<ZirconiumX> Though nMigen - as far as I can tell - guarantees that simulation and synthesis match
<ZirconiumX> Well, I think stuff like CDC is a blocker there, but I think it's an eventual goal
<awygle> Isn't "avoid comparisons" verilog driven?
<awygle> Because of its fucky promotion rules?
<awygle> it should just be a subtraction