diff --git a/sootty/__main__.py b/sootty/__main__.py index aa6ffae..58888f6 100644 --- a/sootty/__main__.py +++ b/sootty/__main__.py @@ -122,6 +122,7 @@ def parse_args(): def main(): + filename, wires, breakpoints, btable, length, start, end, output, radix = parse_args() if filename is None: diff --git a/sootty/storage/wiregroup.py b/sootty/storage/wiregroup.py index a82b5f2..8a71471 100644 --- a/sootty/storage/wiregroup.py +++ b/sootty/storage/wiregroup.py @@ -1,17 +1,56 @@ +import polars as pl + from ..exceptions import * from .wire import Wire class WireGroup: def __init__(self, name: str): - self.name = name + self.name = name # e.g. Test_MIPS.core.alu self.groups = [] self.wires = [] + self.all_wires_df = pl.DataFrame() + + # self.groups_df = pl.DataFrame() + # self.wires_df = pl.DataFrame([], schema={'name':pl.String, 'time': pl.Int64, 'value': pl.Int64, 'length': pl.Int64, 'width': pl.Int64}) + def add_wire(self, wire): self.wires.append(wire) + # this prints out null because time doesn't exist in the value change dictionary yet + name_str = self.name + '.' + wire.name + + # TODO: try using the values in dumpvars for initial values + temp_all_wires_df = pl.DataFrame({ + name_str: [ + {'name': wire.name}, + {'time': wire.__getitem__('time')}, + {'value': wire.__getitem__('value')}, + {'length': wire.length()}, + {'width': wire.width()} + ] + }) + + if self.all_wires_df.is_empty(): + self.all_wires_df = temp_all_wires_df + elif name_str in self.all_wires_df.columns: + #TODO: implement duplicate wire names + pass + + else: + self.all_wires_df = pl.concat( + [ + self.all_wires_df, + temp_all_wires_df + ], + how="horizontal") + + print(self.all_wires_df) + + def add_group(self, group): + # print(group) self.groups.append(group) def num_wires(self): @@ -29,12 +68,20 @@ def length(self): def find(self, name: str): """Returns the first wire object with the given name, if it exists.""" + """dataframe version""" + # print("find") + # print(self.all_wires_df) + # # if not self.name == "__root__": + # find_wires_df = self.all_wires_df.select(self.name + '.' + name) + # print(find_wires_df) + for wire in self.wires: if wire.name == name: return wire for group in self.groups: return group.find(name) raise SoottyError(f"Wire '{name}' does not exist.") + def get_names(self): """Returns list of all wire names.""" diff --git a/sootty/storage/wiretrace.py b/sootty/storage/wiretrace.py index 9d178c1..93947d6 100644 --- a/sootty/storage/wiretrace.py +++ b/sootty/storage/wiretrace.py @@ -1,6 +1,7 @@ import sys -from vcd.reader import * +import polars as pl +from vcd.reader import * from ..exceptions import * from ..parser import parser from .wiregroup import WireGroup @@ -11,6 +12,8 @@ class WireTrace: def __init__(self): self.root = WireGroup("__root__") + self.wires_df = pl.DataFrame() + self.wires_vc = pl.DataFrame() @classmethod def from_vcd(cls, filename): @@ -77,6 +80,11 @@ def from_vcd(cls, filename): this = cls() this.metadata = dict() # dictionary of vcd metadata wires = dict() # map from id_code to wire object + + wire_df_list = [] + wire_vc_dfs = [] + idx_count = 0 + stack = [this.root] # store stack of current group for scoping with open(filename, "rb") as stream: @@ -92,7 +100,9 @@ def from_vcd(cls, filename): elif token.kind is TokenKind.ENDDEFINITIONS: break # end of definitions elif token.kind is TokenKind.SCOPE: - group = WireGroup(token.scope.ident) + prepend_name = '' + prepend_name += stack[-1].name + '.' + token.scope.ident + group = WireGroup(prepend_name) stack[-1].add_group(group) stack.append(group) elif token.kind is TokenKind.TIMESCALE: @@ -103,12 +113,27 @@ def from_vcd(cls, filename): stack.pop() elif token.kind is TokenKind.VAR: if token.var.id_code in wires: + # Used if wire is in multiple groups? + # wire_groups[token.var.id_code].append(stack[-1].name) + # PREPENDING THE NAME HERE BASED ON STACK[-1] Value is stack[-1].add_wire(wires[token.var.id_code]) else: wire = Wire( name=token.var.reference, width=token.var.size, ) + + wire_dict = {"id": token.var.id_code, + "name": token.var.reference, + "size": token.var.size, + "df_idx": idx_count} + wire_df_list.append(wire_dict) + + # wire_groups[tokn.var.id_code].append(stack[-1].name) + vc_df = pl.DataFrame() + # wire_vc_dfs.append(vc_df) + idx_count = idx_count + 1 + wires[token.var.id_code] = wire stack[-1].add_wire(wire) elif token.kind is TokenKind.VERSION: @@ -123,6 +148,12 @@ def from_vcd(cls, filename): elif token.kind is TokenKind.CHANGE_SCALAR: value = token.scalar_change.value value = int(value) if value in ("0", "1") else value + + vc_dict = {"time": time, + "id": token.scalar_change.id_code, + "value": value} + wire_vc_dfs.append(vc_dict) + wires[token.scalar_change.id_code][time] = value elif token.kind is TokenKind.CHANGE_VECTOR: value = token.vector_change.value @@ -148,6 +179,11 @@ def from_vcd(cls, filename): else: raise SoottyError(f"Invalid vcd token when parsing: {token}") + this.wires_df = pl.from_dicts(wire_df_list) + this.wires_vc = pl.from_dicts(wire_vc_dfs) + print(this.wires_df) + print(this.wires_vc) + return this @classmethod @@ -319,4 +355,4 @@ def rec_print(wires): print() print("time", *breakpoints, sep="\t") - rec_print(self.root.get_wires()) + rec_print(self.root.get_wires()) \ No newline at end of file