origen 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7890471b8ec2f67729fe1f77eb91bc06203fd708
4
- data.tar.gz: 46e1254090dfd0a60417b29877d4fd8fe6903b45
3
+ metadata.gz: f23605859c980dd6d2640897a4245aad8906766c
4
+ data.tar.gz: 2e771418b57f561353455cfff1ae6018124742c5
5
5
  SHA512:
6
- metadata.gz: 48539a0c1c7d0dd911d39c896a6510ad88cda19aec158c94241032337d3977439574b7c827f653a382dea13c96652c6b0f55f0bb363428bdf8e622c792424962
7
- data.tar.gz: 1d3cc10f4d91369a046bed8a86fe77cecaffeff7f8b6c1644d542b146718b0620cecfeea8bd07b8d368b38b497f71586d9546e51744f45479ccbcff0676ab170
6
+ metadata.gz: 2c4ad2bba1cfbc00dba89d9764f0276d846039286e15378c6cdb11d25c19a25f729057583a6c23c24decbfbd3f75052d8ad5ffa061e0d2d36fb3b11511d57076
7
+ data.tar.gz: 87b0b8ae625116e81cd673f1e7384d23de2b6be4d5f6195ee11f99f7b3885bed74eb6996e19f09759a32dc159f6a4a832a9f1668098abccae447d5ff83c6f0e5
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Origen
2
2
  MAJOR = 0
3
3
  MINOR = 5
4
- BUGFIX = 7
4
+ BUGFIX = 8
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
data/helpers/guides.rb CHANGED
@@ -8,6 +8,7 @@ facebook: origensdk
8
8
  twitter: origensdk
9
9
  author_url: https://plus.google.com/u/1/b/106463981272125989995/106463981272125989
10
10
  site_name: Origen - The Semiconductor Developer's Kit
11
+ gitter_chat: Origen-SDK/users
11
12
  END
12
13
  end
13
14
 
data/lib/origen.rb CHANGED
@@ -21,6 +21,7 @@ unless defined? RGen::ORIGENTRANSITION
21
21
  require 'origen/logger_methods'
22
22
  require 'option_parser/optparse'
23
23
  require 'bundler'
24
+ require 'origen/undefined'
24
25
 
25
26
  module Origen
26
27
  autoload :Features, 'origen/features'
@@ -28,6 +29,7 @@ unless defined? RGen::ORIGENTRANSITION
28
29
  autoload :Generator, 'origen/generator'
29
30
  autoload :Pins, 'origen/pins'
30
31
  autoload :Registers, 'origen/registers'
32
+ autoload :Ports, 'origen/ports'
31
33
  autoload :Users, 'origen/users'
32
34
  autoload :FileHandler, 'origen/file_handler'
33
35
  autoload :RegressionManager, 'origen/regression_manager'
@@ -49,6 +51,8 @@ unless defined? RGen::ORIGENTRANSITION
49
51
  autoload :Encodings, 'origen/encodings'
50
52
  autoload :Log, 'origen/log'
51
53
  autoload :Chips, 'origen/chips'
54
+ autoload :Netlist, 'origen/netlist'
55
+ autoload :Models, 'origen/models'
52
56
 
53
57
  APP_CONFIG = File.join('config', 'application.rb')
54
58
 
@@ -218,6 +218,10 @@ when 'generate', 'program', 'compile', 'merge', 'interactive', 'target', 'enviro
218
218
  require "origen/commands/#{@command}"
219
219
  exit 0 unless @command == 'interactive'
220
220
 
221
+ when 'exec'
222
+ load ARGV.first
223
+ exit 0
224
+
221
225
  when 'version'
222
226
  Origen.app # Load app
223
227
  require 'origen/commands/version'
@@ -242,6 +246,7 @@ The core origen commands are:
242
246
  program Generate a test program (short-cut alias: "p")
243
247
  interactive Start an interactive Origen console (short-cut alias: "i")
244
248
  compile Compile a template file or directory (short-cut alias: "c")
249
+ exec Execute any Ruby file with access to your app environment
245
250
 
246
251
  rc Revision control commands, see -h for details
247
252
  save Save the new or changed files from the last run or a given log file
@@ -1,4 +1,8 @@
1
1
  class Numeric
2
+ def undefined?
3
+ false
4
+ end
5
+
2
6
  def to_hex
3
7
  "0x#{to_s(16).upcase}"
4
8
  end
@@ -4,4 +4,13 @@ class Range
4
4
  last = self.last
5
5
  last..first
6
6
  end
7
+
8
+ def to_a
9
+ a = super
10
+ if a.empty?
11
+ reverse.to_a.reverse
12
+ else
13
+ a
14
+ end
15
+ end
7
16
  end
@@ -55,7 +55,8 @@ class String
55
55
  # Sanitizes the string for conversion to a symbol and returns a lower
56
56
  # cased symbol version of the string
57
57
  def symbolize
58
- gsub(/(\n|\s|\(|\)|\.|\[|\]|-|{|})/, '_').downcase.to_sym
58
+ @@symbolize ||= {}
59
+ @@symbolize[self] ||= gsub(/(\n|\s|\(|\)|\.|\[|\]|-|{|})/, '_').downcase.to_sym
59
60
  end
60
61
 
61
62
  # acronyms
@@ -57,6 +57,10 @@ module Origen
57
57
  binding
58
58
  end
59
59
 
60
+ def undefined
61
+ Origen::UndefinedClass.instance
62
+ end
63
+
60
64
  Pattern = Origen.pattern unless defined?(Pattern)
61
65
  Flow = Origen.flow unless defined?(Flow)
62
66
  Resources = Origen.resources unless defined?(Resources)
data/lib/origen/model.rb CHANGED
@@ -19,6 +19,8 @@ module Origen
19
19
  include Origen::SubBlocks
20
20
  include Origen::Parameters
21
21
  include Origen::Specs
22
+ include Origen::Ports
23
+ include Origen::Netlist
22
24
  end
23
25
 
24
26
  module ClassMethods
@@ -293,8 +295,34 @@ module Origen
293
295
  end
294
296
  end
295
297
 
298
+ # Returns true after the model's initialize method has been run
299
+ def initialized?
300
+ !!@initialized
301
+ end
302
+
303
+ def clock!
304
+ clock_prepare
305
+ clock_apply
306
+ end
307
+
308
+ def clock_prepare
309
+ sub_blocks.each do |name, block|
310
+ block.clock_prepare if block.respond_to?(:clock_prepare)
311
+ end
312
+ end
313
+
314
+ def clock_apply
315
+ sub_blocks.each do |name, block|
316
+ block.clock_apply if block.respond_to?(:clock_apply)
317
+ end
318
+ end
319
+
296
320
  private
297
321
 
322
+ def initialized
323
+ @initialized = true
324
+ end
325
+
298
326
  def _controller=(controller)
299
327
  @controller = controller
300
328
  end
@@ -21,11 +21,15 @@ module Origen
21
21
  parent = options.delete(:parent)
22
22
  x.parent = parent if parent
23
23
  end
24
+ options.each do |k, v|
25
+ x.send(:instance_variable_set, "@#{k}", v) if x.respond_to?(k)
26
+ end
24
27
  if x.method(:initialize).arity == 0
25
28
  x.send(:initialize, &block)
26
29
  else
27
30
  x.send(:initialize, *args, &block)
28
31
  end
32
+ x.send(:initialized) if x.respond_to?(:is_an_origen_model?)
29
33
  x.register_callback_listener if x.respond_to?(:register_callback_listener)
30
34
  # Do this before wrapping, otherwise the respond to method in the controller will
31
35
  # be looking for the model to be instantiated when it is not fully done yet
@@ -0,0 +1,6 @@
1
+ module Origen
2
+ module Models
3
+ autoload :ScanRegister, 'origen/models/scan_register'
4
+ autoload :Mux, 'origen/models/mux'
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ module Origen
2
+ module Models
3
+ class Mux
4
+ include Origen::Model
5
+
6
+ attr_reader :size
7
+ attr_reader :select_lines
8
+
9
+ def initialize(options = {})
10
+ @input = []
11
+ (2**select_lines).times do |i|
12
+ @input << port("input#{i}".to_sym, size: size)
13
+ end
14
+
15
+ port :select, size: select_lines
16
+ port :output, size: size
17
+
18
+ output.connect_to do |i|
19
+ unless ports[:select].data.undefined?
20
+ send("input#{ports[:select].data}")[i].path
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,74 @@
1
+ module Origen
2
+ module Models
3
+ class ScanRegister
4
+ include Origen::Model
5
+
6
+ attr_reader :size
7
+
8
+ def initialize(options = {})
9
+ # The shift register
10
+ reg :sr, 0, size: size, reset: options[:reset] || 0
11
+ # The update register, this is the value presented to the outside world
12
+ reg :ur, 0, size: size, reset: options[:reset] || 0
13
+
14
+ port :si # Scan in
15
+ port :so # Scan out
16
+ port :c, size: size # Capture in
17
+
18
+ # Control signals
19
+ port :se # Shift enable
20
+ port :ce # Capture enable
21
+ port :ue # Update enable
22
+
23
+ so.connect_to(sr[0])
24
+ end
25
+
26
+ def method_missing(method, *args, &block)
27
+ if BitCollection.instance_methods.include?(method)
28
+ ur.send(method, *args, &block)
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def respond_to?(*args)
35
+ super(*args) || BitCollection.instance_methods.include?(args.first)
36
+ end
37
+
38
+ def mode
39
+ if se.data == 1
40
+ :shift
41
+ elsif ce.data == 1
42
+ :capture
43
+ elsif ue.data == 1
44
+ :update
45
+ else
46
+ undefined
47
+ end
48
+ end
49
+
50
+ def clock_prepare
51
+ @mode = mode
52
+ if @mode == :shift
53
+ @din = si.data
54
+ elsif @mode == :capture
55
+ @din = c.data
56
+ elsif @mode == :update
57
+ @din = sr.data
58
+ end
59
+ end
60
+
61
+ def clock_apply
62
+ if @mode == :shift
63
+ sr.shift_right(@din)
64
+ elsif @mode == :capture
65
+ sr.write(@din)
66
+ elsif @mode == :update
67
+ ur.write(@din)
68
+ end
69
+ @din = nil
70
+ @mode = nil
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,24 @@
1
+ module Origen
2
+ module Netlist
3
+ autoload :List, 'origen/netlist/list'
4
+ autoload :Connectable, 'origen/netlist/connectable'
5
+
6
+ def netlist
7
+ @netlist ||= begin
8
+ if netlist_top_level == self
9
+ List.new(self)
10
+ else
11
+ netlist_top_level.netlist
12
+ end
13
+ end
14
+ end
15
+
16
+ def netlist_top_level
17
+ @netlist_top_level ||= begin
18
+ p = self
19
+ p = p.parent while p.respond_to?(:parent) && p.parent
20
+ p
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Origen
2
+ module Netlist
3
+ module Connectable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Origen::Netlist
8
+ end
9
+
10
+ def connect_to(node = nil, options = {}, &block)
11
+ node, options = nil, node if node.is_a?(Hash)
12
+ node = node.path if node.respond_to?(:path)
13
+ netlist.connect(path, node, &block)
14
+ end
15
+ alias_method :connect, :connect_to
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,152 @@
1
+ module Origen
2
+ module Netlist
3
+ class List
4
+ attr_reader :top_level, :table
5
+
6
+ alias_method :parent, :top_level
7
+ alias_method :owner, :top_level
8
+
9
+ def initialize(top_level)
10
+ @top_level = top_level
11
+ @table = {}
12
+ end
13
+
14
+ # Connect two paths together in the netlist, one can be a numeric
15
+ # value to represent a logic level connection
16
+ def connect(a, b = nil, &block)
17
+ b ||= block
18
+ align(a, b) do |path, index, target|
19
+ table[path] ||= {}
20
+ table[path][index] ||= []
21
+ table[path][index] << target
22
+ end
23
+ end
24
+
25
+ def data_bit(path, index, options = {})
26
+ bits = data_bits(path, index, options)
27
+ if bits.size > 1
28
+ fail "Multiple data bit connections found for node #{path}[#{index}]"
29
+ elsif bits.size == 0
30
+ return undefined
31
+ end
32
+ bits.first
33
+ end
34
+
35
+ def data_bits(path, index, options = {})
36
+ processed_paths = options[:processed_paths] || []
37
+ bits = []
38
+ ['*', index].each do |i|
39
+ unless processed_paths.include?("#{path}[#{i}]")
40
+ processed_paths << "#{path}[#{i}]"
41
+ vals = (table[path] || {})[i] || []
42
+ # Also consider anything attached directly to the requested path, e.g. a
43
+ # drive value applied to a port
44
+ vals << "#{path}[#{i}]" if i != '*' && !options[:sublevel]
45
+ vals.each do |val|
46
+ if val.is_a?(Proc)
47
+ from_proc = true
48
+ val = val.call(index)
49
+ else
50
+ from_proc = false
51
+ end
52
+ if val.is_a?(Fixnum)
53
+ bits << Registers::Bit.new(nil, index, access: :ro, data: (i == '*' && !from_proc) ? val[index] : val)
54
+ elsif val
55
+ vp, vi = *to_v(val)
56
+ bc = eval("top_level.#{vp}[#{vi || index}]")
57
+ if bc.is_a?(Registers::BitCollection)
58
+ bits << bc.bit
59
+ elsif bc.is_a?(Ports::Section) && bc.drive_value
60
+ bits << Registers::Bit.new(nil, index, access: :ro, data: bc.drive_value)
61
+ else
62
+ bits += data_bits(vp, vi || index, processed_paths: processed_paths, sublevel: true) || []
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ bits.uniq
69
+ end
70
+
71
+ private
72
+
73
+ def align(a, b)
74
+ a, b = clean(a), clean(b)
75
+ if a[:size] || b[:size]
76
+ if a[:size] && b[:size]
77
+ size = [a[:size], b[:size]].min
78
+ else
79
+ size = a[:size] || b[:size]
80
+ end
81
+
82
+ unless a[:numeric] || a[:proc]
83
+ size.times do |i|
84
+ index = a[:indexes] ? a[:indexes][i] : i
85
+ if b[:numeric]
86
+ target = b[:path][i]
87
+ elsif b[:proc]
88
+ target = b[:path]
89
+ else
90
+ if b[:indexes]
91
+ target = "#{b[:path]}[#{b[:indexes][i]}]"
92
+ else
93
+ target = "#{b[:path]}[#{i}]"
94
+ end
95
+ end
96
+ yield a[:path], index, target
97
+ end
98
+ end
99
+
100
+ unless b[:numeric] || b[:proc]
101
+ size.times do |i|
102
+ index = b[:indexes] ? b[:indexes][i] : i
103
+ if a[:numeric]
104
+ target = a[:path][i]
105
+ elsif a[:proc]
106
+ target = a[:path]
107
+ else
108
+ if a[:indexes]
109
+ target = "#{a[:path]}[#{a[:indexes][i]}]"
110
+ else
111
+ target = "#{a[:path]}[#{i}]"
112
+ end
113
+ end
114
+ yield b[:path], index, target
115
+ end
116
+ end
117
+
118
+ else
119
+ yield a[:path], '*', b[:path] unless a[:numeric] || a[:proc]
120
+ yield b[:path], '*', a[:path] unless b[:numeric] || b[:proc]
121
+ end
122
+ end
123
+
124
+ def clean(path)
125
+ if path.is_a?(Fixnum)
126
+ { path: path, numeric: true }
127
+ elsif path.is_a?(Proc)
128
+ { path: path, proc: true }
129
+ else
130
+ if path =~ /(.*)\[(\d+):?(\d*)\]$/
131
+ if Regexp.last_match(3).empty?
132
+ { path: Regexp.last_match(1), size: 1, indexes: [Regexp.last_match(2).to_i] }
133
+ else
134
+ a = ((Regexp.last_match(2).to_i)..(Regexp.last_match(3).to_i)).to_a
135
+ { path: Regexp.last_match(1), size: a.size, indexes: a }
136
+ end
137
+ else
138
+ { path: path }
139
+ end
140
+ end
141
+ end
142
+
143
+ def to_v(path)
144
+ if path =~ /(.*)\[(\d+)\]$/
145
+ [Regexp.last_match(1), Regexp.last_match(2).to_i]
146
+ else
147
+ [path, nil]
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end