semaphore + pinmux reg realignement + multi-core bug fix in riscv core
diff --git a/openlane/pinmux/base.sdc b/openlane/pinmux_top/base.sdc
similarity index 100%
rename from openlane/pinmux/base.sdc
rename to openlane/pinmux_top/base.sdc
diff --git a/openlane/pinmux/config.tcl b/openlane/pinmux_top/config.tcl
similarity index 100%
rename from openlane/pinmux/config.tcl
rename to openlane/pinmux_top/config.tcl
diff --git a/openlane/pinmux/pin_order.cfg b/openlane/pinmux_top/pin_order.cfg
similarity index 100%
rename from openlane/pinmux/pin_order.cfg
rename to openlane/pinmux_top/pin_order.cfg
diff --git a/openlane/user_project_wrapper/interactive.mpw4.tcl b/openlane/user_project_wrapper/interactive.mpw4.tcl
deleted file mode 100644
index 1c24305..0000000
--- a/openlane/user_project_wrapper/interactive.mpw4.tcl
+++ /dev/null
@@ -1,394 +0,0 @@
-#!/usr/bin/tclsh
-# SPDX-FileCopyrightText: 2020 Efabless Corporation
-# Copyright 2020 Efabless Corporation
-# Copyright 2020 Sylvain Munaut
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# SPDX-License-Identifier: Apache-2.0
-
-package require openlane;
-
-
-proc run_placement_step {args} {
- if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
- set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
- }
-
- run_placement
-}
-
-proc run_placement {args} {
- puts_info "Running Placement..."
-# |----------------------------------------------------|
-# |---------------- 3. PLACEMENT ------------------|
-# |----------------------------------------------------|
- set ::env(CURRENT_STAGE) placement
-
- if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } {
- set old_pl_target_density $::env(PL_TARGET_DENSITY)
- set ::env(PL_TARGET_DENSITY) $::env(PL_TARGET_DENSITY_CELLS)
- }
-
- if { $::env(PL_RANDOM_GLB_PLACEMENT) } {
- # useful for very tiny designs
- random_global_placement
- } else {
- global_placement_or
- }
-
- if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } {
- set ::env(PL_TARGET_DENSITY) $old_pl_target_density
- }
-
- run_resizer_design
-
- if { [info exists ::env(DONT_BUFFER_PORTS) ]} {
- remove_buffers
- }
- detailed_placement_or
- scrot_klayout -layout $::env(CURRENT_DEF)
-}
-
-
-proc run_cts_step {args} {
- if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
- set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
- }
-
- run_cts
- run_resizer_timing
-}
-
-proc run_routing_step {args} {
- if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
- set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
- }
- run_routing
-}
-
-proc run_diode_insertion_2_5_step {args} {
- if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
- set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
- }
- if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
- run_antenna_check
- heal_antenna_violators; # modifies the routed DEF
- }
-
-}
-
-proc run_power_pins_insertion_step {args} {
- # set_def $::env(tritonRoute_result_file_tag).def
- if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
- set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
- }
- if { $::env(LVS_INSERT_POWER_PINS) } {
- write_powered_verilog
- set_netlist $::env(lvs_result_file_tag).powered.v
- }
-
-}
-
-
-proc run_lvs_step {{ lvs_enabled 1 }} {
- if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
- set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
- }
- if { $lvs_enabled } {
- run_magic_spice_export
- run_lvs; # requires run_magic_spice_export
- }
-
-}
-
-proc run_drc_step {{ drc_enabled 1 }} {
- if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
- set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
- }
- if { $drc_enabled } {
- run_magic_drc
- run_klayout_drc
- }
-}
-
-proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
- if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
- set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
- } else {
- set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
- }
- if { $antenna_check_enabled } {
- run_antenna_check
- }
-}
-
-
-proc gen_pdn {args} {
- puts_info "Generating PDN..."
- TIMER::timer_start
-
- set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def]
- set ::env(PGA_RPT_FILE) [index_file $::env(pdn_report_file_tag).pga.rpt]
-
- try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/pdn.tcl \
- |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0]
-
-
- TIMER::timer_stop
- exec echo "[TIMER::get_runtime]" >> [index_file $::env(pdn_log_file_tag)_runtime.txt 0]
-
- quit_on_unconnected_pdn_nodes
-
- set_def $::env(SAVE_DEF)
-}
-
-proc run_power_grid_generation {args} {
-
- if {[info exists ::env(FP_PDN_POWER_STRAPS)]} {
- set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","]
- }
-
- # internal macros power connections
- if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} {
- set macro_hooks [dict create]
- set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
- foreach pdn_hook $pdn_hooks {
- set instance_name [lindex $pdn_hook 0]
- set power_net [lindex $pdn_hook 1]
- set ground_net [lindex $pdn_hook 2]
- dict append macro_hooks $instance_name [subst {$power_net $ground_net}]
- }
-
- set power_net_indx [lsearch $::env(VDD_NETS) $power_net]
- set ground_net_indx [lsearch $::env(GND_NETS) $ground_net]
-
- # make sure that the specified power domains exist.
- if { $power_net_indx == -1 || $ground_net_indx == -1 || $power_net_indx != $ground_net_indx } {
- puts_err "Can't find $power_net and $ground_net domain. \
- Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)."
- }
- }
-
- # generate multiple power grids per pair of (VDD,GND)
- # offseted by WIDTH + SPACING
- foreach domain $power_domains {
- set ::env(VDD_NET) [lindex $domain 0]
- set ::env(GND_NET) [lindex $domain 1]
- set ::env(_WITH_STRAPS) [lindex $domain 2]
-
- puts_info "Connecting Power: $::env(VDD_NET) & $::env(GND_NET) to All internal macros."
- # internal macros power connections
- set ::env(FP_PDN_MACROS) ""
- if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 } {
- # if macros connections to power are explicitly set
- # default behavoir macro pins will be connected to the first power domain
- if { [info exists ::env(FP_PDN_MACRO_HOOKS)] } {
- set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
- foreach {instance_name hooks} $macro_hooks {
- set power [lindex $hooks 0]
- set ground [lindex $hooks 1]
- if { $power == $::env(VDD_NET) && $ground == $::env(GND_NET) } {
- set ::env(FP_PDN_ENABLE_MACROS_GRID) 1
- set ::env(FP_PDN_IRDROP) "1"
- puts_info "Connecting $instance_name to $power and $ground nets."
- lappend ::env(FP_PDN_MACROS) $instance_name
- }
- }
- }
- } else {
- puts_warn "All internal macros will not be connected to power $::env(VDD_NET) & $::env(GND_NET)."
- }
-
- gen_pdn
-
- set ::env(FP_PDN_ENABLE_RAILS) 0
- set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
- set ::env(FP_PDN_IRDROP) "0"
-
- # allow failure until open_pdks is up to date...
- catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]}
- catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]}
-
- catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \
- [expr $::env(FP_PDN_CORE_RING_VOFFSET)\
- +2*($::env(FP_PDN_CORE_RING_VWIDTH)\
- +max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
- catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\
- +2*($::env(FP_PDN_CORE_RING_HWIDTH)+\
- max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
- puts "FP_PDN_VOFFSET: $::env(FP_PDN_VOFFSET)"
- puts "FP_PDN_HOFFSET: $::env(FP_PDN_HOFFSET)"
- puts "FP_PDN_CORE_RING_VOFFSET: $::env(FP_PDN_CORE_RING_VOFFSET)"
- puts "FP_PDN_CORE_RING_HOFFSET: $::env(FP_PDN_CORE_RING_HOFFSET)"
-
- }
- set ::env(FP_PDN_ENABLE_RAILS) 1
-}
-
-
-proc run_floorplan {args} {
- puts_info "Running Floorplanning..."
- # |----------------------------------------------------|
- # |---------------- 2. FLOORPLAN ------------------|
- # |----------------------------------------------------|
- #
- # intial fp
- init_floorplan
-
-
- # place io
- if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
- place_io_ol
- } else {
- if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
- place_io
- global_placement_or
- place_contextualized_io \
- -lef $::env(FP_CONTEXT_LEF) \
- -def $::env(FP_CONTEXT_DEF)
- } else {
- place_io
- }
- }
-
- apply_def_template
-
- if { [info exist ::env(EXTRA_LEFS)] } {
- if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
- file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(TMP_DIR)/macro_placement.cfg
- manual_macro_placement f
- } else {
- global_placement_or
- basic_macro_placement
- }
- }
-
- # tapcell
- tap_decap_or
- scrot_klayout -layout $::env(CURRENT_DEF)
- # power grid generation
- run_power_grid_generation
-}
-
-
-proc run_flow {args} {
- set script_dir [file dirname [file normalize [info script]]]
-
- set options {
- {-design required}
- {-save_path optional}
- {-no_lvs optional}
- {-no_drc optional}
- {-no_antennacheck optional}
- }
- set flags {-save}
- parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
-
- prep {*}$args
-
- set LVS_ENABLED 1
- set DRC_ENABLED 0
- set ANTENNACHECK_ENABLED 1
-
- set steps [dict create \
- "synthesis" {run_synthesis "" } \
- "floorplan" {run_floorplan ""} \
- "placement" {run_placement_step ""} \
- "cts" {run_cts_step ""} \
- "routing" {run_routing_step ""} \
- "diode_insertion" {run_diode_insertion_2_5_step ""} \
- "power_pins_insertion" {run_power_pins_insertion_step ""} \
- "gds_magic" {run_magic ""} \
- "gds_drc_klayout" {run_klayout ""} \
- "gds_xor_klayout" {run_klayout_gds_xor ""} \
- "lvs" "run_lvs_step $LVS_ENABLED" \
- "drc" "run_drc_step $DRC_ENABLED" \
- "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
- "cvc" {run_lef_cvc}
- ]
-
- set_if_unset arg_values(-to) "cvc";
-
- if { [info exists ::env(CURRENT_STEP) ] } {
- puts "\[INFO\]:Picking up where last execution left off"
- puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
- } else {
- set ::env(CURRENT_STEP) "synthesis";
- }
- set_if_unset arg_values(-from) $::env(CURRENT_STEP);
- set exe 0;
- dict for {step_name step_exe} $steps {
- if { [ string equal $arg_values(-from) $step_name ] } {
- set exe 1;
- }
-
- if { $exe } {
- # For when it fails
- set ::env(CURRENT_STEP) $step_name
- [lindex $step_exe 0] [lindex $step_exe 1] ;
- }
-
- if { [ string equal $arg_values(-to) $step_name ] } {
- set exe 0:
- break;
- }
-
- }
-
- # for when it resumes
- set steps_as_list [dict keys $steps]
- set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
- set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
-
- if { [info exists flags_map(-save) ] } {
- if { ! [info exists arg_values(-save_path)] } {
- set arg_values(-save_path) ""
- }
- save_views -lef_path $::env(magic_result_file_tag).lef \
- -def_path $::env(CURRENT_DEF) \
- -gds_path $::env(magic_result_file_tag).gds \
- -mag_path $::env(magic_result_file_tag).mag \
- -maglef_path $::env(magic_result_file_tag).lef.mag \
- -spice_path $::env(magic_result_file_tag).spice \
- -spef_path $::env(CURRENT_SPEF) \
- -verilog_path $::env(CURRENT_NETLIST) \
- -save_path $arg_values(-save_path) \
- -tag $::env(RUN_TAG)
- }
-
-
- calc_total_runtime
- save_state
- generate_final_summary_report
-
- check_timing_violations
-
- puts_success "Flow Completed Without Fatal Errors."
-
-}
-
-run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/mpw7/config.tcl b/openlane/user_project_wrapper/mpw7/config.tcl
new file mode 100644
index 0000000..63d753a
--- /dev/null
+++ b/openlane/user_project_wrapper/mpw7/config.tcl
@@ -0,0 +1,215 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+
+# Base Configurations. Don't Touch
+# section begin
+
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+# YOU ARE NOT ALLOWED TO CHANGE ANY VARIABLES DEFINED IN THE FIXED WRAPPER CFGS
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/fixed_wrapper_cfgs.tcl
+
+
+# YOU CAN CHANGE ANY VARIABLES DEFINED IN THE DEFAULT WRAPPER CFGS BY OVERRIDING THEM IN THIS CONFIG.TCL
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/default_wrapper_cfgs.tcl
+
+
+set script_dir [file dirname [file normalize [info script]]]
+set proj_dir [file dirname [file normalize [info script]]]
+
+set ::env(DESIGN_NAME) user_project_wrapper
+set verilog_root $::env(DESIGN_DIR)/../../verilog/
+set lef_root $::env(DESIGN_DIR)/../../lef/
+set gds_root $::env(DESIGN_DIR)/../../gds/
+#section end
+
+# User Configurations
+#
+set ::env(DESIGN_IS_CORE) 1
+set ::env(FP_PDN_CORE_RING) 1
+
+
+## Source Verilog Files
+set ::env(VERILOG_FILES) "\
+ $::env(DESIGN_DIR)/../../verilog/rtl//yifive/ycr4c/src/top/ycr4_top_wb.sv \
+ $::env(DESIGN_DIR)/../../verilog/rtl/user_project_wrapper.v"
+
+
+## Clock configurations
+set ::env(CLOCK_PORT) "user_clock2 wb_clk_i"
+#set ::env(CLOCK_NET) "mprj.clk"
+
+set ::env(CLOCK_PERIOD) "10"
+
+## Internal Macros
+### Macro Placement
+set ::env(FP_SIZING) "absolute"
+set ::env(MACRO_PLACEMENT_CFG) $::env(DESIGN_DIR)/macro.cfg
+
+set ::env(PDN_CFG) $::env(DESIGN_DIR)/pdn_cfg.tcl
+
+set ::env(SDC_FILE) $::env(DESIGN_DIR)/base.sdc
+set ::env(BASE_SDC_FILE) $::env(DESIGN_DIR)/base.sdc
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+
+### Black-box verilog and views
+set ::env(VERILOG_FILES_BLACKBOX) "\
+ $::env(DESIGN_DIR)/../../verilog/gl/qspim_top.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/wb_interconnect.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/pinmux.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/uart_i2c_usb_spi_top.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/wb_host.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/ycr_intf.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/ycr_core_top.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/ycr4_iconnect.v \
+ $::env(DESIGN_DIR)/../../verilog/gl/digital_pll.v \
+ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/verilog/sky130_sram_2kbyte_1rw1r_32x512_8.v \
+ "
+
+set ::env(EXTRA_LEFS) "\
+ $lef_root/qspim_top.lef \
+ $lef_root/pinmux.lef \
+ $lef_root/wb_interconnect.lef \
+ $lef_root/uart_i2c_usb_spi_top.lef \
+ $lef_root/wb_host.lef \
+ $lef_root/ycr_intf.lef \
+ $lef_root/ycr_core_top.lef \
+ $lef_root/ycr4_iconnect.lef \
+ $lef_root/digital_pll.lef \
+ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lef/sky130_sram_2kbyte_1rw1r_32x512_8.lef \
+ "
+
+set ::env(EXTRA_GDS_FILES) "\
+ $gds_root/qspim_top.gds \
+ $gds_root/pinmux.gds \
+ $gds_root/wb_interconnect.gds \
+ $gds_root/uart_i2c_usb_spi_top.gds \
+ $gds_root/wb_host.gds \
+ $gds_root/ycr_intf.gds \
+ $gds_root/ycr_core_top.gds \
+ $gds_root/ycr4_iconnect.gds \
+ $gds_root/digital_pll.gds \
+ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/gds/sky130_sram_2kbyte_1rw1r_32x512_8.gds \
+ "
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+set ::env(VERILOG_INCLUDE_DIRS) [glob $::env(DESIGN_DIR)/../../verilog/rtl/yifive/ycr4c/src/includes ]
+
+#set ::env(GLB_RT_MAXLAYER) 6
+set ::env(RT_MAX_LAYER) {met5}
+
+set ::env(FP_PDN_CHECK_NODES) 1
+
+
+## Internal Macros
+### Macro PDN Connections
+
+set ::env(FP_PDN_ENABLE_MACROS_GRID) "1"
+#set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) "1"
+
+set ::env(VDD_NETS) {vccd1 vccd2 vdda1 vdda2}
+set ::env(GND_NETS) {vssd1 vssd2 vssa1 vssa2}
+#
+set ::env(VDD_NET) {vccd1}
+set ::env(GND_NET) {vssd1}
+
+
+set ::env(GRT_OBS) " \
+ li1 150 130 833.1 546.54,\
+ met1 150 130 833.1 546.54,\
+ met2 150 130 833.1 546.54,\
+ met3 150 130 833.1 546.54,\
+ li1 950 130 1633.1 546.54,\
+ met1 950 130 1633.1 546.54,\
+ met2 950 130 1633.1 546.54,\
+ met3 950 130 1633.1 546.54,\
+ li1 150 750 833.1 1166.54,\
+ met1 150 750 833.1 1166.54,\
+ met2 150 750 833.1 1166.54,\
+ met3 150 750 833.1 1166.54,\
+ met5 0 0 2920 3520"
+
+
+set ::env(FP_PDN_MACRO_HOOKS) " \
+ u_pll vccd1 vssd1 VPWR VGND, \
+ u_intercon vccd1 vssd1 vccd1 vssd1,\
+ u_pinmux vccd1 vssd1 vccd1 vssd1,\
+ u_qspi_master vccd1 vssd1 vccd1 vssd1,\
+ u_tsram0_2kb vccd1 vssd1 vccd1 vssd1,\
+ u_icache_2kb vccd1 vssd1 vccd1 vssd1,\
+ u_dcache_2kb vccd1 vssd1 vccd1 vssd1,\
+ u_uart_i2c_usb_spi vccd1 vssd1 vccd1 vssd1,\
+ u_wb_host vccd1 vssd1 vccd1 vssd1,\
+ u_riscv_top.i_core_top_0 vccd1 vssd1 vccd1 vssd1, \
+ u_riscv_top.i_core_top_1 vccd1 vssd1 vccd1 vssd1, \
+ u_riscv_top.i_core_top_2 vccd1 vssd1 vccd1 vssd1, \
+ u_riscv_top.i_core_top_3 vccd1 vssd1 vccd1 vssd1, \
+ u_riscv_top.u_connect vccd1 vssd1 VPWR VGND, \
+ u_riscv_top.u_intf vccd1 vssd1 vccd1 vssd1 \
+ "
+
+
+# The following is because there are no std cells in the example wrapper project.
+set ::env(SYNTH_TOP_LEVEL) 0
+set ::env(PL_RANDOM_GLB_PLACEMENT) 1
+
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 0
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 0
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) 0
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) 0
+
+set ::env(FP_PDN_ENABLE_RAILS) 0
+
+set ::env(DIODE_INSERTION_STRATEGY) 0
+set ::env(FILL_INSERTION) 0
+set ::env(TAP_DECAP_INSERTION) 0
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(QUIT_ON_LVS_ERROR) "1"
+set ::env(QUIT_ON_MAGIC_DRC) "0"
+set ::env(QUIT_ON_NEGATIVE_WNS) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+
+set ::env(FP_PDN_IRDROP) "1"
+set ::env(FP_PDN_HORIZONTAL_HALO) "10"
+set ::env(FP_PDN_VERTICAL_HALO) "10"
+
+#
+
+set ::env(FP_PDN_CORE_RING_HOFFSET) {12.45}
+set ::env(FP_PDN_CORE_RING_HSPACING) {1.7}
+set ::env(FP_PDN_CORE_RING_HWIDTH) {3.1}
+
+set ::env(FP_PDN_CORE_RING_VOFFSET) {12.45}
+set ::env(FP_PDN_CORE_RING_VSPACING) {1.7}
+set ::env(FP_PDN_CORE_RING_VWIDTH) {3.1}
+
+
+set ::env(FP_PDN_VOFFSET) "5"
+set ::env(FP_PDN_VPITCH) "80"
+set ::env(FP_PDN_VSPACING) "15.5"
+set ::env(FP_PDN_VWIDTH) "3.1"
+
+set ::env(FP_PDN_HOFFSET) "10"
+set ::env(FP_PDN_HPITCH) "90"
+set ::env(FP_PDN_HSPACING) "10"
+set ::env(FP_PDN_HWIDTH) "3.1"
+
+
+
diff --git a/openlane/user_project_wrapper/mpw7/interactive.tcl b/openlane/user_project_wrapper/mpw7/interactive.tcl
new file mode 100644
index 0000000..9bb77dc
--- /dev/null
+++ b/openlane/user_project_wrapper/mpw7/interactive.tcl
@@ -0,0 +1,399 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+
+package require openlane;
+
+
+proc gen_pdn {args} {
+ increment_index
+ TIMER::timer_start
+ puts_info "Generating PDN..."
+
+ set ::env(SAVE_DEF) [index_file $::env(floorplan_tmpfiles)/pdn.def]
+ set ::env(PGA_RPT_FILE) [index_file $::env(floorplan_tmpfiles)/pdn.pga.rpt]
+
+ if { ! [info exists ::env(VDD_NET)] } {
+ set ::env(VDD_NET) $::env(VDD_PIN)
+ }
+
+ if { ! [info exists ::env(GND_NET)] } {
+ set ::env(GND_NET) $::env(GND_PIN)
+ }
+
+ run_openroad_script $::env(DESIGN_DIR)/pdn.tcl \
+ |& -indexed_log [index_file $::env(floorplan_logs)/pdn.log]
+
+
+ TIMER::timer_stop
+ exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "pdn generation - openroad"
+
+ quit_on_unconnected_pdn_nodes
+
+ set_def $::env(SAVE_DEF)
+}
+
+proc run_power_grid_generation {args} {
+ if { [info exists ::env(VDD_NETS)] || [info exists ::env(GND_NETS)] } {
+ # they both must exist and be equal in length
+ # current assumption: they cannot have a common ground
+ if { ! [info exists ::env(VDD_NETS)] || ! [info exists ::env(GND_NETS)] } {
+ puts_err "VDD_NETS and GND_NETS must *both* either be defined or undefined"
+ return -code error
+ }
+ # standard cell power and ground nets are assumed to be the first net
+ set ::env(VDD_PIN) [lindex $::env(VDD_NETS) 0]
+ set ::env(GND_PIN) [lindex $::env(GND_NETS) 0]
+ } elseif { [info exists ::env(SYNTH_USE_PG_PINS_DEFINES)] } {
+ set ::env(VDD_NETS) [list]
+ set ::env(GND_NETS) [list]
+ # get the pins that are in $synthesis_tmpfiles.pg_define.v
+ # that are not in $synthesis_results.v
+ #
+ set full_pins {*}[extract_pins_from_yosys_netlist $::env(synthesis_tmpfiles)/pg_define.v]
+ puts_info $full_pins
+
+ set non_pg_pins {*}[extract_pins_from_yosys_netlist $::env(synthesis_results)/$::env(DESIGN_NAME).v]
+ puts_info $non_pg_pins
+
+ # assumes the pins are ordered correctly (e.g., vdd1, vss1, vcc1, vss1, ...)
+ foreach {vdd gnd} $full_pins {
+ if { $vdd ne "" && $vdd ni $non_pg_pins } {
+ lappend ::env(VDD_NETS) $vdd
+ }
+ if { $gnd ne "" && $gnd ni $non_pg_pins } {
+ lappend ::env(GND_NETS) $gnd
+ }
+ }
+ } else {
+ set ::env(VDD_NETS) $::env(VDD_PIN)
+ set ::env(GND_NETS) $::env(GND_PIN)
+ }
+
+ puts_info "Power planning with power {$::env(VDD_NETS)} and ground {$::env(GND_NETS)}..."
+
+ if { [llength $::env(VDD_NETS)] != [llength $::env(GND_NETS)] } {
+ puts_err "VDD_NETS and GND_NETS must be of equal lengths"
+ return -code error
+ }
+
+ gen_pdn
+}
+
+proc run_floorplan {args} {
+ # |----------------------------------------------------|
+ # |---------------- 2. FLOORPLAN ------------------|
+ # |----------------------------------------------------|
+ #
+ # intial fp
+ init_floorplan
+
+ # check for deprecated io variables
+ if { [info exists ::env(FP_IO_HMETAL)]} {
+ set ::env(FP_IO_HLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_HMETAL) - 1}]]
+ puts_warn "You're using FP_IO_HMETAL in your configuration, which is a deprecated variable that will be removed in the future."
+ puts_warn "We recommend you update your configuration as follows:"
+ puts_warn "\tset ::env(FP_IO_HLAYER) {$::env(FP_IO_HLAYER)}"
+ }
+
+ if { [info exists ::env(FP_IO_VMETAL)]} {
+ set ::env(FP_IO_VLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_VMETAL) - 1}]]
+ puts_warn "You're using FP_IO_VMETAL in your configuration, which is a deprecated variable that will be removed in the future."
+ puts_warn "We recommend you update your configuration as follows:"
+ puts_warn "\tset ::env(FP_IO_VLAYER) {$::env(FP_IO_VLAYER)}"
+ }
+
+
+ # place io
+ if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
+ place_io_ol
+ } else {
+ if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
+ place_io
+ global_placement_or
+ place_contextualized_io \
+ -lef $::env(FP_CONTEXT_LEF) \
+ -def $::env(FP_CONTEXT_DEF)
+ } else {
+ place_io
+ }
+ }
+
+ apply_def_template
+
+ if { [info exist ::env(EXTRA_LEFS)] } {
+ if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
+ file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(placement_tmpfiles)/macro_placement.cfg
+ manual_macro_placement -f
+ } else {
+ global_placement_or
+ basic_macro_placement
+ }
+ }
+
+ tap_decap_or
+
+ scrot_klayout -layout $::env(CURRENT_DEF) -log $::env(floorplan_logs)/screenshot.log
+
+ run_power_grid_generation
+}
+
+proc run_placement_step {args} {
+ if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+ set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+ }
+
+ run_placement
+}
+
+proc run_cts_step {args} {
+ if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+ set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+ }
+
+ run_cts
+ run_resizer_timing
+}
+
+proc run_routing_step {args} {
+ if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+ set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+ }
+ if { $::env(ECO_ENABLE) == 0 } {
+ run_routing
+ }
+}
+
+proc run_parasitics_sta_step {args} {
+ if { ! [ info exists ::env(PARSITICS_CURRENT_DEF) ] } {
+ set ::env(PARSITICS_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(PARSITICS_CURRENT_DEF)
+ }
+
+ if { $::env(RUN_SPEF_EXTRACTION) && ($::env(ECO_ENABLE) == 0)} {
+ run_parasitics_sta
+ }
+}
+
+proc run_diode_insertion_2_5_step {args} {
+ if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+ set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+ }
+ if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+ run_antenna_check
+ heal_antenna_violators; # modifies the routed DEF
+ }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+ if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+ set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+ }
+
+ if { $lvs_enabled && $::env(RUN_LVS) } {
+ run_magic_spice_export;
+ run_lvs; # requires run_magic_spice_export
+ }
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+ if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+ set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+ }
+ if { $drc_enabled } {
+ if { $::env(RUN_MAGIC_DRC) } {
+ run_magic_drc
+ }
+ if {$::env(RUN_KLAYOUT_DRC)} {
+ run_klayout_drc
+ }
+ }
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+ if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+ set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+ } else {
+ set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+ }
+ if { $antenna_check_enabled } {
+ run_antenna_check
+ }
+}
+
+proc run_eco_step {args} {
+ if { $::env(ECO_ENABLE) == 1 } {
+ run_eco_flow
+ }
+}
+
+proc run_magic_step {args} {
+ if {$::env(RUN_MAGIC)} {
+ run_magic
+ }
+}
+
+proc run_klayout_step {args} {
+ if {$::env(RUN_KLAYOUT)} {
+ run_klayout
+ }
+ if {$::env(RUN_KLAYOUT_XOR)} {
+ run_klayout_gds_xor
+ }
+}
+
+proc run_post_run_hooks {} {
+ if { [file exists $::env(DESIGN_DIR)/hooks/post_run.py]} {
+ puts_info "Running post run hook"
+ set result [exec $::env(OPENROAD_BIN) -python $::env(DESIGN_DIR)/hooks/post_run.py]
+ puts_info "$result"
+ } else {
+ puts_info "hooks/post_run.py not found, skipping"
+ }
+}
+
+proc run_flow {args} {
+ set options {
+ {-design optional}
+ {-from optional}
+ {-to optional}
+ {-save_path optional}
+ {-override_env optional}
+ }
+ set flags {-save -run_hooks -no_lvs -no_drc -no_antennacheck -gui}
+ parse_key_args "run_non_interactive_mode" args arg_values $options flags_map $flags -no_consume
+
+ prep {*}$args
+ # signal trap SIGINT save_state;
+
+ if { [info exists flags_map(-gui)] } {
+ or_gui
+ return
+ }
+ if { [info exists arg_values(-override_env)] } {
+ load_overrides $arg_values(-override_env)
+ }
+
+ set LVS_ENABLED 1
+ set DRC_ENABLED 0
+
+ set ANTENNACHECK_ENABLED [expr ![info exists flags_map(-no_antennacheck)] ]
+
+ set steps [dict create \
+ "synthesis" "run_synthesis" \
+ "floorplan" "run_floorplan" \
+ "placement" "run_placement_step" \
+ "cts" "run_cts_step" \
+ "routing" "run_routing_step" \
+ "parasitics_sta" "run_parasitics_sta_step" \
+ "eco" "run_eco_step" \
+ "diode_insertion" "run_diode_insertion_2_5_step" \
+ "gds_magic" "run_magic_step" \
+ "gds_klayout" "run_klayout_step" \
+ "lvs" "run_lvs_step $LVS_ENABLED " \
+ "drc" "run_drc_step $DRC_ENABLED " \
+ "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED " \
+ "cvc" "run_lef_cvc"
+ ]
+
+ if { [info exists arg_values(-from) ]} {
+ puts_info "Starting flow at $arg_values(-from)..."
+ set ::env(CURRENT_STEP) $arg_values(-from)
+ } elseif { [info exists ::env(CURRENT_STEP) ] } {
+ puts_info "Resuming flow from $::env(CURRENT_STEP)..."
+ } else {
+ set ::env(CURRENT_STEP) "synthesis"
+ }
+
+ set_if_unset arg_values(-from) $::env(CURRENT_STEP)
+ set_if_unset arg_values(-to) "cvc"
+
+ set exe 0;
+ dict for {step_name step_exe} $steps {
+ if { [ string equal $arg_values(-from) $step_name ] } {
+ set exe 1;
+ }
+
+ if { $exe } {
+ # For when it fails
+ set ::env(CURRENT_STEP) $step_name
+ [lindex $step_exe 0] [lindex $step_exe 1] ;
+ }
+
+ if { [ string equal $arg_values(-to) $step_name ] } {
+ set exe 0:
+ break;
+ }
+
+ }
+
+ # for when it resumes
+ set steps_as_list [dict keys $steps]
+ set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+ set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+ # Saves to <RUN_DIR>/results/final
+ save_final_views
+
+ # Saves to design directory or custom
+ if { [info exists flags_map(-save) ] } {
+ if { ! [info exists arg_values(-save_path)] } {
+ set arg_values(-save_path) $::env(DESIGN_DIR)
+ }
+ save_final_views\
+ -save_path $arg_values(-save_path)\
+ -tag $::env(RUN_TAG)
+ }
+ calc_total_runtime
+ save_state
+ generate_final_summary_report
+
+ check_timing_violations
+
+ if { [info exists arg_values(-save_path)]\
+ && $arg_values(-save_path) != "" } {
+ set ::env(HOOK_OUTPUT_PATH) "[file normalize $arg_values(-save_path)]"
+ } else {
+ set ::env(HOOK_OUTPUT_PATH) $::env(RESULTS_DIR)/final
+ }
+
+ if {[info exists flags_map(-run_hooks)]} {
+ run_post_run_hooks
+ }
+
+ puts_success "Flow complete."
+
+ show_warnings "Note that the following warnings have been generated:"
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/mpw7/pdn.tcl b/openlane/user_project_wrapper/mpw7/pdn.tcl
new file mode 100644
index 0000000..5c94f2d
--- /dev/null
+++ b/openlane/user_project_wrapper/mpw7/pdn.tcl
@@ -0,0 +1,60 @@
+# Copyright 2020-2021 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+foreach lib $::env(LIB_SYNTH_COMPLETE) {
+ read_liberty $lib
+}
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+ foreach lib $::env(EXTRA_LIBS) {
+ read_liberty $lib
+ }
+}
+# Since Current MPW does not handle Macro with Met5 routing, we are hacking the pll
+# macro and removing met5 details - temporarly only for pdn stage
+if {[catch {read_lef $::env(MERGED_LEF)} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+}
+
+if {[catch {read_def $::env(CURRENT_DEF)} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+}
+
+# load the grid definitions
+if {[catch {source $::env(PDN_CFG)} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+}
+
+# run PDNGEN
+if {[catch {pdngen} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+}
+
+# checks for unconnected nodes (e.g., isolated rails or stripes)
+if { $::env(FP_PDN_CHECK_NODES) } {
+ check_power_grid -net $::env(VDD_NET)
+ check_power_grid -net $::env(GND_NET)
+}
+
+if { $::env(FP_PDN_IRDROP) } {
+ # set rc values
+ source $::env(SCRIPTS_DIR)/openroad/set_rc.tcl
+ analyze_power_grid -net $::env(VDD_NET) -outfile $::env(PGA_RPT_FILE)
+}
+
+write_def $::env(SAVE_DEF)
diff --git a/openlane/user_project_wrapper/mpw7/pdn_cfg.tcl b/openlane/user_project_wrapper/mpw7/pdn_cfg.tcl
new file mode 100644
index 0000000..784d843
--- /dev/null
+++ b/openlane/user_project_wrapper/mpw7/pdn_cfg.tcl
@@ -0,0 +1,161 @@
+# Power nets
+if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } {
+ if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } {
+ foreach power_pin $::env(STD_CELL_POWER_PINS) {
+ add_global_connection \
+ -net $::env(VDD_NET) \
+ -inst_pattern .* \
+ -pin_pattern $power_pin \
+ -power
+ }
+ foreach ground_pin $::env(STD_CELL_GROUND_PINS) {
+ add_global_connection \
+ -net $::env(GND_NET) \
+ -inst_pattern .* \
+ -pin_pattern $ground_pin \
+ -ground
+ }
+ }
+}
+
+if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 &&
+ [info exists ::env(FP_PDN_MACRO_HOOKS)]} {
+ set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
+ foreach pdn_hook $pdn_hooks {
+ set instance_name [lindex $pdn_hook 0]
+ set power_net [lindex $pdn_hook 1]
+ set ground_net [lindex $pdn_hook 2]
+ set power_pin [lindex $pdn_hook 3]
+ set ground_pin [lindex $pdn_hook 4]
+
+ if { $power_pin == "" || $ground_pin == "" } {
+ puts "FP_PDN_MACRO_HOOKS missing power and ground pin names"
+ exit -1
+ }
+
+ add_global_connection \
+ -net $power_net \
+ -inst_pattern $instance_name \
+ -pin_pattern $power_pin \
+ -power
+
+ add_global_connection \
+ -net $ground_net \
+ -inst_pattern $instance_name \
+ -pin_pattern $ground_pin \
+ -ground
+ }
+}
+
+set secondary []
+
+foreach vdd $::env(VDD_NETS) gnd $::env(GND_NETS) {
+ if { $vdd != $::env(VDD_NET)} {
+ lappend secondary $vdd
+
+ set db_net [[ord::get_db_block] findNet $vdd]
+ if {$db_net == "NULL"} {
+ set net [odb::dbNet_create [ord::get_db_block] $vdd]
+ $net setSpecial
+ $net setSigType "POWER"
+ }
+ }
+
+ if { $gnd != $::env(GND_NET)} {
+ lappend secondary $gnd
+
+ set db_net [[ord::get_db_block] findNet $gnd]
+ if {$db_net == "NULL"} {
+ set net [odb::dbNet_create [ord::get_db_block] $gnd]
+ $net setSpecial
+ $net setSigType "GROUND"
+ }
+ }
+}
+
+set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET) \
+ -secondary_power $secondary
+
+# Assesses whether the design is the core of the chip or not based on the
+# value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section
+if { $::env(DESIGN_IS_CORE) == 1 } {
+ # Used if the design is the core of the chip
+ define_pdn_grid \
+ -name stdcell_grid \
+ -starts_with POWER \
+ -voltage_domain CORE \
+ -pins "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)"
+
+ add_pdn_stripe \
+ -grid stdcell_grid \
+ -layer $::env(FP_PDN_LOWER_LAYER) \
+ -width $::env(FP_PDN_VWIDTH) \
+ -pitch $::env(FP_PDN_VPITCH) \
+ -offset $::env(FP_PDN_VOFFSET) \
+ -nets "$::env(VDD_NET) $::env(GND_NET)" \
+ -starts_with POWER -extend_to_core_ring
+
+ add_pdn_stripe \
+ -grid stdcell_grid \
+ -layer $::env(FP_PDN_UPPER_LAYER) \
+ -width $::env(FP_PDN_HWIDTH) \
+ -pitch $::env(FP_PDN_HPITCH) \
+ -offset $::env(FP_PDN_HOFFSET) \
+ -nets "$::env(VDD_NET) $::env(GND_NET)" \
+ -starts_with POWER -extend_to_core_ring
+
+ add_pdn_connect \
+ -grid stdcell_grid \
+ -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)"
+} else {
+ # Used if the design is a macro in the core
+ define_pdn_grid \
+ -name stdcell_grid \
+ -starts_with POWER \
+ -voltage_domain CORE \
+ -pins $::env(FP_PDN_LOWER_LAYER)
+
+ add_pdn_stripe \
+ -grid stdcell_grid \
+ -layer $::env(FP_PDN_LOWER_LAYER) \
+ -width $::env(FP_PDN_VWIDTH) \
+ -pitch $::env(FP_PDN_VPITCH) \
+ -offset $::env(FP_PDN_VOFFSET) \
+ -starts_with POWER
+}
+
+# Adds the standard cell rails if enabled.
+if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
+ add_pdn_stripe \
+ -grid stdcell_grid \
+ -layer $::env(FP_PDN_RAILS_LAYER) \
+ -width $::env(FP_PDN_RAIL_WIDTH) \
+ -followpins \
+ -starts_with POWER
+
+ add_pdn_connect \
+ -grid stdcell_grid \
+ -layers "$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)"
+}
+
+
+# Adds the core ring if enabled.
+if { $::env(FP_PDN_CORE_RING) == 1 } {
+ add_pdn_ring \
+ -grid stdcell_grid \
+ -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" \
+ -widths "$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)" \
+ -spacings "$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)" \
+ -core_offset "$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)"
+}
+
+define_pdn_grid \
+ -macro \
+ -default \
+ -name macro \
+ -starts_with POWER \
+ -halo "$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)"
+
+add_pdn_connect \
+ -grid macro \
+ -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)"
diff --git a/verilog/dv/c_func/inc/user_reg_map.h b/verilog/dv/c_func/inc/user_reg_map.h
deleted file mode 100644
index 4508fb2..0000000
--- a/verilog/dv/c_func/inc/user_reg_map.h
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-//-------------------------------------
-// PinMux Register
-// ------------------------------------
-#define reg_pinmux_chip_id (*(volatile uint32_t*)0x30020000) // reg_0 - Chip ID
-#define reg_pinmux_gbl_cfg0 (*(volatile uint32_t*)0x30020004) // reg_1 - Global Config-2
-#define reg_pinmux_gbl_cfg1 (*(volatile uint32_t*)0x30020008) // reg_2 - Global Config-1
-#define reg_pinmux_gbl_intr_msk (*(volatile uint32_t*)0x3002000C) // reg_3 - Global Interrupt Mask
-#define reg_pinmux_gbl_intr (*(volatile uint32_t*)0x30020010) // reg_4 - Global Interrupt
-#define reg_pinmux_gpio_idata (*(volatile uint32_t*)0x30020014) // reg_5 - GPIO Data In
-#define reg_pinmux_gpio_odata (*(volatile uint32_t*)0x30020018) // reg_6 - GPIO Data Out
-#define reg_pinmux_gpio_dsel (*(volatile uint32_t*)0x3002001C) // reg_7 - GPIO Direction Select
-#define reg_pinmux_gpio_type (*(volatile uint32_t*)0x30020020) // reg_8 - GPIO TYPE - Static/Waveform
-#define reg_pinmux_gpio_intr_stat (*(volatile uint32_t*)0x30020024) // reg_9 - GPIO Interrupt status
-#define reg_pinmux_gpio_intr_clr (*(volatile uint32_t*)0x30020024) // reg_9 - GPIO Interrupt Clear
-#define reg_pinmux_gpio_intr_set (*(volatile uint32_t*)0x30020028) // reg_10 - GPIO Interrupt Set
-#define reg_pinmux_gpio_intr_mask (*(volatile uint32_t*)0x3002002C) // reg_11 - GPIO Interrupt Mask
-#define reg_pinmux_gpio_pos_intr (*(volatile uint32_t*)0x30020030) // reg_12 - GPIO Posedge Interrupt
-#define reg_pinmux_gpio_neg_intr (*(volatile uint32_t*)0x30020034) // reg_13 - GPIO Neg Interrupt
-#define reg_pinmux_gpio_multi_func (*(volatile uint32_t*)0x30020038) // reg_14 - GPIO Multi Function
-#define reg_pinmux_soft_reg_0 (*(volatile uint32_t*)0x3002003C) // reg_15 - Soft Register
-#define reg_pinmux_cfg_pwm0 (*(volatile uint32_t*)0x30020040) // reg_16 - PWM Reg-0
-#define reg_pinmux_cfg_pwm1 (*(volatile uint32_t*)0x30020044) // reg_17 - PWM Reg-1
-#define reg_pinmux_cfg_pwm2 (*(volatile uint32_t*)0x30020048) // reg_18 - PWM Reg-2
-#define reg_pinmux_cfg_pwm3 (*(volatile uint32_t*)0x3002004C) // reg_19 - PWM Reg-3
-#define reg_pinmux_cfg_pwm4 (*(volatile uint32_t*)0x30020050) // reg_20 - PWM Reg-4
-#define reg_pinmux_cfg_pwm5 (*(volatile uint32_t*)0x30020054) // reg_21 - PWM Reg-5
-#define reg_pinmux_soft_reg_1 (*(volatile uint32_t*)0x30020058) // reg_22 - Sof Register
-#define reg_pinmux_soft_reg_2 (*(volatile uint32_t*)0x3002005C) // reg_23 - Sof Register
-#define reg_pinmux_soft_reg_3 (*(volatile uint32_t*)0x30020060) // reg_24 - Sof Register
-#define reg_pinmux_soft_reg_4 (*(volatile uint32_t*)0x30020064) // reg_25 - Sof Register
-#define reg_pinmux_soft_reg_5 (*(volatile uint32_t*)0x30020068) // reg_26 - Sof Register
-#define reg_pinmux_soft_reg_6 (*(volatile uint32_t*)0x3002006C) // reg_27 - Sof Register
-#define reg_pinmux_cfg_timer0 (*(volatile uint32_t*)0x30020070) // reg_28 - Timer-0
-#define reg_pinmux_cfg_timer1 (*(volatile uint32_t*)0x30020074) // reg_28 - Timer-1
-#define reg_pinmux_cfg_timer2 (*(volatile uint32_t*)0x30020078) // reg_28 - Timer-2
-
diff --git a/verilog/dv/user_mcore/Makefile b/verilog/dv/user_mcore/Makefile
deleted file mode 100644
index f635413..0000000
--- a/verilog/dv/user_mcore/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# SPDX-FileCopyrightText: 2020 Efabless Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# SPDX-License-Identifier: Apache-2.0
-
-
-# ---- Include Partitioned Makefiles ----
-
-CONFIG = caravel_user_project
-
-#######################################################################
-## Caravel Verilog for Integration Tests
-#######################################################################
-
-DESIGNS?=../../..
-TOOLS?=/opt/riscv32i/
-
-export USER_PROJECT_VERILOG ?= $(DESIGNS)/verilog
-## YIFIVE FIRMWARE
-YIFIVE_FIRMWARE_PATH = $(USER_PROJECT_VERILOG)/dv/firmware
-GCC_PREFIX?=riscv32-unknown-elf
-
-
-## Simulation mode: RTL/GL
-SIM?=RTL
-DUMP?=OFF
-RISC_CORE?=15
-
-### To Enable IVERILOG FST DUMP
-export IVERILOG_DUMPER = fst
-
-
-.SUFFIXES:
-
-PATTERN = user_mcore
-
-all: ${PATTERN:=.vcd}
-
-
-vvp: ${PATTERN:=.vvp}
-
-%.vvp: %_tb.v
- ${GCC_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -c -I./ -I$(YIFIVE_FIRMWARE_PATH) user_mcore.c -o user_mcore.o
- ${GCC_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -c -I./ -I$(YIFIVE_FIRMWARE_PATH) $(YIFIVE_FIRMWARE_PATH)/common_bthread.c -o common_bthread.o
- ${GCC_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -D__ASSEMBLY__=1 -c -I./ -I$(YIFIVE_FIRMWARE_PATH) $(YIFIVE_FIRMWARE_PATH)/crt.S -o crt.o
- ${GCC_PREFIX}-gcc -o user_mcore.elf -T $(YIFIVE_FIRMWARE_PATH)/link.ld user_mcore.o crt.o common_bthread.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32 -N
- ${GCC_PREFIX}-objcopy -O verilog user_mcore.elf user_mcore.hex
- ${GCC_PREFIX}-objdump -D user_mcore.elf > user_mcore.dump
- rm crt.o user_mcore.o
-ifeq ($(SIM),RTL)
- ifeq ($(DUMP),OFF)
- iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib \
- $< -o $@
- else
- iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib \
- $< -o $@
- endif
-else
- ifeq ($(DUMP),OFF)
- iverilog -g2012 -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
- $< -o $@
- else
- iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
- -f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
- $< -o $@
- endif
-endif
-
-%.vcd: %.vvp
- vvp $< +risc_core_id=$(RISC_CORE)
-
-
-# ---- Clean ----
-
-clean:
- rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.o *.dump
-
-.PHONY: clean hex all
diff --git a/verilog/dv/user_mcore/user_mcore.c b/verilog/dv/user_mcore/user_mcore.c
deleted file mode 100644
index dc1899d..0000000
--- a/verilog/dv/user_mcore/user_mcore.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2020 Efabless Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-
-#include "common_misc.h"
-#include "common_bthread.h"
-
-#define SC_SIM_OUTPORT (0xf0000000)
-#define uint32_t long
-#define uint16_t int
-#define size 10
-
-#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x10020000)
-#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x10020004)
-#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x10020008)
-#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x1002000C)
-#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x10020010)
-#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x10020014)
-#define reg_mprj_globl_reg6 (*(volatile uint32_t*)0x10020018)
-#define reg_mprj_globl_reg7 (*(volatile uint32_t*)0x1002001C)
-#define reg_mprj_globl_reg8 (*(volatile uint32_t*)0x10020020)
-#define reg_mprj_globl_reg9 (*(volatile uint32_t*)0x10020024)
-#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x10020028)
-#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x1002002C)
-#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x10020030)
-#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x10020034)
-#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x10020038)
-#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x1002003C)
-#define reg_mprj_globl_reg16 (*(volatile uint32_t*)0x10020040)
-#define reg_mprj_globl_reg17 (*(volatile uint32_t*)0x10020044)
-#define reg_mprj_globl_reg18 (*(volatile uint32_t*)0x10020048)
-#define reg_mprj_globl_reg19 (*(volatile uint32_t*)0x1002004C)
-#define reg_mprj_globl_reg20 (*(volatile uint32_t*)0x10020050)
-#define reg_mprj_globl_reg21 (*(volatile uint32_t*)0x10020054)
-#define reg_mprj_globl_reg22 (*(volatile uint32_t*)0x10020058)
-#define reg_mprj_globl_reg23 (*(volatile uint32_t*)0x1002005C)
-#define reg_mprj_globl_reg24 (*(volatile uint32_t*)0x10020060)
-#define reg_mprj_globl_reg25 (*(volatile uint32_t*)0x10020064)
-#define reg_mprj_globl_reg26 (*(volatile uint32_t*)0x10020068)
-#define reg_mprj_globl_reg27 (*(volatile uint32_t*)0x1002006C)
-// -------------------------------------------------------------------------
-// Multi-core test, Two Array is filled with below data, destination hold sum
-// source result remark
-// src0 src1 dest
-// 0x0000 0x00000000 0x00000000 updated by core-0
-// 0x1111 0x11110000 0x11111111 updated by core-0
-// 0x2222 0x22220000 0x22222222 updated by core-0
-// 0x3333 0x33330000 0x33333333 updated by core-0
-// 0x4444 0x44440000 0x44444444 updated by core-1
-// 0x5555 0x55550000 0x55555555 updated by core-1
-// 0x6666 0x66660000 0x66666666 updated by core-1
-// 0x7777 0x77770000 0x77777777 updated by core-1
-//
-// 0x8888 0x88880000 0x88888888 updated by core-2
-// 0x9999 0x99990000 0x99999999 updated by core-2
-// 0xAAAA 0xAAAA0000 0xAAAAAAAA updated by core-2
-// 0xBBBB 0xBBBB0000 0xBBBBBBBB updated by core-2
-// 0xCCCC 0xCCCC0000 0xCCCCCCCC updated by core-3
-// 0xDDDD 0xDDDD0000 0xDDDDDDDD updated by core-3
-// 0xEEEE 0xEEEE0000 0xEEEEEEEE updated by core-3
-// 0xFFFF 0xFFFF0000 0xFFFFFFFF updated by core-3
-//
-// -------------------------------------------------------------------------
-
-typedef struct {
- int* dest; // pointer to dest array
- int* src0; // pointer to src0 array
- int* src1; // pointer to src1 array
- int begin; // first element this core should process
- int end; // (one past) last element this core should process
-} arg_t;
-
-
-void vvadd_mt(void* arg_vptr )
- {
-
- // Cast void* to argument pointer.
- arg_t* arg_ptr = (arg_t*) arg_vptr;
- // Create local variables for each field of the argument structure.
- int* dest = arg_ptr->dest;
- int* src0 = arg_ptr->src0;
- int* src1 = arg_ptr->src1;
- int begin = arg_ptr->begin;
- int end = arg_ptr->end;
-
- // Do the actual work.
- for ( int i = begin; i < end; i++ ) {
- dest[i] = src0[i] + src1[i];
- }
-
- }
-
- #define buf_size 16
-
- int main( int argc, char* argv[] )
- {
-
- int dest[buf_size];
- int src0[buf_size];
- int src1[buf_size];
- char test_pass = 0x1;
-
- for ( int i = 0; i < buf_size; i++ ) {
- src0[i] = 0x1111 * (i);
- src1[i] = 0x11110000 * (i);
- }
-
- // Create two argument structures that include the array pointers and
- // what elements each core should process.
- arg_t arg0 = { dest, src0, src1, 0, buf_size/4 };
- arg_t arg1 = { dest, src0, src1, buf_size/4, buf_size/2 };
- arg_t arg2 = { dest, src0, src1, buf_size/2, (3*buf_size)/4 };
- arg_t arg3 = { dest, src0, src1, (3*buf_size)/4, buf_size };
-
- reg_mprj_globl_reg22 = 0x11223344; // Sig-1
- // Initialize bare threads (bthread).
- bthread_init();
-
-
- reg_mprj_globl_reg23 = 0x22334455; // Sig-2
- // Start counting stats.
- //test_stats_on();
-
-
- // Spawn work onto core 1
- bthread_spawn( 1, &vvadd_mt, &arg1 );
- bthread_spawn( 2, &vvadd_mt, &arg2 );
- bthread_spawn( 3, &vvadd_mt, &arg3 );
-
- reg_mprj_globl_reg24 = 0x33445566; // Sig-3
- // Have core 0 also do some work.
- vvadd_mt(&arg0);
-
- reg_mprj_globl_reg25 = 0x44556677; // Sig-4
- // Wait for core 1 to finish.
- bthread_join(1);
- bthread_join(2);
- bthread_join(3);
-
-
- // Stop counting stats
- //test_stats_off();
- reg_mprj_globl_reg26 = 0x55667788; // sig-5
-
- // Core 0 will verify the results.
- if ( bthread_get_core_id() == 0 ) {
-
- // Check the Expected Data
- for ( int i = 0; i < buf_size; i++ ) {
- if(dest[i] != (src0[i] + src1[i]))
- test_pass &= 0;
- }
- if(test_pass == 0x1) {
- reg_mprj_globl_reg27 = 0x66778899; // sig-6
- }
-
- }
-
- return 0;
- }
-
-
diff --git a/verilog/dv/user_mcore/user_mcore_tb.v b/verilog/dv/user_mcore/user_mcore_tb.v
deleted file mode 100644
index a8f746b..0000000
--- a/verilog/dv/user_mcore/user_mcore_tb.v
+++ /dev/null
@@ -1,410 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Standalone User validation Test bench ////
-//// ////
-//// This file is part of the riscduino cores project ////
-//// ////
-//// Description ////
-//// This is a standalone test bench to validate the ////
-//// Digital core multi-core behaviour. ////
-//// ////
-//// To Do: ////
-//// nothing ////
-//// ////
-//// Author(s): ////
-//// - Dinesh Annayya, dinesha@opencores.org ////
-//// ////
-//// Revision : ////
-//// 0.1 - 16th Feb 2021, Dinesh A ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source is distributed in the hope that it will be ////
-//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
-//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
-//// PURPOSE. See the GNU Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-
-`default_nettype wire
-
-`timescale 1 ns / 1 ns
-
-`include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
-module user_mcore_tb;
- reg clock;
- reg wb_rst_i;
- reg power1, power2;
- reg power3, power4;
-
- reg wbd_ext_cyc_i; // strobe/request
- reg wbd_ext_stb_i; // strobe/request
- reg [31:0] wbd_ext_adr_i; // address
- reg wbd_ext_we_i; // write
- reg [31:0] wbd_ext_dat_i; // data output
- reg [3:0] wbd_ext_sel_i; // byte enable
-
- wire [31:0] wbd_ext_dat_o; // data input
- wire wbd_ext_ack_o; // acknowlegement
- wire wbd_ext_err_o; // error
-
- // User I/O
- wire [37:0] io_oeb;
- wire [37:0] io_out;
- wire [37:0] io_in;
-
- wire gpio;
- wire [37:0] mprj_io;
- wire [7:0] mprj_io_0;
- reg test_fail;
- reg [31:0] read_data;
- integer d_risc_id;
-
-
-
- // External clock is used by default. Make this artificially fast for the
- // simulation. Normally this would be a slow clock and the digital PLL
- // would be the fast clock.
-
- always #12.5 clock <= (clock === 1'b0);
-
- initial begin
- clock = 0;
- wbd_ext_cyc_i ='h0; // strobe/request
- wbd_ext_stb_i ='h0; // strobe/request
- wbd_ext_adr_i ='h0; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='h0; // data output
- wbd_ext_sel_i ='h0; // byte enable
- end
-
- `ifdef WFDUMP
- initial begin
- $dumpfile("simx.vcd");
- $dumpvars(1, user_mcore_tb);
- $dumpvars(1, user_mcore_tb.u_top);
- $dumpvars(0, user_mcore_tb.u_top.u_riscv_top);
- end
- `endif
-
- initial begin
-
- $value$plusargs("risc_core_id=%d", d_risc_id);
-
- #200; // Wait for reset removal
- repeat (10) @(posedge clock);
- $display("Monitor: Standalone User Risc Boot Test Started");
-
- // Remove Wb Reset
- wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1);
-
- repeat (2) @(posedge clock);
- #1;
- // Remove all the reset
- $display("STATUS: Working with Both core Risc core 0/1/2/3 ");
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_CFG0,'hF1F);
-
-
- // Repeat cycles of 1000 clock edges as needed to complete testbench
- repeat (26) begin
- repeat (1000) @(posedge clock);
- // $display("+1000 cycles");
- end
-
-
- $display("Monitor: Reading Back the expected value");
- // User RISC core expect to write these value in global
- // register, read back and decide on pass fail
- // 0x30000018 = 0x11223344;
- // 0x3000001C = 0x22334455;
- // 0x30000020 = 0x33445566;
- // 0x30000024 = 0x44556677;
- // 0x30000028 = 0x55667788;
- // 0x3000002C = 0x66778899;
-
- test_fail = 0;
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_1,read_data,32'h11223344);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_2,read_data,32'h22334455);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_3,read_data,32'h33445566);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_4,read_data,32'h44556677);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_5,read_data,32'h55667788);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_6,read_data,32'h66778899);
-
-
-
- $display("###################################################");
- if(test_fail == 0) begin
- `ifdef GL
- $display("Monitor: Standalone User Risc Boot (GL) Passed");
- `else
- $display("Monitor: Standalone User Risc Boot (RTL) Passed");
- `endif
- end else begin
- `ifdef GL
- $display("Monitor: Standalone User Risc Boot (GL) Failed");
- `else
- $display("Monitor: Standalone User Risc Boot (RTL) Failed");
- `endif
- end
- $display("###################################################");
- $finish;
- end
-
- initial begin
- wb_rst_i <= 1'b1;
- #100;
- wb_rst_i <= 1'b0; // Release reset
- end
-wire USER_VDD1V8 = 1'b1;
-wire VSS = 1'b0;
-
-user_project_wrapper u_top(
-`ifdef USE_POWER_PINS
- .vccd1(USER_VDD1V8), // User area 1 1.8V supply
- .vssd1(VSS), // User area 1 digital ground
-`endif
- .wb_clk_i (clock), // System clock
- .user_clock2 (1'b1), // Real-time clock
- .wb_rst_i (wb_rst_i), // Regular Reset signal
-
- .wbs_cyc_i (wbd_ext_cyc_i), // strobe/request
- .wbs_stb_i (wbd_ext_stb_i), // strobe/request
- .wbs_adr_i (wbd_ext_adr_i), // address
- .wbs_we_i (wbd_ext_we_i), // write
- .wbs_dat_i (wbd_ext_dat_i), // data output
- .wbs_sel_i (wbd_ext_sel_i), // byte enable
-
- .wbs_dat_o (wbd_ext_dat_o), // data input
- .wbs_ack_o (wbd_ext_ack_o), // acknowlegement
-
-
- // Logic Analyzer Signals
- .la_data_in ('1) ,
- .la_data_out (),
- .la_oenb ('0),
-
-
- // IOs
- .io_in (io_in) ,
- .io_out (io_out) ,
- .io_oeb (io_oeb) ,
-
- .user_irq ()
-
-);
-
-`ifndef GL // Drive Power for Hold Fix Buf
- // All standard cell need power hook-up for functionality work
- initial begin
-
- end
-`endif
-
-//------------------------------------------------------
-// Integrate the Serial flash with qurd support to
-// user core using the gpio pads
-// ----------------------------------------------------
-
- wire flash_clk = io_out[24];
- wire flash_csb = io_out[25];
- // Creating Pad Delay
- wire #1 io_oeb_29 = io_oeb[29];
- wire #1 io_oeb_30 = io_oeb[30];
- wire #1 io_oeb_31 = io_oeb[31];
- wire #1 io_oeb_32 = io_oeb[32];
- tri #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
- tri #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
- tri #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
- tri #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
-
- assign io_in[29] = flash_io0;
- assign io_in[30] = flash_io1;
- assign io_in[31] = flash_io2;
- assign io_in[32] = flash_io3;
-
- // Quard flash
- s25fl256s #(.mem_file_name("user_mcore.hex"),
- .otp_file_name("none"),
- .TimingModel("S25FL512SAGMFI010_F_30pF"))
- u_spi_flash_256mb (
- // Data Inputs/Outputs
- .SI (flash_io0),
- .SO (flash_io1),
- // Controls
- .SCK (flash_clk),
- .CSNeg (flash_csb),
- .WPNeg (flash_io2),
- .HOLDNeg (flash_io3),
- .RSTNeg (!wb_rst_i)
-
- );
-
-
-
-
-task wb_user_core_write;
-input [31:0] address;
-input [31:0] data;
-begin
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_adr_i =address; // address
- wbd_ext_we_i ='h1; // write
- wbd_ext_dat_i =data; // data output
- wbd_ext_sel_i ='hF; // byte enable
- wbd_ext_cyc_i ='h1; // strobe/request
- wbd_ext_stb_i ='h1; // strobe/request
- wait(wbd_ext_ack_o == 1);
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_cyc_i ='h0; // strobe/request
- wbd_ext_stb_i ='h0; // strobe/request
- wbd_ext_adr_i ='h0; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='h0; // data output
- wbd_ext_sel_i ='h0; // byte enable
- $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
- repeat (2) @(posedge clock);
-end
-endtask
-
-task wb_user_core_read;
-input [31:0] address;
-output [31:0] data;
-reg [31:0] data;
-begin
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_adr_i =address; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='0; // data output
- wbd_ext_sel_i ='hF; // byte enable
- wbd_ext_cyc_i ='h1; // strobe/request
- wbd_ext_stb_i ='h1; // strobe/request
- wait(wbd_ext_ack_o == 1);
- repeat (1) @(negedge clock);
- data = wbd_ext_dat_o;
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_cyc_i ='h0; // strobe/request
- wbd_ext_stb_i ='h0; // strobe/request
- wbd_ext_adr_i ='h0; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='h0; // data output
- wbd_ext_sel_i ='h0; // byte enable
- $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
- repeat (2) @(posedge clock);
-end
-endtask
-
-task wb_user_core_read_check;
-input [31:0] address;
-output [31:0] data;
-input [31:0] cmp_data;
-reg [31:0] data;
-begin
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_adr_i =address; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='0; // data output
- wbd_ext_sel_i ='hF; // byte enable
- wbd_ext_cyc_i ='h1; // strobe/request
- wbd_ext_stb_i ='h1; // strobe/request
- wait(wbd_ext_ack_o == 1);
- repeat (1) @(negedge clock);
- data = wbd_ext_dat_o;
- repeat (1) @(posedge clock);
- #1;
- wbd_ext_cyc_i ='h0; // strobe/request
- wbd_ext_stb_i ='h0; // strobe/request
- wbd_ext_adr_i ='h0; // address
- wbd_ext_we_i ='h0; // write
- wbd_ext_dat_i ='h0; // data output
- wbd_ext_sel_i ='h0; // byte enable
- if(data !== cmp_data) begin
- $display("ERROR : WB USER ACCESS READ Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,cmp_data,data);
- test_fail = 1;
- end else begin
- $display("STATUS: WB USER ACCESS READ Address : 0x%x, Data : 0x%x",address,data);
- end
- repeat (2) @(posedge clock);
-end
-endtask
-
-`ifdef GL
-
-wire wbd_spi_stb_i = u_top.u_qspi_master.wbd_stb_i;
-wire wbd_spi_ack_o = u_top.u_qspi_master.wbd_ack_o;
-wire wbd_spi_we_i = u_top.u_qspi_master.wbd_we_i;
-wire [31:0] wbd_spi_adr_i = u_top.u_qspi_master.wbd_adr_i;
-wire [31:0] wbd_spi_dat_i = u_top.u_qspi_master.wbd_dat_i;
-wire [31:0] wbd_spi_dat_o = u_top.u_qspi_master.wbd_dat_o;
-wire [3:0] wbd_spi_sel_i = u_top.u_qspi_master.wbd_sel_i;
-
-wire wbd_uart_stb_i = u_top.u_uart_i2c_usb_spi.reg_cs;
-wire wbd_uart_ack_o = u_top.u_uart_i2c_usb_spi.reg_ack;
-wire wbd_uart_we_i = u_top.u_uart_i2c_usb_spi.reg_wr;
-wire [8:0] wbd_uart_adr_i = u_top.u_uart_i2c_usb_spi.reg_addr;
-wire [7:0] wbd_uart_dat_i = u_top.u_uart_i2c_usb_spi.reg_wdata;
-wire [7:0] wbd_uart_dat_o = u_top.u_uart_i2c_usb_spi.reg_rdata;
-wire wbd_uart_sel_i = u_top.u_uart_i2c_usb_spi.reg_be;
-
-`endif
-
-/**
-`ifdef GL
-//-----------------------------------------------------------------------------
-// RISC IMEM amd DMEM Monitoring TASK
-//-----------------------------------------------------------------------------
-
-`define RISC_CORE user_uart_tb.u_top.u_core.u_riscv_top
-
-always@(posedge `RISC_CORE.wb_clk) begin
- if(`RISC_CORE.wbd_imem_ack_i)
- $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
- if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
- $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
- if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
- $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
-end
-
-`endif
-**/
-endmodule
-`include "s25fl256s.sv"
-`default_nettype wire
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/glbl_reg.sv
similarity index 100%
rename from verilog/rtl/pinmux/src/pinmux_reg.sv
rename to verilog/rtl/pinmux/src/glbl_reg.sv
diff --git a/verilog/rtl/pinmux/src/gpio_control.sv b/verilog/rtl/pinmux/src/gpio_control.sv
deleted file mode 100644
index 4c917dc..0000000
--- a/verilog/rtl/pinmux/src/gpio_control.sv
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// GPIO Interrupt Generation
-module gpio_intr (
- input logic mclk ,// System clk
- input logic h_reset_n ,// system reset
- input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
- input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
- input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
- input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
- input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
- input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
-
-
- output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
- output logic [31:0] gpio_int_event // to the cfg interrupt status reg
-
-);
-
-
-integer i;
-//-----------------------------------------------------------------------
-// Logic for interrupt detection
-//-----------------------------------------------------------------------
-
-reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
-always @(cfg_gpio_data_in or cfg_gpio_negedge_int_sel or cfg_gpio_posedge_int_sel
- or gpio_prev_indata)
-begin
- for (i=0; i<32; i=i+1)
- begin
- // looking for rising edge int
- local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
- & cfg_gpio_data_in[i]) |
- (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
- ~cfg_gpio_data_in[i]));
- // looking for falling edge int
- end
-end
-
-assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
-
-assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
-
-endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux_top.sv
similarity index 100%
rename from verilog/rtl/pinmux/src/pinmux.sv
rename to verilog/rtl/pinmux/src/pinmux_top.sv