HDLRuby 3.9.1 → 3.9.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,23 @@
1
+ # Sample code for testing unary reduction operators.
2
+
3
+ system :with_unary_reduction do
4
+ [8].inner :val
5
+ inner :red0, :red1
6
+
7
+ red0 <= val.|()
8
+ red1 <= val.&()
9
+
10
+ timed do
11
+ val <= 0
12
+ !10.ns
13
+ val <= 1
14
+ !10.ns
15
+ val <= 2
16
+ !10.ns
17
+ val <= 3
18
+ !10.ns
19
+ val <= 255
20
+ !10.ns
21
+ end
22
+
23
+ end
@@ -9,6 +9,8 @@ system :with_values do
9
9
  [64].inner :v64
10
10
  [96].inner :v96
11
11
 
12
+ _CST = _u8b1111_0000
13
+
12
14
 
13
15
  timed do
14
16
  v1 <= _b0
@@ -71,5 +73,7 @@ system :with_values do
71
73
  !10.ns
72
74
  v96 <= 0x1000000000000000000
73
75
  !10.ns
76
+ v8 <= _CST
77
+ !10.ns
74
78
  end
75
79
  end
data/lib/HDLRuby/hdrcc.rb CHANGED
@@ -1079,6 +1079,9 @@ elsif $options[:vhdl] then
1079
1079
  end
1080
1080
  end
1081
1081
  elsif $options[:svg] then
1082
+ # Requires to split the signals for better visibility and routability.
1083
+ require "HDLRuby/hruby_low_split_signals.rb"
1084
+ $top_system.split_signals
1082
1085
  # Requires the viz library.
1083
1086
  require "HDLRuby/hruby_viz.rb"
1084
1087
  # Generate the viz structure.
@@ -100,7 +100,8 @@ module HDLRuby
100
100
  if @content.size < width then
101
101
  @content.concat(content[-1]*(width-@content.size))
102
102
  else
103
- @content.trunc!(width)
103
+ # @content.trunc!(width)
104
+ @content.slice!(width..-1)
104
105
  end
105
106
  @content.reverse!
106
107
  end
@@ -934,10 +934,16 @@ module HDLRuby::High
934
934
  if condition.respond_to?(:to_i) then
935
935
  # The hif can be evaluate straight away. Do metaprograming.
936
936
  if condition.to_i != 0 then
937
+ caught = false
937
938
  HDLRuby::High.top_user.sub do
938
- ruby_block.call
939
+ caught = true
940
+ catch(:HDLRubyThrow) do
941
+ ruby_block.call
942
+ caught = false
943
+ end
939
944
  end
940
945
  @metacond = :hif
946
+ throw(:HDLRubyThrow) if caught
941
947
  else
942
948
  @metacond = :helse
943
949
  end
@@ -956,10 +962,16 @@ module HDLRuby::High
956
962
  return :toif unless condition.respond_to?(:to_i)
957
963
  # The hif can be evaluate straight away. Do metaprograming.
958
964
  if condition.to_i != 0 then
965
+ caught = false
959
966
  HDLRuby::High.top_user.sub do
960
- ruby_block.call
967
+ caught = true
968
+ catch(:HDLRubyThrow) do
969
+ ruby_block.call
970
+ caught = false
971
+ end
961
972
  end
962
973
  @metacond = :hif
974
+ throw(:HDLRubyThrow) if caught
963
975
  else
964
976
  @metacond = :helse
965
977
  end
@@ -990,10 +1002,16 @@ module HDLRuby::High
990
1002
  if @metavalue and match.respond_to?(:to_i) then
991
1003
  # The hwen can be evaluate straight away. Do metaprograming.
992
1004
  if @metavalue == match.to_i then
1005
+ caught = false
993
1006
  HDLRuby::High.top_user.sub do
994
- ruby_block.call
1007
+ caught = true
1008
+ catch(:HDLRubyThrow) do
1009
+ ruby_block.call
1010
+ caught = false
1011
+ end
995
1012
  end
996
1013
  @metacond = :hwhen
1014
+ throw(:HDLRubyThrow) if caught
997
1015
  else
998
1016
  @metacond = :helse
999
1017
  end
@@ -1008,11 +1026,17 @@ module HDLRuby::High
1008
1026
  if @metacond then
1009
1027
  if @metacond == :helse then
1010
1028
  if ruby_block then
1029
+ caught = false
1011
1030
  HDLRuby::High.top_user.sub do
1012
- ruby_block.call
1031
+ caught = true
1032
+ catch(:HDLRubyThrow) do
1033
+ ruby_block.call
1034
+ caught = false
1035
+ end
1013
1036
  end
1014
1037
  end
1015
1038
  @metacond = nil
1039
+ throw(:HDLRubyThrow) if caught
1016
1040
  end
1017
1041
  return true
1018
1042
  end
@@ -3273,14 +3297,18 @@ module HDLRuby::High
3273
3297
  end
3274
3298
  end
3275
3299
 
3276
- # Adds the binary operations generation.
3300
+ # Adds the binary or unary-reduction operations generation.
3277
3301
  [:"+",:"-",:"*",:"/",:"%",:"**",
3278
3302
  :"&",:"|",:"^",
3279
3303
  :"<<",:">>",# :ls,:rs,:lr,:rr, # ls, rs lr and rr are treated separately
3280
3304
  :"==",:"!=",:"<",:">",:"<=",:">="].each do |operator|
3281
- meth = proc do |right|
3305
+ meth = proc do |right = nil|
3282
3306
  expr = self.to_expr
3283
- return expr.type.binary(operator,expr,right.to_expr)
3307
+ if right then
3308
+ return expr.type.binary(operator,expr,right.to_expr)
3309
+ else
3310
+ return expr.type.unary(operator,expr)
3311
+ end
3284
3312
  end
3285
3313
  # Defines the operator method.
3286
3314
  define_method(operator,&meth)
@@ -419,15 +419,15 @@ module HDLRuby::Low
419
419
  return @inouts[name.to_sym]
420
420
  end
421
421
 
422
- # # Gets an inner signal by +name+.
423
- # def get_inner(name)
424
- # return @inners[name.to_sym]
425
- # end
426
-
427
422
  # Gets a signal by +name+.
428
423
  def get_signal(name)
429
- return get_input(name) || get_output(name) || get_inout(name) # ||
430
- # get_inner(name)
424
+ return get_input(name) || get_output(name) || get_inout(name)
425
+ end
426
+
427
+ # Gets a signal by +name+ up to the systemT.
428
+ # Here it is a systemT, so stop here if not found.
429
+ def get_signal_up(name)
430
+ return self.get_signal(name)
431
431
  end
432
432
 
433
433
  # Gets an interface signal by order of declaration +i+.
@@ -435,41 +435,6 @@ module HDLRuby::Low
435
435
  return @interface[i]
436
436
  end
437
437
 
438
- # # Deletes input +signal+.
439
- # def delete_input(signal)
440
- # if @inputs.key?(signal) then
441
- # # The signal is present, delete it.
442
- # @inputs.delete(signal.name)
443
- # @interface.delete(signal)
444
- # # And remove its parent.
445
- # signal.parent = nil
446
- # end
447
- # signal
448
- # end
449
-
450
- # # Deletes output +signal+.
451
- # def delete_output(signal)
452
- # if @outputs.key?(signal) then
453
- # # The signal is present, delete it.
454
- # @outputs.delete(signal.name)
455
- # @interface.delete(signal)
456
- # # And remove its parent.
457
- # signal.parent = nil
458
- # end
459
- # signal
460
- # end
461
-
462
- # # Deletes inout +signal+.
463
- # def delete_inout(signal)
464
- # if @inouts.key?(signal) then
465
- # # The signal is present, delete it.
466
- # @inouts.delete(signal.name)
467
- # @interface.delete(signal)
468
- # # And remove its parent.
469
- # signal.parent = nil
470
- # end
471
- # signal
472
- # end
473
438
 
474
439
  # Iterates over each object deeply.
475
440
  #
@@ -993,56 +958,20 @@ module HDLRuby::Low
993
958
  return @inners[name.to_sym]
994
959
  end
995
960
 
996
- # ## Gets a signal by +path+.
997
- # #
998
- # # NOTE: +path+ can also be a single name or a reference object.
999
- # def get_signal(path)
1000
- # path = path.path_each if path.respond_to?(:path_each) # Ref case.
1001
- # if path.respond_to?(:each) then
1002
- # # Path is iterable: look for the first name.
1003
- # path = path.each
1004
- # name = path.each.next
1005
- # # Maybe it is a system instance.
1006
- # systemI = self.get_systemI(name)
1007
- # if systemI then
1008
- # # Yes, look for the remaining of the path into the
1009
- # # corresponding system type.
1010
- # return systemI.systemT.get_signal(path)
1011
- # else
1012
- # # Maybe it is a signal name.
1013
- # return self.get_signal(name)
1014
- # end
1015
- # else
1016
- # # Path is a single name, look for the signal in the system's
1017
- # # Try in the inputs.
1018
- # signal = get_input(path)
1019
- # return signal if signal
1020
- # # Try in the outputs.
1021
- # signal = get_output(path)
1022
- # return signal if signal
1023
- # # Try in the inouts.
1024
- # signal = get_inout(path)
1025
- # return signal if signal
1026
- # # Not found yet, look into the inners.
1027
- # return get_inner(path)
1028
- # end
1029
- # end
1030
-
1031
961
  # Gets an inner signal by +name+, equivalent to get_inner.
1032
962
  def get_signal(name)
1033
963
  return @inners[name]
1034
964
  end
1035
965
 
1036
- # # Deletes inner +signal+.
1037
- # def delete_inner(signal)
1038
- # if @inners.key?(signal) then
1039
- # # The signal is present, delete it.
1040
- # @inners.delete(signal.name)
1041
- # # And remove its parent.
1042
- # signal.parent = nil
1043
- # end
1044
- # signal
1045
- # end
966
+ # Gets a signal by +name+ up to the systemT.
967
+ # Here it is a systemT, so stop here if not found.
968
+ def get_signal_up(name)
969
+ # Maybe its an inner.
970
+ sig = self.get_inner(name)
971
+ # If not, look in the parent.
972
+ sig = self.parent.get_signal(name) unless sig
973
+ return sig
974
+ end
1046
975
 
1047
976
  # Handling the connections.
1048
977
 
@@ -2556,6 +2485,13 @@ module HDLRuby::Low
2556
2485
  def parent_system
2557
2486
  return self.top_scope.parent
2558
2487
  end
2488
+
2489
+ # Gets a signal by +name+ up to the systemT.
2490
+ # Here it is a systemT, so stop here if not found.
2491
+ def get_signal_up(name)
2492
+ # Look in the parent.
2493
+ return self.parent.get_signal(name)
2494
+ end
2559
2495
  end
2560
2496
 
2561
2497
 
@@ -2710,6 +2646,24 @@ module HDLRuby::Low
2710
2646
  false
2711
2647
  end
2712
2648
 
2649
+ # Give the direction of the signal if possible.
2650
+ def direction
2651
+ # No parent? No direction.
2652
+ return nil unless self.parent
2653
+ if self.parent.is_a?(Block) or self.parent.is_a?(Scope) then
2654
+ # Inner direction.
2655
+ return :inner
2656
+ else
2657
+ if parent.get_input(self.name) then
2658
+ return :input
2659
+ elsif parent.get_output(self.name) then
2660
+ return :output
2661
+ else
2662
+ return :inout
2663
+ end
2664
+ end
2665
+ end
2666
+
2713
2667
  # Adds sub signal +sig+
2714
2668
  def add_signal(sig)
2715
2669
  # puts "add sub=#{sig.name} in signal=#{self}"
@@ -2938,6 +2892,7 @@ module HDLRuby::Low
2938
2892
  :each_signal, :each_signal_deep,
2939
2893
  :get_input, :get_output, :get_inout, :get_inner,
2940
2894
  :get_signal, :get_interface,
2895
+ :get_signal_up,
2941
2896
  :each_systemI, :get_systemI,
2942
2897
  :each_connection, :each_connection_deep,
2943
2898
  :each_statement_deep, :each_arrow_deep,
@@ -4700,6 +4655,16 @@ module HDLRuby::Low
4700
4655
  end
4701
4656
  alias_method :get_signal, :get_inner
4702
4657
 
4658
+ # Gets a signal by +name+ up to the systemT.
4659
+ # Here it is a systemT, so stop here if not found.
4660
+ def get_signal_up(name)
4661
+ # Maybe its an inner.
4662
+ sig = self.get_inner(name)
4663
+ # If not, look in the parent.
4664
+ sig = self.parent.get_signal_up(name) unless sig
4665
+ return sig
4666
+ end
4667
+
4703
4668
  # Iterates over all the signals of the block and its sub block's ones.
4704
4669
  def each_signal_deep(&ruby_block)
4705
4670
  # No ruby block? Return an enumerator.
@@ -0,0 +1,213 @@
1
+ require 'HDLRuby'
2
+ require 'HDLRuby/hruby_tools'
3
+ require 'HDLRuby/hruby_low_mutable'
4
+ require 'HDLRuby/hruby_low_with_bool'
5
+
6
+
7
+ module HDLRuby::Low
8
+
9
+
10
+ ##
11
+ # Split signals with determined bit and range accesses.
12
+ #
13
+ ########################################################################
14
+
15
+
16
+ class SystemT
17
+
18
+ # Get the signals than can be split, where they are used and their
19
+ # resulting sub signals.
20
+ # The result is to be put in the +res+ table.
21
+ def get_signal_splits(res = { })
22
+ # Search in the scope.
23
+ return self.scope.get_signal_splits(res)
24
+ end
25
+
26
+ # Split the signals of a system if they have determined bit or range
27
+ # accessed.
28
+ def split_signals(signals_splits = nil)
29
+ # puts "split_signals for systemT=#{self.name}"
30
+ # Gather the signals to split and their splitting.
31
+ signal_splits = self.get_signal_splits unless signals_splits
32
+
33
+ # Do the splitting.
34
+ signal_splits.each do |sig,splits|
35
+ # Get the owner of the signal.
36
+ owner = sig.parent
37
+ dir = sig.direction
38
+ # # Remove the signal from the owner since it is split.
39
+ # case dir
40
+ # when :input
41
+ # owner.delete_input!(sig)
42
+ # when :output
43
+ # owner.delete_output!(sig)
44
+ # when :inout
45
+ # owner.delete_inout!(sig)
46
+ # when :inner
47
+ # owner.delete_inner!(sig)
48
+ # end
49
+
50
+ # Add instead the corresponding sub signals.
51
+ splits.each do |idx,(sub,places)|
52
+ # puts "owner.class=#{owner.class} sub.class=#{sub.class}"
53
+ # In the owner.
54
+ case dir
55
+ when :input
56
+ owner.add_input(sub)
57
+ when :output
58
+ owner.add_output(sub)
59
+ when :inout
60
+ owner.add_input(sub)
61
+ when :inner
62
+ owner.add_inner(sub)
63
+ end
64
+
65
+ # Replace the references of the signal by its subs.
66
+ places.each do |place|
67
+ place.parent.map_nodes! do |node|
68
+ node == place ? HDLRuby::Low::RefName.new(Bit,RefThis.new,sub.name) : node
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+
77
+ class Scope
78
+ # Get the signals than can be split, where they are used and their
79
+ # resulting sub signals.
80
+ # The result is to be put in the +res+ table.
81
+ def get_signal_splits(res = {})
82
+ # Search in the sub systems.
83
+ self.each_systemT { |sysT| sysT.get_signal_splits(res) }
84
+ # Search in the sub scopes.
85
+ self.each_scope { |scop| scop.get_signal_splits(res) }
86
+ # Search in the instances.
87
+ self.each_systemI { |sysI| sysI.get_signal_splits(res) }
88
+ # Search in the connections.
89
+ self.each_connection { |cnx| cnx.get_signal_splits(res) }
90
+ # Search in the behaviors.
91
+ self.each_behavior { |beh| beh.get_signal_splits(res) }
92
+ return res
93
+ end
94
+ end
95
+
96
+
97
+ class Behavior
98
+ # Get the signals than can be split, where they are used and their
99
+ # resulting sub signals.
100
+ # The result is to be put in the +res+ table.
101
+ def get_signal_splits(res = {})
102
+ # Recurse on the events.
103
+ self.each_event { |ev| ev.get_signal_splits(res) }
104
+ # Recurse on the block.
105
+ self.block.get_signal_splits(res)
106
+ return res
107
+ end
108
+ end
109
+
110
+
111
+ class Event
112
+ # Get the signals than can be split, where they are used and their
113
+ # resulting sub signals.
114
+ # The result is to be put in the +res+ table.
115
+ def get_signal_splits(res = {})
116
+ if self.ref.is_a?(RefIndex) and self.ref.ref.is_a?(RefName) and
117
+ self.ref.index.is_a?(Value) then
118
+ sigref = self.ref
119
+ # A split is found. Get the signal upward.
120
+ sig = self.parent.parent.get_signal_upward(self.ref.name)
121
+ sig.split_to_index(self.ref.index,res)
122
+ elsif self.ref.is_a?(RefRange) and self.ref.ref.is_a?(RefName) and
123
+ self.ref.range.first.is_a?(Value) and
124
+ self.ref.range.last.is_a?(Value) then
125
+ sigref = self.ref
126
+ # A split is found. Get the signal upward.
127
+ sig = self.parent.parent.get_signal_upward(self.ref.name)
128
+ sig.split_to_range(self.ref.range,res)
129
+ end
130
+ return res
131
+ end
132
+ end
133
+
134
+
135
+ class SystemI
136
+ # Get the signals than can be split, where they are used and their
137
+ # resulting sub signals.
138
+ # The result is to be put in the +res+ table.
139
+ def get_signal_splits(res = {})
140
+ return self.systemT.get_signal_splits(res)
141
+ end
142
+ end
143
+
144
+
145
+ class Statement
146
+ # Get the signals than can be split, where they are used and their
147
+ # resulting sub signals.
148
+ # The result is to be put in the +res+ table.
149
+ def get_signal_splits(res = {})
150
+ # Recurse on the sub statements.
151
+ self.each_statement_deep do |stmnt|
152
+ stmnt.each_node_deep do |expr|
153
+ if expr.is_a?(RefIndex) and expr.ref.is_a?(RefName) and
154
+ expr.index.is_a?(Value) then
155
+ # A split is found. Get the signal upward.
156
+ blk = self.block
157
+ sig = blk ? blk.get_signal_up(expr.ref.name) :
158
+ self.scope.get_signal_up(expr.ref.name)
159
+ sig.split_to_index(expr,expr.index,res)
160
+ elsif expr.is_a?(RefRange) and expr.ref.is_a?(RefName) and
161
+ expr.range.first.is_a?(Value) and
162
+ expr.range.last.is_a?(Value) then
163
+ # A split is found. Get the signal upward.
164
+ blk = self.block
165
+ sig = blk ? blk.get_signal_up(expr.ref.name) :
166
+ self.scope.get_signal_up(expr.ref.name)
167
+ sig.split_to_range(expr,expr.range,res)
168
+ end
169
+ end
170
+ end
171
+ return res
172
+ end
173
+ end
174
+
175
+
176
+ class SignalI
177
+ # Split the signal at place +place+ for +index+ and register it to
178
+ # +res+ table.
179
+ def split_to_index(place ,index, res)
180
+ index = index.to_i
181
+ entry = res[self]
182
+ unless entry then
183
+ entry = {}
184
+ res[self] = entry
185
+ end
186
+ split = entry[index]
187
+ unless split then
188
+ split = [SignalI.new(self.name.to_s + "[#{index}]",Bit), []]
189
+ entry[index] = split
190
+ end
191
+ split[1] << place
192
+ return res
193
+ end
194
+
195
+ # Split the signal at place +place+ for +index+ and register it to
196
+ # +res+ table.
197
+ def split_to_range(place ,range, res)
198
+ range = range.first.to_i..range.last.to_i
199
+ entry = res[self]
200
+ unless entry then
201
+ entry = {}
202
+ res[self] = entry
203
+ end
204
+ split = entry[range]
205
+ unless split then
206
+ split = [SignalI.new(self.name.to_s + "[#{range}]",Bit), []]
207
+ entry[range] = split
208
+ end
209
+ split[1] << place
210
+ return res
211
+ end
212
+ end
213
+ end
@@ -156,7 +156,7 @@ module HDLRuby
156
156
 
157
157
 
158
158
  # And
159
- def &(type)
159
+ def &(type = nil)
160
160
  # # puts "compute types with=#{self} and #{type}"
161
161
  # # Resolve the type class.
162
162
  # resolved = self.resolve(type)
@@ -178,7 +178,11 @@ module HDLRuby
178
178
  # return resolved.make(:"",resolved.base,res_lsb..res_msb)
179
179
  # end
180
180
  # The result is the resolve result now!
181
- return self.resolve(type)
181
+ if type then
182
+ return self.resolve(type)
183
+ else
184
+ return self
185
+ end
182
186
  end
183
187
 
184
188
  # Or