Пример #1
0
  def __init__( self, model, collect_metrics = False ):

    # Check that the model has been elaborated
    if not model.is_elaborated():
      raise Exception( "cannot initialize {0} tool.\n"
                       "Provided model has not been elaborated yet!!!"
                       "".format( self.__class__.__name__ ) )

    self.model                = model
    self.ncycles              = 0

    self._event_queue         = EventQueue()
    self._sequential_blocks   = []
    self._register_queue      = []
    self._current_func        = None

    self._nets                = None # TODO: remove me

    #self._DEBUG_signal_cbs    = collections.defaultdict(list)


    # Only collect metrics if they are enabled, otherwise replace
    # with a dummy collection class.

    if collect_metrics:
      self.metrics            = SimulationMetrics()
    else:
      self.metrics            = DummyMetrics()

    # If the -O flag was passed to Python, use the perf implementation
    # of cycle, otherwise use the dev version.

    if flags.optimize:
      self.cycle              = self._perf_cycle
      self.eval_combinational = self._perf_eval
    else:
      self.cycle              = self._dev_cycle
      self.eval_combinational = self._dev_eval


    # Construct a simulator for the provided model.

    signals                 = sim.collect_signals( model )
    nets, slice_connections = sim.signals_to_nets( signals )
    sequential_blocks       = sim.register_seq_blocks( model )

    sim.insert_signal_values( self, nets )

    sim.register_comb_blocks  ( model, self._event_queue )
    sim.create_slice_callbacks( slice_connections, self._event_queue )
    sim.register_cffi_updates ( model )

    self._nets              = nets
    self._sequential_blocks = sequential_blocks

    # Setup vcd dumping if it's configured

    if hasattr( model, 'vcd_file' ) and model.vcd_file:
      from vcd import VCDUtil
      VCDUtil( self, model.vcd_file )
Пример #2
0
    def __init__(self, model, collect_metrics=False):

        # Check that the model has been elaborated
        if not model.is_elaborated():
            raise Exception("cannot initialize {0} tool.\n"
                            "Provided model has not been elaborated yet!!!"
                            "".format(self.__class__.__name__))

        self.model = model
        self.ncycles = 0

        self._event_queue = EventQueue()
        self._sequential_blocks = []
        self._register_queue = []
        self._current_func = None

        self._nets = None  # TODO: remove me

        #self._DEBUG_signal_cbs    = collections.defaultdict(list)

        # Only collect metrics if they are enabled, otherwise replace
        # with a dummy collection class.

        if collect_metrics:
            self.metrics = SimulationMetrics()
        else:
            self.metrics = DummyMetrics()

        # If the -O flag was passed to Python, use the perf implementation
        # of cycle, otherwise use the dev version.

        if flags.optimize:
            self.cycle = self._perf_cycle
            self.eval_combinational = self._perf_eval
        else:
            self.cycle = self._dev_cycle
            self.eval_combinational = self._dev_eval

        # Construct a simulator for the provided model.

        signals = sim.collect_signals(model)
        nets, slice_connections = sim.signals_to_nets(signals)
        sequential_blocks = sim.register_seq_blocks(model)

        sim.insert_signal_values(self, nets)

        sim.register_comb_blocks(model, self._event_queue)
        sim.create_slice_callbacks(slice_connections, self._event_queue)
        sim.register_cffi_updates(model)

        self._nets = nets
        self._sequential_blocks = sequential_blocks

        # Setup vcd dumping if it's configured

        if hasattr(model, 'vcd_file') and model.vcd_file:
            from vcd import VCDUtil
            VCDUtil(self, model.vcd_file)
Пример #3
0
class SimulationTool(object):

    #---------------------------------------------------------------------
    # __init__
    #---------------------------------------------------------------------
    # Construct a simulator based on the provided model.
    def __init__(self, model, collect_metrics=False):

        # Check that the model has been elaborated
        if not model.is_elaborated():
            raise Exception("cannot initialize {0} tool.\n"
                            "Provided model has not been elaborated yet!!!"
                            "".format(self.__class__.__name__))

        self.model = model
        self.ncycles = 0

        self._event_queue = EventQueue()
        self._sequential_blocks = []
        self._register_queue = []
        self._current_func = None

        self._nets = None  # TODO: remove me

        #self._DEBUG_signal_cbs    = collections.defaultdict(list)

        # Only collect metrics if they are enabled, otherwise replace
        # with a dummy collection class.

        if collect_metrics:
            self.metrics = SimulationMetrics()
        else:
            self.metrics = DummyMetrics()

        # If the -O flag was passed to Python, use the perf implementation
        # of cycle, otherwise use the dev version.

        if flags.optimize:
            self.cycle = self._perf_cycle
            self.eval_combinational = self._perf_eval
        else:
            self.cycle = self._dev_cycle
            self.eval_combinational = self._dev_eval

        # Construct a simulator for the provided model.

        signals = sim.collect_signals(model)
        nets, slice_connections = sim.signals_to_nets(signals)
        sequential_blocks = sim.register_seq_blocks(model)

        sim.insert_signal_values(self, nets)

        sim.register_comb_blocks(model, self._event_queue)
        sim.create_slice_callbacks(slice_connections, self._event_queue)
        sim.register_cffi_updates(model)

        self._nets = nets
        self._sequential_blocks = sequential_blocks

        # Setup vcd dumping if it's configured

        if hasattr(model, 'vcd_file') and model.vcd_file:
            from vcd import VCDUtil
            VCDUtil(self, model.vcd_file)

    #---------------------------------------------------------------------
    # reset
    #---------------------------------------------------------------------
    # Sets the reset signal high and cycles the simulator.
    def reset(self):
        self.model.reset.v = 1
        self.cycle()
        self.cycle()
        self.model.reset.v = 0

    #---------------------------------------------------------------------
    # print_line_trace
    #---------------------------------------------------------------------
    # Print cycle number and line trace of model.
    def print_line_trace(self):
        print("{:>3}:".format(self.ncycles), self.model.line_trace())

    #---------------------------------------------------------------------
    # cycle
    #---------------------------------------------------------------------
    # Advances the simulator by a single clock cycle, executing all
    # sequential @tick and @posedge_clk blocks defined in the design, as
    # well as any @combinational blocks that have been added to the event
    # queue.
    #
    # Note: see _debug_cycle and _perf_cycle for actual implementations.
    def cycle(self):
        pass

    #---------------------------------------------------------------------
    # _debug_cycle
    #---------------------------------------------------------------------
    # Implementation of cycle() for use during develop-test-debug loops.
    def _dev_cycle(self):

        # Call all events generated by input changes
        self.eval_combinational()

        # Clock generation needed by VCD tracing
        self.model.clk.value = 0
        self.model.clk.value = 1

        # Distinguish between events caused by input vectors changing (above)
        # and events caused by clocked logic (below).
        self.metrics.start_tick()

        # Call all rising edge triggered functions
        for func in self._sequential_blocks:
            func()

        # Then flop the shadow state on all registers
        while self._register_queue:
            reg = self._register_queue.pop()
            reg.flop()

        # Call all events generated by synchronous logic
        self.eval_combinational()

        # Increment the simulator cycle count
        self.ncycles += 1

        # Tell the metrics module to prepare for the next cycle
        self.metrics.incr_metrics_cycle()

    #---------------------------------------------------------------------
    # _perf_cycle
    #---------------------------------------------------------------------
    # Implementation of cycle() for use when benchmarking models.
    def _perf_cycle(self):

        # Call all events generated by input changes
        self.eval_combinational()

        # Call all rising edge triggered functions
        for func in self._sequential_blocks:
            func()

        # Then flop the shadow state on all registers
        while self._register_queue:
            reg = self._register_queue.pop()
            reg.flop()

        # Call all events generated by synchronous logic
        self.eval_combinational()

        # Increment the simulator cycle count
        self.ncycles += 1

    #---------------------------------------------------------------------
    # eval_combinational
    #---------------------------------------------------------------------
    # Evaluate all combinational logic blocks currently in the eventqueue.
    def eval_combinational(self):
        pass

    #---------------------------------------------------------------------
    # _debug_eval
    #---------------------------------------------------------------------
    # Implementation of eval_combinational() for use during
    # develop-test-debug loops.
    def _dev_eval(self):
        while self._event_queue.len():
            self._current_func = func = self._event_queue.deq()
            self.metrics.incr_comb_evals(func)
            func()
            self._current_func = None

    #---------------------------------------------------------------------
    # _perf_eval
    #---------------------------------------------------------------------
    # Implementation of eval_combinataional () for use when benchmarking
    # models.
    def _perf_eval(self):
        while self._event_queue.len():
            self._current_func = func = self._event_queue.deq()
            func()
            self._current_func = None

    #---------------------------------------------------------------------
    # add_event
    #---------------------------------------------------------------------
    # Add an event to the simulator event queue for later execution.
    #
    # This function will check if the written SignalValue instance has any
    # registered events (functions decorated with @combinational), and if
    # so, adds them to the event queue.
    def add_event(self, signal_value):
        # TODO: debug_event
        #print("    ADDEVENT: VALUE", signal_value.v,  end='')
        #print(signal_value in self._DEBUG_signal_cbs, end='')
        #print([x.fullname for x in signal_value._DEBUG_signal_names], end='')
        #print(self._DEBUG_signal_cbs[signal_value])

        self.metrics.incr_add_events()

        # Place all other callbacks in the event queue for execution later

        for func in signal_value._callbacks:
            self.metrics.incr_add_callbk()
            if func != self._current_func:
                self._event_queue.enq(func.cb, func.id)
Пример #4
0
class SimulationTool( object ):

  #---------------------------------------------------------------------
  # __init__
  #---------------------------------------------------------------------
  # Construct a simulator based on the provided model.
  def __init__( self, model, collect_metrics = False ):

    # Check that the model has been elaborated
    if not model.is_elaborated():
      raise Exception( "cannot initialize {0} tool.\n"
                       "Provided model has not been elaborated yet!!!"
                       "".format( self.__class__.__name__ ) )

    self.model                = model
    self.ncycles              = 0

    self._event_queue         = EventQueue()
    self._sequential_blocks   = []
    self._register_queue      = []
    self._current_func        = None

    self._nets                = None # TODO: remove me

    #self._DEBUG_signal_cbs    = collections.defaultdict(list)


    # Only collect metrics if they are enabled, otherwise replace
    # with a dummy collection class.

    if collect_metrics:
      self.metrics            = SimulationMetrics()
    else:
      self.metrics            = DummyMetrics()

    # If the -O flag was passed to Python, use the perf implementation
    # of cycle, otherwise use the dev version.

    if flags.optimize:
      self.cycle              = self._perf_cycle
      self.eval_combinational = self._perf_eval
    else:
      self.cycle              = self._dev_cycle
      self.eval_combinational = self._dev_eval


    # Construct a simulator for the provided model.

    signals                 = sim.collect_signals( model )
    nets, slice_connections = sim.signals_to_nets( signals )
    sequential_blocks       = sim.register_seq_blocks( model )

    sim.insert_signal_values( self, nets )

    sim.register_comb_blocks  ( model, self._event_queue )
    sim.create_slice_callbacks( slice_connections, self._event_queue )
    sim.register_cffi_updates ( model )

    self._nets              = nets
    self._sequential_blocks = sequential_blocks

    # Setup vcd dumping if it's configured

    if hasattr( model, 'vcd_file' ) and model.vcd_file:
      from vcd import VCDUtil
      VCDUtil( self, model.vcd_file )

  #---------------------------------------------------------------------
  # reset
  #---------------------------------------------------------------------
  # Sets the reset signal high and cycles the simulator.
  def reset( self ):
    self.model.reset.v = 1
    self.cycle()
    self.cycle()
    self.model.reset.v = 0

  #---------------------------------------------------------------------
  # print_line_trace
  #---------------------------------------------------------------------
  # Print cycle number and line trace of model.
  def print_line_trace( self ):
    print( "{:>3}:".format( self.ncycles ), self.model.line_trace() )

  #---------------------------------------------------------------------
  # cycle
  #---------------------------------------------------------------------
  # Advances the simulator by a single clock cycle, executing all
  # sequential @tick and @posedge_clk blocks defined in the design, as
  # well as any @combinational blocks that have been added to the event
  # queue.
  #
  # Note: see _debug_cycle and _perf_cycle for actual implementations.
  def cycle( self ):
    pass

  #---------------------------------------------------------------------
  # _debug_cycle
  #---------------------------------------------------------------------
  # Implementation of cycle() for use during develop-test-debug loops.
  def _dev_cycle( self ):

    # Call all events generated by input changes
    self.eval_combinational()

    # Clock generation needed by VCD tracing
    self.model.clk.value = 0
    self.model.clk.value = 1

    # Distinguish between events caused by input vectors changing (above)
    # and events caused by clocked logic (below).
    self.metrics.start_tick()

    # Call all rising edge triggered functions
    for func in self._sequential_blocks:
      func()

    # Then flop the shadow state on all registers
    while self._register_queue:
      reg = self._register_queue.pop()
      reg.flop()

    # Call all events generated by synchronous logic
    self.eval_combinational()

    # Increment the simulator cycle count
    self.ncycles += 1

    # Tell the metrics module to prepare for the next cycle
    self.metrics.incr_metrics_cycle()

  #---------------------------------------------------------------------
  # _perf_cycle
  #---------------------------------------------------------------------
  # Implementation of cycle() for use when benchmarking models.
  def _perf_cycle( self ):

    # Call all events generated by input changes
    self.eval_combinational()

    # Call all rising edge triggered functions
    for func in self._sequential_blocks:
      func()

    # Then flop the shadow state on all registers
    while self._register_queue:
      reg = self._register_queue.pop()
      reg.flop()

    # Call all events generated by synchronous logic
    self.eval_combinational()

    # Increment the simulator cycle count
    self.ncycles += 1

  #---------------------------------------------------------------------
  # eval_combinational
  #---------------------------------------------------------------------
  # Evaluate all combinational logic blocks currently in the eventqueue.
  def eval_combinational( self ):
    pass

  #---------------------------------------------------------------------
  # _debug_eval
  #---------------------------------------------------------------------
  # Implementation of eval_combinational() for use during
  # develop-test-debug loops.
  def _dev_eval( self ):
    while self._event_queue.len():
      self._current_func = func = self._event_queue.deq()
      self.metrics.incr_comb_evals( func )
      func()
      self._current_func = None

  #---------------------------------------------------------------------
  # _perf_eval
  #---------------------------------------------------------------------
  # Implementation of eval_combinataional () for use when benchmarking
  # models.
  def _perf_eval( self ):
    while self._event_queue.len():
      self._current_func = func = self._event_queue.deq()
      func()
      self._current_func = None

  #---------------------------------------------------------------------
  # add_event
  #---------------------------------------------------------------------
  # Add an event to the simulator event queue for later execution.
  #
  # This function will check if the written SignalValue instance has any
  # registered events (functions decorated with @combinational), and if
  # so, adds them to the event queue.
  def add_event( self, signal_value ):
    # TODO: debug_event
    #print("    ADDEVENT: VALUE", signal_value.v,  end='')
    #print(signal_value in self._DEBUG_signal_cbs, end='')
    #print([x.fullname for x in signal_value._DEBUG_signal_names], end='')
    #print(self._DEBUG_signal_cbs[signal_value])

    self.metrics.incr_add_events()

    # Place all other callbacks in the event queue for execution later

    for func in signal_value._callbacks:
      self.metrics.incr_add_callbk()
      if func != self._current_func:
        self._event_queue.enq( func.cb, func.id )