_florent_ changed the topic of #litex to: LiteX FPGA SoC builder and Cores / Github : https://github.com/enjoy-digital, https://github.com/litex-hub / Logs: https://libera.irclog.whitequark.org/litex
tpb has quit [Remote host closed the connection]
tpb has joined #litex
<jevinskie[m]> benh: how did tweaking the clock detection margins go?
<jevinskie[m]> florent: did you have any ideas about cutting timing on the IP checksum? I thought about pipelining it and found this old RFC that implements it in GALs. I wonder if any universities still use GALs in their intro courses :) https://datatracker.ietf.org/doc/html/rfc1936
<tpb> Title: rfc1936 (at datatracker.ietf.org)
<benh> jevinskie[m]: fixing another bug causing my stuff to break when I add liteeth (unrelated to litex)
<benh> I don't think the above patch I pasted makes a difference since clk_freq is already a float
<benh> thus I don't see why we realy on sys_clk being at least 125Mhz... it should work ok with lower sys_clk as long as the data path is larger than 8 bits no ?
<benh> or am I missing something ?
<benh> of course a real gigabit link will probably flood those tiny cores, especially with only 2 receive slots, no DMA and no pipelined wishbone
Coldberg has joined #litex
<benh> unless I'm mistaken we can probably just remove the asserts in gen.py
C-Man has quit [Ping timeout: 252 seconds]
<jevinskie[m]> I agree that I don’t think sysclk needs to be 125, since counting happens in eth_rx domain. Unless we’re both missing something :)
<benh> yeah, I originally thought the above math would be wrong due to integer arithmetic rouding but then I figured clk_freq is probably floating point, I went back to the old code, regenerated with the 100/125 freqs and the resulting verilog looks fine
<benh> anyways, I'll do more tests
Degi_ has joined #litex
Degi has quit [Ping timeout: 252 seconds]
Degi_ is now known as Degi
<benh> _florent_: what ever happened to the idea of having a way to "fix" the CSR layout for the sake of OS drivers ?
<benh> _florent_: for example I can see today that the liteeth driver that went upstream hard wires the register layout
<benh> _florent_: but the PHY part doesn't match what litex generated :-) because GMII_MII puts the Mode status register before the PHY reset and MDIO so everything is shifted
<benh> _florent_: I have memories that we talked about having a way to specify "templates" via name/offset tables
<benh> in fact, the stuff currently upstream doesn't work at all
<benh> because the CSR banks are generated the other way around between MAC and PHY from the device-tree in Linux vs. what LiteX spat out
<benh> so we have both registers inside the PHY bank changing depending on the PHY type (MDIO gets shifted around because the per-PHY-type stuff comes first)
<benh> and we have the banks themselves flipping around
<benh> jevinskie[m]: So just taking out those asserts in gen.py worked
<benh> I have microwatt at 100Mhz with liteeth+GMII_MII (at 125) and packets are flowing fine
<benh> (once I hacked to compensate for the CSRs moving around)
<jevinskie[m]> Excellent! Good work :D
<jevinskie[m]> I’m trying to figure out WTF is going on with the RGMII timing. I’m getting high nibble for byte X with the low nibble for byte X+Y. The dev kit ref project has bizarre clock / data skew - quartus puts max delay on the data ports and the data path is 0.2 ns longer than the clock path for rx_ctl. Is it accidentally pushing out the clock and data by a cycle? RGMII internal delay is off
<jevinskie[m]> I’ve resorted to looking at the trace lengths. Luckily intel provides the PCB layout file for the max10 dev kit :)
<benh> nah
<benh> I spoke too soon
<benh> it works if I force the link to 100Mb/s
<benh> on the peer
<benh> the mode detection seems to work (reading the CSR) when switching between 100 and 1000
<benh> but at 1000 I don't seem to get any packet
<jevinskie[m]> Well at least the mux is working or stuck on MII xD
<benh> :-)
<benh> the driver tx count increments so the MAC thinks its sending
<jevinskie[m]> Try hooking up litescope to tx/rx ctl/data and looking at something like an ARP packet and compare with wireshark (my current approach)
<benh> the peer doesn't see the packets
<benh> I'm not in LiteX, I'm in standalone mw, we don't have litescope
<benh> but I can try a pure litex design at some point
<benh> the mux works, the detection of 100 vs 1000 works
<benh> I can change the peer speed with ethtool and it's properly reflected in the CSR that exposes the mode
<benh> but no packets flow on the GMII
<benh> I suppose I could at least check gtx with a scope
<benh> jevinskie[m]: am I correct in my understanding that the "mode" argument to LiteEthPHYGMIICRG() constructor is fixed at generation time ?
<benh> or it's a variable ?
<benh> generating HW via migen/litex never agreed with my brain, I just can't read the stuff :-) give me verilog or vhdl anytime :-)
<benh> trying to figure out how is gtx generated
<jevinskie[m]> It’s a signal :) `mode = self.mode_detection.mode`
<benh> jevinskie[m]: yes that I get
<benh> jevinskie[m]: but the argument passed to LiteEthPHYGMIICRG() is actually: mode == modes["MII"]
<benh> which is basically mode == 1
<benh> that baffles me ... I didn't think that would generate via some python black magic another signal behind a comparator
<benh> but it seems to do
<benh> oh well, I don't know why it doesn't work at this point, and I'm out of time
geertu has joined #litex
<benh> hrm... LiteX is generating a bad PLL outside of operating ranges, Vivado barfs
<benh> I'll have a look later
Coldberg has quit [Ping timeout: 265 seconds]
<_florent_> benh: The fixed CSR mapping is not yet in place, but we have been discussing it a few days ago: https://libera.irclog.whitequark.org/litex/2021-09-15#30842762
<tpb> Title: #litex on 2021-09-15 — irc logs at whitequark.org (at libera.irclog.whitequark.org)
<_florent_> i'll try to spend some time on it soon since this makes upstreaming drivers difficult
<_florent_> The current Eth PHYs probably have a CSR capabilities/mapping, so this can explain what you see when switching the PHY. This would be good to uniformize this for the same reasons
<_florent_> jevinskie[m]: A way that can be convenient to debug your RGMII issue could be try a netboot and set software_debug to True: https://github.com/enjoy-digital/litex/blob/master/litex/soc/integration/soc.py#L1403
<_florent_> This will disable the RX hardware checks and let the CPU handle them. The CPU will then also print the RX/TX packets that you can then easily compare with Wireshark captures
<_florent_> If you suspect an issue in RX, you can also create a minimal design with just the PHY + LiteScope and compare received packets with the ones from Wireshark
pftbest_ has quit [Remote host closed the connection]
pftbest has joined #litex
FabM has joined #litex
FabM has joined #litex
FabM has quit [Changing host]
<jevinskie[m]> Yep I’ve taken the latter approach and am just looking at the RX bytes from the DDR inputs with litescope. I have some timing issue since the correct low nibbles are appearing in the next bytes low nibbles. High nibbles are also correct but paired with low data from the wrong cycle. I’m furiously drawing out timing diagrams and measuring path delays to the ddr input registers
<jevinskie[m]> There is negligible trace skew, data and clock are all pretty close. I can’t route the rx clk pin to a PLL on this max10 so it seems all the skewing has to be done with timing constraints? I’m starting to think the reference project works by chance luck
Coldberg has joined #litex
<benh> _florent_: thanks, I'll read those links ltr !
<benh> _florent_: I have neither Rx not Tx
<benh> I'll do more experiments later, right now I'm trying to remove microwatt from the equation and adjusting LiteX own Wukong support to work on board v2
<benh> then I'll see if that works and if not we can debug further, such as using a pure GMII see if that works
<benh> etc...
<benh> _florent_: any idea what can cause LiteX to generate a bad PLL2 ? ie, with parameters out of range that cause vivado to barf
<Melkhior> benh: one known bug in Wukong support is J10 and J11 definitions are swapped
<_florent_> benh: Passing a wrong speedgrade to the PLL could cause it
<Melkhior> (my local copy has a bunch of other changes to support PS/2 and USB PMods)
<_florent_> or a wrong timing constraint at the input
<_florent_> benh, Melkior: BTW if there are different revision of the Wukong board, this could be worth adding revisions to the platform, as done in OrangeCrab for example
<Melkhior> I don't have the new one to test :-( but that's probably the right way if it is very close
<benh> Melkhior: ah good, I had started doing separate _io definitions for v1 and v2 thinking it was a difference between the two versions :-)
<benh> Melkhior: I'll revert that and just fix it
<benh> Melkhior: there's also a bad pin number in the differencial connector (jp something... I'll check later, looks like a typo)
<benh> _florent_: so I added a --board-version parameter but I'll go look at orangecrab later
<benh> also it spits out that PLL:
<Melkhior> benh: never used the differential one so never checked it from the original submission
<benh> .CLKFBOUT_MULT(6'd36),
<benh> .CLKOUT0_DIVIDE(4'd9),
<benh> .CLKIN1_PERIOD(20.0),
<benh> .CLKOUT0_PHASE(1'd0),
<benh> .CLKOUT1_DIVIDE(5'd18),
<benh> .CLKOUT1_PHASE(1'd0),
<benh> .DIVCLK_DIVIDE(1'd1),
<benh> .REF_JITTER1(0.01),
<benh> ) PLLE2_ADV (
<benh> .CLKFBIN(s7pll_pll_fb),
<Melkhior> benh: not sure what you mean?
<benh> .CLKIN1(s7pll_clkin),
<benh> .PWRDWN(pll_idelay_power_down),
<benh> .RST(s7pll_reset7),
<benh> .CLKFBOUT(s7pll_pll_fb),
<benh> .CLKOUT0(s7pll_clkout0),
<benh> .CLKOUT1(s7pll_clkout1),
<benh> .LOCKED(pll_idelay_locked)
<benh> );
<benh> which makes Vivado barf that VCO is out of range
<benh> Yeah i just went through every IO pin :-)
<benh> Melkhior: can you check if the FPGA is really a -2 speed grade ?
<benh> mine is a -1
<benh> well, the PLL generated by LiteX for wukong is what I pasted above, and Vivado errors out at generation because the params cause VCO to be out of range
<benh> I'll dig deeper later if you don't know off hand
<Melkhior> it's a -2 on my board, I think V1 were all -2
<Melkhior> Didn't notice the new one is -1 :-(
<Melkhior> should be easy to change that into a version-dependent parameter, I suppose
<benh> sure, just checking :)
<Melkhior> V1 is a XC7A100T-2FGG676I
<Melkhior> they claim the new one is the same for the A100T
<Melkhior> Vivado barfs when configuring the FPGA or when generating the bitstream? In the second case i'ts weird as the Litex board file should say speed -2 so should be fine
<Melkhior> enjoy-digital/litex/blob/master/litex/soc/cores/cpu/vexriscv_smp/core.py
<Melkhior> (wrong copy/paste at first :-) )
TMM_ has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
TMM_ has joined #litex
<Melkhior> Also the Wukong targets use multiple PLLs to avoids dependency between the system clock, the idelay clock, and the Video clock for the HDMI framebuffer
<Melkhior> I have the same PLL definition in my Verilog output, it's fine on my board
<Melkhior> vivado 2020.1
<benh> Melkhior: no because I changed it to do speed -1 since that's what I have :-)
<benh> I managed to live chat with one of the QMtech guys via Aliexpres "contact vendor" interface the other day
<benh> he confirmed that they are supposed to be -1
<benh> he also confirmed that they aren't producing the A200T variant yet because the FPGA is too expensive
<benh> while at it I suggested that they do a V3 with a dual FTDI so the jtag, wire and power can all be on the same cable like Arty :-)
<benh> Vivado 2019.2 here
<benh> I think it's a -1 vs -2 but I'll play around to check, probably not tonight though
<benh> it barfs in DRC
<tpb> Title: ERROR: [DRC PDRC-43] PLL_adv_ClkFrequency_div_no_dclk: The computed value 1800.0 - Pastebin.com (at pastebin.com)
<benh> interesting... I though 1800.0 was precisely the upper limit, maybe it's 1600..
<Melkhior> 1800 is the limit on -2
<benh> yup, 1600.00 is the limit on -1
<Melkhior> you can try by replacing the speedgrade on all PLL to -1, it should sort you out
<benh> yeah I thought I had, must have missed it, anyways, I have to go, thanks for the advice
<Melkhior> they should fix their documentation if they really produce with -1 :-/
<benh> I'll look again tomorrow and send a PR when v2 works
<Melkhior> feel free to swap J10 and J11 for the V1 in the patch :-)
<benh> actually I don't even know if mine is really a -1 or -2, it's one of those with a QR code only
<benh> it doesn't say what the speed is on the package
<Melkhior> I was thinking of getting a V2 for the embedded sdcard, but if it's a -1, no point, I'll keep mine and the pmod
<benh> yeah and I'll fix the differencial connector too, it's clearly a typo since one pin ends up duplicated
<Melkhior> Vivado HW MGR + JTAG should tell you quickly
<benh> ah how can you tell from JTAG ?
<benh> you mean using the vivado GUI ? yeah I would need to use a vivado compatible jtag probe
<Melkhior> connect to it with the vivado hw manager, it should detect the chip and tell you what it is I think
<benh> I'm currently using an olimex tinyh
<benh> I have an old xilinx platform cable but with an annoying connector I don't have the right match for, and with the ccurrent covid lockdown, I can't really go shopping :-)
<benh> ("jp3", " AF7 AE7 AD8 AC8 AF9 AE9 AD12 AC10",
<benh> "AD12 AC12"),
<benh> "AA11 AB11 AF11 AE11 AD14 AC14 AF13 AE13",
<Melkhior> Got myself a "waveshare" compatible box from Amazon, 40€, works fine with both the Qmtech Wukong and the ZTex board (which has an embedded USB programmer anyway)
<benh> that's the other bug I think... the AD12 in the first line should be AD10
<Melkhior> yeah, sounds plausible :-)
<benh> ok. I ordered a xilinx "compatible" one from aliexpress too, it's somewhere between china and here...
<Melkhior> never tried that connector...
<benh> me neither, I jsut scrubbed the pins to find the diff between 1 and 2
<benh> anyways, gotta go, ttyl
<Melkhior> bye
<Melkhior> benh: turns out I misremembered, it seems Viv HW doesn't see the speedgrade through JTAG - or at least I can't find it in the interface :-(
ilia__s has joined #litex
ilia__s has quit [Remote host closed the connection]
<leons> Melkhior: If the Xilinx forums are to be believed, there is absolutely no way for the FPGA to know it’s own speedgrade. Apparently it’s only determined after manufacturing and not programmed back into the device.
<Melkhior> leons: darn, that's not convenient when you have a heatsink on top of it...
<Melkhior> thx for the info
<benh> I'm making the speed grade an argument to the constructor
<benh> with a default of -2 for v1 and -1 for v2
<benh> Melkhior: allright ... it builds now ... but nothing on serial if I try to run it :-) debugging will be needed, and that will be for another day
<benh> hrm... I suppose it would help if I built it for the right board version =P
<Melkhior> benh: hehe yes, in particular if the clock moved you're not going to get much :-)
<benh> yup :-)
<benh> ok it's up
<benh> and I seem to be getting packets in the peer which is set to 1000bT
<benh> though the "BIOS" says MII on the litex side
<benh> which is .. odd
<benh> that's definitely strange but not something for tonight ... whether I set the peer to 100bT or 1000bT, litex bios says MII (I verified when using gmii_mii in Microwatt standalone that the mode does switch properly there)
<benh> if I look at it with mem_read of the CSR space I see it flipping ... odd
<benh> that said, it shows that liteeth works fine with sys_clk at 100Mhz and rgmii_mii at gigabit speeds
<benh> so the problem with microwatt is ... elsewhere (or timing)
<benh> so as far as BIOS printing the wrong mode, that's because it doesnt' wait long enough after resetting the PHY
<benh> if I sprinkle some eth_mode() here or there it eventually "adjusts":
<Melkhior> benh: to improve reception you can set nrxslots to more than the default 2 in the add_ethernet of the targets, it should buy a bit of time for the core(s) to process packets (as far as I understand)
<Melkhior> help if the traffic is 'bursty'
<Melkhior> if it's sustained, you need faster cores :-)
<benh> Microwatt isn't too bad for such a big beast :-)
<benh> also with pipeline wishbone and my custom L2 cache we get
<benh> Memspeed at 0x40000000 (Sequential, 2.0MiB)...
<benh> Write speed: 84.7MiB/s
<benh> Read speed: 117.0MiB/s
<benh> on the wukong with standalone microwatt (not using LiteX infra, just the standalone eth/dram core + my stuff)
<benh> as a comparison, the standard LiteX VexRiscV on the same board (both at 100Mhz) gives
<benh> Memspeed at 0x40000000 (Sequential, 2.0MiB)...
<benh> Write speed: 27.1MiB/s
<benh> Read speed: 29.2MiB/s
<benh> I think I might know what's wrong with GMII mode on my stuff, I think I hadn't ported over the clock & timing constraints for eth
<benh> sometimes it would be nice to be able to tell Vivado to shut up
<benh> WARNING: [DRC LUTLP-2] Combinatorial Loop Allowed: 1 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. This loop has been identified in the constraints as being known and understood by use of the ALLOW_COMBINATORIAL_LOOPS property on a net in the loop. The cells in the loop are: soc0/processor/execute1_0/random_0/ro_reg
<benh> [63]_i_2.
<benh> well, yeah, we used ALLOW_COMBINATORIAL_LOOPS on this on purpose
<benh> yes, it's not deterministic...
<benh> it's a bloody RNG :-)
<benh> interesting... so MII/GMII switching etc.. works fine in LiteX+VexRiscV
<benh> (using the bios to send/receive packets)
<benh> with standalone microwatt however, I now seem to receive packets fine
<benh> but I can't send
<benh> ie rather it thinks it's sending but nothing lands on the peer
<benh> I'll have to scope it I suppose
<benh> smells like timing
<benh> ah...
<benh> build/microwatt_0/wukong-v2-a100t-vivado/vivado.log:WARNING: [Vivado 12-507] No nets matched 'eth_rx_clk'. [/home/benh/hackplace/microwatt-fusesoc/build/microwatt_0/src/microwatt_0/fpga/wukong-v2.xdc:472]
<benh> build/microwatt_0/wukong-v2-a100t-vivado/vivado.log:CRITICAL WARNING: [Vivado 12-4739] create_clock:No valid object(s) found for '-objects [get_nets eth_rx_clk]'. [/home/benh/hackplace/microwatt-fusesoc/build/microwatt_0/src/microwatt_0/fpga/wukong-v2.xdc:472]
<benh> build/microwatt_0/wukong-v2-a100t-vivado/vivado.log:WARNING: [Vivado 12-507] No nets matched 'eth_tx_clk'. [/home/benh/hackplace/microwatt-fusesoc/build/microwatt_0/src/microwatt_0/fpga/wukong-v2.xdc:473]
<benh> build/microwatt_0/wukong-v2-a100t-vivado/vivado.log:CRITICAL WARNING: [Vivado 12-4739] create_clock:No valid object(s) found for '-objects [get_nets eth_tx_clk]'. [/home/benh/hackplace/microwatt-fusesoc/build/microwatt_0/src/microwatt_0/fpga/wukong-v2.xdc:473]
<benh> if the constraints aren't applied that might explain
<benh> ah the don't touch attributes on the eth_rx_clk/eth_tx_clk nets are getting lost in standalone mode
<benh> hrm.. I wonder where that "keep" comes from
<benh> something's adding a preiod constraint to those clocks, now to find whome...
FabM has quit [Remote host closed the connection]
<_florent_> benh: The keep attribute is automatically added when adding the period constraint on a signal
<_florent_> benh: We should probably add keep attributes in the generator to these signals
<_florent_> benh: Nice otherwise for the mem speed with pipeline wishbone and your L2 cache
<benh> _florent_: yeah I'm debugging ... looks like add_ethernet() adds period constraints to the eth clocks but when using gen.py for a standalone core we don't get them
<benh> _florent_: that's only part of the problem though :-) I need to make my xdc smarter at "finding" the signals... in litex they are all toplevel so the constraints work, with microwatt they are down the hierarchy so I need some smarter constructs
<benh> _florent_: feel free to review my PR fixing up gen.py for ethernet but if you haven't merged yet I suggest you hold
<benh> as I will have more fixes
<benh> but feel free to comment :-)
<benh> oh well, I have the constraints going through now and the problem remains... when used standalone, I get no packets outgoing to the wire at 1000bT
<benh> works fine if I switch the peer to 100 and I can switch back/forth, it always work at 100 and never at 1000
<benh> the mode detection is working fine, I checked looking at the CSR
<benh> and it seems to work with pure litex + vexriscv
<benh> rx works but tx doesn't
<benh> could be a problem with gtx... not sure
<benh> gtx is an oddball DDROutput
hjimenez93[m] has quit [Remote host closed the connection]
promach[m] has quit [Write error: Connection reset by peer]
kaji has quit [Read error: Connection reset by peer]
vomoniyi[m] has quit [Read error: Connection reset by peer]
bluecmd has quit [Remote host closed the connection]
leons has quit [Write error: Connection reset by peer]
dmiller[m] has quit [Write error: Connection reset by peer]
Crofton[m] has quit [Remote host closed the connection]
OmkarBhilare[m] has quit [Remote host closed the connection]
dcallagh has quit [Write error: Connection reset by peer]
Las[m] has quit [Write error: Connection reset by peer]
CarlosEDP has quit [Write error: Connection reset by peer]
a3f has quit [Remote host closed the connection]
david-sawatzke[m has quit [Remote host closed the connection]
willcode4[m] has quit [Write error: Connection reset by peer]
jevinskie[m] has quit [Remote host closed the connection]
sajattack[m] has quit [Remote host closed the connection]
jryans has quit [Write error: Connection reset by peer]
shoragan[m] has quit [Write error: Connection reset by peer]
DerekKozel[m] has quit [Remote host closed the connection]
jryans has joined #litex
shoragan[m] has joined #litex
dcallagh has joined #litex
leons has joined #litex
Las[m] has joined #litex
a3f has joined #litex
promach[m] has joined #litex
jevinskie[m] has joined #litex
CarlosEDP has joined #litex
Crofton[m] has joined #litex
kaji has joined #litex
sajattack[m] has joined #litex
david-sawatzke[m has joined #litex
dmiller[m] has joined #litex
OmkarBhilare[m] has joined #litex
hjimenez93[m] has joined #litex
DerekKozel[m] has joined #litex
willcode4[m] has joined #litex
vomoniyi[m] has joined #litex
bluecmd has joined #litex
yosys-questions has joined #litex
ilia__s has joined #litex
Martoni42 has joined #litex
yosys-questions has quit [Quit: Client closed]
<jevinskie[m]> Well it’s common to clock a ddr bus with a ddr IO itself instead of a dedicated clock pin to reduce skew
<jevinskie[m]> You just fix d_hi to 1, d_lo to 0 and clock and your 1x rate to generate a 1x clock
<tnt> AFAIK it's not just common ... it's the recommended way.
<tnt> "dedicated clock pin" is even often just referring to special input path and means nothing for output.
_franck_ has quit [Excess Flood]
_franck_ has joined #litex
Martoni42 has quit [Ping timeout: 252 seconds]
<jevinskie[m]> My whole problem this whole time was I wasn’t taking into account that ALTDDIO has Xilinx’s SAME_EDGE behavior not SAME_EDGE_PIPELINED. Fixed with a delay register and now ARP core is getting the correct packet :) 🙃
TMM_ has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
TMM_ has joined #litex
yosys-questions has joined #litex
<benh> jevinskie[m]: right, I got that, it's just the way the DDROutput is wired up is a bit funky :-) but it should work
<benh> but for some reason something doesn't and so far I had no luck finding what .... packets are received fine but on tx nothing shows up on the peer
<benh> and my scope isn't fast enough to probe the GMII :-)
<jevinskie[m]> Now we’re in the same boat. Not that traces are even exposed. I’m sure it will end up being something simple, like how I haven’t done ddr constraints on tx yet
<benh> My xdc constraints were bad (the net names weren't right) but fixing that didn't help
<benh> I'll try a pure GMII without the GMII_MII mux later
<benh> gosh, Xilinx are still assholes...
<benh> so that Artix has the new QR code only marking, no speed grade visible... so I requested access to the QR code reading feature in the app
<benh> and they rejected
<benh> some mumbo jumbo about not being an authorized corporate goon
<jevinskie[m]> Yep same here. 🙄
<benh> there is clearly not enough competition in the FPGA space ... :-)
yosys-questions has quit [Quit: Client closed]
<jevinskie[m]> tnt: cough erhmm that fixed the last issue with TX for me :D I’d have 2 ns of skew to figure out what to do with otherwise