Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4035de1
sec global check
Jul 3, 2026
16df2be
kf update
Jul 3, 2026
7908753
kf update
Jul 3, 2026
fe0cab0
sync to latest
Sep 26, 2026
8dfdc20
bump kf
Oct 9, 2026
88e7223
opt fixes
Oct 15, 2026
094f07c
BLOCKS as boundary
Oct 15, 2026
d24de5f
fix deps
Oct 15, 2026
7b1bc61
fix resolve instance
Oct 15, 2026
92e8ec0
ingore unconnected inputs at boundary
Oct 15, 2026
e2261e6
binary relation learning round
Oct 20, 2026
55c59f5
fix ihp cells filtering
Oct 20, 2026
4410239
add modeling for word level in kf
Oct 21, 2026
aaa9502
rom support
Oct 21, 2026
6f5b2c6
partition relation study
Oct 22, 2026
60aac58
further latch support
Oct 22, 2026
22247a9
relation study speedup
Oct 23, 2026
1dd520a
update
Oct 23, 2026
d585487
update kf
Oct 27, 2026
6b423b9
update kf
Oct 27, 2026
d3e0a9b
Merge branch 'The-OpenROAD-Project:master' into global-sec
nanocoh Oct 27, 2026
39d8559
Merge branch 'The-OpenROAD-Project:master' into global-sec
nanocoh Oct 28, 2026
66ecbca
disable sec step when needed
Oct 28, 2026
3f7ba11
Merge branch 'global-sec' of https://github.com/keplertech/OpenROAD-f…
nanocoh Oct 28, 2026
1c297d5
use set_boundary for BLOCKS
Oct 28, 2026
0c51cd6
fix clock extraction
Oct 29, 2026
0ca7f2f
fix clock extraction
Oct 30, 2026
2c303ff
kf update
Nov 1, 2026
8395302
turn off sec step for unsupported designs
Nov 2, 2026
c8adc6d
Merge branch 'master' into global-sec
nanocoh Nov 2, 2026
df1ca2c
fix cva6
Nov 2, 2026
b4fc1e2
Merge branch 'global-sec' of https://github.com/keplertech/OpenROAD-f…
nanocoh Nov 2, 2026
19c892b
bump kf
Nov 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/user/FlowVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ configuration file.
| <a name="SC_LEF"></a>SC_LEF| Path to technology standard cell LEF file.| |
| <a name="SDC_FILE"></a>SDC_FILE| The path to design constraint (SDC) file.| |
| <a name="SEAL_GDS"></a>SEAL_GDS| Seal macro to place around the design.| |
| <a name="SEC_CHECK"></a>SEC_CHECK| Perform a sequential equivalence check between the initial synthesis netlist and final netlist with the Kepler Formal PDR engine. If this fails, report an issue to OpenROAD.| 0|
| <a name="SEC_CHECK"></a>SEC_CHECK| Perform a sequential equivalence check between the initial synthesis netlist and final netlist with the Kepler Formal PDR engine. Hard macros, the sub-blocks listed in BLOCKS and every BLOCK-class cell such as SRAM macros, are checked as black boxes (proof boundaries): they are the same cells in both netlists and their abstracts carry no logic. If this fails, report an issue to OpenROAD.| $(if $(wildcard $(KEPLER_FORMAL_EXE)),1,0)|
| <a name="SETUP_MOVE_SEQUENCE"></a>SETUP_MOVE_SEQUENCE| Passed as -sequence to repair_timing. This should be a string of move keywords separated by commas.| |
| <a name="SETUP_REPAIR_PHASES"></a>SETUP_REPAIR_PHASES| Passed as -phases to repair_timing. This should be a string of setup repair phase names separated by spaces. Set to PARALLEL_EVAL to repair setup timing with the experimental parallel evaluation policy. When unset, repair_timing runs its default phases.| |
| <a name="SETUP_SLACK_MARGIN"></a>SETUP_SLACK_MARGIN| Specifies a time margin for the slack when fixing setup violations. This option allows you to overfix or underfix(negative value, terminate retiming before 0 or positive slack). See HOLD_SLACK_MARGIN for more details.| 0|
Expand Down
4 changes: 4 additions & 0 deletions flow/designs/asap7/chi_async_bridge/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ export VERILOG_TOP_PARAMS = REQ_W 32 RSP_W 16 DAT_W 64 SNP_W 24 DEPTH 4
else ifeq ($(FLOW_VARIANT),medium)
export VERILOG_TOP_PARAMS = DEPTH 4
endif

# Temporary disabling: the asynchronous clock-domain crossings are outside
# the sequential check.
export SEC_CHECK = 0
export SETUP_REPAIR_PHASES = PARALLEL_EVAL
4 changes: 4 additions & 0 deletions flow/designs/asap7/ethmac/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ export PLACE_DENSITY = 0.75
export GPL_PLACE_IOS = 1

export HOLD_SLACK_MARGIN = -10

# Temporary disabling: the design has several clock domains and the
# sequential check does not yet cover logic crossing between them.
export SEC_CHECK = 0
3 changes: 3 additions & 0 deletions flow/designs/asap7/ethmac_lvt/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ export ASAP7_USE_VT = LVT

export RECOVER_POWER = 1

# Temporary disabling: the design has several clock domains and the
# sequential check does not yet cover logic crossing between them.
export SEC_CHECK = 0
export SETUP_REPAIR_PHASES = PARALLEL_EVAL
4 changes: 4 additions & 0 deletions flow/designs/ihp-sg13g2/i2c-gpio-expander/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ export PDN_TCL = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/pdn.tcl

export BLOCKS = I2cDeviceCtrl


# Temporary disabling: the bidirectional IO pads are outside the sequential
# check.
export SEC_CHECK = 0
4 changes: 4 additions & 0 deletions flow/designs/nangate45/mempool_group/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,7 @@ export CORE_AREA = 10 12 1090 1090
export RTLMP_MIN_CHANNEL_SIZE = 20 20

export SYNTH_HDL_FRONTEND = slang

# Temporary disabling: the hierarchical netlist leaves memory write-mask pins
# undriven, which the sequential check cannot verify.
export SEC_CHECK = 0
4 changes: 4 additions & 0 deletions flow/designs/nangate45/swerv/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ export TNS_END_PERCENT = 100

export SWAP_ARITH_OPERATORS = 1
export OPENROAD_HIERARCHICAL = 1

# Temporary disabling: the design has several clock domains and the
# sequential check does not yet cover logic crossing between them.
export SEC_CHECK = 0
4 changes: 4 additions & 0 deletions flow/designs/nangate45/swerv_wrapper/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ export TNS_END_PERCENT = 100

export SWAP_ARITH_OPERATORS = 1
export OPENROAD_HIERARCHICAL = 1

# Temporary disabling: the design has several clock domains and the
# sequential check does not yet cover logic crossing between them.
export SEC_CHECK = 0
4 changes: 4 additions & 0 deletions flow/designs/sky130hd/chameleon/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ export TNS_END_PERCENT = 100
export SETUP_REPAIR_PHASES = PARALLEL_EVAL

export RTLMP_MIN_CHANNEL_SIZE = 70 70

# Temporary disabling: the hard macros carry no logic in their Liberty, which
# leaves no output for the sequential check to verify.
export SEC_CHECK = 0
4 changes: 3 additions & 1 deletion flow/designs/sky130hd/microwatt/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ endif
export SWAP_ARITH_OPERATORS = 1
export OPENROAD_HIERARCHICAL = 1

# Temporary disabling
# Temporary disabling: the hierarchical netlist is rejected by the
# equivalence checker (duplicate wire declaration).
export LEC_CHECK = 0
export SEC_CHECK = 0
2 changes: 1 addition & 1 deletion flow/platforms/ihp-sg13g2/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export KLAYOUT_DRC_FILE ?= $(PLATFORM_DIR)/drc/sg13g2_minimal.lydrc
export CDL_FILE ?= $(PLATFORM_DIR)/cdl/sg13g2_stdcell.cdl
#export KLAYOUT_LVS_FILE = $(PLATFORM_DIR)/lvs/$(PLATFORM).lylvs

export REMOVE_CELLS_FOR_LEC ?= "bondpad_70* sg13g2*"
export REMOVE_CELLS_FOR_LEC ?= "bondpad_70*"

# ---------------------------------------------------------
# Final
Expand Down
91 changes: 91 additions & 0 deletions flow/scripts/formal_check.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,86 @@ proc write_lec_script { step file1 file2 } {
close $outfile
}

# Hardened sub-blocks (BLOCKS) enter the parent netlist as timing-only
# abstracts with no logic model, so a formal check would treat every output
# cone that reaches one as opaque. Return the instance paths of all block
# instances in the loaded design; both netlists come from the same run, so the
# same path exists in both and each instance can be paired with itself.
# Escapes every unescaped `/` in an instance name as `\/`, the OpenSTA SDC
# convention kepler-formal reads: `/` separates hierarchy levels and `\/` is a
# literal slash inside one name. Existing escapes are kept as they are.
proc formal_escape_slashes { name } {
set escaped ""
set length [string length $name]
for { set i 0 } { $i < $length } { incr i } {
set ch [string index $name $i]
if { $ch eq "\\" } {
incr i
append escaped "\\" [string index $name $i]
} elseif { $ch eq "/" } {
append escaped "\\/"
} else {
append escaped $ch
}
}
return $escaped
}

# Mirrors dbNetwork::stripParentPrefix: in a hierarchical database write_verilog
# names a leaf by what follows the last unescaped `/` of its database name.
proc formal_strip_parent_prefix { name } {
set pos [string last "/" $name]
while { $pos >= 0 } {
if { $pos == 0 || [string index $name [expr { $pos - 1 }]] ne "\\" } {
return [string range $name [expr { $pos + 1 }] end]
}
set pos [string last "/" $name [expr { $pos - 2 }]]
}
return $name
}

# Boundary path of a block instance exactly as write_verilog names it: in a flat
# database the whole instance name is one leaf (`\u0/r0 ` in Verilog, so the
# path is `u0\/r0`); in a hierarchical database the leaf keeps its module
# instance path and loses the parent prefix. Paths are never reinterpreted.
proc formal_boundary_path { inst } {
set name [$inst getName]
set prefix ""
if { [[ord::get_db] hasHierarchy] } {
set mod_inst [[$inst getModule] getModInst]
if { $mod_inst != "NULL" } {
set prefix "[$mod_inst getHierarchicalName]/"
}
set name [formal_strip_parent_prefix $name]
}
return "$prefix[formal_escape_slashes $name]"
}

# Hard macros are proof boundaries: the instances of the masters listed in
# BLOCKS, and every instance of a BLOCK-class master (SRAM macros, hardened
# sub-blocks). A macro is the same cell in both netlists, so only its
# connections need checking; expanding its contents into state would only make
# the proof slower.
proc formal_block_instance_paths { } {
set paths {}
set blocks {}
if { [env_var_exists_and_non_empty BLOCKS] } {
set blocks $::env(BLOCKS)
}
set block [ord::get_db_block]
foreach inst [$block getInsts] {
set master [$inst getMaster]
if { [$master isBlock] || [lsearch -exact $blocks [$master getName]] >= 0 } {
lappend paths [formal_boundary_path $inst]
}
}
return [lsort $paths]
}

proc formal_yaml_quote { text } {
return "\"[string map {\\ \\\\ \" \\\"} $text]\""
}

proc write_sec_script { step file1 file2 } {
set outfile [open "$::env(OBJECTS_DIR)/${step}_sec_test.yml" w]
puts $outfile "format: verilog"
Expand All @@ -79,6 +159,17 @@ proc write_sec_script { step file1 file2 } {
foreach libFile $::env(LIB_FILES) {
puts $outfile " - $libFile"
}
# Each macro instance becomes a proof boundary: its input pins are compared
# across the two netlists and its output pins are shared free inputs, so the
# macro is checked as a black box instead of hiding the cones behind it.
set boundaries [formal_block_instance_paths]
if { [llength $boundaries] > 0 } {
puts $outfile "set_as_boundary:"
foreach path $boundaries {
set quoted [formal_yaml_quote $path]
puts $outfile " - \[$quoted, $quoted\]"
}
}
puts $outfile "log_file: $::env(LOG_DIR)/${step}_sec_check.log"
close $outfile
}
Expand Down
4 changes: 2 additions & 2 deletions flow/scripts/variables.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions flow/scripts/variables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1689,9 +1689,12 @@ LEC_CHECK:
SEC_CHECK:
description: >
Perform a sequential equivalence check between the initial synthesis
netlist and final netlist with the Kepler Formal PDR engine. If this
fails, report an issue to OpenROAD.
default: 0
netlist and final netlist with the Kepler Formal PDR engine. Hard macros,
the sub-blocks listed in BLOCKS and every BLOCK-class cell such as SRAM
macros, are checked as black boxes (proof boundaries): they are the same
cells in both netlists and their abstracts carry no logic. If this fails,
report an issue to OpenROAD.
default: $(if $(wildcard $(KEPLER_FORMAL_EXE)),1,0)
stages:
- synth
- final
Expand Down
2 changes: 1 addition & 1 deletion tools/kepler-formal
Submodule kepler-formal updated 324 files