class Template
Constants
- BIASED
- FREE
- RANDOM
- READ
- TRY_FREE
- TRY_READ
- TRY_USED
- TRY_WRITE
- USED
- WRITE
Attributes
Public Class Methods
This method adds every subclass of Template to the list of templates to parse
# File template.rb, line 43 def self.inherited(subclass) subclass_file = parse_caller(caller[0])[0] puts "Loaded template #{subclass} defined in #{subclass_file}" @@template_classes.store subclass, subclass_file end
# File template.rb, line 33 def initialize super @situation_manager = SituationManager.new(self) end
Parses the text of stack entries returned by the “caller” method, which have the following format: <file:line> or <file:line: in `method’>.
# File template.rb, line 51 def self.parse_caller(at) if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at file = Regexp.last_match[1] line = Regexp.last_match[2].to_i method = Regexp.last_match[3] return [file, line, method] end raise "Failed to parse #{at}." end
# File template.rb, line 38 def self.template_classes @@template_classes end
Public Instance Methods
Creates an object that specifies an unknown immediate value to be used as an argument of a mode or op. A corresponding concrete value must be produced as a result of test data generation for some test situation.
# File template.rb, line 397 def _(allocator = nil, attrs = {}) if allocator.is_a? Hash and attrs.empty? then attrs = allocator allocator = nil end if !attrs.is_a?(Hash) raise "#{attrs} is not a Hash" end allocation_data = get_allocation_data allocator, attrs @template.newUnknownImmediate(allocation_data) end
Creates a placeholder for label to be updated in the process of generation.
# File template.rb, line 412 def _label @template.newLazyLabel end
Adds the given block to the current template.
# File template.rb, line 133 def add_new_block(kind, attributes, where, &contents) blockBuilder = @template.beginBlock kind blockBuilder.setWhere where set_builder_attributes blockBuilder, attributes self.instance_eval &contents @template.endBlock end
Adds text to the header of generated files.
# File template.rb, line 550 def add_to_header(text) java_import Java::Ru.ispras.microtesk.test.Printer Printer.addToHeader text end
# File template.rb, line 730 def address(*args) if args.count != 0 and args.count != 2 raise "Wrong argument count: #{args.count}. Must be 0 or 2" end reference = AddressReference.new @template if args.count == 2 reference.bits args[0], args[1] else reference end end
# File template.rb, line 225 def allocation(name, attrs = {}) java_import Java::Ru.ispras.microtesk.test.template.Situation allocation_data = get_allocation_data nil, attrs get_new_situation name, {:allocation => allocation_data}, Situation::Kind::ALLOCATION end
# File template.rb, line 122 def atomic(attributes = {}, &contents) java_import Java::Ru.ispras.microtesk.test.template.Block add_new_block Block::Kind::ATOMIC, attributes, get_caller_location, &contents end
# File template.rb, line 847 def balign(value, fill_with=-1) @template.addDirective @directive.balign(value, fill_with), get_caller_location end
# File template.rb, line 112 def block(attributes = {}, &contents) java_import Java::Ru.ispras.microtesk.test.template.Block add_new_block Block::Kind::BLOCK, attributes, get_caller_location, &contents end
# File template.rb, line 155 def branches(&contents) set_attributes(:branches => true, &contents) end
¶ ↑
Buffer Preparators
¶ ↑
# File template.rb, line 718 def buffer_preparator(attrs, &contents) buffer_id = get_attribute attrs, :target builder = @template.beginBufferPreparator buffer_id if attrs.has_key?(:levels) builder.setLevels attrs[:levels] end self.instance_eval &contents @template.endBufferPreparator end
Adds a comment into the test program (uses sl_comment_starts_with).
# File template.rb, line 503 def comment(format, *args) print_format :COMMENT, format, *args end
# File template.rb, line 569 def comparator(attrs, &contents) create_preparator(true, attrs, &contents) end
Adds the given constraint to the current block.
# File template.rb, line 172 def constraint(&situations) @template.addBlockConstraint(@situation_manager.instance_eval(&situations)) end
# File template.rb, line 573 def create_preparator(is_comparator, attrs, &contents) target = get_attribute attrs, :target builder = @template.beginPreparator target.to_s, is_comparator builder.setWhere get_caller_location(2) name = attrs[:name] if !name.nil? builder.setName name.to_s end mask = attrs[:mask] if !mask.nil? if mask.is_a?(String) builder.setMaskValue mask elsif mask.is_a?(Array) builder.setMaskCollection mask else raise "Illegal mask type: #{mask}" end end arguments = attrs[:arguments] if !arguments.nil? if !arguments.is_a?(Hash) raise "#{arguments} is not a Hash" end arguments.each_pair do |name, value| if value.is_a?(Integer) builder.addArgumentValue name, value elsif value.is_a?(Range) builder.addArgumentRange name, value.min, value.max elsif value.is_a?(Array) builder.addArgumentCollection name, value else raise "Illegal value of #{name} argument: #{value}" end end end self.instance_eval &contents @template.endPreparator end
# File template.rb, line 817 def data(attrs = {}, &contents) if nil == @data_manager raise "Data configuration is undefined" end if attrs.has_key?(:global) global = attrs[:global] else global = false end if attrs.has_key?(:separate_file) separate_file = attrs[:separate_file] else separate_file = false end @data_manager.beginData global, separate_file @data_manager.instance_eval &contents @data_manager.endData end
¶ ↑
Data Definition
¶ ↑
# File template.rb, line 800 def data_config(attrs, &contents) if nil != @data_manager raise "Data configuration is already defined" end target = get_attribute attrs, :target # Default value is 8 bits if other value is not explicitly specified addressableSize = attrs.has_key?(:item_size) ? attrs[:item_size] : 8 @data_manager = DataManager.new(self) @data_manager.beginConfig target, addressableSize @data_manager.instance_eval &contents @data_manager.endConfig end
# File template.rb, line 698 def data_source @template.getDataSource end
# File template.rb, line 76 def define_method(method_name, &method_body) method_name = method_name.downcase if !Template.method_defined?(method_name) Template.send(:define_method, method_name, &method_body) else puts "Error: Failed to define the #{method_name} method" end end
# File template.rb, line 465 def define_op_group(name, distribution) if !distribution.is_a?(Dist) raise "#{distribution} is not a distribution" end @template.defineGroup name, distribution.java_object TemplateBuilder.define_operation_group name end
Creates an object describing the probability distribution for random generation (biased generation). Methods arguments specify ranges of values with corresponding biases.
# File template.rb, line 325 def dist(*ranges) if !ranges.is_a?(Array) raise "#{ranges} is not an Array" end builder = @template.newVariateBuilder ranges.each do |range_item| if !range_item.is_a?(ValueRange) raise "#{range_item} is not a ValueRange" end value = range_item.value bias = range_item.bias if value.is_a?(Range) min = [value.first, value.last].min max = [value.first, value.last].max if bias.nil? then builder.addInterval min, max else builder.addInterval min, max, bias end elsif value.is_a?(Array) if bias.nil? then builder.addCollection value else builder.addCollection value, bias end elsif value.is_a?(Dist) if bias.nil? then builder.addVariate value.java_object else builder.addVariate value.java_object, bias end else if bias.nil? then builder.addValue value else builder.addValue value, bias end end end Dist.new builder.build end
Ends a multi-line comment (uses ml_comment_ends_with)
# File template.rb, line 514 def end_comment print_format :COMMENT_ML_END, '' @is_multiline_comment = false end
# File template.rb, line 743 def entry(*args) if args.count != 0 and args.count != 2 raise "Wrong argument count: #{args.count}. Must be 0 or 2" end reference = BufferEntryReference.new @template if args.count == 2 reference.bits args[0], args[1] else reference end end
# File template.rb, line 915 def epilogue(&contents) @template.beginEpilogue self.instance_eval &contents @template.endEpilogue end
¶ ↑
Exception Handling
¶ ↑
# File template.rb, line 770 def exception_handler(attrs = {}, &contents) if attrs.has_key?(:id) id = attrs[:id] else id = '' end builder = @template.beginExceptionHandler id if attrs.has_key?(:instance) instance = attrs[:instance] else instance = 0..(get_option_value('instance-number').to_i - 1) end if instance.is_a?(Range) builder.setInstances instance.min, instance.max else builder.setInstances instance end exception_handler_object = ExceptionHandler.new self, builder exception_handler_object.instance_eval &contents @template.endExceptionHandler end
# File template.rb, line 147 def executed(&contents) set_attributes(:executed => true, &contents) end
¶ ↑
Test Generation
¶ ↑
# File template.rb, line 998 def generate java_import Java::Ru.ispras.microtesk.test.TestEngine engine = TestEngine.getInstance() TemplateBuilder.define_runtime_methods engine.getModel.getMetaData @template = engine.newTemplate @directive = Directive.new(self) @template.beginPreSection pre @template.endPreSection @template.beginPostSection post @template.endPostSection @template.beginMainSection run @template.endMainSection end
# File template.rb, line 207 def get_address_of(label) @template.getAddressForLabel label.to_s end
# File template.rb, line 251 def get_allocation_data(allocator, attrs) if !attrs.is_a?(Hash) raise "attrs (#{attrs}) must be a Hash" end retain = attrs[:retain] exclude = attrs[:exclude] track = attrs.has_key?(:track) ? attrs[:track] : -1 readAfterRate = attrs.has_key?(:read) ? attrs[:read] : attrs[:rate] writeAfterRate = attrs.has_key?(:write) ? attrs[:write] : attrs[:rate] reserved = attrs.has_key?(:reserved) ? attrs[:reserved] : false allocator = @default_allocator if allocator.nil? @template.newAllocationData( get_caller_location, allocator, retain, exclude, track, readAfterRate, writeAfterRate, reserved) end
# File template.rb, line 70 def get_caller_location(caller_index = 1) # Parses the caller of this method's caller, so the default index is 1 caller_info = Template.parse_caller(caller[caller_index]) @template.where File.basename(caller_info[0]), caller_info[1] end
# File template.rb, line 231 def get_new_situation(name, attrs, kind) if !attrs.is_a?(Hash) raise "attrs (#{attrs}) must be a Hash" end builder = @template.newSituation name, kind attrs.each_pair do |name, value| if value.is_a?(Dist) then attr_value = value.java_object elsif value.is_a?(Symbol) then attr_value = value.to_s else attr_value = value end builder.setAttribute name.to_s, attr_value end builder.build end
# File template.rb, line 1025 def get_option_value(name) java_import Java::Ru.ispras.microtesk.test.TestEngine engine = TestEngine.getInstance engine.getOptionValue name end
# File template.rb, line 191 def global_label(name) @template.addLabel name, true end
# File template.rb, line 702 def index_source @template.getIndexSource end
# File template.rb, line 1037 def is_rev(id) java_import Java::Ru.ispras.microtesk.test.TestEngine engine = TestEngine.getInstance engine.isRevision id end
# File template.rb, line 127 def iterate(attributes = {}, &contents) java_import Java::Ru.ispras.microtesk.test.template.Block add_new_block Block::Kind::ITERATE, attributes, get_caller_location, &contents end
# File template.rb, line 199 def label_b(index) numeric_label_ref index, false end
# File template.rb, line 203 def label_f(index) numeric_label_ref index, true end
Creates a location-based format argument for format-like output methods.
# File template.rb, line 479 def location(name, index) Location.new name, index end
¶ ↑
Memory Objects
¶ ↑
# File template.rb, line 925 def memory_object(attrs) size = get_attribute attrs, :size builder = @template.newMemoryObjectBuilder size va = get_attribute attrs, :va is_va_label = false if va.is_a?(Integer) builder.setVa va elsif va.is_a?(Range) builder.setVa va.min, va.max elsif va.is_a?(String) or va.is_a?(Symbol) builder.setVa va.to_s is_va_label = true else raise "The 'va' attribute has unsupported type #{va.class}" end if !is_va_label pa = get_attribute attrs, :pa if pa.is_a?(Integer) builder.setPa pa elsif pa.is_a?(Range) builder.setPa pa.min, pa.max elsif pa.is_a?(String) or pa.is_a?(Symbol) builder.setPa pa.to_s else raise "The 'pa' attribute has unsupported type #{pa.class}" end end if attrs.has_key?(:name) builder.setName attrs[:name].to_s end if attrs.has_key?(:mode) builder.setMode attrs[:mode].to_s end if attrs.has_key?(:data) builder.setData attrs[:data] end builder.build end
Uses address and data
# File template.rb, line 675 def memory_preparator(attrs, &contents) size = get_attribute attrs, :size builder = @template.beginMemoryPreparator size self.instance_eval &contents @template.endMemoryPreparator end
Hack to allow limited use of caps-locked characters
# File template.rb, line 62 def method_missing(meth, *args, &block) if self.respond_to?(meth.to_s.downcase) self.send meth.to_s.downcase.to_sym, *args, &block else super end end
Adds the new line character into the test program.
# File template.rb, line 489 def newline text '' end
# File template.rb, line 151 def nonexecuted(&contents) set_attributes(:executed => false, &contents) end
# File template.rb, line 859 def option(value) @template.addDirective @directive.option(value), get_caller_location end
# File template.rb, line 855 def org(value, is_absolute=false) @template.addDirective @directive.org(value, is_absolute), get_caller_location end
# File template.rb, line 851 def p2align(value, fill_with=-1) @template.addDirective @directive.p2align(value, fill_with), get_caller_location end
# File template.rb, line 971 def page_table(attrs = {}, &contents) if nil == @data_manager raise "Data configuration is not defined" end if attrs.has_key?(:global) global = attrs[:global] else global = false end if attrs.has_key?(:separate_file) separate_file = attrs[:separate_file] else separate_file = false end @data_manager.beginData global, separate_file page_table = PageTable.new self, @data_manager page_table.instance_eval &contents @data_manager.endData end
Epilogue
# File template.rb, line 100 def post end
Prologue
# File template.rb, line 90 def pre end
# File template.rb, line 655 def prepare(target_mode, value_object, attrs = {}) preparator_name = attrs[:name] if !preparator_name.nil? preparator_name = preparator_name.to_s end variant_name = attrs[:variant] if !variant_name.nil? variant_name = variant_name.to_s end value_object = value_object.java_object if value_object.is_a? WrappedObject @template.addPreparatorCall target_mode, value_object, preparator_name, variant_name end
Prints a format-based output to the simulator log or to the test program depending of the is_runtime flag.
# File template.rb, line 521 def print_format(kind, format, *args) java_import Java::Ru.ispras.microtesk.test.template.Value java_import Java::Ru.ispras.microtesk.test.template.Primitive builder = @template.newOutput kind.to_s, format args.each do |arg| if arg.is_a?(Integer) or arg.is_a?(String) or arg.is_a?(TrueClass) or arg.is_a?(FalseClass) or arg.is_a?(Value) builder.addArgument arg elsif arg.is_a?(Location) builder.addArgument arg.name, arg.index elsif arg.is_a?(Primitive) builder.addArgumentPrimitive arg else raise "Illegal format argument class #{arg.class}" end end @template.addOutput builder.build end
Creates a pseudo instruction call that prints user-specified text.
# File template.rb, line 544 def pseudo(text) @template.setCallText text @template.endBuildingCall end
Creates an object for generating a random integer (to be used as an argument of a mode or op) selected from the specified range or according to the specified distribution.
# File template.rb, line 300 def rand(*args) if args.count == 1 distribution = args.at(0) if !distribution.is_a?(Dist) raise "the argument must be a distribution" end @template.newRandom distribution.java_object elsif args.count == 2 from = args.at(0) to = args.at(1) if !from.is_a?(Integer) or !to.is_a?(Integer) raise "the arguments must be integers" end @template.newRandom from, to else raise "Wrong argument count: #{args.count}. Must be 1 or 2" end end
# File template.rb, line 279 def random_situation(dist) dist.java_object end
Creates an object describing a value range (with corresponding bias) used in random generation. If the bias attribute is not specified, it will be set to nil, which means the default bias.
# File template.rb, line 373 def range(attrs = {}) if !attrs.is_a?(Hash) raise "#{attrs} is not a Hash" end if !attrs.has_key?(:value) raise "The :value attribute is not specified in #{attrs}" end value = attrs[:value] bias = nil if attrs.has_key?(:bias) bias = attrs[:bias] if !bias.is_a?(Integer) raise "#{bias} is not an Integer" end end ValueRange.new value, bias end
# File template.rb, line 1031 def rev_id java_import Java::Ru.ispras.microtesk.test.TestEngine engine = TestEngine.getInstance engine.getModel.getRevisionId end
Main part
# File template.rb, line 95 def run puts "MicroTESK [Ruby] Warning: Trying to execute the original Template#run" end
¶ ↑
Sections
¶ ↑
# File template.rb, line 867 def section(attrs, &contents) name = get_attribute attrs, :name prefix = attrs.has_key?(:prefix) ? attrs[:prefix] : '' pa = attrs[:pa] va = attrs[:va] args = attrs.has_key?(:args) ? attrs[:args] : '' file = attrs.has_key?(:file) ? attrs[:file] : false @template.beginSection name, prefix, pa, va, args, file self.instance_eval &contents @template.endSection end
# File template.rb, line 893 def section_data(attrs = {}, &contents) prefix = attrs.has_key?(:prefix) ? attrs[:prefix] : '' pa = attrs[:pa] va = attrs[:va] args = attrs.has_key?(:args) ? attrs[:args] : '' @template.beginSectionData prefix, pa, va, args self.instance_eval &contents @template.endSection end
# File template.rb, line 881 def section_text(attrs = {}, &contents) prefix = attrs.has_key?(:prefix) ? attrs[:prefix] : '' pa = attrs[:pa] va = attrs[:va] args = attrs.has_key?(:args) ? attrs[:args] : '' @template.beginSectionText prefix, pa, va, args self.instance_eval &contents @template.endSection end
# File template.rb, line 117 def sequence(attributes = {}, &contents) java_import Java::Ru.ispras.microtesk.test.template.Block add_new_block Block::Kind::SEQUENCE, attributes, get_caller_location, &contents end
Sets the given attributes to the nested operations.
# File template.rb, line 160 def set_attributes(attributes, &contents) mapBuilder = set_builder_attributes @template.newMapBuilder, attributes @template.beginAttributes mapBuilder self.instance_eval &contents @template.endAttributes end
# File template.rb, line 436 def set_default_allocator(allocator) @default_allocator = allocator end
# File template.rb, line 283 def set_default_situation(names, &situations) if !names.is_a?(String) and !names.is_a?(Array) raise "#{names} must be String or Array" end default_situation = @situation_manager.instance_eval &situations if names.is_a?(Array) names.each do |name| @template.setDefaultSituation name, default_situation end else @template.setDefaultSituation names, default_situation end end
# File template.rb, line 440 def set_free(mode, flag) @template.addAllocatorAction mode, 'FREE', flag, false end
# File template.rb, line 444 def set_free_all(mode, flag) @template.addAllocatorAction mode, 'FREE', flag, true end
# File template.rb, line 1019 def set_option_value(name, value) java_import Java::Ru.ispras.microtesk.test.TestEngine engine = TestEngine.getInstance engine.setOptionValue name, value end
# File template.rb, line 448 def set_reserved(mode, flag) @template.addAllocatorAction mode, 'RESERVED', flag, false end
Sign-extends the specified value (currently, supports only LazyValue objects).
# File template.rb, line 644 def sign_extend(value_object, bit_size) value_object = value_object.java_object if value_object.is_a? WrappedObject value_object.signExtend bit_size end
Starts a multi-line comment (uses sl_comment_starts_with)
# File template.rb, line 508 def start_comment @is_multiline_comment = true print_format :COMMENT_ML_START, '' end
# File template.rb, line 706 def start_label @template.getStartLabel end
# File template.rb, line 710 def stream(label, data, index, length) @template.addStream label.to_s, data, index, length end
¶ ↑
Data Streams (see also StreamPreparator)
¶ ↑
# File template.rb, line 686 def stream_preparator(attrs, &contents) data = get_attribute attrs, :data_source index = get_attribute attrs, :index_source @template.beginStreamPreparator data.to_s, index.to_s data_stream_object = StreamPreparator.new self, @template data_stream_object.instance_eval &contents @template.endStreamPreparator end
# File template.rb, line 627 def target @template.getPreparatorTarget end
# File template.rb, line 220 def testdata(name, attrs = {}) java_import Java::Ru.ispras.microtesk.test.template.Situation get_new_situation name, attrs, Situation::Kind::TESTDATA end
Adds text into the test program.
# File template.rb, line 494 def text(format, *args) if @is_multiline_comment print_format :COMMENT_ML_BODY, format, *args else print_format :TEXT, format, *args end end
Prints text into the simulator execution log.
# File template.rb, line 484 def trace(format, *args) print_format :TRACE, format, *args end
# File template.rb, line 631 def value(*args) if args.count != 0 and args.count != 2 raise "Wrong argument count: #{args.count}. Must be 0 or 2" end if args.count == 2 @template.newLazy args.at(0), args.at(1) else @template.newLazy end end
# File template.rb, line 618 def variant(attrs = {}, &contents) name = attrs[:name] bias = attrs[:bias] @template.beginPreparatorVariant name, bias self.instance_eval &contents @template.endPreparatorVariant end
# File template.rb, line 195 def weak(name) @template.addWeakLabel name end
Zero-extends the specified value (currently, supports only LazyValue objects).
# File template.rb, line 650 def zero_extend(value_object, bit_size) value_object = value_object.java_object if value_object.is_a? WrappedObject value_object.zeroExtend bit_size end