HDLRuby 2.2.16 → 2.3.3

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,69 @@
1
+ require 'std/loop.rb'
2
+
3
+ include HDLRuby::High::Std
4
+
5
+ system :with_loop do
6
+
7
+ # The clock and reset
8
+ inner :clk, :rst
9
+ # The running signals.
10
+ inner :doit0, :doit1
11
+ # The signal to check for finishing.
12
+ inner :over
13
+
14
+ # A counter.
15
+ [8].inner :count, :count2
16
+
17
+ # The first loop: basic while.
18
+ lp0 = while_loop(clk, proc{count<=0}, count<15) { count <= count + 1 }
19
+
20
+ # The second loop: 10 times.
21
+ lp1 = times_loop(clk,10) { count2 <= count2+2 }
22
+ # Control it using doit1 as req and over as ack.
23
+ rst_req_ack(clk.posedge,rst,doit1,over,lp1)
24
+
25
+ par(clk.posedge) do
26
+ doit1 <= 0
27
+ hif(rst) do
28
+ lp0.reset()
29
+ # lp1.reset()
30
+ # doit1 <= 0
31
+ count2 <= 0
32
+ over <= 0
33
+ end
34
+ helse do
35
+ hif(doit0) { lp0.run }
36
+ lp0.finish { doit0 <= 0; doit1 <= 1 }# ; lp1.run }
37
+ hif(doit1) { lp1.run; lp0.reset() }
38
+ # lp1.finish { over <= 1; doit1 <= 0 }
39
+ # Second pass for first loop.
40
+ hif(over) { lp0.run }
41
+ end
42
+ end
43
+
44
+ timed do
45
+ clk <= 0
46
+ rst <= 0
47
+ doit0 <= 0
48
+ !10.ns
49
+ clk <= 1
50
+ !10.ns
51
+ clk <= 0
52
+ rst <= 1
53
+ !10.ns
54
+ clk <= 1
55
+ !10.ns
56
+ clk <= 0
57
+ rst <= 0
58
+ doit0 <= 1
59
+ !10.ns
60
+ clk <= 1
61
+ !10.ns
62
+ 64.times do
63
+ clk <= 0
64
+ !10.ns
65
+ clk <= 1
66
+ !10.ns
67
+ end
68
+ end
69
+ end
@@ -108,16 +108,26 @@ system :mem_test do
108
108
  end
109
109
 
110
110
 
111
- [8].inner :sum
111
+ [8].inner :sum0, :sum1
112
112
 
113
113
  # Declares a dual edge 8-bit data and address memory.
114
114
  mem_dual([8],256,clk,rst, raddr: :rst,waddr: :rst).(:memDI)
115
115
 
116
116
  # Instantiate the producer to access port waddr of the memory.
117
- producer(memDI.branch(:waddr)).(:producerI).(clk,rst)
117
+ producer(memDI.branch(:waddr)).(:producerI0).(clk,rst)
118
118
 
119
119
  # Instantiate the producer to access port raddr of the memory.
120
- consumer(memDI.branch(:raddr)).(:consumerI).(clk,rst,sum)
120
+ consumer(memDI.branch(:raddr)).(:consumerI0).(clk,rst,sum0)
121
+
122
+
123
+ # Declares a 4-bank 8-bit data and address memory.
124
+ mem_bank([8],4,256/4,clk,rst, raddr: :rst, waddr: :rst).(:memBI)
125
+
126
+ # Instantiate the producer to access port waddr of the memory.
127
+ producer(memBI.branch(:waddr)).(:producerI1).(clk,rst)
128
+
129
+ # Instantiate the producer to access port raddr of the memory.
130
+ consumer(memBI.branch(:raddr)).(:consumerI1).(clk,rst,sum1)
121
131
 
122
132
 
123
133
  end
@@ -113,12 +113,9 @@ module HDLRuby
113
113
  return
114
114
  end
115
115
  # Get its required files.
116
- requires = @checks[-1].get_all_requires
116
+ requires = @checks[-1].get_all_requires +
117
+ @checks[-1].get_all_require_relatives
117
118
  requires.each do |file|
118
- # if file != "HDLRuby" &&
119
- # !@std_files.find { |std| std.include?(file) } then
120
- # read_all(file)
121
- # end
122
119
  read_all(file)
123
120
  end
124
121
  @requires += requires
@@ -244,7 +241,7 @@ include HDLRuby
244
241
  # Process the command line options
245
242
  $options = {}
246
243
  $optparse = OptionParser.new do |opts|
247
- opts.banner = "Usage: hdrcc.rb [options] <input file> [<output file>]"
244
+ opts.banner = "Usage: hdrcc.rb [options] <input file> [<output directory or file>]"
248
245
 
249
246
  opts.separator ""
250
247
  opts.separator "Where:"
@@ -326,18 +323,17 @@ $optparse = OptionParser.new do |opts|
326
323
  opts.separator ""
327
324
  opts.separator "Notice:"
328
325
  opts.separator "* If no output option is given, simply checks the input file"
329
- opts.separator "* If no output file is given, the result is given through the standard output."
330
326
  opts.separator "* If no top system is given, it will be automatically searched in the input file."
331
327
  opts.separator ""
332
328
  opts.separator "Examples:"
333
329
  opts.separator "* Compile system named `adder` from `adder.rb` input file and generate `adder.yaml` low-level YAML description:"
334
330
  opts.separator " hdrcc.rb --yaml --top adder adder.rb adder.yaml"
335
- opts.separator "* Compile `adder.rb` input file and generate `adder.vhd` low-level VHDL description:"
336
- opts.separator " hdrcc.rb --vhdl adder.rb adder.vhd"
331
+ opts.separator "* Compile `adder.rb` input file and generate low-level VHDL description files in `adder_vhd` directory:"
332
+ opts.separator " hdrcc.rb --vhdl adder.rb adder_vhd"
337
333
  opts.separator "* Check the validity of `adder.rb` input file:"
338
334
  opts.separator " hdrcc.rb adder.rb"
339
- opts.separator "* Compile system `adder` whose bit width is generic from `adder_gen.rb` input file to a 16-bit circuit whose low-level Verilog HDL description is dumped to the standard output:"
340
- opts.separator " hdrcc -v -t adder --param 16 adder_gen.rb"
335
+ opts.separator "* Compile system `adder` whose bit width is generic from `adder_gen.rb` input file to a 16-bit circuit whose low-level Verilog HDL description files are put in `adder_gen_v` directory:"
336
+ opts.separator " hdrcc -v -t adder --param 16 adder_gen.rb adder_gen_v"
341
337
  opts.separator "* Compile system `multer` with inputs and output bit width is generic from `multer_gen.rb` input file to a 16x16->32 bit cicruit whose low-level YAML description is saved to output file `multer_gen.yaml`"
342
338
  opts.separator "hdrcc -y -t multer -p 16,16,32 multer_gen.rb multer_gen.yaml"
343
339
 
@@ -563,7 +559,7 @@ elsif $options[:clang] then
563
559
  end
564
560
  Dir.chdir($output)
565
561
  # Kernel.system("make -s")
566
- Kernel.system("cc -o3 -o hruby_simulator *.c")
562
+ Kernel.system("cc -o3 -o hruby_simulator *.c -lpthread")
567
563
  Kernel.system("./hruby_simulator")
568
564
  end
569
565
  elsif $options[:verilog] then
@@ -45,11 +45,20 @@ module HDLRuby
45
45
  (code[1][1] == "require")
46
46
  end
47
47
 
48
+ # Tells if +code+ is require_relative description.
49
+ def is_require_relative?(code)
50
+ # return code[0] && (code[0][0] == :command) &&
51
+ # (code[0][1][1] == "require_relative")
52
+ return code && (code[0] == :command) &&
53
+ (code[1][1] == "require_relative")
54
+ end
55
+
48
56
  # Gets the required file from +code+.
49
57
  def get_require(code)
50
58
  # return (code[0][2][1][0][1][1][1])
51
59
  return (code[2][1][0][1][1][1])
52
60
  end
61
+ alias_method :get_require_relative, :get_require
53
62
 
54
63
  # Gets all the required files of +code+.
55
64
  def get_all_requires(code = @code)
@@ -66,6 +75,21 @@ module HDLRuby
66
75
  end
67
76
  end
68
77
 
78
+ # Gets all the require_relative files of +code+.
79
+ def get_all_require_relatives(code = @code)
80
+ if code.is_a?(Array) then
81
+ require_relatives = (code.select { |sub| is_require_relative?(sub) }).map! do |sub|
82
+ get_require_relative(sub)
83
+ end
84
+ code.each do |sub|
85
+ require_relatives += get_all_require_relatives(sub)
86
+ end
87
+ return require_relatives
88
+ else
89
+ return []
90
+ end
91
+ end
92
+
69
93
  # Tells if +code+ is a system description.
70
94
  def is_system?(code)
71
95
  return code.is_a?(Array) && (code[0] == :command) &&
@@ -77,7 +101,7 @@ module HDLRuby
77
101
  return code[2][1][0][1][1][1]
78
102
  end
79
103
 
80
- # Gets all the required files of +code+.
104
+ # Gets all the systems of +code+.
81
105
  def get_all_systems(code = @code)
82
106
  return [] unless code.is_a?(Array)
83
107
  return code.reduce([]) {|ar,sub| ar + get_all_systems(sub) } +
@@ -1308,6 +1308,12 @@ module HDLRuby::High
1308
1308
  return true
1309
1309
  end
1310
1310
 
1311
+ # Converts to a type.
1312
+ # Returns self since it is already a type.
1313
+ def to_type
1314
+ return self
1315
+ end
1316
+
1311
1317
  # Sets the +name+.
1312
1318
  #
1313
1319
  # NOTE: can only be done if the name is not already set.
@@ -1123,6 +1123,10 @@ module HDLRuby::Low
1123
1123
  return self.parent.is_a?(SystemT) ? self : self.parent.top_scope
1124
1124
  end
1125
1125
 
1126
+ # Gets the parent system, i.e., the parent of the top scope.
1127
+ def parent_system
1128
+ return self.top_scope.parent
1129
+ end
1126
1130
 
1127
1131
  end
1128
1132
 
@@ -1385,7 +1389,8 @@ module HDLRuby::Low
1385
1389
  # NOTE: type definition are actually type with a name refering to another
1386
1390
  # type (and equivalent to it).
1387
1391
  class TypeDef < Type
1388
- extend Forwardable
1392
+ # Moved to constructor
1393
+ # extend Forwardable
1389
1394
 
1390
1395
  # The definition of the type.
1391
1396
  attr_reader :def
@@ -1402,6 +1407,19 @@ module HDLRuby::Low
1402
1407
  end
1403
1408
  # Set the referened type.
1404
1409
  @def = type
1410
+
1411
+ # Sets the delegations
1412
+ self.extend Forwardable
1413
+ [ :signed?, :unsigned?, :fixed?, :float?, :leaf?,
1414
+ :width, :range?, :range, :base?, :base, :types?,
1415
+ :get_all_types, :get_type, :each, :each_type,
1416
+ :regular?,
1417
+ :each_name,
1418
+ :equivalent? ].each do |meth|
1419
+ if @def.respond_to?(meth)
1420
+ self.def_delegator :@def, meth
1421
+ end
1422
+ end
1405
1423
  end
1406
1424
 
1407
1425
  # Comparison for hash: structural comparison.
@@ -1429,14 +1447,15 @@ module HDLRuby::Low
1429
1447
  @def.each_type_deep(&ruby_block)
1430
1448
  end
1431
1449
 
1432
- # Delegate the type methods to the ref.
1433
- def_delegators :@def,
1434
- :signed?, :unsigned?, :fixed?, :float?, :leaf?,
1435
- :width, :range?, :range, :base?, :base, :types?,
1436
- :get_all_types, :get_type, :each, :each_type,
1437
- :regular?,
1438
- :each_name,
1439
- :equivalent?
1450
+ # Moved to constructor
1451
+ # # Delegate the type methods to the ref.
1452
+ # def_delegators :@def,
1453
+ # :signed?, :unsigned?, :fixed?, :float?, :leaf?,
1454
+ # :width, :range?, :range, :base?, :base, :types?,
1455
+ # :get_all_types, :get_type, :each, :each_type,
1456
+ # :regular?,
1457
+ # :each_name,
1458
+ # :equivalent?
1440
1459
  end
1441
1460
 
1442
1461
 
@@ -2117,6 +2136,11 @@ module HDLRuby::Low
2117
2136
  def top_scope
2118
2137
  return parent.top_scope
2119
2138
  end
2139
+
2140
+ # Gets the parent system, i.e., the parent of the top scope.
2141
+ def parent_system
2142
+ return self.top_scope.parent
2143
+ end
2120
2144
  end
2121
2145
 
2122
2146
 
@@ -2604,6 +2628,11 @@ module HDLRuby::Low
2604
2628
  def top_scope
2605
2629
  return self.scope.top_scope
2606
2630
  end
2631
+
2632
+ # Gets the parent system, i.e., the parent of the top scope.
2633
+ def parent_system
2634
+ return self.top_scope.parent
2635
+ end
2607
2636
  end
2608
2637
 
2609
2638
 
@@ -3702,6 +3731,11 @@ module HDLRuby::Low
3702
3731
  def top_scope
3703
3732
  return self.parent.is_a?(Scope) ? self.parent : self.parent.top_scope
3704
3733
  end
3734
+
3735
+ # Gets the parent system, i.e., the parent of the top scope.
3736
+ def parent_system
3737
+ return self.top_scope.parent
3738
+ end
3705
3739
  end
3706
3740
 
3707
3741
 
@@ -546,9 +546,10 @@ module HDLRuby::Low
546
546
  #
547
547
  # NOTE: type tuples are converted to bit vector of their contents.
548
548
  def to_c(level = 0)
549
- return "get_type_tuple(#{self.each.join(",") do |type|
550
- type.to_c(level+1)
551
- end})"
549
+ # return "get_type_tuple(#{self.each.to_a.join(",") do |type|
550
+ # type.to_c(level+1)
551
+ # end})"
552
+ return self.to_vector.to_c(level)
552
553
  end
553
554
  end
554
555
 
@@ -1872,7 +1873,8 @@ module HDLRuby::Low
1872
1873
  res << "idx = value2integer(#{self.index.to_c(level+2)});\n"
1873
1874
  # Make the access.
1874
1875
  res << (" " * ((level+1)*3))
1875
- res << "dst = read_range(ref,idx,idx,#{self.ref.type.base.to_c(level)},dst);\n"
1876
+ # res << "dst = read_range(ref,idx,idx,#{self.ref.type.base.to_c(level)},dst);\n"
1877
+ res << "dst = read_range(ref,idx,idx,#{self.type.to_c(level)},dst);\n"
1876
1878
  # Restore the state of the value pool.
1877
1879
  res << (" " * ((level+1)*3))
1878
1880
  res << "set_value_pos(pool_state);\n"
@@ -1930,7 +1932,9 @@ module HDLRuby::Low
1930
1932
  res << "last = value2integer(#{self.range.last.to_c(level+2)});\n"
1931
1933
  # Make the access.
1932
1934
  res << (" " * ((level+1)*3))
1933
- res << "dst = #{command}_range(ref,first,last,#{self.ref.type.base.to_c(level)},dst);\n"
1935
+ # res << "dst = #{command}_range(ref,first,last,#{self.ref.type.base.to_c(level)},dst);\n"
1936
+ # puts "will read_range for #{self.ref.name} with width=#{self.ref.type.width} with base width=#{self.ref.type.base.width} with range=#{self.ref.type.range} with range=#{self.range.first.content}..#{self.range.last.content}"
1937
+ res << "dst = #{command}_range(ref,first,last,#{self.type.base.to_c(level)},dst);\n"
1934
1938
  # Restore the state of the value pool.
1935
1939
  res << (" " * ((level+1)*3))
1936
1940
  res << "set_value_pos(pool_state);\n"
@@ -566,7 +566,7 @@ module HDLRuby::Low
566
566
  # +level+ is the hierachical level of the object.
567
567
  def to_high(level = 0)
568
568
  return self.child.to_high(level) +
569
- ".cast(" + self.type.to_high(level) + ")"
569
+ ".as(" + self.type.to_high(level) + ")"
570
570
  end
571
571
  end
572
572
 
@@ -345,31 +345,34 @@ module HDLRuby::Low
345
345
  res << " " * (level*3)
346
346
  res << "entity #{Low2VHDL.entity_name(self.name)} is\n"
347
347
  # The ports
348
- res << " " * ((level+1)*3)
349
- res << "port (\n"
350
- # Inputs
351
- self.each_input do |input|
352
- res << " " * ((level+2)*3)
353
- res << Low2VHDL.vhdl_name(input.name) << ": in "
354
- res << input.type.to_vhdl << ";\n"
355
- end
356
- # Outputs
357
- self.each_output do |output|
358
- res << " " * ((level+2)*3)
359
- res << Low2VHDL.vhdl_name(output.name) << ": out "
360
- res << output.type.to_vhdl << ";\n"
361
- end
362
- # Inouts
363
- self.each_inout do |inout|
364
- res << " " * ((level+2)*3)
365
- res << Low2VHDL.vhdl_name(inout.name) << ": inout "
366
- res << inout.type.to_vhdl << ";\n"
348
+ if self.each_input.any? || self.each_output.any? ||
349
+ self.each_inout.any? then
350
+ res << " " * ((level+1)*3)
351
+ res << "port (\n"
352
+ # Inputs
353
+ self.each_input do |input|
354
+ res << " " * ((level+2)*3)
355
+ res << Low2VHDL.vhdl_name(input.name) << ": in "
356
+ res << input.type.to_vhdl << ";\n"
357
+ end
358
+ # Outputs
359
+ self.each_output do |output|
360
+ res << " " * ((level+2)*3)
361
+ res << Low2VHDL.vhdl_name(output.name) << ": out "
362
+ res << output.type.to_vhdl << ";\n"
363
+ end
364
+ # Inouts
365
+ self.each_inout do |inout|
366
+ res << " " * ((level+2)*3)
367
+ res << Low2VHDL.vhdl_name(inout.name) << ": inout "
368
+ res << inout.type.to_vhdl << ";\n"
369
+ end
370
+ # Remove the last ";" for conforming with VHDL syntax.
371
+ res[-2..-1] = "\n" if res[-2] == ";"
372
+ res << " " * ((level+1)*3)
373
+ # Close the port declaration.
374
+ res << ");\n"
367
375
  end
368
- # Remove the last ";" for conforming with VHDL syntax.
369
- res[-2..-1] = "\n" if res[-2] == ";"
370
- res << " " * ((level+1)*3)
371
- # Close the port declaration.
372
- res << ");\n"
373
376
  # Close the entity
374
377
  res << " " * (level*3)
375
378
  res << "end #{Low2VHDL.entity_name(self.name)};\n\n"
@@ -617,7 +620,17 @@ module HDLRuby::Low
617
620
  # # Simply generates the redefined type.
618
621
  # return self.def.to_vhdl(level)
619
622
  # Simply use the name of the type.
620
- return Low2VHDL.vhdl_name(self.name)
623
+ # Is it a composite type?
624
+ if (self.def.is_a?(TypeStruct) ||
625
+ (self.def.is_a?(TypeVector) &&
626
+ (self.def.base.is_a?(TypeVector) ||
627
+ self.def.base.is_a?(TypeStruct))))
628
+ # Yes, generate a VHDL type definition.
629
+ return Low2VHDL.vhdl_name(self.name)
630
+ else
631
+ # No, generates the defined type.
632
+ return self.def.to_vhdl(level)
633
+ end
621
634
  end
622
635
  end
623
636
 
@@ -745,29 +758,31 @@ module HDLRuby::Low
745
758
  res << Low2VHDL.vhdl_name(self.block.name) << ": "
746
759
  end
747
760
  res << "process "
748
- # Generate the senitivity list.
749
- if self.each_event.any? then
750
- # If there is a clock.
751
- res << "("
752
- res << self.each_event.map do |event|
753
- event.ref.to_vhdl(level)
754
- end.join(", ")
755
- res << ")"
756
- else
757
- # If no clock, generate the sensitivity list from the right
758
- # values.
759
- list = self.block.each_node_deep.select do |node|
760
- node.is_a?(RefName) && !node.leftvalue? &&
761
- !node.parent.is_a?(RefName) &&
762
- # Also skip the variables
763
- !vars.find {|var| var.name == node.name }
764
- end.to_a
765
- # Keep only one ref per signal.
766
- list.uniq! { |node| node.name }
767
- # Generate the sensitivity list from it.
768
- res << "("
769
- res << list.map {|node| node.to_vhdl(level) }.join(", ")
770
- res << ")"
761
+ # Generate the senitivity list if not a timed block.
762
+ unless self.block.is_a?(TimeBlock) then
763
+ if self.each_event.any? then
764
+ # If there is a clock.
765
+ res << "("
766
+ res << self.each_event.map do |event|
767
+ event.ref.to_vhdl(level)
768
+ end.join(", ")
769
+ res << ")"
770
+ else
771
+ # If no clock, generate the sensitivity list from the right
772
+ # values.
773
+ list = self.block.each_node_deep.select do |node|
774
+ node.is_a?(RefName) && !node.leftvalue? &&
775
+ !node.parent.is_a?(RefName) &&
776
+ # Also skip the variables
777
+ !vars.find {|var| var.name == node.name }
778
+ end.to_a
779
+ # Keep only one ref per signal.
780
+ list.uniq! { |node| node.name }
781
+ # Generate the sensitivity list from it.
782
+ res << "("
783
+ res << list.map {|node| node.to_vhdl(level) }.join(", ")
784
+ res << ")"
785
+ end
771
786
  end
772
787
  res << "\n"
773
788
  # Generate the variables.