<harryho>
Darius: I think you've just given me the right direction, thanks! I'll take further look into that.
rohitksingh has joined #m-labs
<Dar1us>
harryho: wohoo, go random guesses ;)
<harryho>
ok!
<harryho>
whitequark: Quick question about nMigen: the difference between `m.submodules += ...` and `m.submodules.name = ...` for instantiating an `Instance` object, is it just that the former lets you reuse the object in other lines of code, while the latter doesn't because the object becomes anonymous? Or is there something else I should consider when choosing between the two? Thanks
<harryho>
(I already knew the += version accepts a list while the = one doesn't)
mumptai has joined #m-labs
<Dar1us>
harryho: I think it's just whatever is convenient
<harryho>
whitequark: Thanks! So how does "reusing" work for those unnamed submodules? Because what I assumed is that "reusing" means operating on those submodules by calling their names.
<whitequark>
what is "reusing"?
<whitequark>
the names assigned to submodules serve one purpose: to give them a name inside the generated hierarchy (so in Verilog, VCD files, etc)
proteusdude has joined #m-labs
<harryho>
umm, how about something like `m.submodules.cpu = Minerva(w...)`, and then I use `m.submodules.cpu.ibus` or `.dbus`? If I don't name it then am I supposed not to use its "attributes" (i can't think of a good term sorry)?
<whitequark>
m.submodules.cpu = cpu = Minerva(...)
<whitequark>
cpu.ibus ...
<whitequark>
is the usual idiom.
<_whitenotifier>
[m-labs/nmigen-stdio] whitequark pushed 1 commit to serial [+1/-0/±0] https://git.io/Je3KK
<whitequark>
sb: what is the history behind the removal of migen.flow?
<whitequark>
I want to make something like it for nmigen, so it would be useful to know why it failed before
proteusdude has quit [Ping timeout: 265 seconds]
proteusdude has joined #m-labs
<cr1901_modern>
>but this caused various problems, like how you can't reuse the same instance for different platforms, for example
<cr1901_modern>
Could you elaborate on what you mean by this when you get the chance?
<cr1901_modern>
whitequark: ^^
<whitequark>
cr1901_modern: you can only ever finalize a module once.
<whitequark>
so any platform dependent choices are baked in
<rjo>
i would also like this. i'd want to annotate my modules with port-to-port latencies, supply a graph and then leave everything else to the logic to determine proper pipelining, delay lines, overall cycle length etc. this would help in a lot of DSP applications (SAWG, SU-servo) etc.
<whitequark>
rjo: yes. that is very much what i have in mind.
<whitequark>
feel free to open an issue, list your requirements and a proposed design (if any).
<cr1901_modern>
How does avoiding "self.cpu" when creating a submodule hierarchy solve this problem?
<whitequark>
I am thinking about things like line rate network processing (with TCP/IP in gateware), or PCIe.
<whitequark>
cr1901_modern: well, if you mutate the elaboratable during elaboration, you lose (obvious) reproducibility
<whitequark>
the design I chose for nMigen doesn't require any mutation of the elaboratable in .elaborate(); it merely maps itself to a Module or a Fragment
<rjo>
if this is automated, then so many cool DSP things become much easier. E.g. that RF-NoC that ettus/gnuradio does. or automated mapping out of the different configurations of DSP cores vs their resource usage and timing properties
<whitequark>
yep.
<rjo>
i'll start an issue.
<whitequark>
excellent.
<whitequark>
it was my goal from day 1 to add something like this to nmigen.
<cr1901_modern>
like how you can't reuse the same _instance_ for different platforms <-- oh, you mean "I create my nmigen elaboratable once in a script, and then run build using that elaboratable for all platforms I care about."?
<whitequark>
yeah for example
<whitequark>
or maybe you want to synthesize only a part of a design
<cr1901_modern>
This could potentially solve the combinatorial explosion of e.g. soc targets in CI by making each CI test backend-specific rather than target specific
<cr1901_modern>
s/target/platform/
<whitequark>
hm
<_whitenotifier>
[m-labs/nmigen] whitequark pushed 1 commit to master [+0/-0/±1] https://git.io/Je3Pf
<_whitenotifier>
[nmigen] whitequark commented on issue #12: Implement a sanitizer for memory port combinations - https://git.io/Je39o
<_whitenotifier>
[nmigen] whitequark commented on issue #173: Platform function to calculate optimal BRAM depth for width - https://git.io/Je396
<_whitenotifier>
[nmigen] whitequark closed issue #173: Platform function to calculate optimal BRAM depth for width - https://git.io/fjFCb
<_whitenotifier>
[nmigen] whitequark opened issue #216: Memory port transparency model is flawed - https://git.io/Je3HH
mauz555 has joined #m-labs
<whitequark>
sb: it looks like oMigen AsyncFIFO used two ports in different clock domains, with one port in WRITE_FIRST mode
<whitequark>
as far as I understand, this is actually totally undefined on even Xilinx
<whitequark>
and doesn't synthesize to a BRAM elsewhere
<whitequark>
hm, no, it UG473 recommends WRITE_FIRST
<whitequark>
but how does this actually work?
<_whitenotifier>
[nmigen] whitequark commented on issue #216: Memory port transparency model is flawed - https://git.io/Je3Qt
<_whitenotifier>
[nmigen] whitequark commented on issue #216: Memory port transparency model is flawed - https://git.io/Je3Qm
<ZirconiumX>
whitequark: Is there any way I can help with #178 (Quartus support)?
rohitksingh has joined #m-labs
alexhw has quit [Quit: No Ping reply in 180 seconds.]
alexhw has joined #m-labs
<_whitenotifier>
[nmigen] nakengelhardt commented on issue #12: Implement a sanitizer for memory port combinations - https://git.io/Je3Q4
mumptai has joined #m-labs
<mtrbot-ml>
[mattermost] <nakengelhardt> whitequark: as far as I can tell, if the two ports are in different clock domains, any address collision with a write operation results in undefined data read on the other port.
<whitequark>
ZirconiumX: well, you could work on the outstanding issues described in that PR
<_whitenotifier>
[nmigen] jordens commented on issue #213: flow graph analysis and automation - https://git.io/Je3QV
<mtrbot-ml>
[mattermost] <nakengelhardt> the xilinx "recommendations" are only concerned with power and assume that you are able to avoid address collision somehow.
<whitequark>
ohhh I see
<_whitenotifier>
[nmigen] whitequark commented on issue #216: Memory port transparency model is flawed - https://git.io/Je3QP
<_whitenotifier>
[nmigen] whitequark closed issue #216: Memory port transparency model is flawed - https://git.io/Je3HH
<mtrbot-ml>
[mattermost] <nakengelhardt> xilinx really seems to consider address collisions a weird edge case that they can just assume never happens, the way their stuff is written
<whitequark>
right, ok
<mtrbot-ml>
[mattermost] <nakengelhardt> memory inference explicitly works that way
<mtrbot-ml>
[mattermost] <nakengelhardt> and don't get me started on how they give you a warning for every single blockram that's not in NO_CHANGE mode, because it might use extra power
<whitequark>
btw lol
<whitequark>
er
<whitequark>
btw did you know that apparently READ_FIRST/WRITE_FIRST are done using some sort of strobe delays?
<whitequark>
instead of a mux
<mtrbot-ml>
[mattermost] <nakengelhardt> hah
<mtrbot-ml>
[mattermost] <nakengelhardt> I've never really looked at the internals
<mtrbot-ml>
[mattermost] <nakengelhardt> Also I have no idea what this sentence is supposed to mean: "The time window for a possible collision is up to the lesser of 3000 ps or of the two clock periods."
<ZirconiumX>
whitequark: How generic does the platform have to be? Generic over _all_ Altera chips, or can I stick to the Cyclone V that I have?
<whitequark>
ZirconiumX: if you can't test it you shouldn't claim to support it
<whitequark>
so if you only have cyclone v, it should become something like vendor.altera_cyclone_v
<ZirconiumX>
Allegedly - allegedly - the V family parts are compatible
<ZirconiumX>
Sadly I am not an Altera employee, nor do I know any
<whitequark>
the primitives are all per-device, right?
<whitequark>
the ones you're supposed to instantiate
<whitequark>
e.g. how would you implement a tristate buffer, or a differential buffer
<ZirconiumX>
That's a difficult question, because Quartus is not consistent even with itself
<ZirconiumX>
The generic primitive to "do the right thing" is altiobuf here
<ZirconiumX>
The specific primitive seems to be cyclonev_io_obuf
<whitequark>
right, so you should use the generic one.
<whitequark>
if none of the generic ones are specifically cyclone v specific, then it should be vendor.altera, I think
* ZirconiumX
has the nasty feeling a FOSS Altera platform will need to reimplement much of the IP library
<_whitenotifier>
[nmigen] whitequark commented on issue #172: AsyncFIFO/AsyncFIFOBuffered do not infer BRAMs on iCE40 - https://git.io/Je37Y
rohitksingh has quit [Ping timeout: 264 seconds]
<ZirconiumX>
wq: How do I check what the requested xDR is? I need to instantiate one IP block for SDR/normal, but a different one for DDR
<whitequark>
pin.xdr
<whitequark>
you can use xilinx_7series for inspiration
<whitequark>
nakengelhardt: just to confirm, using READ_FIRST in an AsyncFIFO on Xilinx would be just fine, right?
<mtrbot-ml>
[mattermost] <nakengelhardt> is AsyncFIFO actually supposed to map to BRAM? for SyncFIFO only the buffered variant does
<whitequark>
yes it is
<whitequark>
AsyncFIFOBuffered lets you pack an additional (second) register to the read port
<whitequark>
AsyncFIFOBuffered has the exact same problem anyway.
<mtrbot-ml>
[mattermost] <nakengelhardt> ok. I don't think the mode has any effect for AsyncFIFO at all, since you don't read from the write port.
<whitequark>
ok, thanks.
<mtrbot-ml>
[mattermost] <nakengelhardt> but you would have to have some external way to avoid collisions.
<whitequark>
that's just the AsyncFIFO logic itself, no?
<whitequark>
actually, hm
<mtrbot-ml>
[mattermost] <nakengelhardt> probably, I haven't looked at how asyncfifo is implemented
<mtrbot-ml>
[mattermost] <nakengelhardt> are the counters equal if it's empty?
<whitequark>
yeah they are
<mtrbot-ml>
[mattermost] <nakengelhardt> so usually writing the first entry in an empty fifo will be the sticking point
<whitequark>
right. that actually does look like a problem here.
<whitequark>
since it's an FWFT FIFO.
<mtrbot-ml>
[mattermost] <nakengelhardt> btw, did you change the SyncFIFO implementation in nMigen?
<whitequark>
I don't think I did
<whitequark>
I ditched `replace`
<whitequark>
but other than that IIRC it's the same
<mtrbot-ml>
[mattermost] <nakengelhardt> because that is still an unsolved bug in oMigen, it gets inferred to BRAM sometimes
<mtrbot-ml>
[mattermost] <nakengelhardt> and that's a bug
<whitequark>
hm
<mtrbot-ml>
[mattermost] <nakengelhardt> only SyncFIFOBuffered is safe to be inferred
<whitequark>
well, I will argue that this is a toolchain bug.
<whitequark>
so SyncFIFO should not be changed, but perhaps there should be additional logic to avoid this toolchain bug in every case when a Memory with an async read port is used
<whitequark>
for Xilinx only
<mtrbot-ml>
[mattermost] <nakengelhardt> yes, I think using the async_read=True parameter should probably result in the ram_style = distributed attribute
<whitequark>
there's currently no way to add such a hook
<whitequark>
it'd probably need to be a pass?
<mtrbot-ml>
[mattermost] <nakengelhardt> in fact, that was my PR, but it couldn't be merged because there was no way to tell which platform you were for
<whitequark>
right
<whitequark>
I think there needs to be some infrastructure for post-processing of Memories
<whitequark>
the port sanitizer, and also this would go there
<whitequark>
this seems like 0.2 material
<_whitenotifier>
[m-labs/nmigen] whitequark pushed 3 commits to master [+0/-0/±5] https://git.io/Je35e
<_whitenotifier>
[m-labs/nmigen] whitequark 4b3a068 - hdl.mem: use 1 as reset value for ReadPort.en.
<_whitenotifier>
[m-labs/nmigen] whitequark f9b9c17 - lib.fifo: work around Yosys issue with handling of \TRANSPARENT.
<_whitenotifier>
[nmigen] whitequark opened issue #217: r_data is undefined after a simultaneous write to an empty AsyncFIFO - https://git.io/Je35Z
<ZirconiumX>
wq: So, the altiobuf block allows you to specify an arbitrary signal width as a parameter. Should I use that, or instantiate them per-bit like xilinx.7series?
<whitequark>
ZirconiumX: if that actually works, use it by all means.
<whitequark>
it makes the generated verilog much easier to read.
<whitequark>
nakengelhardt: do you have a link to your PR?
<_whitenotifier>
[nmigen] whitequark opened issue #218: Memory with async read ports can synthesize to a BRAM on Xilinx platforms - https://git.io/Je35B
cr1901_modern1 has joined #m-labs
cr1901_modern has quit [Ping timeout: 276 seconds]
rohitksingh has quit [Ping timeout: 276 seconds]
rohitksingh has joined #m-labs
<ZirconiumX>
wq: I'm trying to understand get_input_output. Is it `port` that's the bidirectional signal here?
<whitequark>
yes
cr1901_modern1 has quit [Quit: Leaving.]
cr1901_modern has joined #m-labs
mauz555 has quit []
<_whitenotifier>
[nmigen] whitequark commented on issue #216: Memory port transparency model is flawed - https://git.io/Je35F
<_whitenotifier>
[nmigen] whitequark reopened issue #216: Memory port transparency model is flawed - https://git.io/Je3HH
<whitequark>
why did you add xdr=1 as a possibility? I don't see any FFs
<ZirconiumX>
Probably because I don't understand xDR signals very well
<ZirconiumX>
Yeah, I'll add DFFs
<whitequark>
so xdr=0 is combinatorial output
<whitequark>
xdr=1 is SDR, xdr=2 is DDR
<whitequark>
xdr>2 is various SERDES modes
<whitequark>
which aren't quite properly supported yet
rohitksingh has quit [Ping timeout: 265 seconds]
<ZirconiumX>
It's going to take me a little while to work out how to adapt the DDR gearboxing to the altiobuf primitive
<_whitenotifier>
[nmigen] whitequark commented on issue #217: r_data is undefined after a simultaneous write to an empty AsyncFIFO - https://git.io/Je3ds
<ZirconiumX>
wq: So xdr=0 means no flip-flops, while xdr=1 means flip-flops?
<whitequark>
yes
<whitequark>
and xdr=2 means ddr
<ZirconiumX>
Okay
<ZirconiumX>
And I'm assuming I can't abuse `m.d.sync` for xdr=1, then?
<whitequark>
does altera support packing FFs into the IO buffer itself?
gnufan_home has joined #m-labs
<whitequark>
usually that requires a special attribute
<whitequark>
this is to make sure that the placement of the FF is consistent between PNR runs
<ZirconiumX>
Given they ask you to explicitly instantiate a separate FF, I'm not sure
<whitequark>
Xilinx tells you to instantiate a separate FF too
<whitequark>
but it has an attribute that marks it as requiring packing
<ZirconiumX>
At the moment I don't know of any equivalent
<whitequark>
ok, well you can do whatever their manual suggests
<whitequark>
oh, you can't do m.d.sync since the clock signal is given to you in pin.[io]_clk
<ZirconiumX>
They say that FFs for output/output enable are optional, but then go on to show how to use FFs anyway
<whitequark>
their documentation is so ... sparse
<ZirconiumX>
So, it seems like the documentation forbids xdr = 0
<whitequark>
what.
<whitequark>
that makes no sense.
<ZirconiumX>
"You must add a register external to the IP core, either a regular DFFE or a DDIO and connect its input to the IP core’s dataout port."
<ZirconiumX>
What do you suggest? Ignore that and just use it as a combinational output?
rohitksingh has joined #m-labs
<whitequark>
try that yeah
<whitequark>
i mean
<whitequark>
you can obviously drive a toplevel inout signal directly
rohitksingh has quit [Ping timeout: 258 seconds]
rohitksingh has joined #m-labs
<ZirconiumX>
<whitequark> what if it's a clock input <-- here's a dumb idea: since the FFs are DFFEs, you could feed a constant high to it and put the clock signal in the FF enable