fhlow 1.91.0 → 1.91.1

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.
Files changed (59) hide show
  1. data/bin/fhlow +58 -10
  2. data/lib/module_config/complexitem.rb +57 -0
  3. data/lib/module_config/config.rb +5 -3
  4. data/lib/module_config/item.rb +0 -4
  5. data/lib/module_config/items/complex.rb +44 -0
  6. data/lib/module_config/items/complexfreqencies.rb +59 -0
  7. data/lib/module_config/items/complexlibrary.rb +46 -0
  8. data/lib/module_config/items/complexpackage.rb +47 -0
  9. data/lib/module_config/items/complexpins.rb +59 -0
  10. data/lib/module_config/items/complexunit.rb +53 -0
  11. data/lib/module_config/items/simple.rb +29 -0
  12. data/lib/module_config/items/simplearchitecture.rb +34 -0
  13. data/lib/module_config/items/simplebindir.rb +31 -0
  14. data/lib/module_config/items/simplebool.rb +24 -0
  15. data/lib/module_config/items/simplepostlayoutsdf.rb +24 -0
  16. data/lib/module_config/items/simplesimulaterun.rb +25 -0
  17. data/lib/module_config/items/simpleverbose.rb +33 -0
  18. data/lib/module_config/section.rb +16 -4
  19. data/lib/module_config/simpleitem.rb +37 -0
  20. data/lib/module_config/test.flw +33 -12
  21. data/lib/module_config/test.rb +54 -4
  22. data/lib/module_config/unittests/config_test.rb +15 -12
  23. data/lib/module_fhlow/leaf.rb +28 -24
  24. data/lib/module_fhlow/leafs/Library.rb +60 -0
  25. data/lib/module_fhlow/leafs/Package.rb +4 -1
  26. data/lib/module_fhlow/leafs/Unit.rb +9 -1
  27. data/lib/module_fhlow/node.rb +4 -5
  28. data/lib/module_fhlow/plugin.rb +11 -0
  29. data/lib/module_fhlow/pluginpool.rb +17 -5
  30. data/lib/module_fhlow/rootnode.rb +4 -3
  31. data/lib/plugins/Modelsim.flw +18 -0
  32. data/lib/plugins/Modelsim.rb +331 -0
  33. data/lib/plugins/Quartus.flw +5 -0
  34. data/lib/plugins/Quartus.rb +237 -0
  35. data/tests/testsuite.rb +0 -0
  36. metadata +84 -79
  37. data/lib/module_config/configitems/complex.rb +0 -71
  38. data/lib/module_config/configitems/complexpackage.rb +0 -67
  39. data/lib/module_config/configitems/complexunit.rb +0 -76
  40. data/lib/module_config/configitems/simple.rb +0 -56
  41. data/lib/module_config/configitems/simplearchitecture.rb +0 -52
  42. data/lib/module_config/configitems/simplepackage.rb +0 -47
  43. data/lib/module_config/configitems/simpleunit.rb +0 -53
  44. data/lib/module_config/configs.test +0 -24
  45. data/lib/module_config/tmp +0 -3
  46. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configexception_rb.html +0 -647
  47. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complex_rb.html +0 -700
  48. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexpackage_rb.html +0 -694
  49. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexunit_rb.html +0 -704
  50. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simple_rb.html +0 -685
  51. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simplepackage_rb.html +0 -676
  52. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simpleunit_rb.html +0 -682
  53. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-item_rb.html +0 -663
  54. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-itemfactory_rb.html +0 -687
  55. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-myconfig_rb.html +0 -687
  56. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-section_rb.html +0 -692
  57. data/lib/module_config/unittests/coverage/index.html +0 -689
  58. data/lib/module_fhlow/leaf.rb~ +0 -202
  59. data/lib/module_fhlow/test.rb +0 -15
@@ -25,7 +25,7 @@ Dir.glob(detectFhlowRootDir+"flw/core/lib/module_*") { |entry| $:.unshift(entry)
25
25
  #######################################################################################
26
26
 
27
27
  require 'test/unit'
28
- require 'myconfig'
28
+ require 'config'
29
29
  require 'configitems/simple'
30
30
  require 'configitems/simpleunit'
31
31
  require 'configitems/simplepackage'
@@ -81,9 +81,6 @@ class TC_config_test < Test::Unit::TestCase
81
81
 
82
82
  assert_equal(s1.value, s.value)
83
83
 
84
- assert_equal(/^\s*(\w+)\s*=\s*([\w,.;\s]+)\s*$/, Config::Simple.getRegex())
85
-
86
-
87
84
  str = "ComplexUnits = {
88
85
  1,2,3(bla);
89
86
  4,5,6(bhv)
@@ -370,11 +367,13 @@ class TC_config_test < Test::Unit::TestCase
370
367
  s2 = nil
371
368
 
372
369
  assert_nothing_raised() do
373
- s = Config::ComplexPackage.new("ComplexPackageThing = { No; thing }")
370
+ s = Config::ComplexPackage.new("ComplexPackageThing = { No; th, ing }")
374
371
  s1 = Config::ComplexPackage.new("ComplexPackageThing = { Other; Value }")
375
372
  s2 = Config::ComplexPackage.new("12Package34 = { 1; 2; 3; 4 }")
376
373
  end
377
374
 
375
+ assert_equal([["No"], ["th","ing"]], s.value)
376
+
378
377
  assert_raise(Config::ConfigMergeException) do
379
378
  s.merge(s2)
380
379
  end
@@ -383,11 +382,9 @@ class TC_config_test < Test::Unit::TestCase
383
382
  s.merge(s1)
384
383
  end
385
384
 
386
- assert_equal(["Other", "Value", "No", "thing"], s.value)
385
+ assert_equal([["Other"], ["Value"], ["No"], ["th", "ing"]], s.value)
387
386
 
388
- assert_equal(/(\w*Package\w*)\s*=(\s*|[\n]*)\{((\s*[^\(\)]*[;][\s\n]*)*(\s*[^\(\)]*[;]*[\s\n]*))\}/, Config::ComplexPackage.getRegex())
389
387
 
390
-
391
388
  str = "ComplexUnits = {
392
389
  1,2,3(bla);
393
390
  4,5,6(bhv)
@@ -463,14 +460,20 @@ class TC_config_test < Test::Unit::TestCase
463
460
  s.merge(s1)
464
461
  end
465
462
 
466
- assert_equal([ {"archs"=>["bhv", "bla", "123"], "deppath"=>"Other, Value"},
467
- {"archs"=>["arch"], "deppath"=>"No"},
468
- {"archs"=>["itecture"], "deppath"=>"thing"}],
463
+ assert_equal([ {"archs"=>["bhv", "bla", "123"], "deppath"=>["Other", "Value"]},
464
+ {"archs"=>["arch"], "deppath"=>["No"]},
465
+ {"archs"=>["itecture"], "deppath"=>["thing"]}],
469
466
  s.value)
470
467
 
471
- assert_equal(/(\w*Unit\w*)\s*=(\s*|[\n]*)\{((\s*.*[;][\s\n]*)*(\s*.*\(.*\)[;]*[\s\n]*))\}/, Config::ComplexUnit.getRegex())
468
+ puts
469
+ p s.value
470
+ puts
472
471
 
472
+ s.merge(Config::ComplexUnit.new("ComplexUnitThing = { No(aasrch); thing(itecture) }"))
473
473
 
474
+ p s.value
475
+ puts
476
+
474
477
  str = "ComplexUnits = {
475
478
  1,2,3(bla);
476
479
  4,5,6(bhv)
@@ -82,12 +82,19 @@ module Fhlow
82
82
  if @conf["Dependencies"].nil?
83
83
  raise FhlowException.new(getPath, "Couldn't find section [Dependencies] in any config.flw file responsible for this leaf.")
84
84
  end
85
-
85
+
86
86
  # iterate through all items of the [Dependencies] section
87
87
  @conf["Dependencies"].each do |item| # item -> one item of the [Dependencies] section
88
88
  fetchOneDependency(item)
89
89
  end
90
-
90
+
91
+
92
+ # there needs to be a target section the config file
93
+ if @conf["Target"+@conf["Target"]["Target"]].nil?
94
+ raise FhlowException.new(getPath, "Couldn't find section [Target#{@conf["Target"]["Target"]}] in any config.flw file responsible for this leaf.")
95
+ end
96
+ fetchOneDependency(@conf["Target"+@conf["Target"]["Target"]].getItem("SimulationLibraries"))
97
+
91
98
  dummy = ""
92
99
  @dependencies.each{ |deptype, leafs| dummy += "#{deptype} -> "; leafs.each { |leaf| dummy += "#{leaf.prefix}#{leaf.name} "}; dummy += "; " }
93
100
  @log.debug(@prefix+@name, "direct dependencies: #{dummy}")
@@ -121,7 +128,7 @@ module Fhlow
121
128
  @dependencies[_item.name].push(leaf) unless @dependencies[_item.name].include?(leaf)
122
129
  end
123
130
 
124
- elsif _item.instance_of?(Config::ComplexPackage)
131
+ elsif _item.instance_of?(Config::ComplexPackage) or _item.instance_of?(Config::ComplexLibrary)
125
132
  _item.value.each do |value|
126
133
  begin
127
134
  leaf = @parent.getLeaf(value, value.length-1)
@@ -130,7 +137,9 @@ module Fhlow
130
137
  # fetch the exception and add the name of this leaf so the errormessage is more accurate
131
138
  raise FhlowObjectNotFoundException.new(@prefix+@name), "#{e.caller}: #{e.message}"
132
139
  end
133
-
140
+
141
+
142
+
134
143
  # init the container if it is nil
135
144
  @dependencies[_item.name] = Array.new if @dependencies[_item.name].nil?
136
145
 
@@ -142,13 +151,6 @@ module Fhlow
142
151
 
143
152
 
144
153
 
145
- =begin def fetchOneDependency(_name, _value)
146
- # this funktion needs to be implemented in an derived class!
147
- raise FhlowException.new(self.class), "fetchOneDependency() is not implemented for "+self.class.to_s
148
- end
149
- =end
150
-
151
-
152
154
  # This function returns an Array of filenames in respect of the dependency tree and needs to be implemented
153
155
  # by subclasses.
154
156
  # +_deptype+:: Type of the requested dependencies (could be Units, BhvUnits, Packages and so on)
@@ -170,19 +172,9 @@ module Fhlow
170
172
  # +_prefix+:: This prefix will be added to the output of ths function.
171
173
  # +_depth+:: The depth of the recursion.
172
174
  # +_caller+:: The reference to the caller.
173
- # == TODO
174
- # in die konkreten leafs auslagern
175
175
  def printMe(_prefix=" ", _depth=0, _caller=nil)
176
-
177
- if self.instance_of?(Unit)
178
- str = ""
179
- @pen.puts _prefix, @pen.magenta, @prefix, @name, @pen.clear,
180
- @architectures[_depth==0 ? self : _caller].nil? ?
181
- "\n" :
182
- "( "+(@architectures[_depth==0 ? self : _caller].each { |key, value| str += "#{@pen.blue}#{key}#{@pen.clear} -> #{value.join(", ")}; " }; str+=")")
183
- else
184
- @pen.print _prefix, @pen.yellow, @prefix, @name, @pen.clear, "\n"
185
- end
176
+
177
+ self.print(_prefix, _depth, _caller)
186
178
 
187
179
  @dependencies.each do |deptype, leafs|
188
180
  leafs.each { |leaf| leaf.printMe(_prefix+" ", _depth+1, self) }
@@ -191,7 +183,19 @@ module Fhlow
191
183
  @pen.print "\n" if _depth == 0
192
184
 
193
185
  end
194
-
186
+
187
+ def getTarget(_itemname)
188
+ if _itemname == "Name"
189
+ "Target#{@conf["Target"]["Target"]}"
190
+ else
191
+ @conf["Target#{@conf["Target"]["Target"]}"][_itemname]
192
+ end
193
+ end
194
+
195
+ private
196
+ def print(_prefix=" ", _depth=0, _caller=nil)
197
+ raise FhlowException.new(self.class), "print() is not implemented for "+self.class.to_s
198
+ end
195
199
  end
196
200
 
197
201
  end
@@ -0,0 +1,60 @@
1
+ require 'leaf'
2
+ require 'leaffactory'
3
+
4
+ module Fhlow
5
+
6
+ # This is a concrete implementation of the abstract class Leaf. A Library represents one Leaf
7
+ # with the prefix "lib".
8
+ class Library < Leaf
9
+
10
+ # Calls the constructor of Leaf.
11
+ # +_name+:: The Name of the Leaf.
12
+ # +_parent+:: The reference to the parent.
13
+ # +_conf+:: The configuration information from higher levels.
14
+ # +_log+:: The reference to the Log object.
15
+ # +_pen+:: The reference to a Pen object.
16
+ def initialize(_name, _parent, _log, _pen)
17
+ super("lib", _name, _parent, _log, _pen)
18
+ end
19
+
20
+ # This function returns an Array of filenames in respect of the dependency tree.
21
+ # +_deptype+:: Type of the requested dependencies (could be Units, BhvUnits, Librarys and so on)
22
+ # +_istoplevel+:: Is used to indicate the first entrance to this function.
23
+ # +_caller+:: Reference to the caller of the function. This is needed to request architectures.
24
+ # +_files+:: The Array of the files which will be filled with the requested filenames and returned in the end.
25
+ def getFiles(_deptype, _istoplevel=true, _caller=nil, _files=Array.new)
26
+ @dependencies[_deptype].each { |dep| dep.getFiles(_deptype, false, self, _files)} unless @dependencies[_deptype].nil?
27
+
28
+ # only act if Libraries are needed
29
+ case _deptype
30
+ when "SimulationLibraries", "Libraries"
31
+ _files.push( { @name => @conf["Self"]["Files"].collect { |file| getPath+"src/"+file } } )
32
+ end
33
+ end
34
+
35
+ def print(_prefix=" ", _depth=0, _caller=nil)
36
+ # TODO: find a way to print only [Dependencies] -> Libraries without [Target*] -> SimulationLibraries
37
+ #@pen.print _prefix, @pen.yellow, @prefix, @name, @pen.clear, "\n"
38
+ end
39
+
40
+ end
41
+
42
+ # This is a concrete implementation of the _abstract_ class LeafFactory .
43
+ # A LibraryFactory creates objects of Unit.
44
+ class LibraryFactory < LeafFactory
45
+
46
+ # Return the prefix used by Units.
47
+ def LibraryFactory.getPrefix()
48
+ return "lib"
49
+ end
50
+
51
+ # Creates objects of Unit.
52
+ # +*_args+:: Array of argumens passed to the constructor of Unit. See Unit.initialize for more details.
53
+ def create(*_args)
54
+ return Library.new(*_args)
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
@@ -23,7 +23,7 @@ module Fhlow
23
23
  # +_caller+:: Reference to the caller of the function. This is needed to request architectures.
24
24
  # +_files+:: The Array of the files which will be filled with the requested filenames and returned in the end.
25
25
  def getFiles(_deptype, _istoplevel=true, _caller=nil, _files=Array.new)
26
- @dependencies.values.each { |v| v.each { |dep| dep.getFiles(_deptype, false, self, _files)} } unless @dependencies.nil?
26
+ @dependencies[_deptype].each { |dep| dep.getFiles(_deptype, false, self, _files)} unless @dependencies[_deptype].nil?
27
27
 
28
28
  # only act if Packages are needed
29
29
  if _deptype == "Packages"
@@ -31,6 +31,9 @@ module Fhlow
31
31
  end
32
32
  end
33
33
 
34
+ def print(_prefix=" ", _depth=0, _caller=nil)
35
+ @pen.print _prefix, @pen.lightyellow, @prefix, @name, @pen.clear, "\n"
36
+ end
34
37
 
35
38
  end
36
39
 
@@ -66,7 +66,7 @@ module Fhlow
66
66
  # * file not found exception::
67
67
  # * -e -ea -eac -ac handling::
68
68
  def getFiles(_deptype, _istoplevel=true, _caller=nil, _files=Array.new)
69
- @dependencies.values.each { |v| v.each { |dep| dep.getFiles(_deptype, false, self, _files)} } unless @dependencies.nil?
69
+ @dependencies[_deptype].each { |dep| dep.getFiles(_deptype, false, self, _files)} unless @dependencies[_deptype].nil?
70
70
 
71
71
  # only act if the Unit is able to handle the _deptype
72
72
  case _deptype
@@ -125,6 +125,14 @@ module Fhlow
125
125
  @architectures[_owner][_deptype] = @architectures[_owner][_deptype].uniq
126
126
  end
127
127
 
128
+
129
+ def print(_prefix=" ", _depth=0, _caller=nil)
130
+ str = ""
131
+ @pen.puts _prefix, @pen.magenta, @prefix, @name, @pen.clear,
132
+ @architectures[_depth==0 ? self : _caller].nil? ?
133
+ "\n" :
134
+ "( "+(@architectures[_depth==0 ? self : _caller].each { |key, value| str += "#{@pen.blue}#{key}#{@pen.clear} -> #{value.join(", ")}; " }; str+=")")
135
+ end
128
136
 
129
137
 
130
138
 
@@ -50,7 +50,7 @@ module Fhlow
50
50
  # +_nodelevel+:: The level of the Node inside the fhlow structure.
51
51
  # +_log+:: Reference to a Log object.
52
52
  # +_pen+:: Reference to a Pen obejct (output to console).
53
- def initialize(_prefix, _name, _parent, _nodelevel, _log, _pen)
53
+ def initialize(_prefix, _name, _parent, _nodelevel, _log, _pen, _defaultconf=_parent.conf)
54
54
  @prefix = _prefix
55
55
  @name = _name
56
56
 
@@ -65,12 +65,12 @@ module Fhlow
65
65
  @parent = _parent
66
66
  @log = _log
67
67
  @pen = _pen
68
-
68
+
69
69
  if File.exist?(@parent.getPath+@prefix+@name+"/config.flw")
70
70
  # read the config file
71
71
  @conf = Config::Config.new(@parent.getPath+@prefix+@name+"/config.flw")
72
72
  # inherit the configurations from previous levels
73
- @conf.merge(@parent.conf)
73
+ @conf.merge(_defaultconf)
74
74
  @log.debug(@prefix+@name, "Sucessfully merged inherited configs from #{@parent.prefix+@parent.name}.")
75
75
  else
76
76
  @log.warning(self, "config.flw does not exists in #{@prefix}#{@name}.")
@@ -83,7 +83,6 @@ module Fhlow
83
83
 
84
84
  @log.info(@prefix+@name, "initializing node...")
85
85
 
86
-
87
86
  if @nodelevel < @conf["fhlow"]["NodePrefixes"].length
88
87
 
89
88
  # add the nodes
@@ -181,7 +180,7 @@ module Fhlow
181
180
  else
182
181
  possibilities = Array.new
183
182
  @leafs.each_key { |leafname| possibilities.push(leafname) if leafname =~ /.*#{_objectfootprint[0]}/ }
184
- raise FhlowObjectNotFoundException.new(@prefix+@name), "There are multible possibilities for leaf #{_objectfootprint[0]}: "+posssibilities.join(", ") if possibilities.length > 1
183
+ raise FhlowObjectNotFoundException.new(@prefix+@name), "There are multible possibilities for leaf #{_objectfootprint[0]}: "+possibilities.join(", ") if possibilities.length > 1
185
184
  raise FhlowObjectNotFoundException.new(@prefix+@name), "No such node <"+(possibilities.empty? ? _objectfootprint[0].to_s : possibilities[0].to_s)+">!" unless @leafs[possibilities[0]]
186
185
  return @leafs[possibilities[0]] # finally the object can be returned
187
186
  end
@@ -18,6 +18,9 @@ module Fhlow
18
18
  @actualLeaf = _actualLeaf
19
19
  @cmd = CmdParse::Command.new(self.class.to_s, true, true)
20
20
  @cmd.pen = @pen
21
+ @target = "Target"+@actualLeaf.conf["Target"]["Target"]
22
+ @varDir = @actualLeaf.getPath+"var/#{self.class.to_s}/"
23
+ @shareDir = @actualLeaf.getPath+"var/share/"
21
24
  end
22
25
 
23
26
  # Describes the Plugins main command. The name of the main command
@@ -48,6 +51,14 @@ module Fhlow
48
51
  @cmd.add_command(subcmd)
49
52
  end
50
53
 
54
+ def runInVarDir(&_block)
55
+ Dir.chdir(@varDir, &_block)
56
+ end
57
+
58
+ def runInShareDir(&_block)
59
+ Dir.chdir(@shareDir, &_block)
60
+ end
61
+
51
62
  end
52
63
 
53
64
  end
@@ -27,7 +27,7 @@ module Fhlow
27
27
 
28
28
  # A Pluginpool is a container that loads, initializes and stores references to
29
29
  # the loaded plugins.
30
- class Pluginpool
30
+ class PluginPool
31
31
 
32
32
  # Loads and initializes the loaded plugins.
33
33
  # +_plugindir+:: The direcotry where the plugins can be found.
@@ -41,15 +41,14 @@ module Fhlow
41
41
  @plugindir = _plugindir
42
42
  @actualLeaf = _actualLeaf
43
43
 
44
-
45
- Dir.glob(@plugindir+"*.rb").each do |plugin|
44
+ Dir.glob(@plugindir + "*.rb").each do |plugin|
46
45
 
47
46
  pluginname = File.basename(plugin, ".rb").capitalize
48
-
47
+
49
48
  require plugin
50
49
 
51
50
  @pool.push(Kernel.const_get(pluginname).new(@actualLeaf, @pen, @log))
52
- @log.info(self, "loaded plugin "+plugin)
51
+ @log.info(self.class, "loaded plugin "+plugin)
53
52
  end
54
53
 
55
54
  end
@@ -75,6 +74,19 @@ module Fhlow
75
74
  @pool.each(&_block)
76
75
  end
77
76
 
77
+ def PluginPool.each_configfile(_plugindir, &_block)
78
+ Dir.glob(_plugindir+"*.rb").each do |plugin|
79
+
80
+ pluginname = File.basename(plugin, ".rb").capitalize
81
+
82
+ if File.exist?(_plugindir+pluginname+".flw")
83
+ _block.call(_plugindir+pluginname+".flw")
84
+ else
85
+ raise Fhlow::FhlowException.new(pluginname), "Does not provide its default configuration file: "+ @plugindir + pluginname +".flw"
86
+ end
87
+ end
88
+ end
89
+
78
90
  end
79
91
 
80
92
  end
@@ -37,17 +37,17 @@ module Fhlow
37
37
  #
38
38
  def initialize(_defaultconf, _log, _pen, _path=RootNode.detectFhlowRootDir)
39
39
 
40
+ @path = _path
41
+
40
42
  # don't do anything if _path is nil
41
43
  raise FhlowException.new(self.class), "Couldn't detect the fhlow root directory!" if _path.nil?
42
44
  raise FhlowException.new(self.class), "You have to provide a default configuration object!" if !_defaultconf.instance_of?(Config::Config)
43
45
 
44
- @path = _path
45
- @conf = _defaultconf
46
46
 
47
47
  # load all the leaf classes
48
48
  LeafFactory.load(@path+"/flw/core/lib/module_fhlow/leafs/")
49
49
 
50
- super("", "RootNode", self, 0, _log, _pen)
50
+ super("", "", self, 0, _log, _pen, _defaultconf)
51
51
 
52
52
  @nodes.each_value { |node| node.fetchDependencies() }
53
53
 
@@ -87,6 +87,7 @@ module Fhlow
87
87
  # the string provided by 'Dir.pwd'.
88
88
  # +_dir+:: The directory that will be used to find the fhlow root directory.
89
89
  def RootNode.detectFhlowRootDir(_dir=Dir.pwd)
90
+ raise FhlowException.new(self.class), "Couldn't detect the fhlow root directory!" if _dir==""
90
91
  if Dir.entries(_dir).include?("flw")
91
92
  return _dir+"/"
92
93
  else
@@ -0,0 +1,18 @@
1
+ [Modelsim]
2
+ # BinDir = /opt/eda/questasim/bin/
3
+ # LicenseFile = 7418@thor:8224@thor:27000@thor:1816@thor:7450@thor
4
+ BinDir =
5
+ LicenseFile =
6
+
7
+ CompileQuiet = false
8
+ CompileOptions = -93
9
+ CompileBuildAll = false
10
+
11
+ SimulateRun = 100 ns
12
+ SimulateConsole = false
13
+ SimulateOptions =
14
+
15
+ PostLayoutSimSDF = min
16
+ PostLayoutSimTbLabel = DUT
17
+
18
+
@@ -0,0 +1,331 @@
1
+ #----------------------------------------------------------------------------
2
+ #
3
+ # Copyright (C) 2007 Simon Lasselsberger
4
+ # simon.lasselsberger@fh-hagenberg.at
5
+ #
6
+ # This file is part of the _fhlow_ scripting environment.
7
+ #
8
+ # The _fhlow_ scripting environment is free software; you can redistribute
9
+ # it and/or modify it under the terms of the GNU General Public License
10
+ # as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # _fhlow_ is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with _fhlow_; if not, write to the Free Software
20
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
+ #
22
+ #----------------------------------------------------------------------------
23
+
24
+ require 'plugin'
25
+ require 'fileutils'
26
+ require 'fhlowexception'
27
+
28
+ class Modelsim < Fhlow::Plugin
29
+
30
+ def initialize(_actualLeaf, _pen, _log)
31
+ super(_actualLeaf, _pen, _log)
32
+
33
+ @vcom_options = []
34
+ @vsim_options = []
35
+
36
+ # default settings
37
+ @vcom_options = @actualLeaf.conf["Modelsim"]["CompileOptions"].split(/\s/)
38
+ if @actualLeaf.conf["Modelsim"]["CompileQuiet"] == true
39
+ @vcom_options.push("-quiet") unless @vcom_options.include?("-quiet")
40
+ end
41
+
42
+ @vsim_simtime = @actualLeaf.conf["Modelsim"]["SimulateRun"]
43
+ @vsim_options.push(@actualLeaf.conf["Modelsim"]["SimulateOptions"])
44
+ @vsim_options.push("-c") if @actualLeaf.conf["Modelsim"]["SimulateConsole"]=="true"
45
+ @buildall = @actualLeaf.conf["Modelsim"]["CompileBuildAll"] == "true"
46
+
47
+ @vsim_sdf = @actualLeaf.conf["Modelsim"]["PostLayoutSimSDF"]
48
+ @vsim_tblabel = @actualLeaf.conf["Modelsim"]["PostLayoutSimTbLabel"]
49
+
50
+ # this functioncall is optional
51
+ describeCmd("Plugin vor Modelsim.",
52
+ "Supported versions: Modelsim 6.1 b")
53
+
54
+
55
+ # --- compile ---
56
+ # create an options object
57
+ compileoptions = CmdParse::OptionParserWrapper.new do |opt|
58
+ opt.separator "<compile-options>:"
59
+ opt.on("-q", "--quiet", "Make vcom quiet.") { @vcom_options.push("-quiet") unless @vcom_options.include?("-quiet") }
60
+ opt.on("-o", "--options VAL", "Options that will be passed to vcom") { |val| @vcom_options.push(val) }
61
+ opt.on("-b", "--buildall", "Rebuilds all sources and libraries.") { @buildall = true }
62
+ end
63
+
64
+ # register the subcommand
65
+ registerSubCmd(
66
+ "compile", # name of the subcmd
67
+ "Compiles the configured sources.", # short description (optional)
68
+ "Compiles the configured sources.", # description (optional)
69
+ compileoptions # the option object (optional)
70
+ ) { compile() } # the action which should be run when this subcmd is invoked
71
+
72
+ # --- simulate ---
73
+ # create an options object
74
+ simulationoptions = CmdParse::OptionParserWrapper.new do |opt|
75
+ opt.separator "<simlation-options>:"
76
+ opt.on("-r", "--run TIME", "Simulation time. Format: \"<value> [ms|us|ns|ps]\"") do |time|
77
+ if time =~ /\d+[ ](ms|us|ns|ps)/
78
+ @vsim_simtime = time
79
+ else
80
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "Simulation time has wrong format: #{time}"
81
+ end
82
+ end
83
+ opt.on("-c", "--console", "Run simulation in console. Do not start GUI.") { @vsim_options.push("-c") }
84
+ opt.on("-o", "--options VAL", "Options that will be passed to vsim.") { |val| @vsim_options.push(val) }
85
+ opt.on("-q", "--quiet", "Make vcom quiet.") { @vcom_options.push("-quiet") unless @vcom_options.include?("-quiet") }
86
+ opt.on("-b", "--buildall", "Rebuilds all sources and libraries.") { @buildall = true }
87
+ end
88
+
89
+ # register the subcommand
90
+ registerSubCmd(
91
+ "simulate", # name of the subcmd
92
+ "Simulates the design.", # short description (optional)
93
+ "Simulates the design.", # description (optional)
94
+ simulationoptions # the option object (optional)
95
+ ) { simulate() } # the action which should be run when this subcmd is invoked
96
+
97
+ # --- post layout simulation ---
98
+ # create an options object
99
+ plsimoptions = CmdParse::OptionParserWrapper.new do |opt|
100
+ opt.separator "<plsim-options>:"
101
+ opt.on("-r", "--run TIME", "Simulation time. Format: \"<value> [ms|us|ns|ps]\"") do |time|
102
+ if time =~ /\d+[ ](ms|us|ns|ps)/
103
+ @vsim_simtime = time
104
+ else
105
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "Simulation time has wrong format: #{time}"
106
+ end
107
+ end
108
+ opt.on("-c", "--console", "Run simulation in console. Do not start GUI.") { @vsim_options.push("-c") }
109
+ opt.on("-o", "--options VAL", "Options that will be passed to vsim.") { |val| @vsim_options.push(val) }
110
+ opt.on("-b", "--buildall", "Rebuilds all sources and libraries.") { @buildall = true }
111
+ end
112
+
113
+ # register the subcommand
114
+ registerSubCmd(
115
+ "plsim", # name of the subcmd
116
+ "Runs post layout simulation of the synthesized design.", # short description (optional)
117
+ "Runs post layout simulation of the synthesized design.", # description (optional)
118
+ plsimoptions # the option object (optional)
119
+ ) { plsim() } # the action which should be run when this subcmd is invoked
120
+
121
+
122
+
123
+
124
+ end
125
+
126
+
127
+ def compile()
128
+ initWork()
129
+
130
+ @pen.puts
131
+ @actualLeaf.printMe
132
+ width = 87
133
+
134
+ @pen.seperator
135
+
136
+ begin
137
+ @pen.print ",", "-"*width,"+\n"
138
+ @pen.print "|", " Compilation".ljust(width), "|\n"
139
+ @pen.print "+", "-"*width,"+\n"
140
+
141
+ unless @actualLeaf.getFiles("Libraries").empty?
142
+ @pen.puts "| Libraries:"
143
+ @actualLeaf.getFiles("Libraries").each do |libhash|
144
+ libhash.each do |libname, files|
145
+ if @buildall or !File.directory?(@varDir+libname)
146
+ @pen.puts "| Library: #{libname}"
147
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vlib #{@varDir}#{libname}` }
148
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vmap #{libname} #{@varDir}#{libname}` }
149
+
150
+ files.each do |f|
151
+ msg = callVcom(f)
152
+ printFile(f, $? == 0, @pen.yellow)
153
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
154
+ end
155
+ else
156
+ @pen.puts "| Library: #{libname} exists, skipping (use --buildall to rebuild)"
157
+ end
158
+ end
159
+ end
160
+ @pen.print "+", "-"*width,"+\n"
161
+ end
162
+
163
+ @pen.puts "| Packages:"
164
+ @actualLeaf.getFiles("Packages").each do |f|
165
+ msg = callVcom(f)
166
+ printFile(f, $? == 0, @pen.lightyellow)
167
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
168
+ end
169
+
170
+
171
+ @pen.print "+", "-"*width,"+\n"
172
+ @pen.puts "| Units:"
173
+ @actualLeaf.getFiles("Units").each do |f|
174
+ msg = callVcom(f)
175
+ printFile(f, $? == 0, @pen.magenta)
176
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
177
+ end
178
+
179
+ @pen.print "+", "-"*width,"+\n"
180
+ @pen.puts "| BhvUnits:"
181
+ @actualLeaf.getFiles("BhvUnits").each do |f|
182
+ msg = callVcom(f)
183
+ printFile(f, $? == 0, @pen.magenta)
184
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
185
+ end
186
+
187
+ @pen.print "+", "-"*width,"+\n"
188
+ @pen.puts "| tbUnits:"
189
+ @actualLeaf.getFiles("tbUnits").each do |f|
190
+ msg = callVcom(f)
191
+ printFile(f, $? == 0, @pen.magenta)
192
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
193
+ end
194
+
195
+ ensure
196
+ @pen.print "`", "-"*width,"+\n"
197
+ end
198
+ end
199
+
200
+
201
+
202
+
203
+ def simulate()
204
+ compile
205
+ @pen.seperator
206
+ ENV["LM_LICENSE_FILE"] = @actualLeaf.conf["Modelsim"]["LicenseFile"]
207
+ @log.debug("Modelsim", "Setting environment variable LM_LICENSE_FILE to #{@actualLeaf.conf["Modelsim"]["LicenseFile"]}")
208
+ @pen.puts "Running Modelsim:"
209
+ instruction = "#{@actualLeaf.conf["Modelsim"]["BinDir"]}vsim work.tb#{@actualLeaf.name} "
210
+ instruction += "#{@vsim_options.join(" ")} "
211
+ instruction += "-do \"source #{@actualLeaf.getPath}src/wave.do; run #{@vsim_simtime}; #{ @vsim_options.include?("-c") ? 'exit' : ''}\" "
212
+ instruction += "2>&1"
213
+ msg = ""; runInVarDir { msg = `#{instruction}` }
214
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors during simulation!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
215
+ @pen.puts msg
216
+ end
217
+
218
+
219
+ def plsim()
220
+ width = 87
221
+ @pen.print ",", "-"*width,"+\n"
222
+ @pen.print "|", " Compilation".ljust(width), "|\n"
223
+ @pen.print "+", "-"*width,"+\n"
224
+
225
+ begin
226
+ @pen.puts "| SimulationLibraries of #{@actualLeaf.getTarget("Name")}:"
227
+ @actualLeaf.getFiles("SimulationLibraries").each do |libhash|
228
+ libhash.each do |libname, files|
229
+ if @buildall or !File.directory?(@varDir+libname)
230
+ @pen.puts "| Library: #{libname}"
231
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vlib #{@varDir}#{libname}` }
232
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vmap #{libname} #{@varDir}#{libname}` }
233
+
234
+ files.each do |f|
235
+ msg = callVcom(f, libname)
236
+ printFile(f, $? == 0, @pen.yellow)
237
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
238
+ end
239
+ else
240
+ @pen.puts "| Library: #{libname} exists, skipping (use --buildall to rebuild)"
241
+ end
242
+ end
243
+ end
244
+
245
+ @pen.print "+", "-"*width,"+\n"
246
+
247
+ @pen.puts "| Netlist:"
248
+ f = @shareDir+"net#{@actualLeaf.name}-#{@actualLeaf.getArchitectures(@actualLeaf)["Units"][0]}-ea.vhd"
249
+ msg = callVcom(f)
250
+ printFile(f, $? == 0, @pen.magenta)
251
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
252
+
253
+ @pen.print "+", "-"*width,"+\n"
254
+ @pen.puts "| Packages:"
255
+ @actualLeaf.getFiles("Packages").each do |f|
256
+ msg = callVcom(f)
257
+ printFile(f, $? == 0, @pen.yellow)
258
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
259
+ end
260
+
261
+
262
+ @pen.print "+", "-"*width,"+\n"
263
+ @pen.puts "| BhvUnits:"
264
+ @actualLeaf.getFiles("BhvUnits").each do |f|
265
+ msg = callVcom(f)
266
+ printFile(f, $? == 0, @pen.magenta)
267
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
268
+ end
269
+
270
+ @pen.print "+", "-"*width,"+\n"
271
+ @pen.puts "| tbUnits:"
272
+ @actualLeaf.getFiles("tbUnits").each do |f|
273
+ msg = callVcom(f)
274
+ printFile(f, $? == 0, @pen.magenta)
275
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors while compiling #{f}!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
276
+ end
277
+
278
+
279
+ ensure
280
+ @pen.print "`", "-"*width,"+\n"
281
+ end
282
+
283
+ @pen.seperator
284
+ @pen.puts "Running post layout simulation with Modelsim:"
285
+
286
+ ENV["LM_LICENSE_FILE"] = @actualLeaf.conf["Modelsim"]["LicenseFile"]
287
+ @log.debug("Modelsim", "Setting environment variable LM_LICENSE_FILE to #{@actualLeaf.conf["Modelsim"]["LicenseFile"]}")
288
+
289
+ instruction = "#{@actualLeaf.conf["Modelsim"]["BinDir"]}vsim work.tb#{@actualLeaf.name} "
290
+ instruction += "#{@vsim_options.join(" ")} "
291
+ instruction += "-do \"source #{@actualLeaf.getPath}src/wave.do; run #{@vsim_simtime}; #{ @vsim_options.include?("-c") ? 'exit' : ''}\" "
292
+ instruction += "-sdfmax /DUT=#{@shareDir}/#{@actualLeaf.name}.sdf -noglitch -t ps "
293
+ instruction += "2>&1"
294
+
295
+ msg = ""; runInVarDir { msg = `#{instruction}` }
296
+ raise Fhlow::FhlowPluginException.new("Modelsim"), "There were some errors during simulation!\n Message from Modelsim:\n-----\n#{msg}\n-----" if $? != 0
297
+
298
+ @pen.print msg
299
+
300
+ end
301
+
302
+
303
+
304
+ # --- some private helper functions ---
305
+ private
306
+ def printFile(_file, _ok, _color, _width=90)
307
+ if _ok == true or _ok == false
308
+ @pen.puts "| [ ", _ok ? @pen.lightgreen+"ok "+@pen.clear : @pen.lightred+"failed "+@pen.clear, " ] ", _color, _file, @pen.clear
309
+ else
310
+ @pen.puts "| [ ", _ok, " ] ", _color, _file, @pen.clear
311
+ end
312
+ end
313
+
314
+
315
+ def initWork(_dir=@varDir)
316
+ FileUtils.rm_r(_dir+"work") if File.directory?(_dir+"work")
317
+ FileUtils.makedirs(_dir)
318
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vlib #{_dir}work` }
319
+ runInVarDir { `#{@actualLeaf.conf["Modelsim"]["BinDir"]}vmap work #{_dir}work` }
320
+ end
321
+
322
+
323
+ def callVcom(_file, _lib="work")
324
+ instruction = "#{@actualLeaf.conf["Modelsim"]["BinDir"]}vcom #{@vcom_options.join(" ")} -work #{@varDir}#{_lib} #{_file} "
325
+ instruction += "2>&1"
326
+ @log.debug("Modelsim", "Running vcom: #{instruction}")
327
+ runInVarDir { `#{instruction}` }
328
+ end
329
+
330
+
331
+ end