origen 0.28.2 → 0.29.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/bin/origen +14 -2
- data/config/version.rb +2 -2
- data/lib/origen.rb +72 -45
- data/lib/origen/application.rb +29 -19
- data/lib/origen/application/deployer.rb +3 -1
- data/lib/origen/application/runner.rb +10 -8
- data/lib/origen/chip_mode.rb +1 -1
- data/lib/origen/commands.rb +24 -12
- data/lib/origen/commands/version.rb +1 -1
- data/lib/origen/commands_global.rb +32 -8
- data/lib/origen/core_ext.rb +1 -2
- data/lib/origen/core_ext/enumerable.rb +2 -2
- data/lib/origen/core_ext/integer.rb +85 -0
- data/lib/origen/core_ext/numeric.rb +28 -4
- data/lib/origen/global_app.rb +9 -0
- data/lib/origen/log.rb +1 -1
- data/lib/origen/model_initializer.rb +6 -1
- data/lib/origen/netlist/list.rb +2 -2
- data/lib/origen/org_file.rb +125 -0
- data/lib/origen/org_file/interceptable.rb +44 -0
- data/lib/origen/org_file/interceptor.rb +100 -0
- data/lib/origen/parameters/set.rb +1 -1
- data/lib/origen/pins.rb +4 -0
- data/lib/origen/pins/function_proxy.rb +8 -0
- data/lib/origen/pins/pin.rb +90 -38
- data/lib/origen/pins/pin_collection.rb +61 -21
- data/lib/origen/ports/port.rb +1 -1
- data/lib/origen/registers.rb +1 -1
- data/lib/origen/registers/reg.rb +1 -1
- data/lib/origen/remote_manager.rb +25 -15
- data/lib/origen/site_config.rb +140 -13
- data/lib/origen/specs/checkers.rb +2 -2
- data/lib/origen/sub_blocks.rb +6 -1
- data/lib/origen/value.rb +119 -0
- data/lib/origen/value/bin_str_val.rb +72 -0
- data/lib/origen/value/hex_str_val.rb +100 -0
- data/origen_site_config.yml +15 -8
- metadata +12 -6
- data/lib/origen/core_ext/bignum.rb +0 -38
- data/lib/origen/core_ext/fixnum.rb +0 -56
data/lib/origen/core_ext.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'origen/core_ext/object'
|
2
2
|
require 'origen/core_ext/string'
|
3
|
-
require 'origen/core_ext/
|
4
|
-
require 'origen/core_ext/bignum'
|
3
|
+
require 'origen/core_ext/integer'
|
5
4
|
require 'origen/core_ext/numeric'
|
6
5
|
require 'origen/core_ext/module'
|
7
6
|
require 'origen/core_ext/hash'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Enumerable
|
2
|
-
PRIMATIVES = [TrueClass, FalseClass, NilClass,
|
2
|
+
PRIMATIVES = [TrueClass, FalseClass, NilClass, String, Symbol, Regexp, Numeric]
|
3
3
|
|
4
4
|
def debug(msg)
|
5
5
|
Origen.log.debug(msg)
|
@@ -48,7 +48,7 @@ module Enumerable
|
|
48
48
|
end
|
49
49
|
next
|
50
50
|
else
|
51
|
-
next unless options[:select].empty? || options[:select].include?(item.class) || PRIMATIVES.
|
51
|
+
next unless options[:select].empty? || options[:select].include?(item.class) || PRIMATIVES.any? { |klass| item.is_a?(klass) }
|
52
52
|
next if options[:ignore].include?(item.class)
|
53
53
|
case item
|
54
54
|
when NilClass
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# The base class of ALL integers, i.e. including Fixum and Bignum
|
2
|
+
|
3
|
+
# Shim to handle Ruby < 2.4.0, where [] is implemented in Fixnum/Bignum instead
|
4
|
+
# of Integer
|
5
|
+
module Origen
|
6
|
+
module IntegerExtension
|
7
|
+
def [](*args)
|
8
|
+
if args.length == 1 && !args.first.is_a?(Range)
|
9
|
+
super
|
10
|
+
else
|
11
|
+
if args.first.is_a?(Range)
|
12
|
+
msb = args.first.first
|
13
|
+
lsb = args.first.last
|
14
|
+
else
|
15
|
+
msb = args.first
|
16
|
+
lsb = args.last
|
17
|
+
end
|
18
|
+
(self >> lsb) & 0.ones_comp(msb - lsb + 1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Integer
|
25
|
+
if RUBY_VERSION >= '2.4.0'
|
26
|
+
prepend Origen::IntegerExtension
|
27
|
+
end
|
28
|
+
|
29
|
+
# Implements 10.cycles
|
30
|
+
def cycles
|
31
|
+
if block_given?
|
32
|
+
times do
|
33
|
+
yield
|
34
|
+
Origen.app.tester.cycle
|
35
|
+
end
|
36
|
+
else
|
37
|
+
Origen.app.tester.cycle(repeat: self)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
alias_method :cycle, :cycles
|
41
|
+
|
42
|
+
def ones_comp(num_bits)
|
43
|
+
self ^ ((1 << num_bits) - 1)
|
44
|
+
end
|
45
|
+
alias_method :ones_complement, :ones_comp
|
46
|
+
alias_method :ones_compliment, :ones_comp
|
47
|
+
|
48
|
+
# Returns a bit mask for the given number of bits:
|
49
|
+
#
|
50
|
+
# 4.to_bit_mask # => 0x1111
|
51
|
+
def to_bit_mask
|
52
|
+
(1 << self) - 1
|
53
|
+
end
|
54
|
+
alias_method :bit_mask, :to_bit_mask
|
55
|
+
|
56
|
+
def to_bool
|
57
|
+
if self == 1
|
58
|
+
return true
|
59
|
+
elsif self == 0
|
60
|
+
return false
|
61
|
+
else
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_spreadsheet_column
|
67
|
+
index_hash = Hash.new { |hash, key| hash[key] = hash[key - 1].next }.merge(0 => 'A')
|
68
|
+
index_hash[self]
|
69
|
+
end
|
70
|
+
alias_method :to_xls_column, :to_spreadsheet_column
|
71
|
+
alias_method :to_xlsx_column, :to_spreadsheet_column
|
72
|
+
alias_method :to_xls_col, :to_spreadsheet_column
|
73
|
+
alias_method :to_xlsx_col, :to_spreadsheet_column
|
74
|
+
alias_method :to_spreadsheet_col, :to_spreadsheet_column
|
75
|
+
end
|
76
|
+
|
77
|
+
if RUBY_VERSION <= '2.4.0'
|
78
|
+
class Fixnum
|
79
|
+
prepend Origen::IntegerExtension
|
80
|
+
end
|
81
|
+
|
82
|
+
class Bignum
|
83
|
+
prepend Origen::IntegerExtension
|
84
|
+
end
|
85
|
+
end
|
@@ -1,6 +1,30 @@
|
|
1
|
+
# The base class of all numbers, i.e. integers and floats
|
1
2
|
class Numeric
|
2
|
-
|
3
|
-
|
3
|
+
# Helpers for cases where a method may return a 0, 1 or an instance
|
4
|
+
# of Origen::Value::X or Origen::Value::Z
|
5
|
+
|
6
|
+
def z?;
|
7
|
+
false;
|
8
|
+
end
|
9
|
+
|
10
|
+
def hi_z?;
|
11
|
+
false;
|
12
|
+
end
|
13
|
+
|
14
|
+
def x?;
|
15
|
+
false;
|
16
|
+
end
|
17
|
+
|
18
|
+
def undefined?;
|
19
|
+
false;
|
20
|
+
end
|
21
|
+
|
22
|
+
def x_or_z?;
|
23
|
+
false;
|
24
|
+
end
|
25
|
+
|
26
|
+
def z_or_x?;
|
27
|
+
false;
|
4
28
|
end
|
5
29
|
|
6
30
|
def to_hex
|
@@ -65,13 +89,13 @@ class Numeric
|
|
65
89
|
|
66
90
|
# Msps ==> Mega samples per second
|
67
91
|
|
68
|
-
%w(GHz Ghz GTs Gts Gsps).each do |m|
|
92
|
+
%w(GHz Ghz GTs Gts Gsps Gbps).each do |m|
|
69
93
|
define_method m do
|
70
94
|
self * 1_000_000_000
|
71
95
|
end
|
72
96
|
end
|
73
97
|
|
74
|
-
%w(MHz Mhz MTs Mts Msps).each do |m|
|
98
|
+
%w(MHz Mhz MTs Mts Msps Mbps).each do |m|
|
75
99
|
define_method m do
|
76
100
|
self * 1_000_000
|
77
101
|
end
|
data/lib/origen/log.rb
CHANGED
@@ -14,7 +14,7 @@ module Origen
|
|
14
14
|
x.send(:init_sub_blocks, *args) if x.respond_to?(:init_sub_blocks)
|
15
15
|
if x.respond_to?(:version=)
|
16
16
|
version = options[:version]
|
17
|
-
version ||= args.first if args.first.is_a?(
|
17
|
+
version ||= args.first if args.first.is_a?(Integer)
|
18
18
|
x.version = version
|
19
19
|
end
|
20
20
|
if x.respond_to?(:parent=)
|
@@ -47,6 +47,11 @@ module Origen
|
|
47
47
|
is_top_level = x.respond_to?(:includes_origen_top_level?)
|
48
48
|
if x.respond_to?(:wrap_in_controller)
|
49
49
|
x = x.wrap_in_controller
|
50
|
+
# If this object has been instantiated after on_create has already been called,
|
51
|
+
# then invoke it now
|
52
|
+
if Origen.application_loaded? && Origen.app.on_create_called?
|
53
|
+
x.controller.on_create if x.controller.respond_to?(:on_create)
|
54
|
+
end
|
50
55
|
end
|
51
56
|
if is_top_level
|
52
57
|
Origen.app.listeners_for(:on_top_level_instantiated, top_level: false).each do |listener|
|
data/lib/origen/netlist/list.rb
CHANGED
@@ -49,7 +49,7 @@ module Origen
|
|
49
49
|
else
|
50
50
|
from_proc = false
|
51
51
|
end
|
52
|
-
if val.is_a?(
|
52
|
+
if val.is_a?(Integer)
|
53
53
|
bits << Registers::Bit.new(nil, index, access: :ro, data: (i == '*' && !from_proc) ? val[index] : val)
|
54
54
|
elsif val
|
55
55
|
vp, vi = *to_v(val)
|
@@ -122,7 +122,7 @@ module Origen
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def clean(path)
|
125
|
-
if path.is_a?(
|
125
|
+
if path.is_a?(Integer)
|
126
126
|
{ path: path, numeric: true }
|
127
127
|
elsif path.is_a?(Proc)
|
128
128
|
{ path: path, proc: true }
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Origen
|
2
|
+
class OrgFile
|
3
|
+
autoload :Interceptor, 'origen/org_file/interceptor'
|
4
|
+
autoload :Interceptable, 'origen/org_file/interceptable'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def new(*args, &block)
|
8
|
+
if @internal_new
|
9
|
+
super
|
10
|
+
else
|
11
|
+
open(*args, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def open(id, options = {})
|
16
|
+
fail "An org_file is already open with id: #{id}" if open_files[id]
|
17
|
+
@internal_new = true
|
18
|
+
f = OrgFile.new(id, options)
|
19
|
+
@internal_new = nil
|
20
|
+
open_files[id] = f
|
21
|
+
if block_given?
|
22
|
+
yield f
|
23
|
+
close(id, options)
|
24
|
+
else
|
25
|
+
f
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def close(id, options = {})
|
30
|
+
fail "An org_file with this ID has not been opened id: #{id}" unless open_files[id]
|
31
|
+
open_files[id].close unless options[:_internal_org_file_call_]
|
32
|
+
open_files[id] = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def org_file(id = nil)
|
36
|
+
id ? open_files[id] : open_files.to_a.last[1]
|
37
|
+
end
|
38
|
+
|
39
|
+
def cycle(number = 1)
|
40
|
+
open_files.each { |id, f| f.cycle(number) }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def open_files
|
46
|
+
@open_files ||= {}.with_indifferent_access
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :path, :filename
|
51
|
+
attr_reader :id, :operation
|
52
|
+
|
53
|
+
def initialize(id, options = {})
|
54
|
+
@id = id
|
55
|
+
@path = options[:path] || default_filepath
|
56
|
+
@filename = options[:filename] || "#{id}.org"
|
57
|
+
FileUtils.mkdir_p(path)
|
58
|
+
@path_to_file = File.join(path, filename)
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_filepath
|
62
|
+
"#{Origen.root}/pattern/org/#{Origen.target.name}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def file
|
66
|
+
@file ||= begin
|
67
|
+
if operation == 'r'
|
68
|
+
fail "No org file found at: #{@path_to_file}" unless exist?
|
69
|
+
end
|
70
|
+
File.open(@path_to_file, operation)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def exist?
|
75
|
+
File.exist?(@path_to_file)
|
76
|
+
end
|
77
|
+
|
78
|
+
def close
|
79
|
+
# Corner case, if no call to read_line or record was made then no file was created and there
|
80
|
+
# is no file to close
|
81
|
+
if @file
|
82
|
+
file.puts "#{@buffer}#{@buffer_cycles}" if @buffer
|
83
|
+
file.close
|
84
|
+
end
|
85
|
+
self.class.close(id, _internal_org_file_call_: true)
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def read_line
|
90
|
+
@operation ||= 'r'
|
91
|
+
operations = file.readline.strip.split(';')
|
92
|
+
cycles = operations.pop.to_i
|
93
|
+
operations = operations.map { |op| op.split(',') }.map { |op| op[0] = eval(op[0]); op }
|
94
|
+
if block_given?
|
95
|
+
yield operations, cycles
|
96
|
+
else
|
97
|
+
[operations, cycles]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def record(path_to_object, method, *args)
|
102
|
+
@operation ||= 'w'
|
103
|
+
@line ||= ''
|
104
|
+
@line += "#{path_to_object},#{method}"
|
105
|
+
@line += ",#{args.join(',')}" unless args.empty?
|
106
|
+
@line += ';'
|
107
|
+
end
|
108
|
+
|
109
|
+
def cycle(number)
|
110
|
+
if @buffer
|
111
|
+
if @line == @buffer
|
112
|
+
@buffer_cycles += 1
|
113
|
+
else
|
114
|
+
file.puts "#{@buffer}#{@buffer_cycles}"
|
115
|
+
@buffer = @line
|
116
|
+
@buffer_cycles = 1
|
117
|
+
end
|
118
|
+
else
|
119
|
+
@buffer = @line
|
120
|
+
@buffer_cycles = 1
|
121
|
+
end
|
122
|
+
@line = nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Origen
|
2
|
+
class OrgFile
|
3
|
+
module Interceptable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
|
7
|
+
# Defers this executing until the whole class has loaded
|
8
|
+
Origen.after_app_loaded do
|
9
|
+
unless (base.instance_methods - Object.methods).include?(:global_path_to)
|
10
|
+
puts 'When adding the OrgFile::Interceptable module to a class, the class must define an instance method called "global_path_to", like this:'
|
11
|
+
puts
|
12
|
+
puts ' # Must return a string that contains a global path to access the given object,'
|
13
|
+
puts ' # here for example if the object was a pin'
|
14
|
+
puts ' def global_path_to'
|
15
|
+
puts ' "dut.pins(:#{id})"'
|
16
|
+
puts ' end'
|
17
|
+
fail "Incomplete integration of OrgFile::Interceptable in #{base}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def new(*args, &block)
|
24
|
+
o = allocate
|
25
|
+
i = OrgFile::Interceptor.new(o)
|
26
|
+
o.__interceptor__ = i
|
27
|
+
i.send(:initialize, *args, &block)
|
28
|
+
i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Class which include OrgFile::Interceptor should use 'myself' anytime then want to reference 'self',
|
33
|
+
# this ensures that there are never any references to the unwrapped object
|
34
|
+
def myself
|
35
|
+
@__interceptor__
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def __interceptor__=(obj)
|
40
|
+
@__interceptor__ = obj
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'set'
|
2
|
+
module Origen
|
3
|
+
class OrgFile
|
4
|
+
# @api private
|
5
|
+
#
|
6
|
+
# Helper for the Interceptor where block_given? doesn't work internally
|
7
|
+
def self._block_given_?(&block)
|
8
|
+
block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
class Interceptor < ::BasicObject
|
12
|
+
def initialize(object, options = {})
|
13
|
+
@object = object
|
14
|
+
@@locked = false unless defined? @@locked
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect(*args)
|
18
|
+
@object.inspect(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(obj)
|
22
|
+
if obj.respond_to?(:__org_file_interceptor__)
|
23
|
+
@object == obj.__object__
|
24
|
+
else
|
25
|
+
@object == obj
|
26
|
+
end
|
27
|
+
end
|
28
|
+
alias_method :equal?, :==
|
29
|
+
|
30
|
+
def record_to_org_file(id = nil, options = {})
|
31
|
+
id, options = nil, id if id.is_a?(::Hash)
|
32
|
+
if options[:only]
|
33
|
+
@org_file_methods_to_intercept = Array(options[:only]).to_set
|
34
|
+
else
|
35
|
+
@org_file_methods_to_intercept = default_org_file_captures
|
36
|
+
if options[:also]
|
37
|
+
@org_file_methods_to_intercept += Array(options[:also]).to_set
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@org_file ||= @old_org_file || OrgFile.org_file(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Temporarily stop recording operations within the given block, or stop recording
|
44
|
+
# completely if no block given
|
45
|
+
def stop_recording_to_org_file(&block)
|
46
|
+
@old_org_file = @org_file
|
47
|
+
if OrgFile._block_given_?(&block)
|
48
|
+
@org_file = nil
|
49
|
+
yield
|
50
|
+
@org_file = @old_org_file
|
51
|
+
else
|
52
|
+
@org_file = nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method, *args, &block)
|
57
|
+
if !@@locked && @org_file && @org_file_methods_to_intercept.include?(method)
|
58
|
+
@org_file.record(@object.global_path_to, method, *args)
|
59
|
+
# Locking prevents an operation on an intercepted container object trigger from generating multiple
|
60
|
+
# org file entries if its contained objects are also intercepted. e.g. Imagine this is a pin group, we
|
61
|
+
# want the org file to reflect the operation called on the pin group, but not the many subsequent internal
|
62
|
+
# operations as the group proxies the operation to its contained pins
|
63
|
+
@@locked = true
|
64
|
+
@object.send(method, *args, &block)
|
65
|
+
@@locked = false
|
66
|
+
else
|
67
|
+
@object.send(method, *args, &block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def respond_to?(method, include_private = false)
|
72
|
+
method == :__org_file_interceptor__ ||
|
73
|
+
@object.respond_to?(method, include_private)
|
74
|
+
end
|
75
|
+
|
76
|
+
def __org_file_interceptor__
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
# @api private
|
81
|
+
#
|
82
|
+
# Don't ever use this! An un-wrapped reference to an object must never make it into
|
83
|
+
# application code or else any operations called on the un-wrapped reference will not
|
84
|
+
# be captured.
|
85
|
+
def __object__
|
86
|
+
@object
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def debugger
|
92
|
+
::Kernel.debugger
|
93
|
+
end
|
94
|
+
|
95
|
+
def default_org_file_captures
|
96
|
+
@default_captures ||= Array(@object.try(:org_file_intercepted_methods)).to_set
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|