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 +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
|