read_vcd bus

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-10-30 10:17:40 -07:00
parent 5cca77d8a6
commit d5f1b2888d
2 changed files with 71 additions and 49 deletions

Binary file not shown.

View File

@ -35,13 +35,17 @@ static void
setVcdActivities(Vcd &vcd, setVcdActivities(Vcd &vcd,
Sta *sta); Sta *sta);
static void static void
setPinActivity(const char *pin_name, findVarActivity(const char *pin_name,
int transition_count, int value_bit,
float activity, const VcdValues &var_values,
float duty, Vcd &vcd,
Debug *debug, float clk_period,
Network *network, Debug *debug,
Power *power); Network *network,
Power *power);
////////////////////////////////////////////////////////////////
void void
readVcdActivities(const char *filename, readVcdActivities(const char *filename,
Sta *sta) Sta *sta)
@ -58,55 +62,48 @@ setVcdActivities(Vcd &vcd,
Network *network = sta->network(); Network *network = sta->network();
Power *power = sta->power(); Power *power = sta->power();
float clk_period = 0.0; float clk_period = INF;
for (Clock *clk : *sta->sdc()->clocks()) for (Clock *clk : *sta->sdc()->clocks())
clk_period = min(clk->period(), clk_period); clk_period = min(clk->period(), clk_period);
VcdTime time_max = vcd.timeMax();
for (VcdVar &var : vcd.vars()) { for (VcdVar &var : vcd.vars()) {
const VcdValues &var_values = vcd.values(var); const VcdValues &var_values = vcd.values(var);
if (!var_values.empty()) { if (!var_values.empty()) {
int transition_count = 0;
char prev_value = var_values[0].value();
VcdTime prev_time = var_values[0].time();
VcdTime high_time = 0;
for (const VcdValue &var_value : var_values) {
VcdTime 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(); string var_name = var.name();
if (var_name[0] == '\\') if (var_name[0] == '\\')
var_name += ' '; var_name += ' ';
const char *sta_name = verilogToSta(var_name.c_str()); const char *sta_name = verilogToSta(var_name.c_str());
if (var.width() == 1) {
setPinActivity(sta_name, transition_count, activity, duty, if (var.width() == 1)
debug, network, power); findVarActivity(sta_name, 0, var_values, vcd,
} clk_period, debug, network, power);
else { else {
char *bus_name; char *bus_name;
int from, to; int from, to;
parseBusRange(sta_name, '[', ']', '\\', parseBusRange(sta_name, '[', ']', '\\',
bus_name, from, to); bus_name, from, to);
if (from > to) int value_bit = 0;
swap(from, to); if (to < from) {
for (int bit = from; bit <= to; bit++) { for (int bus_bit = to; bus_bit <= from; bus_bit++) {
string name = bus_name; string pin_name = bus_name;
name += '['; pin_name += '[';
name += to_string(bit); pin_name += to_string(bus_bit);
name += ']'; pin_name += ']';
setPinActivity(name.c_str(), transition_count, activity, duty, findVarActivity(pin_name.c_str(), value_bit, var_values, vcd,
debug, network, power); clk_period, debug, network, power);
value_bit++;
}
}
else {
for (int bus_bit = to; bus_bit >= from; bus_bit--) {
string pin_name = bus_name;
pin_name += '[';
pin_name += to_string(bus_bit);
pin_name += ']';
findVarActivity(pin_name.c_str(), value_bit, var_values, vcd,
clk_period, debug, network, power);
value_bit++;
}
} }
} }
} }
@ -114,17 +111,42 @@ setVcdActivities(Vcd &vcd,
} }
static void static void
setPinActivity(const char *pin_name, findVarActivity(const char *pin_name,
int transition_count, int value_bit,
float activity, const VcdValues &var_values,
float duty, Vcd &vcd,
Debug *debug, float clk_period,
Network *network, Debug *debug,
Power *power) Network *network,
Power *power)
{ {
int transition_count = 0;
char prev_value = var_values[0].value();
VcdTime prev_time = var_values[0].time();
VcdTime high_time = 0;
for (const VcdValue &var_value : var_values) {
VcdTime time = var_value.time();
char value = var_value.value();
if (value == '\0') {
uint64_t bus_value = var_value.busValue();
value = ((bus_value >> value_bit) & 0x1) ? '1' : '0';
}
if (prev_value == '1')
high_time += time - prev_time;
transition_count++;
prev_time = time;
prev_value = value;
}
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
/ (time_max * vcd.timeUnitScale() / clk_period);
Pin *pin = network->findPin(pin_name); Pin *pin = network->findPin(pin_name);
if (pin) { if (pin) {
debugPrint(debug, "vcd_activities", 1, debugPrint(debug, "read_vcd_activities", 1,
"%s transitions %d activity %.2f duty %.2f", "%s transitions %d activity %.2f duty %.2f",
pin_name, pin_name,
transition_count, transition_count,