Class: LibFST::Reader
- Inherits:
-
Object
- Object
- LibFST::Reader
- Defined in:
- lib/libfst/reader.rb,
lib/libfst/reader.rb,
ext/libfst_rb.c
Defined Under Namespace
Classes: Attribute, Scope, Trace, Variable
Instance Attribute Summary collapse
- #filename ⇒ String readonly
- #root ⇒ Scope readonly
- #traces ⇒ Array<Trace> readonly
- #variables ⇒ Array<Variable> readonly
Instance Method Summary collapse
-
#[](path) ⇒ Scope, ...
Returns the scope or variable corresponding to the specified path.
-
#alias_count ⇒ Integer
Returns the number of variables which point to the same trace.
- #current_flat_scope ⇒ String
- #current_scope_length ⇒ Integer
-
#date_string ⇒ String
Date string produced by the writer of the FST file.
- #double_endian_match_state? ⇒ Boolean
- #dump_activity_change_time(idx) ⇒ Integer
- #dump_activity_change_value(idx) ⇒ Integer
- #end_time ⇒ Integer
-
#file_type ⇒ Symbol
Either
:verilog,:vhdlor:verilog_or_vhdl. - #fseek_failed? ⇒ Boolean
-
#initialize(filename) ⇒ Reader
constructor
A new instance of Reader.
-
#iterate_hier ⇒ Scope, ...
Iterate through the hierarchy.
- #iterate_hier_rewind ⇒ Integer
-
#max_handle ⇒ Integer
Variable handles are integers from 1 to
max_handleinclusive. - #memory_used_by_writer ⇒ Integer
- #number_dump_activity_changes ⇒ Integer
- #pop_scope ⇒ String?
-
#pretty_time(timei) ⇒ String
Pretty print the integer time given as parametter according to the time scale.
- #push_scope(name = nil) ⇒ String?
-
#read(*signals, start_time: nil, end_time: nil) {|trace, time, value, reader| ... } ⇒ Integer
Read the value changes of the traces.
- #reset_scope ⇒ self
- #scope_count ⇒ Integer
- #start_time ⇒ Integer
- #time_scale ⇒ Float
-
#time_scale_exponent ⇒ Integer
Returns the time scale exponent.
- #time_zero ⇒ Integer
-
#trace(name) ⇒ Trace?
Find a Trace by its name or path.
- #value_change_section_count ⇒ Integer
-
#var_count ⇒ Integer
Returns the number of variables.
-
#variable(name) ⇒ Variable?
Find a Variable by its name or path.
-
#version_string ⇒ String
Version string produced by the writer of the FST file.
Constructor Details
#initialize(filename) ⇒ Reader
Returns a new instance of Reader.
213 214 215 216 217 218 219 |
# File 'lib/libfst/reader.rb', line 213 def initialize(filename) @filename = File.(filename) open(@filename) @traces = max_handle.times.collect { |i| Trace.new(i+1) } @variables = [] travel_hierarchy end |
Instance Attribute Details
#filename ⇒ String (readonly)
208 209 210 |
# File 'lib/libfst/reader.rb', line 208 def filename @filename end |
#traces ⇒ Array<Trace> (readonly)
209 210 211 |
# File 'lib/libfst/reader.rb', line 209 def traces @traces end |
#variables ⇒ Array<Variable> (readonly)
210 211 212 |
# File 'lib/libfst/reader.rb', line 210 def variables @variables end |
Instance Method Details
#[](path) ⇒ Scope, ...
Returns the scope or variable corresponding to the specified path
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/libfst/reader.rb', line 245 def [](path) raise ArgumentError, "expecting a String, not a #{path.class}" unless path.is_a?(String) a = path.split('/').reject(&:empty?) return nil if a.empty? return nil if a[0] != @root.name scope = @root var = nil a[1..].each do |w| var = scope.variables.select { |v| v.name == w }.first return var if var s = scope.children.select { |v| v.name == w }.first return nil if s.nil? scope = s end scope end |
#alias_count ⇒ Integer
Returns the number of variables which point to the same trace.
313 314 315 316 317 318 |
# File 'ext/libfst_rb.c', line 313 static VALUE libfst_reader_alias_count(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t alias_count = fstReaderGetAliasCount(ctx); return RB_ULL2NUM(alias_count); } |
#current_flat_scope ⇒ String
331 332 333 334 335 336 |
# File 'ext/libfst_rb.c', line 331 static VALUE libfst_reader_current_flat_scope(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); const char* str = fstReaderGetCurrentFlatScope(ctx); return rb_utf8_str_new_cstr(str); } |
#current_scope_length ⇒ Integer
323 324 325 326 |
# File 'ext/libfst_rb.c', line 323 static VALUE libfst_reader_current_scope_length(VALUE self) { return RB_INT2NUM(fstReaderGetCurrentScopeLen(libfst_reader_from_rbobj(self))); } |
#date_string ⇒ String
Date string produced by the writer of the FST file
342 343 344 345 346 347 |
# File 'ext/libfst_rb.c', line 342 static VALUE libfst_reader_date_string(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); const char* str = fstReaderGetDateString(ctx); return rb_utf8_str_new_cstr(str); } |
#double_endian_match_state? ⇒ Boolean
477 478 479 480 481 |
# File 'ext/libfst_rb.c', line 477 static VALUE libfst_reader_double_endian_match_state(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); return (fstReaderGetDoubleEndianMatchState(ctx) ? Qtrue : Qfalse); } |
#dump_activity_change_time(idx) ⇒ Integer
805 806 807 808 809 810 811 |
# File 'ext/libfst_rb.c', line 805 static VALUE libfst_reader_dump_activity_change_time(VALUE self, VALUE idx) { void *ctx = libfst_reader_from_rbobj(self); uint32_t x = NUM2ULONG(idx); uint64_t t = fstReaderGetDumpActivityChangeTime(ctx, x); return ULL2NUM(t); } |
#dump_activity_change_value(idx) ⇒ Integer
816 817 818 819 820 821 822 |
# File 'ext/libfst_rb.c', line 816 static VALUE libfst_reader_dump_activity_change_value(VALUE self, VALUE idx) { void *ctx = libfst_reader_from_rbobj(self); uint32_t x = NUM2ULONG(idx); int t = fstReaderGetDumpActivityChangeValue(ctx, x); return INT2NUM(t); } |
#end_time ⇒ Integer
384 385 386 387 388 389 |
# File 'ext/libfst_rb.c', line 384 static VALUE libfst_reader_end_time(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetEndTime(ctx); return RB_ULL2NUM(i); } |
#file_type ⇒ Symbol
Returns Either :verilog, :vhdl or :verilog_or_vhdl.
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'ext/libfst_rb.c', line 404 static VALUE libfst_reader_file_type(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); int ft = fstReaderGetFileType(ctx); ID id; switch (ft) { case FST_FT_VERILOG: id = id_verilog; break; case FST_FT_VHDL: id = id_vhdl; break; case FST_FT_VERILOG_VHDL: id = id_verilog_or_vhdl; break; default: rb_raise(rb_eRuntimeError, "Unknown file type %d", ft); } return rb_id2sym(id); } |
#fseek_failed? ⇒ Boolean
468 469 470 471 472 |
# File 'ext/libfst_rb.c', line 468 static VALUE libfst_reader_fseek_failed(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); return (fstReaderGetFseekFailed(ctx) ? Qtrue : Qfalse); } |
#iterate_hier ⇒ Scope, ...
Iterate through the hierarchy.
Successively call this method until it returns nil.
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
# File 'ext/libfst_rb.c', line 776 static VALUE libfst_reader_iterate_hier(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); struct fstHier *hier = fstReaderIterateHier(ctx); if (!hier) return Qnil; VALUE r = Qnil; switch (hier->htyp) { case FST_HT_SCOPE: r = libfst_readerscope_from_struct(hier); break; case FST_HT_UPSCOPE: r = rb_id2sym(id_upscope); break; case FST_HT_VAR: r = libfst_readervar_from_struct(hier); break; case FST_HT_ATTRBEGIN: r = libfst_readerattr_from_struct(hier); break; case FST_HT_ATTREND: r = rb_id2sym(id_attrend); break; } return r; } |
#iterate_hier_rewind ⇒ Integer
572 573 574 575 576 577 |
# File 'ext/libfst_rb.c', line 572 static VALUE libfst_reader_iterate_hier_rewind(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); int r = fstReaderIterateHierRewind(ctx); return INT2NUM(r); } |
#max_handle ⇒ Integer
Variable handles are integers from 1 to max_handle inclusive.
796 797 798 799 800 |
# File 'ext/libfst_rb.c', line 796 static VALUE libfst_reader_max_handle(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); return ULONG2NUM(fstReaderGetMaxHandle(ctx)); } |
#memory_used_by_writer ⇒ Integer
428 429 430 431 432 433 |
# File 'ext/libfst_rb.c', line 428 static VALUE libfst_reader_memory_used_by_writer(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetMemoryUsedByWriter(ctx); return RB_ULL2NUM(i); } |
#number_dump_activity_changes ⇒ Integer
458 459 460 461 462 463 |
# File 'ext/libfst_rb.c', line 458 static VALUE libfst_reader_number_dump_activity_changes(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint32_t i = fstReaderGetNumberDumpActivityChanges(ctx); return RB_ULL2NUM(i); } |
#pop_scope ⇒ String?
530 531 532 533 534 535 536 |
# File 'ext/libfst_rb.c', line 530 static VALUE libfst_reader_pop_scope(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); const char* str = fstReaderPopScope(ctx); if (!str) return Qnil; return rb_utf8_str_new_cstr(str); } |
#pretty_time(timei) ⇒ String
Pretty print the integer time given as parametter according to the time scale
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/libfst/reader.rb', line 265 def pretty_time(timei) return '0 s' if timei == 0 i = time_scale_exponent e = (i/3)*3 f = 10**(i - e) timei *= f loop do break if e >= 0 m = timei % 1000 break if m != 0 timei /= 1000 e += 3 end s = timei.to_s l = s.length i = ((l-1)/3)*3 return "#{timei} #{['', 'm', 'µ', 'n', 'p', 'f'][-e/3]}s" if i <= 0 or e+i > 0 e += i ent = s[0...l-i] frac = s[l-i..].sub(/0+$/, '') "#{ent}.#{frac} #{['', 'm', 'µ', 'n', 'p', 'f'][-e/3]}s" end |
#push_scope(name = nil) ⇒ String?
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
# File 'ext/libfst_rb.c', line 553 static VALUE libfst_reader_push_scope(int argc, VALUE *argv, VALUE self) { void *ctx = libfst_reader_from_rbobj(self); VALUE name_rb = Qnil; const char *name_c = ""; rb_scan_args(argc, argv, "01", &name_rb); if (!NIL_P(name_rb)) { if (!rb_obj_is_kind_of(name_rb, rb_cString)) rb_raise(rb_eTypeError, "expecting a string, not a %s\n", rb_obj_classname(name_rb)); name_c = rb_string_value_cstr(&name_rb); } const char *str = fstReaderPushScope(ctx, name_c, NULL); if (!str) return Qnil; return rb_utf8_str_new_cstr(str); } |
#read(*signals, start_time: nil, end_time: nil) {|trace, time, value, reader| ... } ⇒ Integer
Read the value changes of the traces.
The provided block is called for each value change found in the file.
If signals are specified, the block will be called only for thoses signals.
If a start time and/or an end time are specified, only value changes in this time window will be searched.
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 |
# File 'ext/libfst_rb.c', line 878 static VALUE libfst_reader_read(int argc, VALUE *argv, VALUE self) { void *ctx = libfst_reader_from_rbobj(self); VALUE blk; VALUE splat; VALUE kw; const ID kwkeys[2] = {id_start_time, id_end_time}; VALUE kwvalues[2] = {Qundef, Qundef}; uint64_t start_time, end_time; libfst_reader_value_change_callback_arg_t ; rb_scan_args(argc, argv, "*:&", &splat, &kw, &blk); if (NIL_P(blk)) rb_raise(rb_eRuntimeError, "read expects a block"); if (!NIL_P(kw)) { rb_get_kwargs(kw, kwkeys, 0, 2, kwvalues); if (kwvalues[0] == Qundef || NIL_P(kwvalues[0])) start_time = 0; else if (rb_obj_is_kind_of(kwvalues[0], rb_cInteger)) start_time = NUM2ULL(kwvalues[0]); else if (rb_obj_is_kind_of(kwvalues[0], rb_cFloat)) start_time = (uint64_t)floor(NUM2DBL(kwvalues[0]) / NUM2DBL(libfst_reader_time_scale(self))); else rb_raise(rb_eTypeError, "expecting an Integer or a Float as start time, not a %s", rb_obj_classname(kwvalues[0])); if (kwvalues[1] == Qundef || NIL_P(kwvalues[1])) end_time = fstReaderGetEndTime(ctx) + 1; else if (rb_obj_is_kind_of(kwvalues[1], rb_cInteger)) end_time = NUM2ULL(kwvalues[1]); else if (rb_obj_is_kind_of(kwvalues[1], rb_cFloat)) end_time = (uint64_t)floor(NUM2DBL(kwvalues[1]) / NUM2DBL(libfst_reader_time_scale(self))); else rb_raise(rb_eTypeError, "expecting an Integer or a Float as end time, not a %s", rb_obj_classname(kwvalues[1])); if (end_time < start_time) rb_raise(rb_eRuntimeError, "start_time must be less than end_time (%lu, %lu)", start_time, end_time); fstReaderSetLimitTimeRange(ctx, start_time, end_time); .limit_time = 1; .start_time = start_time; .end_time = end_time; } else { fstReaderSetUnlimitedTimeRange(ctx); .limit_time = 0; } long splatlen = rb_array_len(splat); if (splatlen < 1) { fstReaderSetFacProcessMaskAll(ctx); } else { fstReaderClrFacProcessMaskAll(ctx); long i; fstHandle mh = fstReaderGetMaxHandle(ctx); for (i = 0; i < splatlen; i++) { VALUE t = rb_ary_entry(splat, i); fstHandle facidx; if (rb_obj_is_kind_of(t, rb_cInteger)) { facidx = NUM2ULONG(t); if (facidx < 1 || facidx > mh) rb_raise(rb_eRuntimeError, "bad signal handle"); fstReaderSetFacProcessMask(ctx, facidx); } else if (rb_obj_is_kind_of(t, c_RTrace)) { facidx = NUM2ULONG(rb_ivar_get(t, id_at_handle)); if (facidx < 1 || facidx > mh) rb_raise(rb_eRuntimeError, "bad signal handle"); fstReaderSetFacProcessMask(ctx, facidx); } else if (rb_obj_is_kind_of(t, c_RVariable)) { facidx = NUM2ULONG(rb_ivar_get(rb_ivar_get(t, id_at_trace), id_at_handle)); if (facidx < 1 || facidx > mh) rb_raise(rb_eRuntimeError, "bad signal handle"); fstReaderSetFacProcessMask(ctx, facidx); } else if (rb_obj_is_kind_of(t, c_RScope)) { VALUE variables = rb_ivar_get(t, id_at_variables); long varlen = rb_array_len(variables); long j; for (j = 0; j < varlen; j++) { facidx = NUM2ULONG(rb_ivar_get(rb_ivar_get(rb_ary_entry(variables, j), id_at_trace), id_at_handle)); if (facidx < 1 || facidx > mh) rb_raise(rb_eRuntimeError, "bad signal handle"); fstReaderSetFacProcessMask(ctx, facidx); } } else { rb_raise(rb_eTypeError, "signals can be specified either by a handle (Integer), a %"PRIsVALUE", a %"PRIsVALUE" or a %"PRIsVALUE", not a %s", c_RTrace, c_RVariable, c_RScope, rb_obj_classname(t)); } } } .reader = self; .proc = blk; int r = fstReaderIterBlocks2(ctx, libfst_reader_value_change_callback, libfst_reader_value_change_callback_varlen, &, NULL); RB_GC_GUARD(.reader); RB_GC_GUARD(.proc); return INT2NUM(r); } |
#reset_scope ⇒ self
541 542 543 544 545 546 |
# File 'ext/libfst_rb.c', line 541 static VALUE libfst_reader_reset_scope(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); fstReaderResetScope(ctx); return self; } |
#scope_count ⇒ Integer
438 439 440 441 442 443 |
# File 'ext/libfst_rb.c', line 438 static VALUE libfst_reader_scope_count(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetScopeCount(ctx); return RB_ULL2NUM(i); } |
#start_time ⇒ Integer
374 375 376 377 378 379 |
# File 'ext/libfst_rb.c', line 374 static VALUE libfst_reader_start_time(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetStartTime(ctx); return RB_ULL2NUM(i); } |
#time_scale ⇒ Float
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'ext/libfst_rb.c', line 497 static VALUE libfst_reader_time_scale(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); signed char s = fstReaderGetTimescale(ctx); double d = 1.0; switch (s) { case 2: d = 100.0; break; case 1: d = 10.0; break; case 0: d = 1.0; break; case -1: d = 100e-3; break; case -2: d = 10e-3; break; case -3: d = 1e-3; break; case -4: d = 100e-6; break; case -5: d = 10e-6; break; case -6: d = 1e-6; break; case -7: d = 100e-9; break; case -8: d = 10e-9; break; case -9: d = 1e-9; break; case -10: d = 100e-12; break; case -11: d = 10e-12; break; case -12: d = 1e-12; break; case -13: d = 100e-15; break; case -14: d = 10e-15; break; case -15: d = 1e-15; break; default: d = pow(10.0, (double)s); } return DBL2NUM(d); } |
#time_scale_exponent ⇒ Integer
Returns the time scale exponent.
Real time is integer_time * 10^time_scale_exponent.
489 490 491 492 |
# File 'ext/libfst_rb.c', line 489 static VALUE libfst_reader_time_scale_exponent(VALUE self) { return INT2NUM((int)fstReaderGetTimescale(libfst_reader_from_rbobj(self))); } |
#time_zero ⇒ Integer
394 395 396 397 398 399 |
# File 'ext/libfst_rb.c', line 394 static VALUE libfst_reader_time_zero(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetTimezero(ctx); return RB_ULL2NUM(i); } |
#trace(name) ⇒ Trace?
Find a Trace by its name or path
225 226 227 228 229 230 |
# File 'lib/libfst/reader.rb', line 225 def trace(name) @traces.each do |t| return t if t.name == name or t.path == name end nil end |
#value_change_section_count ⇒ Integer
448 449 450 451 452 453 |
# File 'ext/libfst_rb.c', line 448 static VALUE libfst_reader_value_change_section_count(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetValueChangeSectionCount(ctx); return RB_ULL2NUM(i); } |
#var_count ⇒ Integer
Returns the number of variables.
364 365 366 367 368 369 |
# File 'ext/libfst_rb.c', line 364 static VALUE libfst_reader_var_count(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); uint64_t i = fstReaderGetVarCount(ctx); return RB_ULL2NUM(i); } |
#variable(name) ⇒ Variable?
Find a Variable by its name or path
235 236 237 238 239 240 |
# File 'lib/libfst/reader.rb', line 235 def variable(name) @variables.each do |v| return v if v.name == name or v.path == name end nil end |
#version_string ⇒ String
Version string produced by the writer of the FST file
353 354 355 356 357 358 |
# File 'ext/libfst_rb.c', line 353 static VALUE libfst_reader_version_string(VALUE self) { void *ctx = libfst_reader_from_rbobj(self); const char* str = fstReaderGetVersionString(ctx); return rb_utf8_str_new_cstr(str); } |