Vcd var lookup

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-11-01 19:08:22 -07:00
parent 3ba89a1a9c
commit aff6342435
7 changed files with 173 additions and 44 deletions

Binary file not shown.

View File

@ -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

View File

@ -28,7 +28,6 @@
namespace sta {
using std::min;
using std::swap;
using std::to_string;
class ReadVcdActivities : public StaState
@ -41,9 +40,17 @@ public:
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_;
@ -83,8 +90,6 @@ ReadVcdActivities::readActivities()
for (Clock *clk : *sta_->sdc()->clocks())
clk_period_ = min(clk->period(), clk_period_);
//checkClkPeriods();
setActivities();
}
@ -92,12 +97,12 @@ 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_)
@ -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;
@ -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++;
}
}
@ -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++;
}
}
@ -140,11 +145,39 @@ ReadVcdActivities::setActivities()
}
void
ReadVcdActivities::findVarActivity(const char *pin_name,
int value_bit,
const VcdValues &var_values)
ReadVcdActivities::setVarActivity(const char *pin_name,
const VcdValues &var_values,
int value_bit)
{
int transition_count = 0;
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,
// Return values.
int &transition_count,
float &activity,
float &duty)
{
transition_count = 0;
char prev_value = var_values[0].value();
VcdTime prev_time = var_values[0].time();
VcdTime high_time = 0;
@ -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);
}
}
}

View File

@ -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,
@ -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
@ -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)
{
@ -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()];
}
////////////////////////////////////////////////////////////////

View File

@ -36,6 +36,7 @@ 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 };
@ -43,7 +44,12 @@ 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);
@ -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,
@ -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_;

View File

@ -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;
@ -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
@ -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);
}
}
}
}

View File

@ -30,4 +30,10 @@ void
reportVcdWaveforms(const char *filename,
StaState *sta);
}
void
reportVcdVarValues(const char *filename,
const char *var_name,
StaState *sta);
} // namespace