Skip to content

Commit

Permalink
read_vcd_activities
Browse files Browse the repository at this point in the history
Signed-off-by: James Cherry <[email protected]>
  • Loading branch information
jjcherry56 committed Oct 28, 2022
2 parents 15d9333 + f413437 commit cecb8cd
Show file tree
Hide file tree
Showing 17 changed files with 1,037 additions and 74 deletions.
18 changes: 12 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ set(STA_SOURCE
search/PathRef.cc
search/PathVertex.cc
search/PathVertexRep.cc
search/Power.cc
search/Property.cc
search/ReportPath.cc
search/Search.cc
Expand All @@ -189,6 +188,11 @@ set(STA_SOURCE
search/WorstSlack.cc
search/WritePathSpice.cc

power/Power.cc
power/ReadVcdActivities.cc
power/Vcd.cc
power/VcdReader.cc

util/Debug.cc
util/DispatchQueue.cc
util/Error.cc
Expand Down Expand Up @@ -227,10 +231,10 @@ set(STA_TCL_FILES
tcl/Cmds.tcl
tcl/Variables.tcl
tcl/Sta.tcl
tcl/Power.tcl
tcl/Splash.tcl
dcalc/DelayCalc.tcl
parasitics/Parasitics.tcl
power/Power.tcl
sdf/Sdf.tcl
verilog/Verilog.tcl
)
Expand Down Expand Up @@ -313,18 +317,20 @@ set_property(SOURCE ${STA_SWIG_FILE}
-I${STA_HOME}/sdf
-I${STA_HOME}/dcalc
-I${STA_HOME}/parasitics
-I${STA_HOME}/power
-I${STA_HOME}/verilog
)

set_property(SOURCE ${STA_SWIG_FILE}
PROPERTY DEPENDS
${STA_HOME}/dcalc/DelayCalc.i
${STA_HOME}/parasitics/Parasitics.i
${STA_HOME}/power/Power.i
${STA_HOME}/sdf/Sdf.i
${STA_HOME}/tcl/Exception.i
${STA_HOME}/tcl/StaTcl.i
${STA_HOME}/verilog/Verilog.i
${STA_HOME}/tcl/NetworkEdit.i
${STA_HOME}/sdf/Sdf.i
${STA_HOME}/parasitics/Parasitics.i
${STA_HOME}/dcalc/DelayCalc.i
${STA_HOME}/verilog/Verilog.i
)

swig_add_library(sta_swig
Expand Down
1 change: 1 addition & 0 deletions app/StaApp.i
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
%include "Sdf.i"
%include "DelayCalc.i"
%include "Parasitics.i"
%include "Power.i"
Binary file modified doc/OpenSTA.odt
Binary file not shown.
Binary file modified doc/OpenSTA.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions search/Power.cc → power/Power.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
#include "GraphDelayCalc.hh"
#include "Corner.hh"
#include "PathVertex.hh"
#include "Levelize.hh"
#include "Sim.hh"
#include "search/Levelize.hh"
#include "search/Sim.hh"
#include "Search.hh"
#include "Bfs.hh"
#include "ClkNetwork.hh"
Expand Down
File renamed without changes.
124 changes: 124 additions & 0 deletions power/Power.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
%module power

%{

// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#include "Sta.hh"
#include "power/Power.hh"
#include "power/VcdReader.hh"
#include "power/ReadVcdActivities.hh"

namespace sta {

typedef FloatSeq TmpFloatSeq;

} // namespace

using namespace sta;

%}

%typemap(out) TmpFloatSeq* {
FloatSeq *floats = $1;
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
if (floats) {
for (unsigned i = 0; i < floats->size(); i++) {
Tcl_Obj *obj = Tcl_NewDoubleObj((*floats)[i]);
Tcl_ListObjAppendElement(interp, list, obj);
}
delete floats;
}
Tcl_SetObjResult(interp, list);
}

%inline %{

TmpFloatSeq *
design_power(const Corner *corner)
{
cmdLinkedNetwork();
PowerResult total, sequential, combinational, macro, pad;
Sta::sta()->power(corner, total, sequential, combinational, macro, pad);
FloatSeq *floats = new FloatSeq;
pushPowerResultFloats(total, floats);
pushPowerResultFloats(sequential, floats);
pushPowerResultFloats(combinational, floats);
pushPowerResultFloats(macro, floats);
pushPowerResultFloats(pad, floats);
return floats;
}

TmpFloatSeq *
instance_power(Instance *inst,
const Corner *corner)
{
cmdLinkedNetwork();
PowerResult power;
Sta::sta()->power(inst, corner, power);
FloatSeq *floats = new FloatSeq;
floats->push_back(power.internal());
floats->push_back(power.switching());
floats->push_back(power.leakage());
floats->push_back(power.total());
return floats;
}

void
set_power_global_activity(float activity,
float duty)
{
Sta::sta()->power()->setGlobalActivity(activity, duty);
}

void
set_power_input_activity(float activity,
float duty)
{
return Sta::sta()->power()->setInputActivity(activity, duty);
}

void
set_power_input_port_activity(const Port *input_port,
float activity,
float duty)
{
return Sta::sta()->power()->setInputPortActivity(input_port, activity, duty);
}

void
set_power_pin_activity(const Pin *pin,
float activity,
float duty)
{
return Sta::sta()->power()->setUserActivity(pin, activity, duty,
PwrActivityOrigin::user);
}

void
read_vcd_activities(const char *filename)
{
readVcdActivities(filename, Sta::sta());
}

void
report_vcd_waveforms(const char *filename)
{
reportVcdWaveforms(filename, Sta::sta());
}

%} // inline
5 changes: 5 additions & 0 deletions tcl/Power.tcl → power/Power.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ proc set_power_activity { args } {
}
}

################################################################

# Defined in StaTcl.i
define_cmd_args "read_vcd_activities" { filename }

proc power_find_nan { } {
set corner [cmd_corner]
foreach inst [network_leaf_instances] {
Expand Down
138 changes: 138 additions & 0 deletions power/ReadVcdActivities.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#include "ReadVcdActivities.hh"

#include "VcdReader.hh"
#include "Debug.hh"
#include "Network.hh"
#include "VerilogNamespace.hh"
#include "ParseBus.hh"
#include "Sdc.hh"
#include "Power.hh"
#include "Sta.hh"

namespace sta {

using std::min;
using std::swap;
using std::to_string;

static void
setVcdActivities(Vcd &vcd,
Sta *sta);
static void
setPinActivity(const char *pin_name,
int transition_count,
float activity,
float duty,
Debug *debug,
Network *network,
Power *power);
void
readVcdActivities(const char *filename,
Sta *sta)
{
Vcd vcd = readVcdFile(filename, sta);
setVcdActivities(vcd, sta);
}

static void
setVcdActivities(Vcd &vcd,
Sta *sta)
{
Debug *debug = sta->debug();
Network *network = sta->network();
Power *power = sta->power();

float clk_period = 0.0;
for (Clock *clk : *sta->sdc()->clocks())
clk_period = min(clk->period(), clk_period);

VarTime time_max = vcd.timeMax();
for (VcdVar &var : vcd.vars()) {
const VcdValues &var_values = vcd.values(var);
if (!var_values.empty()) {
int transition_count = 0;
char prev_value = var_values[0].value();
VarTime prev_time = var_values[0].time();
VarTime high_time = 0;
for (const VcdValue &var_value : var_values) {
VarTime time = var_value.time();
char value = var_value.value();
if (prev_value == '1')
high_time += time - prev_time;
transition_count++;
prev_time = time;
prev_value = value;
}
if (prev_value == '1')
high_time += time_max - prev_time;
float duty = static_cast<float>(high_time) / time_max;
float activity = transition_count
/ (time_max * vcd.timeUnitScale() / clk_period);

string var_name = var.name();
if (var_name[0] == '\\')
var_name += ' ';
const char *sta_name = verilogToSta(var_name.c_str());
if (var.width() == 1) {
setPinActivity(sta_name, transition_count, activity, duty,
debug, network, power);
}
else {
char *bus_name;
int from, to;
parseBusRange(sta_name, '[', ']', '\\',
bus_name, from, to);
if (from > to)
swap(from, to);
for (int bit = from; bit <= to; bit++) {
string name = bus_name;
name += '[';
name += to_string(bit);
name += ']';
setPinActivity(name.c_str(), transition_count, activity, duty,
debug, network, power);
}
}
}
}
}

static void
setPinActivity(const char *pin_name,
int transition_count,
float activity,
float duty,
Debug *debug,
Network *network,
Power *power)
{
Pin *pin = network->findPin(pin_name);
if (pin) {
debugPrint(debug, "vcd_activities", 1,
"%s transitions %d activity %.2f duty %.2f",
pin_name,
transition_count,
activity,
duty);
power->setUserActivity(pin, activity, duty,
PwrActivityOrigin::user);
}
}

}
27 changes: 27 additions & 0 deletions power/ReadVcdActivities.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#pragma once

namespace sta {

class Sta;

void
readVcdActivities(const char *filename,
Sta *sta);

} // namespace
Loading

0 comments on commit cecb8cd

Please sign in to comment.