Exemple #1
0
  def __init__(self, vcd_filename, timescale_divisor=1, start_cycle=0):
    super(VcdCircuit, self).__init__()
    logging.info("Parsing VCD file '%s'..." % vcd_filename)
    self.parsed_vcd = parse_vcd(vcd_filename)
    logging.info("Done parsing '%s'" % vcd_filename)
  
    self.nodes = {}
    working_bundles = {}
    self.memory_depths = {} # TODO: refactor
    
    for vcd_key, nets_tv_dict in self.parsed_vcd.iteritems():
      for net_dict in nets_tv_dict['nets']:
        parsed_node = VcdNode(vcd_key=vcd_key,
                              tv_list=scale_tv_list(nets_tv_dict['tv'],
                                                    timescale_divisor),
                              size=int(net_dict['size'], 10))
        node_name = net_dict['hier'] + '.' + net_dict['name']
        bracket_begin = node_name.rfind('[')
        bracket_end = node_name.rfind(']')
        if bracket_begin >= 0 and bracket_end >= 0 and bracket_begin < bracket_end:
          # This deals with ModelSim VCDs which derp bundles into single bits.
          node_name_stripped = node_name[:bracket_begin]
          
          index = node_name[bracket_begin+1:bracket_end]
          delim = index.find(':')
          # TODO more graceful error handling
          if delim >= 0:
            begin_str = index[:delim]
            end_str = index[delim+1:]
            begin = int(begin_str)
            end = int(end_str)
          else:
            begin = end = int(index)
          
          if begin == end and parsed_node.size > 1:
            # Special case for memory element "wires".
            assert node_name not in self.nodes, "duplicate name: '%s': %s" % (node_name, net_dict)
            self.memory_depths[node_name_stripped] = max(self.memory_depths.get(node_name_stripped, 1), begin+1)
            self.nodes[node_name] = parsed_node
          else:
            if node_name_stripped not in working_bundles:
              working_bundles[node_name_stripped] = {} # map high bit to VcdBundleElem
            bundle = working_bundles[node_name_stripped]
          
            assert begin >= end
            assert begin not in bundle
          
            bundle[begin] = VcdBundleElem(begin, end, parsed_node)
        else:
          assert node_name not in self.nodes, "duplicate name: '%s': %s" % (node_name, net_dict)
          self.nodes[node_name] = parsed_node

    logging.info("%i nodes found", len(self.nodes))
    logging.debug("Nodes found: %s", self.nodes.keys())

    # Post-process bundles
    self.bundles = {}
    for node_name, bundle in working_bundles.iteritems():
      largest = None
      prev = 0
      sorted_elems = []
      for begin_idx, bundle_elem in reversed(sorted(bundle.items())):
        assert begin_idx == bundle_elem.high
        if largest is None:
          largest = bundle_elem.high
        else:
          assert bundle_elem.high == prev - 1, "prev %i, next high %i" % (prev, bundle_elem.high)
        prev = bundle_elem.low 
        sorted_elems.append(bundle_elem)
      assert prev == 0
      bundle = VcdBundle(sorted_elems, largest)
      assert node_name not in self.bundles 
      self.bundles[node_name] = bundle
      
    logging.info("%i bundles found", len(self.bundles))  
    logging.debug("Bundles found: %s", self.bundles.keys())
    
    logging.info("%i memories inferred", len(self.memory_depths))
    
    self.initial_temporal_node = self.create_initial_temporal_node(start_cycle)
    self.current_temporal_node = self.initial_temporal_node

    self.width_dict = {}
    for node_name, vcd_node in self.nodes.iteritems():
      self.width_dict[node_name] = vcd_node.size
    for node_name, vcd_bundle in self.bundles.iteritems():
      assert node_name not in self.width_dict
      self.width_dict[node_name] = vcd_bundle.size
  
    self.current_view = ValueDictView(self, self.width_dict, self.memory_depths)
    self.historical_view = ValueDictView(self, self.width_dict, self.memory_depths)
    self.current_view.set_view(self.current_temporal_node.get_historical_state())
Exemple #2
0
class VcdCircuit(Circuit):
  def __init__(self, vcd_filename, timescale_divisor=1, start_cycle=0):
    super(VcdCircuit, self).__init__()
    logging.info("Parsing VCD file '%s'..." % vcd_filename)
    self.parsed_vcd = parse_vcd(vcd_filename)
    logging.info("Done parsing '%s'" % vcd_filename)
  
    self.nodes = {}
    working_bundles = {}
    self.memory_depths = {} # TODO: refactor
    
    for vcd_key, nets_tv_dict in self.parsed_vcd.iteritems():
      for net_dict in nets_tv_dict['nets']:
        parsed_node = VcdNode(vcd_key=vcd_key,
                              tv_list=scale_tv_list(nets_tv_dict['tv'],
                                                    timescale_divisor),
                              size=int(net_dict['size'], 10))
        node_name = net_dict['hier'] + '.' + net_dict['name']
        bracket_begin = node_name.rfind('[')
        bracket_end = node_name.rfind(']')
        if bracket_begin >= 0 and bracket_end >= 0 and bracket_begin < bracket_end:
          # This deals with ModelSim VCDs which derp bundles into single bits.
          node_name_stripped = node_name[:bracket_begin]
          
          index = node_name[bracket_begin+1:bracket_end]
          delim = index.find(':')
          # TODO more graceful error handling
          if delim >= 0:
            begin_str = index[:delim]
            end_str = index[delim+1:]
            begin = int(begin_str)
            end = int(end_str)
          else:
            begin = end = int(index)
          
          if begin == end and parsed_node.size > 1:
            # Special case for memory element "wires".
            assert node_name not in self.nodes, "duplicate name: '%s': %s" % (node_name, net_dict)
            self.memory_depths[node_name_stripped] = max(self.memory_depths.get(node_name_stripped, 1), begin+1)
            self.nodes[node_name] = parsed_node
          else:
            if node_name_stripped not in working_bundles:
              working_bundles[node_name_stripped] = {} # map high bit to VcdBundleElem
            bundle = working_bundles[node_name_stripped]
          
            assert begin >= end
            assert begin not in bundle
          
            bundle[begin] = VcdBundleElem(begin, end, parsed_node)
        else:
          assert node_name not in self.nodes, "duplicate name: '%s': %s" % (node_name, net_dict)
          self.nodes[node_name] = parsed_node

    logging.info("%i nodes found", len(self.nodes))
    logging.debug("Nodes found: %s", self.nodes.keys())

    # Post-process bundles
    self.bundles = {}
    for node_name, bundle in working_bundles.iteritems():
      largest = None
      prev = 0
      sorted_elems = []
      for begin_idx, bundle_elem in reversed(sorted(bundle.items())):
        assert begin_idx == bundle_elem.high
        if largest is None:
          largest = bundle_elem.high
        else:
          assert bundle_elem.high == prev - 1, "prev %i, next high %i" % (prev, bundle_elem.high)
        prev = bundle_elem.low 
        sorted_elems.append(bundle_elem)
      assert prev == 0
      bundle = VcdBundle(sorted_elems, largest)
      assert node_name not in self.bundles 
      self.bundles[node_name] = bundle
      
    logging.info("%i bundles found", len(self.bundles))  
    logging.debug("Bundles found: %s", self.bundles.keys())
    
    logging.info("%i memories inferred", len(self.memory_depths))
    
    self.initial_temporal_node = self.create_initial_temporal_node(start_cycle)
    self.current_temporal_node = self.initial_temporal_node

    self.width_dict = {}
    for node_name, vcd_node in self.nodes.iteritems():
      self.width_dict[node_name] = vcd_node.size
    for node_name, vcd_bundle in self.bundles.iteritems():
      assert node_name not in self.width_dict
      self.width_dict[node_name] = vcd_bundle.size
  
    self.current_view = ValueDictView(self, self.width_dict, self.memory_depths)
    self.historical_view = ValueDictView(self, self.width_dict, self.memory_depths)
    self.current_view.set_view(self.current_temporal_node.get_historical_state())

  def create_initial_temporal_node(self, cycle=0):
    # TODO: refactor so they reference common data structure instead of two
    # dicts (for efficiency reasons - constant term savings).
    vcd_position = VcdPosition({}, {})
    state = {}
    for node_name, vcd_node in self.nodes.iteritems():
      position, value = vcd_node_next(cycle, 0, vcd_node)
      state[node_name] = vcd_val_to_int(value)
      vcd_position.node[node_name] = position
    for node_name, vcd_bundle in self.bundles.iteritems():
      position, value = vcd_bundle_next(cycle, [0]*len(vcd_bundle.elements), vcd_bundle)
      state[node_name] = vcd_val_to_int(value)
      vcd_position.bundle[node_name] = position
    return VcdTemporalNode(self, None, cycle, vcd_position, state)

  def get_current_temporal_node(self):
    return self.current_temporal_node
      
  def get_current_view(self):
    return self.current_view
      
  def get_historical_view(self):
    return self.historical_view
  
  def navigate_next_mod(self):
    logging.warn("No modifiable state in VCDs")
    pass
  
  def navigate_prev_mod(self):
    logging.warn("No modifiable state in VCDs")
    pass

  def navigate_back(self):
    if self.current_temporal_node.get_prev_time():
      self.current_temporal_node = self.current_temporal_node.get_prev_time()
    else:
      logging.warn("Can't navigate back any further")
    self.current_view.set_view(self.current_temporal_node.get_historical_state())
      
  def navigate_fwd(self, cycles=None):
    if cycles is None:
      cycles = 1
    if cycles == 1:
      self.current_temporal_node = self.current_temporal_node.get_next_time()
      assert self.current_temporal_node is not None
    else:
      target_cyc = self.current_temporal_node.cycle + cycles
      self.current_temporal_node = self.create_initial_temporal_node(target_cyc)
    self.current_view.set_view(self.current_temporal_node.get_historical_state())
      
  def reset(self, cycles):
    self.current_temporal_node = self.initial_temporal_nodel
    self.current_view.set_view(self.current_temporal_node.get_historical_state())