HDLRuby 2.4.29 → 2.6.4
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/lib/HDLRuby/drivers/xcd.rb +79 -0
- data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +1 -1
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +27 -0
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +19 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
- data/lib/HDLRuby/hdr_samples/huge_rom.rb +25 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +21 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/multi_timed_bench.rb +54 -0
- data/lib/HDLRuby/hdr_samples/music.rb +79 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +42 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_function_generator.rb +25 -0
- data/lib/HDLRuby/hdrcc.rb +162 -26
- data/lib/HDLRuby/hruby_decorator.rb +250 -0
- data/lib/HDLRuby/hruby_high.rb +468 -91
- data/lib/HDLRuby/hruby_low.rb +913 -45
- data/lib/HDLRuby/hruby_low2c.rb +122 -168
- data/lib/HDLRuby/hruby_low2hdr.rb +738 -0
- data/lib/HDLRuby/hruby_low2high.rb +331 -549
- data/lib/HDLRuby/hruby_low2vhd.rb +39 -2
- data/lib/HDLRuby/hruby_low_bool2select.rb +29 -0
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +27 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +25 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +70 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +28 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -3
- data/lib/HDLRuby/hruby_low_without_namespace.rb +7 -4
- data/lib/HDLRuby/hruby_low_without_select.rb +13 -0
- data/lib/HDLRuby/hruby_tools.rb +11 -1
- data/lib/HDLRuby/hruby_verilog.rb +1577 -1709
- data/lib/HDLRuby/sim/hruby_sim.h +29 -3
- data/lib/HDLRuby/sim/hruby_sim_calc.c +63 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +24 -9
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +5 -1
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +22 -6
- data/lib/HDLRuby/std/fixpoint.rb +9 -0
- data/lib/HDLRuby/std/function_generator.rb +139 -0
- data/lib/HDLRuby/std/hruby_unit.rb +75 -0
- data/lib/HDLRuby/template_expander.rb +61 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +21 -5
@@ -14,3 +14,19 @@ system :rom4_8 do
|
|
14
14
|
data1 <= content1[addr]
|
15
15
|
data2 <= content2[addr]
|
16
16
|
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
system :test_rom do
|
21
|
+
[2..0].inner :addr
|
22
|
+
[7..0].inner :data0,:data1,:data2
|
23
|
+
|
24
|
+
rom4_8(:my_rom).(addr,data0,data1,data2)
|
25
|
+
|
26
|
+
timed do
|
27
|
+
8.times do |i|
|
28
|
+
addr <= i
|
29
|
+
!10.ns
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'std/function_generator.rb'
|
2
|
+
|
3
|
+
include HDLRuby::High::Std
|
4
|
+
|
5
|
+
# System for testing the function generator standard library.
|
6
|
+
system :with_function_generator do
|
7
|
+
# signed[8].inner :x
|
8
|
+
# signed[32].inner :y
|
9
|
+
bit[8].inner :x
|
10
|
+
signed[8].inner :y
|
11
|
+
|
12
|
+
# function_generator(Math.method(:sin).to_proc,
|
13
|
+
# signed[8],signed[32],4,-Math::PI..Math::PI,-2..2).
|
14
|
+
function_generator(Math.method(:sin).to_proc,
|
15
|
+
bit[8],signed[8],4,-Math::PI..Math::PI,-2..2).
|
16
|
+
(:my_sin).(x,y)
|
17
|
+
|
18
|
+
timed do
|
19
|
+
# (-128..127).each do |i|
|
20
|
+
(0..255).each do |i|
|
21
|
+
x <= i
|
22
|
+
!10.ns
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'tempfile'
|
4
5
|
require 'HDLRuby'
|
5
6
|
require 'HDLRuby/hruby_check.rb'
|
6
7
|
# require 'ripper'
|
7
|
-
require 'HDLRuby/
|
8
|
+
require 'HDLRuby/hruby_low2hdr'
|
8
9
|
require 'HDLRuby/hruby_low2c'
|
9
10
|
require 'HDLRuby/hruby_low2vhd'
|
10
11
|
require 'HDLRuby/hruby_low_fix_types'
|
@@ -50,12 +51,21 @@ module HDLRuby
|
|
50
51
|
# The required files.
|
51
52
|
attr_reader :requires
|
52
53
|
|
53
|
-
# Creates a new loader for a +top_system+ system in file +
|
54
|
+
# Creates a new loader for a +top_system+ system in file +top_file_name+
|
54
55
|
# from directory +dir+ with generic parameters +params+.
|
56
|
+
#
|
57
|
+
# NOTE: +top_file+ can either be a file or a file name.
|
55
58
|
def initialize(top_system,top_file,dir,*params)
|
56
59
|
# Sets the top and the looking directory.
|
57
60
|
@top_system = top_system.to_s
|
58
|
-
@top_file
|
61
|
+
# @top_file can either be a file or a string giving the file name.
|
62
|
+
if top_file.respond_to?(:path) then
|
63
|
+
@top_file = top_file
|
64
|
+
@top_file_name = top_file.path
|
65
|
+
else
|
66
|
+
@top_file = nil
|
67
|
+
@top_file_name = top_file.to_s
|
68
|
+
end
|
59
69
|
@dir = dir.to_s
|
60
70
|
@params = params
|
61
71
|
|
@@ -82,31 +92,48 @@ module HDLRuby
|
|
82
92
|
end
|
83
93
|
|
84
94
|
# Loads a single +file+.
|
95
|
+
#
|
96
|
+
# NOTE: +file+ can either be a file or a file name.
|
85
97
|
def read(file)
|
86
98
|
# Resolve the file.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
99
|
+
if file.respond_to?(:read) then
|
100
|
+
found = file
|
101
|
+
else
|
102
|
+
found = File.join(@dir,file)
|
103
|
+
unless File.exist?(found) then
|
104
|
+
founds = Dir.glob(@std_dirs.map do |path|
|
105
|
+
File.join(path,file)
|
106
|
+
end)
|
107
|
+
if founds.empty? then
|
108
|
+
# No standard file with this name, this is an error.
|
109
|
+
raise "Unknown required file: #{file}."
|
110
|
+
else
|
111
|
+
# A standard file is found, skip it since it does not
|
112
|
+
# need to be read.
|
113
|
+
# puts "Standard files: #{founds}"
|
114
|
+
return false
|
115
|
+
end
|
98
116
|
end
|
99
117
|
end
|
100
118
|
# Load the file.
|
101
|
-
# @texts << File.read(File.join(@dir,file) )
|
102
119
|
@texts << File.read(found)
|
103
|
-
|
104
|
-
|
120
|
+
if found.respond_to?(:path) then
|
121
|
+
@checks << Checker.new(@texts[-1],found.path)
|
122
|
+
else
|
123
|
+
@checks << Checker.new(@texts[-1])
|
124
|
+
end
|
105
125
|
return true
|
106
126
|
end
|
107
127
|
|
108
128
|
# Loads all the files from +file+.
|
109
|
-
def read_all(file =
|
129
|
+
def read_all(file = nil)
|
130
|
+
unless file then
|
131
|
+
if @top_file then
|
132
|
+
file = @top_file
|
133
|
+
else
|
134
|
+
file = @top_file_name
|
135
|
+
end
|
136
|
+
end
|
110
137
|
# puts "read_all with file=#{file}"
|
111
138
|
# Read the file
|
112
139
|
# read(file)
|
@@ -174,7 +201,7 @@ module HDLRuby
|
|
174
201
|
# Maybe it is a parse error, look for it.
|
175
202
|
bind = TOPLEVEL_BINDING.clone
|
176
203
|
eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
|
177
|
-
eval(@texts[0],bind,@
|
204
|
+
eval(@texts[0],bind,@top_file_name,1)
|
178
205
|
# No parse error found.
|
179
206
|
raise "Cannot find a top system." unless @top_system
|
180
207
|
end
|
@@ -183,7 +210,7 @@ module HDLRuby
|
|
183
210
|
bind = TOPLEVEL_BINDING.clone
|
184
211
|
eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
|
185
212
|
# Process it.
|
186
|
-
eval(@texts[0],bind,@
|
213
|
+
eval(@texts[0],bind,@top_file_name,1)
|
187
214
|
# Get the resulting instance
|
188
215
|
if @params.empty? then
|
189
216
|
# There is no generic parameter
|
@@ -225,6 +252,20 @@ module HDLRuby
|
|
225
252
|
|
226
253
|
end
|
227
254
|
|
255
|
+
# Locate an executable from cmd.
|
256
|
+
def which(cmd)
|
257
|
+
# Get the possible exetensions (for windows case).
|
258
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
259
|
+
# Look for the command within the executable paths.
|
260
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
261
|
+
exts.each do |ext|
|
262
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
263
|
+
return exe if File.executable?(exe) && !File.directory?(exe)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
nil
|
267
|
+
end
|
268
|
+
|
228
269
|
|
229
270
|
|
230
271
|
if __FILE__ == $0 then
|
@@ -310,14 +351,24 @@ $optparse = OptionParser.new do |opts|
|
|
310
351
|
opts.on("-D", "--debug","Set the HDLRuby debug mode") do |d|
|
311
352
|
$options[:debug] = d
|
312
353
|
end
|
354
|
+
opts.on("-T","--test t0,t1,t2","Compile the unit tests named t0,t1,...") do |t|
|
355
|
+
$options[:test] = t
|
356
|
+
end
|
357
|
+
opts.on("--testall","Compile all the available unit tests.") do |t|
|
358
|
+
$options[:testall] = t
|
359
|
+
end
|
313
360
|
opts.on("-t", "--top system", "Specify the top system to process") do|t|
|
314
361
|
$options[:top] = t
|
315
362
|
end
|
316
363
|
opts.on("-p", "--param x,y,z", "Specify the generic parameters") do |p|
|
317
364
|
$options[:param] = p
|
318
365
|
end
|
319
|
-
opts.on("--
|
320
|
-
|
366
|
+
opts.on("--dump","Dump all the properties to yaml files") do |v|
|
367
|
+
$options[:dump] = v
|
368
|
+
$options[:multiple] = v
|
369
|
+
end
|
370
|
+
opts.on("--version", "Shows the version of HDLRuby.") do |v|
|
371
|
+
puts VERSION
|
321
372
|
exit
|
322
373
|
end
|
323
374
|
# opts.on_tail("-h", "--help", "Show this message") do
|
@@ -370,6 +421,28 @@ if $input == nil then
|
|
370
421
|
exit
|
371
422
|
end
|
372
423
|
|
424
|
+
if ($options[:test] || $options[:testall]) then
|
425
|
+
$top = "__test__"
|
426
|
+
tests = $options[:test]
|
427
|
+
if tests then
|
428
|
+
tests = tests.to_s.split(",")
|
429
|
+
tests.map! {|test| ":\"#{test}\"" }
|
430
|
+
tests = ", #{tests.join(",")}"
|
431
|
+
else
|
432
|
+
tests = ""
|
433
|
+
end
|
434
|
+
# Generate the unit test file.
|
435
|
+
$test_file = Tempfile.new('tester.rb',Dir.getwd)
|
436
|
+
$test_file.write("require 'std/hruby_unit.rb'\nrequire_relative '#{$input}'\n\n" +
|
437
|
+
"HDLRuby::Unit.test(:\"#{$top}\"#{tests})\n")
|
438
|
+
# $test_file.rewind
|
439
|
+
# puts $test_file.read
|
440
|
+
# exit
|
441
|
+
$test_file.rewind
|
442
|
+
# It is the new input file.
|
443
|
+
$input = $test_file
|
444
|
+
end
|
445
|
+
|
373
446
|
# Open the output.
|
374
447
|
if $output then
|
375
448
|
if $options[:multiple] then
|
@@ -382,7 +455,7 @@ if $output then
|
|
382
455
|
$output = File.open($output,"w")
|
383
456
|
end
|
384
457
|
else
|
385
|
-
if $
|
458
|
+
if $options[:multiple] then
|
386
459
|
raise "Need a target directory in multiple files generation mode."
|
387
460
|
end
|
388
461
|
$output = $stdout
|
@@ -394,6 +467,12 @@ $loader = HDRLoad.new($top,$input,$options[:directory].to_s,*$params)
|
|
394
467
|
$loader.read_all
|
395
468
|
$loader.check_all
|
396
469
|
|
470
|
+
# Remove the test file if any, it is not needed any longer.
|
471
|
+
if $test_file then
|
472
|
+
$test_file.close
|
473
|
+
$test_file.unlink
|
474
|
+
end
|
475
|
+
|
397
476
|
if $options[:syntax] then
|
398
477
|
if $options[:multiple] then
|
399
478
|
raise "Multiple files generation mode not supported for syntax tree output."
|
@@ -414,6 +493,24 @@ end
|
|
414
493
|
# Get the top systemT.
|
415
494
|
$top_system = $top_instance.to_low.systemT
|
416
495
|
|
496
|
+
|
497
|
+
# Apply the pre drivers if any.
|
498
|
+
Hdecorator.each_with_property(:pre_driver) do |obj, value|
|
499
|
+
unless value.is_a?(Array) && value.size == 2 then
|
500
|
+
raise "pre_driver requires a driver file name command name."
|
501
|
+
end
|
502
|
+
# Load the driver.
|
503
|
+
require_relative(value[0].to_s)
|
504
|
+
# Ensure obj is the low version.
|
505
|
+
if obj.properties.key?(:high2low) then
|
506
|
+
# obj is high, get the corresponding low.
|
507
|
+
obj = obj.properties[:high2low][0]
|
508
|
+
end
|
509
|
+
# Execute it.
|
510
|
+
send(value[1].to_sym,obj,*value[2..-1])
|
511
|
+
end
|
512
|
+
|
513
|
+
|
417
514
|
# Gather the non-HDLRuby code.
|
418
515
|
$non_hdlruby = []
|
419
516
|
$top_system.each_systemT_deep do |systemT|
|
@@ -455,7 +552,7 @@ elsif $options[:hdr] then
|
|
455
552
|
# $output << systemT.to_high
|
456
553
|
# end
|
457
554
|
# $output << $top_instance.to_low.systemT.to_high
|
458
|
-
$output << $top_system.
|
555
|
+
$output << $top_system.to_hdr
|
459
556
|
elsif $options[:clang] then
|
460
557
|
# top_system = $top_instance.to_low.systemT
|
461
558
|
# top_system = $top_system
|
@@ -572,8 +669,19 @@ elsif $options[:clang] then
|
|
572
669
|
end
|
573
670
|
end
|
574
671
|
Dir.chdir($output)
|
575
|
-
#
|
576
|
-
|
672
|
+
# Find the compiler.
|
673
|
+
cc_cmd = which('cc')
|
674
|
+
unless cc_cmd then
|
675
|
+
cc_cmd = which('gcc')
|
676
|
+
end
|
677
|
+
unless cc_cmd then
|
678
|
+
raise "Could not find any compiler, please compile by hand as follows:\n" +
|
679
|
+
" In folder #{$output} execute:\n" +
|
680
|
+
" <my compiler> -o hruby_simulator *.c -lpthread\n" +
|
681
|
+
" Then execute:\n hruby_simulator"
|
682
|
+
end
|
683
|
+
# Use it.
|
684
|
+
Kernel.system("#{cc_cmd} -o3 -o hruby_simulator *.c -lpthread")
|
577
685
|
Kernel.system("./hruby_simulator")
|
578
686
|
end
|
579
687
|
elsif $options[:verilog] then
|
@@ -678,3 +786,31 @@ elsif $options[:vhdl] then
|
|
678
786
|
end
|
679
787
|
end
|
680
788
|
end
|
789
|
+
|
790
|
+
# Apply the post drivers if any.
|
791
|
+
Hdecorator.each_with_property(:post_driver) do |obj, value|
|
792
|
+
# Load the driver.
|
793
|
+
require_relative(value[0].to_s)
|
794
|
+
# Execute it.
|
795
|
+
send(value[1].to_sym,obj,$output)
|
796
|
+
end
|
797
|
+
|
798
|
+
# Dump the properties
|
799
|
+
if $options[:dump] then
|
800
|
+
# Decorate with the parent ids.
|
801
|
+
Hdecorator.decorate_parent_id
|
802
|
+
|
803
|
+
# Generate the directory for the properties
|
804
|
+
property_dir = $output + "/properties"
|
805
|
+
unless File.directory?(property_dir)
|
806
|
+
FileUtils.mkdir_p(property_dir)
|
807
|
+
end
|
808
|
+
|
809
|
+
# Dump to one file per key
|
810
|
+
Properties.each_key do |key|
|
811
|
+
File.open(property_dir + "/#{key}.yaml", "w") do |f|
|
812
|
+
Hdecorator.dump(key,f)
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module HDLRuby
|
5
|
+
|
6
|
+
##
|
7
|
+
# Library for describing a decorator used for adding properties to
|
8
|
+
# HDLRuby objects that are persistent and can be used for back annotation
|
9
|
+
########################################################################
|
10
|
+
|
11
|
+
##
|
12
|
+
# Gives a decorator the HDLRuby object.
|
13
|
+
module Hdecorator
|
14
|
+
# The decorator requires that each HDLRuby object has a uniq
|
15
|
+
# persistent id
|
16
|
+
|
17
|
+
# The id
|
18
|
+
attr_reader :hdr_id
|
19
|
+
|
20
|
+
# The id to object table
|
21
|
+
@@id_map = {}
|
22
|
+
|
23
|
+
# Generate the ID
|
24
|
+
@@id_gen = 0
|
25
|
+
|
26
|
+
# Ensures the ID is generated when object is initialized
|
27
|
+
def self.included(base) # built-in Ruby hook for modules
|
28
|
+
base.class_eval do
|
29
|
+
original_method = instance_method(:initialize)
|
30
|
+
define_method(:initialize) do |*args, &block|
|
31
|
+
original_method.bind(self).call(*args, &block)
|
32
|
+
# Generate the id.
|
33
|
+
@hdr_id = @@id_gen
|
34
|
+
@@id_gen += 1
|
35
|
+
# Update the id to object table
|
36
|
+
@@id_map[@hdr_id] = self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get an object by id.
|
42
|
+
def self.get(id)
|
43
|
+
return @@id_map[id]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Iterate over all the id with their object.
|
47
|
+
#
|
48
|
+
# Returns an enumerator if no ruby block is given.
|
49
|
+
#
|
50
|
+
# NOTE: converts the hash to an array to allow on-the-fly modification.
|
51
|
+
def self.each(&ruby_block)
|
52
|
+
# No ruby block? Return an enumerator.
|
53
|
+
return to_enum(:each) unless ruby_block
|
54
|
+
# A ruby block? Apply it on each object.
|
55
|
+
@@id_map.to_a.each(&ruby_block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# The decorator also need to add properties to the HDLRuby objects.
|
59
|
+
|
60
|
+
# Access the set of properties
|
61
|
+
def properties
|
62
|
+
# Create the properties if not present.
|
63
|
+
unless @properties then
|
64
|
+
@properties = Properties.new(self)
|
65
|
+
end
|
66
|
+
return @properties
|
67
|
+
end
|
68
|
+
|
69
|
+
# Iterate over all the objects from +top+ with +prop+ property.
|
70
|
+
#
|
71
|
+
# Returns an enumerator if no ruby block is given.
|
72
|
+
# NOTE: if +top+ is not given, iterate over all the objects.
|
73
|
+
def self.each_with_property(prop, top = nil, &ruby_block)
|
74
|
+
# No ruby block? Return an enumerator.
|
75
|
+
return to_enum(:each_with_property) unless ruby_block
|
76
|
+
# A ruby block? Apply the ruby_block...
|
77
|
+
if (top) then
|
78
|
+
# A top... on each object from it.
|
79
|
+
top.each_deep do |obj|
|
80
|
+
if (obj.properties.key?(prop)) then
|
81
|
+
ruby_block.call(obj, *obj.properties[prop])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else
|
85
|
+
# No top... on all the objects.
|
86
|
+
self.each do |id,obj|
|
87
|
+
if (obj.properties.key?(prop)) then
|
88
|
+
ruby_block.call(obj, *obj.properties[prop])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# # Access the set of properties and the inherited properties from
|
95
|
+
# # the high objects.
|
96
|
+
# def all_properties
|
97
|
+
# high_id = self.properties[:low2high]
|
98
|
+
# if high_id && high_id >= 0 then
|
99
|
+
# return properties.merge(Hdecorator.get(high_id))
|
100
|
+
# else
|
101
|
+
# return properties.clone
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
|
105
|
+
# Saves properties +key+ of all the object associated with
|
106
|
+
# their id to +target+.
|
107
|
+
def self.dump(key, target = "")
|
108
|
+
# Build the table to dump
|
109
|
+
tbl = {}
|
110
|
+
self.each do |id,obj|
|
111
|
+
value = obj.properties[key]
|
112
|
+
if value.any? then
|
113
|
+
tbl[id] = value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
# Dump the table.
|
117
|
+
target << YAML.dump(tbl)
|
118
|
+
return target
|
119
|
+
end
|
120
|
+
|
121
|
+
# Loads properties to +key+ for all objects from +source+.
|
122
|
+
def self.load(source,key)
|
123
|
+
# Load the id to property table.
|
124
|
+
tbl = YAML.load(source)
|
125
|
+
# Adds the property of each object according to tbl
|
126
|
+
tbl.each do |id,value|
|
127
|
+
@@id_map[id].properties[key] = value
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Some predefined properties to set.
|
132
|
+
|
133
|
+
def self.decorate_parent_id
|
134
|
+
@@id_map.each do |id, obj|
|
135
|
+
parent = obj.parent
|
136
|
+
if parent then
|
137
|
+
obj.properties[:parent_id] = obj.parent.hdr_id
|
138
|
+
else
|
139
|
+
obj.properties[:parent_id] = -1
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
## A HDLRuby set of properties
|
148
|
+
class Properties
|
149
|
+
|
150
|
+
# The set of all the property keys
|
151
|
+
@@property_keys = Set.new
|
152
|
+
|
153
|
+
# The HDLRuby object owning of the set of properties
|
154
|
+
attr_reader :owner
|
155
|
+
|
156
|
+
# Create a new set of properties and attach it to HDLRuby object
|
157
|
+
# +owner+.
|
158
|
+
def initialize(owner)
|
159
|
+
# Attach the owner.
|
160
|
+
@owner = owner
|
161
|
+
# Create the set.
|
162
|
+
@content = {}
|
163
|
+
end
|
164
|
+
|
165
|
+
# Clones the properties: also clone the contents.
|
166
|
+
def clone
|
167
|
+
result = Properties.new(owner)
|
168
|
+
@contents.each do |k,vals|
|
169
|
+
vals.each { |v| result[k] = v }
|
170
|
+
end
|
171
|
+
return result
|
172
|
+
end
|
173
|
+
|
174
|
+
# Create a new set of properties by merging with +prop+
|
175
|
+
def merge(prop)
|
176
|
+
result = self.clone
|
177
|
+
prop.each do |k,vals|
|
178
|
+
vals.each { |v| result[k] = v }
|
179
|
+
end
|
180
|
+
return result
|
181
|
+
end
|
182
|
+
|
183
|
+
# Tells if +key+ is present.
|
184
|
+
def key?(key)
|
185
|
+
@content.key?(key)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Add a property
|
189
|
+
def []=(key,value)
|
190
|
+
@@property_keys << key
|
191
|
+
# Add an entry if not present.
|
192
|
+
@content[key] = [] unless @content.key?(key)
|
193
|
+
# Add the value to the entry.
|
194
|
+
@content[key] << value
|
195
|
+
end
|
196
|
+
|
197
|
+
# Get a property
|
198
|
+
def [](key)
|
199
|
+
return @content[key]
|
200
|
+
end
|
201
|
+
|
202
|
+
# Iterate over each value associated with +key+.
|
203
|
+
def each_with_key(key,&ruby_block)
|
204
|
+
return unless @content.key?(key)
|
205
|
+
@content[key].each(&ruby_block)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Iterate over the properties of the current set.
|
209
|
+
#
|
210
|
+
# Returns an enumerator if no ruby block is given.
|
211
|
+
def each(&ruby_block)
|
212
|
+
# No ruby block? Return an enumerator.
|
213
|
+
return to_enum(:each) unless ruby_block
|
214
|
+
# A ruby block? Apply it on each input signal instance.
|
215
|
+
@content.each(&ruby_block)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Iterator over all the property keys
|
219
|
+
#
|
220
|
+
# Returns an enumerator if no ruby block is given.
|
221
|
+
def self.each_key(&ruby_block)
|
222
|
+
# No ruby block? Return an enumerator.
|
223
|
+
return to_enum(:each_key) unless ruby_block
|
224
|
+
# A ruby block? Apply it on each input signal instance.
|
225
|
+
@@property_keys.each(&ruby_block)
|
226
|
+
end
|
227
|
+
|
228
|
+
# # Iterate over the property set of all the objects from current owner.
|
229
|
+
# #
|
230
|
+
# # Returns an enumerator if no ruby block is given.
|
231
|
+
# def each_properties(&ruby_block)
|
232
|
+
# # No ruby block? Return an enumerator.
|
233
|
+
# return to_enum(:each_properties) unless ruby_block
|
234
|
+
# # A ruby block? Apply it.
|
235
|
+
# # On current property set
|
236
|
+
# ruby_block.call(self)
|
237
|
+
# # And on the properties set of sub objects of the owner.
|
238
|
+
# self.owner.instance_variables.each do |var|
|
239
|
+
# obj = owner.instance_variable_get(var)
|
240
|
+
# if (obj.is_a?(Hproperties)) then
|
241
|
+
# # obj has properties, recurse on them.
|
242
|
+
# obj.properties.each_properties(&ruby_block)
|
243
|
+
# end
|
244
|
+
# end
|
245
|
+
# end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
end
|