vhdl_tb 0.7.7 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
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