origen_sim 0.16.1 → 0.20.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/application.rb +2 -0
- data/config/commands.rb +29 -20
- data/config/version.rb +2 -2
- data/ext/bridge.c +72 -14
- data/ext/origen.c +29 -17
- data/ext/origen.h +6 -0
- data/ext/origen_tasks.tab +2 -0
- data/lib/origen_sim/commands/build.rb +90 -59
- data/lib/origen_sim/origen/pins/pin.rb +38 -0
- data/lib/origen_sim/origen/top_level.rb +8 -3
- data/lib/origen_sim/simulation.rb +1 -1
- data/lib/origen_sim/simulator/user_details.rb +0 -1
- data/lib/origen_sim/simulator.rb +70 -70
- data/lib/origen_sim/tester.rb +53 -10
- data/lib/origen_sim_dev/dut.rb +66 -46
- data/lib/origen_sim_dev/ip.rb +15 -8
- data/pattern/concurrent_ip.rb +17 -0
- data/pattern/test.rb +122 -10
- data/templates/empty.rc +16 -26
- data/templates/origen_guides/simulation/ams.md.erb +141 -0
- data/templates/origen_guides/simulation/compiling.md.erb +52 -7
- data/templates/origen_guides/simulation/debugging.md.erb +1 -1
- data/templates/origen_guides/simulation/direct.md.erb +112 -0
- data/templates/origen_guides/simulation/environment.md.erb +6 -3
- data/templates/origen_guides/simulation/patterns.md.erb +2 -7
- data/templates/rtl_v/origen.v.erb +114 -12
- metadata +13 -9
    
        data/lib/origen_sim/simulator.rb
    CHANGED
    
    | @@ -428,8 +428,8 @@ module OrigenSim | |
| 428 428 | 
             
                    edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
         | 
| 429 429 | 
             
                    cmd = "cd #{edir} && "
         | 
| 430 430 | 
             
                    if configuration[:verdi]
         | 
| 431 | 
            -
                      unless ENV['VCS_HOME'] | 
| 432 | 
            -
                         | 
| 431 | 
            +
                      unless ENV['VCS_HOME']
         | 
| 432 | 
            +
                        Origen.log.warning "Your environment doesn't define VCS_HOME, you will probably need that to run Verdi"
         | 
| 433 433 | 
             
                      end
         | 
| 434 434 | 
             
                      edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
         | 
| 435 435 | 
             
                      cmd = "cd #{edir} && "
         | 
| @@ -778,7 +778,7 @@ module OrigenSim | |
| 778 778 | 
             
                # set up internal handles to efficiently access them
         | 
| 779 779 | 
             
                def define_pins
         | 
| 780 780 | 
             
                  @pins_by_rtl_name = {}
         | 
| 781 | 
            -
                  dut.rtl_pins.each_with_index do |(name, pin), i|
         | 
| 781 | 
            +
                  dut.rtl_pins(type: :digital).each_with_index do |(name, pin), i|
         | 
| 782 782 | 
             
                    @pins_by_rtl_name[pin.rtl_name] = pin
         | 
| 783 783 | 
             
                    pin.simulation_index = i
         | 
| 784 784 | 
             
                    put("0^#{pin.rtl_name}^#{i}^#{pin.drive_wave.index}^#{pin.compare_wave.index}")
         | 
| @@ -865,6 +865,7 @@ module OrigenSim | |
| 865 865 |  | 
| 866 866 | 
             
                def error(message)
         | 
| 867 867 | 
             
                  simulation.logged_errors = true
         | 
| 868 | 
            +
                  poke "#{testbench_top}.debug.errors", error_count + 1
         | 
| 868 869 | 
             
                  log message, :error
         | 
| 869 870 | 
             
                end
         | 
| 870 871 |  | 
| @@ -877,87 +878,82 @@ module OrigenSim | |
| 877 878 | 
             
                # resolve to a valid node
         | 
| 878 879 | 
             
                #
         | 
| 879 880 | 
             
                # The value is returned as an instance of Origen::Value
         | 
| 880 | 
            -
                def peek(net)
         | 
| 881 | 
            -
                  # The Verilog spec does not specify that underlying VPI put method should
         | 
| 882 | 
            -
                  # handle a part select, so some simulators do not handle it. Therefore we
         | 
| 883 | 
            -
                  # deal with it here to ensure cross simulator compatibility.
         | 
| 884 | 
            -
             | 
| 885 | 
            -
                  # http://rubular.com/r/eTVGzrYmXQ
         | 
| 886 | 
            -
                  if net =~ /(.*)\[(\d+):?(\.\.)?(\d*)\]$/
         | 
| 887 | 
            -
                    net = Regexp.last_match(1)
         | 
| 888 | 
            -
                    msb = Regexp.last_match(2).to_i
         | 
| 889 | 
            -
                    lsb = Regexp.last_match(4)
         | 
| 890 | 
            -
                    lsb = lsb.empty? ? nil : lsb.to_i
         | 
| 891 | 
            -
                  end
         | 
| 892 | 
            -
             | 
| 881 | 
            +
                def peek(net, real = false)
         | 
| 893 882 | 
             
                  sync_up
         | 
| 894 | 
            -
                   | 
| 895 | 
            -
             | 
| 883 | 
            +
                  if dut_version > '0.19.0'
         | 
| 884 | 
            +
                    if real
         | 
| 885 | 
            +
                      put("9^#{clean(net)}^f")
         | 
| 886 | 
            +
                      m = get.strip
         | 
| 887 | 
            +
                      if m == 'FAIL'
         | 
| 888 | 
            +
                        return nil
         | 
| 889 | 
            +
                      else
         | 
| 890 | 
            +
                        m.to_f
         | 
| 891 | 
            +
                      end
         | 
| 892 | 
            +
                    else
         | 
| 893 | 
            +
                      put("9^#{clean(net)}^i")
         | 
| 894 | 
            +
                      m = get.strip
         | 
| 896 895 |  | 
| 897 | 
            -
             | 
| 898 | 
            -
             | 
| 899 | 
            -
             | 
| 900 | 
            -
                    if msb
         | 
| 901 | 
            -
                      # Setting a range of bits
         | 
| 902 | 
            -
                      if lsb
         | 
| 903 | 
            -
                        Origen::Value.new('b' + m[(m.size - 1 - msb)..(m.size - 1 - lsb)])
         | 
| 896 | 
            +
                      if m == 'FAIL'
         | 
| 897 | 
            +
                        Origen.log.warning "Peek of net #{net} failed to return any data!"
         | 
| 898 | 
            +
                        return nil
         | 
| 904 899 | 
             
                      else
         | 
| 905 | 
            -
                        Origen::Value.new('b' + m | 
| 900 | 
            +
                        Origen::Value.new('b' + m)
         | 
| 906 901 | 
             
                      end
         | 
| 902 | 
            +
                    end
         | 
| 903 | 
            +
                  else
         | 
| 904 | 
            +
                    put("9^#{clean(net)}")
         | 
| 905 | 
            +
                    m = get.strip
         | 
| 906 | 
            +
             | 
| 907 | 
            +
                    if m == 'FAIL'
         | 
| 908 | 
            +
                      Origen.log.warning "Peek of net #{net} failed to return any data!"
         | 
| 909 | 
            +
                      return nil
         | 
| 907 910 | 
             
                    else
         | 
| 908 911 | 
             
                      Origen::Value.new('b' + m)
         | 
| 909 912 | 
             
                    end
         | 
| 910 913 | 
             
                  end
         | 
| 911 914 | 
             
                end
         | 
| 912 915 |  | 
| 916 | 
            +
                def peek_real(net)
         | 
| 917 | 
            +
                  peek(net, true)
         | 
| 918 | 
            +
                end
         | 
| 919 | 
            +
             | 
| 913 920 | 
             
                # Forces the given value to the given net.
         | 
| 914 921 | 
             
                # Note that no error checking is done and no error will be communicated if an illegal
         | 
| 915 922 | 
             
                # net is supplied. The user should follow up with a peek if they want to verify that
         | 
| 916 923 | 
             
                # the poke was applied.
         | 
| 917 924 | 
             
                def poke(net, value)
         | 
| 918 | 
            -
                   | 
| 919 | 
            -
                   | 
| 920 | 
            -
             | 
| 921 | 
            -
             | 
| 922 | 
            -
             | 
| 923 | 
            -
             | 
| 924 | 
            -
                     | 
| 925 | 
            -
             | 
| 926 | 
            -
                     | 
| 927 | 
            -
             | 
| 928 | 
            -
             | 
| 929 | 
            -
                    v = peek(path)
         | 
| 930 | 
            -
                    return nil unless v
         | 
| 931 | 
            -
                    # Setting a range of bits
         | 
| 932 | 
            -
                    if lsb
         | 
| 933 | 
            -
                      upper = v >> (msb + 1)
         | 
| 934 | 
            -
                      # Make sure value does not overflow
         | 
| 935 | 
            -
                      value = value[(msb - lsb)..0]
         | 
| 936 | 
            -
                      if lsb == 0
         | 
| 937 | 
            -
                        value = (upper << (msb + 1)) | value
         | 
| 938 | 
            -
                      else
         | 
| 939 | 
            -
                        lower = v[(lsb - 1)..0]
         | 
| 940 | 
            -
                        value = (upper << (msb + 1)) |
         | 
| 941 | 
            -
                                (value << lsb) | lower
         | 
| 942 | 
            -
                      end
         | 
| 925 | 
            +
                  sync_up
         | 
| 926 | 
            +
                  if dut_version > '0.19.0'
         | 
| 927 | 
            +
                    if value.is_a?(Integer)
         | 
| 928 | 
            +
                      put("b^#{clean(net)}^i^#{value}")
         | 
| 929 | 
            +
                    else
         | 
| 930 | 
            +
                      put("b^#{clean(net)}^f^#{value}")
         | 
| 931 | 
            +
                    end
         | 
| 932 | 
            +
                  else
         | 
| 933 | 
            +
                    put("b^#{clean(net)}^#{value}")
         | 
| 934 | 
            +
                  end
         | 
| 935 | 
            +
                end
         | 
| 943 936 |  | 
| 944 | 
            -
             | 
| 937 | 
            +
                def force(net, value)
         | 
| 938 | 
            +
                  sync_up
         | 
| 939 | 
            +
                  if dut_version > '0.19.0'
         | 
| 940 | 
            +
                    if value.is_a?(Integer)
         | 
| 941 | 
            +
                      put("r^#{clean(net)}^i^#{value}")
         | 
| 945 942 | 
             
                    else
         | 
| 946 | 
            -
                       | 
| 947 | 
            -
                        upper = v >> 1
         | 
| 948 | 
            -
                        value = (upper << 1) | value[0]
         | 
| 949 | 
            -
                      else
         | 
| 950 | 
            -
                        lower = v[(msb - 1)..0]
         | 
| 951 | 
            -
                        upper = v >> (msb + 1)
         | 
| 952 | 
            -
                        value = (upper << (msb + 1)) |
         | 
| 953 | 
            -
                                (value[0] << msb) | lower
         | 
| 954 | 
            -
                      end
         | 
| 943 | 
            +
                      put("r^#{clean(net)}^f^#{value}")
         | 
| 955 944 | 
             
                    end
         | 
| 956 | 
            -
             | 
| 945 | 
            +
                  else
         | 
| 946 | 
            +
                    OrigenSim.error 'Your DUT needs to be recompiled with OrigenSim >= 0.20.0 to support forcing, force not applied!'
         | 
| 957 947 | 
             
                  end
         | 
| 948 | 
            +
                end
         | 
| 958 949 |  | 
| 950 | 
            +
                def release(net)
         | 
| 959 951 | 
             
                  sync_up
         | 
| 960 | 
            -
                   | 
| 952 | 
            +
                  if dut_version > '0.19.0'
         | 
| 953 | 
            +
                    put("s^#{clean(net)}")
         | 
| 954 | 
            +
                  else
         | 
| 955 | 
            +
                    OrigenSim.error 'Your DUT needs to be recompiled with OrigenSim >= 0.20.0 to support releasing, force not released!'
         | 
| 956 | 
            +
                  end
         | 
| 961 957 | 
             
                end
         | 
| 962 958 |  | 
| 963 959 | 
             
                def interactive_shutdown
         | 
| @@ -1124,17 +1120,13 @@ module OrigenSim | |
| 1124 1120 | 
             
                end
         | 
| 1125 1121 |  | 
| 1126 1122 | 
             
                def peek_str(signal)
         | 
| 1127 | 
            -
                  val =  | 
| 1123 | 
            +
                  val = peek(signal)
         | 
| 1128 1124 | 
             
                  unless val.nil?
         | 
| 1129 | 
            -
                    puts val
         | 
| 1130 | 
            -
                    puts val.class
         | 
| 1131 1125 | 
             
                    # All zeros seems to be what an empty string is returned from the VPI,
         | 
| 1132 1126 | 
             
                    # Otherwise, break the string up into 8-bit chunks and decode the ASCII>
         | 
| 1133 1127 | 
             
                    val = (val.to_s == 'b00000000' ? '' : val.to_s[1..-1].scan(/.{1,8}/).collect { |char| char.to_i(2).chr }.join)
         | 
| 1134 1128 | 
             
                  end
         | 
| 1135 1129 | 
             
                  val
         | 
| 1136 | 
            -
                  # puts "Peaking #{signal}: #{a}: #{a.class}"
         | 
| 1137 | 
            -
                  # tester.simulator.peek(signal).to_s[1..-1].scan(/.{1,8}/).collect { |char| char.to_i(2).chr }.join
         | 
| 1138 1130 | 
             
                end
         | 
| 1139 1131 | 
             
                alias_method :str_peek, :peek_str
         | 
| 1140 1132 | 
             
                alias_method :peek_string, :peek_str
         | 
| @@ -1161,8 +1153,8 @@ module OrigenSim | |
| 1161 1153 | 
             
                    errors = []
         | 
| 1162 1154 | 
             
                    error_count.times do |i|
         | 
| 1163 1155 | 
             
                      data = get  # => "tdo,648,1,0\n"
         | 
| 1164 | 
            -
                      pin_name, cycle, expected,  | 
| 1165 | 
            -
                      errors << { pin_name: pin_name, cycle: cycle.to_i, expected: expected.to_i,  | 
| 1156 | 
            +
                      pin_name, cycle, expected, received = *(data.strip.split(','))
         | 
| 1157 | 
            +
                      errors << { pin_name: pin_name, cycle: cycle.to_i, expected: expected.to_i, received: received.to_i }
         | 
| 1166 1158 | 
             
                    end
         | 
| 1167 1159 | 
             
                    [true, error_count > max_errors, errors]
         | 
| 1168 1160 | 
             
                  end
         | 
| @@ -1175,6 +1167,14 @@ module OrigenSim | |
| 1175 1167 | 
             
                  get.strip.to_i
         | 
| 1176 1168 | 
             
                end
         | 
| 1177 1169 |  | 
| 1170 | 
            +
                # Returns true if the snapshot has been compiled with WREAL support
         | 
| 1171 | 
            +
                def wreal?
         | 
| 1172 | 
            +
                  return @wreal if defined?(@wreal)
         | 
| 1173 | 
            +
                  @wreal = (dut_version > '0.19.0' &&
         | 
| 1174 | 
            +
                            peek("#{testbench_top}.debug.wreal_enabled").to_i == 1)
         | 
| 1175 | 
            +
                end
         | 
| 1176 | 
            +
                alias_method :wreal_enabled?, :wreal?
         | 
| 1177 | 
            +
             | 
| 1178 1178 | 
             
                private
         | 
| 1179 1179 |  | 
| 1180 1180 | 
             
                # Will be called when the simulator has aborted due to the max error count being exceeded
         | 
    
        data/lib/origen_sim/tester.rb
    CHANGED
    
    | @@ -16,6 +16,7 @@ module OrigenSim | |
| 16 16 | 
             
                  simulator.configure(opts, &block)
         | 
| 17 17 | 
             
                  @comment_buffer = []
         | 
| 18 18 | 
             
                  @last_comment_size = 0
         | 
| 19 | 
            +
                  @execution_time_in_ns = 0
         | 
| 19 20 | 
             
                  super()
         | 
| 20 21 | 
             
                end
         | 
| 21 22 |  | 
| @@ -38,9 +39,9 @@ module OrigenSim | |
| 38 39 | 
             
                  end
         | 
| 39 40 | 
             
                  @sync_pins.map do |pin|
         | 
| 40 41 | 
             
                    if @sync_cycles.size == 1
         | 
| 41 | 
            -
                      simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory[0] | 
| 42 | 
            +
                      simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory")[0]
         | 
| 42 43 | 
             
                    else
         | 
| 43 | 
            -
                      simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory[ | 
| 44 | 
            +
                      simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory").to_i[(@sync_cycles - 1)..0]
         | 
| 44 45 | 
             
                    end
         | 
| 45 46 | 
             
                  end
         | 
| 46 47 | 
             
                end
         | 
| @@ -80,11 +81,13 @@ module OrigenSim | |
| 80 81 | 
             
                    unless options[:timeset]
         | 
| 81 82 | 
             
                      puts 'No timeset defined!'
         | 
| 82 83 | 
             
                      puts 'Add one to your top level startup method or target like this:'
         | 
| 83 | 
            -
                      puts ' | 
| 84 | 
            +
                      puts 'tester.set_timeset("nvmbist", 40)   # Where 40 is the period in ns'
         | 
| 84 85 | 
             
                      exit 1
         | 
| 85 86 | 
             
                    end
         | 
| 86 87 | 
             
                    flush_comments unless @comment_buffer.empty?
         | 
| 87 | 
            -
                     | 
| 88 | 
            +
                    repeat = options[:repeat] || 1
         | 
| 89 | 
            +
                    simulator.cycle(repeat)
         | 
| 90 | 
            +
                    @execution_time_in_ns += repeat * tester.timeset.period_in_ns
         | 
| 88 91 | 
             
                    if @after_next_vector
         | 
| 89 92 | 
             
                      @after_next_vector.call(@after_next_vector_args)
         | 
| 90 93 | 
             
                      @after_next_vector = nil
         | 
| @@ -94,6 +97,7 @@ module OrigenSim | |
| 94 97 |  | 
| 95 98 | 
             
                def c1(msg, options = {})
         | 
| 96 99 | 
             
                  if @step_comment_on
         | 
| 100 | 
            +
                    PatSeq.add_thread(msg) unless options[:no_thread_id]
         | 
| 97 101 | 
             
                    simulator.log msg
         | 
| 98 102 | 
             
                    @comment_buffer << msg
         | 
| 99 103 | 
             
                  end
         | 
| @@ -293,7 +297,7 @@ module OrigenSim | |
| 293 297 | 
             
                            if c = read_reg_cycles[error[:cycle]]
         | 
| 294 298 | 
             
                              if p = c[simulator.pins_by_rtl_name[error[:pin_name]]]
         | 
| 295 299 | 
             
                                if p[:position]
         | 
| 296 | 
            -
                                  diffs << [p[:position], error[: | 
| 300 | 
            +
                                  diffs << [p[:position], error[:received], error[:expected]]
         | 
| 297 301 | 
             
                                end
         | 
| 298 302 | 
             
                              end
         | 
| 299 303 | 
             
                            end
         | 
| @@ -301,6 +305,7 @@ module OrigenSim | |
| 301 305 | 
             
                          if diffs.empty?
         | 
| 302 306 | 
             
                            if @read_reg_meta_supplied
         | 
| 303 307 | 
             
                              Origen.log.warning 'It looks like the miscompare(s) occurred on pins/cycles that are not associated with register data'
         | 
| 308 | 
            +
                              non_data_miscompare = true
         | 
| 304 309 | 
             
                            else
         | 
| 305 310 | 
             
                              Origen.log.warning 'It looks like your current read register driver does not provide the necessary meta-data to map these errors to an actual register value'
         | 
| 306 311 | 
             
                            end
         | 
| @@ -323,7 +328,11 @@ module OrigenSim | |
| 323 328 | 
             
                            end
         | 
| 324 329 |  | 
| 325 330 | 
             
                            diffs.each do |position, received, expected|
         | 
| 326 | 
            -
                               | 
| 331 | 
            +
                              if received == -1
         | 
| 332 | 
            +
                                reg_or_val[position].unknown = true
         | 
| 333 | 
            +
                              else
         | 
| 334 | 
            +
                                reg_or_val[position].data = received
         | 
| 335 | 
            +
                              end
         | 
| 327 336 | 
             
                            end
         | 
| 328 337 |  | 
| 329 338 | 
             
                            actual = bit_names.map do |name|
         | 
| @@ -357,7 +366,8 @@ module OrigenSim | |
| 357 366 | 
             
                              Origen.log.error msg
         | 
| 358 367 | 
             
                            end
         | 
| 359 368 | 
             
                          else
         | 
| 360 | 
            -
                             | 
| 369 | 
            +
                            # This means that the correct data was read, but errors occurred on other pins/cycles during the transaction
         | 
| 370 | 
            +
                            msg += " received #{expected}" if non_data_miscompare
         | 
| 361 371 | 
             
                            Origen.log.error msg
         | 
| 362 372 | 
             
                          end
         | 
| 363 373 | 
             
                        end
         | 
| @@ -367,7 +377,10 @@ module OrigenSim | |
| 367 377 | 
             
                        if actual_data_available
         | 
| 368 378 | 
             
                          actual = reg_or_val
         | 
| 369 379 | 
             
                          diffs.each do |position, received, expected|
         | 
| 370 | 
            -
                            if received == 1
         | 
| 380 | 
            +
                            if received == -1
         | 
| 381 | 
            +
                              actual = '?' * reg_or_val.to_s(16).size
         | 
| 382 | 
            +
                              break
         | 
| 383 | 
            +
                            elsif received == 1
         | 
| 371 384 | 
             
                              actual |= (1 << position)
         | 
| 372 385 | 
             
                            else
         | 
| 373 386 | 
             
                              lower = actual[(position - 1)..0]
         | 
| @@ -376,9 +389,14 @@ module OrigenSim | |
| 376 389 | 
             
                              actual |= lower
         | 
| 377 390 | 
             
                            end
         | 
| 378 391 | 
             
                          end
         | 
| 379 | 
            -
                           | 
| 392 | 
            +
                          if actual.is_a?(String)
         | 
| 393 | 
            +
                            msg += " received #{actual}"
         | 
| 394 | 
            +
                          else
         | 
| 395 | 
            +
                            msg += " received #{actual.to_s(16).upcase}"
         | 
| 396 | 
            +
                          end
         | 
| 380 397 | 
             
                        else
         | 
| 381 | 
            -
                           | 
| 398 | 
            +
                          # This means that the correct data was read, but errors occurred on other pins/cycles during the transaction
         | 
| 399 | 
            +
                          msg += " received #{reg_or_val.to_s(16).upcase}" if non_data_miscompare
         | 
| 382 400 | 
             
                        end
         | 
| 383 401 | 
             
                        Origen.log.error msg
         | 
| 384 402 | 
             
                      end
         | 
| @@ -409,6 +427,31 @@ module OrigenSim | |
| 409 427 | 
             
                  @read_reg_meta_supplied = val
         | 
| 410 428 | 
             
                end
         | 
| 411 429 |  | 
| 430 | 
            +
                # Shorthand for simulator.poke
         | 
| 431 | 
            +
                def poke(*args)
         | 
| 432 | 
            +
                  simulator.poke(*args)
         | 
| 433 | 
            +
                end
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                # Shorthand for simulator.peek
         | 
| 436 | 
            +
                def peek(*args)
         | 
| 437 | 
            +
                  simulator.peek(*args)
         | 
| 438 | 
            +
                end
         | 
| 439 | 
            +
             | 
| 440 | 
            +
                # Shorthand for simulator.peek_real
         | 
| 441 | 
            +
                def peek_real(*args)
         | 
| 442 | 
            +
                  simulator.peek_real(*args)
         | 
| 443 | 
            +
                end
         | 
| 444 | 
            +
             | 
| 445 | 
            +
                # Shorthand for simulator.force
         | 
| 446 | 
            +
                def force(*args)
         | 
| 447 | 
            +
                  simulator.force(*args)
         | 
| 448 | 
            +
                end
         | 
| 449 | 
            +
             | 
| 450 | 
            +
                # Shorthand for simulator.release
         | 
| 451 | 
            +
                def release(*args)
         | 
| 452 | 
            +
                  simulator.release(*args)
         | 
| 453 | 
            +
                end
         | 
| 454 | 
            +
             | 
| 412 455 | 
             
                private
         | 
| 413 456 |  | 
| 414 457 | 
             
                def flush_comments
         | 
    
        data/lib/origen_sim_dev/dut.rb
    CHANGED
    
    | @@ -26,6 +26,8 @@ module OrigenSimDev | |
| 26 26 | 
             
                  add_pin :v2, rtl_name: :nc
         | 
| 27 27 | 
             
                  add_pin :done
         | 
| 28 28 | 
             
                  add_pin :not_present
         | 
| 29 | 
            +
                  add_power_pin :vdd
         | 
| 30 | 
            +
                  add_pin :ana, type: :analog
         | 
| 29 31 |  | 
| 30 32 | 
             
                  timeset :func do |t|
         | 
| 31 33 | 
             
                    # Generate a clock pulse on TCK
         | 
| @@ -73,6 +75,15 @@ module OrigenSimDev | |
| 73 75 | 
             
                    reg.bits 2..0, :b6
         | 
| 74 76 | 
             
                  end
         | 
| 75 77 |  | 
| 78 | 
            +
                  add_reg :ana_test, 0x1C do |reg|
         | 
| 79 | 
            +
                    reg.bit 0, :vdd_valid, access: :ro
         | 
| 80 | 
            +
                    reg.bit 1, :bgap_out
         | 
| 81 | 
            +
                    reg.bit 2, :osc_out
         | 
| 82 | 
            +
                    reg.bit 3, :vdd_div4
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  add_reg :x_reg, 0x20
         | 
| 86 | 
            +
             | 
| 76 87 | 
             
                  sub_block :ip1, class_name: 'IP'
         | 
| 77 88 | 
             
                  sub_block :ip2, class_name: 'IP'
         | 
| 78 89 | 
             
                end
         | 
| @@ -84,6 +95,10 @@ module OrigenSimDev | |
| 84 95 | 
             
                  end
         | 
| 85 96 | 
             
                end
         | 
| 86 97 |  | 
| 98 | 
            +
                def simulation_startup
         | 
| 99 | 
            +
                  power_pin(:vdd).drive(0)
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 87 102 | 
             
                def startup(options = {})
         | 
| 88 103 | 
             
                  # tester.simulator.log_messages = true
         | 
| 89 104 | 
             
                  tester.set_timeset('func', 100)
         | 
| @@ -101,60 +116,65 @@ module OrigenSimDev | |
| 101 116 | 
             
                end
         | 
| 102 117 |  | 
| 103 118 | 
             
                def write_register(reg, options = {})
         | 
| 104 | 
            -
                   | 
| 105 | 
            -
                     | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
                     | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 119 | 
            +
                  PatSeq.serialize :jtag do
         | 
| 120 | 
            +
                    if reg.path =~ /ip(\d)/
         | 
| 121 | 
            +
                      ir_val = 0b0100 | Regexp.last_match(1).to_i
         | 
| 122 | 
            +
                      jtag.write_ir(ir_val, size: 4)
         | 
| 123 | 
            +
                      ip = reg.parent
         | 
| 124 | 
            +
                      ip.dr.bits(:write).write(1)
         | 
| 125 | 
            +
                      ip.dr.bits(:address).write(reg.address)
         | 
| 126 | 
            +
                      ip.dr.bits(:data).write(reg.data)
         | 
| 127 | 
            +
                      jtag.write_dr(ip.dr)
         | 
| 128 | 
            +
                    # Write to top-level reg
         | 
| 129 | 
            +
                    else
         | 
| 130 | 
            +
                      jtag.write_ir(0x8, size: 4)
         | 
| 131 | 
            +
                      dr.rg_enable.write(1)
         | 
| 132 | 
            +
                      dr.rg_read.write(0)
         | 
| 133 | 
            +
                      dr.rg_addr.write(reg.address)
         | 
| 134 | 
            +
                      dr.rg_data.write(reg.data)
         | 
| 135 | 
            +
                      jtag.write_dr(dr)
         | 
| 136 | 
            +
                    end
         | 
| 120 137 | 
             
                  end
         | 
| 121 138 | 
             
                end
         | 
| 122 139 |  | 
| 123 140 | 
             
                def read_register(reg, options = {})
         | 
| 124 | 
            -
                   | 
| 125 | 
            -
                     | 
| 126 | 
            -
             | 
| 127 | 
            -
                       | 
| 128 | 
            -
             | 
| 129 | 
            -
                         | 
| 130 | 
            -
                           | 
| 141 | 
            +
                  PatSeq.serialize :jtag do
         | 
| 142 | 
            +
                    tester.read_register(reg, options) do
         | 
| 143 | 
            +
                      # Special read for this register to test sync'ing over a parallel port
         | 
| 144 | 
            +
                      if reg.id == :parallel_read
         | 
| 145 | 
            +
                        pins = []
         | 
| 146 | 
            +
                        reg.shift_out_with_index do |bit, i|
         | 
| 147 | 
            +
                          if bit.is_to_be_stored?
         | 
| 148 | 
            +
                            pins << dut.pins(:dout)[i]
         | 
| 149 | 
            +
                          end
         | 
| 131 150 | 
             
                        end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
                      dut.pins(:dout).dont_care
         | 
| 136 | 
            -
                    else
         | 
| 137 | 
            -
                      if reg.path =~ /ip(\d)/
         | 
| 138 | 
            -
                        ir_val = 0b0100 | Regexp.last_match(1).to_i
         | 
| 139 | 
            -
                        jtag.write_ir(ir_val, size: 4)
         | 
| 140 | 
            -
                        ip = reg.parent
         | 
| 141 | 
            -
                        ip.dr.bits(:write).write(0)
         | 
| 142 | 
            -
                        ip.dr.bits(:address).write(reg.address)
         | 
| 143 | 
            -
                        ip.dr.bits(:data).write(0)
         | 
| 144 | 
            -
                        jtag.write_dr(ip.dr)
         | 
| 145 | 
            -
                        ip.dr.bits(:data).copy_all(reg)
         | 
| 146 | 
            -
                        jtag.read_dr(ip.dr)
         | 
| 151 | 
            +
                        tester.store_next_cycle(*pins.reverse)
         | 
| 152 | 
            +
                        1.cycle
         | 
| 153 | 
            +
                        dut.pins(:dout).dont_care
         | 
| 147 154 | 
             
                      else
         | 
| 148 | 
            -
                         | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
             | 
| 155 | 
            +
                        if reg.path =~ /ip(\d)/
         | 
| 156 | 
            +
                          ir_val = 0b0100 | Regexp.last_match(1).to_i
         | 
| 157 | 
            +
                          jtag.write_ir(ir_val, size: 4)
         | 
| 158 | 
            +
                          ip = reg.parent
         | 
| 159 | 
            +
                          ip.dr.bits(:write).write(0)
         | 
| 160 | 
            +
                          ip.dr.bits(:address).write(reg.address)
         | 
| 161 | 
            +
                          ip.dr.bits(:data).write(0)
         | 
| 162 | 
            +
                          jtag.write_dr(ip.dr)
         | 
| 163 | 
            +
                          ip.dr.bits(:data).copy_all(reg)
         | 
| 164 | 
            +
                          jtag.read_dr(ip.dr)
         | 
| 165 | 
            +
                        else
         | 
| 166 | 
            +
                          jtag.write_ir(0x8, size: 4)
         | 
| 167 | 
            +
                          dr.rg_enable.write(1)
         | 
| 168 | 
            +
                          dr.rg_read.write(1)
         | 
| 169 | 
            +
                          dr.rg_addr.write(reg.address)
         | 
| 170 | 
            +
                          jtag.write_dr(dr)
         | 
| 171 | 
            +
                          dr.rg_enable.write(0)
         | 
| 172 | 
            +
                          dr.rg_data.copy_all(reg)
         | 
| 173 | 
            +
                          jtag.read_dr(dr)
         | 
| 174 | 
            +
                        end
         | 
| 156 175 | 
             
                      end
         | 
| 157 176 | 
             
                    end
         | 
| 177 | 
            +
                    reg.clear_flags
         | 
| 158 178 | 
             
                  end
         | 
| 159 179 | 
             
                end
         | 
| 160 180 | 
             
              end
         | 
    
        data/lib/origen_sim_dev/ip.rb
    CHANGED
    
    | @@ -33,14 +33,21 @@ module OrigenSimDev | |
| 33 33 |  | 
| 34 34 | 
             
                def execute_cmd(code)
         | 
| 35 35 | 
             
                  ss "Execute command #{code}"
         | 
| 36 | 
            -
                   | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 36 | 
            +
                  PatSeq.reserve :jtag do
         | 
| 37 | 
            +
                    # This is redundant, but added as a test that if an embedded reservation is made to the same
         | 
| 38 | 
            +
                    # resource then the end of the inner block does not release the reservation before completion
         | 
| 39 | 
            +
                    # of the outer block
         | 
| 40 | 
            +
                    PatSeq.reserve :jtag do
         | 
| 41 | 
            +
                      # Verify that no command is currently running
         | 
| 42 | 
            +
                      status.read!(0)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    cmd.write!(code)
         | 
| 46 | 
            +
                    10.cycles
         | 
| 47 | 
            +
                    # Verify that the command has started
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    status.busy.read!(1)
         | 
| 50 | 
            +
                  end
         | 
| 44 51 |  | 
| 45 52 | 
             
                  # Wait for the command to complete, a 'command' lasts for
         | 
| 46 53 | 
             
                  # 1000 cycles times the command code
         |