vhdl_tb 0.7.7 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c923a4fa6709c50c3884373bccd42bf10d10edf991433583a3e9049893e890a
4
- data.tar.gz: 9472e003ed9122fc25119a14694773427b18f7f2815d9c6be109587fc4469284
3
+ metadata.gz: 313f1e44991a5318c80cedf07f0762100a2bfd71171c6de3dcdf75a4b6594bfb
4
+ data.tar.gz: 7c6c361dfef387ae6767c4b59113145f0e71ab8e35217fa46272b8d69322fc32
5
5
  SHA512:
6
- metadata.gz: efd367b33ef40a420bea6b2fc7466158d4b06003990e37ae4ef8b9f59ec24020c5d71a4b18e27a6aa370ca886a80ce4e635c7aa573e6a547dc244b4664a2d11a
7
- data.tar.gz: 4a0d1c8094896ab286974dc0b7cc88d0d20b517fcaa5cbda9a3dfc2c0da5a786b089b079903c67a26967f0ee60283dfebee6da6b2cb408c1689db2680abebed1
6
+ metadata.gz: 2b8fdf9e01c639116a968b6e88873eeece3100ad9e7741b092ff6e98e2387a3391c9320ba0e7c7d484d2d9db3183026bcf8de09b7648d1d2379a043236b21e34
7
+ data.tar.gz: c4a5947e34d387336f174e8259991a9884080d35bebd6c8c50e38c5b8834f97071a7a7aa7ce7d5e74ce05036d8fe46df808b2e8e19f9454463c2e16c51f57b91
data/bin/tbgen CHANGED
@@ -1,6 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/compiler'
4
- compiler=VHDL_TB::Compiler.new
5
- compiler.analyze_options(ARGV)
6
- compiler.generate
2
+ require_relative '../lib/runner'
3
+ VHDL_TB::Runner.run(*ARGV)
@@ -1,6 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/compiler'
4
- generator=VHDL_TB::Compiler.new
5
- generator.analyze_options(ARGV)
6
- generator.generate
2
+ require_relative '../lib/runner'
3
+ VHDL_TB::Runner.run(*ARGV)
data/lib/ast.rb CHANGED
@@ -1,5 +1,18 @@
1
1
  module VHDL_TB
2
- Root=Struct.new(:design_units)
2
+ class AstNode
3
+ end
4
+
5
+ class Root < AstNode
6
+ attr_accessor :design_units
7
+ def initialize design_units=[]
8
+ @design_units=design_units
9
+ end
10
+
11
+ def << e
12
+ @design_units << e
13
+ end
14
+ end
15
+
3
16
  Entity=Struct.new(:name,:generics,:ports)
4
17
  Generic=Struct.new(:name,:type,:init)
5
18
  Input=Struct.new(:name,:type)
@@ -24,10 +37,27 @@ module VHDL_TB
24
37
  end
25
38
  end
26
39
 
40
+ class Expression < AstNode
41
+ end
27
42
 
28
- Binary=Struct.new(:lhs,:op,:rhs) do
29
- def to_s
30
- "#{self.lhs} #{self.op} #{self.rhs}"
43
+ class Binary < Expression
44
+ attr_accessor :lhs,:op,:rhs
45
+ def initialize lhs=nil,op=nil,rhs=nil
46
+ @lhs,@op,@rhs=lhs,op,rhs
47
+ end
48
+ end
49
+
50
+ class FuncCall
51
+ attr_accessor :name,:actual_args
52
+ def initialize name=nil,args=[]
53
+ @name,@args=name,args
54
+ end
55
+ end
56
+
57
+ class Timed
58
+ attr_accessor :lhs,:rhs
59
+ def initialize lhs,rhs
60
+ @lhs,@rhs=lhs,rhs
31
61
  end
32
62
  end
33
63
  end
@@ -8,60 +8,37 @@ require_relative 'version'
8
8
 
9
9
  module VHDL_TB
10
10
 
11
- TestBench=Struct.new(:name)
11
+ TestBench=Struct.new(:name)
12
12
 
13
13
  class Compiler
14
14
 
15
- def initialize
16
- #puts __dir__
17
- banner
15
+ attr_accessor :options
16
+ attr_accessor :ast
17
+
18
+ def initialize options={}
18
19
  @engine=ERB.new(IO.read "#{__dir__}/template.tb.vhd")
19
- @parser=Parser.new
20
20
  end
21
21
 
22
- def banner
23
- puts "==> VHDL testbench generator #{VERSION} <=="
22
+ def compile filename
23
+ puts "analyzing VHDL file : #{filename}"
24
+ @ast=Parser.new.parse filename
25
+ analyze filename
26
+ generate
24
27
  end
25
28
 
26
- def analyze_options args
27
- args << "-h" if args.empty?
28
-
29
- opt_parser = OptionParser.new do |opts|
30
- opts.banner = "Usage: vhdl_tb (or tbgen) <filename>"
31
-
32
- opts.on("-v", "--version", "Prints version") do |n|
33
- puts VERSION
34
- abort
35
- end
36
-
37
- opts.on("-h", "--help", "Prints this help") do
38
- puts "Generates testbench in VHDL, from a given file containing an Entity-Architecture couple."
39
- puts
40
- puts opts
41
- abort
42
- end
43
- end
44
-
45
- begin
46
- opt_parser.parse!(args)
47
- @args=args
48
-
49
- rescue Exception => e
50
- puts e
51
- #puts e.backtrace
52
- exit
53
- end
29
+ def parse_2 filename
30
+ @ast=Parser.new.parse_2 filename
31
+ pp @ast
54
32
  end
55
33
 
56
- def generate entity_filename=@args.first
34
+ def generate
57
35
  @symtable=[]
58
36
  @symtable << "clk"
59
37
  @symtable << "reset_n"
60
38
  @symtable << "sreset"
61
39
  begin
62
- analyze(entity_filename)
63
40
  tb_txt=@engine.result(binding)
64
- tb_filename="#{@tb.name}.vhd"
41
+ tb_filename="#{@tb.name}.vhd".downcase
65
42
  File.open(tb_filename,'w'){|f| f.puts tb_txt}
66
43
  puts "testbench generated : #{tb_filename}"
67
44
  rescue Exception => e
@@ -72,15 +49,11 @@ module VHDL_TB
72
49
  end
73
50
 
74
51
  def analyze entity_filename
75
- puts "analyzing VHDL file : #{entity_filename}"
76
-
77
- root=Parser.new.parse entity_filename
78
-
79
52
  #puts "parsed #{entity_filename}. Good."
80
- @entity=root.design_units.find{|du| du.class==Entity}
53
+ @entity=ast.design_units.find{|du| du.class==Entity}
81
54
  puts "entity found : #{@entity.name} (#{@entity.ports.size} ports)"
82
55
 
83
- @arch=root.design_units.find{|du| du.is_a? Architecture}
56
+ @arch=ast.design_units.find{|du| du.is_a? Architecture}
84
57
  check
85
58
  # prepare ERB through instance variables
86
59
  @max_length=@entity.ports.map{|p| p.name.val.size}.max
@@ -18,8 +18,23 @@ class GenericParser
18
18
  end
19
19
  end
20
20
 
21
+ def maybe kind
22
+ if showNext.kind==kind
23
+ return acceptIt
24
+ end
25
+ nil
26
+ end
27
+
21
28
  def more?
22
29
  !tokens.empty?
23
30
  end
24
31
 
32
+ def lookahead n
33
+ showNext(k=n)
34
+ end
35
+
36
+ def niy
37
+ raise "NIY"
38
+ end
39
+
25
40
  end
@@ -65,6 +65,7 @@ module VHDL_TB
65
65
  keyword 'on'
66
66
  keyword 'open'
67
67
  keyword 'or'
68
+ keyword 'xor'
68
69
  keyword 'others'
69
70
  keyword 'out'
70
71
  keyword 'package'
@@ -93,6 +94,7 @@ module VHDL_TB
93
94
  keyword 'then'
94
95
  keyword 'to'
95
96
  keyword 'transport'
97
+ keyword 'time'
96
98
  keyword 'type'
97
99
  keyword 'unaffected'
98
100
  keyword 'units'
@@ -105,37 +107,48 @@ module VHDL_TB
105
107
  keyword 'with'
106
108
  keyword 'xnor'
107
109
  keyword 'xorkeyword '
110
+ keyword 'ns'
111
+ keyword 'ps'
112
+ keyword 'ms'
108
113
 
109
114
  #.............................................................
110
- token :comment => /\A\-\-(.*)$/
115
+ token :comment => /\A\-\-(.*)$/
116
+
111
117
  token :selected_name => /\w+(\.\w+)+/ # /\S+\w+\.\w+/
112
- token :identifier => /[a-zA-Z]\w*/
118
+ token :bit_string_literal => /([bB]|[oO]|[xX])"[^_]\w+"/
119
+ token :ident => /[a-zA-Z]\w*/
113
120
 
114
121
  token :string_literal => /"[^"]*"/
115
122
  token :char_literal => /'(\w+)'/
116
123
  token :attribute_literal => /'(\w+)/
117
124
  token :decimal_literal => /\d+(\.\d+)?(E([+-]?)\d+)?/
118
125
  token :based_literal => /\d+#\w+(\.\w+)?#(E[+-]?\d+)/
119
- token :bit_string_literal => /(b|o|x)"[^_]\w+"/
120
126
  token :vassign => /\A\:\=/
127
+ token :sassign => /\A\<\=/
121
128
  token :comma => /\A\,/
122
129
  token :colon => /\A\:/
123
130
  token :semicolon => /\A\;/
124
131
  token :lparen => /\A\(/
125
132
  token :rparen => /\A\)/
126
- token :plus => /\A\+/
127
- token :minus => /\A\-/
128
- token :times => /\A\*/
133
+
134
+ # arith
135
+ token :add => /\A\+/
136
+ token :sub => /\A\-/
137
+ token :mul => /\A\*/
129
138
  token :div => /\A\//
130
139
 
131
- token :sassign => /\A\<\=/
132
140
  token :imply => /\A\=\>/
141
+ # logical
133
142
  token :eq => /\A\=/
134
- token :ampersand => /\A\&/
135
143
  token :neq => /\A\/\=/
136
144
  token :gte => /\A\>\=/
137
145
  token :gt => /\A\>/
138
146
  token :lt => /\A\</
147
+
148
+ token :sassign => /\A\<\=/
149
+
150
+ token :ampersand => /\A\&/
151
+
139
152
  token :urange => /\A<>/
140
153
  token :dot => /\A\./
141
154
  token :bar => /\|/
@@ -32,6 +32,31 @@ module VHDL_TB
32
32
  end
33
33
  end
34
34
 
35
+ def parse_2 filename
36
+ @tokens=lex(filename)
37
+ root=Root.new([])
38
+ while @tokens.any?
39
+ case showNext.kind
40
+ when :comment
41
+ root << acceptIt
42
+ when :library
43
+ root << parse_library
44
+ when :use
45
+ root << parse_use
46
+ when :entity
47
+ root << parse_entity
48
+ when :architecture
49
+ root << parse_architecture
50
+ when :package
51
+ root << parse_package
52
+ else
53
+ raise "got #{showNext}"
54
+ raise
55
+ end
56
+ end
57
+ root
58
+ end
59
+
35
60
  def parse filename
36
61
  @tokens=lex(filename)
37
62
  #pp @tokens
@@ -39,10 +64,8 @@ module VHDL_TB
39
64
  begin
40
65
  consume_to :entity
41
66
  root.design_units << entity=parse_entity
42
-
43
67
  consume_to :architecture
44
68
  root.design_units << archi=parse_architecture
45
-
46
69
  rescue Exception => e
47
70
  puts e.backtrace
48
71
  puts e
@@ -61,46 +84,63 @@ module VHDL_TB
61
84
  end
62
85
  end
63
86
 
87
+ def parse_library
88
+ expect :library
89
+ expect :ident
90
+ while showNext.is_a?(:comma)
91
+ acceptIt
92
+ expeact :ident
93
+ end
94
+ expect :semicolon
95
+ end
96
+
97
+ def parse_use
98
+ expect :use
99
+ expect :selected_name
100
+ expect :semicolon
101
+ end
102
+
64
103
  def parse_entity
65
104
  entity=Entity.new(nil,nil,[])
66
105
  expect :entity
67
- entity.name=expect :identifier
106
+ entity.name=expect :ident
68
107
  expect :is
69
- if showNext.is_a? :generic
70
- entity.generics=parse_generics
71
- end
108
+ parse_generics?
72
109
  if showNext.is_a? :port
73
110
  entity.ports=parse_ports
74
111
  end
75
112
  expect :end
113
+ maybe :ident
76
114
  if showNext.is_a? :semicolon
77
115
  acceptIt
78
116
  end
79
117
  return entity
80
118
  end
81
119
 
82
- def parse_generics
83
- generics=[]
84
- expect :generic
85
- expect :lparen
86
- while showNext.is_not_a? :rparen
87
- generics << parse_generic
88
- if showNext.is_a? :semicolon
89
- acceptIt
120
+ def parse_generics?
121
+ if showNext.is_a? :generic
122
+ generics=[]
123
+ expect :generic
124
+ expect :lparen
125
+ while showNext.is_not_a? :rparen
126
+ generics << parse_generic
127
+ if showNext.is_a? :semicolon
128
+ acceptIt
129
+ end
90
130
  end
131
+ expect :rparen
132
+ expect :semicolon
133
+ generics.flatten!
134
+ return generics
91
135
  end
92
- expect :rparen
93
- expect :semicolon
94
- generics.flatten!
95
- generics
96
136
  end
97
137
 
98
138
  def parse_generic
99
139
  ids=[]
100
- ids << expect(:identifier)
140
+ ids << expect(:ident)
101
141
  while showNext.is_a? :comma
102
142
  acceptIt
103
- ids << expect(:identifier)
143
+ ids << expect(:ident)
104
144
  end
105
145
  expect :colon
106
146
  type=parse_type
@@ -129,13 +169,13 @@ module VHDL_TB
129
169
 
130
170
  def parse_io
131
171
  ids=[]
132
- ids << expect(:identifier)
172
+ ids << expect(:ident)
133
173
  while showNext.is_a? :comma
134
174
  acceptIt
135
- ids << expect(:identifier)
175
+ ids << expect(:ident)
136
176
  end
137
177
  expect :colon
138
- if showNext.is_a? [:in,:out]
178
+ if showNext.is_a? [:in,:out,:inout]
139
179
  dir=acceptIt
140
180
  dir=dir.kind
141
181
  end
@@ -146,8 +186,8 @@ module VHDL_TB
146
186
  def parse_type
147
187
  type=Identifier.new
148
188
  case showNext.kind
149
- when :identifier
150
- type.tok=expect(:identifier)
189
+ when :ident
190
+ type.tok=acceptIt
151
191
  if showNext.is_a? :lparen
152
192
  acceptIt
153
193
  name=type.tok
@@ -166,36 +206,686 @@ module VHDL_TB
166
206
  type
167
207
  end
168
208
 
209
+ def parse_architecture
210
+ archi=Architecture.new
211
+ expect :architecture
212
+ archi.name=expect(:ident)
213
+ expect :of
214
+ archi.entity=expect(:ident)
215
+ expect :is
216
+ parse_archi_decls
217
+ parse_archi_body
218
+ archi
219
+ end
220
+
221
+ def parse_archi_decls
222
+ parse_decls
223
+ end
224
+
225
+ def parse_decls
226
+ decls=[]
227
+ while showNext.kind!=:begin and showNext.kind!=:end
228
+ case showNext.kind
229
+ when :constant
230
+ decls << parse_constant
231
+ when :type
232
+ decls << parse_typedecl
233
+ when :signal
234
+ decls << parse_signal
235
+ when :procedure
236
+ decls << parse_procedure
237
+ when :function
238
+ decls << parse_function
239
+ when :component
240
+ decls << parse_component_decl
241
+ when :attribute
242
+ decls << parse_attribute
243
+ when :variable
244
+ decls << parse_variable
245
+ else
246
+ raise "ERROR : parse_decls #{pp showNext}"
247
+ end
248
+ end
249
+ decls
250
+ end
251
+
252
+ def parse_constant
253
+ expect :constant
254
+ expect :ident
255
+ while showNext.is_a?(:comma)
256
+ acceptIt
257
+ expect :ident
258
+ end
259
+ expect :colon
260
+ parse_type
261
+ initialized?
262
+ expect :semicolon
263
+ end
264
+
265
+ def parse_typedecl
266
+ expect :type
267
+ expect :ident
268
+ expect :is
269
+ case showNext.kind
270
+ when :lparen
271
+ acceptIt
272
+ expect :ident
273
+ while showNext.is_a?(:comma)
274
+ acceptIt
275
+ expect :ident
276
+ end
277
+ expect :rparen
278
+ when :record
279
+ parse_record
280
+ else
281
+ raise "parse_typedecl : #{pp showNext}"
282
+ end
283
+ expect :semicolon
284
+ end
285
+
286
+ def parse_record
287
+ expect :record
288
+ while showNext.not_a?(:end)
289
+ parse_record_item
290
+ end
291
+ expect :end
292
+ expect :record
293
+ end
294
+
295
+ def parse_record_item
296
+ expect :ident
297
+ while showNext.is_a?(:comma)
298
+ acceptIt
299
+ expect :ident
300
+ end
301
+ expect :colon
302
+ parse_type
303
+ expect :semicolon
304
+ end
305
+
306
+
307
+ def parse_signal
308
+ expect :signal
309
+ expect :ident
310
+ while showNext.is_a?(:comma)
311
+ acceptIt
312
+ expect :ident
313
+ end
314
+ expect :colon
315
+ parse_type
316
+ initialized?
317
+ expect :semicolon
318
+ end
319
+
320
+ def parse_procedure
321
+ expect :procedure
322
+ expect :ident
323
+ if showNext.is_a?(:lparen)
324
+ acceptIt
325
+ parse_formal_parameters
326
+ expect :rparen
327
+ end
328
+ expect :is
329
+ parse_decls
330
+ expect :begin
331
+ parse_body
332
+ expect :end
333
+ expect :procedure
334
+ expect :semicolon
335
+ end
336
+
337
+ def parse_formal_parameters
338
+ ret=[]
339
+ parse_formal_parameter
340
+ while showNext.is_a?(:comma)
341
+ acceptIt
342
+ ret << parse_formal_parameter
343
+ end
344
+ ret.flatten!
345
+ ret
346
+ end
347
+
348
+ def parse_formal_parameter
349
+ expect :ident
350
+ while showNext.is_a?(:comma)
351
+ acceptIt
352
+ expect :ident
353
+ end
354
+ expect :colon
355
+ parse_type
356
+ end
357
+
358
+ def parse_function
359
+ expect :function
360
+ expect :ident
361
+ if showNext.is_a?(:lparen)
362
+ acceptIt
363
+ parse_formal_parameters
364
+ expect :rparen
365
+ end
366
+
367
+ expect :return
368
+ parse_type
369
+
370
+ unless showNext.is_a?(:semicolon)
371
+ expect :is
372
+ parse_decls
373
+ expect :begin
374
+ parse_body
375
+ expect :end
376
+ maybe :function
377
+ maybe :ident
378
+ end
379
+ expect :semicolon
380
+ end
381
+
382
+ def parse_component_decl
383
+ expect :component
384
+ expect :ident
385
+ expect :is
386
+ parse_generics?
387
+ parse_ports
388
+ expect :end
389
+ expect :component
390
+ expect :semicolon
391
+ end
392
+
393
+ def parse_attribute
394
+ expect :attribute
395
+ expect :ident
396
+ case showNext.kind
397
+ when :colon #declaration
398
+ acceptIt
399
+ parse_type
400
+ when :of # specification
401
+ acceptIt
402
+ expect :ident
403
+ expect :colon
404
+ consume_to :semicolon
405
+ else
406
+ raise "ERROR : parse_attribute #{showNext}"
407
+ end
408
+ expect :semicolon
409
+ end
410
+
411
+ def parse_variable
412
+ expect :variable
413
+ expect :ident
414
+ while showNext.is_a?(:comma)
415
+ acceptIt
416
+ expect :ident
417
+ end
418
+ expect :colon
419
+ parse_type
420
+ expect :semicolon
421
+ end
422
+ #======================================
423
+ def parse_archi_body
424
+ expect :begin
425
+ while !showNext.is_a?(:end)
426
+ parse_concurrent_stmt
427
+ end
428
+ expect :end
429
+ expect :ident
430
+ expect :semicolon
431
+ end
432
+
433
+ def parse_concurrent_stmt
434
+ parse_label?
435
+ case showNext.kind
436
+ when :process
437
+ parse_process
438
+ when :entity
439
+ parse_entity_instanciation
440
+ when :ident
441
+ parse_assign
442
+ when :component
443
+ parse_component_instanciation
444
+ else
445
+ raise "parse_concurrent_stmt : #{pp showNext}"
446
+ end
447
+ end
448
+
449
+ def parse_label?
450
+ if lookahead(2).is_a?(:colon)
451
+ expect(:ident)
452
+ expect(:colon)
453
+ end
454
+ end
455
+
456
+ def parse_process
457
+ expect :process
458
+ if showNext.is_a?(:lparen)
459
+ parse_sensitivity_list
460
+ end
461
+ parse_decls
462
+ expect :begin
463
+ parse_body
464
+ expect :end
465
+ expect :process
466
+ expect :semicolon
467
+ end
468
+
469
+ def parse_sensitivity_list
470
+ expect :lparen
471
+ expect :ident
472
+ while showNext.is_a?(:comma)
473
+ acceptIt
474
+ expect :ident
475
+ end
476
+ expect :rparen
477
+ end
478
+
479
+ def parse_component_instanciation
480
+ expect :component
481
+ expect :ident
482
+ parse_generic_map?
483
+ parse_port_map
484
+ expect :semicolon
485
+ end
486
+
487
+ def parse_generic_map?
488
+ if showNext.is_a? :generic
489
+ acceptIt
490
+ expect :map
491
+ expect :lparen
492
+ while !showNext.is_a?(:rparen)
493
+ parse_assoc
494
+ if showNext.is_a?(:comma)
495
+ acceptIt
496
+ end
497
+ end
498
+ expect :rparen
499
+ end
500
+ end
501
+
502
+ def parse_entity_instanciation
503
+ expect :entity
504
+ expect :selected_name
505
+ if showNext.is_a?(:lparen)
506
+ acceptIt
507
+ expect :ident
508
+ expect :rparen
509
+ end
510
+ parse_generic_map?
511
+ parse_port_map
512
+ expect :semicolon
513
+ end
514
+
515
+ def parse_port_map
516
+ expect :port
517
+ expect :map
518
+ expect :lparen
519
+ while !showNext.is_a?(:rparen)
520
+ parse_assoc
521
+ if showNext.is_a?(:comma)
522
+ acceptIt
523
+ end
524
+ end
525
+ expect :rparen
526
+ end
527
+
528
+ def parse_assoc
529
+ expect :ident
530
+ expect :imply
531
+ if showNext.is_a?(:open)
532
+ acceptIt
533
+ else
534
+ parse_expression
535
+ end
536
+ end
537
+ #============== package
538
+
539
+ def parse_package
540
+ expect :package
541
+ case showNext.kind
542
+ when :ident
543
+ parse_package_decl
544
+ when :body
545
+ parse_package_body
546
+ else
547
+ raise "ERROR : parse_package"
548
+ end
549
+ end
550
+
551
+ def parse_package_decl
552
+ expect :ident
553
+ expect :is
554
+ while !showNext.is_a?(:end)
555
+ parse_decls
556
+ end
557
+ expect :end
558
+ maybe :package
559
+ expect :semicolon
560
+ end
561
+
562
+ def parse_package_body
563
+ expect :body
564
+ expect :ident
565
+ expect :is
566
+ while !showNext.is_a?(:end)
567
+ parse_decls
568
+ end
569
+ expect :end
570
+ expect :package
571
+ expect :body
572
+ expect :semicolon
573
+ end
574
+
575
+ #============== body
576
+ def parse_body
577
+ while !showNext.is_a?(:end) and !showNext.is_a?(:elsif) and !showNext.is_a?(:else) and !showNext.is_a?(:when)
578
+ parse_seq_stmt
579
+ end
580
+ end
581
+
582
+ def parse_seq_stmt
583
+ #puts "parse_seq_stmt line #{showNext.pos.first}"
584
+ case showNext.kind
585
+ when :null
586
+ parse_null_stmt
587
+ when :if
588
+ parse_if_stmt
589
+ when :for
590
+ parse_for
591
+ when :while
592
+ parse_while
593
+ when :case
594
+ parse_case
595
+ when :wait
596
+ parse_wait
597
+ when :report
598
+ parse_report
599
+ when :return
600
+ parse_return
601
+ when :ident,:selected_name
602
+ parse_assign
603
+ else
604
+ raise "ERROR : parse_seq_stmt : #{pp showNext}"
605
+ end
606
+ end
607
+
608
+ def parse_null_stmt
609
+ expect :null
610
+ expect :semicolon
611
+ end
612
+
613
+ def parse_assign
614
+ parse_term
615
+ if showNext.is_a? [:vassign,:sassign]
616
+ acceptIt
617
+ end
618
+
619
+ parse_expression
620
+
621
+ while showNext.is_a?(:comma)
622
+ acceptIt
623
+ parse_expression
624
+ end
625
+
626
+ while showNext.is_a?(:when)
627
+ got_when=true
628
+ acceptIt
629
+ parse_expression
630
+ end
631
+
632
+ if got_when
633
+ expect :else
634
+ parse_expression
635
+ end
636
+
637
+ expect :semicolon
638
+ end
639
+
640
+ def parse_if_stmt
641
+ expect :if
642
+ parse_expression
643
+ expect :then
644
+ parse_body
645
+ while showNext.is_a?(:elsif)
646
+ parse_elsif
647
+ end
648
+ if showNext.is_a?(:else)
649
+ acceptIt
650
+ parse_body
651
+ end
652
+ expect :end
653
+ expect :if
654
+ expect :semicolon
655
+ end
656
+
657
+ def parse_elsif
658
+ expect :elsif
659
+ parse_expression
660
+ expect :then
661
+ parse_body
662
+ end
663
+
664
+ def parse_for
665
+ expect :for
666
+ expect :ident
667
+ expect :in
668
+ parse_expression
669
+ if showNext.is_a? :to
670
+ expect :to
671
+ parse_expression
672
+ end
673
+ expect :loop
674
+ parse_body
675
+ expect :end
676
+ expect :loop
677
+ expect :semicolon
678
+ end
679
+
680
+ def parse_while
681
+ niy
682
+ end
683
+
684
+ def parse_case
685
+ expect :case
686
+ parse_expression
687
+ expect :is
688
+ while showNext.is_a? :when
689
+ parse_when_case
690
+ end
691
+ expect :end
692
+ expect :case
693
+ expect :semicolon
694
+ end
695
+
696
+ def parse_when_case
697
+ expect :when
698
+ parse_expression
699
+ expect :imply
700
+ parse_body
701
+ end
702
+
703
+ def parse_wait
704
+ expect :wait
705
+ case showNext.kind
706
+ when :until
707
+ acceptIt
708
+ parse_expression
709
+ when :for
710
+ acceptIt
711
+ parse_expression
712
+ when :semicolon
713
+ else
714
+ raise "parse_wait : #{pp showNext}"
715
+ end
716
+ expect :semicolon
717
+ end
718
+
719
+ def parse_report
720
+ expect :report
721
+ parse_expression
722
+ expect :semicolon
723
+ end
724
+
725
+ def parse_return
726
+ expect :return
727
+ parse_expression
728
+ expect :semicolon
729
+ end
730
+
731
+ # ============================= expression ===============================
732
+ COMPARISON_OP=[:eq,:neq,:gt,:gte,:lt,:lte]
169
733
  def parse_expression
170
- e1=parse_term
171
- while showNext.is_a? [:plus,:minus,:times,:div]
734
+ t1=parse_additive
735
+ while more? && showNext.is_a?(COMPARISON_OP)
172
736
  op=acceptIt
173
- e2=parse_term
174
- e1=Binary.new(e1,op,e2)
737
+ t2=parse_additive
738
+ t1=Binary.new(t1,op,t2)
739
+ end
740
+ return t1
741
+ end
742
+
743
+ ADDITIV_OP =[:add,:sub, :or, :xor] #xor ?
744
+ def parse_additive
745
+ t1=parse_multiplicative
746
+ while more? && showNext.is_a?(ADDITIV_OP)
747
+ op=acceptIt #full token
748
+ t2=parse_multiplicative
749
+ t1=Binary.new(t1,op,t2)
175
750
  end
176
- return e1
751
+ return t1
752
+ end
753
+
754
+ MULTITIV_OP=[:mul,:div,:mod,:and,:shiftr,:shiftl]
755
+ def parse_multiplicative
756
+ t1=parse_term
757
+ while more? && showNext.is_a?(MULTITIV_OP)
758
+ op=acceptIt
759
+ t2=parse_term
760
+ t1=Binary.new(t1,op,t2)
761
+ end
762
+ return t1
177
763
  end
178
764
 
179
765
  def parse_term
180
- if showNext.is_a? [:decimal_literal,:identifier]
766
+ if showNext.is_a? [:ident,:selected_name,:decimal_literal,:char_literal,:string_literal,:bit_string_literal,:lparen,:others,:not,:sub]
181
767
  case showNext.kind
768
+ when :ident
769
+ ret=Identifier.new(acceptIt)
770
+ when :lparen
771
+ ret=parse_parenth
772
+ when :not
773
+ ret=parse_unary
182
774
  when :decimal_literal
183
- return IntLit.new(acceptIt)
184
- when :identifier
185
- return Identifier.new(acceptIt)
775
+ ret=IntLit.new(acceptIt)
776
+ when :char_literal
777
+ ret=acceptIt
778
+ when :string_literal,:bit_string_literal
779
+ ret=acceptIt
780
+ when :selected_name
781
+ ret=acceptIt
782
+ when :others
783
+ ret=acceptIt
186
784
  else
187
- puts "cannot parse term"
785
+ puts "cannot parse term : #{showNext}"
786
+ end
787
+ end
788
+ while showNext && showNext.is_a?([:lbrack,:attribute_literal,:lparen,:ns,:ps,:ms,:after,:ampersand])
789
+ if par=parenthesized?
790
+ #par.name=ret
791
+ ret=par
792
+ elsif attribute=attributed?
793
+ #attribute.lhs=ret
794
+ ret=attribute
795
+ elsif timed=timed?
796
+ timed.lhs=ret
797
+ ret=timed
798
+ elsif after=after?
799
+ #after.lhs=ret
800
+ ret=after
801
+ elsif concat=concat?
802
+ ret=concat
188
803
  end
189
804
  end
805
+ ret
190
806
  end
191
807
 
192
- def parse_architecture
193
- archi=Architecture.new
194
- expect :architecture
195
- archi.name=expect(:identifier)
196
- expect :of
197
- archi.entity=expect(:identifier)
198
- archi
808
+ # parenthesized expressions (NOT indexed or funcall)
809
+ def parse_parenth
810
+ expect :lparen
811
+ if showNext.is_a?(:others) # e.g : (others=>'0')
812
+ acceptIt
813
+ expect :imply
814
+ parse_expression
815
+ else
816
+ parse_expression
817
+ end
818
+
819
+ while showNext.is_a?(:comma) # aggregate
820
+ acceptIt
821
+ parse_expression
822
+ end
823
+ expect :rparen
824
+ end
825
+
826
+ def parse_unary
827
+ if showNext.is_a?([:not,:sub])
828
+ acceptIt
829
+ parse_expression
830
+ end
831
+ end
832
+
833
+ def timed?
834
+ if showNext.is_a? [:ps,:ns,:ms]
835
+ tok=acceptIt
836
+ ret=Timed.new(nil,tok)
837
+ end
838
+ end
839
+
840
+ def parenthesized?
841
+ if showNext.is_a? :lparen
842
+ acceptIt
843
+ ret=FuncCall.new
844
+ args=[]
845
+ while !showNext.is_a? :rparen
846
+ args << parse_expression()
847
+ while showNext.is_a? :comma
848
+ acceptIt
849
+ args << parse_expression()
850
+ end
851
+ if showNext.is_a? [:downto,:to] #slice !
852
+ acceptIt
853
+ parse_expression
854
+ end
855
+ end
856
+ expect :rparen
857
+ ret.actual_args = args
858
+ else
859
+ return false
860
+ end
861
+ return ret
862
+ end
863
+
864
+ def initialized?
865
+ if showNext.is_a?(:vassign)
866
+ acceptIt
867
+ parse_expression
868
+ end
869
+ end
870
+
871
+ def after?
872
+ if showNext.is_a?(:after)
873
+ acceptIt
874
+ parse_expression
875
+ end
876
+ end
877
+
878
+ def concat?
879
+ if showNext.is_a?(:ampersand)
880
+ acceptIt
881
+ parse_expression
882
+ end
883
+ end
884
+
885
+ def attributed?
886
+ if showNext.is_a?(:attribute_literal)
887
+ acceptIt
888
+ end
199
889
  end
200
890
  end
201
891
  end
@@ -0,0 +1,89 @@
1
+ require "optparse"
2
+
3
+ require_relative "compiler"
4
+
5
+ module VHDL_TB
6
+
7
+ class Runner
8
+
9
+ def self.run *arguments
10
+ new.run(arguments)
11
+ end
12
+
13
+ def run arguments
14
+ compiler=Compiler.new
15
+ compiler.options = args = parse_options(arguments)
16
+ if args[:parse_only]
17
+ filename=args[:vhdl_file]
18
+ compiler.parse_2 filename
19
+ elsif filename=args[:vhdl_file]
20
+ compiler.compile filename
21
+ else
22
+ puts "need a VHDL file : vhdl_tb [options] <file.vhd>"
23
+ end
24
+ end
25
+
26
+ def header
27
+ puts "VHDL utilities (#{VERSION})- (c) JC Le Lann 2016-20"
28
+ end
29
+
30
+ private
31
+ def parse_options(arguments)
32
+ header
33
+
34
+ parser = OptionParser.new
35
+
36
+ no_arguments=arguments.empty?
37
+
38
+ options = {}
39
+
40
+ parser.on("-h", "--help", "Show help message") do
41
+ puts parser
42
+ exit(true)
43
+ end
44
+
45
+ parser.on("-p", "--parse", "parse only") do
46
+ options[:parse_only]=true
47
+ end
48
+
49
+ parser.on("--pp", "pretty print back source code ") do
50
+ options[:pp] = true
51
+ end
52
+
53
+ parser.on("--ast", "abstract syntax tree (AST)") do
54
+ options[:ast] = true
55
+ end
56
+
57
+ parser.on("--check", "elaborate and check types") do
58
+ options[:check] = true
59
+ end
60
+
61
+ parser.on("--draw_ast", "draw abstract syntax tree (AST)") do
62
+ options[:draw_ast] = true
63
+ end
64
+
65
+ parser.on("--dummy_transform", "dummy ast transform") do
66
+ options[:dummy_transform] = true
67
+ end
68
+
69
+ parser.on("--vv", "verbose") do
70
+ options[:verbose] = true
71
+ end
72
+
73
+ parser.on("-v", "--version", "Show version number") do
74
+ puts VERSION
75
+ exit(true)
76
+ end
77
+
78
+ parser.parse!(arguments)
79
+
80
+ options[:vhdl_file]=arguments.shift #the remaining c file
81
+
82
+ if no_arguments
83
+ puts parser
84
+ end
85
+
86
+ options
87
+ end
88
+ end
89
+ end
@@ -18,6 +18,11 @@ class Token
18
18
  end
19
19
  end
20
20
 
21
+ def not_a? kind
22
+ result=self.is_a? kind
23
+ !result
24
+ end
25
+
21
26
  def is_not_a? kind
22
27
  case kind
23
28
  when Symbol
@@ -1,3 +1,3 @@
1
1
  module VHDL_TB
2
- VERSION="0.7.7"
2
+ VERSION="0.8.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vhdl_tb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Christophe Le Lann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-27 00:00:00.000000000 Z
11
+ date: 2020-04-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple testbench generator for VHDL
14
14
  email: jean-christophe.le_lann@ensta-bretagne.fr
@@ -26,6 +26,7 @@ files:
26
26
  - lib/generic_parser.rb
27
27
  - lib/lexer.rb
28
28
  - lib/parser.rb
29
+ - lib/runner.rb
29
30
  - lib/template.tb.vhd
30
31
  - lib/token.rb
31
32
  - lib/version.rb