<h_ro>
Wanda[cis]: never used XACT before, so I am interested in hearing what you came up with and how your reversing methodology for XACT differs from ISE
<Wanda[cis]>
methodology is the same, but I structured the code a lot better
<Wanda[cis]>
well, at least the same for the actual reversing; I improved geometry extraction methodology a bit
<Wanda[cis]>
the ISE bitstream reversing code uses Rust macros to construct testcases, with some weird sexpr-like syntax to describe the attribtues to be tested and the prerequisites. this was a major mistake, as it centralizes pretty much every kind of attribute I could possibly want to test in all supported devices in a single unwieldy macro, and then in a single unwieldy enum which is matched over by incredibly unwieldy test-batcher code
<Wanda[cis]>
when I started, I thought I'd only need like a handful of those, but... well reality turned out to be complex
<Wanda[cis]>
the testcase generation code is split in a funny way: first, I generate a declarative list of things I'd like to test within every tile type
<Wanda[cis]>
this is the majority of the code
<h_ro>
Are you referring to the fuzzing macros in ise_hammer?
<Wanda[cis]>
second, a test batcher goes through this list and assigns every testcase to an actual test batch, and to an actual tile of the desired type
<Wanda[cis]>
yes
<Wanda[cis]>
they are absolutely horrible.
<Wanda[cis]>
so. the second part is much shorter than the first, and I hoped it'd be simple
<Wanda[cis]>
unfortunately turns out that sometimes assigning the testcase to an actual tile of the device involves complex logic
<Wanda[cis]>
it contains pretty much all of the second stage
<Wanda[cis]>
it has highly generic code mixed in with very device-specific code
<Wanda[cis]>
there are also problems with using macros in the first place. the immediately noticable one is that compiling the crate is ridiculously slow
<Wanda[cis]>
it's also annoying when writing the code because rustfmt either gives up on the macro invocations, or in rare cases formats them in nonsensical way
<h_ro>
yeah that looks cumbersome
<Wanda[cis]>
the corresponding code in xact_hammer is structured differently; the macros are replaced by a builder pattern, the TileKV/BelKV/... enums are replaced with dynamic dispatch (boxed dyn trait objects)
<Wanda[cis]>
the "generic" attributes stay in generic code and get used most of the time, and when I need weird device-specific processing in the second stage, I just define a new impl of the trait right next to whatever first-stage code uses it
ari has quit [Ping timeout: 246 seconds]
sdomi has quit [Ping timeout: 272 seconds]
sdomi has joined #prjcombine
Maja has quit [Ping timeout: 245 seconds]
Maja has joined #prjcombine
<Wanda[cis]>
then there's geometry extraction
<Wanda[cis]>
which would be xrd2geom for ISE
<Wanda[cis]>
this stage produces several results
<Wanda[cis]>
1) an interconnect tile database (list of tile types, list of wires in all tiles, list of connections between wires, list of bels and assignment of their pins to wires)
<Wanda[cis]>
2) a naming database (whatever is necessary to map prjcombine wire/bel/... IDs to toolchain identifiers; for ISE, it's wire names; for XACT, it's (X, Y) coordinates of every connection point)
<Wanda[cis]>
3) device database (enough information about each device of FPGA family to reconstruct a complete tile grid and whatever else we need)
<Wanda[cis]>
4) package database (pin <-> I/O pad mapping)
<Wanda[cis]>
the ISE code is a bit of a mess; for 3., each family has a bit of code that scans the toolchain grid and extracts just enough information
<Wanda[cis]>
for 1. and 2.... well this is the really messy part
<Wanda[cis]>
first I manually produce the list of wires and their geometry for each device kind, plus enough information to figure out the mapping to ISE wire names
<Wanda[cis]>
then I go over all tile types, look for a specimen within the device, and extract the pips and bels
<Wanda[cis]>
using the ugliest piece of code in the entire project, the prjcombine_rdintb crate
<Wanda[cis]>
it's an incredibly delicate piece of code that automatically extracts pips based on a ton of knobs that can be tweaked by the device-specific code before invoking it; it kinda suffers from the same problem as fgen.rs, ie. containing a lot of device specific hacks that can interact with each other in unpredictable ways sometimes, and I feel really uneasy whenever I have to tweak something there
ari has joined #prjcombine
<Wanda[cis]>
the other problem is that it operates on the source database only locally
<Wanda[cis]>
it does some verification, but it can easily fail to notice more complex problems
<Wanda[cis]>
so the final stage uses the information previously extracted to do a full verification pass of the resulting database against the source database
<Wanda[cis]>
that's what prjcombine_rdverify and prjcombine_<device>_rdverify are for
<Wanda[cis]>
this, of course, duplicates a bunch of work
<h_ro>
Just curious: what would you say sitePIPs (and site wires) are? Are these just bits you enable in the bitstream for the corresponding tile/site?
<Wanda[cis]>
the XACT database extractor does a single extraction+verification pass
<Wanda[cis]>
not sure what you mean by site wires
<Wanda[cis]>
or site pips for that matter
<Wanda[cis]>
are these the vivado terms?
<h_ro>
Routing BELs on CLB for instance can select between an inverted signal or non-inverting signal. So I was wondering how these map to the bitstream
<Wanda[cis]>
what device is this about?
<h_ro>
7 series; likely vivado terms
<Wanda[cis]>
that's strange; the virtex7 CLB contains like only a single programmable inverter for the clock signal, I think?
<h_ro>
ultrascale has a few more I believe
<Wanda[cis]>
yeah ultrascale has a bunch more of that
<h_ro>
DSP48 has several for some inputs
<Wanda[cis]>
also older devices have more
<Wanda[cis]>
v5/v6/v7/s6 have mostly just clocks
<Wanda[cis]>
anyway, well
<Wanda[cis]>
it's just a programmable inverter on the clock input of the CLB
<Wanda[cis]>
the clock signal from the interconnect MUX is essentially XORed with a bitstream bit before being routed to the FFs within CLB; that's it
<h_ro>
I see
<Wanda[cis]>
you can find the relevant bit in prjcombine database as SLICE*.INV.CLK on the CLB* tiles
<Wanda[cis]>
in general I use `INV.<pin>` on bels for invertible inputs, as a convention
<Wanda[cis]>
that's for virtex7 and similar devices at least, where the inversion is conceptually part of the bel
<Wanda[cis]>
on the other hand, for virtex2/virtex4, the inversion is actually part of the interconnect tile (ie. the relevant inverter bit is always at the same location for a given interconnect mux, regardless of what bel it feeds, if any)
<Wanda[cis]>
(this is actually observable if you make use of the interconnect test circuitry to U-turn the input mux output back into the interconnect; on virtex4, you'll see the inverted signal, while on virtex5 and up you'll see the signal before inversion)
<Wanda[cis]>
as for site pips and site wires
<Wanda[cis]>
vivado uses them to name internal wires and muxes within the bel (ie. internal stuff not exposed to general interconnect)
<Wanda[cis]>
prjcombine just considers them part of the bel, and whatever bits control the muxes get represented as bel attributes
<Wanda[cis]>
(this is consistent with how ISE represents them)
<h_ro>
ISE PlanAhead does have the relevent tcl command `get_site_pips`
<Wanda[cis]>
PlanAhead is basically an early and incredibly buggy vivado.
<h_ro>
true
<h_ro>
Alright, thanks for answering
<Wanda[cis]>
I tried extracting geometry data from it instead of dealing with xdl, but quickly abandoned this plan when it became clear that it's just going to segfault if you so much as look at it wrong
<Wanda[cis]>
there's btw another related concept
<Wanda[cis]>
to the site pip
<Wanda[cis]>
I don't remember what it was called in vivado
<Wanda[cis]>
ISE calls them "routethrough pips"
<h_ro>
I think I have heard of it in RapidWright
<Wanda[cis]>
it's basically a fake pip that's in the routing database, which is actually realized by programming a bel in a particular way
<Wanda[cis]>
eg. whenever you have a LUT, you also have a routethrough pip that goes from its I1 input to its comb output
<Wanda[cis]>
(or from any other input for that matter)
<Wanda[cis]>
it's not a real separate thing; if you attempt to use it, ISE/vivado will just realize it by configuring a passthrough truth table into the LUT
<Wanda[cis]>
prjcombine just strips them out, they're not represented in the database in any way
<Wanda[cis]>
btw both this and the decision on how to represent site pips are done this way because I already have a rough plan on how a mostly-generic P&R (and, in particular, the packing stage) interface should be implemented
<Wanda[cis]>
see, site pips should not be treated the same as proper interconnect pips because of what they imply for your routing stage
<Wanda[cis]>
the site pip is kinda the same thing as a regular pip in its function, but from routing PoV it implies a heavy constraint: the two things you connect must be within the same block
<Wanda[cis]>
ie. either the two primitives you're connecting are already in the right position and you can and should trivially use the site pip, or they are not and the site pip is useless
<Wanda[cis]>
ie. site pips actually come into play during packing/placement stage, not routing
<h_ro>
I'd love to pick your brain on PNR stages, but I will need to head out soon.
<Wanda[cis]>
that's why I represent them the exact same way as bel attributes (which can become packing constraints just like site pips)
<Wanda[cis]>
... XC2000 done
<mupuf>
Wanda[cis]: jeez, you are on fire! Have you slept at all?
<mupuf>
or did you just leave your fuzzer run while taking a cat nap?