Skip to content

Commit

Permalink
Yosys Script Enhancements (The-OpenROAD-Project#1446)
Browse files Browse the repository at this point in the history
+ Add yosys to `run_tcl_script`, enabling the automatic production of reproducibles
~ yosys -> f109fa3d4c56fe33bc626c298e04d45ae510dd0e
~ Cleaned up LEC script a bit (thanks @EmJunaid for initial work)
~ Fix bug where cell_count was not extracted properly
- Removed `get_yosys_bin`: It's been deprecated forever
  • Loading branch information
donn authored Nov 10, 2022
1 parent 8b391c0 commit 86615f8
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 114 deletions.
2 changes: 1 addition & 1 deletion dependencies/tool_metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
cp vlog2Verilog $PREFIX/bin
- name: yosys
repo: https://github.com/YosysHQ/yosys
commit: 6e907acf86d9ff0edd9a1c10274e62690e19e939
commit: f109fa3d4c56fe33bc626c298e04d45ae510dd0e
build: |
make clean
make PREFIX=$PREFIX config-gcc
Expand Down
2 changes: 1 addition & 1 deletion docs/source/reference/openlane_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Most of the following commands' implementation exists in this [file][9]
| `logic_equiv_check` | | Runs logic verification using yosys between the two given netlists. |
| | `-lhs <verilog_netlist_file>` | The first netlist (lefthand-side) in the logic verification comparison. |
| | `-rhs <verilog_netlist_file>` | The second netlist (righthand-side) in the logic verification comparison. |
| `get_yosys_bin` | | **Deprecated:** Returns the used binary for yosys. |
| `get_yosys_bin` | | **Removed: Read $::env(SYNTH_BIN)** Returns the used binary for yosys. |
| `verilog_to_verilogPower` | | **Removed: Use `write_verilog -powered`** Adds the power pins and connections to a verilog file. |
| | `-input <verilog_netlist_file>` | The input verilog that doesn't contain the power pins and connections. |
| | `-output <verilog_netlist_file>` | The output verilog file. |
Expand Down
10 changes: 7 additions & 3 deletions scripts/or_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@
)
@click.option(
"--input-type",
type=click.Choice(["def", "netlist", "odb"]),
type=click.Choice(["def", "netlist", "odb", "n/a"]),
default="odb",
help="Use a netlist or a DEF layout as an input instead of an ODB file. Useful for evaluating some scripts such as floorplan.tcl.",
help="Determine type of input file.",
)
@click.option("--output-dir", default=None, help="Output to this directory.")
@click.option(
"--tool",
type=click.Choice(["openroad", "magic"]),
type=click.Choice(["openroad", "magic", "yosys"]),
help="The tool used for the desired Tcl script. [required]",
)
@click.argument("input_file")
Expand Down Expand Up @@ -178,6 +178,8 @@ def issue(
env["SAVE_ODB"] = save_odb
elif input_type == "netlist":
input_key = "CURRENT_NETLIST"
elif input_type == "n/a":
input_key = "CURRENT_NOTHING"

env[input_key] = input_file

Expand Down Expand Up @@ -364,6 +366,8 @@ def env_list(
run_cmd = "$TOOL_BIN -exit $PACKAGED_SCRIPT_0"
elif tool == "magic":
run_cmd = "$TOOL_BIN -dnull -noconsole -rcfile $MAGIC_MAGICRC < $PACKAGED_SCRIPT_0"
elif tool == "yosys":
run_cmd = "$TOOL_BIN -c $PACKAGED_SCRIPT_0"
f.write(
textwrap.dedent(
f"""\
Expand Down
2 changes: 1 addition & 1 deletion scripts/report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def re_get_last_capture(rx, string):

# Cell Count
cell_count = -1
yosys_report = Artifact(rp, "reports", "synthesis", "synthesis.stat.rpt", True)
yosys_report = Artifact(rp, "reports", "synthesis", ".stat.rpt", True)
yosys_report_content = yosys_report.get_content()
if yosys_report_content is not None:
match = re.search(r"Number of cells:\s*(\d+)", yosys_report_content)
Expand Down
2 changes: 1 addition & 1 deletion scripts/tcl_commands/all.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ proc set_netlist {args} {
try_catch sed -i -e "s/\\(set ::env(CURRENT_NETLIST)\\).*/\\1 $replace/" "$::env(GLB_CFG_FILE)"

if { [info exists flags_map(-lec)] && $::env(LEC_ENABLE) && [file exists $previous_netlist] } {
logic_equiv_check -rhs $previous_netlist -lhs $netlist
logic_equiv_check -lhs $previous_netlist -rhs $netlist
}
}

Expand Down
32 changes: 15 additions & 17 deletions scripts/tcl_commands/synthesis.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

proc get_yosys_bin {} {
return $::env(SYNTH_BIN)
}

proc convert_pg_pins {lib_in lib_out} {
try_catch sed -E {s/^([[:space:]]+)pg_pin(.*)/\1pin\2\n\1 direction : "inout";/g} $lib_in > $lib_out
}
Expand All @@ -24,15 +20,21 @@ proc run_yosys {args} {
set options {
{-output optional}
{-log optional}
{-indexed_log optional}
}
set flags {
-no_set_netlist
}

parse_key_args "run_yosys" args arg_values $options flags_map $flags

if { [info exists arg_values(-log)] } {
puts_warn "run_yosys -log is deprecated: replace -log with -indexed_log."
set arg_values(-indexed_log) $arg_values(-log)
}

set_if_unset arg_values(-output) $::env(synthesis_results)/$::env(DESIGN_NAME).v
set_if_unset arg_values(-log) /dev/null
set_if_unset arg_values(-indexed_log) /dev/null

if { [ info exists ::env(SYNTH_ADDER_TYPE)] && ($::env(SYNTH_ADDER_TYPE) in [list "RCA" "CSA"]) } {
set ::env(SYNTH_READ_BLACKBOX_LIB) 1
Expand All @@ -57,10 +59,7 @@ proc run_yosys {args} {
}

set ::env(SAVE_NETLIST) $arg_values(-output)
try_catch $::env(SYNTH_BIN) \
-c $::env(SYNTH_SCRIPT) \
-l $arg_values(-log)\
|& tee $::env(TERMINAL_OUTPUT)
run_yosys_script $::env(SYNTH_SCRIPT) -indexed_log $arg_values(-indexed_log)


if { ! [info exists flags_map(-no_set_netlist)] } {
Expand Down Expand Up @@ -88,7 +87,7 @@ proc run_synth_exploration {args} {
set ::env(SYNTH_EXPLORE) 1
set log [index_file $::env(synthesis_logs)/synthesis.log]

run_yosys -log $log
run_yosys -indexed_log $log

set exploration_report [index_file $::env(synthesis_reports)/exploration_analysis.html]

Expand Down Expand Up @@ -118,7 +117,7 @@ proc run_synthesis {args} {
puts_warn "A netlist at $::env(synthesis_results)/$::env(DESIGN_NAME).v already exists. Synthesis will be skipped."
set_netlist $::env(synthesis_results)/$::env(DESIGN_NAME).v
} else {
run_yosys -log $log
run_yosys -indexed_log $log
}
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "synthesis - yosys"
Expand Down Expand Up @@ -172,9 +171,7 @@ proc yosys_rewrite_verilog {filename} {

set ::env(SAVE_NETLIST) $filename

try_catch $::env(SYNTH_BIN) \
-c $::env(SCRIPTS_DIR)/yosys/rewrite_verilog.tcl \
-l $log
run_yosys_script $::env(SCRIPTS_DIR)/yosys/rewrite_verilog.tcl -indexed_log $log

unset ::env(SAVE_NETLIST)

Expand Down Expand Up @@ -209,10 +206,11 @@ proc logic_equiv_check {args} {
increment_index
TIMER::timer_start
set log [index_file $::env(synthesis_logs).equiv.log]
puts_info "Running LEC: $::env(LEC_LHS_NETLIST) Vs. $::env(LEC_RHS_NETLIST) (log: [relpath . $log])..."

set lhs_rel [relpath . $::env(LEC_LHS_NETLIST)]
set rhs_rel [relpath . $::env(LEC_RHS_NETLIST)]
puts_info "Running LEC: '$lhs_rel' vs. '$rhs_rel' (log: [relpath . $log])..."

if { [catch {exec $::env(SYNTH_BIN) -c $::env(SCRIPTS_DIR)/yosys/logic_equiv_check.tcl -l $log |& tee $::env(TERMINAL_OUTPUT)} ]} {
if { [run_yosys_script $::env(SCRIPTS_DIR)/yosys/logic_equiv_check.tcl -indexed_log $log]} {
puts_err "$::env(LEC_LHS_NETLIST) is not logically equivalent to $::env(LEC_RHS_NETLIST)."
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "logic equivalence check - yosys"
Expand Down
16 changes: 12 additions & 4 deletions scripts/utils/utils.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ proc relpath {args} {
return [exec python3 -c "import os; print(os.path.relpath('$to', '$from'), end='')"]
}

proc run_yosys_script {args} {
run_tcl_script -tool yosys -no_consume {*}$args
}

proc run_openroad_script {args} {
run_tcl_script -tool openroad -no_consume {*}$args
}
Expand Down Expand Up @@ -219,7 +223,7 @@ proc flow_fail {args} {
save_state
puts_err "Flow failed."
show_warnings "The failure may have been because of the following warnings:"
return -code error
exit -1
}
}

Expand Down Expand Up @@ -434,7 +438,7 @@ proc manipulate_layout {args} {
}

proc run_tcl_script {args} {
# -tool: openroad/magic
# -tool: openroad/magic/yosys
# -indexed_log: a log that is already pre-indexed
# -save:
# OpenROAD only. A list of commands to handle saving views.
Expand Down Expand Up @@ -565,8 +569,10 @@ proc run_tcl_script {args} {
}
} elseif { $arg_values(-tool) == "magic" } {
set args "magic -noconsole -dnull -rcfile $::env(MAGIC_MAGICRC) < $script |& tee $::env(TERMINAL_OUTPUT) $arg_values(-indexed_log)"
} elseif { $arg_values(-tool) == "yosys" } {
set args "$::env(SYNTH_BIN) -c $script |& tee $::env(TERMINAL_OUTPUT) $arg_values(-indexed_log)"
} else {
puts_err "run_tcl_script only supports '-tool magic' and '-tool openroad' for now."
puts_err "run_tcl_script only supports tools 'magic', 'yosys' or 'openroad' for now."
return -code error
}

Expand Down Expand Up @@ -614,7 +620,9 @@ proc run_tcl_script {args} {
lappend or_issue_arg_list --script $script
lappend or_issue_arg_list --run-path $::env(RUN_DIR)

if { [info exists flag_map(-netlist_in)] } {
if { $tool == "yosys" } {
lappend or_issue_arg_list --input-type "n/a" "/dev/null"
} elseif { [info exists flag_map(-netlist_in)] } {
lappend or_issue_arg_list --input-type "netlist" $::env(CURRENT_NETLIST)
} elseif { $tool != "openroad" || [info exists flag_map(-def_in)]} {
lappend or_issue_arg_list --input-type "def" $::env(CURRENT_DEF)
Expand Down
126 changes: 40 additions & 86 deletions scripts/yosys/logic_equiv_check.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -13,110 +13,64 @@
# limitations under the License.
yosys -import

if { [info exists ::env(FP_WELLTAP_CELL)] && $::env(FP_WELLTAP_CELL) ne ""} {
set well_tap_cell "$::env(FP_WELLTAP_CELL)"
proc exclude_fills {args} {
set fills "$::env(CELL_PAD_EXCLUDE)"
foreach fill_wildcard $fills {
hierarchy -generate $fill_wildcard
}
}
set decap_cell_wildcard "$::env(DECAP_CELL)*"
set fill_cell_wildcard "$::env(FILL_CELL)*"

set vtop $::env(DESIGN_NAME)
#set sdc_file $::env(SDC_FILE)

# LHS
if { [info exists ::env(SYNTH_DEFINES) ] } {
foreach define $::env(SYNTH_DEFINES) {
puts "Defining $define"
verilog_defines -D$define
proc initialize {args} {
if { [info exists ::env(SYNTH_DEFINES) ] } {
foreach define $::env(SYNTH_DEFINES) {
puts "Defining $define"
verilog_defines -D$define
}
}
}
if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
read_verilog -lib $verilog_file
if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
read_verilog -lib $verilog_file
}
}
foreach lib $::env(LIB_TYPICAL) {
read_liberty -ignore_miss_func -ignore_miss_dir $lib
}
}
foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
read_liberty -nooverwrite -lib -ignore_miss_dir -setattr blackbox $lib
}

read_verilog $::env(LEC_LHS_NETLIST)
rmports
if { [info exists well_tap_cell] } {
hierarchy -generate $well_tap_cell
}
hierarchy -generate $decap_cell_wildcard
hierarchy -generate $fill_cell_wildcard
splitnets -ports;;
hierarchy -auto-top
if { $::env(SYNTH_FLAT_TOP) } {
flatten
}
setattr -set keep 1
stat
renames -top gold
design -stash gold
proc read_nl {netlist name} {
initialize
read_verilog $netlist

rmports

# RHS
# Rebuild the database due to -stash
if { [info exists ::env(SYNTH_DEFINES) ] } {
foreach define $::env(SYNTH_DEFINES) {
puts "Defining $define"
verilog_defines -D$define
}
}
if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
read_verilog -lib $verilog_file
exclude_fills

splitnets -ports
hierarchy -top $::env(DESIGN_NAME)

if { $::env(SYNTH_FLAT_TOP) } {
flatten
}
}
foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
read_liberty -nooverwrite -lib -ignore_miss_dir -setattr blackbox $lib
}

read_verilog $::env(LEC_RHS_NETLIST)
rmports
if { [info exists well_tap_cell] } {
hierarchy -generate $well_tap_cell
}
hierarchy -generate $decap_cell_wildcard
hierarchy -generate $fill_cell_wildcard
splitnets -ports;;
hierarchy -auto-top
if { $::env(SYNTH_FLAT_TOP) } {
flatten
stat
renames -top $name
design -stash $name
}
setattr -set keep 1
stat
renames -top gate
design -stash gate

# LHS
read_nl $::env(LEC_LHS_NETLIST) gold

# RHS
read_nl $::env(LEC_RHS_NETLIST) gate

# LEC
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate

# Rebuild the database due to -stash
if { [info exists ::env(SYNTH_DEFINES) ] } {
foreach define $::env(SYNTH_DEFINES) {
puts "Defining $define"
verilog_defines -D$define
}
}
if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
read_verilog -lib $verilog_file
}
}
foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
read_liberty -nooverwrite -lib -ignore_miss_dir -setattr blackbox $lib
}
initialize
exclude_fills

equiv_make gold gate equiv
if { [info exists well_tap_cell] } {
hierarchy -generate $well_tap_cell
}
hierarchy -generate $decap_cell_wildcard
hierarchy -generate $fill_cell_wildcard
setattr -set keep 1
prep -flatten -top equiv
equiv_simple -seq 10 -v
equiv_status -assert

0 comments on commit 86615f8

Please sign in to comment.