origen 0.5.7 → 0.5.8
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/version.rb +1 -1
- data/helpers/guides.rb +1 -0
- data/lib/origen.rb +4 -0
- data/lib/origen/commands.rb +5 -0
- data/lib/origen/core_ext/numeric.rb +4 -0
- data/lib/origen/core_ext/range.rb +9 -0
- data/lib/origen/core_ext/string.rb +2 -1
- data/lib/origen/global_methods.rb +4 -0
- data/lib/origen/model.rb +28 -0
- data/lib/origen/model_initializer.rb +4 -0
- data/lib/origen/models.rb +6 -0
- data/lib/origen/models/mux.rb +26 -0
- data/lib/origen/models/scan_register.rb +74 -0
- data/lib/origen/netlist.rb +24 -0
- data/lib/origen/netlist/connectable.rb +18 -0
- data/lib/origen/netlist/list.rb +152 -0
- data/lib/origen/pins.rb +0 -71
- data/lib/origen/pins/pin.rb +6 -10
- data/lib/origen/pins/pin_collection.rb +1 -1
- data/lib/origen/ports.rb +66 -0
- data/lib/origen/ports/bit_collection.rb +6 -0
- data/lib/origen/ports/port.rb +129 -0
- data/lib/origen/ports/port_collection.rb +19 -0
- data/lib/origen/ports/section.rb +116 -0
- data/lib/origen/registers.rb +7 -1
- data/lib/origen/registers/bit.rb +8 -3
- data/lib/origen/registers/bit_collection.rb +57 -2
- data/lib/origen/registers/reg.rb +2 -2
- data/lib/origen/revision_control/design_sync.rb +47 -3
- data/lib/origen/sub_blocks.rb +12 -3
- data/lib/origen/undefined.rb +13 -0
- data/templates/nanoc/layouts/bootstrap.html.erb +8 -0
- metadata +16 -5
- data/lib/origen/pins/port.rb +0 -268
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f23605859c980dd6d2640897a4245aad8906766c
|
4
|
+
data.tar.gz: 2e771418b57f561353455cfff1ae6018124742c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c4ad2bba1cfbc00dba89d9764f0276d846039286e15378c6cdb11d25c19a25f729057583a6c23c24decbfbd3f75052d8ad5ffa061e0d2d36fb3b11511d57076
|
7
|
+
data.tar.gz: 87b0b8ae625116e81cd673f1e7384d23de2b6be4d5f6195ee11f99f7b3885bed74eb6996e19f09759a32dc159f6a4a832a9f1668098abccae447d5ff83c6f0e5
|
data/config/version.rb
CHANGED
data/helpers/guides.rb
CHANGED
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
|
|
data/lib/origen/commands.rb
CHANGED
@@ -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
|
@@ -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
|
-
|
58
|
+
@@symbolize ||= {}
|
59
|
+
@@symbolize[self] ||= gsub(/(\n|\s|\(|\)|\.|\[|\]|-|{|})/, '_').downcase.to_sym
|
59
60
|
end
|
60
61
|
|
61
62
|
# acronyms
|
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,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
|