mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: enhance synthesis and metrics handling with recipe-specific outputs and configurations
This commit is contained in:
13 files changed
+175
-60
No files matched your search
@@ -102,13 +102,18 @@ VARIANT_ROOT := $(abspath $(BUILD_ROOT))/$(VARIANT_ID)
|
|||||||
SW_BUILD_DIR := $(VARIANT_ROOT)/sw
|
SW_BUILD_DIR := $(VARIANT_ROOT)/sw
|
||||||
SIM_TOOL_NAME := $(shell printf '%s' '$(SIMU)' | tr '[:upper:]' '[:lower:]')
|
SIM_TOOL_NAME := $(shell printf '%s' '$(SIMU)' | tr '[:upper:]' '[:lower:]')
|
||||||
SIM_BUILD_ROOT := $(VARIANT_ROOT)/sim/$(SIM_TOOL_NAME)
|
SIM_BUILD_ROOT := $(VARIANT_ROOT)/sim/$(SIM_TOOL_NAME)
|
||||||
ifeq ($(SYNTH_RECIPE),balanced)
|
|
||||||
SYN_BUILD_ROOT := $(VARIANT_ROOT)/syn/yosys
|
|
||||||
else
|
|
||||||
SYN_BUILD_ROOT := $(VARIANT_ROOT)/syn/yosys-$(SYNTH_RECIPE)
|
|
||||||
endif
|
|
||||||
STA_BUILD_ROOT := $(VARIANT_ROOT)/sta/opensta
|
|
||||||
META_DIR := $(VARIANT_ROOT)/meta
|
META_DIR := $(VARIANT_ROOT)/meta
|
||||||
|
ifeq ($(SYNTH_RECIPE),balanced)
|
||||||
|
SYN_BUILD_ROOT := $(VARIANT_ROOT)/syn/yosys
|
||||||
|
STA_BUILD_ROOT := $(VARIANT_ROOT)/sta/opensta
|
||||||
|
NETLIST_SIM_ROOT := $(SIM_BUILD_ROOT)/netl
|
||||||
|
METRICS_OUTPUT := $(META_DIR)/metrics.json
|
||||||
|
else
|
||||||
|
SYN_BUILD_ROOT := $(VARIANT_ROOT)/syn/yosys-$(SYNTH_RECIPE)
|
||||||
|
STA_BUILD_ROOT := $(VARIANT_ROOT)/sta/opensta-$(SYNTH_RECIPE)
|
||||||
|
NETLIST_SIM_ROOT := $(SIM_BUILD_ROOT)/netl-$(SYNTH_RECIPE)
|
||||||
|
METRICS_OUTPUT := $(META_DIR)/metrics-$(SYNTH_RECIPE).json
|
||||||
|
endif
|
||||||
ifeq ($(SYNTH),YOSYS)
|
ifeq ($(SYNTH),YOSYS)
|
||||||
FLOW_FILELIST_DIR := $(SYN_BUILD_ROOT)/filelists
|
FLOW_FILELIST_DIR := $(SYN_BUILD_ROOT)/filelists
|
||||||
else
|
else
|
||||||
@@ -407,10 +412,11 @@ check-warnings:
|
|||||||
|
|
||||||
metrics:
|
metrics:
|
||||||
python3 $(ROOT_PATH)/scripts/metrics.py collect --variant-root $(VARIANT_ROOT) \
|
python3 $(ROOT_PATH)/scripts/metrics.py collect --variant-root $(VARIANT_ROOT) \
|
||||||
--output $(META_DIR)/metrics.json
|
--synth-root $(SYN_BUILD_ROOT) --sta-root $(STA_BUILD_ROOT) \
|
||||||
|
--recipe $(SYNTH_RECIPE) --output $(METRICS_OUTPUT)
|
||||||
|
|
||||||
check-metrics: metrics
|
check-metrics: metrics
|
||||||
python3 $(ROOT_PATH)/scripts/metrics.py check --metrics $(META_DIR)/metrics.json \
|
python3 $(ROOT_PATH)/scripts/metrics.py check --metrics $(METRICS_OUTPUT) \
|
||||||
--policy $(ROOT_PATH)/quality/metrics/policy.json \
|
--policy $(ROOT_PATH)/quality/metrics/policy.json \
|
||||||
--baseline $(ROOT_PATH)/quality/metrics/baseline.json
|
--baseline $(ROOT_PATH)/quality/metrics/baseline.json
|
||||||
|
|
||||||
|
|||||||
+32
-9
@@ -121,19 +121,42 @@ build/<variant>/
|
|||||||
sw/
|
sw/
|
||||||
sim/<simulator>/
|
sim/<simulator>/
|
||||||
formal/<proof>/
|
formal/<proof>/
|
||||||
syn/yosys/
|
syn/yosys/ (balanced)
|
||||||
syn/yosys-area/ (optional SYNTH_RECIPE=area)
|
syn/yosys-area/ (SYNTH_RECIPE=area)
|
||||||
syn/yosys-speed/ (optional SYNTH_RECIPE=speed)
|
syn/yosys-speed/ (SYNTH_RECIPE=speed)
|
||||||
sta/opensta/
|
sta/opensta/ (balanced)
|
||||||
|
sta/opensta-area/ (SYNTH_RECIPE=area)
|
||||||
|
sta/opensta-speed/ (SYNTH_RECIPE=speed)
|
||||||
meta/manifest.json
|
meta/manifest.json
|
||||||
meta/warnings.json
|
meta/warnings.json
|
||||||
meta/metrics.json
|
meta/metrics.json (balanced)
|
||||||
|
meta/metrics-area.json (SYNTH_RECIPE=area)
|
||||||
|
meta/metrics-speed.json (SYNTH_RECIPE=speed)
|
||||||
```
|
```
|
||||||
|
|
||||||
The default Yosys recipe writes `syn/yosys/`. Optional `SYNTH_RECIPE=area` and
|
`SYNTH_RECIPE` is a flow selector and does not change the configuration hash.
|
||||||
`SYNTH_RECIPE=speed` jobs write sibling directories; STA, netlist simulation, warning analysis,
|
The selected recipe determines the synthesis netlist consumed by OpenSTA and
|
||||||
and metrics read only `syn/yosys/`. `SYNTH_RECIPE` is a flow selector and does not change the
|
netlist simulation, and determines which metrics file is written. `balanced`
|
||||||
configuration hash.
|
is the default PR flow. Nightly IHP130 runs `area` and `speed` through synth,
|
||||||
|
STA, and metrics; their netlist simulation remains an explicit, on-demand
|
||||||
|
validation because of its runtime.
|
||||||
|
|
||||||
|
Use the same commit, PDK, `BUILD_TIMESTAMP`, and `YOSYS_TARGET_PERIOD_PS` for
|
||||||
|
all recipes in a QoR comparison:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=balanced synth
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area STA=OPENSTA sta
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
Recipe optimization is evaluated using top area, cell count, WNS/TNS, flow
|
||||||
|
duration, warning signatures, and netlist simulation verdict together. The
|
||||||
|
`area` recipe is area-first and the `speed` recipe is timing-first; a single
|
||||||
|
improved metric is not sufficient to replace `balanced`. Metrics policy remains
|
||||||
|
in `observe` mode while recipe baselines are collected and reviewed.
|
||||||
|
|
||||||
Generated filelists and MPW output are flow-local. Make depfiles track expanded RTL sources and
|
Generated filelists and MPW output are flow-local. Make depfiles track expanded RTL sources and
|
||||||
included headers. The shared MPW generator is protected by a file lock. Default tool parallelism is
|
included headers. The shared MPW generator is protected by a file lock. Default tool parallelism is
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
OPENSTA ?= sta
|
OPENSTA ?= sta
|
||||||
OPENSTA_THREADS ?= $(JOBS)
|
OPENSTA_THREADS ?= $(JOBS)
|
||||||
OPENSTA_NETLIST ?= $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v
|
OPENSTA_NETLIST ?= $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||||
OPENSTA_REPORT ?= $(STA_BUILD_ROOT)/retrosoc_sta.log
|
OPENSTA_REPORT ?= $(STA_BUILD_ROOT)/retrosoc_sta.log
|
||||||
OPENSTA_LOG ?= $(STA_BUILD_ROOT)/opensta.log
|
OPENSTA_LOG ?= $(STA_BUILD_ROOT)/opensta.log
|
||||||
OPENSTA_METRICS ?= $(STA_BUILD_ROOT)/timing_metrics.rpt
|
OPENSTA_METRICS ?= $(STA_BUILD_ROOT)/timing_metrics.rpt
|
||||||
OPENSTA_CONFIG ?= $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.config
|
OPENSTA_CONFIG ?= $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.config
|
||||||
OPENSTA_SDC ?= $(STA_BUILD_ROOT)/retrosoc_core.sdc
|
OPENSTA_SDC ?= $(STA_BUILD_ROOT)/retrosoc_core.sdc
|
||||||
OPENSTA_SDC_GEN := $(ROOT_PATH)/physical/smoke/sta/opensta/generate_sdc.py
|
OPENSTA_SDC_GEN := $(ROOT_PATH)/physical/smoke/sta/opensta/generate_sdc.py
|
||||||
OPENSTA_DOMAIN_MAP := $(ROOT_PATH)/rtl/mini/integration/clock_reset_domains.json
|
OPENSTA_DOMAIN_MAP := $(ROOT_PATH)/rtl/mini/integration/clock_reset_domains.json
|
||||||
|
|||||||
@@ -10,25 +10,42 @@ Use a committed profile and run the supported flow:
|
|||||||
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS synth
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS synth
|
||||||
```
|
```
|
||||||
|
|
||||||
`SYNTH_RECIPE` selects the ABC mapping recipe without changing the variant hash:
|
`SYNTH_RECIPE` selects the ABC mapping recipe without changing the variant hash.
|
||||||
|
The recipe also selects the synthesis-derived output roots so timing, netlist
|
||||||
|
simulation, and metrics cannot accidentally consume the `balanced` netlist:
|
||||||
|
|
||||||
- `balanced` (default) writes `build/<variant>/syn/yosys/`
|
- `balanced` (default): `syn/yosys/`, `sta/opensta/`, `sim/<tool>/netl/`, and `meta/metrics.json`
|
||||||
- `area` writes `build/<variant>/syn/yosys-area/`
|
- `area`: `syn/yosys-area/`, `sta/opensta-area/`, `sim/<tool>/netl-area/`, and `meta/metrics-area.json`
|
||||||
- `speed` writes `build/<variant>/syn/yosys-speed/`
|
- `speed`: `syn/yosys-speed/`, `sta/opensta-speed/`, `sim/<tool>/netl-speed/`, and `meta/metrics-speed.json`
|
||||||
|
|
||||||
STA, netlist simulation, warning analysis, and metrics consume the default
|
`balanced` remains the PR and default CI recipe. Nightly IHP130 runs `area`
|
||||||
`syn/yosys/` slot. Nightly IHP130 regression also runs the `area` and `speed`
|
and `speed` through synthesis, OpenSTA, and metrics; their long netlist
|
||||||
recipes as synth-only extra jobs.
|
simulation is available on demand but is not part of nightly-extra.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth
|
||||||
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth
|
||||||
|
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area STA=OPENSTA sta
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area metrics
|
||||||
|
make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area SIMU=IVERILOG netsim
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Replace `area` with `speed` for the corresponding recipe. Run all three
|
||||||
|
recipes with the same commit, PDK, `BUILD_TIMESTAMP`, and
|
||||||
|
`YOSYS_TARGET_PERIOD_PS` when collecting a comparable QoR baseline.
|
||||||
|
|
||||||
|
Compare top area, cell count, WNS/TNS, synthesis and STA duration, warning
|
||||||
|
signatures, and the netlist simulation verdict. Area is an area-first mapping
|
||||||
|
recipe and speed is a timing-first exploration recipe; neither is promoted to
|
||||||
|
the default solely from one area or timing result. Metrics remain in observe
|
||||||
|
mode until the documented baseline review is complete.
|
||||||
|
|
||||||
The default ABC target period is derived from the `external` STA period in
|
The default ABC target period is derived from the `external` STA period in
|
||||||
`rtl/mini/integration/clock_reset_domains.json`. Override it with
|
`rtl/mini/integration/clock_reset_domains.json`. Override it with
|
||||||
`YOSYS_TARGET_PERIOD_PS=<ps>` when needed.
|
`YOSYS_TARGET_PERIOD_PS=<ps>` when needed.
|
||||||
|
|
||||||
Synthesis outputs are generated below `build/` and must not be committed.
|
Synthesis outputs are generated below `build/` and must not be committed.
|
||||||
Review warning and metric changes with `make check-warnings check-metrics` for
|
Review warning and metric changes with `make check-warnings check-metrics` for
|
||||||
the affected profile.
|
the affected profile. `make metrics` writes the recipe-specific file listed
|
||||||
|
above; `make check-metrics` checks that same file.
|
||||||
@@ -28,16 +28,6 @@ source $script_dir/init_tech.tcl
|
|||||||
yosys read_slang --top $top_design -F $sv_flist \
|
yosys read_slang --top $top_design -F $sv_flist \
|
||||||
--keep-hierarchy --allow-use-before-declare --ignore-initial --ignore-timing
|
--keep-hierarchy --allow-use-before-declare --ignore-initial --ignore-timing
|
||||||
|
|
||||||
# # blackbox requested modules
|
|
||||||
# if { [info exists ::env(YOSYS_BLACKBOX_MODULES)] } {
|
|
||||||
# foreach sel $::env(YOSYS_BLACKBOX_MODULES) {
|
|
||||||
# puts "Blackboxing the module ${sel}"
|
|
||||||
# yosys select -list {*}$sel
|
|
||||||
# yosys blackbox {*}$sel
|
|
||||||
# yosys setattr -set keep_hierarchy 1 {*}$sel
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # preserve hierarchy of selected modules/instances
|
# # preserve hierarchy of selected modules/instances
|
||||||
if { [info exists ::env(YOSYS_KEEP_HIER_INST)] } {
|
if { [info exists ::env(YOSYS_KEEP_HIER_INST)] } {
|
||||||
foreach sel $::env(YOSYS_KEEP_HIER_INST) {
|
foreach sel $::env(YOSYS_KEEP_HIER_INST) {
|
||||||
@@ -116,7 +106,6 @@ yosys select -write ${report_dir}/${proj_name}_registers.rpt t:*DFF*
|
|||||||
yosys clean -purge
|
yosys clean -purge
|
||||||
|
|
||||||
# print paths to important instances
|
# print paths to important instances
|
||||||
yosys select -write ${report_dir}/${proj_name}_registers.rpt t:*DFF*
|
|
||||||
set report [open ${report_dir}/${proj_name}_instances.rpt "w"]
|
set report [open ${report_dir}/${proj_name}_instances.rpt "w"]
|
||||||
close $report
|
close $report
|
||||||
if { [info exists ::env(YOSYS_REPORT_INSTS)] } {
|
if { [info exists ::env(YOSYS_REPORT_INSTS)] } {
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
# Authors:
|
# Authors:
|
||||||
# - Philippe Sauter <phsauter@iis.ee.ethz.ch>
|
# - Philippe Sauter <phsauter@iis.ee.ethz.ch>
|
||||||
|
|
||||||
# modules Yosys will treat as blackboxes
|
|
||||||
export YOSYS_BLACKBOX_MODULES := "*tc_sram_blackbox*"
|
|
||||||
|
|
||||||
# flatten hierarchy (except for below selections)
|
# flatten hierarchy (except for below selections)
|
||||||
export YOSYS_FLATTEN_HIER := 1
|
export YOSYS_FLATTEN_HIER := 1
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ FORMAL_I2C_TIMEOUT ?= 300
|
|||||||
FORMAL_OPIPSRAM_TIMEOUT ?= 300
|
FORMAL_OPIPSRAM_TIMEOUT ?= 300
|
||||||
FORMAL_DMA_TIMEOUT ?= 120
|
FORMAL_DMA_TIMEOUT ?= 120
|
||||||
FORMAL_SDIO_TIMEOUT ?= 120
|
FORMAL_SDIO_TIMEOUT ?= 120
|
||||||
|
FORMAL_COMPACT_COVER_TARGETS := i2c opipsram
|
||||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio ws2812 uart i2c timer clint dvp i2s psram opipsram dma sdio
|
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio ws2812 uart i2c timer clint dvp i2s psram opipsram dma sdio
|
||||||
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
||||||
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
||||||
@@ -186,7 +187,7 @@ $(FORMAL_DIR)/%/cover.sby: $(FORMAL_DIR)/%/design.v $(RTL_PATH)/formal/%_formal_
|
|||||||
python3 $(FORMAL_SBY_GENERATOR) --top $*_formal --input $< \
|
python3 $(FORMAL_SBY_GENERATOR) --top $*_formal --input $< \
|
||||||
--properties $(RTL_PATH)/formal/$*_formal_props.sv --solver $(FORMAL_SOLVER) \
|
--properties $(RTL_PATH)/formal/$*_formal_props.sv --solver $(FORMAL_SOLVER) \
|
||||||
--mode cover --depth $(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_COVER_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH)))))))) \
|
--mode cover --depth $(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_COVER_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH)))))))) \
|
||||||
$(if $(filter i2c,$*),--no-vcd) --output $@
|
$(if $(filter $(FORMAL_COMPACT_COVER_TARGETS),$*),--no-vcd) --output $@
|
||||||
@if [ "$*" = opipsram ]; then sed -i '/^async2sync/i clk2fflogic' $@; fi
|
@if [ "$*" = opipsram ]; then sed -i '/^async2sync/i clk2fflogic' $@; fi
|
||||||
|
|
||||||
$(FORMAL_DIR)/opipsram/bmc.sby: $(FORMAL_DIR)/opipsram/design.v \
|
$(FORMAL_DIR)/opipsram/bmc.sby: $(FORMAL_DIR)/opipsram/design.v \
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ IVERILOG ?= iverilog
|
|||||||
VVP ?= vvp
|
VVP ?= vvp
|
||||||
GTKWAVE ?= gtkwave
|
GTKWAVE ?= gtkwave
|
||||||
|
|
||||||
NETLIST_PATH ?= $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v
|
NETLIST_PATH ?= $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||||
POST_PATH ?= $(ROOT_PATH)/physical/sdf/retrosoc_asic.v
|
POST_PATH ?= $(ROOT_PATH)/physical/sdf/retrosoc_asic.v
|
||||||
SDF_PATH ?= $(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz
|
SDF_PATH ?= $(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz
|
||||||
SDF_SCOPE ?= $(RTL_TOP).u_retrosoc_asic
|
SDF_SCOPE ?= $(RTL_TOP).u_retrosoc_asic
|
||||||
|
|
||||||
IVERILOG_ROOT := $(SIM_BUILD_ROOT)
|
IVERILOG_ROOT := $(SIM_BUILD_ROOT)
|
||||||
IVERILOG_BEHV_DIR := $(IVERILOG_ROOT)/behv
|
IVERILOG_BEHV_DIR := $(IVERILOG_ROOT)/behv
|
||||||
IVERILOG_NETL_DIR := $(IVERILOG_ROOT)/netl
|
IVERILOG_NETL_DIR := $(NETLIST_SIM_ROOT)
|
||||||
IVERILOG_POST_DIR := $(IVERILOG_ROOT)/post
|
IVERILOG_POST_DIR := $(IVERILOG_ROOT)/post
|
||||||
IVERILOG_BEHV_FLIST := $(IVERILOG_BEHV_DIR)/iverilog.fl
|
IVERILOG_BEHV_FLIST := $(IVERILOG_BEHV_DIR)/iverilog.fl
|
||||||
IVERILOG_NETL_FLIST := $(IVERILOG_NETL_DIR)/iverilog.fl
|
IVERILOG_NETL_FLIST := $(IVERILOG_NETL_DIR)/iverilog.fl
|
||||||
|
|||||||
+5
-5
@@ -10,7 +10,7 @@ VCS_FLOW_PYTHON := $(strip $(VCS_RUNNER) $(PYTHON))
|
|||||||
COMP_LOG := -l compile.log
|
COMP_LOG := -l compile.log
|
||||||
SIM_LOG := -l sim.log
|
SIM_LOG := -l sim.log
|
||||||
# netlist file path
|
# netlist file path
|
||||||
NETLIST_PATH := -v $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v
|
NETLIST_PATH := -v $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||||
POST_PATH := -v $(ROOT_PATH)/physical/sdf/retrosoc_asic.v
|
POST_PATH := -v $(ROOT_PATH)/physical/sdf/retrosoc_asic.v
|
||||||
SDF_PATH := "$(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz"
|
SDF_PATH := "$(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz"
|
||||||
# testbench filelist
|
# testbench filelist
|
||||||
@@ -48,7 +48,7 @@ SIM_OPTS := +vcs+loopreport+1000 -suppress=ASLR_DETECTED_INFO \
|
|||||||
+sim_timeout=$(RTL_SIM_TIMEOUT) +wave_$(WAVE)
|
+sim_timeout=$(RTL_SIM_TIMEOUT) +wave_$(WAVE)
|
||||||
|
|
||||||
VCS_BEHV_DIR := $(SIM_BUILD_ROOT)/behv
|
VCS_BEHV_DIR := $(SIM_BUILD_ROOT)/behv
|
||||||
VCS_NETL_DIR := $(SIM_BUILD_ROOT)/netl
|
VCS_NETL_DIR := $(NETLIST_SIM_ROOT)
|
||||||
VCS_POST_DIR := $(SIM_BUILD_ROOT)/post
|
VCS_POST_DIR := $(SIM_BUILD_ROOT)/post
|
||||||
VCS_BEHV_SIMV := $(VCS_BEHV_DIR)/simv
|
VCS_BEHV_SIMV := $(VCS_BEHV_DIR)/simv
|
||||||
VCS_NETL_SIMV := $(VCS_NETL_DIR)/simv
|
VCS_NETL_SIMV := $(VCS_NETL_DIR)/simv
|
||||||
@@ -69,7 +69,7 @@ $(VCS_NETL_SIMV): DIR := $(VCS_NETL_DIR)
|
|||||||
$(VCS_NETL_SIMV): FLIST := $(NETLIST_PATH) $(NET_FLIST) $(TB_FLIST)
|
$(VCS_NETL_SIMV): FLIST := $(NETLIST_PATH) $(NET_FLIST) $(TB_FLIST)
|
||||||
$(VCS_NETL_SIMV): OPTS := $(TIME_OPTION)
|
$(VCS_NETL_SIMV): OPTS := $(TIME_OPTION)
|
||||||
$(VCS_NETL_SIMV): DEPFILE := $(VCS_NETL_DEPFILE)
|
$(VCS_NETL_SIMV): DEPFILE := $(VCS_NETL_DEPFILE)
|
||||||
$(VCS_NETL_SIMV): DEPS_ARGS := $(NET_FLIST) -f $(GENERATED_FL_DIR)/tb.fl --extra $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v
|
$(VCS_NETL_SIMV): DEPS_ARGS := $(NET_FLIST) -f $(GENERATED_FL_DIR)/tb.fl --extra $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||||
|
|
||||||
$(VCS_POST_SIMV): DIR := $(VCS_POST_DIR)
|
$(VCS_POST_SIMV): DIR := $(VCS_POST_DIR)
|
||||||
$(VCS_POST_SIMV): FLIST := $(POST_PATH) $(NET_FLIST) $(TB_FLIST)
|
$(VCS_POST_SIMV): FLIST := $(POST_PATH) $(NET_FLIST) $(TB_FLIST)
|
||||||
@@ -82,7 +82,7 @@ netsim: DIR := $(VCS_NETL_DIR)
|
|||||||
postsim: DIR := $(VCS_POST_DIR)
|
postsim: DIR := $(VCS_POST_DIR)
|
||||||
|
|
||||||
wave: DIR := $(SIM_BUILD_ROOT)/behv
|
wave: DIR := $(SIM_BUILD_ROOT)/behv
|
||||||
netwave: DIR := $(SIM_BUILD_ROOT)/netl
|
netwave: DIR := $(NETLIST_SIM_ROOT)
|
||||||
postwave: DIR := $(SIM_BUILD_ROOT)/post
|
postwave: DIR := $(SIM_BUILD_ROOT)/post
|
||||||
|
|
||||||
comp: $(VCS_BEHV_SIMV)
|
comp: $(VCS_BEHV_SIMV)
|
||||||
@@ -101,7 +101,7 @@ $(VCS_BEHV_SIMV) $(VCS_NETL_SIMV) $(VCS_POST_SIMV): $(MPW_VARIANT_STAMP) $(FILEL
|
|||||||
$(SIM_TOOL) $(COMMON_OPTS) $(OPTS) $(FLIST) -top $(RTL_TOP) $(COMP_LOG)
|
$(SIM_TOOL) $(COMMON_OPTS) $(OPTS) $(FLIST) -top $(RTL_TOP) $(COMP_LOG)
|
||||||
$(FLOW_PYTHON) $(RTL_PATH)/script/filelist_deps.py $(DEPS_ARGS) --target $@ --output $(DEPFILE)
|
$(FLOW_PYTHON) $(RTL_PATH)/script/filelist_deps.py $(DEPS_ARGS) --target $@ --output $(DEPFILE)
|
||||||
|
|
||||||
$(VCS_NETL_SIMV): $(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v
|
$(VCS_NETL_SIMV): $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||||
$(VCS_POST_SIMV): $(ROOT_PATH)/physical/sdf/retrosoc_asic.v $(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz
|
$(VCS_POST_SIMV): $(ROOT_PATH)/physical/sdf/retrosoc_asic.v $(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz
|
||||||
|
|
||||||
sim netsim postsim:
|
sim netsim postsim:
|
||||||
|
|||||||
+23
-5
@@ -22,19 +22,21 @@ HIERARCHY_RE = re.compile(r"^\s*(\d+)\s+[0-9.eE+-]+\s+retrosoc_asic\s*$", re.MUL
|
|||||||
|
|
||||||
def collect(args: argparse.Namespace) -> int:
|
def collect(args: argparse.Namespace) -> int:
|
||||||
root = args.variant_root.resolve()
|
root = args.variant_root.resolve()
|
||||||
|
synth_root = (args.synth_root or root / "syn/yosys").resolve()
|
||||||
|
sta_root = (args.sta_root or root / "sta/opensta").resolve()
|
||||||
metrics: dict[str, Any] = {
|
metrics: dict[str, Any] = {
|
||||||
"schema_version": 1,
|
"schema_version": 2,
|
||||||
"policy": "observe",
|
"policy": "observe",
|
||||||
"firmware": {},
|
"firmware": {},
|
||||||
"synthesis": {},
|
"synthesis": {"recipe": args.recipe},
|
||||||
"timing": {},
|
"timing": {},
|
||||||
"flows": {},
|
"flows": {},
|
||||||
}
|
}
|
||||||
for binary in sorted((root / "sw").glob("*.bin")):
|
for binary in sorted((root / "sw").glob("*.bin")):
|
||||||
metrics["firmware"][binary.name] = {"bytes": binary.stat().st_size}
|
metrics["firmware"][binary.name] = {"bytes": binary.stat().st_size}
|
||||||
|
|
||||||
area_json = root / "syn/yosys/rpt/retrosoc_asic_area.json"
|
area_json = synth_root / "rpt/retrosoc_asic_area.json"
|
||||||
area_report = root / "syn/yosys/rpt/retrosoc_asic_area.rpt"
|
area_report = synth_root / "rpt/retrosoc_asic_area.rpt"
|
||||||
if area_json.is_file():
|
if area_json.is_file():
|
||||||
design = json.loads(area_json.read_text(encoding="utf-8"))["design"]
|
design = json.loads(area_json.read_text(encoding="utf-8"))["design"]
|
||||||
metrics["synthesis"]["top_area"] = float(design["area"])
|
metrics["synthesis"]["top_area"] = float(design["area"])
|
||||||
@@ -48,7 +50,7 @@ def collect(args: argparse.Namespace) -> int:
|
|||||||
if hierarchy:
|
if hierarchy:
|
||||||
metrics["synthesis"]["top_cells"] = int(hierarchy[-1])
|
metrics["synthesis"]["top_cells"] = int(hierarchy[-1])
|
||||||
|
|
||||||
timing_report = root / "sta/opensta/timing_metrics.rpt"
|
timing_report = sta_root / "timing_metrics.rpt"
|
||||||
if timing_report.is_file():
|
if timing_report.is_file():
|
||||||
labels = ("wns_min", "wns_max", "tns_min", "tns_max")
|
labels = ("wns_min", "wns_max", "tns_min", "tns_max")
|
||||||
timing_text = timing_report.read_text(encoding="utf-8", errors="replace")
|
timing_text = timing_report.read_text(encoding="utf-8", errors="replace")
|
||||||
@@ -73,6 +75,19 @@ def collect(args: argparse.Namespace) -> int:
|
|||||||
"status": data.get("status"),
|
"status": data.get("status"),
|
||||||
"duration_seconds": data.get("duration_seconds"),
|
"duration_seconds": data.get("duration_seconds"),
|
||||||
}
|
}
|
||||||
|
for label, result in (
|
||||||
|
("synthesis", synth_root / "result-synth.json"),
|
||||||
|
("sta", sta_root / "result-sta.json"),
|
||||||
|
):
|
||||||
|
if result.is_file():
|
||||||
|
try:
|
||||||
|
data = json.loads(result.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, json.JSONDecodeError):
|
||||||
|
continue
|
||||||
|
metrics["flows"][label] = {
|
||||||
|
"status": data.get("status"),
|
||||||
|
"duration_seconds": data.get("duration_seconds"),
|
||||||
|
}
|
||||||
atomic_write(args.output, json.dumps(metrics, indent=2, sort_keys=True) + "\n")
|
atomic_write(args.output, json.dumps(metrics, indent=2, sort_keys=True) + "\n")
|
||||||
print(f"metrics: {args.output.resolve()}")
|
print(f"metrics: {args.output.resolve()}")
|
||||||
return 0
|
return 0
|
||||||
@@ -130,6 +145,9 @@ def parse_args() -> argparse.Namespace:
|
|||||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||||
collect_parser = subparsers.add_parser("collect")
|
collect_parser = subparsers.add_parser("collect")
|
||||||
collect_parser.add_argument("--variant-root", type=Path, required=True)
|
collect_parser.add_argument("--variant-root", type=Path, required=True)
|
||||||
|
collect_parser.add_argument("--synth-root", type=Path)
|
||||||
|
collect_parser.add_argument("--sta-root", type=Path)
|
||||||
|
collect_parser.add_argument("--recipe", choices=("balanced", "area", "speed"), default="balanced")
|
||||||
collect_parser.add_argument("--output", type=Path, required=True)
|
collect_parser.add_argument("--output", type=Path, required=True)
|
||||||
baseline_parser = subparsers.add_parser("baseline")
|
baseline_parser = subparsers.add_parser("baseline")
|
||||||
baseline_parser.add_argument("--input", type=Path, action="append", required=True)
|
baseline_parser.add_argument("--input", type=Path, action="append", required=True)
|
||||||
|
|||||||
@@ -65,7 +65,11 @@ NIGHTLY_EXTRA_COMMANDS = (
|
|||||||
("SIMU=VERILATOR", "HAVE_SVA=YES", "coremark-report"),
|
("SIMU=VERILATOR", "HAVE_SVA=YES", "coremark-report"),
|
||||||
),
|
),
|
||||||
("configs/ci/ihp130.mk", ("SYNTH=YOSYS", "SYNTH_RECIPE=area", "synth")),
|
("configs/ci/ihp130.mk", ("SYNTH=YOSYS", "SYNTH_RECIPE=area", "synth")),
|
||||||
|
("configs/ci/ihp130.mk", ("STA=OPENSTA", "SYNTH_RECIPE=area", "sta")),
|
||||||
|
("configs/ci/ihp130.mk", ("SYNTH_RECIPE=area", "metrics")),
|
||||||
("configs/ci/ihp130.mk", ("SYNTH=YOSYS", "SYNTH_RECIPE=speed", "synth")),
|
("configs/ci/ihp130.mk", ("SYNTH=YOSYS", "SYNTH_RECIPE=speed", "synth")),
|
||||||
|
("configs/ci/ihp130.mk", ("STA=OPENSTA", "SYNTH_RECIPE=speed", "sta")),
|
||||||
|
("configs/ci/ihp130.mk", ("SYNTH_RECIPE=speed", "metrics")),
|
||||||
)
|
)
|
||||||
NIGHTLY_COMMANDS = (
|
NIGHTLY_COMMANDS = (
|
||||||
*PR_COMMANDS,
|
*PR_COMMANDS,
|
||||||
|
|||||||
@@ -894,10 +894,26 @@ def test_nightly_regression_runs_optional_yosys_recipes() -> None:
|
|||||||
"configs/ci/ihp130.mk",
|
"configs/ci/ihp130.mk",
|
||||||
("SYNTH=YOSYS", "SYNTH_RECIPE=area", "synth"),
|
("SYNTH=YOSYS", "SYNTH_RECIPE=area", "synth"),
|
||||||
) in NIGHTLY_COMMANDS
|
) in NIGHTLY_COMMANDS
|
||||||
|
assert (
|
||||||
|
"configs/ci/ihp130.mk",
|
||||||
|
("STA=OPENSTA", "SYNTH_RECIPE=area", "sta"),
|
||||||
|
) in NIGHTLY_COMMANDS
|
||||||
|
assert (
|
||||||
|
"configs/ci/ihp130.mk",
|
||||||
|
("SYNTH_RECIPE=area", "metrics"),
|
||||||
|
) in NIGHTLY_COMMANDS
|
||||||
assert (
|
assert (
|
||||||
"configs/ci/ihp130.mk",
|
"configs/ci/ihp130.mk",
|
||||||
("SYNTH=YOSYS", "SYNTH_RECIPE=speed", "synth"),
|
("SYNTH=YOSYS", "SYNTH_RECIPE=speed", "synth"),
|
||||||
) in NIGHTLY_COMMANDS
|
) in NIGHTLY_COMMANDS
|
||||||
|
assert (
|
||||||
|
"configs/ci/ihp130.mk",
|
||||||
|
("STA=OPENSTA", "SYNTH_RECIPE=speed", "sta"),
|
||||||
|
) in NIGHTLY_COMMANDS
|
||||||
|
assert (
|
||||||
|
"configs/ci/ihp130.mk",
|
||||||
|
("SYNTH_RECIPE=speed", "metrics"),
|
||||||
|
) in NIGHTLY_COMMANDS
|
||||||
assert not any(
|
assert not any(
|
||||||
any(value.startswith("SYNTH_RECIPE=") for value in values) for _, values in PR_COMMANDS
|
any(value.startswith("SYNTH_RECIPE=") for value in values) for _, values in PR_COMMANDS
|
||||||
)
|
)
|
||||||
@@ -914,7 +930,11 @@ def test_nightly_regression_runs_optional_yosys_recipes() -> None:
|
|||||||
"--dry-run",
|
"--dry-run",
|
||||||
)
|
)
|
||||||
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth" in nightly.stdout
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth" in nightly.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk STA=OPENSTA SYNTH_RECIPE=area sta" in nightly.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area metrics" in nightly.stdout
|
||||||
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth" in nightly.stdout
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth" in nightly.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk STA=OPENSTA SYNTH_RECIPE=speed sta" in nightly.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=speed metrics" in nightly.stdout
|
||||||
|
|
||||||
pr = run(
|
pr = run(
|
||||||
sys.executable,
|
sys.executable,
|
||||||
@@ -953,7 +973,11 @@ def test_nightly_extra_regression_skips_pr_netsim() -> None:
|
|||||||
)
|
)
|
||||||
assert "+ make CONFIG=configs/benchmark/ihp130-hazard3-coremark.mk SIMU=VERILATOR HAVE_SVA=YES coremark-report" in extra.stdout
|
assert "+ make CONFIG=configs/benchmark/ihp130-hazard3-coremark.mk SIMU=VERILATOR HAVE_SVA=YES coremark-report" in extra.stdout
|
||||||
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth" in extra.stdout
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=area synth" in extra.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk STA=OPENSTA SYNTH_RECIPE=area sta" in extra.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=area metrics" in extra.stdout
|
||||||
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth" in extra.stdout
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS SYNTH_RECIPE=speed synth" in extra.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk STA=OPENSTA SYNTH_RECIPE=speed sta" in extra.stdout
|
||||||
|
assert "+ make CONFIG=configs/ci/ihp130.mk SYNTH_RECIPE=speed metrics" in extra.stdout
|
||||||
assert "netsim" not in extra.stdout
|
assert "netsim" not in extra.stdout
|
||||||
|
|
||||||
invalid = subprocess.run(
|
invalid = subprocess.run(
|
||||||
@@ -1522,7 +1546,7 @@ def test_metrics_collection_and_observe_policy(tmp_path: Path) -> None:
|
|||||||
)
|
)
|
||||||
data = json.loads(metrics.read_text(encoding="utf-8"))
|
data = json.loads(metrics.read_text(encoding="utf-8"))
|
||||||
assert data["firmware"]["firmware.bin"]["bytes"] == 4
|
assert data["firmware"]["firmware.bin"]["bytes"] == 4
|
||||||
assert data["synthesis"] == {"top_area": 124.0, "top_cells": 43}
|
assert data["synthesis"] == {"recipe": "balanced", "top_area": 124.0, "top_cells": 43}
|
||||||
assert data["timing"]["wns_min"] == -1.0
|
assert data["timing"]["wns_min"] == -1.0
|
||||||
|
|
||||||
policy = tmp_path / "policy.json"
|
policy = tmp_path / "policy.json"
|
||||||
@@ -1538,6 +1562,38 @@ def test_metrics_collection_and_observe_policy(tmp_path: Path) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_metrics_collection_selects_recipe_roots(tmp_path: Path) -> None:
|
||||||
|
variant = tmp_path / "variant"
|
||||||
|
synth_root = variant / "syn/yosys-area"
|
||||||
|
sta_root = variant / "sta/opensta-area"
|
||||||
|
(synth_root / "rpt").mkdir(parents=True)
|
||||||
|
sta_root.mkdir(parents=True)
|
||||||
|
(synth_root / "rpt/retrosoc_asic_area.json").write_text(
|
||||||
|
json.dumps({"design": {"area": 88.0, "num_cells": 19}}), encoding="utf-8"
|
||||||
|
)
|
||||||
|
(sta_root / "timing_metrics.rpt").write_text("wns_max=-0.25\n", encoding="utf-8")
|
||||||
|
metrics = tmp_path / "metrics-area.json"
|
||||||
|
run(
|
||||||
|
sys.executable,
|
||||||
|
str(ROOT / "scripts/metrics.py"),
|
||||||
|
"collect",
|
||||||
|
"--variant-root",
|
||||||
|
str(variant),
|
||||||
|
"--synth-root",
|
||||||
|
str(synth_root),
|
||||||
|
"--sta-root",
|
||||||
|
str(sta_root),
|
||||||
|
"--recipe",
|
||||||
|
"area",
|
||||||
|
"--output",
|
||||||
|
str(metrics),
|
||||||
|
)
|
||||||
|
data = json.loads(metrics.read_text(encoding="utf-8"))
|
||||||
|
assert data["schema_version"] == 2
|
||||||
|
assert data["synthesis"] == {"recipe": "area", "top_area": 88.0, "top_cells": 19}
|
||||||
|
assert data["timing"]["wns_max"] == -0.25
|
||||||
|
|
||||||
|
|
||||||
def test_safe_extract_rejects_parent_traversal(tmp_path: Path) -> None:
|
def test_safe_extract_rejects_parent_traversal(tmp_path: Path) -> None:
|
||||||
archive = tmp_path / "unsafe.tar"
|
archive = tmp_path / "unsafe.tar"
|
||||||
with tarfile.open(archive, "w") as bundle:
|
with tarfile.open(archive, "w") as bundle:
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ def test_yosys_recipe_scripts_and_public_slot_are_stable() -> None:
|
|||||||
assert "SYNTH_RECIPE ?= balanced" in makefile
|
assert "SYNTH_RECIPE ?= balanced" in makefile
|
||||||
assert "VALID_SYNTH_RECIPE := balanced area speed" in makefile
|
assert "VALID_SYNTH_RECIPE := balanced area speed" in makefile
|
||||||
assert "syn/yosys-$(SYNTH_RECIPE)" in makefile
|
assert "syn/yosys-$(SYNTH_RECIPE)" in makefile
|
||||||
|
assert "sta/opensta-$(SYNTH_RECIPE)" in makefile
|
||||||
|
assert "netl-$(SYNTH_RECIPE)" in makefile
|
||||||
|
assert "metrics-$(SYNTH_RECIPE).json" in makefile
|
||||||
assert "CONFIG_KEY_VARS" in makefile
|
assert "CONFIG_KEY_VARS" in makefile
|
||||||
assert "SYNTH_RECIPE" not in makefile.split("CONFIG_KEY_VARS", 1)[1].split("VARIANT_ID", 1)[0]
|
assert "SYNTH_RECIPE" not in makefile.split("CONFIG_KEY_VARS", 1)[1].split("VARIANT_ID", 1)[0]
|
||||||
assert "--env SYNTH_RECIPE=$(SYNTH_RECIPE)" in yosys_mk
|
assert "--env SYNTH_RECIPE=$(SYNTH_RECIPE)" in yosys_mk
|
||||||
@@ -55,11 +58,12 @@ def test_yosys_recipe_scripts_and_public_slot_are_stable() -> None:
|
|||||||
assert "abc_${synth_recipe}.script" in synth_tcl
|
assert "abc_${synth_recipe}.script" in synth_tcl
|
||||||
assert "yosys abc {*}$tech_cells_args -D $period_ps -script $abc_script -constr $abc_constr" in synth_tcl
|
assert "yosys abc {*}$tech_cells_args -D $period_ps -script $abc_script -constr $abc_constr" in synth_tcl
|
||||||
assert "S110" not in synth_tcl
|
assert "S110" not in synth_tcl
|
||||||
assert "$(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v" in opensta
|
assert "$(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v" in opensta
|
||||||
assert "$(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v" in iverilog
|
assert "$(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v" in iverilog
|
||||||
assert "$(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v" in vcs
|
assert "$(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v" in vcs
|
||||||
assert "SYN_BUILD_ROOT" not in opensta
|
assert "$(NETLIST_SIM_ROOT)" in iverilog
|
||||||
assert "SYN_BUILD_ROOT" not in iverilog.split("NETLIST_PATH", 1)[1][:200]
|
assert "$(NETLIST_SIM_ROOT)" in vcs
|
||||||
|
assert "$(VARIANT_ROOT)/syn/yosys/out/retrosoc_asic_yosys.v" not in vcs
|
||||||
assert (YOSYS_SCRIPTS / "abc_balanced.script").read_text(encoding="utf-8").count("&nf {D}") == 1
|
assert (YOSYS_SCRIPTS / "abc_balanced.script").read_text(encoding="utf-8").count("&nf {D}") == 1
|
||||||
assert "&nf {D}" not in (YOSYS_SCRIPTS / "abc_area.script").read_text(encoding="utf-8")
|
assert "&nf {D}" not in (YOSYS_SCRIPTS / "abc_area.script").read_text(encoding="utf-8")
|
||||||
assert (YOSYS_SCRIPTS / "abc_speed.script").read_text(encoding="utf-8").count("&nf {D}") == 6
|
assert (YOSYS_SCRIPTS / "abc_speed.script").read_text(encoding="utf-8").count("&nf {D}") == 6
|
||||||
|
|||||||
Reference in new issue
Block a user