Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard cell placement under power straps with same metal as standard cell pins causing obstructions for route. #1938

Closed
nchiolino opened this issue Apr 15, 2024 · 103 comments
Labels
dpl Detailed Placement Legalization gpl Global Placement mpl Macro Placement

Comments

@nchiolino
Copy link

Subject

[Stage]: Detail Placement.

Describe the bug

I am working with a less mature process that has only three metal layers. The standard cell pins use both Metal-1 and Metal-2 for escapement to routing. I am using Metal-2 for the vertical power strapping to the standard cell horizontal rows. Detail placement is placing standard cells under the Metal-2 power straps which is resulting in the Metal-2 standard cell pins to short to power or ground as well as being obstructed during detailed route.

Expected Behavior

Shouldn't the detailed placement tool know that the standard cell pins contain Metal-2 and not to short them to the Metal-2 power and ground straps during placement? If not, how do I tell the detail placement tool to not place any standard cells under the Metal-2 power and ground straps?

Environment

[WARNING] Your current OpenROAD version is outdated.

It is recommened to pull the latest changes.

If problem persists, file a github issue with the re-producible test case.

kernel: Linux 6.5.0-26-generic

os: Ubuntu 22.04.4 LTS (Jammy Jellyfish)

cmake version 3.24.2

-- The CXX compiler identification is GNU 11.4.0

-- Detecting CXX compiler ABI info

-- Detecting CXX compiler ABI info - done

-- Check for working CXX compiler: /usr/bin/c++ - skipped

-- Detecting CXX compile features

-- Detecting CXX compile features - done

-- OpenROAD version: v2.0-10925-gb7c9b7e1c

-- System name: Linux

-- Compiler: GNU 11.4.0

-- Build type: RELEASE

-- Install prefix: /usr/local

-- C++ Standard: 17

-- C++ Standard Required: ON

-- C++ Extensions: OFF

-- The C compiler identification is GNU 11.4.0

-- Detecting C compiler ABI info

-- Detecting C compiler ABI info - done

-- Check for working C compiler: /usr/bin/cc - skipped

-- Detecting C compile features

-- Detecting C compile features - done

-- Found Python: /usr/bin/python3.10 (found version "3.10.12") found components: Interpreter 

-- Performing Test CMAKE_HAVE_LIBC_PTHREAD

-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success

-- Found Threads: TRUE  

-- Performing Test C_COMPILER_SUPPORTS__-Wall

-- Performing Test C_COMPILER_SUPPORTS__-Wall - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wall

-- Performing Test CXX_COMPILER_SUPPORTS__-Wall - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-array-bounds

-- Performing Test C_COMPILER_SUPPORTS__-Wno-array-bounds - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-array-bounds

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-array-bounds - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-nonnull

-- Performing Test C_COMPILER_SUPPORTS__-Wno-nonnull - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-nonnull

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-nonnull - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-maybe-uninitialized

-- Performing Test C_COMPILER_SUPPORTS__-Wno-maybe-uninitialized - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-maybe-uninitialized

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-maybe-uninitialized - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-format-overflow

-- Performing Test C_COMPILER_SUPPORTS__-Wno-format-overflow - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-format-overflow

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-format-overflow - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-variable

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-variable - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-variable

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-variable - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-function

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-function - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-function

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-function - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-write-strings

-- Performing Test C_COMPILER_SUPPORTS__-Wno-write-strings - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-write-strings

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-write-strings - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-sign-compare

-- Performing Test C_COMPILER_SUPPORTS__-Wno-sign-compare - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-sign-compare

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-sign-compare - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-deprecated

-- Performing Test C_COMPILER_SUPPORTS__-Wno-deprecated - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-deprecated

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-deprecated - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-c++11-narrowing

-- Performing Test C_COMPILER_SUPPORTS__-Wno-c++11-narrowing - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-c++11-narrowing

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-c++11-narrowing - Failed

-- Performing Test C_COMPILER_SUPPORTS__-Wno-register

-- Performing Test C_COMPILER_SUPPORTS__-Wno-register - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-register

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-register - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-format

-- Performing Test C_COMPILER_SUPPORTS__-Wno-format - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-format

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-format - Success

-- Performing Test C_COMPILER_SUPPORTS__-Wno-reserved-user-defined-literal

-- Performing Test C_COMPILER_SUPPORTS__-Wno-reserved-user-defined-literal - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-reserved-user-defined-literal

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-reserved-user-defined-literal - Failed

-- Performing Test C_COMPILER_SUPPORTS__-fpermissive

-- Performing Test C_COMPILER_SUPPORTS__-fpermissive - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__-fpermissive

-- Performing Test CXX_COMPILER_SUPPORTS__-fpermissive - Success

-- Performing Test C_COMPILER_SUPPORTS__-x

-- Performing Test C_COMPILER_SUPPORTS__-x - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__-x

-- Performing Test CXX_COMPILER_SUPPORTS__-x - Failed

-- Performing Test C_COMPILER_SUPPORTS__c++

-- Performing Test C_COMPILER_SUPPORTS__c++ - Failed

-- Performing Test CXX_COMPILER_SUPPORTS__c++

-- Performing Test CXX_COMPILER_SUPPORTS__c++ - Failed

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-but-set-variable

-- Performing Test C_COMPILER_SUPPORTS__-Wno-unused-but-set-variable - Success

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-but-set-variable

-- Performing Test CXX_COMPILER_SUPPORTS__-Wno-unused-but-set-variable - Success

-- TCL library: /usr/lib/x86_64-linux-gnu/libtcl.so

-- TCL header: /usr/include/tcl/tcl.h

-- TCL readline library: /usr/lib/x86_64-linux-gnu/libtclreadline.so

-- TCL readline header: /usr/include/x86_64-linux-gnu

-- Found SWIG: /usr/bin/swig4.0 (found suitable version "4.0.2", minimum required is "3.0")  

-- Found Boost: /usr/local/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found version "1.80.0")  

-- boost: 1.80.0

-- Found Python3: /usr/include/python3.10 (found version "3.10.12") found components: Development Development.Module Development.Embed 

-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 

-- spdlog: 1.8.1

-- Found BISON: /usr/bin/bison (found version "3.8.2") 

-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 

-- STA version: 2.4.0

-- STA git sha: 3e2295adfd5ffb7053aa6bb68f31b0eae8f2986f

-- System name: Linux

-- Compiler: GNU 11.4.0

-- Build type: RELEASE

-- Build CXX_FLAGS: -O3 -DNDEBUG

-- Install prefix: /usr/local

-- Found FLEX: /usr/bin/flex (found version "2.6.4") 

-- TCL library: /usr/lib/x86_64-linux-gnu/libtcl.so

-- TCL header: /usr/include/tcl/tcl.h

-- SSTA: 0

-- STA executable: /home/nchiolino/OpenROAD-flow-scripts/tools/OpenROAD/src/sta/app/sta

-- Found re2: /opt/or-tools/lib/cmake/re2/re2Config.cmake (found version "9.0.0") 

-- Found Clp: /opt/or-tools/lib/cmake/Clp/ClpConfig.cmake (found version "1.17.7") 

-- Found Cbc: /opt/or-tools/lib/cmake/Cbc/CbcConfig.cmake (found version "2.10.7") 

-- Found SCIP: /opt/or-tools/lib/cmake/scip/scip-config.cmake (found version "8.0.1") 

-- Found OpenMP_CXX: -fopenmp (found version "4.5") 

-- Found OpenMP: TRUE (found version "4.5")  

-- GPU is not enabled

-- TCL library: /usr/lib/x86_64-linux-gnu/libtcl.so

-- TCL header: /usr/include/tcl/tcl.h

-- Found Eigen3: /usr/local/share/eigen3/cmake/Eigen3Config.cmake (found version "3.4.1") 

-- GUI is enabled

-- Charts widget is not enabled

-- Found Boost: /usr/local/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found version "1.80.0") found components: serialization 

-- Could NOT find VTune (missing: VTune_LIBRARIES VTune_INCLUDE_DIRS) 

-- Found Boost: /usr/local/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found suitable version "1.80.0", minimum required is "1.78")  

-- TCL library: /usr/lib/x86_64-linux-gnu/libtcl.so

-- TCL header: /usr/include/tcl/tcl.h

-- Found Boost: /usr/local/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found version "1.80.0") found components: serialization system thread 

-- TCL readline enabled

-- Tcl Extended disabled

-- Python3 enabled

-- Configuring done

-- Generating done

-- Build files have been written to: /tmp/tmp.CtPBzhKa85

To Reproduce

I am implementing a proprietary technology so unfortunately, this is not reproduceable by the community.

Relevant log output

No response

Screenshots

As seen in this image, Metal-2 vertical straps (RED) are running over Metal-2 standard cell pins (RED). This results in a pin short to either power or ground and also obstructs the detailed router and will not complete the flow. Unobstructed standard cells can be seen on the left side of the image.
image

Additional Context

My plan is to leave large columns of unobstructed area for routing of M1-M3 over standard cells. Vertical straps of Metal-2 will interrupt placement cells allowing only Metal-3 to route east/west to hop over Metal-2 power/ground straps. Floorplan can be seen in the attached image.
image

@maliberty
Copy link
Member

In pdks with more layers you rarely see this so the placer doesn't handle it currently. I suggest putting placement blockages under your stripes to avoid any cells going there as a workaround.

@maliberty maliberty added dpl Detailed Placement Legalization gpl Global Placement labels Apr 15, 2024
@nchiolino
Copy link
Author

Matt, thank you so very much for the super fast response.
Understood. That sounds like a great work around, how would I put placement blockage under the stripes? I apologize if that is somewhat straight forward. Do I handle that in the PDN.tcl file?

@maliberty
Copy link
Member

I think it will require some custom scripting. You could see https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/master/flow/scripts/placement_blockages.tcl as an example of creating blockages (in that case for macro channels).

@nchiolino
Copy link
Author

Ok. So if I am understanding this correctly. This script is run every time right now for macros. So would I insert what I need into this script or create a script of my own? Does this script get called in the Makefile?

@maliberty
Copy link
Member

There is a hook in pdn for POST_PDN_TCL (

if { [info exists ::env(POST_PDN_TCL)] && [file exists $::env(POST_PDN_TCL)] } {
) so you could create a script and set the variable to pick it up.

@nchiolino
Copy link
Author

Excellent! I will give that a shot.
Thank you very much for the support.

@nchiolino
Copy link
Author

Before this issue is closed, would you like for me to feedback to you if it worked? I will leave that decision up to you.

@maliberty
Copy link
Member

Its always nice to hear about success 😄

@nchiolino
Copy link
Author

The issue that I am running into right now is I dont know how to get the shape of the POWER and GROUND nets. In the macro version it sets a box after it finds the instances using
foreach inst [$block getInsts] { if {[[$inst getMaster] getType] == "BLOCK"} { set box [$inst getBBox]
But when I go to find nets using $block getNets it does not return the shape of the net. I am assuming. How do I get a box of the nets? Is there a getNetShape or something?

@maliberty
Copy link
Member

You'll need to use dbNet::getSWires and then dbSWire::getWires to get the boxes that make up the net.

@nchiolino
Copy link
Author

I apologize for bothering you again on this but I think I need some assistance in understanding what these odb objects are doing. I tried modifying the placement_blockage.tcl script to simply place a box of placement blockage of specific x and y size it seems to not be working. I ran the flow past placement and when viewing the layout in the gui I am not seeing the blockage. I have placement blockage view turned on as well. Here is the script.

proc block_stripes {} {
  set block [ord::get_db_block]
  set b [odb::dbBlockage_create $block 200 60 400 200]
 $b setSoft
 puts $b
}

@maliberty
Copy link
Member

I think you are making such a small blockage it is hard to see. I tried set b [odb::dbBlockage_create $block 1200 60 4000 2000]
image

@nchiolino
Copy link
Author

Ah yes. I made a bad assumption of the order of magnitude of the box. I see it on my end now. Excellent! Thank you very much.

@nchiolino
Copy link
Author

Thank you for helping me with that. It looks like it is sort of working but cells are still placing over that area. Is there a way to set a hard keep out? Sorry for all the questions and thank you for the support.
image

@maliberty
Copy link
Member

Blockages are hard by default

@maliberty
Copy link
Member

I can't actually see the placement blockage in your image - would you turn off the stripe and turn on the blockage

@nchiolino
Copy link
Author

Oh sorry. Is this image better? Again, it seems to be placing standard cells over the blockage still.
image

@maliberty
Copy link
Member

At what step in the flow are you creating the blockage?

@nchiolino
Copy link
Author

The code that is generating that blockage is being implemented in the POST_PDN.tcl file. So it is executed during the PDN step. Should the blockage exist before the PDN script? I notice that it looks for macros before this step, is that critical?

@maliberty
Copy link
Member

That should work. Is this something where you can provide a non-proprietary test case?

@nchiolino
Copy link
Author

Yes, I did some work to repeat this "issue" with the sky130hd tech. To repeat what I have, I modified the the following:
/flow/designs/sky130hd/gcd/config.mk

export DESIGN_NAME = gcd
export PLATFORM    = sky130hd
export VERILOG_FILES = ./designs/src/$(DESIGN_NICKNAME)/gcd.v
export SDC_FILE      = ./designs/$(PLATFORM)/$(DESIGN_NICKNAME)/constraint.sdc
# Adders degrade GCD
export ADDER_MAP_FILE :=
export CORE_UTILIZATION = 20
export CORE_ASPECT_RATIO = 0.3
export CORE_MARGIN       = 2
export PLACE_DENSITY     = 0.65
#export TNS_END_PERCENT = 100
#export DIE_AREA    = 0.0 0.0 86.36 88.88
#export CORE_AREA   = 5.00 5.00 81.36 83.88
# Use custom power grid with core rings offset from the pads
export PDN_TCL = ./designs/$(PLATFORM)/gcd/pdn.tcl
#export EQUIVALENCE_CHECK    =   1
export REMOVE_CELLS_FOR_EQY = sky130_fd_sc_hd__tapvpwrvgnd*

I added the line
export POST_PDN_TCL ?= $(PLATFORM_DIR)/post_pdn.tcl
to /flow/platforms/sky130hd/config.mk
The custom pdn.tcl file that I added here: /flow/designs/sky130hd/gcd/pdn.tcl

####################################
# global connections
####################################
add_global_connection -net VDD -pin_pattern {^VDD$} -power
add_global_connection -net VDD -pin_pattern {^VDDPE$}
add_global_connection -net VDD -pin_pattern {^VDDCE$}
add_global_connection -net VDD -pin_pattern {VPWR}
add_global_connection -net VDD -pin_pattern {vdd}
add_global_connection -net VSS -pin_pattern {^VSS$} -ground
add_global_connection -net VSS -pin_pattern {^VSSE$}
add_global_connection -net VSS -pin_pattern {VGND}
####################################
# voltage domains
####################################
set_voltage_domain -power VDD -ground VSS
####################################
# standard cell grid
####################################
define_pdn_grid -name "Core"
#add_pdn_ring -grid {grid} -layers {met4 met5} -widths {3 3} -spacings {1.6 1.6} -pad_offsets {10 10} -connect_to_pads -starts_with POWER
add_pdn_ring -grid "Core" -layers {met4 met5} -widths 3.0 -spacings 1.6 -core_offsets 10
add_pdn_stripe -layer {met1} -width 0.49  -pitch 5.44  -offset 0.00 -followpins
#add_pdn_stripe -layer {met4} -width 0.96 -spacing 5.00 -pitch 56.00 -offset 2.00 -extend_to_core_ring
add_pdn_stripe -layer {met4} -width 2.96 -spacing 1.00 -pitch 56.00 -offset 2.00 -extend_to_core_ring
add_pdn_stripe -layer {met5} -width 1.60 -pitch 56.00 -offset 2.00 -extend_to_core_ring
add_pdn_connect -layers {met1 met4}
add_pdn_connect -layers {met4 met5}
pdngen
####################################

The next file that was added generates the blockage. It lives here:
/flow/platforms/sky130hd/post_pdn.tcl

proc block_stripes {} {
  set block [ord::get_db_block]
      set b [odb::dbBlockage_create $block 32000 14000 165000 40000]
      $b setSoft
}

The function block_stripes has to then get called in the pdn.tcl script here:
/OpenROAD-flow-scripts/flow/scripts/pdn.tcl

source $::env(SCRIPTS_DIR)/load.tcl
load_design 2_5_floorplan_tapcell.odb 1_synth.sdc "Starting PDN generation"

source $::env(PDN_TCL)
pdngen

if { [info exists ::env(POST_PDN_TCL)] && [file exists $::env(POST_PDN_TCL)] } {
  source $::env(POST_PDN_TCL)
}

block_stripes

# Check all supply nets
set block [ord::get_db_block]
foreach net [$block getNets] {
    set type [$net getSigType]
    if {$type == "POWER" || $type == "GROUND"} {
# Temporarily disable due to CI issues
#        puts "Check supply: [$net getName]"
#        check_power_grid -net [$net getName]
    }
}

if {![info exists save_checkpoint] || $save_checkpoint} {
  if {[info exists ::env(GALLERY_REPORT)]  && $::env(GALLERY_REPORT) != 0} {
    write_def $::env(RESULTS_DIR)/2_floorplan.def
  }
  write_db $::env(RESULTS_DIR)/2_6_floorplan_pdn.odb
}

All other files associated with the sky130hd has not been modified from when I grabbed it from the repo.
Once this is all setup, I ran
make place
and it generated the image attached. You can see that a standard cell has been placed inside the blockage.
image
Let me know your thoughts.
Thank you

@nchiolino
Copy link
Author

nchiolino commented Apr 23, 2024

Sorry to request more help on this issue but as it turns out, I am terrible at TCL, definitely not my strong suit. That in combination with little to no documentation on the db variable, I think I could use a hand on this script. I have test all the sections of this script apart from the collection of shapes. The set shapset, clip result, and output work. The only portion that I cannot correctly script is the collect shapes portion (lines 12-17).

proc block_stripes {} {
  set tech [ord::get_db_tech]
  set units [$tech getDbUnitsPerMicron]
  set block [ord::get_db_block]

  #
  # Collect up all the stripes as boxes
  #
  #set shapes {}
  #    lappend shapes [odb::newSetFromRect 873399 0 903399 306200]

  set shapes [dbNet::getSWires]
  foreach wires [$wires dbSWire::getWires] {
       set box [$wires getBBox]
       lappend shapes [odb::newSetFromRect [$box xMin] [$box yMin] [$box xMax] [$box yMax]]
    }
  #
  # Set shapeset variable 
  #
  set shapeSet [odb::orSets $shapes]

  #
  # Clip result to the core area
  #
  set core [$block getCoreArea]
  set xl [$core xMin]
  set yl [$core yMin]
  set xh [$core xMax]
  set yh [$core yMax]
  set core_rect [odb::newSetFromRect $xl $yl $xh $yh]
  set shapeSet [odb::andSet $shapeSet $core_rect]

  #
  # Output the blockages
  #
  set rects [odb::getRectangles $shapeSet]
  foreach rect $rects {
      set b [odb::dbBlockage_create $block \
                 [$rect xMin] [$rect yMin] [$rect xMax] [$rect yMax]]
      $b setSoft
   }
}

@maliberty
Copy link
Member

I looked at the detailed placer and I think it is not handling such blockages (the global placer does). A workaround would be to generate the blockage creation into a script and then run it before initialize_flooplan so that the rows are cut by these blockages.

@nchiolino
Copy link
Author

@maliberty , thank you very much for looking into that. That makes sense to have to generate the shape before it creates the site rows. I apologize for the delayed response, I have been working to get other parts of the flow operating with this technology. I am now back onto this issue and I very much need this to work in order to realize a fully routed design unfortunately.
I started by inserting the block_stripes proc in the floorplan.tcl script below, at this point and unfortunately, it looks like its working too well. It is now cutting the horizontal power strapes and the pdn generation is attempting to connect the met1 strapes with another pair of met2 vertical wires. Any advice on what to do next?

# Initialize floorplan using CORE_UTILIZATION
# ----------------------------------------------------------------------------
} elseif {[info exists ::env(CORE_UTILIZATION)] && $::env(CORE_UTILIZATION) != "" } {
  set aspect_ratio 1.0
  if {[info exists ::env(CORE_ASPECT_RATIO)] && $::env(CORE_ASPECT_RATIO) != ""} {
    set aspect_ratio $::env(CORE_ASPECT_RATIO)
  }

  set core_margin 1.0
  if {[info exists ::env(CORE_MARGIN)] && $::env(CORE_MARGIN) != ""} {
    set core_margin $::env(CORE_MARGIN)
  }

proc block_stripes {} {
  set block [ord::get_db_block]
      set b [odb::dbBlockage_create $block 838399 39100 903399 268899]
      $b setSoft
}
block_stripes

  initialize_floorplan -utilization $::env(CORE_UTILIZATION) \
                       -aspect_ratio $aspect_ratio \
                       -core_space $core_margin \
                       -site $::env(PLACE_SITE)

# Initialize floorplan using DIE_AREA/CORE_AREA

image
image

@nchiolino
Copy link
Author

@maliberty , I had another idea that I am trying to setup. Is the flow capable of placing a MACRO with no pins and no liberty information in the core? I think that if I can create a BLOCK of met2 obstruction or via obstruction right under the power straps, that the DRC rules will avoid placing a standard cell in that area. Is that equivalent to the blockage we have already tried? I am trying to use the macro place command but cant seem to get it to work.

place_macro
    -macro_name macro_name
    -location {x y}
    [-orientation orientation]

Any thoughts on that idea?

@rovinski
Copy link
Member

rovinski commented May 6, 2024

placing a MACRO with no pins and no liberty information in the core?

Yes

There is the cut_rows command which breaks up rows to remove certain cell sites, and this could be run after power planning is done so that it won't impact the power grid. Unfortunately, it's only set up right now to remove cell sites underneath macros.

If you could create fake macros (they don't even need obstruction layers) over the areas you want to prevent placement, I believe you could run cut_rows to remove the cell sites, and then delete the macros.

I was thinking briefly about how hard it would be to simply add in a manual cut_rows function to remove sites in a user-specified rectangle, but I think that ultimately making the detailed placer respect placement blockages is a better solution.

@maliberty
Copy link
Member

It is somewhat equivalent as the macro will just cause the rows to be cut the same as the blockage did. However the OBS will induce spacing requirements that I don't think you want.

@maliberty
Copy link
Member

@rovinski note that if dpl obeys the blockage the flow will have to be changed as well. Today gpl will respect blockages around macros but rsz might put some buffers in an otherwise blocked channel between macros. Currently dpl will legalize them there but if we obeyed the blockage they would be moved far away. We would have to remove the macro blockages after gpl. We would need to distinguish mpl created blockages from user ones.

@maliberty
Copy link
Member

I don't see how adding blockages would have had this effect. Please check for any pilot error.

@nchiolino
Copy link
Author

I get a successful result if I run the flow with no PDN or blockage.
image
I can get all the way to DRT (successful DPL) with no obstructions. Obviously it cant route because of the original problem.
image
Then when I add the blockage in the POST_PDN.tcl file, I get the result below. I even made sure that the blockage snapped to the row grid, in case that helped. So from my end, the only addition that is making this error occur is adding the blockage. I dont see any description about them being fixed. Here is a screen shot of the inspector with a "bad" cell (095) as well as the error again showing that its during DPL. Is there a chance its still something on my end?
image
image

@nchiolino
Copy link
Author

Also, I am still getting a GUI error with this new build. It seems to be when it tries to open klayout and proceed with the GDS conversion and end of flow. Here is a screen shot of the error when running the Nandgate45/gcd example. I don't mean to conflict errors in the same stream but I didn't know if these issues were related. It's just new since I did the most recent build. Do I need to file a separate issue?
image

@maliberty
Copy link
Member

That would be a separate issue.

I'm totally perplexed by this. Do you get any messages during detailed_place? Are those instances in the same location they were before detailed_place? Can you run with blockages but no pdn?

@nchiolino
Copy link
Author

Ok, I will file a bug in a separate issue.

It still does not seem to work with PDN off. I have attached the log from DPL. Here is a screen shot from right after floorplan (3_1_place_gp_skip_io).
image
3_5_place_dp.tmp.log
Stupid question. When executing a new build of the tool, does it update all of the script files? I noticed that the blockage additions that I had made to the floorplan.tcl file was still there after I did the new build. Is there a chance that I am running a new OR tool with previous scripts?

@maliberty
Copy link
Member

3_1_place_gp_skip_io is before detailed_place has been run so it is too early in the flow to evaluate. You need to look at 3_5_place_dp

@maliberty
Copy link
Member

build.sh updates the OR submodule but does not update ORFS itself.

@nchiolino
Copy link
Author

Yea, I see that now. I tried to run the flow with updated ORFS and nothing works so I will need some time to untangle this knot. My apologies.

@nchiolino
Copy link
Author

@maliberty , I was able to get a fresh build of ORFS working with the latest OR and unfortunately I am having the same issue. Something is happening during DRT with the obstructions that is breaking it. Have you run this fix with ORFS or just OR under the test directory?
image
image

@maliberty
Copy link
Member

I suppose you meant dpl not drt. Is this something where you could make an equivalent test case on a public PDK? Its getting hard to make much progress without data.

@nchiolino
Copy link
Author

Yes, my apologies, I meant DPL.
I have re-created the issue with the sky130hd technology pointing at the gcd design. Here is how I re-created the issue:

  1. Created a POST_PDN file here: /flow/platforms/sky130hd/post_pdn.tcl
    Its contents are:
proc block_stripes {} {
  set block [ord::get_db_block]
      set a [odb::dbBlockage_create $block 29440 18800 41289 73680]
}
block_stripes

  1. Added the POST_PDN env viable in the platform config file:
    /flow/platforms/sky130hd/config.mk
    Its contents are:
#--------------------------------------------------------
# Floorplan
# -------------------------------------------------------

# Placement site for core cells
# This can be found in the technology lef
export PLACE_SITE = unithd

# IO Placer pin layers
export IO_PLACER_H = met3
export IO_PLACER_V = met2

# Define default PDN config
export PDN_TCL ?= $(PLATFORM_DIR)/pdn.tcl
export POST_PDN_TCL ?= $(PLATFORM_DIR)/post_pdn.tcl

# Endcap and Welltie cells
export TAPCELL_TCL = $(PLATFORM_DIR)/tapcell.tcl

export MACRO_PLACE_HALO ?= 40 40
export MACRO_PLACE_CHANNEL ?= 80 80
  1. run make
    Everything else for the gcd example was unchanged. Here is the result I got:
    image
    image

@nchiolino
Copy link
Author

I dont mean to add to the thread too much here but I had a hunch that I wanted to test. I drastically reduced the size of the blockage and it reduced the number of misplaced gates down to one but still produced the same error as before. However, and this might be very off so bear with me, I realized that since the blockage is being inserted into the core area after floor planning, is there a chance that the core utilization calculation is not calculating properly because its calculating the core area without the blockage? Would that be effecting the DPL script?

@maliberty
Copy link
Member

Thanks I am able to reproduce it and will take a look.

@maliberty
Copy link
Member

Though I get the same errors I don't have the same layout:
image

This looks like it has been mostly legalized. Are you showing the input rather than the output?

@nchiolino
Copy link
Author

Which file are you loading in the GUI?

@maliberty
Copy link
Member

Which file are you loading in the GUI?

Since it fails no file is written. I just ran that step in the GUI.

@nchiolino
Copy link
Author

Oh, then I definitely loading the input I suppose. I don't know how to run that step in the GUI unfortunately.

@maliberty
Copy link
Member

Oh, then I definitely loading the input I suppose. I don't know how to run that step in the GUI unfortunately.

#2023 should simplify it by writing 3_5_place_dp-failed.odb

@maliberty
Copy link
Member

The problem is not in detailed_placement but in improve_placement. Short term you can comment that out in your flow while I work on fixing it.

@nchiolino
Copy link
Author

Excellent! Thank you very much for looking at that. For now, I am very much in business.
image

@maliberty
Copy link
Member

The improve_placement problem should be fixed with The-OpenROAD-Project/OpenROAD#5143

@nchiolino
Copy link
Author

@maliberty , unfortunately I am getting the same result as before.

@maliberty
Copy link
Member

I just merged it - please update/rebuild and try again.

@nchiolino
Copy link
Author

Im so sorry but it looks to be behaving the same. Did I not get the latest version of OR?
image

@maliberty
Copy link
Member

How are you building OR? The output of openroad -version would be helpful

@nchiolino
Copy link
Author

I follow the flow build instructions:

git clone --recursive https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts
cd OpenROAD-flow-scripts
sudo ./setup.sh
./build_openroad.sh --local

My openroad version is: v2.0-13842-geef07d637

@nchiolino
Copy link
Author

I am making an assumption that the flow build also builds openroad.

@rovinski
Copy link
Member

rovinski commented May 22, 2024

Try ./build_openroad.sh --local --latest because I don't think the fix has been upstreamed to ORFS yet.

@nchiolino
Copy link
Author

Great! It looks as though everything is working now. Thank you very much.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dpl Detailed Placement Legalization gpl Global Placement mpl Macro Placement
Projects
None yet
Development

No branches or pull requests

4 participants