Power estimation in OpenROAD using the SAIF wave format in Verilator
Published:
Topics: Open source tools, Open ASICs, Open FPGA
Power consumption is a major aspect of chip design, and the ability to reliably and efficiently predict it can save a lot of engineering cycles. While it is difficult to predict the exact consumption upfront without delving into the physical aspects of the implementation, RTL simulators such as Verilator can generate information about changes of signals over time, which can then be further processed and visualized to provide digital designers with some good insights and ability to reason about the expected behavior of their system.
The VCD (Value Change Dump) format supported by many simulators, Verilator included, provides detailed information about each value change of every signal in time. While useful for a lot of scenarios such as debugging, VCD files tend to grow rather large (even to gigabytes) with simulation time. SAIF (Switching Activity Interchange Format) is a format developed as an alternative to VCD, intended for analyzing cumulative switching activity. SAIF files only grow with the size of the simulated model, as they only accumulate signal statistics instead saving every change separately.
This more coarse-grained information can be perfectly fine for use cases like power estimation, and so for a recent project we added support for SAIF into Verilator to enable more efficient power analysis for our customer. In this article we describe our work on introducing support for SAIF in Verilator and showcase its application with a static power analysis workflow of a post-synthesis design with Verilator and the open source OpenROAD ASIC design toolchain.
SAIF support in Verilator
The SAIF format is based on static probability and toggle rate, and is used for analyzing power consumption in a digital design. A SAIF file provides information about changes in signals over time, including:
- T0 - duration for which a signal remains in logic state 0
- T1 - duration for which a signal remains in logic state 1
- TX - duration for which a signal remains in logic state X (unknown)
- TC - Toggle Count
Thanks to their smaller size, SAIF files enable faster and more efficient processing by power analysis tools.
A SAIF simulation trace can now be generated with Verilator by using the VerilatedSaifC
trace class in simulation code and the --trace-saif
flag while generating C++ code from the design (i.e. verilating it).
As an example, let’s use a simple Verilog design:
module counter (clk, state);
input clk;
output[7:0] state;
reg[7:0] counter = 0;
assign state = counter;
always @ (posedge clk) begin
counter <= counter + 1;
end
endmodule
A SAIF file generated from this design with the same simulation conditions (duration and timescale) is smaller compared to a VCD file and this difference will become more significant as the design size and simulation time increase, as VCD stores every change of variable values, while SAIF compresses that down to accumulated statistics.
Static power analysis with Verilator and OpenROAD
Performing static power analysis with Verilator and OpenROAD requires the design to be processed with a process design kit (PDK). It can be done by running synthesis and place and route steps flow scripts provided by OpenROAD-flow-scripts. To use them, you will also need the config.mk
and constraint.sdc
files, which describe the design parameters necessary for those steps. For the counter
example we will use the following configuration files:
# config.mk
export PLATFORM = asap7
export DESIGN_NAME = counter
export VERILOG_FILES = $(sort $(wildcard $(DESIGN_HOME)/src/$(DESIGN_NAME)/*.v))
export SDC_FILE = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NAME)/constraint.sdc
export DIE_AREA = 0 0 13.8 13.8
export CORE_AREA = 1.04 1.04 13.4 13.4
export PLACE_DENSITY = 0.20
and
# constraint.sdc
current_design counter
set clk_name core_clock
set clk_port_name clk
set clk_period 200
set clk_port [get_ports $clk_port_name]
create_clock -name $clk_name -period $clk_period $clk_port
set non_clock_inputs [lsearch -inline -all -not -exact [all_inputs] $clk_port]
They contain information about the used platform, design name, path to Verilog sources, place and route step parameters and which signal is a clock. OpenROAD-flow-scripts expects you to place those configuration files in the flow/designs/{PLATFORM}/{DESIGN_NAME}
directory.
To execute the synthesis and place and route steps, from the OpenROAD-flow-scripts project base directory run:
make -C flow DESIGN_CONFIG=designs/asap7/counter/config.mk route
This will generate 1_synth.v
containing the Verilog source of the synthesized design and 5_route.odb
with the design after the place and route step. Those files will be located in the flow/results/{PLATFORM}/{DESIGN_NAME}/base
directory and you can now use 1_synth.v
(further renamed as counter.v
for simplicity) to generate a SAIF file with Verilator. For this simulation step, you will need the asap7 PDK Verilog sources. In this example we will use the asap7sc7p5t_28 version. Simulation will be driven by the counter_tb.cpp
test benchmark code, which uses the previously mentioned VerilatedSaifC
class for collecting signal changes to generate a SAIF file:
// counter_tb.cpp
#include <memory>
#include <verilated.h>
// SAIF generator header
#include <verilated_saif_c.h>
#include "Vcounter.h"
int main(int argc, char** argv) {
Verilated::debug(0);
Verilated::traceEverOn(true);
Verilated::commandArgs(argc, argv);
static constexpr const char* TOP_SCOPE_NAME{"counter_tb"};
std::unique_ptr<Vcounter> top{new Vcounter{TOP_SCOPE_NAME}};
// Initialize SAIF generator
std::unique_ptr<VerilatedSaifC> tfp{new VerilatedSaifC};
// Specify simulation trace generator
static constexpr int SIMULATION_DURATION{1000};
top->trace(tfp.get(), SIMULATION_DURATION);
// Create output for SAIF file
static constexpr const char* TRACE_FILE_NAME{"sim.saif"};
tfp->open(TRACE_FILE_NAME);
unsigned int main_time = 0;
while (main_time <= SIMULATION_DURATION) {
top->clk = !top->clk;
top->eval();
tfp->dump(main_time);
main_time += 10;
}
// Finish simulation and SAIF generator
tfp->close();
top->final();
tfp.reset();
top.reset();
printf("*-* All Finished *-*\n");
return 0;
}
Verilator will need asap7 cells Verilog sources, which are located in the Verilog
directory of the asap7sc7p5t_28 project. We will add it as an include directory by specifying the path to it as an ASAP7_SRC
environmental variable. Finally, run verilation and simulation:
verilator --cc --build --exe --trace-saif -Wno-TIMESCALEMOD --top-module counter -I$ASAP7_SRC \
counter.v \
counter_tb.cpp \
asap7sc7p5t_INVBUF_RVT_TT_201020.v \
asap7sc7p5t_SEQ_RVT_TT_220101.v \
asap7sc7p5t_SIMPLE_RVT_TT_201020.v \
asap7sc7p5t_OA_RVT_TT_201020.v \
asap7sc7p5t_AO_RVT_TT_201020.v
./obj_dir/Vcounter
This will generate a simulation trace file called sim.saif
containing information about changes in signals over time, which can be now fed to the OpenROAD toolchain for power estimation. OpenROAD leverages the OpenSTA static timing analyzer to generate a power consumption report. OpenSTA will iterate over the file, gather the information into pin average activity and use that information to generate a power consumption report for the given design.
For simplicity, set the path to asap7 liberty files as a LIB_DIR
environmental variable. OpenROAD-flow-scripts provides liberty files for supported platforms in the flow/platforms/{PLATFORM}/lib
directory. For asap7, it will be flow/platforms/asap7/lib/NLDM/
. To generate a power consumption report, run:
openroad power.tcl -exit
where power.tcl
is a TCL script with the necessary commands:
# power.tcl
read_liberty $::env(LIB_DIR)/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz
read_liberty $::env(LIB_DIR)/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz
read_liberty $::env(LIB_DIR)/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz
read_liberty $::env(LIB_DIR)/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz
read_liberty $::env(LIB_DIR)/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib
read_db 5_route.odb
read_sdc 1_synth.sdc
read_saif -scope counter_tb/counter sim.saif
report_power
read_liberty
loads information about PDK cells power usage from the previously mentioned liberty files. read_db
and read_sdc
load the design and its parameters. The 1_synth.sdc
file is just constraint.sdc
copied to the result directory during the synthesis step. read_saif
loads the provided SAIF file and narrows the scope to the specified one - in this example counter_tb/counter
. Finally, report_power
leverages the given information and generates a static power analysis report.
An OpenROAD static power analysis report for a SAIF file generated from the example Verilog design is shown below:
The power estimate shows that most of the power dissipation is internal. Based on the report you can evaluate the power usage of different components of your design and identify potential optimization options, then run simulation and analysis again to compare the results.
A more complex example of using the SAIF format for static power analysis of a post-synthesis Ibex core can be found in a dedicated repository.
Open source-driven digital design optimization
SAIF support in Verilator, which is included in Verilator’s most recent release, enables more efficient power estimation and optimization during chip design. By combining it with the OpenROAD toolchain, we provide a flexible, open source-driven solution for analyzing signal activity and optimizing power efficiency.
Antmicro can help you adopt and customize Verilator and other open source ASIC design tools for real-world, large and complex designs, as showcased by the recently introduced improvements to Verilator’s hierarchical mode. If you would like to learn more about our engineering services, reach out to us at contact@antmicro.com and visit our offering page.