lib/ruby-vpi.rb in ruby-vpi-12.1.0 vs lib/ruby-vpi.rb in ruby-vpi-13.0.0

- old
+ new

@@ -24,24 +24,40 @@ # 2. the proto.rb file if prototyping is enabled # 3. the spec.rb file # # aDesignId:: The name of the Ruby design object. # aSpecFormat:: The format being used by the specification. - def RubyVpi.init_bench aDesignId, aSpecFormat + # aClockTrigger:: When the return value of this block is +true+, then the relay_verilog method returns. This block is given one argument: a handle to the clock signal that drives the design under test. If this block is not specified, relay_verilog will always return upon the next positive edge of the clock signal. + # + # # return upon positive edge + # RubyVpi.init_bench ... |clk| + # clk.intVal == 1 + # end + # + # # return upon negative edge + # RubyVpi.init_bench ... do |clk| + # clk.intVal == 0 + # end + # + # # return whenever clock changes + # RubyVpi.init_bench ... do |clk| + # true + # end + # + def RubyVpi.init_bench aDesignId, aSpecFormat, &aClockTrigger # :yields: clock_signal if caller.find {|s| s =~ /^(.*?)_bench.rb:/} testName = $1 else raise 'Unable to determine name of test.' end + aClockTrigger ||= lambda {|clk| clk.intVal == 1} + useDebugger = !(ENV['DEBUG'] || '').empty? useCoverage = !(ENV['COVERAGE'] || '').empty? usePrototype = !(ENV['PROTOTYPE'] || '').empty? - # service the $ruby_init() task - Vpi::relay_verilog - # set up code coverage analysis if useCoverage require 'ruby-vpi/rcov' RubyVpi.with_coverage_analysis do |a| @@ -104,16 +120,52 @@ # load the design's prototype if usePrototype require "#{testName}_proto.rb" - Vpi.class_eval do + Vpi.module_eval do define_method :relay_verilog do design.simulate! end end Vpi::vpi_printf "#{Config::PROJECT_NAME}: prototype is enabled for test #{testName.inspect}\n" + + # trigger relay_verilog according to aClockTrigger + else + regs = design[VpiReg].sort_by {|h| h.lineNo} + clock = regs.first + + Vpi.module_eval do + # register callback for relay_verilog + time = S_vpi_time.new + time.type = VpiSuppressTime + + value = S_vpi_value.new + value.format = VpiSuppressVal + + alarm = S_cb_data.new + alarm.reason = CbValueChange + alarm.cb_rtn = Vlog_relay_ruby + alarm.obj = clock + alarm.time = time + alarm.value = value + alarm.index = 0 + alarm.user_data = nil + + vpi_free_object(vpi_register_cb(alarm)) + + alias_method :relay_verilog_old, :relay_verilog + + define_method :relay_verilog do + begin + relay_verilog_old + end until aClockTrigger.call(clock) + end + end + + # XXX: this completes the handshake with pthread_mutex_lock() in relay_main() in the C extension + relay_verilog_old end # load the design's specification require "#{testName}_spec.rb" end