<mwk>
*sigh* I'm impressed by the shittiness of Virtex 2 / Spartan 3 DDR registers
<mwk>
so they (as opposed to later FPGAs including Spartan 3E/3A) have DDR register primitives that are also simultanously input or output buffers
<d1b2>
<dub_dub_11> That's I/ODDR2 right? What's the actual difference between them and a I/ODDR?
<mwk>
no, I/ODDR2 is Spartan 3E/3A/6, those are fine
<d1b2>
<dub_dub_11> Ah
<d1b2>
<dub_dub_11> Oh this is before either?
<mwk>
yes
<d1b2>
<dub_dub_11> Right
<mwk>
those are called IFDDR{CP,RS}E, OFDDR{CP,RS}E, OFDDRT{CP,RS}E
<mwk>
so... yeah, they have integrated I/O buffers
<mwk>
which would be fine except they don't support differential input/output, which is otherwise supported by the relevant hardware
<d1b2>
<dub_dub_11> Which presumably makes it much more complicated to instantiate them?
<mwk>
yes, that too
<mwk>
I'm trying to add support for this mess to nmigen and of course doing that would complicate the code
<d1b2>
<dub_dub_11> Oh and the DDR registers are the ones that don't support differential pairs... How odd
<mwk>
but also I don't see a way to support diff pairs at all, which is uhh
<daveshah>
Perhaps it is done just with the IO type?
<daveshah>
That's how Lattice do it, and they would have been relatively convergent at that point in time having both recently moved to NeoCAD
<mwk>
and for bidir pins, I'd have to have both IFDDR* and OFDDRT* on the same top-level port; not sure if it's going to be happy about what are effectively two buffers
<mwk>
hmmm
<mwk>
could be
<mwk>
... should I just leave the n side hanging then
<mwk>
feels like something that will blow up
futarisIRCcloud has joined #nmigen
<mwk>
eh, I'll just try it out and see if it manages to make a bitstream
peteut has quit [Ping timeout: 272 seconds]
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
emeb has joined #nmigen
Degi has quit [Ping timeout: 240 seconds]
Degi has joined #nmigen
<mwk>
@dub_dub_11 also since I haven't answered your other question: I/ODDR2 is second-generation DDR register (Spartan 3E/3A/6), I/ODDR is third-generation (Virtex 4, 5, 6, Series 7)
<mwk>
the differences are twofold
<mwk>
first, I/ODDR2 takes 2 clocks and you're supposed to invert one of them yourself, while I/ODDR takes one and does the inversion
<mwk>
second, IDDR has the extra feature over IDDR2 of SAME_EDGE_PIPELINED mode, which aligns both outputs to one of the clocks in the same clock cycle, making it convenient to use
<mwk>
for IDDR2 you need to supply the extra flop yourself
<mwk>
ODDR, as far as I can see, has the same features as ODDR2
<d1b2>
<dub_dub_11> ah interesting, ty
<mwk>
there are also the fourth-generation DDR registers, IDDRE1 and ODDRE1
<mwk>
which... are actually IDDR/ODDR with lots of stuff removed
<mwk>
you can no longer have both set and reset, or any mode other than fully-pipelined same-clock-edge mode, or clock enable
<mwk>
okay, I think I've managed to merge the three Xilinx platforms into one and add support for loads of devices on the way
<d1b2>
<dub_dub_11> can I be of any help testing (on V5)
<d1b2>
<dub_dub_11> ah found it
<d1b2>
<dub_dub_11> oh
<d1b2>
<dub_dub_11> @mwk you have __all__ = ["XilinxPlatform", "XilinxSpartan3APlatform", "XilinxSpartan6Platform", "Xilinx7SeriesPlatform", "XilinxUltraScalePlatform"] but never declare anything other than XilinxPlatform
<d1b2>
<dub_dub_11> which means if you do import * it will try import stuff that doesn't exist
<mwk>
... oh right
<mwk>
I've added a fix
<d1b2>
<dub_dub_11> I think in all the other ones it just says XilinxSpartan3APlatform = XilinxPlatform etc at the bottom
<mwk>
so anyway, the main part that I doubt is iddr/oddr handling
<mwk>
in particular on Spartan 3 and earlier
<mwk>
... which is exactly what I'm testing now
<d1b2>
<dub_dub_11> right
<d1b2>
<dub_dub_11> cause that's the new bit
<mwk>
and of course turns out it's broken for differential pairs, using OFDDRT* on differential pairs breaks stuff
<d1b2>
<dub_dub_11> ah
<mwk>
having both IFDDR* and OFDDR* on a single single-ended pad seems to work though
<d1b2>
<dub_dub_11> if it helps I've also run it for V5 and seen this error: line 840, in get_input i, o, t = self._get_xdr_buffer(m, pin, port, i_invert=invert) TypeError: _get_xdr_buffer() takes 3 positional arguments but 4 positional arguments (and 1 keyword-only argument) were given which is probably an entirely seperate problem but probably affects anything else with the same types of io
<mwk>
please update to current state
peeps[zen] is now known as peepsalot
<mwk>
the version I originally pushed was basically completely broken
<d1b2>
<dub_dub_11> ah mb
<mwk>
*sigh* there is also one possibility I don't really like
<mwk>
perhaps I'm supposed to use the undocumented FDDR primitives instead
<d1b2>
<dub_dub_11> 😦
<mwk>
I'm going to try that
<d1b2>
<dub_dub_11> well I can report it created some verilog and constraint file without complaint, about to see if they work
<d1b2>
<dub_dub_11> (I haven't tested the actual ISE toolchain bit yet because I have a weird setup
<mwk>
okay, using semi-documented primitives did the trick
<mwk>
*sigh* I hate you for that, ISE
<d1b2>
<dub_dub_11> >.<
* mwk
looks into the xdl file
<mwk>
(yeah, of course I don't trust you)
<mwk>
mmm, looks... reasonable, actually
<awygle>
are the irc logs down for anybody else?
<miek>
yup
<mwk>
*sigh* on Spartan 3E/3A the ODDR2's alignment feature cannot be used with differential pairs in pseudo-differential standards
<mwk>
now that's a highly specific set of circumstances
<mwk>
I mean, I know *why*, but...
<mwk>
*sigh* and Spartan 6 requires ODDR2 on T pin if O is also ODDR2
<mwk>
did anybody ever properly test the old Spartan 3A/6 platform
<mwk>
... don't answer that question
<mwk>
also, argh, the damn thing rejects the init values because they're 32-bit and not 1-bit
<mwk>
... yeah, definitely nobody bothered to even look at ISE input for the existing platform code
<mwk>
oh, and also Spartan 6 (but not any other FPGA) has the requirement of using same clock for DDR input and DDR output for a given pin
<mwk>
whitequark: do we have an easy way to verify that this is the case while still in nMigen (i_clk == o_clk), or should I just leave it up to ISE to trigger an unroutable design error in this case?
<daveshah>
fwiw, ecp5 is the same
<mwk>
okay, seems Spartan 6 is working fine now, so... what do I do about 3E/3A
<mwk>
the problem here is that the alignment feature effectively borrows registers from the neighbouring IO
<mwk>
so to know if I should allow it, I have to know if the other IO in the tile is unused
<mwk>
or rather, its register
<mwk>
for true differential IO and pseudo differential input, this is always true; for pseudo differential output, this is always false (because the other output register is busy registering the negated signal)
<mwk>
for single-ended IO... good luck figuring this out, it's likely free to use, but there's really no way to know
<mwk>
other than looking at *all* pins in the design and their registers, and also having a map of which pins belong to which IO tile
<mwk>
it'd be nice if, say, the P&R tool could handle this, since it's trivial to get the relevant information there
<mwk>
but alas, ISE
<mwk>
... screw that, I'll just do alignment manually for single-ended ios and pseudo-diff outputs
<mwk>
of course, I need to recognize pseudo-diff iostandards now... ugh
* mwk
looks at Ultrascale platform code emitting ODDRE1 with the DDR_CLK_EDGE parameter that does not, in fact, exist
<mwk>
I guess nobody tested this damn thing either
<_whitenotifier>
[nmigen] mwkmwkmwk opened pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcUA
<_whitenotifier>
[nmigen] codecov[bot] commented on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcT8
<_whitenotifier>
[nmigen] codecov[bot] edited a comment on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcT8
<_whitenotifier>
[nmigen] codecov[bot] edited a comment on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcT8
<_whitenotifier>
[nmigen] codecov[bot] edited a comment on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcT8
<_whitenotifier>
[nmigen] codecov[bot] edited a comment on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcT8
<_whitenotifier>
[nmigen] mwkmwkmwk commented on pull request #563: Unify Xilinx platforms into a single class, support more devices - https://git.io/JLcTA
<mwk>
okay, I now consider this thing ready
<mwk>
... I may or may not try throwing in Versal support at some point
chipmuenk has quit [Quit: chipmuenk]
<d1b2>
<dub_dub_11> is that their fancy compute module?
<mwk>
it's the newest not-quite-released generation of their hw
<mwk>
it's more of a spiritual successor to Zynq tbh
<d1b2>
<dub_dub_11> oh right
<d1b2>
<dub_dub_11> they do market it as "compute acceleration platform"
<d1b2>
<dub_dub_11> but it does make sense that would mean fabric+CPU
<mwk>
*shrug* I see an ARM SoC and an FPGA there, and it's made by Xilinx, so it's a Zynq
<d1b2>
<dub_dub_11> yeah fair
<d1b2>
<dub_dub_11> nevermind what the marketing wants you to think it is 😄
<mwk>
well, fine, it also has "AI cores" (aka vector processors) slapped on it in some variants
<mwk>
which are a new thing
<mwk>
but other than that... yeah, a glorified Zynq
<d1b2>
<dub_dub_11> mhm
<_whitenotifier>
[nmigen] whitequark commented on issue #562: Way to start register with "random" value? - https://git.io/JLctz