vertigo_vhdl 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.
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