The-OpenROAD-Project / OpenLane

OpenLane is an automated RTL to GDSII flow based on several components including OpenROAD, Yosys, Magic, Netgen and custom methodology scripts for design exploration and optimization.
https://openlane.readthedocs.io/
Apache License 2.0
1.31k stars 370 forks source link

[ERROR PDN-9999] Unexpected error: key "vccd1" not known in dictionary #537

Closed lakshmi-sathi closed 3 years ago

lakshmi-sathi commented 3 years ago

The bug

The following error message shows up during the floorplan step and the flow fails:

[INFO PDN-0012] **** END INFO ****
[INFO PDN-0013] Inserting stdcell grid - grid
[INFO PDN-0010] Inserting macro grid for 10 macros
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.dmem.macro.mem.sram8x1024_1
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.dmem.macro.mem.sram8x1024_2
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.dmem.macro.mem.sram8x1024_3
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.dmem.macro.mem.sram8x1024_4
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_1
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_2
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_3
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_4
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_5
[INFO PDN-0034]   - grid for instance proc.h.z.vcore.icache0.imem_0.macro.mem.sram8x1024_6
[INFO PDN-0015] Writing to database
-code 1 -level 0 -errorcode NONE -errorinfo {key "vccd1" not known in dictionary
    while executing
"dict get $global_connections $net_name"
    (procedure "get_valid_mterms" line 5)
    invoked from within
"get_valid_mterms $net_name"
    (procedure "get_global_connect_list_default" line 8)
    invoked from within
"get_global_connect_list_default [dict get $design_data core_domain] false"
    (procedure "export_opendb_global_connection" line 8)
    invoked from within
"export_opendb_global_connection"
    (procedure "export_opendb_specialnets" line 13)
    invoked from within
"export_opendb_specialnets"
    (procedure "opendb_update_grid" line 4)
    invoked from within
"opendb_update_grid"
    (procedure "apply" line 7)
    invoked from within
"apply $config"
    (procedure "pdngen::apply_pdn" line 13)
    invoked from within
"pdngen::apply_pdn $config_file $verbose "} -errorline 9
[ERROR PDN-9999] Unexpected error: key "vccd1" not known in dictionary
PDN-9999
[ERROR]: during executing: "openroad -exit /openLANE_flow/scripts/openroad/or_pdn.tcl |& tee >&@stdout /openLANE_flow/designs/bsg_manycore_tile_compute_mesh_real/runs/14-08_17-42/logs/floorplan/13-pdn.log"
[ERROR]: Exit code: 1
[ERROR]: Last 10 lines:
child process exited abnormally

[ERROR]: Please check openroad  log file
[ERROR]: Dumping to /openLANE_flow/designs/bsg_manycore_tile_compute_mesh_real/runs/14-08_17-42/error.log

This issue does not arise on the stable OpenLane (v0.21) frozen by Efabless for the shuttle.

Steps to reproduce the behavior:

  1. Place the design in OpenLane (2021.08.02_05.21.44-7-g71bf5bd)
  2. Run the flow
  3. This error should show up during the floorplan step.

As this issue doesn't occur in the stable version of OpenLane (v0.21), expecting this to be an issue specific to the newer OpenLane (2021.08.02_05.21.44-7-g71bf5bd)

Versions Used:

Additional Context This issue has also been observed when running the flow on a black parrot design. This issue does not occur on the default spm design. It seems to be occurring when macros are used but it does not occur on the default 'manual_macro_placement_test' design. This is the config file used

donn commented 3 years ago

@maliberty Does pdngen support different names for VPWR/VGND yet?

maliberty commented 3 years ago

@Colin-Holehouse is the right person to ask about pdngen. Does pdngen support different names for VPWR/VGND yet?

lakshmi-sathi commented 3 years ago

Just adding on, it seems for macros, giving explicit naming for the power and ground pins is suggested in the PDN part of the manual, am I understanding it correctly?

I think having the power pins named as 'vccd1' & 'vssd1' for the macro should be possible because: -> I had previously been able to push a simple SRAM wrapper through the stable version of OpenLane (v0.21) using this same naming scheme ('vccd1' and 'vssd1'). -> Also, the LEFs of the openram test chip in the shuttle also seem to be utilizing "vccd1" & "vssd1" as the naming for the power and ground pins respectively.

Am I right?

Colin-Holehouse commented 3 years ago

The incoming netlist after synthesis has no power/ground connectivity, so there needs to be a mechanism to define the power/ground net names and connections.

The pdn code has a default set of global connections defined:

variable default_global_connections {
  VDD {
    {inst_name .* pin_name ^VDD$}
    {inst_name .* pin_name ^VDDPE$}
    {inst_name .* pin_name ^VDDCE$}
  }
  VSS {
    {inst_name .* pin_name ^VSS$}
    {inst_name .* pin_name ^VSSE$}
  }
}

This declares the net VDD and states that pins matching patterns ^VDD$, ^VDDPE$ and ^VDDCE$ found on instances matching the pattern .* (i.e. all instances) are to be connected to this net. Similarly for VSS.

If for your design style you dont want these names for power and ground, and/or you need to have different instance/pin patterns then you can specify them in the PDN config file as follows

set pdngen::global_connections {
  vccd1 {
    {inst_name .* pin_name ^VDD$}
  }
  vssd1 {
    {inst_name .* pin_name ^VSS$}
  }
}

or else you could use the (new) TCL command add_global_connection e.g.

add_global_connection -net vccd1 -pin_pattern {^VDD$} -power
add_global_connection -net vssd1 -pin_pattern {^VDD$} -power

(there is a -inst_pattern option, which defaults to .* if not specified)

The error that is reported above arises because vccd1 is not specified in the global connections definition. I will add an error message to this effect.

Using the approach described above, it should be possible to have any net name for your power/ground nets, and it should be possible to connect to any desired pin on any given instance to fore the power/ground net connectivity.

lakshmi-sathi commented 3 years ago

I tried the TCL command mentioned but it says it's not found.

% add_global_connection -net vccd1 -pin_pattern {^VDD$} -power
invalid command name "add_global_connection"

I tried it on one of the newer versions 2021.08.17_03.26.57 too, still the same error. Am I missing something?

As earlier mentioned I am able to push through a simple SRAM wrapper with the naming 'vccd1', 'vssd1', through OpenLane v0.21 without having to give any separate PDN config file or the 'add_global_connection' command. I checked the connections to the macro power pins in the resulting GDS and they indeed seem to be connected properly (Image below)

image (The vertical strips on the right are the vccd1 and vssd1 of the macro.)

It was only on the newer OpenLane version, that I had to specify a separate PDN config file for pushing the same design. If it runs on a previous version without the need for a separate pdn config (or command), then on the newer version too it should run without one, am I right? Or is this the expected behaviour in the newer versions?

donn commented 3 years ago

All you need to do is add this to config.tcl:

set ::env(PDN_CFG) $::env(DESIGN_DIR)/pdn.tcl

Then add this file as pdn.tcl to the same directory as config.tcl:

# Power nets

if { ! [info exists ::env(VDD_NET)] } {
    set ::env(VDD_NET) $::env(VDD_PIN)
}

if { ! [info exists ::env(GND_NET)] } {
    set ::env(GND_NET) $::env(GND_PIN)
}
set ::power_nets $::env(VDD_NET)
set ::ground_nets $::env(GND_NET)

if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } {
    if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } {
        # to parameterize -- needs a PDNGEN fix
        set pdngen::global_connections {
            vccd1 {
                {inst_name .* pin_name VPWR}
                {inst_name .* pin_name VPB}
            }
            vssd1 {
                {inst_name .* pin_name VGND}
                {inst_name .* pin_name VNB}
            }
        }
    }
}

# Used if the design is the core of the chip
set stdcell_core {
    name grid
    straps {
        $::env(FP_PDN_LOWER_LAYER) {width $::env(FP_PDN_VWIDTH) pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
        $::env(FP_PDN_UPPER_LAYER) {width $::env(FP_PDN_HWIDTH) pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
    }
    connect {{$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}}
    pins { $::env(FP_PDN_UPPER_LAYER) }
}

# Used if the design is a macro in the core
set stdcell_macro {
    name grid
    straps {
        $::env(FP_PDN_LOWER_LAYER) {width $::env(FP_PDN_VWIDTH) pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
    }
    connect {}
}

# Assesses whether the deisgn is the core of the chip or not based on the value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section
if { [info exists ::env(DESIGN_IS_CORE)] } {
    if { $::env(DESIGN_IS_CORE) == 1 } {
        set stdcell $stdcell_core
    } else {
        set stdcell $stdcell_macro
    }
} else {
    set stdcell $stdcell_core
}

# Adds the core ring if enabled.
if { [info exists ::env(FP_PDN_CORE_RING)] } {
    if { $::env(FP_PDN_CORE_RING) == 1 } {
        dict append stdcell core_ring {
                $::env(FP_PDN_LOWER_LAYER) {width $::env(FP_PDN_CORE_RING_VWIDTH) spacing $::env(FP_PDN_CORE_RING_VSPACING) core_offset $::env(FP_PDN_CORE_RING_VOFFSET)}
                $::env(FP_PDN_UPPER_LAYER) {width $::env(FP_PDN_CORE_RING_HWIDTH) spacing $::env(FP_PDN_CORE_RING_HSPACING) core_offset $::env(FP_PDN_CORE_RING_HOFFSET)}
            }
    }
}

# Adds the core ring if enabled.
if { [info exists ::env(FP_PDN_ENABLE_RAILS)] } {
    if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
        dict append stdcell rails {
            $::env(FP_PDN_RAILS_LAYER) {width $::env(FP_PDN_RAIL_WIDTH) pitch $::env(PLACE_SITE_HEIGHT) offset $::env(FP_PDN_RAIL_OFFSET)}
        }
        dict update stdcell connect current_connect {
            append current_connect { {$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)}}
        }
    } else {
        dict append stdcell rails {}
    }
}

pdngen::specify_grid stdcell [subst $stdcell]

# A general macro that follows the premise of the set heirarchy. You may want to modify this or add other macro configs
# TODO: generate automatically per instance:
set macro {
    orient {R0 R180 MX MY R90 R270 MXR90 MYR90}
    power_pins $::env(VDD_NET)
    ground_pins $::env(GND_NET)
    blockages "li1 met1 met2 met3 met4"
    straps {
    }
    connect {{$::env(FP_PDN_LOWER_LAYER)_PIN_ver $::env(FP_PDN_UPPER_LAYER)}}
}

pdngen::specify_grid macro [subst $macro]

set ::halo [expr min($::env(FP_HORIZONTAL_HALO), $::env(FP_VERTICAL_HALO))]

# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
set ::rails_start_with "POWER" ;

# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
set ::stripes_start_with "POWER" ;

There is something to be said here that these values should be VDD_NET and GND_NET by default, but that's an Open PDKs issue.

donn commented 3 years ago

Fixed by #609