origen_sim 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/shared_commands.rb +18 -0
- data/config/version.rb +1 -1
- data/ext/bridge.c +6 -6
- data/ext/common.h +4 -0
- data/ext/defines.h.erb +1 -0
- data/ext/origen.c +8 -0
- data/lib/origen_sim/commands/build.rb +4 -2
- data/lib/origen_sim/commands/pack.rb +37 -0
- data/lib/origen_sim/simulator.rb +206 -58
- data/lib/origen_sim/tester.rb +9 -2
- data/lib/origen_sim.rb +77 -0
- metadata +5 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f670da6bba360fa76ac30b10cd097cde48d6353a
         | 
| 4 | 
            +
              data.tar.gz: 07a1c407163212fd4fd04b45336ff399751155e2
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 0f0bcd9d653bf6ba02617116e3d843c9e1f39c20f023544b9cf5bbf152289fd9fa5654be8d72b2bcd77928f0a26041ed4da9370110b1281b98e1e7568df73aa5
         | 
| 7 | 
            +
              data.tar.gz: 1bd7de244589567b366d0213279df4f295f0ed374311bfc1b22d0666eacfd6855c19ecaa7fe4f7c6214452d54fb0ab4076b69f3714fae397dc9d25142ebfa580
         | 
    
        data/config/shared_commands.rb
    CHANGED
    
    | @@ -16,10 +16,28 @@ when "sim:co", "origen_sim:co" | |
| 16 16 | 
             
              require "#{Origen.root!}/lib/origen_sim/commands/co"
         | 
| 17 17 | 
             
              exit 0
         | 
| 18 18 |  | 
| 19 | 
            +
            when "sim:pack"
         | 
| 20 | 
            +
              require "#{Origen.root!}/lib/origen_sim/commands/pack"
         | 
| 21 | 
            +
              OrigenSim::Commands::Pack.pack
         | 
| 22 | 
            +
              exit 0
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            when "sim:unpack"
         | 
| 25 | 
            +
              require "#{Origen.root!}/lib/origen_sim/commands/pack"
         | 
| 26 | 
            +
              OrigenSim::Commands::Pack.unpack
         | 
| 27 | 
            +
              exit 0
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #when "sim:list"
         | 
| 30 | 
            +
            #  require "#{Origen.root!}/lib/origen_sim/commands/pack"
         | 
| 31 | 
            +
            #  OrigenSim::Commands::Pack.list
         | 
| 32 | 
            +
            #  exit 0
         | 
| 33 | 
            +
             | 
| 19 34 | 
             
            else
         | 
| 20 35 | 
             
              @plugin_commands << <<-EOT
         | 
| 21 36 | 
             
             sim:ci       Checkin a simulation snapshot
         | 
| 22 37 | 
             
             sim:co       Checkout a simulation snapshot
         | 
| 38 | 
            +
             sim:pack     Packs the snapshot into a compressed directory
         | 
| 39 | 
            +
             sim:unpack   Unpacks a snapshot
         | 
| 40 | 
            +
             sim:list     List the available snapshot packs
         | 
| 23 41 | 
             
              EOT
         | 
| 24 42 |  | 
| 25 43 | 
             
            end
         | 
    
        data/config/version.rb
    CHANGED
    
    
    
        data/ext/bridge.c
    CHANGED
    
    | @@ -83,7 +83,7 @@ static void bridge_define_pin(char * name, char * pin_ix, char * drive_wave_ix, | |
| 83 83 | 
             
              (*pin).capture_en = false;
         | 
| 84 84 |  | 
| 85 85 | 
             
              char * driver = (char *) malloc(strlen(name) + 16);
         | 
| 86 | 
            -
              strcpy(driver, " | 
| 86 | 
            +
              strcpy(driver, ORIGEN_SIM_TESTBENCH_CAT("pins."));
         | 
| 87 87 | 
             
              strcat(driver, name);
         | 
| 88 88 |  | 
| 89 89 | 
             
              char * data = (char *) malloc(strlen(driver) + 16);
         | 
| @@ -661,7 +661,7 @@ PLI_INT32 bridge_wait_for_msg(p_cb_data data) { | |
| 661 661 | 
             
                  // Set Pattern Name
         | 
| 662 662 | 
             
                  //   a^atd_ramp_25mhz
         | 
| 663 663 | 
             
                  case 'a' :
         | 
| 664 | 
            -
                    handle = vpi_handle_by_name(" | 
| 664 | 
            +
                    handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("debug.pattern"), NULL);
         | 
| 665 665 | 
             
                    arg1 = strtok(NULL, "^");
         | 
| 666 666 |  | 
| 667 667 | 
             
                    v.format = vpiStringVal;
         | 
| @@ -686,7 +686,7 @@ PLI_INT32 bridge_wait_for_msg(p_cb_data data) { | |
| 686 686 | 
             
                  // Set Comment
         | 
| 687 687 | 
             
                  //   c^Some comment about the pattern
         | 
| 688 688 | 
             
                  case 'c' :
         | 
| 689 | 
            -
                    handle = vpi_handle_by_name(" | 
| 689 | 
            +
                    handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("debug.comments"), NULL);
         | 
| 690 690 | 
             
                    arg1 = strtok(NULL, "^");
         | 
| 691 691 |  | 
| 692 692 | 
             
                    v.format = vpiStringVal;
         | 
| @@ -710,14 +710,14 @@ PLI_INT32 bridge_wait_for_msg(p_cb_data data) { | |
| 710 710 | 
             
                    break;
         | 
| 711 711 | 
             
                  // Sync enable
         | 
| 712 712 | 
             
                  case 'f' :
         | 
| 713 | 
            -
                    handle = vpi_handle_by_name(" | 
| 713 | 
            +
                    handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("pins.sync"), NULL);
         | 
| 714 714 | 
             
                    v.format = vpiDecStrVal;
         | 
| 715 715 | 
             
                    v.value.str = "1";
         | 
| 716 716 | 
             
                    vpi_put_value(handle, &v, NULL, vpiNoDelay);
         | 
| 717 717 | 
             
                    break;
         | 
| 718 718 | 
             
                  // Sync disable
         | 
| 719 719 | 
             
                  case 'g' :
         | 
| 720 | 
            -
                    handle = vpi_handle_by_name(" | 
| 720 | 
            +
                    handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("pins.sync"), NULL);
         | 
| 721 721 | 
             
                    v.format = vpiDecStrVal;
         | 
| 722 722 | 
             
                    v.value.str = "0";
         | 
| 723 723 | 
             
                    vpi_put_value(handle, &v, NULL, vpiNoDelay);
         | 
| @@ -751,7 +751,7 @@ static void end_simulation() { | |
| 751 751 | 
             
              s_vpi_value v;
         | 
| 752 752 |  | 
| 753 753 | 
             
              // Setting this node will cause the testbench to call $finish
         | 
| 754 | 
            -
              handle = vpi_handle_by_name(" | 
| 754 | 
            +
              handle = vpi_handle_by_name(ORIGEN_SIM_TESTBENCH_CAT("finish"), NULL);
         | 
| 755 755 | 
             
              v.format = vpiDecStrVal;
         | 
| 756 756 | 
             
              v.value.str = "1";
         | 
| 757 757 | 
             
              vpi_put_value(handle, &v, NULL, vpiNoDelay);
         | 
    
        data/ext/common.h
    CHANGED
    
    | @@ -11,6 +11,10 @@ | |
| 11 11 |  | 
| 12 12 | 
             
            #define ENABLE_DEBUG
         | 
| 13 13 |  | 
| 14 | 
            +
            /// Prepends the testbench name to the signal.
         | 
| 15 | 
            +
            /// e.g.: TESTBENCH_CAT(pins) => TESTBENCH_NAME.pins => origen.pins
         | 
| 16 | 
            +
            #define ORIGEN_SIM_TESTBENCH_CAT(signal) ORIGEN_SIM_TESTBENCH_NAME "." signal
         | 
| 17 | 
            +
             | 
| 14 18 | 
             
            #ifdef ENABLE_DEBUG
         | 
| 15 19 | 
             
            /* #define DEBUG(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
         | 
| 16 20 | 
             
                __FILE__, __LINE__, __func__, ##args) */
         | 
    
        data/ext/defines.h.erb
    CHANGED
    
    
    
        data/ext/origen.c
    CHANGED
    
    | @@ -85,6 +85,14 @@ PLI_INT32 origen_shutdown(p_cb_data data) { | |
| 85 85 | 
             
              return 0;
         | 
| 86 86 | 
             
            }
         | 
| 87 87 |  | 
| 88 | 
            +
            /// Function to call the init PLI's init function
         | 
| 89 | 
            +
            /// Some toolchains will call this automatically, some will not
         | 
| 90 | 
            +
            /// Available here for those which do not automatically call init() for each PLI 
         | 
| 91 | 
            +
            PLI_INT32 bootstrap(p_cb_data data) {
         | 
| 92 | 
            +
              vpi_printf("Origen Bootstrap Called!\n");
         | 
| 93 | 
            +
              init();
         | 
| 94 | 
            +
              return 0;
         | 
| 95 | 
            +
            }
         | 
| 88 96 |  | 
| 89 97 | 
             
            ///
         | 
| 90 98 | 
             
            /// Registers a very basic VPI callback with reason and handler.
         | 
| @@ -3,7 +3,7 @@ require 'origen_sim' | |
| 3 3 | 
             
            require_relative '../../../config/version'
         | 
| 4 4 | 
             
            require 'origen_verilog'
         | 
| 5 5 |  | 
| 6 | 
            -
            options = { source_dirs: [] }
         | 
| 6 | 
            +
            options = { source_dirs: [], testbench_name: 'origen' }
         | 
| 7 7 |  | 
| 8 8 | 
             
            # App options are options that the application can supply to extend this command
         | 
| 9 9 | 
             
            app_options = @application_options || []
         | 
| @@ -18,6 +18,7 @@ Usage: origen sim:build TOP_LEVEL_VERILOG_FILE [options] | |
| 18 18 | 
             
              EOT
         | 
| 19 19 | 
             
              opts.on('-o', '--output DIR', String, 'Override the default output directory') { |t| options[:output] = t }
         | 
| 20 20 | 
             
              opts.on('-t', '--top NAME', String, 'Specify the top-level Verilog module name if OrigenSim can\'t work it out') { |t| options[:top_level_name] = t }
         | 
| 21 | 
            +
              opts.on('--testbench NAME', String, 'Specify the testbench name if different from \'origen\'') { |t| options[:testbench_name] = t }
         | 
| 21 22 | 
             
              opts.on('-s', '--source_dir PATH', 'Directories to look for include files in (the directory containing the top-level is already considered)') do |path|
         | 
| 22 23 | 
             
                options[:source_dirs] << path
         | 
| 23 24 | 
             
              end
         | 
| @@ -86,7 +87,8 @@ Origen.app.runner.launch action:            :compile, | |
| 86 87 | 
             
                                     files:             "#{Origen.root!}/ext",
         | 
| 87 88 | 
             
                                     output:            output_directory,
         | 
| 88 89 | 
             
                                     check_for_changes: false,
         | 
| 89 | 
            -
                                     quiet:             true
         | 
| 90 | 
            +
                                     quiet:             true,
         | 
| 91 | 
            +
                                     options:           options
         | 
| 90 92 |  | 
| 91 93 | 
             
            dut.export(rtl_top_module, dir: "#{output_directory}", namespace: nil)
         | 
| 92 94 |  | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module OrigenSim
         | 
| 2 | 
            +
              module Commands
         | 
| 3 | 
            +
                module Pack
         | 
| 4 | 
            +
                  # Note, making this a module instead of straight code so it can be called
         | 
| 5 | 
            +
                  # programatically to auto-unpack a snapshot.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def self.pack(options = {})
         | 
| 8 | 
            +
                    testbench = "#{Origen.app.root}/simulation"
         | 
| 9 | 
            +
                    unless Dir.exist?(testbench)
         | 
| 10 | 
            +
                      fail "Could not find path #{testbench}/#{ARGV[0]}"
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    FileUtils.mkdir("#{Origen.app.root}/simulation/static") unless Dir.exist?("#{Origen.app.root}/simulation/static")
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    output = "#{Origen.app.root}/simulation/static/#{ARGV[0]}.tar.gz"
         | 
| 16 | 
            +
                    puts "Packing #{testbench} into #{output}..."
         | 
| 17 | 
            +
                    system "tar vczf #{output} -C #{testbench} #{Origen.target.name}"
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def self.unpack(options = {})
         | 
| 21 | 
            +
                    testbench = "#{Origen.app.root}/simulation/static/#{ARGV[0]}.tar.gz"
         | 
| 22 | 
            +
                    unless File.exist?(testbench)
         | 
| 23 | 
            +
                      fail "Could not find #{testbench}"
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    output = "#{Origen.app.root}/simulation"
         | 
| 27 | 
            +
                    FileUtils.mkdir(output) unless Dir.exist?(output)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    puts "Unpakcing Testbench into #{output}"
         | 
| 30 | 
            +
                    system "tar vxzf #{testbench} -C #{output} #{ARGV[0]}"
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def self.list(options = {})
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
    
        data/lib/origen_sim/simulator.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            require 'socket'
         | 
| 2 | 
            +
            require 'io/wait'
         | 
| 2 3 | 
             
            module OrigenSim
         | 
| 3 4 | 
             
              # Responsible for managing and communicating with the simulator
         | 
| 4 5 | 
             
              # process, a single instance of this class is instantiated as
         | 
| @@ -6,10 +7,16 @@ module OrigenSim | |
| 6 7 | 
             
              class Simulator
         | 
| 7 8 | 
             
                include Origen::PersistentCallbacks
         | 
| 8 9 |  | 
| 9 | 
            -
                VENDORS = [:icarus, :cadence, :synopsys]
         | 
| 10 | 
            +
                VENDORS = [:icarus, :cadence, :synopsys, :generic]
         | 
| 10 11 |  | 
| 11 | 
            -
                attr_reader :socket, :failed, :configuration
         | 
| 12 | 
            +
                attr_reader :socket, :failed, :configuration, :stderr, :stdout, :heartbeat
         | 
| 12 13 | 
             
                alias_method :config, :configuration
         | 
| 14 | 
            +
                # Returns the PID of the simulator process
         | 
| 15 | 
            +
                attr_reader :pid
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def initialize
         | 
| 18 | 
            +
                  @socket_ids = {}
         | 
| 19 | 
            +
                end
         | 
| 13 20 |  | 
| 14 21 | 
             
                # When set to true the simulator will log all messages it receives, note that
         | 
| 15 22 | 
             
                # this must be run in conjunction with -d supplied to the Origen command to actually
         | 
| @@ -22,6 +29,22 @@ module OrigenSim | |
| 22 29 | 
             
                  end
         | 
| 23 30 | 
             
                end
         | 
| 24 31 |  | 
| 32 | 
            +
                def testbench_top
         | 
| 33 | 
            +
                  config[:testbench_top] || 'origen'
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def rtl_top
         | 
| 37 | 
            +
                  config[:rtl_top] || 'dut'
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def generic_run_cmd
         | 
| 41 | 
            +
                  config[:generic_run_cmd]
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def post_process_run_cmd
         | 
| 45 | 
            +
                  config[:post_process_run_cmd]
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 25 48 | 
             
                def fetch_simulation_objects(options = {})
         | 
| 26 49 | 
             
                  sid = options[:id] || id
         | 
| 27 50 | 
             
                  ldir = "#{Origen.root}/simulation/#{sid}"
         | 
| @@ -83,7 +106,7 @@ module OrigenSim | |
| 83 106 | 
             
                  FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
         | 
| 84 107 | 
             
                end
         | 
| 85 108 |  | 
| 86 | 
            -
                def configure(options)
         | 
| 109 | 
            +
                def configure(options, &block)
         | 
| 87 110 | 
             
                  fail 'A vendor must be supplied, e.g. OrigenSim::Tester.new(vendor: :icarus)' unless options[:vendor]
         | 
| 88 111 | 
             
                  unless VENDORS.include?(options[:vendor])
         | 
| 89 112 | 
             
                    fail "Unknown vendor #{options[:vendor]}, valid values are: #{VENDORS.map { |v| ':' + v.to_s }.join(', ')}"
         | 
| @@ -125,14 +148,6 @@ module OrigenSim | |
| 125 148 | 
             
                  end
         | 
| 126 149 | 
             
                end
         | 
| 127 150 |  | 
| 128 | 
            -
                def pid_dir
         | 
| 129 | 
            -
                  @pid_dir ||= begin
         | 
| 130 | 
            -
                    d = "#{Origen.root}/tmp/origen_sim/pids"
         | 
| 131 | 
            -
                    FileUtils.mkdir_p(d)
         | 
| 132 | 
            -
                    d
         | 
| 133 | 
            -
                  end
         | 
| 134 | 
            -
                end
         | 
| 135 | 
            -
             | 
| 136 151 | 
             
                def wave_config_dir
         | 
| 137 152 | 
             
                  @wave_config_dir ||= begin
         | 
| 138 153 | 
             
                    d = "#{Origen.root}/config/waves/#{id}"
         | 
| @@ -215,10 +230,42 @@ module OrigenSim | |
| 215 230 | 
             
                  when :synopsys
         | 
| 216 231 | 
             
                    cmd = "#{compiled_dir}/simv +socket+#{socket_id} -vpd_file origen.vpd"
         | 
| 217 232 |  | 
| 233 | 
            +
                  when :generic
         | 
| 234 | 
            +
                    # Generic tester requires that a generic_run_command option/block be provided.
         | 
| 235 | 
            +
                    # This should either be a string, an array (which will be joined here), or a block that needs to return either
         | 
| 236 | 
            +
                    # a string or array. In the event of a block, the block will be given the simulator.
         | 
| 237 | 
            +
                    if generic_run_cmd
         | 
| 238 | 
            +
                      cmd = generic_run_cmd
         | 
| 239 | 
            +
                      if cmd.is_a?(Proc)
         | 
| 240 | 
            +
                        cmd = cmd.call(self)
         | 
| 241 | 
            +
                      end
         | 
| 242 | 
            +
             | 
| 243 | 
            +
                      if cmd.is_a?(Array)
         | 
| 244 | 
            +
                        # We'll join this together with the '; ' string. This means that each array element will be run
         | 
| 245 | 
            +
                        # sequentially.
         | 
| 246 | 
            +
                        cmd = cmd.join(' && ')
         | 
| 247 | 
            +
                      elsif !cmd.is_a?(String)
         | 
| 248 | 
            +
                        # If its Proc, it was already run, and if its a Array if would have gone into the other case.
         | 
| 249 | 
            +
                        # So, this is either another proc, not an array and not a string, so not sure what to do with this.
         | 
| 250 | 
            +
                        # Complain about the cmd.
         | 
| 251 | 
            +
                        fail "OrigenSim :generic_run_cmd is of class #{generic_run_cmd.class}. It must be either an Array, String, or a Proc that returns an Array or String."
         | 
| 252 | 
            +
                      end
         | 
| 253 | 
            +
                    else
         | 
| 254 | 
            +
                      fail 'OrigenSim Generic Toolchain/Vendor requires a :generic_run_cmd option/block to be provided. No options/block provided!'
         | 
| 255 | 
            +
                    end
         | 
| 256 | 
            +
             | 
| 218 257 | 
             
                  else
         | 
| 219 258 | 
             
                    fail "Run cmd not defined yet for simulator #{config[:vendor]}"
         | 
| 220 259 |  | 
| 221 260 | 
             
                  end
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                  # Allow the user to post-process the command. This should be a block which will be given two parameters:
         | 
| 263 | 
            +
                  # 1. the command, and 2. the simulation object (self).
         | 
| 264 | 
            +
                  # In the event of a generic tester, this *could* replace the launch command, but that's not the real intention,
         | 
| 265 | 
            +
                  # since a simulator could be made that inherits from a generic simulator setup and still post process the command.
         | 
| 266 | 
            +
                  cmd = post_process_run_cmd.call(cmd, self) if post_process_run_cmd
         | 
| 267 | 
            +
                  fail "OrigenSim: :post_process_run_cmd returned object of class #{cmd.class}. Must return a String." unless cmd.is_a?(String)
         | 
| 268 | 
            +
             | 
| 222 269 | 
             
                  cmd
         | 
| 223 270 | 
             
                end
         | 
| 224 271 |  | 
| @@ -253,6 +300,20 @@ module OrigenSim | |
| 253 300 | 
             
                    cmd += " -session #{f}"
         | 
| 254 301 | 
             
                    cmd += ' &'
         | 
| 255 302 |  | 
| 303 | 
            +
                  when :generic
         | 
| 304 | 
            +
                    # Since this could be anything, the simulator will need to set this up. But, once it is, we can print it here.
         | 
| 305 | 
            +
                    if config[:view_waveform_cmd]
         | 
| 306 | 
            +
                      cmd = config[:view_waveform_cmd]
         | 
| 307 | 
            +
                    else
         | 
| 308 | 
            +
                      Origen.log.warn 'OrigenSim cannot provide a view-waveform command for a :generic vendor.'
         | 
| 309 | 
            +
                      Origen.log.warn 'Please supply a view-waveform command though the :view_waveform_cmd option during the OrigenSim::Generic instantiation.'
         | 
| 310 | 
            +
                    end
         | 
| 311 | 
            +
             | 
| 312 | 
            +
                  else
         | 
| 313 | 
            +
                    # Print a warning stating an unknown vendor was reached here.
         | 
| 314 | 
            +
                    # This shouldn't happen, but just in case.
         | 
| 315 | 
            +
                    Origen.log.warn "OrigenSim does not know the command to view waveforms for vendor :#{config[:vendor]}!"
         | 
| 316 | 
            +
             | 
| 256 317 | 
             
                  end
         | 
| 257 318 | 
             
                  cmd
         | 
| 258 319 | 
             
                end
         | 
| @@ -270,31 +331,86 @@ module OrigenSim | |
| 270 331 | 
             
                def start
         | 
| 271 332 | 
             
                  fetch_simulation_objects
         | 
| 272 333 |  | 
| 334 | 
            +
                  # Socket used for Origen -> Verilog commands
         | 
| 273 335 | 
             
                  server = UNIXServer.new(socket_id)
         | 
| 274 | 
            -
                   | 
| 336 | 
            +
                  # Socket used to capture stdout from the simulator
         | 
| 337 | 
            +
                  stdout_socket_id = socket_id(:stdout)
         | 
| 338 | 
            +
                  # Socket used to capture stderr from the simulator
         | 
| 339 | 
            +
                  stderr_socket_id = socket_id(:stderr)
         | 
| 340 | 
            +
                  # Socket used to provide a heartbeat to let the Ruby process in charge of the simulator
         | 
| 341 | 
            +
                  # know that the mast Origen process is still alive. If the Origen process crashes and leaves
         | 
| 342 | 
            +
                  # the simulator running, the child process will automatically reap it after a couple of missed
         | 
| 343 | 
            +
                  # heartbeats
         | 
| 344 | 
            +
                  heartbeat_socket_id = socket_id(:heartbeat)
         | 
| 345 | 
            +
                  server_stdout = UNIXServer.new(stdout_socket_id)
         | 
| 346 | 
            +
                  server_stderr = UNIXServer.new(stderr_socket_id)
         | 
| 347 | 
            +
                  server_heartbeat = UNIXServer.new(heartbeat_socket_id)
         | 
| 275 348 | 
             
                  cmd = run_cmd + ' & echo \$!'
         | 
| 276 349 |  | 
| 277 350 | 
             
                  launch_simulator = %(
         | 
| 278 351 | 
             
                    require 'open3'
         | 
| 352 | 
            +
                    require 'socket'
         | 
| 353 | 
            +
                    require 'io/wait'
         | 
| 354 | 
            +
                    require 'origen'
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                    pid = nil
         | 
| 357 | 
            +
             | 
| 358 | 
            +
                    stdout_socket = UNIXSocket.new('#{stdout_socket_id}')
         | 
| 359 | 
            +
                    stderr_socket = UNIXSocket.new('#{stderr_socket_id}')
         | 
| 360 | 
            +
                    heartbeat = UNIXSocket.new('#{heartbeat_socket_id}')
         | 
| 361 | 
            +
             | 
| 362 | 
            +
                    begin
         | 
| 363 | 
            +
             | 
| 364 | 
            +
                      Dir.chdir '#{run_dir}' do
         | 
| 365 | 
            +
                        Open3.popen3('#{cmd}') do |stdin, stdout, stderr, thread|
         | 
| 366 | 
            +
                          pid = stdout.gets.strip.to_i
         | 
| 367 | 
            +
                          heartbeat.puts(pid.to_s)
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                          # Listen for a heartbeat from the main Origen process every 5 seconds, kill the
         | 
| 370 | 
            +
                          # simulator after two missed heartbeats
         | 
| 371 | 
            +
                          Thread.new do
         | 
| 372 | 
            +
                            missed_heartbeats = 0
         | 
| 373 | 
            +
                            loop do
         | 
| 374 | 
            +
                              sleep 5
         | 
| 375 | 
            +
                              if heartbeat.ready?
         | 
| 376 | 
            +
                                while heartbeat.ready? do
         | 
| 377 | 
            +
                                  heartbeat.gets
         | 
| 378 | 
            +
                                end
         | 
| 379 | 
            +
                                missed_heartbeats = 0
         | 
| 380 | 
            +
                              else
         | 
| 381 | 
            +
                                missed_heartbeats += 1
         | 
| 382 | 
            +
                              end
         | 
| 383 | 
            +
                              if missed_heartbeats > 1
         | 
| 384 | 
            +
                                Process.kill('KILL', pid)
         | 
| 385 | 
            +
                                exit!(1)
         | 
| 386 | 
            +
                              end
         | 
| 387 | 
            +
                            end
         | 
| 388 | 
            +
                          end
         | 
| 279 389 |  | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
                        end
         | 
| 286 | 
            -
                        threads = []
         | 
| 287 | 
            -
                        threads << Thread.new do
         | 
| 288 | 
            -
                          until (line = stdout.gets).nil?
         | 
| 289 | 
            -
                            puts line if #{verbose ? 'true' : 'false'}
         | 
| 390 | 
            +
                          threads = []
         | 
| 391 | 
            +
                          threads << Thread.new do
         | 
| 392 | 
            +
                            until (line = stdout.gets).nil?
         | 
| 393 | 
            +
                              stdout_socket.puts line
         | 
| 394 | 
            +
                            end
         | 
| 290 395 | 
             
                          end
         | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
                             | 
| 396 | 
            +
                          threads << Thread.new do
         | 
| 397 | 
            +
                            until (line = stderr.gets).nil?
         | 
| 398 | 
            +
                              stderr_socket.puts line
         | 
| 399 | 
            +
                            end
         | 
| 295 400 | 
             
                          end
         | 
| 401 | 
            +
                          threads.each(&:join)
         | 
| 296 402 | 
             
                        end
         | 
| 297 | 
            -
             | 
| 403 | 
            +
                      end
         | 
| 404 | 
            +
             | 
| 405 | 
            +
                    ensure
         | 
| 406 | 
            +
                      # Make sure this process never finishes and leaves the simulator running
         | 
| 407 | 
            +
                      begin
         | 
| 408 | 
            +
                        # If the process already finished, then we will see an Errno exception.
         | 
| 409 | 
            +
                        # It does not harm anything, but looks ugly, so catch it here and ignore.
         | 
| 410 | 
            +
                        Process.kill('KILL', pid) if pid
         | 
| 411 | 
            +
                        0
         | 
| 412 | 
            +
                      rescue Errno::ESRCH => e
         | 
| 413 | 
            +
                        0
         | 
| 298 414 | 
             
                      end
         | 
| 299 415 | 
             
                    end
         | 
| 300 416 | 
             
                  )
         | 
| @@ -303,6 +419,19 @@ module OrigenSim | |
| 303 419 | 
             
                  Process.detach(simulator_parent_process)
         | 
| 304 420 |  | 
| 305 421 | 
             
                  timeout_connection(config[:startup_timeout] || 60) do
         | 
| 422 | 
            +
                    @heartbeat = server_heartbeat.accept
         | 
| 423 | 
            +
                    @pid = heartbeat.gets.chomp.to_i
         | 
| 424 | 
            +
             | 
| 425 | 
            +
                    # Send a heartbeat to the child process running the simulator every 5 seconds
         | 
| 426 | 
            +
                    Thread.new do
         | 
| 427 | 
            +
                      loop do
         | 
| 428 | 
            +
                        heartbeat.write("OK\n")
         | 
| 429 | 
            +
                        sleep 5
         | 
| 430 | 
            +
                      end
         | 
| 431 | 
            +
                    end
         | 
| 432 | 
            +
             | 
| 433 | 
            +
                    @stdout = server_stdout.accept
         | 
| 434 | 
            +
                    @stderr = server_stderr.accept
         | 
| 306 435 | 
             
                    @socket = server.accept
         | 
| 307 436 | 
             
                    @connection_established = true
         | 
| 308 437 | 
             
                    if @connection_timed_out
         | 
| @@ -327,22 +456,9 @@ module OrigenSim | |
| 327 456 | 
             
                  Origen.listeners_for(:simulation_startup).each(&:simulation_startup)
         | 
| 328 457 | 
             
                end
         | 
| 329 458 |  | 
| 330 | 
            -
                # Returns the pid of the simulator process
         | 
| 331 | 
            -
                def pid
         | 
| 332 | 
            -
                  return @pid if @pid_set
         | 
| 333 | 
            -
                  @pid = File.readlines(pid_file).first.strip.to_i if File.exist?(pid_file)
         | 
| 334 | 
            -
                  @pid ||= 0
         | 
| 335 | 
            -
                  @pid_set = true
         | 
| 336 | 
            -
                  @pid
         | 
| 337 | 
            -
                end
         | 
| 338 | 
            -
             | 
| 339 | 
            -
                def pid_file
         | 
| 340 | 
            -
                  "#{Origen.root}/tmp/origen_sim/pids/#{socket_number}"
         | 
| 341 | 
            -
                end
         | 
| 342 | 
            -
             | 
| 343 459 | 
             
                # Returns true if the simulator process is running
         | 
| 344 460 | 
             
                def running?
         | 
| 345 | 
            -
                  return false  | 
| 461 | 
            +
                  return false unless pid
         | 
| 346 462 | 
             
                  begin
         | 
| 347 463 | 
             
                    Process.getpgid(pid)
         | 
| 348 464 | 
             
                    true
         | 
| @@ -474,6 +590,7 @@ module OrigenSim | |
| 474 590 |  | 
| 475 591 | 
             
                def cycle(number_of_cycles)
         | 
| 476 592 | 
             
                  put("3^#{number_of_cycles}")
         | 
| 593 | 
            +
                  read_sim_output
         | 
| 477 594 | 
             
                end
         | 
| 478 595 |  | 
| 479 596 | 
             
                # Blocks the Origen process until the simulator indicates that it has
         | 
| @@ -484,11 +601,42 @@ module OrigenSim | |
| 484 601 | 
             
                  unless data.strip == 'OK!'
         | 
| 485 602 | 
             
                    fail 'Origen and the simulator are out of sync!'
         | 
| 486 603 | 
             
                  end
         | 
| 604 | 
            +
                  read_sim_output
         | 
| 605 | 
            +
                end
         | 
| 606 | 
            +
             | 
| 607 | 
            +
                def read_sim_output
         | 
| 608 | 
            +
                  while stdout.ready?
         | 
| 609 | 
            +
                    line = stdout.gets.chomp
         | 
| 610 | 
            +
                    if OrigenSim.error_strings.any? { |s| line =~ /#{s}/ } &&
         | 
| 611 | 
            +
                       !OrigenSim.error_string_exceptions.any? { |s| line =~ /#{s}/ }
         | 
| 612 | 
            +
                      @simulator_logged_errors = true
         | 
| 613 | 
            +
                      Origen.log.error "(STDOUT): #{line}"
         | 
| 614 | 
            +
                    else
         | 
| 615 | 
            +
                      if OrigenSim.verbose? ||
         | 
| 616 | 
            +
                         OrigenSim.log_strings.any? { |s| line =~ /#{s}/ }
         | 
| 617 | 
            +
                        Origen.log.info line
         | 
| 618 | 
            +
                      else
         | 
| 619 | 
            +
                        Origen.log.debug line
         | 
| 620 | 
            +
                      end
         | 
| 621 | 
            +
                    end
         | 
| 622 | 
            +
                  end
         | 
| 623 | 
            +
                  while stderr.ready?
         | 
| 624 | 
            +
                    line = stderr.gets.chomp
         | 
| 625 | 
            +
                    if OrigenSim.fail_on_stderr && !OrigenSim.stderr_string_exceptions.any? { |s| line =~ /#{s}/ }
         | 
| 626 | 
            +
                      # We're failing on stderr, so print its results and log as errors if its not an exception.
         | 
| 627 | 
            +
                      @stderr_logged_errors = true
         | 
| 628 | 
            +
                      Origen.log.error "(STDERR): #{line}"
         | 
| 629 | 
            +
                    elsif OrigenSim.verbose?
         | 
| 630 | 
            +
                      # We're not failing on stderr, or the string in stderr is an exception.
         | 
| 631 | 
            +
                      # Print the string as regular output if verbose is set, otherwise just ignore.
         | 
| 632 | 
            +
                      Origen.log.info line
         | 
| 633 | 
            +
                    end
         | 
| 634 | 
            +
                  end
         | 
| 487 635 | 
             
                end
         | 
| 488 636 |  | 
| 489 637 | 
             
                # Returns the current simulation error count
         | 
| 490 638 | 
             
                def error_count
         | 
| 491 | 
            -
                  peek( | 
| 639 | 
            +
                  peek("#{testbench_top}.debug.errors").to_i
         | 
| 492 640 | 
             
                end
         | 
| 493 641 |  | 
| 494 642 | 
             
                # Returns the current value of the given net, or nil if the given path does not
         | 
| @@ -546,7 +694,6 @@ module OrigenSim | |
| 546 694 |  | 
| 547 695 | 
             
                    v = peek(path)
         | 
| 548 696 | 
             
                    return nil unless v
         | 
| 549 | 
            -
             | 
| 550 697 | 
             
                    # Setting a range of bits
         | 
| 551 698 | 
             
                    if lsb
         | 
| 552 699 | 
             
                      upper = v >> (msb + 1)
         | 
| @@ -588,15 +735,16 @@ module OrigenSim | |
| 588 735 | 
             
                  Origen.listeners_for(:simulation_shutdown).each(&:simulation_shutdown)
         | 
| 589 736 | 
             
                  ended = Time.now
         | 
| 590 737 | 
             
                  end_simulation
         | 
| 591 | 
            -
                  # Give the simulator  | 
| 592 | 
            -
                  sleep 1 while running? | 
| 593 | 
            -
                   | 
| 594 | 
            -
                   | 
| 595 | 
            -
                   | 
| 596 | 
            -
                   | 
| 597 | 
            -
                  FileUtils.rm_f(pid_file) if File.exist?(pid_file) && !running?
         | 
| 598 | 
            -
                  @socket.close if @socket
         | 
| 738 | 
            +
                  # Give the simulator time to shut down
         | 
| 739 | 
            +
                  sleep 0.1 while running?
         | 
| 740 | 
            +
                  socket.close if socket
         | 
| 741 | 
            +
                  stderr.close if stderr
         | 
| 742 | 
            +
                  stdout.close if stdout
         | 
| 743 | 
            +
                  heartbeat.close if heartbeat
         | 
| 599 744 | 
             
                  File.unlink(socket_id) if File.exist?(socket_id)
         | 
| 745 | 
            +
                  File.unlink(socket_id(:stderr)) if File.exist?(socket_id(:stderr))
         | 
| 746 | 
            +
                  File.unlink(socket_id(:stdout)) if File.exist?(socket_id(:stdout))
         | 
| 747 | 
            +
                  File.unlink(socket_id(:heartbeat)) if File.exist?(socket_id(:heartbeat))
         | 
| 600 748 | 
             
                end
         | 
| 601 749 |  | 
| 602 750 | 
             
                def on_origen_shutdown
         | 
| @@ -605,9 +753,11 @@ module OrigenSim | |
| 605 753 | 
             
                      Origen.log.debug 'Shutting down simulator...'
         | 
| 606 754 | 
             
                      unless @failed_to_start
         | 
| 607 755 | 
             
                        c = error_count
         | 
| 608 | 
            -
                        if c > 0
         | 
| 756 | 
            +
                        if c > 0 || @simulator_logged_errors || @stderr_logged_errors
         | 
| 609 757 | 
             
                          @failed = true
         | 
| 610 | 
            -
                          Origen.log.error "The simulation failed with #{c} errors!"
         | 
| 758 | 
            +
                          Origen.log.error "The simulation failed with #{c} errors!" if c > 0
         | 
| 759 | 
            +
                          Origen.log.error 'The simulation log reported errors!' if @simulator_logged_errors
         | 
| 760 | 
            +
                          Origen.log.error 'The simulation stderr reported errors!' if @stderr_logged_errors
         | 
| 611 761 | 
             
                        elsif !@simulation_completed_cleanly
         | 
| 612 762 | 
             
                          @failed = true
         | 
| 613 763 | 
             
                          Origen.log.error 'The simulation exited early!'
         | 
| @@ -630,12 +780,10 @@ module OrigenSim | |
| 630 780 | 
             
                      puts
         | 
| 631 781 | 
             
                    end
         | 
| 632 782 | 
             
                  end
         | 
| 633 | 
            -
                ensure
         | 
| 634 | 
            -
                  Process.kill(15, pid) if @enabled && running?
         | 
| 635 783 | 
             
                end
         | 
| 636 784 |  | 
| 637 | 
            -
                def socket_id
         | 
| 638 | 
            -
                  @ | 
| 785 | 
            +
                def socket_id(type = nil)
         | 
| 786 | 
            +
                  @socket_ids[type] ||= "/tmp/#{socket_number}#{type}.sock"
         | 
| 639 787 | 
             
                end
         | 
| 640 788 |  | 
| 641 789 | 
             
                def socket_number
         | 
| @@ -654,7 +802,7 @@ module OrigenSim | |
| 654 802 | 
             
                    # release our process and then exit
         | 
| 655 803 | 
             
                    unless @connection_established
         | 
| 656 804 | 
             
                      @connection_timed_out = true
         | 
| 657 | 
            -
                      UNIXSocket.new(socket_id).puts( | 
| 805 | 
            +
                      UNIXSocket.new(socket_id).puts("Time out\n")
         | 
| 658 806 | 
             
                    end
         | 
| 659 807 | 
             
                  end
         | 
| 660 808 | 
             
                  yield
         | 
    
        data/lib/origen_sim/tester.rb
    CHANGED
    
    | @@ -5,8 +5,15 @@ module OrigenSim | |
| 5 5 |  | 
| 6 6 | 
             
                TEST_PROGRAM_GENERATOR = OrigenSim::Generator
         | 
| 7 7 |  | 
| 8 | 
            -
                def initialize(options = {})
         | 
| 9 | 
            -
                   | 
| 8 | 
            +
                def initialize(options = {}, &block)
         | 
| 9 | 
            +
                  # Use Origen's collector to allow options to be set either from the options hash, or from the block
         | 
| 10 | 
            +
                  if block_given?
         | 
| 11 | 
            +
                    opts = Origen::Utility.collector(hash: options, merge_method: :keep_hash, &block).to_hash
         | 
| 12 | 
            +
                  else
         | 
| 13 | 
            +
                    opts = options
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  simulator.configure(opts, &block)
         | 
| 10 17 | 
             
                  super()
         | 
| 11 18 | 
             
                end
         | 
| 12 19 |  | 
    
        data/lib/origen_sim.rb
    CHANGED
    
    | @@ -23,5 +23,82 @@ module OrigenSim | |
| 23 23 | 
             
              def self.simulator
         | 
| 24 24 | 
             
                @simulator
         | 
| 25 25 | 
             
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # Provide some shortcut methods to set the vendor
         | 
| 28 | 
            +
              def self.generic(options = {}, &block)
         | 
| 29 | 
            +
                Tester.new(options.merge(vendor: :generic), &block)
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def self.cadence(options = {}, &block)
         | 
| 33 | 
            +
                Tester.new(options.merge(vendor: :cadence), &block)
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def self.synopsys(optoins = {}, &block)
         | 
| 37 | 
            +
                Tester.new(options.merge(vendor: :synopsys), &block)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def self.icarus(options = {}, &block)
         | 
| 41 | 
            +
                Tester.new(options.merge(vendor: :icarus), &block)
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def self.verbose=(val)
         | 
| 45 | 
            +
                @verbose = val
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              def self.verbose?
         | 
| 49 | 
            +
                !!(@verbose || Origen.debugger_enabled?)
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def self.error_strings
         | 
| 53 | 
            +
                @error_strings ||= ['ERROR']
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              def self.error_strings=(val)
         | 
| 57 | 
            +
                unless val.is_a?(Array)
         | 
| 58 | 
            +
                  fail 'OrigenSim.error_strings can only be set to an array of string values!'
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
                @error_strings = val
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              def self.error_string_exceptions
         | 
| 64 | 
            +
                @error_string_exceptions ||= []
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def self.error_string_exceptions=(val)
         | 
| 68 | 
            +
                unless val.is_a?(Array)
         | 
| 69 | 
            +
                  fail 'OrigenSim.error_string_exceptions can only be set to an array of string values!'
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                @error_string_exceptions = val
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              def self.stderr_string_exceptions
         | 
| 75 | 
            +
                @stderr_string_exceptions ||= []
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              def self.stderr_string_exceptions=(val)
         | 
| 79 | 
            +
                unless val.is_a?(Array)
         | 
| 80 | 
            +
                  fail 'OrigenSim.error_string_exceptions can only be set to an array of string values!'
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
                @stderr_string_exceptions = val
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              def self.log_strings
         | 
| 86 | 
            +
                @log_strings ||= []
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def self.log_strings=(val)
         | 
| 90 | 
            +
                unless val.is_a?(Array)
         | 
| 91 | 
            +
                  fail 'OrigenSim.log_strings can only be set to an array of string values!'
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
                @log_strings = val
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              def self.fail_on_stderr=(val)
         | 
| 97 | 
            +
                @fail_on_stderr = val
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              def self.fail_on_stderr
         | 
| 101 | 
            +
                defined?(@fail_on_stderr) ? @fail_on_stderr : true
         | 
| 102 | 
            +
              end
         | 
| 26 103 | 
             
            end
         | 
| 27 104 | 
             
            OrigenSim.__instantiate_simulator__
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: origen_sim
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.9.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Stephen McGinty
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-06-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: origen
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 19 | 
            +
                    version: 0.33.1
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 26 | 
            +
                    version: 0.33.1
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: origen_testers
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -78,6 +78,7 @@ files: | |
| 78 78 | 
             
            - lib/origen_sim/commands/build.rb
         | 
| 79 79 | 
             
            - lib/origen_sim/commands/ci.rb
         | 
| 80 80 | 
             
            - lib/origen_sim/commands/co.rb
         | 
| 81 | 
            +
            - lib/origen_sim/commands/pack.rb
         | 
| 81 82 | 
             
            - lib/origen_sim/flow.rb
         | 
| 82 83 | 
             
            - lib/origen_sim/generator.rb
         | 
| 83 84 | 
             
            - lib/origen_sim/origen/pins/pin.rb
         |