From 83764d3329c3ec3a17d5aaf544d34e3c7c9e8df4 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 9 Feb 2023 13:01:08 -0800 Subject: [PATCH] [skip ci] add power-rtl and power-syn targets --- docs/VLSI/Advanced-Usage.rst | 34 ++++++--- vlsi/Makefile | 137 ++++++----------------------------- vlsi/example-tools.yml | 1 + vlsi/power.mk | 85 +++++++++++++++++++--- vlsi/sim.mk | 78 ++++++++++++++++++++ 5 files changed, 199 insertions(+), 136 deletions(-) diff --git a/docs/VLSI/Advanced-Usage.rst b/docs/VLSI/Advanced-Usage.rst index 8ea54c78..07e71884 100644 --- a/docs/VLSI/Advanced-Usage.rst +++ b/docs/VLSI/Advanced-Usage.rst @@ -47,37 +47,51 @@ For more information about all the options that can be passed to the Hammer comm Manual Step Execution & Dependency Tracking ------------------------------------------- -It is invariably necessary to debug certain steps of the flow, e.g. if the power strap settings need to be updated. The underlying Hammer commands support options such as ``--to_step``, ``--from_step``, and ``--only_step``. These allow you to control which steps of a particular action are executed. +It is invariably necessary to debug certain steps of the flow, e.g. if the power strap settings need to be updated. The underlying Hammer commands support options such as ``--stop_after_step``, ``--start_before_step``, and ``--only_step``. These allow you to control which steps of a particular action are executed. Make's dependency tracking can sometimes result in re-starting the entire flow when the user only wants to re-run a certain action. Hammer's build system has "redo" targets such as ``redo-syn`` and ``redo-par`` to run certain actions without typing out the entire Hammer command. -Say you need to update some power straps settings in ``example.yml`` and want to try out the new settings: +Say you need to update some power straps settings in ``new_power_straps.yml`` and want to try out the new settings: .. code-block:: shell - make redo-par HAMMER_REDO_ARGS='-p example.yml --only_step power_straps' + make redo-par HAMMER_REDO_ARGS='-p new_power_straps.yml --only_step power_straps' + +The command that is executed will be: + +.. code-block:: shell + + ./example-vlsi -e /path/to/env.yml -p /path/to/par-input.json -p new_power_straps.yml --only_step power_straps --obj_dir /path/to/build par Hierarchical RTL/Gate-level Simulation, Power Estimation -------------------------------------------------------- -With the Synopsys plugin, hierarchical RTL and gate-level simulation is supported using VCS at the chip-level. Also, post-par power estimation with Voltus in the Cadence plugin is also supported. Special Make targets are provided in the ``vlsi/`` directory in ``sims.mk`` and ``power.mk``. Here is a brief description: +With the Synopsys plugin, hierarchical RTL and gate-level simulation is supported using VCS at the chip-level. Also, rtl-level/post-syn power estimation with Joules and post-par power estimation with Voltus in the Cadence plugin is also supported. Special Make targets are provided in the ``vlsi/`` directory in ``sims.mk`` and ``power.mk``. Here is a brief description: * ``sim-rtl``: RTL-level simulation - * ``sim-rtl-debug``: Also write a VPD waveform + * ``sim-rtl-debug``: Also write a FSDB waveform * ``sim-syn``: Post-synthesis gate-level simulation - * ``sim-syn-debug``: Also write a VPD waveform - * ``sim-syn-timing-debug``: Timing-annotated with VPD waveform + * ``sim-syn-debug``: Also write a FSDB waveform + * ``sim-syn-timing-debug``: Timing-annotated with FSDB waveform * ``sim-par``: Post-par gate-level simulation - * ``sim-par-debug``: Also write a VPD waveform - * ``sim-par-timing-debug``: Timing-annotated with VPD waveform + * ``sim-par-debug``: Also write a FSDB waveform + * ``sim-par-timing-debug``: Timing-annotated with FSDB waveform + +* ``power-rtl``: RTL-level power estimation + + * Note: this will run ``sim-rtl-debug`` first + +* ``power-syn``: Post-synthesis power estimation + + * Note: this will run ``sim-syn-debug`` first * ``power-par``: Post-par power estimation - * Note: this will run ``sim-par`` first + * Note: this will run ``sim-par-debug`` first * ``redo-`` can be appended to all above targets to break dependency tracking, like described above. diff --git a/vlsi/Makefile b/vlsi/Makefile index a25cc746..210589fb 100644 --- a/vlsi/Makefile +++ b/vlsi/Makefile @@ -109,122 +109,6 @@ $(SRAM_CONF): $(SRAM_GENERATOR_CONF) cd $(vlsi_dir) && $(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(SRAM_GENERATOR_CONF), -p $(x)) --obj_dir $(build_dir) sram_generator cd $(vlsi_dir) && cp output.json $@ -######################################################################################### -# simulation input configuration -######################################################################################### -include $(base_dir)/vcs.mk - -SIM_FILE_REQS += \ - $(ROCKETCHIP_RSRCS_DIR)/vsrc/TestDriver.v - -# copy files but ignore *.h files in *.f since vcs has +incdir+$(build_dir) -$(sim_files): $(SIM_FILE_REQS) | $(build_dir) - cp -f $^ $(build_dir) - $(foreach file,\ - $^,\ - $(if $(filter %.h,$(file)),\ - ,\ - echo "$(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;)) - -SIM_CONF = $(OBJ_DIR)/sim-inputs.yml -SIM_DEBUG_CONF = $(OBJ_DIR)/sim-debug-inputs.yml -SIM_TIMING_CONF = $(OBJ_DIR)/sim-timing-inputs.yml - -include $(vlsi_dir)/sim.mk -$(SIM_CONF): $(sim_common_files) - mkdir -p $(dir $@) - echo "sim.inputs:" > $@ - echo " top_module: $(VLSI_TOP)" >> $@ - echo " tb_name: ''" >> $@ # don't specify -top - echo " input_files:" >> $@ - for x in $(shell cat $(sim_common_files)); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " input_files_meta: 'append'" >> $@ - echo " timescale: '1ns/10ps'" >> $@ - echo " options:" >> $@ - for x in $(filter-out -f $(sim_common_files),$(VCS_NONCC_OPTS)); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " options_meta: 'append'" >> $@ - echo " defines:" >> $@ - for x in $(subst +define+,,$(PREPROC_DEFINES)); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " defines_meta: 'append'" >> $@ - echo " compiler_cc_opts:" >> $@ - for x in $(filter-out "",$(VCS_CXXFLAGS)); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " compiler_cc_opts_meta: 'append'" >> $@ - echo " compiler_ld_opts:" >> $@ - for x in $(filter-out "",$(VCS_LDFLAGS)); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " compiler_ld_opts_meta: 'append'" >> $@ - echo " execution_flags_prepend: ['$(PERMISSIVE_ON)']" >> $@ - echo " execution_flags_append: ['$(PERMISSIVE_OFF)']" >> $@ - echo " execution_flags:" >> $@ - for x in $(SIM_FLAGS); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " execution_flags_meta: 'append'" >> $@ -ifneq ($(BINARY), ) - echo " benchmarks: ['$(BINARY)']" >> $@ -endif - echo " tb_dut: 'TestDriver.testHarness.$(VLSI_MODEL_DUT_NAME)'" >> $@ - -$(SIM_DEBUG_CONF): $(sim_common_files) - mkdir -p $(dir $@) - mkdir -p $(output_dir) - echo "sim.inputs:" > $@ - echo " defines: ['DEBUG']" >> $@ - echo " defines_meta: 'append'" >> $@ - echo " execution_flags:" >> $@ - for x in $(VERBOSE_FLAGS) $(WAVEFORM_FLAG); do \ - echo ' - "'$$x'"' >> $@; \ - done - echo " execution_flags_meta: 'append'" >> $@ - echo " saif.mode: 'time'" >> $@ - echo " saif.start_time: '0ns'" >> $@ - echo " saif.end_time: '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@ -ifndef USE_VPD - echo " options:" >> $@ - echo ' - "-kdb"' >> $@ - echo " options_meta: 'append'" >> $@ - echo "sim.outputs.waveforms: ['$(sim_out_name).fsdb']" >> $@ -else - echo "sim.outputs.waveforms: ['$(sim_out_name).vpd']" >> $@ -endif - -$(SIM_TIMING_CONF): $(sim_common_files) - mkdir -p $(dir $@) - echo "sim.inputs:" > $@ - echo " defines: ['NTC']" >> $@ - echo " defines_meta: 'append'" >> $@ - echo " timing_annotated: 'true'" >> $@ - -POWER_CONF = $(OBJ_DIR)/power-inputs.yml -include $(vlsi_dir)/power.mk -$(POWER_CONF): $(VLSI_RTL) - mkdir -p $(dir $@) - echo "power.inputs:" > $@ - echo " tb_dut: 'testHarness/$(VLSI_MODEL_DUT_NAME)'" >> $@ - echo " database: '$(OBJ_DIR)/par-rundir/$(VLSI_TOP)_FINAL'" >> $@ -ifneq ($(BINARY), ) - echo " waveforms: [" >> $@ -ifndef USE_VPD - echo " '$(sim_out_name).fsdb'" >> $@ -else - echo " '$(sim_out_name).vpd'" >> $@ -endif - echo " ]" >> $@ -endif - echo " start_times: ['0ns']" >> $@ - echo " end_times: [" >> $@ - echo " '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@ - echo " ]" >> $@ - ######################################################################################### # synthesis input configuration ######################################################################################### @@ -243,6 +127,27 @@ $(SYN_CONF): $(VLSI_RTL) echo ' - "'$$x'"' >> $@; \ done +######################################################################################### +# simulation and power input configuration +######################################################################################### +include $(base_dir)/vcs.mk + +SIM_FILE_REQS += \ + $(ROCKETCHIP_RSRCS_DIR)/vsrc/TestDriver.v + +# copy files but ignore *.h files in *.f since vcs has +incdir+$(build_dir) +$(sim_files): $(SIM_FILE_REQS) | $(build_dir) + cp -f $^ $(build_dir) + $(foreach file,\ + $^,\ + $(if $(filter %.h,$(file)),\ + ,\ + echo "$(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;)) + +include $(vlsi_dir)/sim.mk + +include $(vlsi_dir)/power.mk + ######################################################################################### # AUTO BUILD FLOW ######################################################################################### diff --git a/vlsi/example-tools.yml b/vlsi/example-tools.yml index 23744eaa..57cfd124 100644 --- a/vlsi/example-tools.yml +++ b/vlsi/example-tools.yml @@ -18,5 +18,6 @@ vlsi.core.sim_tool: "hammer.sim.vcs" sim.vcs.version: "S-2021.09-SP1-1" # Voltus options vlsi.core.power_tool: "hammer.power.voltus" +power.joules.version: "211" power.voltus.version: "211_ISR3" # NOTE (about VCS+Voltus versions): if using FSDB, the VCS version should be approx 2 years older than the Voltus version for compatibility diff --git a/vlsi/power.mk b/vlsi/power.mk index 7fcc5c67..bc7359ee 100644 --- a/vlsi/power.mk +++ b/vlsi/power.mk @@ -1,10 +1,75 @@ -.PHONY: $(POWER_CONF) -power-par: $(POWER_CONF) sim-par-debug -power-par-$(VLSI_TOP): $(POWER_CONF) sim-par-debug-$(VLSI_TOP) -power-par: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -power-par-$(VLSI_TOP): override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -redo-power-par: $(POWER_CONF) -redo-power-par-$(VLSI_TOP): $(POWER_CONF) -redo-power-par: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -redo-power-par-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -$(OBJ_DIR)/power-par-%/power-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_POWER_EXTRA_ARGS) +POWER_CONF = $(OBJ_DIR)/power-inputs.yml +POWER_RTL_CONF = $(OBJ_DIR)/power-rtl-inputs.yml +POWER_SYN_CONF = $(OBJ_DIR)/power-syn-inputs.yml +POWER_PAR_CONF = $(OBJ_DIR)/power-par-inputs.yml + +.PHONY: $(POWER_CONF) $(POWER_RTL_CONF) $(POWER_SYN_CONF) $(POWER_PAR_CONF) + +$(POWER_CONF): $(VLSI_RTL) + mkdir -p $(dir $@) + echo "power.inputs:" > $@ + echo " top_module: $(VLSI_TOP)" >> $@ + echo " tb_name: TestDriver" >> $@ + echo " tb_dut: 'testHarness/$(VLSI_MODEL_DUT_NAME)'" >> $@ +ifneq ($(BINARY), ) + echo " waveforms: [" >> $@ +ifndef USE_VPD + echo " '$(sim_out_name).fsdb'" >> $@ +else + echo " '$(sim_out_name).vpd'" >> $@ +endif + echo " ]" >> $@ +endif + echo " start_times: ['0ns']" >> $@ + echo " end_times: [" >> $@ + echo " '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@ + echo " ]" >> $@ + +$(POWER_RTL_CONF): $(VLSI_RTL) + echo "vlsi.core.power_tool: hammer.power.joules" > $@ + echo "power.inputs:" >> $@ + echo " level: rtl" >> $@ + echo " input_files:" >> $@ + for x in $(shell cat $(VLSI_RTL)); do \ + echo ' - "'$$x'"' >> $@; \ + done + +$(POWER_SYN_CONF): $(VLSI_RTL) + echo "vlsi.core.power_tool: hammer.power.joules" > $@ + echo "power.inputs:" >> $@ + echo " level: syn" >> $@ + +$(POWER_PAR_CONF): $(VLSI_RTL) + echo "vlsi.core.power_tool: hammer.power.voltus" > $@ + echo "power.inputs:" >> $@ + echo " level: par" >> $@ + echo " database: '$(OBJ_DIR)/par-rundir/$(VLSI_TOP)_FINAL'" >> $@ + +power-rtl: $(POWER_CONF) $(POWER_RTL_CONF) sim-rtl-debug +power-rtl-$(VLSI_TOP): $(POWER_CONF) $(POWER_RTL_CONF) sim-rtl-debug-$(VLSI_TOP) +power-rtl: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_RTL_CONF) +power-rtl-$(VLSI_TOP): override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_RTL_CONF) +redo-power-rtl: $(POWER_CONF) $(POWER_RTL_CONF) +redo-power-rtl-$(VLSI_TOP): $(POWER_CONF) $(POWER_RTL_CONF) +redo-power-rtl: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_RTL_CONF) +redo-power-rtl-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_RTL_CONF) + +power-syn: $(POWER_CONF) $(POWER_SYN_CONF) sim-syn-debug +power-syn-$(VLSI_TOP): $(POWER_CONF) $(POWER_SYN_CONF) sim-syn-debug-$(VLSI_TOP) +power-syn: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_SYN_CONF) +power-syn-$(VLSI_TOP): override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_SYN_CONF) +redo-power-syn: $(POWER_CONF) $(POWER_SYN_CONF) +redo-power-syn-$(VLSI_TOP): $(POWER_CONF) $(POWER_SYN_CONF) +redo-power-syn: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_SYN_CONF) +redo-power-syn-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_SYN_CONF) + +power-par: $(POWER_CONF) $(POWER_PAR_CONF) sim-par-debug +power-par-$(VLSI_TOP): $(POWER_CONF) $(POWER_PAR_CONF) sim-par-debug-$(VLSI_TOP) +power-par: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_PAR_CONF) +power-par-$(VLSI_TOP): override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_PAR_CONF) +redo-power-par: $(POWER_CONF) $(POWER_PAR_CONF) +redo-power-par-$(VLSI_TOP): $(POWER_CONF) $(POWER_PAR_CONF) +redo-power-par: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_PAR_CONF) +redo-power-par-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -p $(POWER_PAR_CONF) + +$(OBJ_DIR)/power-%/power-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_POWER_EXTRA_ARGS) diff --git a/vlsi/sim.mk b/vlsi/sim.mk index 5bd02853..65b836cc 100644 --- a/vlsi/sim.mk +++ b/vlsi/sim.mk @@ -1,4 +1,82 @@ +SIM_CONF = $(OBJ_DIR)/sim-inputs.yml +SIM_DEBUG_CONF = $(OBJ_DIR)/sim-debug-inputs.yml +SIM_TIMING_CONF = $(OBJ_DIR)/sim-timing-inputs.yml + .PHONY: $(SIM_CONF) $(SIM_DEBUG_CONF) $(SIM_TIMING_CONF) + +$(SIM_CONF): $(sim_common_files) + mkdir -p $(dir $@) + echo "sim.inputs:" > $@ + echo " top_module: $(VLSI_TOP)" >> $@ + echo " tb_name: ''" >> $@ # don't specify -top + echo " input_files:" >> $@ + for x in $(shell cat $(sim_common_files)); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " input_files_meta: 'append'" >> $@ + echo " timescale: '1ns/10ps'" >> $@ + echo " options:" >> $@ + for x in $(filter-out -f $(sim_common_files),$(VCS_NONCC_OPTS)); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " options_meta: 'append'" >> $@ + echo " defines:" >> $@ + for x in $(subst +define+,,$(PREPROC_DEFINES)); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " defines_meta: 'append'" >> $@ + echo " compiler_cc_opts:" >> $@ + for x in $(filter-out "",$(VCS_CXXFLAGS)); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " compiler_cc_opts_meta: 'append'" >> $@ + echo " compiler_ld_opts:" >> $@ + for x in $(filter-out "",$(VCS_LDFLAGS)); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " compiler_ld_opts_meta: 'append'" >> $@ + echo " execution_flags_prepend: ['$(PERMISSIVE_ON)']" >> $@ + echo " execution_flags_append: ['$(PERMISSIVE_OFF)']" >> $@ + echo " execution_flags:" >> $@ + for x in $(SIM_FLAGS); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " execution_flags_meta: 'append'" >> $@ +ifneq ($(BINARY), ) + echo " benchmarks: ['$(BINARY)']" >> $@ +endif + echo " tb_dut: 'TestDriver.testHarness.$(VLSI_MODEL_DUT_NAME)'" >> $@ + +$(SIM_DEBUG_CONF): $(sim_common_files) + mkdir -p $(dir $@) + mkdir -p $(output_dir) + echo "sim.inputs:" > $@ + echo " defines: ['DEBUG']" >> $@ + echo " defines_meta: 'append'" >> $@ + echo " execution_flags:" >> $@ + for x in $(VERBOSE_FLAGS) $(WAVEFORM_FLAG); do \ + echo ' - "'$$x'"' >> $@; \ + done + echo " execution_flags_meta: 'append'" >> $@ + echo " saif.mode: 'time'" >> $@ + echo " saif.start_time: '0ns'" >> $@ + echo " saif.end_time: '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@ +ifndef USE_VPD + echo " options:" >> $@ + echo ' - "-kdb"' >> $@ + echo " options_meta: 'append'" >> $@ + echo "sim.outputs.waveforms: ['$(sim_out_name).fsdb']" >> $@ +else + echo "sim.outputs.waveforms: ['$(sim_out_name).vpd']" >> $@ +endif + +$(SIM_TIMING_CONF): $(sim_common_files) + mkdir -p $(dir $@) + echo "sim.inputs:" > $@ + echo " defines: ['NTC']" >> $@ + echo " defines_meta: 'append'" >> $@ + echo " timing_annotated: 'true'" >> $@ + # Update hammer top-level sim targets to include our generated sim configs redo-sim-rtl: $(SIM_CONF) redo-sim-rtl-$(VLSI_TOP): $(SIM_CONF)