Skip to content

[ENG-1794] Support for start/stop time in read_vcd Command#46

Open
stanminlee wants to merge 33 commits intomainfrom
vcd-timestamp
Open

[ENG-1794] Support for start/stop time in read_vcd Command#46
stanminlee wants to merge 33 commits intomainfrom
vcd-timestamp

Conversation

@stanminlee
Copy link
Copy Markdown

Add -start_time and -stop_time arguments to read_vcd to only count transitions/signals from the specified timestamps.

To do this, we add support for start/stop time to be passed in to relevant functions (most of the changes are for this).

  • IncrCounts: We check if we have reached the filter window, only count as we were previously if we are in the window.
  • highTime: Function used at the very END for duty cycle calculation
  • We cover the case where the signal is 1 before the filter window start, as to not count the time it was 1 before

@stanminlee stanminlee changed the title Support for start/stop time in read_vcd Command [ENG-1794] Support for start/stop time in read_vcd Command Apr 7, 2026
@linear
Copy link
Copy Markdown

linear bot commented Apr 7, 2026

ENG-1794

@stanminlee stanminlee marked this pull request as ready for review April 9, 2026 19:11
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 9, 2026

Greptile Summary

This PR adds -start_time / -end_time filter arguments to read_vcd, threading the values from Tcl through SWIG into a new VcdCount::setFilter() static method that gates both high-time accumulation and transition counting to the requested window.

  • P1 — incorrect duty cycle for signals whose transition to '0' falls after end_time: incrCounts always writes back prev_time_ / prev_value_ even when in_window=false. If a signal was '1' inside the window and transitions to '0' at t > end_time, the tail of that high period is never accumulated and highTime(end_time) returns an underestimated value. The test VCD avoids this because all value changes occur at #50; real VCDs will expose incorrect duty cycles.
  • P1 — static filter_start_ / filter_end_: sharing filter state as class-level statics works today because setFilter is always called before each parse, but makes every VcdCount instance sensitive to global side-effects and is fragile under future refactoring.

Confidence Score: 3/5

Not safe to merge: the end_time clipping bug will silently produce wrong duty cycles for any real VCD where transitions occur after the specified end_time.

Two P1 findings remain: (1) out-of-window incrCounts calls overwrite prev_value_, discarding the tail of the last high interval and causing incorrect duty cycle calculations; (2) static filter fields are fragile. The test suite passes only because the test VCD has no value changes after any tested end_time boundary.

power/VcdReader.cc — specifically the incrCounts and highTime methods and the static VcdCount::filter_start_/filter_end_ members

Important Files Changed

Filename Overview
power/VcdReader.cc Core filtering logic; contains P1 bug where out-of-window transitions overwrite prev_value_, silently dropping the tail of the last high interval, plus static filter fields design smell
power/VcdParse.cc Correctly pre-sets time_min to start_time and gates the initial setTimeMin call; setTimeMax at end of parseVarValues honours end_time_ when specified
power/Power.tcl Adds -start_time/-end_time keys with -1 defaults; public flag name inconsistency vs PR description (stop_time vs end_time)
power/Power.i Adds stdint.i include and int64_t params to read_vcd_file; straightforward SWIG binding update
test/vcd_timestamp.vcd Test VCD only has value changes at t=0 and t=50 with parallaxsw#100 as an empty timestamp; no transitions after any tested end_time, limiting bug coverage

Reviews (2): Last reviewed commit: "ok this is a real fix" | Re-trigger Greptile

@akashlevy
Copy link
Copy Markdown

@stanminlee can you address greptile and lmk when ready for review?

@stanminlee
Copy link
Copy Markdown
Author

@greptile review my pull request again

Comment on lines +62 to +78
static void setFilter(VcdTime start, VcdTime end);

private:
VcdTime clippedIntervalStart() const;
PinSeq pins_;
VcdTime prev_time_;
char prev_value_;
VcdTime high_time_;
double transition_count_;

static VcdTime filter_start_;
static VcdTime filter_end_;
};

// Define static members
VcdTime VcdCount::filter_start_ = -1;
VcdTime VcdCount::filter_end_ = -1;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Static filter fields make VcdCount non-reentrant across read_vcd calls

filter_start_ and filter_end_ are static class members, so they are shared by every VcdCount instance in the entire process. setFilter() is called once per readActivities(), which is correct for a single sequential call, but introduces a latent issue: if read_vcd is ever invoked without a filter after a previous call that did set a filter, the statics retain the old window values until the next setFilter(). Since setFilter is always called at the top of readActivities() before parsing, this is currently safe — but only by convention. A future refactor that skips the no-filter case could silently re-apply the previous call's filter.

Consider making filter_start_ / filter_end_ instance members (non-static) and passing them via the constructor or a per-instance setFilter call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants