blob: c453a7e61e1921abf25ab786214f55d857b2feb4 [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#####################
## PREPARE FLOW ##
#####################
proc get_env_var {name} {
if {[info exists ::env($name)]} {
set val "[set ::env([set name])]"
puts "::env($name) = $val"
return $val
} else {
puts "ERROR: Script run without $name environment variable."
quit
}
}
set FOUNDRY_ROOT [get_env_var "FOUNDRY_ROOT"]
set SV_FLIST [get_env_var "SV_FLIST"]
set BUILD_DIR [get_env_var "BUILD_DIR"]
set DUT [get_env_var "DUT"]
set CONSTRAINT [get_env_var "CONSTRAINT"]
set FOUNDRY_CONSTRAINT [get_env_var "FOUNDRY_CONSTRAINT"]
set PARAMS [get_env_var "PARAMS"]
set CDC_WAIVER_FILE [get_env_var "CDC_WAIVER_FILE"]
set CDC_WAIVER_DIR [file dirname $CDC_WAIVER_FILE]
set ENV_FILE [get_env_var "ENV_FILE"]
# Used to disable some SDC constructs that are not needed by CDC.
set IS_CDC_RUN 1
########################
## Library Setup ##
########################
# if the foundry root is specified, some more library setup is needed.
if {$FOUNDRY_ROOT != ""} {
# TODO: add lib setup tcl file here
# this PRIM_DEFAULT_IMPL selects the appropriate technology by defining
# PRIM_DEFAULT_IMPL=prim_pkg::Impl<tech identifier>
# PRIM_DEFAULT_IMPL is set inside the library setup script
set DEFINE "PRIM_DEFAULT_IMPL=${PRIM_DEFAULT_IMPL}+${PRIM_STD_CELL_VARIANT}"
source "${FOUNDRY_ROOT}/cdc/verixcdc/setup.tcl"
} else {
set DEFINE ""
}
########################
## Configure CDC Tool ##
########################
# TODO: potentially more settings are needed.
# set ri_enable_sva false
set ri_create_outputs_in_create_env true
set ri_print_module_nand2_counts true
# enable analysis of large arrays
set ri_max_total_range_bits 100000
#########################
## Analyze & Elaborate ##
#########################
# TODO(#11492): Fix the issue of CDC delay
if {$DEFINE != ""} {
analyze -sverilog +define+${DEFINE} +define+AST_BYPASS_CLK -f ${SV_FLIST}
} else {
analyze -sverilog +define+AST_BYPASS_CLK -f ${SV_FLIST}
}
# TODO(#13197): two flops are accessing the same memory cells
# prim_generic_ram_2p is not recognized as a CDC module by the tool
# So, it's black-boxed while waiting for a tool patch
if {$PARAMS != ""} {
elaborate -params "$PARAMS" $DUT -black_box prim_generic_ram_2p
} else {
elaborate $DUT -black_box prim_generic_ram_2p
}
#################################
## Define Common Synchronizers ##
#################################
# Glitch Free Mux
# WARNING!!! prim_clock_mux2 is not a glitch free mux
#set_user_glitch_free_muxes -name opentitan_clock_mux prim_generic_clock_mux2
#set_user_glitch_free_muxes -name opentitan_glitchfree_mux prim_generic_clock_glitchfree_mux2
# 2FF synchronizer.
# TODO: Process dependent module name later
set prim_2ff_modules {}
# Find every derivated modules from 2FF synchronizer
foreach mod [get_all_modules prim_flop_2sync] {
lappend prim_2ff_modules $mod
puts "Adding to list prim_2ff_modules: $mod"
}
set_user_cntl_synchronizer -name opentitan_2ff $prim_2ff_modules
# Pulse synchronizer
# Req/Ack synchronizer
# TODO: These should not be hardcoded here, instead, we need to create another variable called CDC_CONSTRAINT
# where a top could specifically suppli this
#
# The following paths ignore data integrity errors that are directly generated on the async fifo data
# The path is as follows: asycn_fifo.rdata_o -> data integrity check -> a_valid
# There are two such paths: One path is a the error pin directly into ibex, and the other is ibex's internal check
set async_fifo_data [get_pins -of_objects [get_cells -hier * -filter {ref_name == prim_fifo_async}] -filter {name =~ rdata_o*}]
set_ignore_cdc_paths -name async_fifo_to_ibex_data_err -through_signal $async_fifo_data -through_signal [get_pins top_earlgrey/u_rv_core_ibex/u_core/data_err_i]
set_ignore_cdc_paths -name async_fifo_to_ibex_ecc_err -through_signal $async_fifo_data -through_signal [get_pins top_earlgrey/u_rv_core_ibex/u_core/u_ibex_core/load_store_unit_i/load_intg_err_o]
# The following paths ignore valid qualification using the response data
# In the socketm1 module, the returned ID is used to pick which of the original source made the request
# CDC sees this as rdata directly affecting the control, but the control signal should already dictate whether the rdata is safe to use.
set_ignore_cdc_paths -name async_fifo_to_ibex_ivalid -through_signal $async_fifo_data -through_signal [get_pins top_earlgrey/u_rv_core_ibex/u_core/instr_rvalid_i]
set_ignore_cdc_paths -name async_fifo_to_ibex_dvalid -through_signal $async_fifo_data -through_signal [get_pins top_earlgrey/u_rv_core_ibex/u_core/data_rvalid_i]
# CDC between tlul_fifo_async and regs : ignored
set tlul_async_data [get_pins -of_objects [get_cells -hier * -filter {ref_name == tlul_fifo_async}] -filter {name =~ tl_d_o*}]
set_ignore_cdc_paths -name tlul_async_fifo_err -through_signal $tlul_async_data -through_signal [get_pins {top_earlgrey/*/u_reg/u_io_*meas_ctrl_shadowed_cdc/src_we_i}]
#########################
## Apply Constraints ##
#########################
read_sdc $CONSTRAINT
if {$FOUNDRY_CONSTRAINT != ""} {
read_sdc $FOUNDRY_CONSTRAINT
}
############################
## Apply Environment File ##
############################
if {$ENV_FILE != ""} {
read_env $ENV_FILE
}
#########################
## Run CDC ##
#########################
analyze_intent
verify_cdc
#########################
## Top Modules ##
#########################
# TODO: modules are used after elaboration. If a module is instantiated
# multiple times, the module name should be uniquified name.
# Due to this, uart, i2c, spi_host reports are not correct.
set modules {
spi_device
kmac
hmac
uart
gpio
spi_host
flash_ctrl
alert_handler
otp_ctrl
lc_ctrl
pwrmgr
clkmgr
rstmgr
keymgr
csrng
entropy_src
aes
rom_ctrl
edn
}
#########################
## Read in Waivers ##
#########################
source $CDC_WAIVER_FILE
#########################
## Write out report ##
#########################
report_policy -verbose -skip_empty_summary_status -compat -output vcdc.rpt ALL
file mkdir ../REPORT/
foreach mod $modules {
# Find unique modules
set umods [get_all_modules $mod]
set umods_length [llength $umods]
puts "Generating Policy Reports for $mod ( $umods ) ..."
if {$umods_length == 1} {
# Just report as original module
report_policy -verbose -skip_empty_summary_status -compat \
-output ../REPORT/vcdc.$mod.rpt -module [lindex $umods 0] \
{NEW TO_BE_FIXED DEFERRED}
} else {
# Report file name is increamental index not uniquified module name
set idx 0
foreach umod $umods {
report_policy -verbose -skip_empty_summary_status -compat \
-output ../REPORT/vcdc.$mod_$idx.rpt -module $umod \
{NEW TO_BE_FIXED DEFERRED}
incr idx 1
}
}
}
# Report waived in a separate file
report_policy -verbose -skip_empty_summary_status -compat -output ../REPORT/vcdc.new.rpt {NEW}
report_policy -verbose -skip_empty_summary_status -compat -output ../REPORT/vcdc.waived.rpt {WAIVED}
# report_messages -output verix_cdc.rpt
# Clock report
report_clock_domains -flops -output ../REPORT/clocks.flops.rpt
report_clock_matrix -output ../REPORT/clocks.matrix.rpt