vertigo_vhdl 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +7 -0
  2. data/bin/vertigo +7 -0
  3. data/lib/vertigo.rb +4 -0
  4. data/lib/vertigo/ast.rb +87 -0
  5. data/lib/vertigo/ast_vertigo_rkgen.rb +607 -0
  6. data/lib/vertigo/code.rb +57 -0
  7. data/lib/vertigo/compiler.rb +61 -0
  8. data/lib/vertigo/generic_lexer.rb +61 -0
  9. data/lib/vertigo/generic_parser.rb +44 -0
  10. data/lib/vertigo/indent.rb +20 -0
  11. data/lib/vertigo/lexer.rb +172 -0
  12. data/lib/vertigo/parser.rb +1458 -0
  13. data/lib/vertigo/pretty_printer.rb +749 -0
  14. data/lib/vertigo/runner.rb +115 -0
  15. data/lib/vertigo/tb_generator.rb +81 -0
  16. data/lib/vertigo/template.tb.vhd +72 -0
  17. data/lib/vertigo/token.rb +67 -0
  18. data/lib/vertigo/version.rb +3 -0
  19. data/lib/vertigo/vertigo.rkg +354 -0
  20. data/lib/vertigo/visitor_vertigo_rkgen.rb +447 -0
  21. data/tests/ghdl_tests/fsm.vhd +98 -0
  22. data/tests/ghdl_tests/fsm_synth.vhd +248 -0
  23. data/tests/ghdl_tests/test_fsm.vhd +162 -0
  24. data/tests/parser_tests/else.vhd +64 -0
  25. data/tests/parser_tests/test_MUST_fail.vhd +1 -0
  26. data/tests/parser_tests/test_accelerator.vhd +160 -0
  27. data/tests/parser_tests/test_accelerator_pp.vhd +144 -0
  28. data/tests/parser_tests/test_aggregate.vhd +17 -0
  29. data/tests/parser_tests/test_aggregate_pp.vhd +15 -0
  30. data/tests/parser_tests/test_archi_1.vhd +45 -0
  31. data/tests/parser_tests/test_archi_1_pp.vhd +41 -0
  32. data/tests/parser_tests/test_array_array_00.vhd +25 -0
  33. data/tests/parser_tests/test_array_array_00_pp.vhd +25 -0
  34. data/tests/parser_tests/test_array_urange.vhd +25 -0
  35. data/tests/parser_tests/test_array_urange_pp.vhd +25 -0
  36. data/tests/parser_tests/test_chu-1.vhd +80 -0
  37. data/tests/parser_tests/test_chu-1_pp.vhd +104 -0
  38. data/tests/parser_tests/test_concat.vhd +11 -0
  39. data/tests/parser_tests/test_concat_pp.vhd +14 -0
  40. data/tests/parser_tests/test_counter.vhd +35 -0
  41. data/tests/parser_tests/test_counter_pp.vhd +35 -0
  42. data/tests/parser_tests/test_de2.vhd +358 -0
  43. data/tests/parser_tests/test_de2_pp.vhd +274 -0
  44. data/tests/parser_tests/test_encode.vhd +2679 -0
  45. data/tests/parser_tests/test_encode_pp.vhd +2549 -0
  46. data/tests/parser_tests/test_fsm.vhd +162 -0
  47. data/tests/parser_tests/test_fsm_pp.vhd +125 -0
  48. data/tests/parser_tests/test_fsm_synth.vhd +248 -0
  49. data/tests/parser_tests/test_fsm_synth_pp.vhd +197 -0
  50. data/tests/parser_tests/test_function-01.vhd +33 -0
  51. data/tests/parser_tests/test_function-01_pp.vhd +18 -0
  52. data/tests/parser_tests/test_lfsr.vhd +75 -0
  53. data/tests/parser_tests/test_lfsr_pp.vhd +44 -0
  54. data/tests/parser_tests/test_microwatt_cache_ram.vhd +1 -0
  55. data/tests/parser_tests/test_microwatt_cache_ram_pp.vhd +68 -0
  56. data/tests/parser_tests/test_microwatt_common.vhd +1 -0
  57. data/tests/parser_tests/test_microwatt_common_pp.vhd +336 -0
  58. data/tests/parser_tests/test_microwatt_control.vhd +1 -0
  59. data/tests/parser_tests/test_microwatt_control_pp.vhd +187 -0
  60. data/tests/parser_tests/test_microwatt_core.vhd +1 -0
  61. data/tests/parser_tests/test_microwatt_core_debug.vhd +1 -0
  62. data/tests/parser_tests/test_microwatt_core_debug_pp.vhd +104 -0
  63. data/tests/parser_tests/test_microwatt_core_pp.vhd +231 -0
  64. data/tests/parser_tests/test_microwatt_core_tb.vhd +1 -0
  65. data/tests/parser_tests/test_microwatt_core_tb_pp.vhd +43 -0
  66. data/tests/parser_tests/test_microwatt_countzero.vhd +1 -0
  67. data/tests/parser_tests/test_microwatt_countzero_pp.vhd +120 -0
  68. data/tests/parser_tests/test_microwatt_countzero_tb.vhd +1 -0
  69. data/tests/parser_tests/test_microwatt_countzero_tb_pp.vhd +70 -0
  70. data/tests/parser_tests/test_microwatt_cr_file.vhd +1 -0
  71. data/tests/parser_tests/test_microwatt_cr_file_pp.vhd +74 -0
  72. data/tests/parser_tests/test_microwatt_cr_hazard.vhd +1 -0
  73. data/tests/parser_tests/test_microwatt_cr_hazard_pp.vhd +51 -0
  74. data/tests/parser_tests/test_microwatt_crhelpers.vhd +1 -0
  75. data/tests/parser_tests/test_microwatt_crhelpers_pp.vhd +48 -0
  76. data/tests/parser_tests/test_microwatt_dcache.vhd +1 -0
  77. data/tests/parser_tests/test_microwatt_dcache_pp.vhd +481 -0
  78. data/tests/parser_tests/test_microwatt_dcache_tb.vhd +1 -0
  79. data/tests/parser_tests/test_microwatt_dcache_tb_pp.vhd +98 -0
  80. data/tests/parser_tests/test_microwatt_decode1.vhd +1 -0
  81. data/tests/parser_tests/test_microwatt_decode1_pp.vhd +138 -0
  82. data/tests/parser_tests/test_microwatt_decode2.vhd +1 -0
  83. data/tests/parser_tests/test_microwatt_decode2_pp.vhd +300 -0
  84. data/tests/parser_tests/test_microwatt_decode_types.vhd +1 -0
  85. data/tests/parser_tests/test_microwatt_decode_types_pp.vhd +67 -0
  86. data/tests/parser_tests/test_microwatt_divider.vhd +1 -0
  87. data/tests/parser_tests/test_microwatt_divider_pp.vhd +132 -0
  88. data/tests/parser_tests/test_microwatt_divider_tb.vhd +1 -0
  89. data/tests/parser_tests/test_microwatt_divider_tb_pp.vhd +95 -0
  90. data/tests/parser_tests/test_microwatt_dmi_dtm_dummy.vhd +1 -0
  91. data/tests/parser_tests/test_microwatt_dmi_dtm_dummy_pp.vhd +29 -0
  92. data/tests/parser_tests/test_microwatt_dmi_dtm_tb.vhd +1 -0
  93. data/tests/parser_tests/test_microwatt_dmi_dtm_tb_pp.vhd +197 -0
  94. data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx.vhd +1 -0
  95. data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx_pp.vhd +139 -0
  96. data/tests/parser_tests/test_microwatt_execute1.vhd +1 -0
  97. data/tests/parser_tests/test_microwatt_execute1_pp.vhd +689 -0
  98. data/tests/parser_tests/test_microwatt_fetch1.vhd +1 -0
  99. data/tests/parser_tests/test_microwatt_fetch1_pp.vhd +88 -0
  100. data/tests/parser_tests/test_microwatt_fetch2.vhd +1 -0
  101. data/tests/parser_tests/test_microwatt_fetch2_pp.vhd +79 -0
  102. data/tests/parser_tests/test_microwatt_glibc_random.vhd +1 -0
  103. data/tests/parser_tests/test_microwatt_glibc_random_helpers.vhd +1 -0
  104. data/tests/parser_tests/test_microwatt_glibc_random_helpers_pp.vhd +25 -0
  105. data/tests/parser_tests/test_microwatt_glibc_random_pp.vhd +41 -0
  106. data/tests/parser_tests/test_microwatt_gpr_hazard.vhd +1 -0
  107. data/tests/parser_tests/test_microwatt_gpr_hazard_pp.vhd +68 -0
  108. data/tests/parser_tests/test_microwatt_helpers.vhd +1 -0
  109. data/tests/parser_tests/test_microwatt_helpers_pp.vhd +153 -0
  110. data/tests/parser_tests/test_microwatt_icache.vhd +1 -0
  111. data/tests/parser_tests/test_microwatt_icache_pp.vhd +337 -0
  112. data/tests/parser_tests/test_microwatt_icache_tb.vhd +1 -0
  113. data/tests/parser_tests/test_microwatt_icache_tb_pp.vhd +104 -0
  114. data/tests/parser_tests/test_microwatt_insn_helpers.vhd +1 -0
  115. data/tests/parser_tests/test_microwatt_insn_helpers_pp.vhd +208 -0
  116. data/tests/parser_tests/test_microwatt_loadstore1.vhd +1 -0
  117. data/tests/parser_tests/test_microwatt_loadstore1_pp.vhd +222 -0
  118. data/tests/parser_tests/test_microwatt_logical.vhd +1 -0
  119. data/tests/parser_tests/test_microwatt_logical_pp.vhd +87 -0
  120. data/tests/parser_tests/test_microwatt_multiply.vhd +1 -0
  121. data/tests/parser_tests/test_microwatt_multiply_pp.vhd +84 -0
  122. data/tests/parser_tests/test_microwatt_multiply_tb.vhd +1 -0
  123. data/tests/parser_tests/test_microwatt_multiply_tb_pp.vhd +75 -0
  124. data/tests/parser_tests/test_microwatt_plru.vhd +1 -0
  125. data/tests/parser_tests/test_microwatt_plru_pp.vhd +46 -0
  126. data/tests/parser_tests/test_microwatt_plru_tb.vhd +1 -0
  127. data/tests/parser_tests/test_microwatt_plru_tb_pp.vhd +93 -0
  128. data/tests/parser_tests/test_microwatt_ppc_fx_insns.vhd +1 -0
  129. data/tests/parser_tests/test_microwatt_ppc_fx_insns_pp.vhd +665 -0
  130. data/tests/parser_tests/test_microwatt_register_file.vhd +1 -0
  131. data/tests/parser_tests/test_microwatt_register_file_pp.vhd +86 -0
  132. data/tests/parser_tests/test_microwatt_rotator.vhd +1 -0
  133. data/tests/parser_tests/test_microwatt_rotator_pp.vhd +149 -0
  134. data/tests/parser_tests/test_microwatt_rotator_tb.vhd +1 -0
  135. data/tests/parser_tests/test_microwatt_rotator_tb_pp.vhd +134 -0
  136. data/tests/parser_tests/test_microwatt_sim_bram.vhd +1 -0
  137. data/tests/parser_tests/test_microwatt_sim_bram_helpers.vhd +1 -0
  138. data/tests/parser_tests/test_microwatt_sim_bram_helpers_pp.vhd +52 -0
  139. data/tests/parser_tests/test_microwatt_sim_bram_pp.vhd +53 -0
  140. data/tests/parser_tests/test_microwatt_sim_console.vhd +1 -0
  141. data/tests/parser_tests/test_microwatt_sim_console_pp.vhd +43 -0
  142. data/tests/parser_tests/test_microwatt_sim_jtag.vhd +1 -0
  143. data/tests/parser_tests/test_microwatt_sim_jtag_pp.vhd +64 -0
  144. data/tests/parser_tests/test_microwatt_sim_jtag_socket.vhd +1 -0
  145. data/tests/parser_tests/test_microwatt_sim_jtag_socket_pp.vhd +36 -0
  146. data/tests/parser_tests/test_microwatt_sim_uart.vhd +1 -0
  147. data/tests/parser_tests/test_microwatt_sim_uart_pp.vhd +90 -0
  148. data/tests/parser_tests/test_microwatt_soc.vhd +1 -0
  149. data/tests/parser_tests/test_microwatt_soc_pp.vhd +195 -0
  150. data/tests/parser_tests/test_microwatt_utils.vhd +1 -0
  151. data/tests/parser_tests/test_microwatt_utils_pp.vhd +39 -0
  152. data/tests/parser_tests/test_microwatt_wishbone_arbiter.vhd +1 -0
  153. data/tests/parser_tests/test_microwatt_wishbone_arbiter_pp.vhd +54 -0
  154. data/tests/parser_tests/test_microwatt_wishbone_bram_tb.vhd +1 -0
  155. data/tests/parser_tests/test_microwatt_wishbone_bram_tb_pp.vhd +157 -0
  156. data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper.vhd +1 -0
  157. data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper_pp.vhd +62 -0
  158. data/tests/parser_tests/test_microwatt_wishbone_debug_master.vhd +1 -0
  159. data/tests/parser_tests/test_microwatt_wishbone_debug_master_pp.vhd +124 -0
  160. data/tests/parser_tests/test_microwatt_wishbone_types.vhd +1 -0
  161. data/tests/parser_tests/test_microwatt_wishbone_types_pp.vhd +38 -0
  162. data/tests/parser_tests/test_microwatt_writeback.vhd +1 -0
  163. data/tests/parser_tests/test_microwatt_writeback_pp.vhd +87 -0
  164. data/tests/parser_tests/test_package-1.vhd +68 -0
  165. data/tests/parser_tests/test_package-1_pp.vhd +53 -0
  166. data/tests/parser_tests/test_precedence.vhd +13 -0
  167. data/tests/parser_tests/test_precedence_pp.vhd +16 -0
  168. data/tests/parser_tests/test_selected_sig.vhd +14 -0
  169. data/tests/parser_tests/test_selected_sig_pp.vhd +10 -0
  170. data/tests/parser_tests/test_slice.vhd +15 -0
  171. data/tests/parser_tests/test_slice_pp.vhd +16 -0
  172. data/tests/parser_tests/test_tb-00.vhd +94 -0
  173. data/tests/parser_tests/test_tb-00_pp.vhd +71 -0
  174. data/tests/parser_tests/test_type_decl_02.vhd +9 -0
  175. data/tests/parser_tests/test_type_decl_02_pp.vhd +11 -0
  176. data/tests/parser_tests/test_use.vhd +7 -0
  177. data/tests/parser_tests/test_use_pp.vhd +10 -0
  178. data/tests/parser_tests/test_while_1.vhd +38 -0
  179. data/tests/parser_tests/test_while_1_pp.vhd +26 -0
  180. data/tests/parser_tests/test_with-00.vhd +21 -0
  181. data/tests/parser_tests/test_with-00_pp.vhd +12 -0
  182. data/tests/tb_gen_tests/test_accelerator.vhd +160 -0
  183. metadata +224 -0
@@ -0,0 +1,57 @@
1
+ class Code
2
+
3
+ attr_accessor :indent,:lines
4
+
5
+ def initialize str=nil
6
+ @lines=[]
7
+ (@lines << str) if str
8
+ @indent=0
9
+ end
10
+
11
+ def <<(thing)
12
+ if (code=thing).is_a? Code
13
+ code.lines.each do |line|
14
+ @lines << " "*@indent+line.to_s
15
+ end
16
+ elsif thing.is_a? Array
17
+ thing.each do |kode|
18
+ @lines << kode
19
+ end
20
+ elsif thing.nil?
21
+ else
22
+ @lines << " "*@indent+thing.to_s
23
+ end
24
+ end
25
+
26
+ def finalize
27
+ str=@lines.join("\n") if @lines.any?
28
+ str=clean(str)
29
+ return str if @lines.any?
30
+ ""
31
+ end
32
+
33
+ def clean str
34
+ str=str.gsub(/;[\s\n]*;/ ,';')
35
+ str=str.gsub(/;[\s\n]*\)/ ,')')
36
+ str=str.gsub(/,[\s\n]*\)/,')')
37
+ end
38
+
39
+ def newline
40
+ @lines << " "
41
+ end
42
+
43
+ def save_as filename,verbose=true
44
+ str=self.finalize
45
+ File.open(filename,'w'){|f| f.puts(str)}
46
+ return filename
47
+ end
48
+
49
+ def size
50
+ @lines.size
51
+ end
52
+
53
+ def last
54
+ @lines.last
55
+ end
56
+
57
+ end
@@ -0,0 +1,61 @@
1
+ require_relative 'ast'
2
+ require_relative 'parser'
3
+ require_relative 'version'
4
+ require_relative 'pretty_printer'
5
+ require_relative 'tb_generator'
6
+
7
+ module Vertigo
8
+
9
+ class Compiler
10
+
11
+ attr_accessor :options
12
+ attr_accessor :ast
13
+
14
+ def initialize options={}
15
+ @options=options
16
+ end
17
+
18
+ def compile filename
19
+ begin
20
+ parse(filename)
21
+ puts "=> parsed successfully. Good" unless options[:mute]
22
+ dump_ast if options[:dump_ast]
23
+ pretty_print if options[:pp] or options[:pp_to_file]
24
+ return true
25
+ rescue Exception => e
26
+ puts e.backtrace unless options[:mute]
27
+ puts e unless options[:mute]
28
+ raise
29
+ end
30
+ end
31
+
32
+ def parse filename
33
+ puts "=> parsing VHDL file : #{filename}" unless options[:mute]
34
+ @basename=File.basename(filename,File.extname(filename))
35
+ @ast=Parser.new(options).parse filename
36
+ end
37
+
38
+ def dump_ast
39
+ pp @ast
40
+ end
41
+
42
+ def pretty_print
43
+ puts "=> pretty printing" unless options[:mute]
44
+ begin
45
+ code=PrettyPrinter.new.print(ast)
46
+ file=code.save_as "#{@basename}_pp.vhd" if options[:pp_to_file]
47
+ puts " - saved as #{file}" if options[:pp_to_file] unless options[:mute]
48
+ puts code.finalize if options[:pp]
49
+ rescue Exception => e
50
+ puts e.backtrace if options[:pp]
51
+ puts e if options[:pp]
52
+ raise "pp error"
53
+ end
54
+ end
55
+
56
+ def gen_tb filename
57
+ parse filename
58
+ TestBenchGenerator.new(options).generate_from(ast)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ require 'strscan'
2
+ require_relative 'token'
3
+
4
+ class GenericLexer
5
+
6
+ def initialize
7
+ @rules = []
8
+ @rules << [:newline,/[\n]/]
9
+ end
10
+
11
+ def ignore pattern
12
+ @rules << [:skip,pattern]
13
+ end
14
+
15
+ def keyword str
16
+ @rules.unshift [str.to_sym,/#{str}\b/i]
17
+ end
18
+
19
+ def token hash
20
+ token,pattern=*hash.to_a.flatten
21
+ @rules << [token, pattern]
22
+ end
23
+
24
+ def open code
25
+ @ssc = StringScanner.new code
26
+ @line=0
27
+ end
28
+
29
+ def next_token
30
+ return [nil,nil,nil] if @ssc.empty?
31
+ tok = get_token
32
+ return (tok.is_a? :skip) ? next_token : tok
33
+ end
34
+
35
+ def get_token
36
+ linecol=position()
37
+ @rules.each do |rule, regexp|
38
+ val = @ssc.scan(regexp)
39
+ return Vertigo::Token.new([rule, val, linecol]) if val
40
+ end
41
+ raise "lexing error line #{linecol.first} around : ...'#{@ssc.peek(5)}'... "
42
+ end
43
+
44
+ def position
45
+ if @ssc.bol?
46
+ @line+=1
47
+ @old_pos=@ssc.pos
48
+ end
49
+ [@line,@ssc.pos-@old_pos+1]
50
+ end
51
+
52
+ def tokenize code
53
+ open(code)
54
+ tokens=[]
55
+ tokens << next_token() while not @ssc.eos?
56
+ # while not @ssc.eos?
57
+ # tokens << (p next_token)
58
+ # end #usefull for debug
59
+ tokens
60
+ end
61
+ end
@@ -0,0 +1,44 @@
1
+ class GenericParser
2
+
3
+ def acceptIt
4
+ tok=tokens.shift
5
+ puts "consuming #{tok.val} (#{tok.kind})" if @verbose
6
+ tok
7
+ end
8
+
9
+ def showNext k=1
10
+ tokens[k-1]
11
+ end
12
+
13
+ def expect kind
14
+ if (actual=showNext.kind)!=kind
15
+ abort "ERROR at #{showNext.pos}. Expecting #{kind}. Got #{actual}"
16
+ else
17
+ return acceptIt()
18
+ end
19
+ end
20
+
21
+ def maybe kind
22
+ if showNext.kind==kind
23
+ return acceptIt
24
+ end
25
+ nil
26
+ end
27
+
28
+ def more?
29
+ !tokens.empty?
30
+ end
31
+
32
+ def lookahead n
33
+ showNext(k=n)
34
+ end
35
+
36
+ def niy
37
+ raise "NIY"
38
+ end
39
+
40
+ def next_tokens n=5
41
+ @tokens[0..n].map{|tok| [tok.kind,tok.val].to_s}.join(',')
42
+ end
43
+
44
+ end
@@ -0,0 +1,20 @@
1
+ module Indent
2
+
3
+ INDENT=2
4
+
5
+ def indent str
6
+ @indentation||=-INDENT
7
+ @indentation+=INDENT
8
+ say(str)
9
+ end
10
+
11
+ def dedent
12
+ @indentation-=INDENT
13
+ end
14
+
15
+ def say str
16
+ @indentation||=0
17
+ puts " "*@indentation+str if @verbose
18
+ end
19
+
20
+ end
@@ -0,0 +1,172 @@
1
+ require_relative 'generic_lexer'
2
+ require_relative 'generic_parser'
3
+
4
+ module Vertigo
5
+ class Lexer < GenericLexer
6
+ def initialize
7
+ super
8
+ keyword 'abs'
9
+ keyword 'access'
10
+ keyword 'after'
11
+ keyword 'alias'
12
+ keyword 'all'
13
+ keyword 'and'
14
+ keyword 'architecture'
15
+ keyword 'array'
16
+ keyword 'assert'
17
+ keyword 'attribute'
18
+ keyword 'begin'
19
+ keyword 'block'
20
+ keyword 'body'
21
+ keyword 'buffer'
22
+ keyword 'bus'
23
+ keyword 'case'
24
+ keyword 'component'
25
+ keyword 'configuration'
26
+ keyword 'constant'
27
+ keyword 'disconnect'
28
+ keyword 'downto'
29
+ keyword 'else'
30
+ keyword 'elsif'
31
+ keyword 'end'
32
+ keyword 'entity'
33
+ keyword 'exit'
34
+ keyword 'file'
35
+ keyword 'for'
36
+ keyword 'function'
37
+ keyword 'generate'
38
+ keyword 'generic'
39
+ keyword 'group'
40
+ keyword 'guarded'
41
+ keyword 'if'
42
+ keyword 'impure'
43
+ keyword 'inertial'
44
+ keyword 'inout'
45
+ keyword 'in'
46
+ keyword 'is'
47
+ keyword 'label'
48
+ keyword 'library'
49
+ keyword 'linkage'
50
+ keyword 'literal'
51
+ keyword 'loop'
52
+ keyword 'map'
53
+ keyword 'mod'
54
+ keyword 'nand'
55
+ keyword 'natural'
56
+ keyword 'integer'
57
+ keyword 'boolean'
58
+ keyword 'positive'
59
+ keyword 'new'
60
+ keyword 'next'
61
+ keyword 'nor'
62
+ keyword 'not'
63
+ keyword 'null'
64
+ keyword 'of'
65
+ keyword 'on'
66
+ keyword 'open'
67
+ keyword 'or'
68
+ keyword 'xor'
69
+ keyword 'others'
70
+ keyword 'out'
71
+ keyword 'package'
72
+ keyword 'port'
73
+ keyword 'postponed'
74
+ keyword 'procedure'
75
+ keyword 'process'
76
+ keyword 'pure'
77
+ keyword 'range'
78
+ keyword 'record'
79
+ keyword 'register'
80
+ keyword 'reject'
81
+ keyword 'report'
82
+ keyword 'return'
83
+ keyword 'rol'
84
+ keyword 'ror'
85
+ keyword 'select'
86
+ keyword 'severity'
87
+ keyword 'signal'
88
+ keyword 'shared'
89
+ keyword 'sla'
90
+ keyword 'sli'
91
+ keyword 'sra'
92
+ keyword 'srl'
93
+ keyword 'subtype'
94
+ keyword 'then'
95
+ keyword 'to'
96
+ keyword 'transport'
97
+ keyword 'time'
98
+ keyword 'type'
99
+ keyword 'unaffected'
100
+ keyword 'units'
101
+ keyword 'until'
102
+ keyword 'use'
103
+ keyword 'variable'
104
+ keyword 'wait'
105
+ keyword 'when'
106
+ keyword 'while'
107
+ keyword 'with'
108
+ keyword 'xnor'
109
+ keyword 'xorkeyword '
110
+ keyword 'ns'
111
+ keyword 'ps'
112
+ keyword 'ms'
113
+ keyword 'warning'
114
+ keyword 'error'
115
+ keyword 'note'
116
+ keyword 'failure'
117
+ keyword 'true'
118
+ keyword 'false'
119
+ #.............................................................
120
+ token :comment => /\A\-\-(.*)$/
121
+
122
+ # token :selected_name => /\w+(\.\w+)+/ # /\S+\w+\.\w+/
123
+ token :bit_string_literal => /([bB]|[oO]|[xX])"[^_]\w+"/
124
+ token :ident => /[a-zA-Z]\w*/
125
+
126
+ token :string_literal => /"[^"]*"/
127
+ token :char_literal => /'(\w+)'/
128
+ token :attribute_literal => /'(\w+)/
129
+ token :based_literal => /\d+#\w+(\.\w+)?#/
130
+ token :decimal_literal => /\d+(\.\d+)?(E([+-]?)\d+)?/
131
+ token :vassign => /\A\:\=/
132
+ #token :sassign => /\A\<\=/
133
+ token :comma => /\A\,/
134
+ token :colon => /\A\:/
135
+ token :semicolon => /\A\;/
136
+ token :lparen => /\A\(/
137
+ token :rparen => /\A\)/
138
+
139
+ token :tick => /\A'/ #for qualified expression
140
+
141
+ token :neq => /\A\/\=/ # here for precedence
142
+
143
+ # arith
144
+ token :add => /\A\+/
145
+ token :sub => /\A\-/
146
+ token :exp => /\A\*\*/
147
+ token :mul => /\A\*/
148
+ token :div => /\A\//
149
+
150
+ token :imply => /\A\=\>/
151
+ token :urange => /\A<>/
152
+
153
+ # logical
154
+ token :eq => /\A\=/
155
+ token :gte => /\A\>\=/
156
+ token :gt => /\A\>/
157
+ token :leq => /\A\<\=/
158
+ token :lt => /\A\</
159
+
160
+ token :sassign => /\A\<\=/
161
+
162
+ token :ampersand => /\A\&/
163
+
164
+ token :dot => /\A\./
165
+ token :bar => /\|/
166
+ #............................................................
167
+ token :newline => /[\n]/
168
+ token :space => /[ \t\r]+/
169
+
170
+ end #def
171
+ end #class
172
+ end #module
@@ -0,0 +1,1458 @@
1
+ # coding: utf-8
2
+ require_relative 'generic_parser'
3
+ require_relative 'ast'
4
+ require_relative 'lexer'
5
+
6
+ module Vertigo
7
+
8
+ class Parser < GenericParser
9
+ attr_accessor :options
10
+ attr_accessor :lexer,:tokens
11
+ attr_accessor :basename,:filename
12
+
13
+ def initialize options={}
14
+ @options=options
15
+ end
16
+
17
+ def lex filename
18
+ unless File.exists?(filename)
19
+ raise "ERROR : cannot find file '#{filename}'"
20
+ end
21
+ begin
22
+ str=IO.read(filename).downcase
23
+ tokens=Lexer.new.tokenize(str)
24
+ tokens=tokens.select{|t| t.class==Token} # filters [nil,nil,nil]
25
+ tokens.reject!{|tok| tok.is_a? [:comment,:newline,:space]}
26
+ return tokens
27
+ rescue Exception=>e
28
+ unless options[:mute]
29
+ puts e.backtrace
30
+ puts e
31
+ end
32
+ raise "an error occured during LEXICAL analysis. Sorry. Aborting."
33
+ end
34
+ end
35
+
36
+ def parse filename
37
+ begin
38
+ @tokens=lex(filename)
39
+ root=Root.new([])
40
+ while @tokens.any?
41
+ case showNext.kind
42
+ when :comment
43
+ root << acceptIt
44
+ when :library
45
+ root << parse_library
46
+ when :use
47
+ root << parse_use
48
+ when :entity
49
+ root << parse_entity
50
+ when :architecture
51
+ root << parse_architecture
52
+ when :package
53
+ root << parse_package
54
+ when :configuration
55
+ root << parse_configuration
56
+ else
57
+ raise "got #{showNext}"
58
+ end
59
+ end
60
+ rescue Exception => e
61
+ unless options[:mute]
62
+ puts e.backtrace
63
+ puts e
64
+ end
65
+ raise
66
+ end
67
+ root.flatten!
68
+ root
69
+ end
70
+
71
+ def consume_to token_kind
72
+ while showNext && showNext.kind!=token_kind
73
+ acceptIt
74
+ end
75
+ if showNext.nil?
76
+ raise "cannot find token '#{token_kind}'"
77
+ end
78
+ end
79
+
80
+ def parse_library
81
+ ret=[]
82
+ expect :library
83
+ ret << lib=Library.new
84
+ lib.name=Ident.new(expect :ident)
85
+ while showNext.is_a?(:comma)
86
+ acceptIt
87
+ ret << lib=Library.new
88
+ lib.name=Ident.new(expect :ident)
89
+ end
90
+ expect :semicolon
91
+ ret
92
+ end
93
+
94
+ def parse_use
95
+ ret=Use.new
96
+ expect :use
97
+ selected_name=parse_term #ENSURE selected_name
98
+ unless selected_name.is_a?(SelectedName)
99
+ raise "expecting selected name afer 'use'"
100
+ end
101
+ ret.library=selected_name.lhs.lhs
102
+ ret.package=selected_name.lhs.rhs
103
+ ret.element=selected_name.rhs
104
+ expect :semicolon
105
+ ret
106
+ end
107
+
108
+ def parse_entity
109
+ entity=Entity.new
110
+ expect :entity
111
+ entity.name=Ident.new(expect :ident)
112
+ expect :is
113
+ entity.generics=parse_generics?
114
+ if showNext.is_a? :port
115
+ entity.ports=parse_ports
116
+ end
117
+ expect :end
118
+ maybe :entity
119
+ maybe :ident
120
+ expect :semicolon
121
+ return entity
122
+ end
123
+
124
+ def parse_generics?
125
+ generics=[]
126
+ if showNext.is_a? :generic
127
+ generics=[]
128
+ expect :generic
129
+ expect :lparen
130
+ while showNext.is_not_a? :rparen
131
+ generics << parse_generic
132
+ if showNext.is_a? :semicolon
133
+ acceptIt
134
+ end
135
+ end
136
+ expect :rparen
137
+ expect :semicolon
138
+ end
139
+ generics.flatten!
140
+ return generics
141
+ end
142
+
143
+ def parse_generic
144
+ ids=[]
145
+ ids << expect(:ident)
146
+ while showNext.is_a? :comma
147
+ acceptIt
148
+ ids << expect(:ident)
149
+ end
150
+ expect :colon
151
+ type=parse_type
152
+ if showNext.is_a? :vassign
153
+ acceptIt
154
+ expr=parse_expression
155
+ end
156
+ ids.map{|id| Generic.new(id,type,expr)}
157
+ end
158
+
159
+ def parse_ports
160
+ ports=[]
161
+ expect :port
162
+ expect :lparen
163
+ while showNext.is_not_a? :rparen
164
+ ports << parse_io
165
+ if showNext.is_a? :semicolon
166
+ acceptIt
167
+ end
168
+ end
169
+ expect :rparen
170
+ expect :semicolon
171
+ ports.flatten!
172
+ ports
173
+ end
174
+
175
+ def parse_io
176
+ ids=[]
177
+ ids << expect(:ident)
178
+ while showNext.is_a? :comma
179
+ acceptIt
180
+ ids << expect(:ident)
181
+ end
182
+ expect :colon
183
+ if showNext.is_a? [:in,:out,:inout]
184
+ dir=acceptIt
185
+ dir=dir.kind
186
+ end
187
+ type=parse_type
188
+ ids.map{|id|
189
+ case dir
190
+ when :in
191
+ Input.new(id,type)
192
+ when :out
193
+ Output.new(id,type)
194
+ when :inout
195
+ InOut.new(id,type)
196
+ end
197
+ }
198
+ end
199
+
200
+ def parse_type
201
+ case showNext.kind
202
+ when :ident
203
+ type=NamedType.new
204
+ type.ident=Ident.new(acceptIt)
205
+ else
206
+ type=StdType.new
207
+ type.ident=Ident.new(acceptIt) # natural,...
208
+ if ranged_type=ranged_type?
209
+ ranged_type.type=type
210
+ type=ranged_type
211
+ end
212
+ end
213
+ if showNext.is_a? :lparen
214
+ old=type
215
+ type=ArrayType.new
216
+ type.name=old
217
+ acceptIt
218
+ type.discrete_ranges << parse_discrete_range
219
+ while showNext.is_a?(:comma) # multidim array types
220
+ acceptIt
221
+ type.discrete_ranges << parse_discrete_range
222
+ end
223
+ expect :rparen
224
+ end
225
+ type
226
+ end
227
+
228
+ def ranged_type?
229
+ if showNext.is_a?(:range)
230
+ acceptIt
231
+ ret=RangedType.new
232
+ ret.range=parse_discrete_range
233
+ return ret
234
+ end
235
+ end
236
+
237
+ def parse_discrete_range
238
+ e1=parse_expression
239
+ if showNext.is_a? [:downto,:to]
240
+ dir=acceptIt
241
+ e2=parse_expression
242
+ return DiscreteRange.new(e1,dir,e2)
243
+ end
244
+ e1
245
+ end
246
+
247
+ def parse_architecture
248
+ archi=Architecture.new
249
+ expect :architecture
250
+ archi.name=expect(:ident)
251
+ expect :of
252
+ archi.entity_name=expect(:ident)
253
+ expect :is
254
+ archi.decls=parse_archi_decls
255
+ archi.body=parse_archi_body
256
+ archi
257
+ end
258
+
259
+ def parse_archi_decls
260
+ parse_decls
261
+ end
262
+
263
+ def parse_decls
264
+ decls=[]
265
+ while showNext.kind!=:begin and showNext.kind!=:end
266
+ case showNext.kind
267
+ when :constant
268
+ decls << parse_constant
269
+ when :type,:subtype
270
+ decls << parse_typedecl
271
+ when :signal
272
+ decls << parse_signal
273
+ when :procedure
274
+ decls << parse_procedure
275
+ when :function,:impure
276
+ decls << parse_function
277
+ when :component
278
+ decls << parse_component_decl
279
+ when :attribute
280
+ decls << parse_attribute
281
+ when :variable
282
+ decls << parse_variable
283
+ when :alias
284
+ decls << parse_alias
285
+ else
286
+ raise "ERROR : parse_decls #{pp showNext}"
287
+ end
288
+ end
289
+ decls.flatten!
290
+ decls
291
+ end
292
+
293
+ def parse_constant
294
+ ret=[]
295
+ expect :constant
296
+ ret << cst=Constant.new
297
+ cst.name=Ident.new(expect :ident)
298
+ while showNext.is_a?(:comma)
299
+ acceptIt
300
+ ret << cst=Constant.new
301
+ cst.name=Ident.new(expect :ident)
302
+ end
303
+ expect :colon
304
+ type=parse_type
305
+ ret.each{|cst| cst.type=type}
306
+ expect :vassign
307
+ ret.last.expr=parse_expression
308
+ expect :semicolon
309
+ ret
310
+ end
311
+
312
+ def parse_typedecl
313
+ ret=TypeDecl.new
314
+ case showNext.kind
315
+ when :type
316
+ acceptIt
317
+ when :subtype
318
+ acceptIt
319
+ ret=SubTypeDecl.new
320
+ else
321
+ raise "ERROR : expecting 'type' or 'subtype'"
322
+ end
323
+ ret.name=Ident.new(expect :ident)
324
+ expect :is
325
+ case showNext.kind
326
+ when :lparen
327
+ ret.spec=parse_enum
328
+ when :record
329
+ ret.spec=parse_record
330
+ when :array
331
+ ret.spec=parse_array_decl
332
+ when :integer,:natural,:positive,:ident
333
+ ret.spec=parse_type
334
+ else
335
+ raise "parse_typedecl : #{pp showNext}"
336
+ end
337
+ expect :semicolon
338
+ ret
339
+ end
340
+
341
+ def parse_enum
342
+ ret=EnumDecl.new
343
+ expect :lparen
344
+ ret << Ident.new(expect :ident)
345
+ while showNext.is_a?(:comma)
346
+ acceptIt
347
+ ret << Ident.new(expect :ident)
348
+ end
349
+ expect :rparen
350
+ ret
351
+ end
352
+
353
+ def parse_record
354
+ ret=RecordDecl.new
355
+ expect :record
356
+ while showNext.not_a?(:end)
357
+ ret.elements << parse_record_items
358
+ end
359
+ ret.elements.flatten!
360
+ expect :end
361
+ expect :record
362
+ ret
363
+ end
364
+
365
+ def parse_record_items
366
+ ret=[]
367
+ ret << ri=RecordItem.new
368
+ # in microwatt => name of the item can be 'error' !
369
+ # we simply accept the first token as name !
370
+ ri.name=Ident.new(acceptIt)
371
+ while showNext.is_a?(:comma)
372
+ acceptIt
373
+ ret << ri=RecordItem.new
374
+ ri.name=Ident.new(expect :ident)
375
+ end
376
+ expect :colon
377
+ type=parse_type
378
+ ret.each{|ri| ri.type=type}
379
+ expect :semicolon
380
+ ret
381
+ end
382
+
383
+ def parse_array_decl
384
+ ret=ArrayDecl.new
385
+ expect :array
386
+ expect :lparen
387
+ ret.dim_decls=parse_array_dim_decls
388
+ expect :rparen
389
+ expect :of
390
+ ret.type=parse_type
391
+ ret
392
+ end
393
+
394
+ def parse_array_dim_decls
395
+ ret=[]
396
+ ret << parse_array_dim_decl
397
+ while showNext.is_a?(:comma) #multi dimensions
398
+ acceptIt
399
+ ret << parse_array_dim_decl
400
+ end
401
+ ret
402
+ end
403
+
404
+ def parse_array_dim_decl
405
+ ret=ArrayDimDecl.new
406
+ case showNext.kind
407
+ when :natural,:integer,:positive
408
+ ret.type_mark=acceptIt
409
+ expect :range
410
+ ret.range=expect(:urange)
411
+ else
412
+ ret.range=parse_discrete_range
413
+ # puts "ERROR : niy at #{showNext.pos}"
414
+ # niy
415
+ end
416
+ ret
417
+ end
418
+
419
+ def parse_signal
420
+ ret=[]
421
+ expect :signal
422
+ ret << sig=Signal.new
423
+ sig.name=Ident.new(expect :ident)
424
+ while showNext.is_a?(:comma)
425
+ acceptIt
426
+ ret << sig=Signal.new
427
+ sig.name=Ident.new(expect :ident)
428
+ end
429
+ expect :colon
430
+ type=parse_type
431
+ ret.map{|sig| sig.type=type}
432
+ init=initialized?
433
+ ret.last.init=init
434
+ expect :semicolon
435
+ ret
436
+ end
437
+
438
+ def parse_procedure
439
+ ret=ProcedureDecl.new
440
+ expect :procedure
441
+ ret.name=Ident.new(expect :ident)
442
+ if showNext.is_a?(:lparen)
443
+ acceptIt
444
+ ret.formal_args=parse_formal_args
445
+ expect :rparen
446
+ end
447
+ if showNext.is_a?(:is)
448
+ acceptIt
449
+ ret.decls=parse_decls
450
+ expect :begin
451
+ ret.body=parse_body
452
+ expect :end
453
+ maybe :procedure
454
+ maybe :ident
455
+ end
456
+ expect :semicolon
457
+ ret
458
+ end
459
+
460
+ def parse_formal_args
461
+ ret=[]
462
+ ret << parse_formal_arg
463
+ while showNext.is_a?(:semicolon)
464
+ acceptIt
465
+ ret << parse_formal_arg
466
+ end
467
+ ret.flatten!
468
+ ret
469
+ end
470
+
471
+ def parse_formal_arg
472
+ ret=[]
473
+ is_signal=(maybe :signal)
474
+ ret << fp=FormalArg.new
475
+ fp.name=Ident.new(expect :ident)
476
+ while showNext.is_a?(:comma)
477
+ acceptIt
478
+ ret << fp=FormalArg.new
479
+ fp.name=Ident.new(expect :ident)
480
+ end
481
+ expect :colon
482
+ if showNext.is_a? [:in,:out,:inout]
483
+ direction=acceptIt
484
+ end
485
+ type=parse_type
486
+ ret.each{|fp|
487
+ fp.direction=direction
488
+ fp.type=type
489
+ }
490
+ ret
491
+ end
492
+
493
+ def parse_function
494
+ ret=FuncDecl.new
495
+ maybe :impure
496
+ expect :function
497
+ ret.name=Ident.new(expect :ident)
498
+ if showNext.is_a?(:lparen)
499
+ acceptIt
500
+ ret.formal_args=parse_formal_args
501
+ expect :rparen
502
+ end
503
+
504
+ expect :return
505
+ ret.return_type=parse_type
506
+
507
+ unless showNext.is_a?(:semicolon)
508
+ expect :is
509
+ ret.decls=parse_decls
510
+ expect :begin
511
+ ret.body=parse_body
512
+ expect :end
513
+ maybe :function
514
+ maybe :ident
515
+ else
516
+ proto=FuncProtoDecl.new
517
+ proto.name=ret.name
518
+ proto.formal_args=ret.formal_args
519
+ proto.return_type=ret.return_type
520
+ ret=proto
521
+ end
522
+ expect :semicolon
523
+ ret
524
+ end
525
+
526
+ def parse_component_decl
527
+ ret=ComponentDecl.new
528
+ expect :component
529
+ ret.name=Ident.new(expect :ident)
530
+ maybe :is
531
+ ret.generics=parse_generics?
532
+ ret.ports=parse_ports
533
+ expect :end
534
+ expect :component
535
+ expect :semicolon
536
+ ret
537
+ end
538
+
539
+ def parse_attribute
540
+ expect :attribute
541
+ name=Ident.new(expect :ident)
542
+ case showNext.kind
543
+ when :colon #declaration
544
+ ret=AttributeDecl.new
545
+ ret.name=name
546
+ acceptIt
547
+ ret.type=parse_type
548
+ when :of # specification
549
+ ret=AttributeSpec.new
550
+ ret.name=name
551
+ acceptIt
552
+ ret.entity_spec=parse_entity_spec
553
+ expect :is
554
+ ret.expr=parse_expression
555
+ else
556
+ raise "ERROR : parse attribute error at line #{showNext.line} #{showNext}"
557
+ end
558
+ expect :semicolon
559
+ ret
560
+ end
561
+
562
+ def parse_entity_spec
563
+ ret=EntitySpec.new
564
+ ret.elements << Ident.new(expect :ident)
565
+ while showNext.is_a?(:comma)
566
+ acceptit
567
+ ret.elements << Ident.new(expect :ident)
568
+ end
569
+ expect :colon
570
+ ret.entity_class=acceptIt # entity,procedure, architecture etc...
571
+ ret
572
+ end
573
+
574
+ def parse_variable
575
+ ret=[] << var=Variable.new
576
+ expect :variable
577
+ var.name=Ident.new(expect :ident)
578
+ while showNext.is_a?(:comma)
579
+ acceptIt
580
+ ret << var=Variable.new
581
+ var.name=Ident.new(expect :ident)
582
+ end
583
+ expect :colon
584
+ type=parse_type
585
+ ret.each{|var| var.type=type}
586
+ init=initialized?
587
+ ret.last.init=init
588
+ expect :semicolon
589
+ ret
590
+ end
591
+
592
+ def parse_alias
593
+ ret=Alias.new # or ret=[] as for variable ?
594
+ expect :alias
595
+ ret.designator=Ident.new(expect :ident) # Warn : see designator in IEEE
596
+ expect :colon
597
+ ret.type=parse_type
598
+ expect :is
599
+ ret.name=Ident.new(expect :ident)
600
+ ret.signature=nil #NIY
601
+ unless showNext.is_a?(:semicolon)
602
+ raise "ERROR : parse alias (signature not implemented yet)"
603
+ end
604
+ expect :semicolon
605
+ ret
606
+ end
607
+ #======================================
608
+ def parse_archi_body
609
+ ret=Body.new
610
+ expect :begin
611
+ while !showNext.is_a?(:end)
612
+ ret << parse_concurrent_stmt
613
+ end
614
+ expect :end
615
+ maybe :architecture
616
+ maybe :ident
617
+ expect :semicolon
618
+ ret
619
+ end
620
+
621
+ def parse_concurrent_stmt
622
+ label=parse_label?
623
+ case showNext.kind
624
+ when :process
625
+ ret=parse_process
626
+ when :entity
627
+ ret=parse_entity_instanciation
628
+ when :ident # assign or component instanciation
629
+ case lookahead(2).kind
630
+ when :port,:generic
631
+ ret=parse_component_instanciation
632
+ else
633
+ ret=parse_assign
634
+ end
635
+ when :component
636
+ ret=parse_component_instanciation
637
+ when :with
638
+ ret=parse_select
639
+ when :if
640
+ ret=parse_if_generate
641
+ when :assert
642
+ ret=parse_assert
643
+ when :for
644
+ ret=parse_for_generate
645
+ else
646
+ raise "parse_concurrent_stmt : #{pp showNext}"
647
+ end
648
+ ret.label=label if label
649
+ ret
650
+ end
651
+
652
+ def parse_label?
653
+ if lookahead(2).is_a?(:colon)
654
+ ret=Label.new
655
+ ret.ident=Ident.new(expect(:ident))
656
+ expect(:colon)
657
+ return ret
658
+ end
659
+ end
660
+
661
+ def parse_process
662
+ ret=Vertigo::Process.new
663
+ expect :process
664
+ if showNext.is_a?(:lparen)
665
+ ret.sensitivity=parse_sensitivity_list
666
+ end
667
+ ret.decls=parse_decls
668
+ ret.decls.flatten!
669
+ expect :begin
670
+ ret.body=parse_body
671
+ expect :end
672
+ expect :process
673
+ maybe :ident
674
+ expect :semicolon
675
+ ret
676
+ end
677
+
678
+ def parse_sensitivity_list
679
+ ret=Sensitivity.new
680
+ expect :lparen
681
+ case showNext.kind
682
+ when :ident
683
+ ret << Ident.new(acceptIt)
684
+ while showNext.is_a?(:comma)
685
+ acceptIt
686
+ ret << Ident.new(expect :ident)
687
+ end
688
+ when :all # VHDL'08 for Microwatt !
689
+ ret << acceptIt
690
+ end
691
+ expect :rparen
692
+ ret
693
+ end
694
+
695
+ def parse_component_instanciation
696
+ ret=ComponentInstance.new
697
+ maybe :component
698
+ ret.name=expect :ident
699
+ ret.generic_map=parse_generic_map?
700
+ ret.port_map=parse_port_map?
701
+ expect :semicolon
702
+ ret
703
+ end
704
+
705
+ def parse_generic_map?
706
+ if showNext.is_a? :generic
707
+ ret=GenericMap.new
708
+ acceptIt
709
+ expect :map
710
+ expect :lparen
711
+ while !showNext.is_a?(:rparen)
712
+ ret << parse_map
713
+ if showNext.is_a?(:comma)
714
+ acceptIt
715
+ end
716
+ end
717
+ expect :rparen
718
+ return ret
719
+ end
720
+ nil
721
+ end
722
+
723
+ def parse_entity_instanciation
724
+ ret=EntityInstance.new
725
+ expect :entity
726
+ ret.full_name=parse_term # ENSURE :selected_name
727
+ if showNext.is_a?(:lparen)
728
+ acceptIt
729
+ ret.arch_name=Ident.new(expect :ident)
730
+ expect :rparen
731
+ end
732
+ ret.generic_map=parse_generic_map?
733
+ ret.port_map=parse_port_map?
734
+ expect :semicolon
735
+ ret
736
+ end
737
+
738
+ def parse_port_map?
739
+ if showNext.is_a?(:port)
740
+ ret=PortMap.new
741
+ expect :port
742
+ expect :map
743
+ expect :lparen
744
+ while !showNext.is_a?(:rparen)
745
+ ret.elements << parse_map
746
+ if showNext.is_a?(:comma)
747
+ acceptIt
748
+ end
749
+ end
750
+ expect :rparen
751
+ return ret
752
+ end
753
+ end
754
+
755
+ def parse_map
756
+ ret=parse_expression
757
+ if map=mapped?
758
+ map.lhs=ret
759
+ ret=map
760
+ end
761
+ ret
762
+ end
763
+
764
+ def parse_select
765
+ ret=WithSelect.new
766
+ expect :with
767
+ ret.with_expr=parse_expression
768
+ expect :select
769
+ ret.assigned=parse_term
770
+ expect :leq
771
+ ret.selected_whens << parse_selected_when
772
+ while showNext.is_a?(:comma)
773
+ acceptIt
774
+ ret.selected_whens << parse_selected_when
775
+ end
776
+ expect :semicolon
777
+ ret
778
+ end
779
+
780
+ def parse_selected_when
781
+ ret=SelectedWhen.new
782
+ ret.lhs=parse_expression
783
+ expect :when
784
+ ret.rhs=parse_expression
785
+ ret
786
+ end
787
+
788
+ def parse_if_generate
789
+ #pp @tokens[0..5].map{|t| t.val}.join(' | ')
790
+ ret=IfGenerate.new
791
+ expect :if
792
+ ret.cond=parse_expression
793
+ expect :generate
794
+ if showNext.is_a?(:begin) # seems optional!
795
+ acceptIt
796
+ end
797
+ ret.body=parse_concurrent_stmt
798
+ expect :end
799
+ expect :generate
800
+ expect :semicolon
801
+ ret
802
+ end
803
+
804
+ def parse_for_generate
805
+ ret=ForGenerate.new
806
+ expect :for
807
+ ret.index=Ident.new(acceptIt)
808
+ expect :in
809
+ ret.range=parse_discrete_range
810
+ expect :generate
811
+ while showNext.is_not_a?(:begin)
812
+ parse_decls
813
+ end
814
+ ret.body=body=Body.new
815
+ expect :begin
816
+ while !showNext.is_a?(:end)
817
+ body << parse_concurrent_stmt
818
+ end
819
+ expect :end
820
+ expect :generate
821
+ expect :semicolon
822
+ ret
823
+ end
824
+ #============== package
825
+
826
+ def parse_package
827
+ expect :package
828
+ case showNext.kind
829
+ when :ident
830
+ ret=parse_package_decl
831
+ when :body
832
+ ret=parse_package_body
833
+ else
834
+ raise "ERROR : parse_package"
835
+ end
836
+ end
837
+
838
+ def parse_package_decl
839
+ ret=Package.new
840
+ ret.name=Ident.new(expect :ident)
841
+ expect :is
842
+ while !showNext.is_a?(:end)
843
+ ret.decls << parse_decls
844
+ end
845
+ ret.decls.flatten!
846
+ expect :end
847
+ maybe :package
848
+ maybe :ident
849
+ expect :semicolon
850
+ ret
851
+ end
852
+
853
+ def parse_package_body
854
+ ret=PackageBody.new
855
+ expect :body
856
+ ret.name=Ident.new(expect :ident)
857
+ expect :is
858
+ while !showNext.is_a?(:end)
859
+ ret.decls << parse_decls
860
+ end
861
+ ret.decls.flatten!
862
+ expect :end
863
+ maybe :package
864
+ maybe :body
865
+ maybe :ident
866
+ expect :semicolon
867
+ ret
868
+ end
869
+
870
+ # ============= configuration
871
+ def parse_configuration
872
+ expect :configuration
873
+ expect :ident
874
+ expect :of
875
+ expect :ident
876
+ expect :is
877
+ parse_configuration_body
878
+ expect :end
879
+ expect :ident
880
+ expect :semicolon
881
+ end
882
+
883
+ def parse_configuration_body
884
+ case showNext.kind
885
+ when :for
886
+ parse_configuration_for
887
+ else
888
+ raise "ERROR : configurations not fully supported. Sorry."
889
+ end
890
+ end
891
+
892
+ def parse_configuration_for
893
+ expect :for
894
+ expect :ident
895
+ expect :end
896
+ expect :for
897
+ expect :semicolon
898
+ end
899
+ # ============== body
900
+ def parse_body
901
+ ret=Body.new
902
+ while !showNext.is_a?(:end) and !showNext.is_a?(:elsif) and !showNext.is_a?(:else) and !showNext.is_a?(:when)
903
+ ret << parse_seq_stmt
904
+ end
905
+ ret
906
+ end
907
+
908
+ def parse_seq_stmt
909
+ #puts "parse_seq_stmt line #{showNext.pos.first}"
910
+ label=parse_label?
911
+ case showNext.kind
912
+ when :null
913
+ ret=parse_null_stmt
914
+ when :if
915
+ ret=parse_if_stmt
916
+ when :for
917
+ ret=parse_for
918
+ when :while
919
+ ret=parse_while
920
+ when :case
921
+ ret=parse_case
922
+ when :wait
923
+ ret=parse_wait
924
+ when :report
925
+ ret=parse_report
926
+ when :return
927
+ ret=parse_return
928
+ when :assert
929
+ ret=parse_assert
930
+ when :loop
931
+ ret=parse_loop
932
+ when :exit
933
+ ret=parse_exit
934
+ when :ident
935
+ ret=parse_assign
936
+ else
937
+ raise "ERROR : parse_seq_stmt : #{pp showNext}"
938
+ end
939
+ ret
940
+ end
941
+
942
+ def parse_null_stmt
943
+ ret=NullStmt.new
944
+ expect :null
945
+ expect :semicolon
946
+ ret
947
+ end
948
+
949
+ def parse_assign
950
+ lhs=parse_term
951
+
952
+ if showNext.is_a? [:vassign,:leq,:semicolon]
953
+ case showNext.kind
954
+ when :vassign
955
+ acceptIt
956
+ ret=VarAssign.new(lhs)
957
+ when :leq
958
+ acceptIt
959
+ ret=SigAssign.new(lhs)
960
+ when :semicolon #assign? No ! Procedure call !
961
+ acceptIt
962
+ ret=ProcedureCall.new
963
+ ret.name=lhs
964
+ ret.actual_args=[]
965
+ return ret
966
+ end
967
+ end
968
+
969
+ ret.rhs=rhs=parse_expression
970
+ case showNext.kind
971
+ when :comma
972
+ ret.rhs=wfm=Waveform.new
973
+ wfm.elements << rhs
974
+ while showNext.is_a?(:comma)
975
+ acceptIt
976
+ wfm.elements << parse_expression
977
+ end
978
+ when :when
979
+ ret.rhs=cond=CondExpr.new
980
+ while showNext.is_a?(:when) #cond assign
981
+ cond.whens << when_=When.new
982
+ got_when=true
983
+ acceptIt
984
+ when_.expr=rhs
985
+ when_.cond=parse_expression
986
+ expect :else
987
+ rhs=parse_expression
988
+ end
989
+ cond.else_=rhs
990
+ when :semicolon
991
+ # pp showNext
992
+ # ret.rhs=rhs
993
+ else
994
+ raise "unexpected error in parse assign : #{showNext.val}, at #{showNext.pos}"
995
+ end
996
+ expect :semicolon
997
+ ret
998
+ end
999
+
1000
+ def parse_if_stmt
1001
+ ret=If.new
1002
+ expect :if
1003
+ ret.cond=parse_expression
1004
+ expect :then
1005
+ ret.body=parse_body
1006
+ while showNext.is_a?(:elsif)
1007
+ ret.elsifs << parse_elsif
1008
+ end
1009
+ if showNext.is_a?(:else)
1010
+ ret.else_=parse_else
1011
+ end
1012
+ expect :end
1013
+ expect :if
1014
+ expect :semicolon
1015
+ ret
1016
+ end
1017
+
1018
+ def parse_elsif
1019
+ ret=Elsif.new
1020
+ expect :elsif
1021
+ ret.cond=parse_expression
1022
+ expect :then
1023
+ ret.body=parse_body
1024
+ ret
1025
+ end
1026
+
1027
+ def parse_else
1028
+ ret=Else.new
1029
+ expect :else
1030
+ ret.body=parse_body
1031
+ ret
1032
+ end
1033
+
1034
+ def parse_for
1035
+ expect :for
1036
+ expect :ident
1037
+ expect :in
1038
+ parse_discrete_range
1039
+ parse_loop
1040
+ end
1041
+
1042
+ def parse_while
1043
+ expect :while
1044
+ parse_expression
1045
+ parse_loop
1046
+ end
1047
+
1048
+ def parse_case
1049
+ ret=Case.new
1050
+ expect :case
1051
+ ret.expr=parse_expression
1052
+ expect :is
1053
+ while showNext.is_a? :when
1054
+ ret << parse_when_case
1055
+ end
1056
+ expect :end
1057
+ expect :case
1058
+ expect :semicolon
1059
+ ret
1060
+ end
1061
+
1062
+ def parse_when_case
1063
+ ret=CaseWhen.new
1064
+ expect :when
1065
+ ret.expr=expr=parse_expression
1066
+ if showNext.is_a?(:bar)
1067
+ alternative=Alternative.new
1068
+ alternative << ret.expr
1069
+ ret.expr=alternative
1070
+ while showNext.is_a?(:bar)
1071
+ acceptIt
1072
+ alternative << parse_expression
1073
+ end
1074
+ end
1075
+ expect :imply
1076
+ ret.body=parse_body
1077
+ ret
1078
+ end
1079
+
1080
+ def parse_wait
1081
+ ret=Wait.new
1082
+ expect :wait
1083
+ case showNext.kind
1084
+ when :until
1085
+ acceptIt
1086
+ ret.until_=parse_expression
1087
+ when :for
1088
+ acceptIt
1089
+ ret.for_=parse_expression
1090
+ when :semicolon
1091
+ else
1092
+ raise "parse_wait : #{pp showNext}"
1093
+ end
1094
+ expect :semicolon
1095
+ ret
1096
+ end
1097
+
1098
+ def parse_report
1099
+ ret=Report.new
1100
+ expect :report
1101
+ ret.expr=parse_expression
1102
+ if showNext.is_a?(:severity)
1103
+ ret.severity=parse_severity
1104
+ end
1105
+ expect :semicolon
1106
+ return ret
1107
+ end
1108
+
1109
+ def parse_return
1110
+ ret=Return.new
1111
+ expect :return
1112
+ unless showNext.is_a?(:semicolon)
1113
+ ret.expr=parse_expression
1114
+ end
1115
+ expect :semicolon
1116
+ return ret
1117
+ end
1118
+
1119
+ def parse_assert
1120
+ ret=Assert.new
1121
+ expect :assert
1122
+ ret.cond=parse_expression
1123
+ if showNext.is_a?(:report)
1124
+ ret.report=parse_report
1125
+ end
1126
+ if showNext.is_a?(:severity)
1127
+ ret.severity=parse_severity
1128
+ end
1129
+ expect(:semicolon) unless ret.report
1130
+ ret
1131
+ end
1132
+
1133
+ def parse_severity
1134
+ if showNext.is_a?(:severity)
1135
+ ret=Severity.new
1136
+ acceptIt
1137
+ if showNext.is_a? severity=[:warning,:note,:error,:failure]
1138
+ ret.type=acceptIt
1139
+ else
1140
+ raise "ERROR : expecting one of #{severity.join(',')}. Got : #{showNext.val}[#{showNext.kind}]"
1141
+ end
1142
+ end
1143
+ end
1144
+
1145
+ def parse_loop #unusual loop...end loop
1146
+ expect :loop
1147
+ parse_body
1148
+ expect :end
1149
+ expect :loop
1150
+ maybe :ident
1151
+ expect :semicolon
1152
+ end
1153
+
1154
+ #EXIT [ loop_label ] [ WHEN condition ] ;
1155
+ def parse_exit
1156
+ expect :exit
1157
+ if showNext.is_a?(:ident)
1158
+ acceptIt
1159
+ end
1160
+ if showNext.is_a?(:when)
1161
+ acceptIt
1162
+ parse_expression
1163
+ end
1164
+ expect :semicolon
1165
+ end
1166
+
1167
+ # ============================= expression ===============================
1168
+ def parse_expression
1169
+ e=parse_additive
1170
+ e=fix_corner_case(e) # things like => zero := not (or e_in.write_data);
1171
+ e
1172
+ end
1173
+
1174
+ # z(0) := or (rs(15 downto 0));
1175
+ # zero := not (or e_in.write_data);
1176
+ def fix_corner_case e
1177
+ case e
1178
+ when Binary
1179
+ if e.lhs.nil?
1180
+ ret=FuncCall.new
1181
+ ret.name=Ident.new(Vertigo::Token.create(:ident,e.op.val))
1182
+ case parenth=e.rhs
1183
+ when Parenth
1184
+ ret.actual_args=[parenth.expr].flatten
1185
+ else
1186
+ ret.actual_args=[e.rhs].flatten
1187
+ end
1188
+ return ret
1189
+ end
1190
+ end
1191
+ e
1192
+ end
1193
+
1194
+ ADDITIV_OP =[:add,:sub, :or, :xor,:xnor, :nor] #xor ?
1195
+ def parse_additive
1196
+ t1=parse_multiplicative
1197
+ while more? && showNext.is_a?(ADDITIV_OP)
1198
+ op=acceptIt #full token
1199
+ t2=parse_multiplicative
1200
+ t1=Binary.new(t1,op,t2)
1201
+ end
1202
+ return t1
1203
+ end
1204
+
1205
+ MULTITIV_OP=[:mul,:div,:mod,:and,:nand,:shiftr,:shiftl,:exp] #exp ?
1206
+ def parse_multiplicative
1207
+ t1=parse_comparative
1208
+ while more? && showNext.is_a?(MULTITIV_OP)
1209
+ op=acceptIt
1210
+ t2=parse_comparative
1211
+ t1=Binary.new(t1,op,t2)
1212
+ end
1213
+ return t1
1214
+ end
1215
+
1216
+ COMPARISON_OP=[:eq,:neq,:gt,:gte,:lt,:lte,:leq]
1217
+ def parse_comparative
1218
+ t1=parse_term
1219
+ while more? && showNext.is_a?(COMPARISON_OP)
1220
+ op=acceptIt
1221
+ t2=parse_term
1222
+ t1=Binary.new(t1,op,t2)
1223
+ end
1224
+ return t1
1225
+ end
1226
+
1227
+
1228
+ def parse_term
1229
+ if showNext.is_a? [:ident,:dot,:integer,:natural,:positive,:decimal_literal,:based_literal,:char_literal,:string_literal,:true,:false,:bit_string_literal,:lparen,:others,:abs,:not,:sub,:open]
1230
+ case showNext.kind
1231
+ when :ident
1232
+ ret=Ident.new(acceptIt)
1233
+ when :lparen
1234
+ ret=parse_parenth
1235
+ when :not,:abs,:sub
1236
+ ret=parse_unary
1237
+ when :decimal_literal
1238
+ ret=IntLit.new(acceptIt)
1239
+ when :char_literal
1240
+ ret=CharLit.new(acceptIt)
1241
+ when :string_literal,:bit_string_literal,:based_literal
1242
+ ret=acceptIt
1243
+ when :true,:false
1244
+ ret=BoolLit.new(acceptIt)
1245
+ when :others
1246
+ ret=acceptIt
1247
+ when :open
1248
+ ret=acceptIt
1249
+ when :integer,:natural,:positive
1250
+ ret=acceptIt
1251
+ else
1252
+ puts "cannot parse term : #{showNext} #{showNext.pos}"
1253
+ end
1254
+ end
1255
+ #pp showNext
1256
+ while showNext && showNext.is_a?([:lbrack,:dot,:attribute_literal,:lparen,:ns,:ps,:ms,:after,:ampersand,:tick])
1257
+ if par=sliced=parenthesized?
1258
+ case par
1259
+ when FuncCall
1260
+ par.name=ret
1261
+ ret=par
1262
+ when Sliced
1263
+ sliced.expr=ret
1264
+ ret=sliced
1265
+ end
1266
+ elsif selected_name=selected_name?
1267
+ selected_name.lhs=ret
1268
+ ret=selected_name
1269
+ elsif attribute=attributed?
1270
+ attribute.lhs=ret
1271
+ ret=attribute
1272
+ elsif timed=timed?
1273
+ timed.lhs=ret
1274
+ ret=timed
1275
+ elsif after=after?
1276
+ after.lhs=ret
1277
+ ret=after
1278
+ elsif concat=concat?
1279
+ concat.lhs=ret
1280
+ ret=concat
1281
+ elsif qualified=qualified?
1282
+ qualified.lhs=ret
1283
+ ret=qualified
1284
+ end
1285
+ end
1286
+ ret
1287
+ end
1288
+
1289
+ def print_tokens n
1290
+ require "colorize"
1291
+ pp @tokens[0..n-1].map{|tok| tok.val}.join(" ")
1292
+ end
1293
+
1294
+ # parenthesized expressions (NOT indexed or funcall)
1295
+ def parse_parenth
1296
+ ret=Parenth.new
1297
+ expect :lparen
1298
+ ret.expr=expr=parse_aggregate_part
1299
+ if aggregate=aggregated?
1300
+ aggregate.elements.unshift expr
1301
+ ret=aggregate
1302
+ end
1303
+ expect :rparen
1304
+ ret
1305
+ end
1306
+
1307
+ def aggregated?
1308
+ if showNext.is_a? [:comma]
1309
+ ret=Aggregate.new
1310
+ ret.pos=showNext.pos
1311
+ while showNext.is_a?(:comma)
1312
+ acceptIt
1313
+ ret << parse_aggregate_part
1314
+ end
1315
+ return ret
1316
+ end
1317
+ end
1318
+
1319
+ def parse_aggregate_part
1320
+ ret=parse_expression
1321
+ if showNext.is_a? [:downto,:to]
1322
+ dr=DiscreteRange.new
1323
+ dr.lhs=ret
1324
+ dr.dir=acceptIt
1325
+ dr.rhs=parse_expression
1326
+ ret=dr
1327
+ end
1328
+ if map=mapped?
1329
+ map.lhs=ret
1330
+ ret=map
1331
+ end
1332
+ ret
1333
+ end
1334
+
1335
+ #-----------------------------------------------------------------^ !!!! ..^......
1336
+ #req_laddr <= r0.addr(63 downto LINE_OFF_BITS) & (LINE_OFF_BITS-1 downto 0 => '0');
1337
+ #------------------------------------------------[ expr ]
1338
+ # NOT used ?
1339
+ def isolated_range?
1340
+ if showNext.is_a? [:downto,:to]
1341
+ acceptIt
1342
+ ret=IsolatedRange.new
1343
+ ret.rhs=parse_expression
1344
+ return ret
1345
+ end
1346
+ end
1347
+
1348
+ def mapped?
1349
+ if showNext.is_a?(:imply)
1350
+ acceptIt
1351
+ ret=Map.new
1352
+ ret.rhs=parse_expression
1353
+ return ret
1354
+ end
1355
+ end
1356
+
1357
+ def selected_name?
1358
+ while showNext.is_a? [:dot]
1359
+ ret=SelectedName.new
1360
+ acceptIt
1361
+ if showNext.is_a? [:ident,:all]
1362
+ case showNext.kind
1363
+ when :ident
1364
+ ret.rhs=Ident.new(acceptIt)
1365
+ when :all
1366
+ ret.rhs=acceptIt #all
1367
+ end
1368
+ return ret
1369
+ else
1370
+ raise "ERROR : expecting ident or 'all' at #{showNext.pos}"
1371
+ end
1372
+ end
1373
+ end
1374
+
1375
+ def parse_unary
1376
+ if showNext.is_a?([:not,:sub,:abs])
1377
+ acceptIt
1378
+ parse_expression
1379
+ end
1380
+ end
1381
+
1382
+ def timed?
1383
+ if showNext.is_a? [:ps,:ns,:ms]
1384
+ tok=acceptIt
1385
+ ret=Timed.new(nil,tok)
1386
+ end
1387
+ end
1388
+
1389
+ def parenthesized?
1390
+ if showNext.is_a? :lparen
1391
+ acceptIt
1392
+ ret=FuncCall.new
1393
+ args=[]
1394
+ while !showNext.is_a? :rparen
1395
+ args << parse_map()
1396
+ while showNext.is_a? :comma
1397
+ acceptIt
1398
+ args << parse_map()
1399
+ end
1400
+ ret.actual_args = args
1401
+ if showNext.is_a? [:downto,:to] #finally this was a Sliced !
1402
+ ret=Sliced.new
1403
+ ret.dir=acceptIt
1404
+ ret.rhs=parse_expression
1405
+ ret.lhs=args.first
1406
+ end
1407
+ end
1408
+ expect :rparen
1409
+
1410
+ return ret
1411
+ else
1412
+ return false
1413
+ end
1414
+ end
1415
+
1416
+ def initialized?
1417
+ if showNext.is_a?(:vassign)
1418
+ acceptIt
1419
+ return parse_expression
1420
+ end
1421
+ end
1422
+
1423
+ def after?
1424
+ if showNext.is_a?(:after)
1425
+ ret=After.new
1426
+ acceptIt
1427
+ ret.rhs=parse_expression
1428
+ return ret
1429
+ end
1430
+ end
1431
+
1432
+ def concat?
1433
+ if showNext.is_a?(:ampersand)
1434
+ ret=Concat.new
1435
+ acceptIt
1436
+ ret.rhs=parse_expression
1437
+ return ret
1438
+ end
1439
+ end
1440
+
1441
+ def attributed?
1442
+ if showNext.is_a?(:attribute_literal)
1443
+ ret=Attributed.new
1444
+ ret.rhs=acceptIt
1445
+ return ret
1446
+ end
1447
+ end
1448
+
1449
+ def qualified?
1450
+ if showNext.is_a?(:tick)
1451
+ acceptIt
1452
+ ret=Qualified.new
1453
+ ret.rhs=parse_expression
1454
+ return ret
1455
+ end
1456
+ end
1457
+ end
1458
+ end