<GitHub193>
artiq/master 0e41725 Robert Jordens: pdq2: sync with pdq2
<sb0>
nah, you want to mix combinatorial statements and NextValue freely in a fsm.act()
<sb0>
e.g. fsm.act(XXX, If(foo, blah.eq(1), NextValue(quux, 2)))
<whitequark>
hm, right
<rjo>
why? you can't do that in self.comb either.
<sb0>
that's why I'm proposing to replace sync with NextValue
<sb0>
and I tend to need that more frequently in FSMs than in comb
<whitequark>
maybe if we call it something like quux.next(2) or something
<whitequark>
but it's still not quite right, because outside of fsms you may want to add it to clock c domains
<sb0>
if done in a non-careful manner though, the generated Verilog won't look like normal hand-written Verilog at all
<sb0>
this will make it less readable, and maybe synthesizer opts will choke on it
<sb0>
it's a pretty complex feature to implement
<sb0>
with clock_domain: .... quux.next()
<sb0>
or if you're mixing clock domains closely: foo.next(1, clock_domain=cd1), bar.next(2, clock_domain=cd2)
<whitequark>
why is it complex? it's mostly just rearranging syntax
<sb0>
how do you deal with "If(x, foo.eq(1), blah.next(2))" in the best way for synthesizers to optimize, and without making the generated verilog excessively unreadable?
<whitequark>
oh, I see what you mean
<rjo>
foo.cd1(1), bar.cd2(2), quux.comb(3)
<whitequark>
rjo: that requires __getattr__
<rjo>
but isn't that more of a verilog problem than one for the synthesizer.
<rjo>
for the netlist describing If(x, foo.eq(1), bla.next(2)) is trivial. just for verilog that needs to be split into two if statements, right?
<cr1901_modern>
whitequark: Re: Karnaugh Maps. They're easy to do once you know how to do them. But I'd just use a Quine-McCluskey solver for anything you need. It's more general and you can do more complex problems even on paper once you get it.
* cr1901_modern
doesn't actually remember how to do Quine-McCluskey algorithm
<whitequark>
we need to run another instcombine+sccp after licm or something like that
<whitequark>
file an issue, I'll fix it later. it's not hard, just needs some time to figure out why the existing pipeline isn't enough
<rjo>
whitequark: ack
<rjo>
whitequark: i could imagine that making quite a difference for the dds stuff as well. (where it is currently slow).
<whitequark>
I recall that test_pulse_rate_dds was optimized to the point where nothing could be done
<whitequark>
and there's no real reason it should have regressed
<whitequark>
but yeah, it's not out of question
<rjo>
whitequark: ack. another interesting thing for speed could be making the timeline manipulations (delay_mu(), now_mu()) custom cpu instructions (or pin it to a register as you proposed). and maybe making rtio_output an instruction... for somebody who loves to play with these things.
<whitequark>
pinning to a register... hrm
<whitequark>
so perhaps the first thing that needs to be done is marking @now as non-aliasing
<whitequark>
we might also need to move now_save/now_init into __modinit__
<whitequark>
since then it would be a module-local global
<whitequark>
rtio_output can raise
<whitequark>
which is the largest problem with it.
<whitequark>
if you make the error case of rtio_output raise an interrupt then we can just inline
<whitequark>
or, alternatively (because unwinding from an interrupt handler is yucky): add code to every back edge that polls some flag
<whitequark>
if the flag is set, goes the slow path that raises
<whitequark>
rjo: i'm pretty sure i can optimize rtio and dds operations quite a bit
<whitequark>
the prior optimization effort was only really focused on non-syscall operations
<cr1901_modern>
Well, this article suggests "no, your execution doesn't matter either b/c as a startup, there is no chance in hell you can keep up with the economies of scale that Chinese factories offer." Kinda defeatist. But I REALLY don't see that as a fully bad thing
<whitequark>
if what you're building is an answer to a fad that's little more than two arduinos slapped together, then yes, it doesn't matter, and nothing wrong with that
<GitHub112>
[artiq] sbourdeauducq pushed 4 new commits to master: https://git.io/vPMsQ
<GitHub112>
artiq/master ed26245 Sebastien Bourdeauducq: master: ensure same dataset is in broadcast and local when mutating
<GitHub142>
[artiq] sbourdeauducq pushed 2 new commits to release-2: https://git.io/vPMsj
<GitHub142>
artiq/release-2 363a7eb Sebastien Bourdeauducq: master: ensure same dataset is in broadcast and local when mutating
<GitHub142>
artiq/release-2 67ce341 Sebastien Bourdeauducq: master: keep dataset manager consistent when set_dataset is called with contradictory attributes
<sb0>
CRITICAL WARNING: [Netlist 29-73] Incorrect value '19200.000000' specified for property 'CLKFBOUT_MULT_F'. The system will either use the default value or the property value will be dropped. Verify your source files
<sb0>
how is that a warning and not an error...
<sb0>
sure, let's output some random clock frequency, surely that will work
<whitequark>
but it didn't attach the reset anywhere.
<cr1901_modern>
my_rst = ResetSignal("sys")
<whitequark>
migen doesn't simulate ResetSignal()
<cr1901_modern>
Oh. Hmmm... I see what you're saying now. I never needed to assert rst like that in a simulation
sandeepkr has quit [Ping timeout: 256 seconds]
<cr1901_modern>
But when you create a clock domain, if reset_less != True, a reset signal should be created for you. I wonder if that's disabled in the context of the simulator
kuldeep has quit [Ping timeout: 260 seconds]
<whitequark>
migen creates a resetless clock domain
<whitequark>
hm.
<whitequark>
cr1901_modern: actually, no, your solution also worked
<cr1901_modern>
Wait... that can't be right. I have simulations with resets
<cr1901_modern>
Ahhh
<whitequark>
it's just that for some reason the simulator needs two cycles to reset
<whitequark>
and not one as I thought
<whitequark>
sb0: ^ why?
<whitequark>
if it's as designed I should document that
<cr1901_modern>
The simulation starts one half cycle before reset is asserted IIRC?
<cr1901_modern>
I only took a brief look earlier, but are you clocking in the bits for the UART (recv) at the end of the bit period?
<whitequark>
nope.
<whitequark>
line 51
<whitequark>
this is actually something that was *extremely* irritating to do in verilog, and my solution in UART.v was bad.
<whitequark>
I'm now writing a detailed comparison here
<cr1901_modern>
Oh, that's clever. Now I get it!
<cr1901_modern>
I don't remember what I did for my UART. I recall not using FSMs tho and just keeping track of the states manually.
rohitksingh_work has joined #m-labs
FabM has quit [Remote host closed the connection]
kuldeep has quit [Ping timeout: 252 seconds]
sandeepkr__ has quit [Ping timeout: 252 seconds]
sandeepkr__ has joined #m-labs
FabM has joined #m-labs
kuldeep has joined #m-labs
sandeepkr__ has quit [Max SendQ exceeded]
FabM has quit [Remote host closed the connection]
kuldeep has quit [Max SendQ exceeded]
kuldeep has joined #m-labs
sandeepkr__ has joined #m-labs
FabM has joined #m-labs
kuldeep has quit [Ping timeout: 250 seconds]
sandeepkr__ has quit [Ping timeout: 260 seconds]
rohitksingh_work has quit [Read error: Connection reset by peer]
kuldeep has joined #m-labs
sandeepkr__ has joined #m-labs
fengling has joined #m-labs
fengling has quit [Ping timeout: 268 seconds]
kuldeep has quit [Ping timeout: 252 seconds]
sandeepkr__ has quit [Ping timeout: 257 seconds]
sandeepkr__ has joined #m-labs
kuldeep has joined #m-labs
sandeepkr_ has joined #m-labs
sandeepkr_ has quit [Read error: Connection reset by peer]
sandeepkr_ has joined #m-labs
sandeepkr_ has quit [Read error: Connection reset by peer]
kuldeep has quit [Ping timeout: 260 seconds]
sandeepkr__ has quit [Ping timeout: 260 seconds]
<sb0>
there is no reason for two-cycle resets afair
<sb0>
can you upload that comparison to the m-labs website?
<sb0>
what exactly do you mean by "needs two cycles to reset"? the implicit (i.e. not created via ResetInserter) is not user accessible from the simulator
<sb0>
and ResetInserter just creates regular logic so I don't see why there would be a special case here
<sb0>
you can drive rx_ready and rx_error in act() instead of separating them with ongoing()
<sb0>
I don't actually like ongoing() very much since it's trivial to do signal.eq(1) in act()
<sb0>
_florent_, since the UART uses a 32-bit phase accumulator for the baudrate, is it really needed to support crossing clock domains there?
<whitequark>
sb0: (reset) so what I did is I added dut.clock_domains.cd_sys = ClockDomain("sys")
<whitequark>
but adding one with ResetInserter resulted in exactly same two-cycle behavior
<whitequark>
(ongoing) ack. and I agree. that was a goof from a direct verilog port
<whitequark>
(misoc uart) yes. I know about misoc uart. a) I wanted to port the one I wrote, because the primary goal of this exercise is to teach myself migen, not implement an uart; and b) I think the misoc uart is rather confusingly written
<whitequark>
(upload the comparison) I would prefer not to; it's written as opinion and in fact originally was going to be an email; and I don't consider myself an authority on Verilog to write such comparisons objectively. I'm pretty certain some of my complains are fixed in SV, not that I am motivated to learn SV
<whitequark>
if I replace "yield;" with "yield; yield;" it succeeds
<sb0>
yes, signals are read right before the clock edge and set right after
<whitequark>
oh
<sb0>
same semantics as nonblocking verilog assignments
<whitequark>
oh! it's a synchronous reset
<whitequark>
and I've used an asynchronous reset in my verilog
<whitequark>
that explains it
<sb0>
yes, I haven't found any reason for using asynchronous resets
<sb0>
it just special-cases the reset signal for nothing
<sb0>
I've heard (but not checked) that you can make an area-optimized FF with an asynch reset, but this seem irrelevant for common FPGA FFs which have a builtin synch reset
<whitequark>
well for example ice40 has synchronous set/reset as well as asynchronous set/reset variants
<_florent_>
sb0: IIRC I needed different clock domain for a uart link over usb (core was clocked at sys clock, phy was using usb clock)
<whitequark>
I suppose then it makes no difference which one you use
<_florent_>
sb0: but if you don't see use case for that, you can simplify code
<sb0>
you can also have asynch resets in xilinx, but why bother?
<sb0>
_florent_, and can't the phy use the sys clock as well?
<whitequark>
yeah, this makes sense
<sb0>
or was it not rs232?
<_florent_>
sb0: it was not rs232, I was only using the core and a specific phy
<sb0>
ah, pushing into a ftdi fifo?
<_florent_>
yes
<sb0>
that's not really a "uart" anymore...
<_florent_>
not really, you remove that if you want
<rjo>
whitequark: lgtm. i personally would havve felt a strong urge to not use the NextValue() things in favor of doing those actions in self.sync. but that might be a matter of taste.
<whitequark>
rjo: like the misoc uart? I find that style very hard to understand
<whitequark>
but then I'll gladly describe a two-state process in terms of an explicit FSM
<rjo>
whitequark: not quite. using an fsm makes these things much clearer. but i would have used something like "self.sync += If(fsm.before_entering("foo"), a.eq(2))" and the like
<whitequark>
oh, the before_entering thing
<whitequark>
I never actually understood how it worked, since it was undocumented
<rjo>
whitequark: nesting multiple ifs becomes really hard to read. writing it as an fsm even if it's just two or three states is good.
<rjo>
those give you signals that are 1 in the cycle before/after leaving/entering the given state.
<rjo>
at least they are supposed to do that. there are few tests or users that verify that.
<whitequark>
so "before_entering("foo")
<whitequark>
" is the same as "self.next_state == self.encoding["foo"]" ?
<rjo>
and if you are cool with using the numpy docstring format (it also has some other name but i forgot), let's stick with that. i find it easier to read in the source.
<whitequark>
I'm not sure what are you referring to
<rjo>
will explain later. bbl.
tmbinc__ has quit [*.net *.split]
ysionneau has quit [*.net *.split]
tmbinc__ has joined #m-labs
ysionneau has joined #m-labs
sandeepkr has joined #m-labs
<whitequark>
sb0: what is the problem with synthesis of latches anyway?
<whitequark>
I've seen some vague claims that "timing analysis tools have a problem with latches" but not anything concrete
mumptai has joined #m-labs
<whitequark>
is this because the timing models used don't accurately model propagation through a LUT with feedback?
<cr1901_modern>
Related thought: Is there a name for "the condition where a cycle in a given graph cannot occur without traversing a node meeting a specific condition"? Analogous to how a node is dominated if it "can't be reached in any path without going through the node that dominates it".
<whitequark>
"all cycles in this graph include (X)"
<cr1901_modern>
whitequark: Less, abstractly, I'm looking for an algorithm that will detect combinatorial loops. And to a first approx "combinatorial loops will occur if there's a cycle where any none of the nodes meet the condition IS_CLOCKED=true".
<cr1901_modern>
So I guess I just look for cycles where none of the nodes meet the condition IS_CLOCKED=true
<larsc>
remove all nodes where IS_CLOCKD=true and than the problem becomes trivial
<larsc>
any remaining subgraph that is not DAG is a comb loop
<cr1901_modern>
larsc: Good idea :). Wish I thought of it
<cr1901_modern>
whitequa1k: Skimmed. This is really good writeup, I like. "There wasn’t a single downside to it." The platform.request() is acceptable?
<whitequark>
have you *tried* writing constraint files by hand
<whitequark>
especially with arachne-pnr, where not having a connected signal is an error, or a warning if you spend especially much effort
whitequa1k has quit [Quit: leaving]
<cr1901_modern>
Sure, it sucks. And also, I just saw it summed up my "it's not stellar, but it's much better than HDL"
<cr1901_modern>
by*
<whitequark>
than... HDL?
<cr1901_modern>
Sorry, this is what I get for typing from memory. At the end of the post, you mention Migen dependency management is Python, "which isn’t stellar but is far better". I thought you were going to mention things you would improve in Migen's dependency management
<cr1901_modern>
if given the chance*
<cr1901_modern>
"Migen doesn’t have this spurious coupling between syntax and behavior that Migen has;" <-- typo?
<whitequark>
right
<whitequark>
so I won't improve anything in particular in Migen but like
<whitequark>
there are pip, setuptools, easy_install and conda
<whitequark>
and all four of them are shit
<whitequark>
its actually not that hard to write a package manager thats not shit.
<whitequark>
well, not today, when you can clone one of >>1 that is known to work
<cr1901_modern>
like the OCaml one or cargo?
mumptai has quit [Remote host closed the connection]
<whitequark>
yup, opam or cargo
<whitequark>
even *npm* would be an improvement, and I don't say this often
<cr1901_modern>
At times I've been thinking "it would be nice to have a central repo of Migen code snippets that I reuse. I also take genlib for granted."
<cr1901_modern>
Some of which is a pain to implement (AsyncFIFO)
<cr1901_modern>
Oh cool, new Icestick-compatible dev board added to Migen!
<whitequark>
that's not icestick...
<cr1901_modern>
Icestorm*
<cr1901_modern>
they have the same first 5 letters :P
<rjo>
you are unfairly misrepresenting the python packaging situation. the four are not orthogonal. but indeed, they should converge, apart from conda which does have a different scope.
<whitequark>
they are indeed not orthogonal
<whitequark>
my claim is that all four are badly designed and implemented
<whitequark>
and if for the older ones there are some decent excuses, for conda there are none
<rjo>
whitequark: the docstring format i like is -- apparently nowadays -- called "napoleon", http://sphinxcontrib-napoleon.readthedocs.io/ that's what "numpydoc" in doc/conf.py/extensions does.
<whitequark>
that works as expected in simulation but, incomprehensibly, not on the FPGA
<rjo>
whitequark: but if your goal is to be able to provide "everything" needed to run e.g. scipy on platform X, that's equivalent to writing a full package manager suitable for compilers, c-libraries, pkg-config, -dev/-dbg library splits, soname handling, all the glorious details of a full distribution package manager. indeed conda miserably fails at being one.
<rjo>
whitequark: how do you know your design does not work?
<rjo>
leds?
<whitequark>
yup
<rjo>
nothing obvious. no issue with shadowing, i.e. ibus/dbus caching the writes to leds?
<rjo>
... after 2 minutes of looking at it slightly drunk
<whitequark>
the caches are turned off since my FPGA is tiny
<rjo>
is that the reason you didn't use misoc.integration.soc_core.SoCCore?
<whitequark>
no, I wanted to understand how SoCCore and friends work
<whitequark>
and similarly I wanted to understand how wishbone transactions work
<whitequark>
sb0 wants me to write an expanded mailbox, so I started by studying migen in-depth and now how the SoC is put together, because I was not sure how to write that mailbox and I didn't want to cargo-cult code
<whitequark>
... hm
<rjo>
ok. sounds wise.
<whitequark>
the simulator seems to think that r0 is uninitialized?!
<rjo>
r0=0 no?
<whitequark>
according to the ISA
<whitequark>
but it propagates X's
<whitequark>
I xored it and now it doesn't, so I assume mor1kx doesn't actually fix r0 at 0
<whitequark>
it's just a GPR
<rjo>
maybe on synthesis that happens to be initialized as r0=0 by accident.
<rjo>
anyway. gotta go again. 'nite!
jbqubit has joined #m-labs
<jbqubit>
@whitequark same error for artiq_compile
<jbqubit>
$ artiq_compile startup_kernel.py ====== LLVM IR (BROKEN) DUMP ====== LLVM IR (broken) dumped as /tmp/tmpcrx5ocqw.ll Traceback (most recent call last): File "/home/britton/anaconda3/envs/artiq-phaser/bin/artiq_compile", line 11, in <module> load_entry_point('artiq==3.0.dev0+159.gbf942fc', 'console_scripts', 'artiq_compile')() File "/home/britton/artiq-dev-phaser/artiq/artiq/frontend/artiq_compile.py", line 58, in main wit