HDLRuby 2.4.26 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f20b0aa1f19499dddcec1f7eedcff464ed1e440a323c181df7d908730899bb8
4
- data.tar.gz: 512b16d80eb0621270e516ffa51c9d2b6b2b61d93842fb02a4cdeb5a1a71d5bc
3
+ metadata.gz: 53e83131d2fb3a3f03c085a3139a69d70f4422ade7be950d009e97e17bb92490
4
+ data.tar.gz: dcbbcbf3bd1e5aa43ac359e502dc0da6dec886d115371f3b2fceead01bcaa9d3
5
5
  SHA512:
6
- metadata.gz: 81250f799e3e102a155fce24aeb29cfc00e254cd0e0568162f103bbccaeb8bfcc82f3f2cb43ad6fe2eb120801c55e35e631e39d10280df98b137d0f85f8df5cd
7
- data.tar.gz: 5dff6e40cf54495703b7d3825f25776c0a1d1fdd7243f93ff85c8466e2f9ee1713b2a403efe3092dc5f451d5b9ba0260ffcba6f5fed1edb68edb49115d082dd0
6
+ metadata.gz: 1656a5763fef86bd1b8c01eff8d377cc94ff3145889fd486fac99ac7d86b6f6671a30e040679f81da6a76bc08ee09ff5babd11cae72fc8adb721f0258e724fb9
7
+ data.tar.gz: 8f83372948477da9374abf302ab3910d73b434b22aa020b25071f2ed9127dc7ee95b3c6959952bd9ec008f1ff17327c7edc9e1b9584d1437a530a753b0886f4d
@@ -0,0 +1,79 @@
1
+ require "HDLRuby/template_expander"
2
+
3
+ ##
4
+ # XCD file generator from 'xcd' properties
5
+ ##########################################
6
+
7
+
8
+ # Generates a xcd file from the HDLRuby objects from +top+ using
9
+ # their 'xcd' properties.
10
+ # The file is saved in +path+ directory.
11
+ def xcd_generator(top, path)
12
+ # Ensure top is a system.
13
+ if top.is_a?(HDLRuby::Low::SystemI) then
14
+ top = top.systemT
15
+ elsif !top.is_a?(HDLRuby::Low::SystemT) then
16
+ raise "The 'xcd_generator' driver can only be applied on SystemT objects."
17
+ end
18
+
19
+ # Get the name of the resulting file if any.
20
+ if (top.properties.key?(:xcd_file)) then
21
+ xcd_file = top.properties[:xcd_file].join
22
+ else
23
+ # Default file name.
24
+ xcd_file = "default.xcd"
25
+ end
26
+
27
+ # Get the target template.
28
+ xcd_target = top.properties[:xcd_target].join
29
+ xcd_target_name = xcd_target
30
+ xcd_target_name += ".xcd" unless xcd_target_name.end_with?(".xcd")
31
+ xcd_target_tries = [ xcd_target_name,
32
+ File.join(path,xcd_target_name),
33
+ File.join(File.dirname(__FILE__),"xcd",xcd_target_name) ]
34
+ xcd_target_file = xcd_target_tries.find { |fname| File.exist?(fname) }
35
+ unless xcd_target_file then
36
+ raise "XCD target template not found for #{xcd_target}."
37
+ end
38
+ # Load the template.
39
+ template = File.read(xcd_target_file)
40
+
41
+ # Gather the signals by xcd key.
42
+ xcd2sig = top.each_signal.reduce([]) do |ar,sig|
43
+ ar += sig.properties.each_with_key(:xcd).map do |val|
44
+ [val,sig.name.to_s]
45
+ end
46
+ end
47
+
48
+ # Create the template expander that will generate the xcd file.
49
+ expander = TemplateExpander.new([
50
+ [ /^\?.*(\n|\z)/, proc do |str| # Signal link to port
51
+ if xcd2sig.any? do |match,rep|
52
+ if str.include?(match) then
53
+ str = str.gsub("<>",rep)[1..-1]
54
+ else
55
+ false
56
+ end
57
+ end then
58
+ str
59
+ else
60
+ ""
61
+ end
62
+ end ]
63
+ ])
64
+
65
+ # # Generate the xcd file.
66
+ # File.open(File.join(path,xcd_file),"w") do |file|
67
+ # # Generate the signals mapping.
68
+ # top.each_signal do |signal|
69
+ # signal.properties.each_with_key(:xcd) do |value|
70
+ # file << "#{value}\n"
71
+ # end
72
+ # end
73
+ # end
74
+
75
+ # Generate the xcd file.
76
+ File.open(File.join(path,xcd_file),"w") do |file|
77
+ expander.expand(template,file)
78
+ end
79
+ end
@@ -0,0 +1,4 @@
1
+ <Dummy xcd template>
2
+ ?<PORT <> CLK>
3
+ ?<PORT <> RST>
4
+
@@ -0,0 +1,19 @@
1
+ # A simple D-FF
2
+ system :dff do
3
+ input :clk, :rst, :d
4
+ output :q, :qb
5
+
6
+ qb <= ~q
7
+
8
+ par(clk.posedge) { q <= d & ~rst }
9
+
10
+ clk.properties[:xcd] = "CLK"
11
+ rst.properties[:xcd] = "RST"
12
+ d.properties[:xcd] = "PORT0"
13
+ q.properties[:xcd] = "PORT1"
14
+ qb.properties[:xcd] = "PORT2"
15
+ cur_system.properties[:xcd_target] = "dummy"
16
+ cur_system.properties[:xcd_file] = "dff.xcd"
17
+ cur_system.properties[:post_driver] = "drivers/xcd.rb", :xcd_generator
18
+ end
19
+
@@ -0,0 +1,54 @@
1
+ # Testing HDLRuby unit test.
2
+ # require 'hruby_unit.rb'
3
+
4
+ # Declare multiple simple dff-systems and their corresponding test.
5
+
6
+ 1.times do |i|
7
+
8
+ # A simple D-FF
9
+ system:"dff#{i}" do
10
+ input :clk, :rst, :d
11
+ output :q, :qb
12
+
13
+ qb <= ~q
14
+
15
+ par(clk.posedge) { q <= d & ~rst }
16
+ end
17
+
18
+ # Code for testing it.
19
+ Unit.system :"test_dff#{i}" do
20
+ inner :clk, :rst, :d, :q, :qb
21
+
22
+ send(:"dff#{i}",:dffI).(clk,rst,d,q,qb)
23
+
24
+ timed do
25
+ clk <= 0
26
+ rst <= 0
27
+ d <= 0
28
+ !10.ns
29
+ clk <= 1
30
+ !10.ns
31
+ clk <= 0
32
+ rst <= 1
33
+ !10.ns
34
+ clk <= 1
35
+ !10.ns
36
+ clk <= 0
37
+ rst <= 0
38
+ !10.ns
39
+ clk <= 1
40
+ !10.ns
41
+ clk <= 0
42
+ d <= 1
43
+ !10.ns
44
+ clk <= 1
45
+ !10.ns
46
+ clk <= 0
47
+ d <= 0
48
+ !10.ns
49
+ clk <= 1
50
+ !10.ns
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,59 @@
1
+ # require "../hruby_low2c.rb"
2
+
3
+
4
+
5
+ # A system for testing the execution of par block in seq block.
6
+ system :seqpar_bench do
7
+
8
+ inner :rst, :clk
9
+ signed[8].inner :a, :b, :c, :d
10
+ signed[8].inner :out
11
+
12
+ seq(clk.posedge) do
13
+ hif(rst) do
14
+ a <= 0
15
+ b <= 0
16
+ c <= 0
17
+ d <= 0
18
+ end
19
+ helse do
20
+ a <= a + 1
21
+ b <= a + 2
22
+ par do
23
+ c <= b + 3
24
+ d <= c + 4
25
+ end
26
+ a <= d + 5
27
+ end
28
+ end
29
+
30
+ out <= a
31
+
32
+ timed do
33
+ clk <= 0
34
+ rst <= 0
35
+ !20.ns
36
+ clk <= 1
37
+ !20.ns
38
+ clk <= 0
39
+ rst <= 1
40
+ !20.ns
41
+ clk <= 1
42
+ !20.ns
43
+ clk <= 0
44
+ rst <= 0
45
+ !20.ns
46
+ clk <= 1
47
+ !20.ns
48
+ clk <= 0
49
+ !20.ns
50
+ clk <= 1
51
+ !20.ns
52
+ clk <= 0
53
+ !20.ns
54
+ clk <= 1
55
+ !20.ns
56
+ clk <= 0
57
+ !20.ns
58
+ end
59
+ end
data/lib/HDLRuby/hdrcc.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  require 'fileutils'
4
+ require 'tempfile'
4
5
  require 'HDLRuby'
5
6
  require 'HDLRuby/hruby_check.rb'
6
7
  # require 'ripper'
@@ -20,6 +21,7 @@ require 'HDLRuby/hruby_low_with_var'
20
21
  require 'HDLRuby/hruby_low_without_concat'
21
22
  require 'HDLRuby/hruby_low_without_connection'
22
23
  require 'HDLRuby/hruby_low_casts_without_expression'
24
+ require 'hruby_low_without_parinseq'
23
25
  require 'HDLRuby/hruby_low_cleanup'
24
26
 
25
27
  require 'HDLRuby/hruby_verilog.rb'
@@ -49,12 +51,21 @@ module HDLRuby
49
51
  # The required files.
50
52
  attr_reader :requires
51
53
 
52
- # Creates a new loader for a +top_system+ system in file +top_file+
54
+ # Creates a new loader for a +top_system+ system in file +top_file_name+
53
55
  # from directory +dir+ with generic parameters +params+.
56
+ #
57
+ # NOTE: +top_file+ can either be a file or a file name.
54
58
  def initialize(top_system,top_file,dir,*params)
55
59
  # Sets the top and the looking directory.
56
60
  @top_system = top_system.to_s
57
- @top_file = top_file.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
58
69
  @dir = dir.to_s
59
70
  @params = params
60
71
 
@@ -81,31 +92,48 @@ module HDLRuby
81
92
  end
82
93
 
83
94
  # Loads a single +file+.
95
+ #
96
+ # NOTE: +file+ can either be a file or a file name.
84
97
  def read(file)
85
98
  # Resolve the file.
86
- found = File.join(@dir,file)
87
- unless File.exist?(found) then
88
- founds = Dir.glob(@std_dirs.map {|path| File.join(path,file) })
89
- if founds.empty? then
90
- # No standard file with this name, this is an error.
91
- raise "Unknown required file: #{file}."
92
- else
93
- # A standard file is found, skip it since it does not
94
- # need to be read.
95
- # puts "Standard files: #{founds}"
96
- return false
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
+ # puts "Standard files: #{founds}"
114
+ return false
115
+ end
97
116
  end
98
117
  end
99
118
  # Load the file.
100
- # @texts << File.read(File.join(@dir,file) )
101
119
  @texts << File.read(found)
102
- # @checks << Checker.new(@texts[-1],file)
103
- @checks << Checker.new(@texts[-1],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
104
125
  return true
105
126
  end
106
127
 
107
128
  # Loads all the files from +file+.
108
- def read_all(file = @top_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
109
137
  # puts "read_all with file=#{file}"
110
138
  # Read the file
111
139
  # read(file)
@@ -173,7 +201,7 @@ module HDLRuby
173
201
  # Maybe it is a parse error, look for it.
174
202
  bind = TOPLEVEL_BINDING.clone
175
203
  eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
176
- eval(@texts[0],bind,@top_file,1)
204
+ eval(@texts[0],bind,@top_file_name,1)
177
205
  # No parse error found.
178
206
  raise "Cannot find a top system." unless @top_system
179
207
  end
@@ -182,7 +210,7 @@ module HDLRuby
182
210
  bind = TOPLEVEL_BINDING.clone
183
211
  eval("require 'HDLRuby'\n\nconfigure_high\n\n",bind)
184
212
  # Process it.
185
- eval(@texts[0],bind,@top_file,1)
213
+ eval(@texts[0],bind,@top_file_name,1)
186
214
  # Get the resulting instance
187
215
  if @params.empty? then
188
216
  # There is no generic parameter
@@ -309,15 +337,18 @@ $optparse = OptionParser.new do |opts|
309
337
  opts.on("-D", "--debug","Set the HDLRuby debug mode") do |d|
310
338
  $options[:debug] = d
311
339
  end
340
+ opts.on("-T","--test","Compile the unit tests.") do |t|
341
+ $options[:test] = t
342
+ end
312
343
  opts.on("-t", "--top system", "Specify the top system to process") do|t|
313
344
  $options[:top] = t
314
345
  end
315
346
  opts.on("-p", "--param x,y,z", "Specify the generic parameters") do |p|
316
347
  $options[:param] = p
317
348
  end
318
- opts.on("--version", "Print the version number, then exit") do
319
- puts "hdrcc: HDLRuby #{HDLRuby::VERSION} compiler"
320
- exit
349
+ opts.on("--dump","Dump all the properties to yaml files") do |v|
350
+ $options[:dump] = v
351
+ $options[:multiple] = v
321
352
  end
322
353
  # opts.on_tail("-h", "--help", "Show this message") do
323
354
  opts.on("-h", "--help", "Show this message") do
@@ -369,6 +400,19 @@ if $input == nil then
369
400
  exit
370
401
  end
371
402
 
403
+ if ($options[:test]) then
404
+ $top = "__test__"
405
+ # Generate the unit test file.
406
+ $test_file = Tempfile.new('tester.rb',Dir.getwd)
407
+ $test_file.write("require 'hruby_unit.rb'\nrequire_relative '#{$input}'\n\n" +
408
+ "HDLRuby::Unit.test(\"#{$top}\")\n")
409
+ # $test_file.rewind
410
+ # puts $test_file.read
411
+ $test_file.rewind
412
+ # It is the new input file.
413
+ $input = $test_file
414
+ end
415
+
372
416
  # Open the output.
373
417
  if $output then
374
418
  if $options[:multiple] then
@@ -393,6 +437,12 @@ $loader = HDRLoad.new($top,$input,$options[:directory].to_s,*$params)
393
437
  $loader.read_all
394
438
  $loader.check_all
395
439
 
440
+ # Remove the test file if any, it is not needed any longer.
441
+ if $test_file then
442
+ $test_file.close
443
+ $test_file.unlink
444
+ end
445
+
396
446
  if $options[:syntax] then
397
447
  if $options[:multiple] then
398
448
  raise "Multiple files generation mode not supported for syntax tree output."
@@ -460,6 +510,9 @@ elsif $options[:clang] then
460
510
  # top_system = $top_system
461
511
  # Preprocess the HW description for valid C generation.
462
512
  $top_system.each_systemT_deep do |systemT|
513
+ # Coverts the par blocks in seq blocks to seq blocks to match
514
+ # the simulation engine.
515
+ systemT.par_in_seq2seq!
463
516
  # Converts the connections to behaviors.
464
517
  systemT.connections_to_behaviors!
465
518
  # Break the RefConcat.
@@ -583,6 +636,7 @@ elsif $options[:verilog] then
583
636
  systemT.to_global_systemTs!
584
637
  # systemT.break_types!
585
638
  # systemT.expand_types!
639
+ systemT.par_in_seq2seq!
586
640
  systemT.initial_concat_to_timed!
587
641
  systemT.with_port!
588
642
  end
@@ -673,3 +727,31 @@ elsif $options[:vhdl] then
673
727
  end
674
728
  end
675
729
  end
730
+
731
+ # Apply the post drivers if any.
732
+ Hdecorator.each_with_property(:post_driver) do |obj, value|
733
+ # Load the driver.
734
+ require_relative(value[0].to_s)
735
+ # Execute it.
736
+ send(value[1].to_sym,obj,$output)
737
+ end
738
+
739
+ # Dump the properties
740
+ if $options[:dump] then
741
+ # Decorate with the parent ids.
742
+ Hdecorator.decorate_parent_id
743
+
744
+ # Generate the directory for the properties
745
+ property_dir = $output + "/properties"
746
+ unless File.directory?(property_dir)
747
+ FileUtils.mkdir_p(property_dir)
748
+ end
749
+
750
+ # Dump to one file per key
751
+ Properties.each_key do |key|
752
+ File.open(property_dir + "/#{key}.yaml", "w") do |f|
753
+ Hdecorator.dump(key,f)
754
+ end
755
+ end
756
+
757
+ end