Class: RubyVPI::CallbackClass

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/ruby-vpi/core/callback.rb

Overview

:nodoc:

Instance Method Summary collapse

Constructor Details

#initializeCallbackClass

Returns a new instance of CallbackClass.



12
13
14
15
16
# File 'lib/ruby-vpi/core/callback.rb', line 12

def initialize
  @id2handler = {}
  @id2receipt = {}
  @lock = Mutex.new
end

Instance Method Details

#attach(aData, &aHandler) ⇒ Object

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ruby-vpi/core/callback.rb', line 18

def attach aData, &aHandler
  raise ArgumentError, "block must be given" unless block_given?
  id = aHandler.object_id.to_s

  # register the callback with Verilog
  aData.user_data = id
  aData.cb_rtn    = VPI::RubyVPI_user_resume
  receipt         = VPI.__callback__vpi_register_cb(aData)

  @lock.synchronize do
    @id2handler[id] = aHandler
    @id2receipt[id] = receipt
  end

  receipt
end

#detach(aData) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ruby-vpi/core/callback.rb', line 35

def detach aData
  id = aData.user_data.to_s
  receipt = @lock.synchronize{ @id2receipt[id] }

  if receipt
    VPI.__callback__vpi_remove_cb(receipt)

    @lock.synchronize do
      @id2handler.delete id
      @id2receipt.delete id
    end
  end
end

#relay_verilog(aTimeSlot, aNumSteps) ⇒ Object

Transfers control to the simulator, which will return control during the given time slot after the given number of time steps.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ruby-vpi/core/callback.rb', line 51

def relay_verilog aTimeSlot, aNumSteps
  # schedule wake-up callback from verilog
    time            = VPI::S_vpi_time.new
    time.integer    = aNumSteps
    time.type       = VPI::VpiSimTime

    value           = VPI::S_vpi_value.new
    value.format    = VPI::VpiSuppressVal

    alarm           = VPI::S_cb_data.new
    alarm.reason    = aTimeSlot
    alarm.cb_rtn    = VPI::RubyVPI_user_resume
    alarm.obj       = nil
    alarm.time      = time
    alarm.value     = value
    alarm.index     = 0
    alarm.user_data = nil

    VPI.vpi_free_object(VPI.__callback__vpi_register_cb(alarm))

  # transfer control to verilog
    while ring = RubyVPI.pause
      id = ring.user_data.to_s
      handler = @lock.synchronize { @id2handler[id] }

      if handler
        handler.call ring
      else
        break
      end
    end
end