mirror of https://github.com/efabless/caravel.git
Merge branch 'cocotb' of github.com:efabless/caravel into cocotb
This commit is contained in:
commit
f5e1060c6d
|
@ -9,6 +9,7 @@
|
||||||
````
|
````
|
||||||
export CARAVEL_ROOT=<caravel path>
|
export CARAVEL_ROOT=<caravel path>
|
||||||
export MCW_ROOT=<mgmt core path>
|
export MCW_ROOT=<mgmt core path>
|
||||||
|
export UPRJ_ROOT=<caravel user project path>
|
||||||
export PDK_ROOT=<path to pdk>
|
export PDK_ROOT=<path to pdk>
|
||||||
export PDK=<sky130A/B>
|
export PDK=<sky130A/B>
|
||||||
|
|
||||||
|
@ -17,10 +18,9 @@ python3 signoff_automation.py [-options]
|
||||||
usage: signoff_automation.py [-h] [-d] [-l] [-v] [-rtl] [-gl] [-sdf] [-iv] [-sta] [-a]
|
usage: signoff_automation.py [-h] [-d] [-l] [-v] [-rtl] [-gl] [-sdf] [-iv] [-sta] [-a]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
|
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
|
|
||||||
-d, --drc_check run drc check
|
-drc, --drc_check run drc check
|
||||||
|
|
||||||
-l, --lvs_check run lvs check
|
-l, --lvs_check run lvs check
|
||||||
|
|
||||||
|
@ -34,13 +34,20 @@ optional arguments:
|
||||||
|
|
||||||
-iv, --iverilog run verification using iverilog
|
-iv, --iverilog run verification using iverilog
|
||||||
|
|
||||||
-sta, --primetime_sta
|
-sta, --primetime_sta run STA using PrimeTime
|
||||||
run verification using iverilog
|
|
||||||
|
-d DESIGN, --design DESIGN design under test
|
||||||
|
|
||||||
-a, --all run all checks
|
-a, --all run all checks
|
||||||
````
|
````
|
||||||
|
### How to run Caravel top-level STA including user project wrapper
|
||||||
|
1. edit in [pt_sta.tcl](./pt_sta.tcl) the spef mapping section to add the user project module instantiated in user project wrapper
|
||||||
|
2. run the command
|
||||||
|
````
|
||||||
|
python3 signoff_automation.py -d caravel -sta
|
||||||
|
````
|
||||||
## Reports and logs
|
## Reports and logs
|
||||||
|
|
||||||
Reports can be found `$CARAVEL_ROOT/signoff/<design_name>/`
|
Reports can be found `$CARAVEL_ROOT/signoff/<design_name>/`
|
||||||
|
|
||||||
Logs can be found at `$CARAVEL_ROOT/scripts/logs/`
|
Logs can be found at `$CARAVEL_ROOT/scripts/logs/`
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
##PT script
|
if {\
|
||||||
|
[catch {
|
||||||
# Adding SCL and IO link libraries based on the process corner specified
|
##PT script
|
||||||
if {$::env(PROC_CORNER) == "t"} {
|
# Adding SCL and IO link libraries based on the process corner specified
|
||||||
|
if {$::env(PROC_CORNER) == "t"} {
|
||||||
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_tt_1.80v_25C.lib \
|
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_tt_1.80v_25C.lib \
|
||||||
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_25C.lib \
|
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_25C.lib \
|
||||||
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_lowhv_3.3v_lv_1.8v_25C.lib \
|
$::env(PT_LIB_ROOT)/scs130hvl_tt_3.3v_lowhv_3.3v_lv_1.8v_25C.lib \
|
||||||
|
@ -14,7 +15,7 @@ if {$::env(PROC_CORNER) == "t"} {
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib \
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib \
|
||||||
"
|
"
|
||||||
} elseif {$::env(PROC_CORNER) == "f"} {
|
} elseif {$::env(PROC_CORNER) == "f"} {
|
||||||
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ff_1.95v_-40C.lib \
|
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ff_1.95v_-40C.lib \
|
||||||
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_-40C.lib \
|
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_-40C.lib \
|
||||||
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_lowhv_5.5v_lv_1.95v_-40C.lib \
|
$::env(PT_LIB_ROOT)/scs130hvl_ff_5.5v_lowhv_5.5v_lv_1.95v_-40C.lib \
|
||||||
|
@ -27,7 +28,7 @@ if {$::env(PROC_CORNER) == "t"} {
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ff_n40C_1v95_5v50_5v50.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ff_n40C_1v95_5v50_5v50.lib \
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ff_n40C_1v95_5v50.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ff_n40C_1v95_5v50.lib \
|
||||||
"
|
"
|
||||||
} elseif {$::env(PROC_CORNER) == "s"} {
|
} elseif {$::env(PROC_CORNER) == "s"} {
|
||||||
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ss_1.40v_100C.lib \
|
set link_path "* $::env(PT_LIB_ROOT)/scs130hd_ss_1.40v_100C.lib \
|
||||||
$::env(PT_LIB_ROOT)/scs130hvl_ss_3.00v_100C.lib \
|
$::env(PT_LIB_ROOT)/scs130hvl_ss_3.00v_100C.lib \
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_ss_ss_100C_1v60_3v00.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_ss_ss_100C_1v60_3v00.lib \
|
||||||
|
@ -39,28 +40,33 @@ if {$::env(PROC_CORNER) == "t"} {
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ss_100C_1v60_3v00_3v00.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ss_100C_1v60_3v00_3v00.lib \
|
||||||
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ss_100C_1v60_3v00.lib \
|
$::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_ss_100C_1v60_3v00.lib \
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reading design netlist
|
# Reading design netlist
|
||||||
# TODO: get chip io netlist instead of reading the RTL
|
set search_path "$::env(CARAVEL_ROOT)/verilog/gl $::env(MCW_ROOT)/verilog/gl $::env(UPRJ_ROOT)/verilog/gl $::env(PT_LIB_ROOT)"
|
||||||
set search_path "$::env(CARAVEL_ROOT)/verilog/gl $::env(MCW_ROOT)/verilog/gl $::env(PT_LIB_ROOT)"
|
puts "list of verilog files:"
|
||||||
foreach verilog "[glob $::env(CARAVEL_ROOT)/verilog/gl/*.v] [glob $::env(MCW_ROOT)/verilog/gl/*.v]" {
|
foreach verilog "[glob $::env(CARAVEL_ROOT)/verilog/gl/*.v] [glob $::env(MCW_ROOT)/verilog/gl/*.v] [glob $::env(UPRJ_ROOT)/verilog/gl/*.v]" {
|
||||||
|
puts $verilog
|
||||||
read_verilog $verilog
|
read_verilog $verilog
|
||||||
}
|
}
|
||||||
|
|
||||||
current_design $::env(DESIGN)
|
current_design $::env(DESIGN)
|
||||||
link
|
link
|
||||||
|
|
||||||
# Reading constraints (signoff)
|
# Reading constraints (signoff)
|
||||||
if {$::env(DESIGN) == "mgmt_core_wrapper" | $::env(DESIGN) == "RAM256" | $::env(DESIGN) == "RAM128"} {
|
if {$::env(DESIGN) == "mgmt_core_wrapper" | $::env(DESIGN) == "RAM256" | $::env(DESIGN) == "RAM128"} {
|
||||||
read_sdc $::env(MCW_ROOT)/sdc/$::env(DESIGN).sdc
|
read_sdc $::env(MCW_ROOT)/sdc/$::env(DESIGN).sdc
|
||||||
} else {
|
} else {
|
||||||
read_sdc $::env(CARAVEL_ROOT)/sdc/$::env(DESIGN).sdc
|
read_sdc $::env(CARAVEL_ROOT)/sdc/$::env(DESIGN).sdc
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reading parasitics based on the RC corner specified
|
# Reading parasitics based on the RC corner specified
|
||||||
proc read_spefs {design rc_corner} {
|
proc read_spefs {design rc_corner} {
|
||||||
if {$design == "caravel"} {
|
if {$design == "caravel"} {
|
||||||
|
set spef_mapping(mprj) $::env(UPRJ_ROOT)/spef/user_project_wrapper/user_project_wrapper.${rc_corner}.spef
|
||||||
|
# add your module name instantiated in user_project_wrapper here
|
||||||
|
# set spef_mapping(mprj/<instance name>) $::env(UPRJ_ROOT)/spef/<design name>/<design name>.${rc_corner}.spef
|
||||||
|
|
||||||
set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf/xres_buf.${rc_corner}.spef
|
set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf/xres_buf.${rc_corner}.spef
|
||||||
set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io/chip_io.${rc_corner}.spef
|
set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io/chip_io.${rc_corner}.spef
|
||||||
set spef_mapping(padframe/\constant_value_inst[0]) $::env(CARAVEL_ROOT)/spef/constant_block/constant_block.${rc_corner}.spef
|
set spef_mapping(padframe/\constant_value_inst[0]) $::env(CARAVEL_ROOT)/spef/constant_block/constant_block.${rc_corner}.spef
|
||||||
|
@ -220,8 +226,8 @@ proc read_spefs {design rc_corner} {
|
||||||
read_parasitics -verbose $::env(CARAVEL_ROOT)/spef/${design}/${design}.${rc_corner}.spef -pin_cap_included
|
read_parasitics -verbose $::env(CARAVEL_ROOT)/spef/${design}/${design}.${rc_corner}.spef -pin_cap_included
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
proc report_results {design rc_corner proc_corner} {
|
proc report_results {design rc_corner proc_corner} {
|
||||||
report_constraint -all_violators -significant_digits 4 -nosplit > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-all_viol.rpt
|
report_constraint -all_violators -significant_digits 4 -nosplit > $::env(OUT_DIR)/pt_reports/${design}/${design}-${rc_corner}-${proc_corner}-all_viol.rpt
|
||||||
|
|
||||||
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
|
report_timing -delay min -path_type full_clock_expanded -transition_time -capacitance -nets -nosplit \
|
||||||
|
@ -263,10 +269,15 @@ proc report_results {design rc_corner proc_corner} {
|
||||||
set extract_model_enable_report_delay_calculation true
|
set extract_model_enable_report_delay_calculation true
|
||||||
set extract_model_with_clock_latency_arcs true
|
set extract_model_with_clock_latency_arcs true
|
||||||
extract_model -output $::env(OUT_DIR)/pt_etm/${design}/${design}-${rc_corner}-${proc_corner} -format {db lib} -test_design
|
extract_model -output $::env(OUT_DIR)/pt_etm/${design}/${design}-${rc_corner}-${proc_corner} -format {db lib} -test_design
|
||||||
|
}
|
||||||
|
|
||||||
|
read_spefs $::env(DESIGN) $::env(RC_CORNER)
|
||||||
|
update_timing
|
||||||
|
report_results $::env(DESIGN) $::env(RC_CORNER) $::env(PROC_CORNER)
|
||||||
|
|
||||||
|
exit
|
||||||
|
} err]
|
||||||
|
} {
|
||||||
|
puts stderr $err
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
read_spefs $::env(DESIGN) $::env(RC_CORNER)
|
|
||||||
update_timing
|
|
||||||
report_results $::env(DESIGN) $::env(RC_CORNER) $::env(PROC_CORNER)
|
|
||||||
|
|
||||||
exit
|
|
|
@ -32,6 +32,7 @@ def run_sta (
|
||||||
os.environ["PDK"] = os.getenv('PDK')
|
os.environ["PDK"] = os.getenv('PDK')
|
||||||
os.environ["PT_LIB_ROOT"] = os.getenv('PT_LIB_ROOT')
|
os.environ["PT_LIB_ROOT"] = os.getenv('PT_LIB_ROOT')
|
||||||
os.environ["CARAVEL_ROOT"] = os.getenv('CARAVEL_ROOT')
|
os.environ["CARAVEL_ROOT"] = os.getenv('CARAVEL_ROOT')
|
||||||
|
os.environ["UPRJ_ROOT"] = os.getenv('UPRJ_ROOT')
|
||||||
os.environ["MCW_ROOT"] = os.getenv('MCW_ROOT')
|
os.environ["MCW_ROOT"] = os.getenv('MCW_ROOT')
|
||||||
os.environ["OUT_DIR"] = output_dir
|
os.environ["OUT_DIR"] = output_dir
|
||||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -68,6 +69,7 @@ def check_env_vars():
|
||||||
pdk = os.getenv('PDK')
|
pdk = os.getenv('PDK')
|
||||||
pt_lib_root = os.getenv('PT_LIB_ROOT')
|
pt_lib_root = os.getenv('PT_LIB_ROOT')
|
||||||
caravel_root = os.getenv('CARAVEL_ROOT')
|
caravel_root = os.getenv('CARAVEL_ROOT')
|
||||||
|
uprj_root = os.getenv('UPRJ_ROOT')
|
||||||
mcw_root = os.getenv('MCW_ROOT')
|
mcw_root = os.getenv('MCW_ROOT')
|
||||||
if pdk_root is None:
|
if pdk_root is None:
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
|
@ -89,6 +91,10 @@ def check_env_vars():
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
"Please export MCW_ROOT to the Caravel Management SoC Litex repo path"
|
"Please export MCW_ROOT to the Caravel Management SoC Litex repo path"
|
||||||
)
|
)
|
||||||
|
if uprj_root is None:
|
||||||
|
raise FileNotFoundError(
|
||||||
|
"Please export UPRJ_ROOT to the Caravel User Project Wrapper repo path"
|
||||||
|
)
|
||||||
|
|
||||||
# Analyze the STA all violators output report
|
# Analyze the STA all violators output report
|
||||||
def search_viol(
|
def search_viol(
|
||||||
|
|
|
@ -448,7 +448,7 @@ if __name__ == "__main__":
|
||||||
out, err = sta_p.communicate()
|
out, err = sta_p.communicate()
|
||||||
sta_log = open(f"{log_dir}/PT_STA_{design}.log", "w")
|
sta_log = open(f"{log_dir}/PT_STA_{design}.log", "w")
|
||||||
if err:
|
if err:
|
||||||
logging.error(err.decode())
|
logging.error(err)
|
||||||
sta_log.write(err)
|
sta_log.write(err)
|
||||||
|
|
||||||
if not check_errors(
|
if not check_errors(
|
||||||
|
|
|
@ -88,8 +88,8 @@ set_max_fanout 12 [current_design]
|
||||||
# synthesis max fanout should be less than 12 (7 maybe)
|
# synthesis max fanout should be less than 12 (7 maybe)
|
||||||
|
|
||||||
## Set system monitoring mux select to zero so that the clock/user_clk monitoring is disabled
|
## Set system monitoring mux select to zero so that the clock/user_clk monitoring is disabled
|
||||||
set_case_analysis 0 [get_pins housekeeping/_3948_/S]
|
set_case_analysis 0 [get_pins housekeeping/_3936_/S]
|
||||||
set_case_analysis 0 [get_pins housekeeping/_3949_/S]
|
set_case_analysis 0 [get_pins housekeeping/_3937_/S]
|
||||||
|
|
||||||
# Add case analysis for pads DM[2]==1'b1 & DM[1]==1'b1 & DM[0]==1'b0
|
# Add case analysis for pads DM[2]==1'b1 & DM[1]==1'b1 & DM[0]==1'b0
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ void main(){
|
||||||
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
||||||
|
|
||||||
// bitbang
|
// bitbang
|
||||||
for(int i =0;i<19*13;i++){
|
for(int i =0;i<62;i++){
|
||||||
clock00();
|
clock00();
|
||||||
clock00();
|
clock00();
|
||||||
clock11();
|
clock11();
|
||||||
|
|
|
@ -49,7 +49,7 @@ void main(){
|
||||||
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
||||||
|
|
||||||
// bitbang
|
// bitbang
|
||||||
for(int i =0;i<19*13;i++){
|
for(int i =0;i<124;i++){
|
||||||
clock00();
|
clock00();
|
||||||
clock11();
|
clock11();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ void main(){
|
||||||
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
||||||
|
|
||||||
// bitbang
|
// bitbang
|
||||||
for(int i =0;i<19*13;i++){
|
for(int i =0;i<124;i++){
|
||||||
clock11();
|
clock11();
|
||||||
clock00();
|
clock00();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ void main(){
|
||||||
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
|
||||||
|
|
||||||
// bitbang
|
// bitbang
|
||||||
for(int i =0;i<19*13;i++){
|
for(int i =0;i<62;i++){
|
||||||
clock11();
|
clock11();
|
||||||
clock11();
|
clock11();
|
||||||
clock00();
|
clock00();
|
||||||
|
|
1002
verilog/gl/chip_io.v
1002
verilog/gl/chip_io.v
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue