From 3f7c392e1a54ac6b8efe141fad133fc229306f96 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 20:41:26 -0700 Subject: [PATCH 1/7] activity computation --- Makefile | 21 ++--- passes/cmds/activity.cc | 144 ++++++++++++++++++++++++++++++++++ passes/sat/sim.cc | 170 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 318 insertions(+), 17 deletions(-) create mode 100644 passes/cmds/activity.cc diff --git a/Makefile b/Makefile index add13055d..fa5da0b78 100644 --- a/Makefile +++ b/Makefile @@ -155,7 +155,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.46+34 +YOSYS_VER := 0.46+32 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -729,6 +729,7 @@ OBJS += passes/cmds/setattr.o OBJS += passes/cmds/splitcells.o OBJS += passes/cmds/splitfanout.o OBJS += passes/cmds/splitnets.o +OBJS += passes/cmds/activity.o OBJS += passes/cmds/tee.o OBJS += passes/sat/sim.o @@ -1012,20 +1013,8 @@ endif # also others, but so long as it doesn't fail this is enough to know we tried docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) - $(Q) mkdir -p docs/source/cmd - $(Q) mkdir -p temp/docs/source/cmd - $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' - $(Q) rsync -rc temp/docs/source/cmd docs/source - $(Q) rm -rf temp -docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS) - $(Q) mkdir -p docs/source/cell - $(Q) mkdir -p temp/docs/source/cell - $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual' - $(Q) rsync -rc temp/docs/source/cell docs/source - $(Q) rm -rf temp - -docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@' + mkdir -p docs/source/cmd + ./$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' PHONY: docs/gen_examples docs/gen_images docs/guidelines docs/usage docs/reqs docs/gen_examples: $(TARGETS) @@ -1068,7 +1057,7 @@ docs/reqs: $(Q) $(MAKE) -C docs reqs .PHONY: docs/prep -docs/prep: docs/source/cmd/abc.rst docs/source/generated/cells.json docs/gen_examples docs/gen_images docs/guidelines docs/usage +docs/prep: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage DOC_TARGET ?= html docs: docs/prep diff --git a/passes/cmds/activity.cc b/passes/cmds/activity.cc new file mode 100644 index 000000000..527ab3270 --- /dev/null +++ b/passes/cmds/activity.cc @@ -0,0 +1,144 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2024 Alain Dargelas + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct ActivityProp { + Module *module; + SigMap sigmap; + + void tokenize(std::string_view str, std::string_view separator, std::vector &result, bool skipEmpty) + { + std::string::size_type pos{0}; + const auto sepSize = separator.size(); + const auto stringSize = str.size(); + std::string tmp; + std::string::size_type n = str.find(separator, pos); + while (n != std::string::npos) { + tmp = str.substr(pos, n - pos); + if (!(tmp.empty() && skipEmpty)) + result.push_back(tmp); + pos = n + sepSize; + n = str.find(separator, pos); + } + if (pos < stringSize) { // put last part + tmp = str.substr(pos, stringSize - pos); + if (!(tmp.empty() && skipEmpty)) + result.push_back(tmp); + } + } + + std::vector tokenize(std::string_view str, std::string_view separator, bool skipEmpty) + { + std::vector result; + tokenize(str, separator, result, skipEmpty); + return result; + } + + ActivityProp(Module *module) : module(module), sigmap(module) + { + std::map ActivityMap; + std::map DutyMap; + // Build {signal bit - activity} map from the wire activities calculated in the sim pass + for (Wire *wire : module->wires()) { + SigSpec sig(sigmap(wire)); + std::string act = wire->get_string_attribute("$ACKT"); + std::string duty = wire->get_string_attribute("$DUTY"); + std::vector activities = tokenize(act, " ", true); + std::vector duties = tokenize(duty, " ", true); + for (int i = 0; i < GetSize(sig); i++) { + SigBit bit(sig[i]); + ActivityMap.emplace(bit, activities[i]); + DutyMap.emplace(bit, duties[i]); + } + } + // Attach port activity to cell using sigmap + for (auto cell : module->cells()) { + std::string cell_ports_activity; + std::string cell_ports_duty; + for (auto conn : cell->connections()) { + for (int i = 0; i < GetSize(conn.second); i++) { + SigBit bit(sigmap(conn.second[i])); + std::string port_name = std::string(conn.first.c_str()) + "[" + std::to_string(i) + "]"; + { + std::map::iterator itr = ActivityMap.find(bit); + if (itr != ActivityMap.end()) { + cell_ports_activity += port_name + "=" + (*itr).second + " "; + } else { + RTLIL::SigSpec sigspec(bit); + if (!sigspec.is_fully_const()) { + log_warning("No activity found for : %s/%s/%s", module->name.c_str(), cell->name.c_str(), port_name.c_str()); + } + // constants have no activity + cell_ports_activity += port_name + "=" + "0.0 "; + } + } + { + std::map::iterator itr = DutyMap.find(bit); + if (itr != DutyMap.end()) { + cell_ports_duty += port_name + "=" + (*itr).second + " "; + } else { + RTLIL::SigSpec sigspec(bit); + if (!sigspec.is_fully_const()) { + log_warning("No dutycycle found for : %s/%s/%s", module->name.c_str(), cell->name.c_str(), port_name.c_str()); + } + // constant 1 has duty cycle 1, constant 0 has duty cycle 0 + cell_ports_duty += port_name + "=" + (sigspec.as_bool() ? "1.0" : "0.0") + " "; + } + } + } + } + cell->set_string_attribute("$ACKT:", cell_ports_activity); + cell->set_string_attribute("$DUTY:", cell_ports_duty); + } + } +}; + +struct ActivityPropPass : public Pass { + ActivityPropPass() : Pass("activity_prop", "Attaches wire activity to cell ports") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" activity_prop\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing Activity propagation pass\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + // No options currently. When adding in the future make sure to update docstring with [options] + break; + } + extra_args(args, argidx, design); + + for (auto module : design->modules()) { + ActivityProp worker(module); + } + } +} ActivityPropPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index c3fa213f6..813bf00cd 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1460,7 +1460,7 @@ struct SimWorker : SimShared { log_assert(top == nullptr); fst = new FstData(sim_filename); - + timescale = fst->getTimescaleString(); if (scope.empty()) log_error("Scope must be defined for co-simulation.\n"); @@ -2397,6 +2397,170 @@ struct VCDWriter : public OutputWriter std::ofstream vcdfile; }; +struct AnnotateActivity : public OutputWriter { + AnnotateActivity(SimWorker *worker) : OutputWriter(worker) {} + + struct SignalActivityData { + std::vector lastValues; + std::vector toggleCounts; + std::vector highTimes; + }; + + typedef std::map SignalActivityDataMap; + + void write(std::map &use_signal) override + { + // Init map + SignalActivityDataMap dataMap; + // For each event (new time when a value changed) + for (auto &d : worker->output_data) { + // For each signal/values in that time slice + for (auto &data : d.second) { + int sig = data.first; + if (!use_signal.at(sig)) + continue; + // Create an entry in the map with all zeros for all bits of the signal + SignalActivityDataMap::iterator itr = dataMap.find(sig); + if (itr == dataMap.end()) { + Const value = data.second; + std::vector vals(GetSize(value), 0); + SignalActivityData data; + data.highTimes = vals; + data.lastValues = vals; + data.toggleCounts = vals; + dataMap.emplace(sig, data); + } + } + } + // Max simulation time + int max_time = 0; + // clock pin id (highest toggling signal) + int clk = 0; + int highest_toggle = 0; + // Used to compute time intervals + int prev_time = 0; + // For each event (new time when a value changed) + for (auto &d : worker->output_data) { + int time = d.first; + // For each signal/values in that time slice + for (auto &data : d.second) { + int sig = data.first; + if (!use_signal.at(sig)) + continue; + Const value = data.second; + SignalActivityDataMap::iterator itr = dataMap.find(sig); + std::vector &lastVals = (*itr).second.lastValues; + std::vector &toggleCounts = (*itr).second.toggleCounts; + std::vector &highTimes = (*itr).second.highTimes; + for (int i = GetSize(value) - 1; i >= 0; i--) { + int val = '-'; + switch (value[i]) { + case State::S0: + val = '0'; + break; + case State::S1: + val = '1'; + break; + case State::Sx: + val = 'x'; + break; + default: + val = 'z'; + } + if (val != lastVals[i]) { + toggleCounts[i]++; + if (toggleCounts[i] > highest_toggle) { + highest_toggle = toggleCounts[i]; + clk = sig; + } + lastVals[i] = val; + } + if (lastVals[i] == '1') { + highTimes[i] += time - prev_time; + } + } + } + prev_time = time; + max_time = time; + } + + // Retrieve VCD timescale + std::string timescale = worker->timescale; + double real_timescale = 1e-12; // ps + if (timescale == "ns") + real_timescale = 1e-9; + if (timescale == "fs") + real_timescale = 1e-15; + + bool debug = false; + + // Compute clock period, find the highest toggling signal and compute its average period + SignalActivityDataMap::iterator itr = dataMap.find(clk); + std::vector &clktoggleCounts = (*itr).second.toggleCounts; + double clk_period = real_timescale * (double)max_time / (clktoggleCounts[0] / 2); + if (debug) { + std::cout << "Clock toggle count: " << clktoggleCounts[0] << "\n"; + std::cout << "Max time: " << max_time << "\n"; + std::cout << "Clock period: " << clk_period << "\n"; + } + worker->top->write_output_header( + [this, debug](IdString name) { + if (debug) + std::cout << stringf("module %s\n", log_id(name)); + }, + [this, debug]() { + if (debug) + std::cout << "endmodule\n"; + }, + [this, use_signal, dataMap, max_time, real_timescale, clk_period, debug] + (const char *name, int size, Wire *w, int id, bool is_reg) { + if (!use_signal.at(id)) + return; + std::string full_name = form_vcd_name(name, size, w); + SignalActivityDataMap::const_iterator itr = dataMap.find(id); + const std::vector &toggleCounts = (*itr).second.toggleCounts; + const std::vector &highTimes = (*itr).second.highTimes; + if (debug) { + std::cout << full_name << ":\n"; + std::cout << " TC: "; + for (uint32_t i = 0; i < (uint32_t)size; i++) { + std::cout << toggleCounts[i] << " "; + } + std::cout << "\n"; + std::cout << " HT: "; + for (uint32_t i = 0; i < (uint32_t)size; i++) { + std::cout << highTimes[i] << " "; + } + std::cout << "\n"; + std::cout << " ACK: "; + } + std::string activity_str; + for (uint32_t i = 0; i < (uint32_t)size; i++) { + // Compute Activity + double activity = toggleCounts[i] / ((double)max_time * real_timescale / clk_period); + activity_str += std::to_string(activity) + " "; + } + if (debug) { + std::cout << activity_str; + std::cout << "\n"; + std::cout << " DUTY: "; + } + std::string duty_str; + for (uint32_t i = 0; i < (uint32_t)size; i++) { + // Compute Duty cycle + double duty = (double)highTimes[i] / (double)max_time; + duty_str += std::to_string(duty) + " "; + } + if (debug) { + std::cout << duty_str; + std::cout << "\n"; + } + w->set_string_attribute("$ACKT", activity_str); + w->set_string_attribute("$DUTY", duty_str); + }); + } +}; + struct FSTWriter : public OutputWriter { FSTWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { @@ -2871,6 +3035,10 @@ struct SimPass : public Pass { worker.multiclock = true; continue; } + if (args[argidx] == "-activity") { + worker.outputfiles.emplace_back(std::unique_ptr(new AnnotateActivity(&worker))); + continue; + } break; } extra_args(args, argidx, design); From 4132636712697b54712adfd1323463e69713d094 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 20:52:07 -0700 Subject: [PATCH 2/7] Activity computation --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b1ff267fc..d58909157 100644 --- a/Makefile +++ b/Makefile @@ -743,6 +743,7 @@ OBJS += passes/cmds/splitnets.o OBJS += passes/cmds/activity.o OBJS += passes/cmds/tee.o OBJS += passes/sat/sim.o +OBJS += passes/sat/activity.o include $(YOSYS_SRC)/passes/hierarchy/Makefile.inc include $(YOSYS_SRC)/passes/memory/Makefile.inc From f022ee0517642d9313626b2719bbd5de313308c7 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 21:02:55 -0700 Subject: [PATCH 3/7] Correct Makefile diffs --- Makefile | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index d58909157..4e7b8a41a 100644 --- a/Makefile +++ b/Makefile @@ -740,7 +740,6 @@ OBJS += passes/cmds/setattr.o OBJS += passes/cmds/splitcells.o OBJS += passes/cmds/splitfanout.o OBJS += passes/cmds/splitnets.o -OBJS += passes/cmds/activity.o OBJS += passes/cmds/tee.o OBJS += passes/sat/sim.o OBJS += passes/sat/activity.o @@ -1025,8 +1024,17 @@ endif # also others, but so long as it doesn't fail this is enough to know we tried docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) - mkdir -p docs/source/cmd - ./$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' + $(Q) mkdir -p docs/source/cmd + $(Q) rsync -rc temp/docs/source/cmd docs/source + $(Q) rm -rf temp +docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS) + $(Q) mkdir -p docs/source/cell + $(Q) mkdir -p temp/docs/source/cell + $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual' + $(Q) rsync -rc temp/docs/source/cell docs/source + $(Q) rm -rf temp +docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) + $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@' PHONY: docs/gen_examples docs/gen_images docs/guidelines docs/usage docs/reqs docs/gen_examples: $(TARGETS) @@ -1069,7 +1077,7 @@ docs/reqs: $(Q) $(MAKE) -C docs reqs .PHONY: docs/prep -docs/prep: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage +docs/prep: docs/source/cmd/abc.rst docs/source/generated/cells.json docs/gen_examples docs/gen_images docs/guidelines docs/usage DOC_TARGET ?= html docs: docs/prep From cc919f6ea6562d1b2a4d3c3a95074c3c49f6f137 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 21:14:52 -0700 Subject: [PATCH 4/7] Correct Makefile diffs --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 4e7b8a41a..6b9c14a68 100644 --- a/Makefile +++ b/Makefile @@ -1025,6 +1025,8 @@ endif # also others, but so long as it doesn't fail this is enough to know we tried docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) $(Q) mkdir -p docs/source/cmd + $(Q) mkdir -p temp/docs/source/cmd + $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' $(Q) rsync -rc temp/docs/source/cmd docs/source $(Q) rm -rf temp docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS) @@ -1033,6 +1035,7 @@ docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS) $(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual' $(Q) rsync -rc temp/docs/source/cell docs/source $(Q) rm -rf temp + docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@' From 516a4be6f8188cd90db5bad4d152097900a582d8 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 21:17:03 -0700 Subject: [PATCH 5/7] Correct tab --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 813bf00cd..b9ecf2d5e 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2533,7 +2533,7 @@ struct AnnotateActivity : public OutputWriter { } std::cout << "\n"; std::cout << " ACK: "; - } + } std::string activity_str; for (uint32_t i = 0; i < (uint32_t)size; i++) { // Compute Activity From 389518a8f02274376bcfda626903afd3d985a5a7 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 16 Oct 2024 21:37:41 -0700 Subject: [PATCH 6/7] tab issue --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index b9ecf2d5e..77591b35a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2419,7 +2419,7 @@ struct AnnotateActivity : public OutputWriter { int sig = data.first; if (!use_signal.at(sig)) continue; - // Create an entry in the map with all zeros for all bits of the signal + // Create an entry in the map with all zeros for all bits of the signal SignalActivityDataMap::iterator itr = dataMap.find(sig); if (itr == dataMap.end()) { Const value = data.second; From f6d67ac21ef439e05df1f418b0ed361abd71b41a Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Thu, 17 Oct 2024 09:33:08 -0700 Subject: [PATCH 7/7] More comments --- passes/cmds/activity.cc | 11 +++++++++++ passes/sat/sim.cc | 14 ++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/passes/cmds/activity.cc b/passes/cmds/activity.cc index 527ab3270..efac64cb9 100644 --- a/passes/cmds/activity.cc +++ b/passes/cmds/activity.cc @@ -28,6 +28,8 @@ struct ActivityProp { Module *module; SigMap sigmap; + // Split a string based on separator, returns a vector of tokens as reference argument + // If skipEmpty is true, return "" for string " ", when separator is " " void tokenize(std::string_view str, std::string_view separator, std::vector &result, bool skipEmpty) { std::string::size_type pos{0}; @@ -49,6 +51,8 @@ struct ActivityProp { } } + // Split a string based on separator, returns a vector of tokens + // If skipEmpty is true, return "" for string " ", when separator is " " std::vector tokenize(std::string_view str, std::string_view separator, bool skipEmpty) { std::vector result; @@ -63,10 +67,14 @@ struct ActivityProp { // Build {signal bit - activity} map from the wire activities calculated in the sim pass for (Wire *wire : module->wires()) { SigSpec sig(sigmap(wire)); + // Retrieve the activity/dutycycle attributes created in the sim pass, attached to wires, in the form: + // $ACKT: 0.1 0.2 .... (Each bit in a bus has its own activity, index 0 of the bus is left most) std::string act = wire->get_string_attribute("$ACKT"); std::string duty = wire->get_string_attribute("$DUTY"); + // Split the activity lists std::vector activities = tokenize(act, " ", true); std::vector duties = tokenize(duty, " ", true); + // Assign them to each SigBit (1 signal bit) for (int i = 0; i < GetSize(sig); i++) { SigBit bit(sig[i]); ActivityMap.emplace(bit, activities[i]); @@ -78,6 +86,7 @@ struct ActivityProp { std::string cell_ports_activity; std::string cell_ports_duty; for (auto conn : cell->connections()) { + // Recombine individual bit activities for all cell ports into a list attached to the cell for (int i = 0; i < GetSize(conn.second); i++) { SigBit bit(sigmap(conn.second[i])); std::string port_name = std::string(conn.first.c_str()) + "[" + std::to_string(i) + "]"; @@ -109,6 +118,8 @@ struct ActivityProp { } } } + // Annotate on cells the complete list of ports activities and dutycycles in the form: + // $ACKT: \P1=0.1 \P2=0.2 .... cell->set_string_attribute("$ACKT:", cell_ports_activity); cell->set_string_attribute("$DUTY:", cell_ports_duty); } diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 77591b35a..46614cd4f 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2449,9 +2449,9 @@ struct AnnotateActivity : public OutputWriter { continue; Const value = data.second; SignalActivityDataMap::iterator itr = dataMap.find(sig); - std::vector &lastVals = (*itr).second.lastValues; - std::vector &toggleCounts = (*itr).second.toggleCounts; - std::vector &highTimes = (*itr).second.highTimes; + std::vector &lastVals = itr->second.lastValues; + std::vector &toggleCounts = itr->second.toggleCounts; + std::vector &highTimes = itr->second.highTimes; for (int i = GetSize(value) - 1; i >= 0; i--) { int val = '-'; switch (value[i]) { @@ -2467,6 +2467,7 @@ struct AnnotateActivity : public OutputWriter { default: val = 'z'; } + // If signal toggled if (val != lastVals[i]) { toggleCounts[i]++; if (toggleCounts[i] > highest_toggle) { @@ -2492,11 +2493,12 @@ struct AnnotateActivity : public OutputWriter { if (timescale == "fs") real_timescale = 1e-15; + // TODO: remove all debug sections when dev is completed bool debug = false; // Compute clock period, find the highest toggling signal and compute its average period SignalActivityDataMap::iterator itr = dataMap.find(clk); - std::vector &clktoggleCounts = (*itr).second.toggleCounts; + std::vector &clktoggleCounts = itr->second.toggleCounts; double clk_period = real_timescale * (double)max_time / (clktoggleCounts[0] / 2); if (debug) { std::cout << "Clock toggle count: " << clktoggleCounts[0] << "\n"; @@ -2518,8 +2520,8 @@ struct AnnotateActivity : public OutputWriter { return; std::string full_name = form_vcd_name(name, size, w); SignalActivityDataMap::const_iterator itr = dataMap.find(id); - const std::vector &toggleCounts = (*itr).second.toggleCounts; - const std::vector &highTimes = (*itr).second.highTimes; + const std::vector &toggleCounts = itr->second.toggleCounts; + const std::vector &highTimes = itr->second.highTimes; if (debug) { std::cout << full_name << ":\n"; std::cout << " TC: ";