Skip to content

Commit

Permalink
Vcd var lookup
Browse files Browse the repository at this point in the history
Signed-off-by: James Cherry <[email protected]>
  • Loading branch information
jjcherry56 committed Nov 2, 2022
1 parent 3ba89a1 commit aff6342
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 43 deletions.
Binary file modified doc/OpenSTA.odt
Binary file not shown.
8 changes: 8 additions & 0 deletions power/Power.i
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,12 @@ report_vcd_waveforms(const char *filename)
reportVcdWaveforms(filename, Sta::sta());
}

// debugging
void
report_vcd_var_values(const char *filename,
const char *var_name)
{
reportVcdVarValues(filename, var_name, Sta::sta());
}

%} // inline
92 changes: 64 additions & 28 deletions power/ReadVcdActivities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
namespace sta {

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

class ReadVcdActivities : public StaState
Expand All @@ -41,9 +40,17 @@ class ReadVcdActivities : public StaState

private:
void setActivities();
void findVarActivity(const char *pin_name,
void setVarActivity(const char *pin_name,
const VcdValues &var_values,
int value_bit);
void findVarActivity(const VcdValues &var_values,
int value_bit,
const VcdValues &var_values);
// Return values.
int &transition_count,
float &activity,
float &duty);
void checkClkPeriod(const Pin *pin,
int transition_count);

const char *filename_;
const char *scope_;
Expand Down Expand Up @@ -83,21 +90,19 @@ ReadVcdActivities::readActivities()
for (Clock *clk : *sta_->sdc()->clocks())
clk_period_ = min(clk->period(), clk_period_);

//checkClkPeriods();

setActivities();
}

void
ReadVcdActivities::setActivities()
{
size_t scope_length = strlen(scope_);
for (VcdVar &var : vcd_.vars()) {
for (VcdVar *var : vcd_.vars()) {
const VcdValues &var_values = vcd_.values(var);
if (!var_values.empty()
&& (var.type() == VcdVarType::wire
|| var.type() == VcdVarType::reg)) {
string var_name = var.name();
&& (var->type() == VcdVarType::wire
|| var->type() == VcdVarType::reg)) {
string var_name = var->name();
// string::starts_with in c++20
if (scope_length
&& var_name.substr(0, scope_length) == scope_)
Expand All @@ -106,8 +111,8 @@ ReadVcdActivities::setActivities()
var_name += ' ';
const char *sta_name = verilogToSta(var_name.c_str());

if (var.width() == 1)
findVarActivity(sta_name, 0, var_values);
if (var->width() == 1)
setVarActivity(sta_name, var_values, 0);
else {
char *bus_name;
int from, to;
Expand All @@ -120,7 +125,7 @@ ReadVcdActivities::setActivities()
pin_name += '[';
pin_name += to_string(bus_bit);
pin_name += ']';
findVarActivity(pin_name.c_str(), value_bit, var_values);
setVarActivity(pin_name.c_str(), var_values, value_bit);
value_bit++;
}
}
Expand All @@ -130,7 +135,7 @@ ReadVcdActivities::setActivities()
pin_name += '[';
pin_name += to_string(bus_bit);
pin_name += ']';
findVarActivity(pin_name.c_str(), value_bit, var_values);
setVarActivity(pin_name.c_str(), var_values, value_bit);
value_bit++;
}
}
Expand All @@ -140,11 +145,39 @@ ReadVcdActivities::setActivities()
}

void
ReadVcdActivities::findVarActivity(const char *pin_name,
ReadVcdActivities::setVarActivity(const char *pin_name,
const VcdValues &var_values,
int value_bit)
{
const Pin *pin = network_->findPin(pin_name);
if (pin) {
int transition_count;
float activity, duty;
findVarActivity(var_values, value_bit,
transition_count, activity, duty);
debugPrint(debug_, "read_vcd_activities", 1,
"%s transitions %d activity %.2f duty %.2f",
pin_name,
transition_count,
activity,
duty);
if (sdc_->isLeafPinClock(pin))
checkClkPeriod(pin, transition_count);
else
power_->setUserActivity(pin, activity, duty,
PwrActivityOrigin::user);
}
}

void
ReadVcdActivities::findVarActivity(const VcdValues &var_values,
int value_bit,
const VcdValues &var_values)
// Return values.
int &transition_count,
float &activity,
float &duty)
{
int transition_count = 0;
transition_count = 0;
char prev_value = var_values[0].value();
VcdTime prev_time = var_values[0].time();
VcdTime high_time = 0;
Expand All @@ -164,20 +197,23 @@ ReadVcdActivities::findVarActivity(const char *pin_name,
VcdTime time_max = vcd_.timeMax();
if (prev_value == '1')
high_time += time_max - prev_time;
float duty = static_cast<float>(high_time) / time_max;
float activity = transition_count
duty = static_cast<float>(high_time) / time_max;
activity = transition_count
/ (time_max * vcd_.timeUnitScale() / clk_period_);
}

Pin *pin = network_->findPin(pin_name);
if (pin) {
debugPrint(debug_, "read_vcd_activities", 1,
"%s transitions %d activity %.2f duty %.2f",
pin_name,
transition_count,
activity,
duty);
power_->setUserActivity(pin, activity, duty,
PwrActivityOrigin::user);
void
ReadVcdActivities::checkClkPeriod(const Pin *pin,
int transition_count)
{
VcdTime time_max = vcd_.timeMax();
float sim_period = time_max * vcd_.timeUnitScale() / ((transition_count - 1) / 2.0);

ClockSet *clks = sdc_->findLeafPinClocks(pin);
if (clks) {
for (Clock *clk : *clks) {
//printf("%.2e %.2e\n", clk->period(), sim_period);
}
}
}

Expand Down
67 changes: 59 additions & 8 deletions power/Vcd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,50 @@ Vcd::Vcd(StaState *sta) :
{
}

////////////////////////////////////////////////////////////////
Vcd::Vcd(const Vcd &vcd) :
StaState(vcd),
date_(vcd.date_),
comment_(vcd.comment_),
version_(vcd.version_),
time_scale_(vcd.time_scale_),
time_unit_(vcd.time_unit_),
time_unit_scale_(vcd.time_unit_scale_),
vars_(vcd.vars_),
var_name_map_(vcd.var_name_map_),
max_var_name_length_(vcd.max_var_name_length_),
max_var_width_(vcd.max_var_width_),
id_values_map_(vcd.id_values_map_),
min_delta_time_(vcd.min_delta_time_),
time_max_(vcd.time_max_)
{
}

Vcd&
Vcd::operator=(Vcd &&vcd1)
{
date_ = vcd1.date_;
comment_ = vcd1.comment_;
version_ = vcd1.version_;
time_scale_ = vcd1.time_scale_;
time_unit_ = vcd1.time_unit_;
time_unit_scale_ = vcd1.time_unit_scale_;
vars_ = vcd1.vars_;
var_name_map_ = vcd1.var_name_map_;
max_var_name_length_ = vcd1.max_var_name_length_;
max_var_width_ = vcd1.max_var_width_;
id_values_map_ = vcd1.id_values_map_;
min_delta_time_ = vcd1.min_delta_time_;
time_max_ = vcd1.time_max_;

vcd1.vars_.clear();
return *this;
}

Vcd::~Vcd()
{
for (VcdVar *var : vars_)
delete var;
}

void
Vcd::setTimeUnit(const string &time_unit,
Expand Down Expand Up @@ -72,7 +115,7 @@ Vcd::setMinDeltaTime(VcdTime min_delta_time)
void
Vcd::setTimeMax(VcdTime time_max)
{
time_max_ = time_max;
time_max_ = time_max;
}

void
Expand All @@ -81,13 +124,21 @@ Vcd::makeVar(string &name,
int width,
string &id)
{
vars_.push_back(VcdVar(name, type, width, id));
VcdVar *var = new VcdVar(name, type, width, id);
vars_.push_back(var);
var_name_map_[name] = var;
max_var_name_length_ = std::max(max_var_name_length_, name.size());
max_var_width_ = std::max(max_var_width_, width);
// Make entry for var ID.
id_values_map_[id].clear();
}

VcdVar *
Vcd::var(const string name)
{
return var_name_map_[name];
}

bool
Vcd::varIdValid(string &id)
{
Expand All @@ -113,17 +164,17 @@ Vcd::varAppendBusValue(string &id,
}

VcdValues &
Vcd::values(VcdVar &var)
Vcd::values(VcdVar *var)
{
if (id_values_map_.find(var.id()) == id_values_map_.end()) {
if (id_values_map_.find(var->id()) == id_values_map_.end()) {
report_->error(805, "Unknown variable %s ID %s",
var.name().c_str(),
var.id().c_str());
var->name().c_str(),
var->id().c_str());
static VcdValues empty;
return empty;
}
else
return id_values_map_[var.id()];
return id_values_map_[var->id()];
}

////////////////////////////////////////////////////////////////
Expand Down
13 changes: 10 additions & 3 deletions power/Vcd.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@ class VcdValue;
typedef vector<VcdValue> VcdValues;
typedef int64_t VcdTime;
typedef vector<string> VcdScope;
typedef map<string, VcdVar*> VcdNameMap;

enum class VcdVarType { wire, reg, parameter, real };

class Vcd : public StaState
{
public:
Vcd(StaState *sta);
VcdValues &values(VcdVar &var);
Vcd(const Vcd &vcd);
// Move copy assignment.
Vcd& operator=(Vcd &&vcd1);
~Vcd();
VcdVar *var(const string name);
VcdValues &values(VcdVar *var);

const string &date() const { return date_; }
void setDate(const string &date);
Expand All @@ -61,7 +67,7 @@ public:
void setTimeMax(VcdTime time_max);
VcdTime minDeltaTime() const { return min_delta_time_; }
void setMinDeltaTime(VcdTime min_delta_time);
vector<VcdVar> vars() { return vars_; }
vector<VcdVar*> vars() { return vars_; }
void makeVar(string &name,
VcdVarType type,
int width,
Expand All @@ -84,7 +90,8 @@ private:
string time_unit_;
double time_unit_scale_;

vector<VcdVar> vars_;
vector<VcdVar*> vars_;
VcdNameMap var_name_map_;
size_t max_var_name_length_;
int max_var_width_;
map<string, VcdValues> id_values_map_;
Expand Down
27 changes: 24 additions & 3 deletions power/VcdReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,11 @@ reportWaveforms(Vcd &vcd,
int time_delta = vcd.minDeltaTime();

int max_var_name_length = vcd.maxVarNameLength();
for (VcdVar &var : vcd.vars()) {
for (VcdVar *var : vcd.vars()) {
string line;
stringPrint(line, " %-*s",
static_cast<int>(max_var_name_length),
var.name().c_str());
var->name().c_str());
const VcdValues &var_values = vcd.values(var);
if (!var_values.empty()) {
size_t value_index = 0;
Expand All @@ -367,7 +367,7 @@ reportWaveforms(Vcd &vcd,
// 01UZX
char value = var_value.value();
char prev_value = prev_var_value.value();
if (var.width() == 1) {
if (var->width() == 1) {
if (value == '0' || value == '1') {
for (int z = 0; z < zoom; z++) {
if (z == 0
Expand Down Expand Up @@ -404,4 +404,25 @@ reportWaveforms(Vcd &vcd,
}
}

void
reportVcdVarValues(const char *filename,
const char *var_name,
StaState *sta)
{
Vcd vcd = readVcdFile(filename, sta);
VcdVar *var = vcd.var(var_name);
if (var) {
Report *report = sta->report();
for (const VcdValue &var_value : vcd.values(var)) {
double time = var_value.time() * vcd.timeUnitScale();
char value = var_value.value();
if (value == '\0')
report->reportLine("%.2e %llu",
time, var_value.busValue());
else
report->reportLine("%.2e %c", time, value);
}
}
}

}
8 changes: 7 additions & 1 deletion power/VcdReader.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ void
reportVcdWaveforms(const char *filename,
StaState *sta);

}
void
reportVcdVarValues(const char *filename,
const char *var_name,
StaState *sta);

} // namespace

0 comments on commit aff6342

Please sign in to comment.