Those tracks should definitely be large enough to ...
# openroad
t
Those tracks should definitely be large enough to contain vias, but tracking down what fails, it seems to only consider the overlap between the two tracks when checking the "ENCLOSURE" requirements. Which sounds wrong to me. The
met5
runs horizontally and the
met4
tracks vertically and so it checks the overlaps width (which is the
met4
width against the
met5
enclosure requirement ...)
m
pdn is unconcerned with tracks. It will but a via at the met4/met5 crossing is legal. It sounds like it isn't at this location but without more information its impossible to say much. You could add -failed_via_report <file> to get more info
t
Is that a command line option to openroad ?
nm got it.
Copy code
violation type: Build - macro - top_I.branch\[28\].block\[15\].um_I.block_28_15.tt_pg_vdd_I - met4 -> met5
    srcs: net:vssd1
    bbox = (99.3600, 131.3200) - (100.5600, 137.5200) on Layer -
That really doesn't tell me much though.
m
You can load it in the GUI's drc viewer and see what's going on at that location. Some screen shots would be helpful
t
This is what it looks like :

https://i.imgur.com/ASchSLH.png

And this is what it should look like :

https://i.imgur.com/cQiy2i0.png

m
are the purple stripes wide enough to support the via enclosure?
t
Yes. See the bottom version where
pdngen
put the via, the only thing that changed between those two version is the Y position of the yellow striped. ( In the top version I have
CORE_AREA
set in OpenLane and not in the bottom version which shifts things a bit ).
m
You could try 'set_debug_level PDN Via 2" which will give a lot of output but may give info on why it rejects that via
in your script before calling pdn
set_debug_level PDN ViaEnclosure 2 could be helpful as well
Otherwise you can file an OR issue with an attached test case
t
Definitely prints a lot of info, trying to get the relevant lines for one of the failing vias.
m
look for fail or error in the output
t
yeah the above is a log of a failing one , it tries the 5 generate rules then the 5 tech rules and fails for all.
But in the output there is stuff like :
Copy code
[DEBUG PDN-ViaEnclosure] Top layer met5 with width 6.2000 has 1 rules and enclosures of 0.200000 and 1.100000.
[DEBUG PDN-ViaEnclosure] Top rule enclosures 0.310000 and 0.310000 -> false.
Which I don't get ... the top track (in yellow) is massive, 6.2 wide and thousands long, so it can for sure fit a 0.31 (enclosure) + 0.8 (cut) + 0.31 (enclosure) there there ...
I just tweaked the offset given to pdn gen so that the
met5
stripes end up at exactly the same
Y
coordinate wether I set CORE_AREA or not ... and still one one case I get via and in the other I don't ...
m
That sounds very odd
t
Yeah, I've been banging my head against the wall for the past 6 hours about this ..
I'm not sure if it's the same root cause but someone has some similar symptoms at least : https://github.com/The-OpenROAD-Project/OpenLane/issues/2102
Untitled.diff
Small diff of debug output between working and non working case.
m
must_fix_x differing is interesting. Is there some change in the preferred direction?
t
Nope.
m
or a change in terms?
t
terms ?
m
top level ports?
or block terms
t
No. The only change between the runs is I set
CORE_AREA
in openlane or not, and adjust the PDN offset to make the stripe match Y position to be able to compare.
Same macro, same everything else.
So apparently it's triggered by having the left margin being 0. (between die area and core area).
m
how can you tell?
t
Copy code
"DIE_AREA": [0, 0, 3166.63, 4766.63],
    "CORE_AREA": [0.1, 0, 3166.63, 4766.63],
The above works. If I set CORE_AREA to start at 0.0, it doesn't ...
m
Its not clear to me what the connection is
t
Yeah, me either ...
hasTermConnections()
returns true for the failing case for some reason.
For some reason it thinks the first 1.6um of each horizontal PDN strip on
met5
is a BTerm ... (at leas tthat's the rect in the bterm list).
And I'm having a hard time tracing in the flow where that gets inserted in that list.
Copy code
// add bpins that touch edges
  odb::Rect die_area = getBlock()->getDieArea();
  const odb::Rect& final_shape_rect = shape_ptr->getRect();
  const int min_width = shape_ptr->getLayer()->getMinWidth();
  if (final_shape_rect.xMin() == die_area.xMin()) {
    const int x = std::min(static_cast<int>(die_area.xMin() + min_width),
                           final_shape_rect.xMax());
    odb::Rect pin_rect = final_shape_rect;
    pin_rect.set_xhi(x);
    shape_ptr->addBTermConnection(pin_rect);
  }
So it's done on purpose for some reason ?!?!? But this completely messes with the VIA creation.
m
That is looking at die area not core area - I thought you were changing the core area
Perhaps the difference is that with the core==die these stripes reach the edges and therefore get pins attached to them
t
yes exactly
m
It is unusual to have core==die - what is the use model?
t
This is the top-level for tiny tapeout. It's just "gluing" a bunch of macros together, there is no standard cell grid being generated and having everything referenced to the origin 0,0 makes things a bit easier to keep everything where it needs to be.
But even if pins get attached, I don't really see it as a reason to not generate via that fit just fine ...
m
Is this something you can make a public issue for?
t
Yes, I'm writing it up right now and uploading a reproduce case.
m
My guess is that the bpin's trigger a more restrictive view to require full enclosure but it would be easiest to pass it to Peter
Thanks please file against OR directly