Skip to content

Commit

Permalink
padringer fixes (The-OpenROAD-Project#1601)
Browse files Browse the repository at this point in the history
For `padringer.py`:
\+ Add output `ODB` and optional `DEF`
\+ Add `--odb-lef` which is the lef file to included with `ODB` output file.
\+ `--width` and `--height` are no longer required as they can be fetched from the config file
\+ `--input-lef` and `--padframe-config` click options are now multiple 
others:
\+ Add `FP_PADFRAME_CFG` which points to configuration file passed to `padringer.py`
\+ Add `GPIO_PADS_PREFIX` to parameterize prefix passed to `padringer.py`
\+ Add `padframe_gen_batch` to capture all of the above in a simple wrapper
  • Loading branch information
kareefardi authored Jan 8, 2023
1 parent d720107 commit a44a76b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 30 deletions.
1 change: 1 addition & 0 deletions docs/source/for_developers/pdk_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ This section defines the neccessary variables for PDK configuration file. Note t
| `KLAYOUT_PROPERTIES` | Points to the klayout properties file (.lyp). |
| `MAGIC_MAGICRC` | Points to the magicrc file that is sourced while running magic in the flow. |
| `GPIO_PADS_LEF` | A list of the pads lef views. For example:`[glob "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lef/sky130_fd_io.lef"]` |
| `GPIO_PADS_PREFIX` | A list of pad cells name prefixes. |
| `NETGEN_SETUP_FILE` | Points to the setup file for netgen(lvs), that can exclude certain cells etc.. |
| `FP_TAPCELL_DIST` | The distance between tapcell columns. Used in floorplanning in tapcell insertion. |
| `DEFAULT_MAX_TRAN` | Defines the default maximum transition value, used in CTS & synthesis. |
Expand Down
1 change: 1 addition & 0 deletions docs/source/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ These variables are optional that can be specified in the design configuration f
| `GND_NETS` | Specifies the ground nets/pins to be used when creating the power grid for the design. |
| `SYNTH_USE_PG_PINS_DEFINES` | Specifies the power guard used in the verilog source code to specify the power and ground pins. This is used to automatically extract `VDD_NETS` and `GND_NET` variables from the verilog, with the assumption that they will be order `inout vdd1, inout gnd1, inout vdd2, inout gnd2, ...`. |
| `FP_IO_MIN_DISTANCE` | The minmimum distance between the IOs in microns. <br> (Default: `3`) |
| `FP_PADFRAME_CFG` | A configuration file passed to padringer, a padframe generator. <br> (Default: NONE) |
| `FP_PDN_IRDROP` | **Removed: worthless** Enable calculation of power grid IR drop during PDN generation. <br> (Default: `1`)|

#### Deprecated I/O Layer variables
Expand Down
53 changes: 23 additions & 30 deletions scripts/odbpy/padringer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,13 @@ def generate_cfg(north, east, south, west, corner_pads, width, height):

@click.command()
@click.option(
"-o",
"--output",
default="./out.def",
help="A verilog netlist containing pads and other user macros",
required=True,
help="Output ODB file",
)
@click.option(
"--output-def",
help="Output DEF file",
)
@click.option(
"-v",
Expand All @@ -111,11 +114,17 @@ def generate_cfg(north, east, south, west, corner_pads, width, height):
@click.option(
"-l",
"--input-lef",
multiple=True,
required=True,
help="LEF file needed to have a proper view of the DEF files",
)
@click.option("-w", "--width", required=True, help="Width of the die area.")
@click.option("-h", "--height", required=True, help="Height of the die area.")
@click.option(
"--odb-lef",
required=True,
help="LEF file to be included in output odb",
)
@click.option("-w", "--width", help="Width of the die area.")
@click.option("-h", "--height", help="Height of the die area.")
@click.option(
"-c",
"--padframe-config",
Expand All @@ -125,8 +134,8 @@ def generate_cfg(north, east, south, west, corner_pads, width, height):
@click.option(
"-P",
"--pad-name-prefixes",
default="sky130_fd_io;sky130_ef_io",
help="Semicolon;delimited list of padname prefixes",
multiple=True,
help="Padname prefixes",
)
@click.option(
"-i",
Expand All @@ -147,9 +156,11 @@ def generate_cfg(north, east, south, west, corner_pads, width, height):
@click.argument("design")
def padringer(
output,
output_def,
verilog_netlist,
def_netlist,
input_lef,
odb_lef,
width,
height,
padframe_config,
Expand All @@ -169,8 +180,7 @@ def padringer(
"""

config_file_name = padframe_config
output_file_name = output
lefs = [input_lef]
lefs = input_lef

working_def = f"{working_dir}/{design}.pf.def"
working_cfg = f"{working_dir}/{design}.pf.cfg"
Expand Down Expand Up @@ -198,13 +208,11 @@ def padringer(
openroad_script.append(f"read_verilog {verilog_netlist}")
openroad_script.append(f"link_design {design}")
openroad_script.append(f"write_def {working_def}")
# openroad_script.append(f"write_db {design}.pf.db")
openroad_script.append("exit")

p = Popen(["openroad"], stdout=PIPE, stdin=PIPE, stderr=PIPE, encoding="utf8")

openroad_script = "\n".join(openroad_script)
# print(openroad_script)

output = p.communicate(openroad_script)
print("STDOUT:")
Expand All @@ -220,7 +228,7 @@ def padringer(

assert os.path.exists(working_def), "DEF file doesn't exist"

top = OdbReader(lefs, working_def)
top = OdbReader(odb_lef, working_def)

print(f"Top-level design name: {top.name}")

Expand Down Expand Up @@ -405,24 +413,9 @@ def padringer(
new_inst.setPlacementStatus("FIRM")
created_cells_count += 1

# TODO: place the core macros within the padframe (chip floorplan)
for inst in top.block.getInsts():
if inst.isPlaced() or inst.isFixed():
continue
print("Placing", inst.getName())
master = inst.getMaster()
master_width = master.getWidth()
master_height = master.getHeight()
print(master_width, master_height)
print(width, height)

inst.setLocation(
width * 1000 // 2 - master_width // 2,
height * 1000 // 2 - master_height // 2,
)
inst.setPlacementStatus("PLACED")

odb.write_def(top.block, output_file_name)
if output_def:
odb.write_def(top.block, output_def)
odb.write_db(top.db, output)
print("Done.")


Expand Down
66 changes: 66 additions & 0 deletions scripts/tcl_commands/floorplan.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,72 @@ proc run_power_grid_generation {args} {
gen_pdn
}

proc padframe_gen_batch {args} {
increment_index
TIMER::timer_start

set options {
{-odb optional}
{-def optional}
{-cfg optional}
{-log optional}
{-output_def optional}
{-output_odb optional}
{-odb_lef optional}
{-design_name optional}
}
set flags {}
parse_key_args "padframe_gen_batch" args arg_values $options flags_map $flags

set_if_unset arg_values(-output) [index_file $::env(floorplan_tmpfiles)/padframe_out.odb]
set_if_unset arg_values(-output_def) [index_file $::env(floorplan_tmpfiles)/padframe_out.def]
set_if_unset arg_values(-odb_lef) $::env(MERGED_LEF)
set_if_unset arg_values(-log) [index_file $::env(floorplan_logs)/padringer.log]
set_if_unset arg_values(-odb) $::env(CURRENT_ODB)
set_if_unset arg_values(-cfg) $::env(FP_PADFRAME_CFG)
set_if_unset arg_values(-design_name) $::env(DESIGN_NAME)
set_odb $arg_values(-odb)

if { ![info exist arg_values(-def)]} {
puts_verbose "Converting ODB to DEF for padringer"
run_openroad_script $::env(SCRIPTS_DIR)/openroad/write_views.tcl\
-indexed_log [index_file $::env(floorplan_logs)/odb_to_def.log]\
-save "to=$::env(floorplan_tmpfiles),name=padframe_in,def,odb"
set arg_values(-def) $::env(CURRENT_DEF)
}

set extra_lefs ""
if { [info exists ::env(EXTRA_LEFS)] } {
set extra_lefs $::env(EXTRA_LEFS)
}
set lefs_argument ""
foreach lef "$::env(TECH_LEF) $::env(GPIO_PADS_LEF) $extra_lefs" {
set lefs_argument "$lefs_argument --input-lef $lef"
}

set prefix_argument ""
foreach prefix "$::env(GPIO_PADS_PREFIX)" {
set prefix_argument "$prefix_argument --pad-name-prefixes $prefix"
}

puts_info "Generating pad frame"
try_catch openroad -python -exit $::env(SCRIPTS_DIR)/odbpy/padringer.py\
--def-netlist $arg_values(-def) \
{*}$prefix_argument \
{*}$lefs_argument \
--odb-lef $arg_values(-odb_lef) \
-c $arg_values(-cfg) \
--working-dir $::env(floorplan_tmpfiles) \
--output $arg_values(-output) \
--output-def $arg_values(-output_def) \
$arg_values(-design_name) \
|& tee $::env(TERMINAL_OUTPUT) $arg_values(-log)

TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "floorplan padringer"

}

proc run_floorplan {args} {
# |----------------------------------------------------|
# |---------------- 2. FLOORPLAN ------------------|
Expand Down

0 comments on commit a44a76b

Please sign in to comment.