HDLRuby 2.7.11 → 2.10.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.
@@ -0,0 +1,592 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'fileutils'
4
+ require 'tempfile'
5
+ require 'HDLRuby'
6
+ require 'HDLRuby/hruby_check.rb'
7
+ # require 'ripper'
8
+ require 'HDLRuby/hruby_low2hdr'
9
+ require 'HDLRuby/hruby_low2c'
10
+ require 'HDLRuby/hruby_low2vhd'
11
+ require 'HDLRuby/hruby_low_fix_types'
12
+ # require 'HDLRuby/hruby_low_expand_types' # For now dormant
13
+ require 'HDLRuby/hruby_low_without_outread'
14
+ require 'HDLRuby/hruby_low_with_bool'
15
+ require 'HDLRuby/hruby_low_bool2select'
16
+ require 'HDLRuby/hruby_low_without_select'
17
+ require 'HDLRuby/hruby_low_without_namespace'
18
+ require 'HDLRuby/hruby_low_without_bit2vector'
19
+ require 'HDLRuby/hruby_low_with_port'
20
+ require 'HDLRuby/hruby_low_with_var'
21
+ require 'HDLRuby/hruby_low_without_concat'
22
+ require 'HDLRuby/hruby_low_without_connection'
23
+ require 'HDLRuby/hruby_low_casts_without_expression'
24
+ require 'hruby_low_without_parinseq'
25
+ require 'HDLRuby/hruby_low_cleanup'
26
+
27
+ require 'HDLRuby/hruby_verilog.rb'
28
+
29
+ require 'HDLRuby/backend/hruby_allocator'
30
+ require 'HDLRuby/backend/hruby_c_allocator'
31
+
32
+ require 'HDLRuby/version.rb'
33
+
34
+ ##
35
+ # HDLRuby compiler interface program
36
+ #####################################
37
+
38
+ module HDLRuby
39
+
40
+
41
+
42
+ # Class for loading HDLRuby files.
43
+ class HDRLoad
44
+
45
+ # TOP_NAME = "__hdr_top_instance__"
46
+ TOP_NAME = "__"
47
+
48
+ # The top instance, only accessible after parsing the files.
49
+ attr_reader :top_instance
50
+
51
+ # The required files.
52
+ attr_reader :requires
53
+
54
+ # Creates a new loader for a +top_system+ system in file +top_file_name+
55
+ # from directory +dir+ with generic parameters +params+.
56
+ #
57
+ # NOTE: +top_file+ can either be a file or a file name.
58
+ def initialize(top_system,top_file,dir,*params)
59
+ # Sets the top and the looking directory.
60
+ @top_system = top_system.to_s
61
+ # @top_file can either be a file or a string giving the file name.
62
+ if top_file.respond_to?(:path) then
63
+ @top_file = top_file
64
+ @top_file_name = top_file.path
65
+ else
66
+ @top_file = nil
67
+ @top_file_name = top_file.to_s
68
+ end
69
+ @dir = dir.to_s
70
+ @params = params
71
+
72
+ # The list of the standard library files to exclude for
73
+ # checking.
74
+ # Get the directory of the HDLRuby and Ruby standard libraries.
75
+ @std_dirs = $LOAD_PATH
76
+ # @std_dirs << File.dirname(__FILE__) + "/std"
77
+ # # Gather the files with their path to std.
78
+ # @std_files = Dir[@std_dir + "/*"]
79
+
80
+ # The list of required files.
81
+ @requires = []
82
+
83
+ # The list of the code texts (the first one should be the one
84
+ # containing the top system).
85
+ @texts = []
86
+
87
+ # The list of the code checkers.
88
+ @checks = []
89
+
90
+ # The name of the top instance
91
+ @top_name = TOP_NAME
92
+ end
93
+
94
+ # Loads a single +file+.
95
+ #
96
+ # NOTE: +file+ can either be a file or a file name.
97
+ def read(file)
98
+ # Resolve the file.
99
+ if file.respond_to?(:read) then
100
+ found = file
101
+ else
102
+ found = File.join(@dir,file)
103
+ unless File.exist?(found) then
104
+ founds = Dir.glob(@std_dirs.map do |path|
105
+ File.join(path,file)
106
+ end)
107
+ if founds.empty? then
108
+ # No standard file with this name, this is an error.
109
+ raise "Unknown required file: #{file}."
110
+ else
111
+ # A standard file is found, skip it since it does not
112
+ # need to be read.
113
+ # show? "Standard files: #{founds}"
114
+ return false
115
+ end
116
+ end
117
+ end
118
+ # Load the file.
119
+ @texts << File.read(found)
120
+ if found.respond_to?(:path) then
121
+ @checks << Checker.new(@texts[-1],found.path)
122
+ else
123
+ @checks << Checker.new(@texts[-1])
124
+ end
125
+ return true
126
+ end
127
+
128
+ # Loads all the files from +file+.
129
+ def read_all(file = nil)
130
+ unless file then
131
+ if @top_file then
132
+ file = @top_file
133
+ else
134
+ file = @top_file_name
135
+ end
136
+ end
137
+ # show? "read_all with file=#{file}"
138
+ # Read the file
139
+ # read(file)
140
+ unless read(file) then
141
+ # The file is to skip.
142
+ return
143
+ end
144
+ # Get its required files.
145
+ requires = @checks[-1].get_all_requires +
146
+ @checks[-1].get_all_require_relatives
147
+ requires.each do |file|
148
+ read_all(file)
149
+ end
150
+ @requires += requires
151
+ @requires.uniq!
152
+ end
153
+
154
+ # Checks the read files.
155
+ def check_all
156
+ @checks.each { |check| check.assign_check }
157
+ end
158
+
159
+ # Displays the syntax tree of all the files.
160
+ def show_all(outfile = $stdout)
161
+ # show? "@checks.size=#{@checks.size}"
162
+ @checks.each { |check| check.show(outfile) }
163
+ end
164
+
165
+ # Gets the (first) top system.
166
+ def get_top
167
+ # Get all the systems.
168
+ systems = @checks.reduce([]) {|ar,check| ar + check.get_all_systems}
169
+ # show? "First systems=#{systems}"
170
+ # Remove the systems that are instantiated or included
171
+ # (they cannot be tops)
172
+ @checks.each do |check|
173
+ # The instances
174
+ check.get_all_instances(systems).each do |instance|
175
+ systems.delete(check.get_instance_system(instance))
176
+ end
177
+ # The explicitly included systems
178
+ check.get_all_includes(systems).each do |included|
179
+ systems.delete(check.get_include_system(included))
180
+ end
181
+ # The system included when declaring (inheritance)
182
+ check.get_all_inherits(systems).each do |inherit|
183
+ systems -= check.get_inherit_systems(inherit)
184
+ end
185
+ end
186
+ # show? "Now systems=#{systems}"
187
+ # Return the first top of the list.
188
+ return systems[-1]
189
+ end
190
+
191
+
192
+ # Load the HDLRuby structure from an instance of the top module.
193
+ def parse
194
+ # Is there a top system specified yet?
195
+ if @top_system == "" then
196
+ # No, look for it.
197
+ @top_system = get_top
198
+ # show? "@top_system=#{@top_system}"
199
+ unless @top_system then
200
+ # Not found? Error.
201
+ # Maybe it is a parse error, look for it.
202
+ bind = TOPLEVEL_BINDING.clone
203
+ eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
204
+ eval(@texts[0],bind,@top_file_name,1)
205
+ # No parse error found.
206
+ raise "Cannot find a top system." unless @top_system
207
+ end
208
+ end
209
+ # Initialize the environment for processing the hdr file.
210
+ bind = TOPLEVEL_BINDING.clone
211
+ eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
212
+ # Process it.
213
+ eval(@texts[0],bind,@top_file_name,1)
214
+ # Get the resulting instance
215
+ if @params.empty? then
216
+ # There is no generic parameter
217
+ @top_instance =
218
+ eval("#{@top_system} :#{@top_name}\n#{@top_name}",bind)
219
+ else
220
+ # There are generic parameters
221
+ @top_instance =
222
+ # eval("#{@top_system} :#{@top_name},#{@params.join(",")}\n#{@top_name}",bind)
223
+ eval("#{@top_system}(#{@params.join(",")}).(:#{@top_name})\n#{@top_name}",bind)
224
+ end
225
+ end
226
+ end
227
+
228
+
229
+ # Extend the Code class with generation of file for the content.
230
+ class HDLRuby::Low::Code
231
+
232
+ ## Creates a file in +path+ containing the content of the code.
233
+ def to_file(path = "")
234
+ self.each_chunk do |chunk|
235
+ # Process the lumps of the chunk.
236
+ # NOTE: for now use the C code generation of Low2C
237
+ content = chunk.to_c
238
+ # Dump to a file.
239
+ if chunk.name != :sim then
240
+ # The chunk is to be dumbed to a file.
241
+ # show? "Outputing chunk:#{HDLRuby::Low::Low2C.obj_name(chunk)}"
242
+ outfile = File.open(path + "/" +
243
+ HDLRuby::Low::Low2C.obj_name(chunk) + "." +
244
+ chunk.name.to_s,"w")
245
+ outfile << content
246
+ outfile.close
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+
253
+ end
254
+
255
+ # Locate an executable from cmd.
256
+ def which(cmd)
257
+ # Get the possible exetensions (for windows case).
258
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
259
+ # Look for the command within the executable paths.
260
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
261
+ exts.each do |ext|
262
+ exe = File.join(path, "#{cmd}#{ext}")
263
+ return exe if File.executable?(exe) && !File.directory?(exe)
264
+ end
265
+ end
266
+ nil
267
+ end
268
+
269
+
270
+
271
+ if __FILE__ == $0 then
272
+ # From hdrcc.rb
273
+ $hdr_dir = File.dirname(__FILE__)
274
+ else
275
+ # Form hdrcc
276
+ $hdr_dir = File.dirname(Gem.bin_path("HDLRuby","hdrcc")).chomp("exe") +
277
+ "lib/HDLRuby"
278
+ end
279
+
280
+ include HDLRuby
281
+
282
+
283
+ def hdr_test
284
+ $top = "__test__"
285
+ tests = $options[:test]
286
+ if tests then
287
+ tests = tests.to_s.split(",")
288
+ tests.map! {|test| ":\"#{test}\"" }
289
+ tests = ", #{tests.join(",")}"
290
+ else
291
+ tests = ""
292
+ end
293
+ # Generate the unit test file.
294
+ $test_file = Tempfile.new('tester.rb',Dir.getwd)
295
+ $test_file.write("require 'std/hruby_unit.rb'\nrequire_relative '#{$input}'\n\n" +
296
+ "HDLRuby::Unit.test(:\"#{$top}\"#{tests})\n")
297
+ # $test_file.rewind
298
+ # show? $test_file.read
299
+ # exit
300
+ $test_file.rewind
301
+ # It is the new input file.
302
+ $input = $test_file
303
+ end
304
+
305
+ # Sets the options.
306
+ $options = {}
307
+
308
+ # Sets the default input name.
309
+ $input = "top_system"
310
+
311
+ # Open the output.
312
+ $output = "HDLRubyWorkspace"
313
+
314
+ def hdr_output(output = $output)
315
+ # Create a directory if necessary.
316
+ unless File.directory?($output)
317
+ FileUtils.mkdir_p($output)
318
+ end
319
+ end
320
+
321
+ hdr_output
322
+
323
+ # Read some files.
324
+ def hdr_load(input)
325
+ # loader = HDRLoad.new($top,input,"./",*params)
326
+ # loader.read_all
327
+ # loader.check_all
328
+ # # Not debug mode, use the error management.
329
+ # error_manager(loader.requires + [input]) { top_instance = loader.parse }
330
+ # $top_system = top_instance.to_low.systemT
331
+ # $top_intance = nil # Free as much memory as possible.
332
+ load(input)
333
+ end
334
+
335
+
336
+ # Process a system for generation.
337
+ def hdr_make(sys,params = [])
338
+ if sys.is_a?(SystemI) then
339
+ $top_system = sys.to_low.systemT
340
+ elsif params.empty? then
341
+ $top_system = sys.(HDLRuby.uniq_name).to_low.systemT
342
+ else
343
+ $top_system = sys.(*params).(HDLRuby.uniq_name).to_low.systemT
344
+ end
345
+ end
346
+
347
+ $non_hdlruby = []
348
+
349
+ def hdr_code
350
+ # Gather the non-HDLRuby code.
351
+ $top_system.each_systemT_deep do |systemT|
352
+ systemT.scope.each_scope_deep do |scope|
353
+ scope.each_code do |code|
354
+ non_hdlruby << code
355
+ end
356
+ end
357
+ end
358
+ # Generates its code.
359
+ $non_hdlruby.each {|code| code.to_file($output) }
360
+ end
361
+
362
+
363
+ def hdr_yaml
364
+ puts $top_system.to_yaml
365
+ end
366
+
367
+ def hdr_hdr
368
+ puts $top_system.to_hdr
369
+ end
370
+
371
+ def hdr_sim
372
+ $top_system.each_systemT_deep do |systemT|
373
+ HDLRuby.show "seq2seq step..."
374
+ # Coverts the par blocks in seq blocks to seq blocks to match
375
+ # the simulation engine.
376
+ systemT.par_in_seq2seq!
377
+ HDLRuby.show Time.now
378
+ HDLRuby.show "connections_to_behaviors step..."
379
+ # Converts the connections to behaviors.
380
+ systemT.connections_to_behaviors!
381
+ HDLRuby.show Time.now
382
+ # Break the RefConcat.
383
+ HDLRuby.show "concat_assigns step..."
384
+ systemT.break_concat_assigns!
385
+ HDLRuby.show Time.now
386
+ # Explicits the types.
387
+ HDLRuby.show "explicit_types step..."
388
+ systemT.explicit_types!
389
+ HDLRuby.show Time.now
390
+ end
391
+ # Generate the C.
392
+ # Get the base name of the input file, it will be used for
393
+ # generating the main name of the multiple result files.
394
+ $basename = File.basename($input,File.extname($input))
395
+ $basename = $output + "/" + $basename
396
+ # Multiple files generation mode.
397
+ # Generate the h file.
398
+ $hname = $output + "/hruby_sim_gen.h"
399
+ $hnames = [ File.basename($hname) ]
400
+ $outfile = File.open($hname,"w")
401
+ # Adds the generated globals
402
+ $top_system.each_systemT_deep do |systemT|
403
+ systemT.to_ch($outfile)
404
+ # # # Close the file.
405
+ # # output.close
406
+ # # # Clears the name.
407
+ # # hname = nil
408
+ end
409
+ # Adds the globals from the non-HDLRuby code
410
+ $non_hdlruby.each do |code|
411
+ code.each_chunk do |chunk|
412
+ if chunk.name == :sim then
413
+ $outfile << "extern "
414
+ $outfile << HDLRuby::Low::Low2C.prototype(chunk.to_c(""))
415
+ end
416
+ end
417
+ end
418
+ $outfile.close
419
+
420
+ # Prepare the initial name for the main file.
421
+ $name = $basename + ".c"
422
+ # Generate the code for it.
423
+ $main = File.open($name,"w")
424
+
425
+ # Select the vizualizer depending on the options.
426
+ init_visualizer = $options[:vcd] ? "init_vcd_visualizer" :
427
+ "init_default_visualizer"
428
+
429
+ # Gather the system to generate and sort them in the right order
430
+ # to ensure references are generated before being used.
431
+ # Base: reverse order of the tree.
432
+ # Then, multiple configuration of a system instance must be
433
+ # reverversed so that the base configuration is generated first.
434
+ c_systems = $top_system.each_systemT_deep_ref
435
+ # Generate the code of the main function.
436
+ # HDLRuby start code
437
+ $main << HDLRuby::Low::Low2C.main("hruby_simulator",
438
+ init_visualizer,
439
+ $top_system,
440
+ c_systems,
441
+ $hnames)
442
+ $main.close
443
+
444
+ $top_system.each_systemT_deep do |systemT|
445
+ # For the c file.
446
+ name = $output + "/" +
447
+ HDLRuby::Low::Low2C.c_name(systemT.name) +
448
+ ".c"
449
+ # show? "for systemT=#{systemT.name} generating: #{name}"
450
+ # Open the file for current systemT
451
+ outfile = File.open(name,"w")
452
+ # Generate the C code in to.
453
+ # outfile << systemT.to_c(0,*$hnames)
454
+ systemT.to_c(outfile,0,*$hnames)
455
+ # Close the file.
456
+ outfile.close
457
+ # Clears the name.
458
+ name = nil
459
+ end
460
+
461
+ # Simulation mode, compile and exectute.
462
+ # Path of the simulator core files.
463
+ $simdir = $hdr_dir + "/sim/"
464
+ # Generate and execute the simulation commands.
465
+ # Kernel.system("cp -n #{simdir}* #{$output}/; cd #{$output}/ ; make -s ; ./hruby_simulator")
466
+ Dir.entries($simdir).each do |filename|
467
+ if !File.directory?(filename) && /\.[ch]$/ === filename then
468
+ FileUtils.cp($simdir + "/" + filename,$output)
469
+ end
470
+ end
471
+ Dir.chdir($output)
472
+ # Find the compiler.
473
+ cc_cmd = which('cc')
474
+ unless cc_cmd then
475
+ cc_cmd = which('gcc')
476
+ end
477
+ unless cc_cmd then
478
+ raise "Could not find any compiler, please compile by hand as follows:\n" +
479
+ " In folder #{$output} execute:\n" +
480
+ " <my compiler> -o hruby_simulator *.c -lpthread\n" +
481
+ " Then execute:\n hruby_simulator"
482
+ end
483
+ # Use it.
484
+ Kernel.system("#{cc_cmd} -o3 -o hruby_simulator *.c -lpthread")
485
+ Kernel.system("./hruby_simulator")
486
+ Dir.chdir("..")
487
+ end
488
+
489
+ def hdr_verilog
490
+ # Make description compatible with verilog generation.
491
+ $top_system.each_systemT_deep do |systemT|
492
+ # HDLRuby.show "casts_without_expression! step..."
493
+ # systemT.casts_without_expression!
494
+ # HDLRuby.show Time.now
495
+ HDLRuby.show "to_upper_space! step..."
496
+ systemT.to_upper_space!
497
+ HDLRuby.show Time.now
498
+ end
499
+ HDLRuby.show "to_global_space! step (global)..."
500
+ $top_system.to_global_systemTs!
501
+ HDLRuby.show Time.now
502
+ $top_system.each_systemT_deep do |systemT|
503
+ ## systemT.break_types!
504
+ ## systemT.expand_types!
505
+ HDLRuby.show "par_in_seq2seq! step..."
506
+ systemT.par_in_seq2seq!
507
+ HDLRuby.show Time.now
508
+ HDLRuby.show "initial_concat_to_timed! step..."
509
+ systemT.initial_concat_to_timed!
510
+ HDLRuby.show Time.now
511
+ HDLRuby.show "with_port! step..."
512
+ systemT.with_port!
513
+ HDLRuby.show Time.now
514
+ end
515
+ # # Verilog generation
516
+ # $output << top_system.to_verilog
517
+ # Generate the Verilog.
518
+ # Get the base name of the input file, it will be used for
519
+ # generating the main name of the multiple result files.
520
+ $basename = File.basename($input,File.extname($input))
521
+ $basename = $output + "/" + $basename
522
+ # # File name counter.
523
+ # $namecount = 0
524
+ # Prepare the initial name for the main file.
525
+ $name = $basename + ".v"
526
+ # Multiple files generation mode.
527
+ $top_system.each_systemT_deep do |systemT|
528
+ # Generate the name if necessary.
529
+ unless $name
530
+ $name = $output + "/" +
531
+ HDLRuby::Verilog.name_to_verilog(systemT.name) +
532
+ ".v"
533
+ end
534
+ # Open the file for current systemT
535
+ outfile = File.open($name,"w")
536
+ # Generate the Verilog code in to.
537
+ outfile << systemT.to_verilog
538
+ # Close the file.
539
+ outfile.close
540
+ # Clears the name.
541
+ $name = nil
542
+ end
543
+ end
544
+
545
+ def hdr_vhdl
546
+ # top_system = $top_instance.to_low.systemT
547
+ # top_system = $top_system
548
+ # Make description compatible with vhdl generation.
549
+ $top_system.each_systemT_deep do |systemT|
550
+ systemT.outread2inner! unless $options[:vhdl08] || $options[:alliance]
551
+ systemT.with_boolean!
552
+ systemT.boolean_in_assign2select! unless $options[:alliance]
553
+ systemT.bit2vector2inner! unless $options[:vhdl08] || $options[:alliance]
554
+ systemT.select2case! # if $options[:alliance]
555
+ systemT.break_concat_assigns! # if $options[:alliance]
556
+ systemT.to_upper_space!
557
+ systemT.to_global_systemTs!
558
+ systemT.break_types!
559
+ systemT.with_port!
560
+ systemT.with_var!
561
+ systemT.cleanup!
562
+ end
563
+ # Generate the vhdl.
564
+ # Get the base name of the input file, it will be used for
565
+ # generating the main name of the multiple result files.
566
+ $basename = File.basename($input,File.extname($input))
567
+ $basename = $output + "/" + $basename
568
+ # # File name counter.
569
+ # $namecount = 0
570
+ # Prepare the initial name for the main file.
571
+ $name = $basename + ".vhd"
572
+ # Multiple files generation mode.
573
+ $top_system.each_systemT_deep do |systemT|
574
+ # Generate the name if necessary.
575
+ unless $name
576
+ $name = $output + "/" +
577
+ HDLRuby::Low::Low2VHDL.entity_name(systemT.name) +
578
+ ".vhd"
579
+ end
580
+ # Open the file for current systemT
581
+ outfile = File.open($name,"w")
582
+ # Generate the VHDL code in to.
583
+ outfile << systemT.to_vhdl
584
+ # Close the file.
585
+ outfile.close
586
+ # Clears the name.
587
+ $name = nil
588
+ end
589
+ end
590
+
591
+
592
+ configure_high