soc_maker 0.1.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 (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/History.txt +4 -0
  4. data/LICENSE +678 -0
  5. data/README.rdoc +228 -0
  6. data/Rakefile +46 -0
  7. data/bin/soc_maker_cli +80 -0
  8. data/bin/soc_maker_parser +85 -0
  9. data/core_lib/cores/adv_debug_sys/01_adv_debug_sys.yaml +245 -0
  10. data/core_lib/cores/or1200_rel2/01_or1200.yaml +208 -0
  11. data/core_lib/cores/or1200_rel2/02_or1200_files.yaml +421 -0
  12. data/core_lib/cores/or1200_rel2/03_or1200_sparam.yaml +188 -0
  13. data/core_lib/cores/or1200_rel2/or1200_defines.v.in +1799 -0
  14. data/core_lib/cores/ram_wb/ram_wb.yaml +102 -0
  15. data/core_lib/cores/ram_wb/ram_wb_b3.v.in +259 -0
  16. data/core_lib/cores/uart16550/01_uart16550.yaml +99 -0
  17. data/core_lib/cores/uart16550/02_uart16550_files.yaml +70 -0
  18. data/core_lib/cores/wb_connect/minsoc_tc_top.v +1802 -0
  19. data/core_lib/cores/wb_connect/wb_connect.yaml +733 -0
  20. data/core_lib/inc.yaml +13 -0
  21. data/core_lib/interfaces/clk_rst/clk.yaml +9 -0
  22. data/core_lib/interfaces/clk_rst/rst.yaml +9 -0
  23. data/core_lib/interfaces/clk_rst/single.yaml +7 -0
  24. data/core_lib/interfaces/debug/debug.yaml +32 -0
  25. data/core_lib/interfaces/jtag/jtag.yaml +13 -0
  26. data/core_lib/interfaces/jtag/jtag_tap.yaml +22 -0
  27. data/core_lib/interfaces/power/or_power.yaml +25 -0
  28. data/core_lib/interfaces/uart/uart.yaml +21 -0
  29. data/core_lib/interfaces/wishbone/wishbone_ma_b3.yaml +54 -0
  30. data/core_lib/interfaces/wishbone/wishbone_sl_b3.yaml +51 -0
  31. data/doc/class_arch.uml +5113 -0
  32. data/doc/fig/hierarchical.svg +273 -0
  33. data/examples/or1200_test/or1200_test.cmd +78 -0
  34. data/examples/or1200_test/or1200_test.rb +136 -0
  35. data/examples/or1200_test/rtl/or1200_test_top.vhd +274 -0
  36. data/examples/or1200_test/rtl/s3astarter.ucf +10 -0
  37. data/examples/or1200_test/rtl/xilinx_internal_jtag.v +438 -0
  38. data/examples/or1200_test/rtl/xilinx_internal_jtag_options.v +12 -0
  39. data/examples/or1200_test/sw/README.txt +35 -0
  40. data/examples/or1200_test/sw/bin2vmem.c +159 -0
  41. data/examples/or1200_test/sw/board.h +24 -0
  42. data/examples/or1200_test/sw/compile.sh +18 -0
  43. data/examples/or1200_test/sw/except.S +152 -0
  44. data/examples/or1200_test/sw/int.c +79 -0
  45. data/examples/or1200_test/sw/int.h +14 -0
  46. data/examples/or1200_test/sw/interconnect.h +17 -0
  47. data/examples/or1200_test/sw/interrupts.c +14 -0
  48. data/examples/or1200_test/sw/main.c +16 -0
  49. data/examples/or1200_test/sw/or1200.h +454 -0
  50. data/examples/or1200_test/sw/orp.ld +60 -0
  51. data/examples/or1200_test/sw/reset.S +112 -0
  52. data/examples/or1200_test/sw/support.c +123 -0
  53. data/examples/or1200_test/sw/support.h +33 -0
  54. data/examples/or1200_test/sw/tick.c +30 -0
  55. data/examples/or1200_test/sw/tick.h +2 -0
  56. data/examples/or1200_test/sw/uart.c +136 -0
  57. data/examples/or1200_test/sw/uart.h +126 -0
  58. data/lib/soc_maker.rb +324 -0
  59. data/lib/soc_maker/cli.rb +544 -0
  60. data/lib/soc_maker/conf.rb +310 -0
  61. data/lib/soc_maker/core_def.rb +579 -0
  62. data/lib/soc_maker/core_inst.rb +305 -0
  63. data/lib/soc_maker/err.rb +211 -0
  64. data/lib/soc_maker/hdl_coder.rb +500 -0
  65. data/lib/soc_maker/hdl_file.rb +166 -0
  66. data/lib/soc_maker/hdl_parser.rb +431 -0
  67. data/lib/soc_maker/ifc_def.rb +193 -0
  68. data/lib/soc_maker/ifc_port.rb +133 -0
  69. data/lib/soc_maker/ifc_spc.rb +180 -0
  70. data/lib/soc_maker/lib.rb +289 -0
  71. data/lib/soc_maker/lib_inc.rb +109 -0
  72. data/lib/soc_maker/parameter.rb +149 -0
  73. data/lib/soc_maker/soc_def.rb +847 -0
  74. data/lib/soc_maker/sparameter.rb +289 -0
  75. data/lib/soc_maker/version.rb +8 -0
  76. data/lib/soc_maker/ypp.rb +130 -0
  77. data/soc_maker.gemspec +28 -0
  78. data/spec/cli_cmds1.txt +39 -0
  79. data/spec/cli_spec.rb +49 -0
  80. data/spec/conf_spec.rb +44 -0
  81. data/spec/core_def_spec.rb +503 -0
  82. data/spec/core_inst_spec.rb +169 -0
  83. data/spec/hdl_file_spec.rb +154 -0
  84. data/spec/hdl_parser_spec.rb +201 -0
  85. data/spec/ifc_def_spec.rb +121 -0
  86. data/spec/ifc_port_spec.rb +92 -0
  87. data/spec/ifc_spc_spec.rb +196 -0
  88. data/spec/lib_inc_spec.rb +99 -0
  89. data/spec/lib_spec.rb +209 -0
  90. data/spec/parameter_spec.rb +86 -0
  91. data/spec/soc_def_spec.rb +611 -0
  92. data/spec/soc_maker_spec.rb +7 -0
  93. data/spec/sparameter_spec.rb +182 -0
  94. data/spec/spec_helper.rb +78 -0
  95. data/spec/test_soc.yaml +105 -0
  96. data/spec/test_soc2.yaml +60 -0
  97. data/spec/test_soc_lib/cores/core_A_rel1/00_core_a.yaml +75 -0
  98. data/spec/test_soc_lib/cores/core_A_rel1/01_core_a.yaml +57 -0
  99. data/spec/test_soc_lib/cores/core_A_rel1/core_a.vhd +29 -0
  100. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg.vhd.src +3 -0
  101. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg2.vhd.src +4 -0
  102. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg3.v.src +6 -0
  103. data/spec/test_soc_lib/cores/core_B_rel1/core_b.vhd +25 -0
  104. data/spec/test_soc_lib/cores/core_B_rel1/core_b.yaml +36 -0
  105. data/spec/test_soc_lib/cores/core_C_v1/core_C.vhd +57 -0
  106. data/spec/test_soc_lib/cores/core_C_v1/core_c.yaml +42 -0
  107. data/spec/test_soc_lib/cores/soc_A/soc_A.yaml +12 -0
  108. data/spec/test_soc_lib/cores/soc_maker_include.yaml +6 -0
  109. data/spec/test_soc_lib/ifcs/core_AB_ifc/bidir_ifc.yaml +19 -0
  110. data/spec/test_soc_lib/ifcs/core_AB_ifc/core_AB_ifc.yaml +15 -0
  111. data/spec/test_soc_lib/ifcs/core_AB_ifc/top_ifc.yaml +9 -0
  112. data/spec/test_soc_lib/soc_maker_include.yaml +4 -0
  113. data/spec/yaml_examples.rb +367 -0
  114. data/spec/ypp_spec.rb +156 -0
  115. data/test/test_soc_maker.rb +0 -0
  116. metadata +255 -0
@@ -0,0 +1,166 @@
1
+ ###############################################################
2
+ #
3
+ # File: hdl_file.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ #
35
+ # Description:
36
+ #
37
+ #
38
+ #
39
+ #
40
+ ###############################################################
41
+
42
+ module SOCMaker
43
+
44
+
45
+
46
+
47
+ # A small classes, used to group information
48
+ # and to verify, auto-correct and auto-complete
49
+ # this information:
50
+ # The class represents an high-level-description (HDL) file.
51
+ # The two supported file-types are *.vhdl and *.v, whose information
52
+ # is stored in #type ('verilog' or 'vhdl').
53
+ # A #path is mandatory and defines, where the file is located.
54
+ # In addition, is is used for auto-detecting the file-type (if not given).
55
+ # There are three flags:
56
+ # - #use_syn (use in synthesis)
57
+ # - #use_sys_sim (use in system simulation)
58
+ # - #use_mod_sim (use in module simulation)
59
+ # These flags are not used at the moment and reserved for
60
+ # future implementation.
61
+ class HDLFile
62
+ include ERR
63
+
64
+ # file path of the HDL file
65
+ attr_accessor :path
66
+
67
+ # synthesis flag
68
+ attr_accessor :use_syn
69
+
70
+ # system simulation flag (reserved and not used)
71
+ attr_accessor :use_sys_sim
72
+
73
+ # modul simulation flag (reserved and not used)
74
+ attr_accessor :use_mod_sim
75
+
76
+ # type of this hdl file: 'vhdl' or 'verilog'
77
+ attr_accessor :type
78
+
79
+ # The constructor gets the path as mandatory argument.
80
+ # Everything else can be passed with optional arguments
81
+ def initialize( path, optional = {} )
82
+ init_with( { 'path' => path }.merge( optional ) )
83
+ end
84
+
85
+ #
86
+ # Encoder method (to yaml)
87
+ #
88
+ # +coder+:: An instance of the Psych::Coder to encode this class to a YAML file
89
+ #
90
+ def encode_with( coder )
91
+ init_error_if !coder.is_a?( Psych::Coder ),
92
+ 'coder is not given as Psych::Coder'
93
+ %w[ path use_syn use_sys_sim use_mod_sim type ].
94
+ each { |v| coder[ v ] = instance_variable_get "@#{v}" }
95
+ end
96
+
97
+ #
98
+ # Initialization method (from yaml)
99
+ #
100
+ # +coder+:: An instance of the Psych::Coder to init this class from a YAML file
101
+ #
102
+ #
103
+ def init_with( coder )
104
+
105
+ init_error_if !( coder.is_a?( Hash ) || coder.is_a?( Psych::Coder ) ),
106
+ 'coder is not given as Hash neither as Psych::Coder'
107
+
108
+ # check path
109
+ init_error 'no filepath specified' if coder[ 'path' ] == nil
110
+ @path = coder[ 'path' ]
111
+ init_error 'path must be of type string' if !@path.is_a?( String )
112
+
113
+ # auto-complete to 'true'
114
+ @use_syn = coder[ 'use_syn' ] || true
115
+ @use_sys_sim = coder[ 'use_sys_sim' ] || true
116
+ @use_mod_sim = coder[ 'use_mod_sim' ] || true
117
+
118
+ # ensure, that the thee use... fields are boolean
119
+ init_error 'use_syn field must be true of false' if !!@use_syn != @use_syn
120
+ init_error 'use_sys_sim field must be true of false' if !!@use_sys_sim != @use_sys_sim
121
+ init_error 'use_mod_sim field must be true of false' if !!@use_mod_sim != @use_mod_sim
122
+
123
+ # if the file-type is not given, we try to auto-detect it
124
+ # *.vhd -> vhdl
125
+ # *.v -> verilog
126
+ # (see conf[ :vhdl_file_regex ] and
127
+ # conf[ :verilog_file_regex ] )
128
+ if coder[ 'type' ] == nil
129
+ if @path =~ SOCMaker::conf[ :vhdl_file_regex ]
130
+ SOCMaker::logger.warn "Auto-detected vhdl file type for #{ @path }"
131
+ @type = 'vhdl'
132
+ elsif @path =~ SOCMaker::conf[ :verilog_file_regex ]
133
+ SOCMaker::logger.warn "Auto-detected verilog file type for #{ @path }"
134
+ @type = 'verilog'
135
+ else
136
+ init_error "Cant auto-detect file type for #{path}"
137
+ end
138
+ else
139
+ # if the file-type is given, ensure, that it is either 'vhdl' or 'verilog'
140
+ init_error "The type must be 'vhdl' or 'verilog'",
141
+ instance: @path,
142
+ field: 'type' if !SOCMaker::conf[ :hdl_type_regex ].match( coder[ 'type' ] )
143
+ @type = coder[ 'type' ]
144
+ end
145
+
146
+ end
147
+
148
+
149
+
150
+ #
151
+ # Equality operator
152
+ #
153
+ def ==(o)
154
+ o.class == self.class &&
155
+ o.path == self.path &&
156
+ o.use_syn == self.use_syn &&
157
+ o.use_sys_sim == self.use_sys_sim &&
158
+ o.use_mod_sim == self.use_mod_sim &&
159
+ o.type == self.type
160
+ end
161
+
162
+ end
163
+ end
164
+
165
+ # vim: noai:ts=2:sw=2
166
+
@@ -0,0 +1,431 @@
1
+ ###############################################################
2
+ #
3
+ # File: hdl_parser.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2015 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ #
35
+ # Description:
36
+ #
37
+ #
38
+ #
39
+ ###############################################################
40
+
41
+
42
+ require 'singleton'
43
+ require 'pathname'
44
+
45
+ module SOCMaker
46
+
47
+ class HDLParser
48
+
49
+
50
+ include ERR
51
+
52
+ # to organize it as singleton
53
+ #
54
+ include Singleton
55
+
56
+
57
+ def initialize
58
+
59
+ end
60
+
61
+
62
+ def get_content( file )
63
+ return File.open( file, "r"){ |f| f.read }
64
+ end
65
+
66
+
67
+ def get_extension( file )
68
+ return File.extname( file )
69
+ end
70
+
71
+ def get_all_hdl_files( files )
72
+ hdl_files = []
73
+ files.each { |f| hdl_files += Dir[f] }
74
+ return hdl_files
75
+ end
76
+
77
+
78
+
79
+
80
+ def parse_core( top_file, files, package_file = nil )
81
+
82
+ files = [ files ] if not files.kind_of?( Array )
83
+
84
+ #
85
+ # read and parse toplevel file
86
+ #
87
+ content = get_content( top_file )
88
+ if get_extension( top_file ) == ".v"
89
+ toplevel = VerilogParser.instance.parse_toplevel( content )
90
+ toplevel = VerilogParser.instance.extract_length( toplevel )
91
+ elsif get_extension( top_file ) == ".vhd"
92
+ toplevel = VHDLParser.instance.parse_toplevel( content )
93
+ toplevel = VHDLParser.instance.extract_length( toplevel )
94
+ end
95
+
96
+ #
97
+ # read and parse package file
98
+ #
99
+ # -> not yet supported
100
+ #
101
+ if package_file != nil
102
+ content = get_content( package_file )
103
+ if get_extension( package_file ) == ".v"
104
+ package = VerilogParser.instance.parse_package( content )
105
+ elsif get_extension( top_file ) == ".vhd"
106
+ package = VerilogParser.instance.parse_package( content )
107
+ end
108
+ else
109
+ package = {}
110
+ end
111
+
112
+
113
+ #
114
+ # get all HDL files
115
+ #
116
+ hdl_files = get_all_hdl_files( files )
117
+
118
+
119
+
120
+ #
121
+ # Prepare options and ports hashes
122
+ #
123
+ options = { 'inst_parameters' => {},
124
+ 'hdlfiles' => {},
125
+ 'interfaces' => {} }
126
+
127
+ if toplevel.has_key?( :generic )
128
+ toplevel[ :generic ].values.each do | v |
129
+ options[ 'inst_parameters' ][ v[:name] ] = Parameter.new( v[ :type ], default: v[ :default ] )
130
+ end
131
+ end
132
+
133
+ ports = {}
134
+ if toplevel.has_key?( :port )
135
+ toplevel[ :port ].values.each do | v |
136
+ ports[ v[ :name ] ] = IfcPort.new( v[:name], v[:length] )
137
+ end
138
+ end
139
+
140
+ ifc_name = toplevel[:name].to_s + '_ifc'
141
+ ifc_id = ifc_name + ",v1"
142
+ options[ 'interfaces'][ ifc_name ] = IfcDef.new( ifc_name, ifc_id, 0, ports )
143
+
144
+ hdl_files.each do | f |
145
+ f_opts = {}
146
+ name = Pathname.new( f ).basename( ".*" ).to_s
147
+ if name.include? "sim"
148
+ f_opts[ 'use_syn' => false ]
149
+ f_opts[ 'use_mod_sim' => true ]
150
+ else
151
+ f_opts[ 'use_syn' => true ]
152
+ f_opts[ 'use_mod_sim' => false ]
153
+ end
154
+ options[ 'hdlfiles' ][ name ] = HDLFile.new( f, f_opts )
155
+ end
156
+
157
+ #
158
+ # create new core
159
+ #
160
+ d = CoreDef.new( toplevel[ :name ],
161
+ toplevel[ :name ]+",v1",
162
+ toplevel[ :name ], options)
163
+
164
+
165
+
166
+ # dump the result
167
+ return SOCMaker::to_yaml_s( d )
168
+
169
+ end
170
+
171
+
172
+ end
173
+
174
+
175
+ class VerilogParser < HDLParser
176
+
177
+ include ERR
178
+
179
+ # to organize it as singleton
180
+ #
181
+ include Singleton
182
+
183
+
184
+ def initialize
185
+
186
+ end
187
+
188
+ def parse_toplevel( data )
189
+ # remove all newlines
190
+ data = data.gsub( "\n", " " )
191
+
192
+ # empty result hash
193
+ result = {}
194
+
195
+ module_regex = /\s*module\s+(\w+)*\s*\(.*?\);/
196
+ port_regex = /(input|output)\s*(\[([\d\w\-\:\s]*)\s*\])?\s*(\w*);/
197
+ parameter_regex = /parameter\s*(\w*)\s*=\s(.*?);/
198
+
199
+
200
+ # extract module name
201
+ if m = module_regex.match( data )
202
+ result[ :name ] = m[1]
203
+ else
204
+ result[ :name ] = "unknown"
205
+ end
206
+
207
+ #
208
+ # extract parameteters
209
+ #
210
+ parameters = data.scan( parameter_regex )
211
+ result[ :generic ] = {}
212
+ parameters.each do |port|
213
+
214
+ result[ :generic ][ port[0] ] = { name: port[0], default: port[1], type: "integer" }
215
+
216
+ end
217
+
218
+ #
219
+ # extract ports
220
+ #
221
+ ports = data.scan( port_regex )
222
+ result[ :port ] = {}
223
+ ports.each do |port|
224
+ result[ :port ][ port[3] ] = { name: port[3] }
225
+
226
+
227
+ if port[0]
228
+ if port[0] == "input"
229
+ result[ :port ][ port[3] ][ :dir ] = "in"
230
+ elsif port[0] == "output"
231
+ result[ :port ][ port[3] ][ :dir ] = "out"
232
+ else
233
+ result[ :port ][ port[3] ][ :dir ] = "in"
234
+ end
235
+ end
236
+
237
+
238
+ if port[ 2 ]
239
+ result[ :port ][ port[ 3 ] ][ :range ] = port[ 2 ]
240
+ end
241
+
242
+ end
243
+
244
+ return result
245
+ end
246
+
247
+ def extract_length( content )
248
+
249
+ numeric_regex = /^\s*([0-9+\-\s]+):([0-9+\-\s]+)/
250
+ parameter_regex = /^\s*(\D[\D\d]+)\s*-\s*1\s*:\s*0/
251
+
252
+
253
+ content[ :port ].values.each do |port|
254
+ if port[ :range ]
255
+ if m = numeric_regex.match( port[ :range ] )
256
+ tmp = " ( #{ m[1] } ) - ( #{ m[ 2 ] } ) + 1 "
257
+ begin
258
+ port[ :length ] = eval( tmp )
259
+ rescue Exception
260
+ port[:length] = 'UNKNOWN'
261
+ end
262
+
263
+ elsif m = parameter_regex.match( port[ :range ] )
264
+ port[:length] = m[1]
265
+ end
266
+ else
267
+ port[ :length ] = 1
268
+ end
269
+ end
270
+ return content
271
+ end
272
+
273
+ def parse_package( data )
274
+ result = {}
275
+ #data.split("\n").each do |line|
276
+ #end
277
+ return result
278
+ end
279
+
280
+
281
+ end
282
+
283
+
284
+
285
+ class VHDLParser < HDLParser
286
+
287
+ include ERR
288
+
289
+ # to organize it as singleton
290
+ #
291
+ include Singleton
292
+
293
+ def initialize
294
+
295
+ end
296
+
297
+
298
+
299
+ def parse_toplevel( data )
300
+
301
+ # remove all newlines
302
+ data = data.gsub( "\n", " " )
303
+
304
+ # empty result hash
305
+ result = {}
306
+
307
+ # thee expressions to parse the entity header
308
+ entity_regex = /
309
+ entity\s+(\S+)\s+is\s+ # entity <name> is
310
+ (generic\s*\(\s*(.*?)\s*\)\s*;)?\s* # generic ( <generic-infos> ) ; --> optional
311
+ (port\s*\(\s*(.*?)\s*\)\s*;)?\s* # port ( <port-info> ) ; --> optional
312
+ end\s*(entity)?\s*(\S*)\s*; # end <entity-name --> optional> ;
313
+ /x
314
+
315
+ generic_regex = /\s*(\S+)\s*:\s*(\w+)\s*(\((.*?)\))?\s*(:\s*=\s([\d\w]+))?/
316
+ port_regex = /\s*(\S+)\s*:\s*(in|out)?\s*(\w+)\s*(\((.*?)\))?\s*/
317
+
318
+
319
+
320
+ # match the whole entity header,
321
+ # -> extract name
322
+ # -> extract generics
323
+ # -> extract ports
324
+ if m = entity_regex.match( data )
325
+
326
+
327
+ result[ :name ] = m[1]
328
+
329
+
330
+ # if there are generics:
331
+ # -> process each
332
+ if m[3]
333
+ result[ :generic ] = {}
334
+
335
+ m[3].split(";").each do |x|
336
+ if match = generic_regex.match( x )
337
+
338
+ result[ :generic ][ match[1] ] = {
339
+ type: match[2],
340
+ name: match[1]
341
+ }
342
+ if( match[3])
343
+ result[ :generic ][ match[1] ][ :range ] = match[4]
344
+ end
345
+ if( match[5])
346
+ result[ :generic ][ match[1] ][ :default ] = match[6]
347
+ end
348
+ end
349
+ end
350
+ end
351
+
352
+ # if there are ports
353
+ # -> process each
354
+ #
355
+ if m[5]
356
+ result[ :port ] = {}
357
+ m[5].split(";").each do |x|
358
+ if port_match = port_regex.match( x )
359
+ result[ :port ][ port_match[ 1 ] ] = {
360
+ name: port_match[1],
361
+ type: port_match[3]
362
+ }
363
+ if( port_match[2])
364
+ result[ :port ][ port_match[1] ][ :direction] = port_match[2]
365
+ else
366
+ result[ :port ][ port_match[1] ][ :direction] = "in"
367
+ end
368
+
369
+
370
+ if( port_match[ 4 ])
371
+ result[ :port ][ port_match[1] ][ :range] = port_match[5]
372
+ end
373
+
374
+ end
375
+ end
376
+ end
377
+ end
378
+ return result;
379
+ end
380
+
381
+ def extract_length( content )
382
+
383
+ content[ :port ].values.each do |v|
384
+
385
+ v[:length ] = 'UNKNOWN'
386
+
387
+ if v[:range]
388
+
389
+ numeric_regex = /^\s*([0-9+\-\s]+)(to|downto+)([0-9+\-\s]+)/i
390
+ parameter_regex = /^\s*(\D[\D\d]+)\s*-\s*1\s*(to|downto+)\s+0/i
391
+
392
+ if m = numeric_regex.match( v[:range] )
393
+
394
+ if( m[2].downcase == "downto")
395
+ tmp = "(" + m[1] + ") - ( " + m[3] + ") + 1"
396
+ else
397
+ tmp = "(" + m[3] + ") - ( " + m[1] + ") + 1"
398
+ end
399
+ begin
400
+ v[ :length ] = eval( tmp )
401
+ rescue Exception
402
+ v[:length] = 'UNKNOWN'
403
+ end
404
+
405
+ elsif m = parameter_regex.match( v[ :range ] )
406
+ v[:length] = m[1]
407
+ end
408
+ else
409
+ v[ :length ] = 1
410
+ end
411
+ end
412
+ return content
413
+ end
414
+
415
+
416
+ def parse_package( data )
417
+ result = {}
418
+ #const_regex = /^\s*constant\s*(\S+)\s*:\s*(\w+)\s*(\(.*?\))?\s*:\s*=\s*"?([\d\w]+)"?/i
419
+ #data.split("\n").each do |line|
420
+ #end
421
+ return result
422
+ end
423
+
424
+ end
425
+
426
+
427
+
428
+ end
429
+
430
+
431
+