Class: HDLRuby::Low::SystemT

Inherits:
Base::SystemT
  • Object
show all
Includes:
ForceName, Hparent, Low2Symbol
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2seq.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_cleanup.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_resolve.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_with_var.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_with_bool.rb,
lib/HDLRuby/hruby_low_with_port.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_without_concat.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/backend/hruby_c_allocator.rb,
lib/HDLRuby/hruby_low_without_outread.rb,
lib/HDLRuby/hruby_low_without_namespace.rb,
lib/HDLRuby/hruby_low_without_bit2vector.rb,
lib/HDLRuby/hruby_low_without_connection.rb

Overview

Extends the SystemT class with functionality for breaking assingments to concats.

Direct Known Subclasses

High::SystemT

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes included from Hparent

#parent

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ForceName

#extend_name!, #force_name!

Methods included from Low2Symbol

#to_sym

Constructor Details

#initialize(name, scope) ⇒ SystemT

Creates a new system type named +name+ with +scope+.



31
32
33
34
35
36
37
38
# File 'lib/HDLRuby/hruby_db.rb', line 31

def initialize(name)
    # Initialize the system type structure.
    super(name)
    # Update the library of existing system types.
    # Note: no check is made so an exisiting system type with a same
    # name is overwritten.
    SystemTs[@name] = self
end

Instance Attribute Details

#nameObject (readonly)

The name of the system.



74
75
76
# File 'lib/HDLRuby/hruby_low.rb', line 74

def name
  @name
end

#scopeObject (readonly)

The scope of the system type.



77
78
79
# File 'lib/HDLRuby/hruby_low.rb', line 77

def scope
  @scope
end

Class Method Details

.get(name) ⇒ Object

Get an existing system type by +name+.



25
26
27
28
# File 'lib/HDLRuby/hruby_db.rb', line 25

def self.get(name)
    return name if name.is_a?(SystemT)
    return SystemTs[name.to_sym]
end

Instance Method Details

#add_inout(signal) ⇒ Object

Adds inout +signal+.



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/HDLRuby/hruby_low.rb', line 189

def add_inout(signal)
    # Check and add the signal.
    unless signal.is_a?(SignalI)
        raise AnyError,
              "Invalid class for a signal instance: #{signal.class}"
    end
    if @inouts.include?(signal) then
        raise AnyError, "SignalI #{signal.name} already present."
    end
    # Set the parent of the signal.
    signal.parent = self
    # And add the signal.
    @inouts.add(signal)
    @interface << signal
    return signal
end

#add_input(signal) ⇒ Object

Adds input +signal+.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/HDLRuby/hruby_low.rb', line 152

def add_input(signal)
    # print "add_input with signal: #{signal.name}\n"
    # Check and add the signal.
    unless signal.is_a?(SignalI)
        raise AnyError,
              "Invalid class for a signal instance: #{signal.class}"
    end
    if @inputs.include?(signal) then
        raise AnyError, "SignalI #{signal.name} already present."
    end
    # Set the parent of the signal.
    signal.parent = self
    # And add the signal.
    @inputs.add(signal)
    @interface << signal
    return signal
end

#add_output(signal) ⇒ Object

Adds output +signal+.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/HDLRuby/hruby_low.rb', line 171

def add_output(signal)
    # Check and add the signal.
    unless signal.is_a?(SignalI)
        raise AnyError,
              "Invalid class for a signal instance: #{signal.class}"
    end
    if @outputs.include?(signal) then
        raise AnyError, "SignalI #{signal.name} already present."
    end
    # Set the parent of the signal.
    signal.parent = self
    # And add the signal.
    @outputs.add(signal)
    @interface << signal
    return signal
end

#bit2vector2inner!Object

Replace bit to vector conversions by assignment to on bit of an intermediate inner vector.

NOTE: the result is the same systemT.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/HDLRuby/hruby_low_without_bit2vector.rb', line 23

def bit2vector2inner!
    # puts "For system: #{self.name}"
    # First gather the bit conversions to vector.
    bits2vectors = Set.new
    gather_bits2vectors = proc do |node|
        if node.is_a?(Expression) && node.type == Bit &&
                node.parent.is_a?(Expression) && 
                # References are not relevant parents
                !node.parent.is_a?(Ref) && 
                # Neither do concat that are processed separatly
                !node.parent.is_a?(Concat) && 
                node.parent.type != Bit then
            # puts "node=#{node.to_high}, node.parent=#{node.parent}"
            bits2vectors.add(node)
        end
    end
    # Apply the procedure for gathering the read on outputs signals.
    self.scope.each_scope_deep do |scope|
        scope.each_connection do |connection|
            # Recurse on the connection.
            connection.each_node_deep(&gather_bits2vectors)
        end
        scope.each_behavior do |behavior|
            behavior.each_event do |event|
                gather_bits2vectors.(event.ref)
            end
            behavior.each_statement do |statement|
                # puts "statement=#{statement.class}"
                statement.each_node_deep(&gather_bits2vectors)
            end
        end
    end
    # puts "bits2vectors=#{bits2vectors.size}"

    # Create the 1-bit-vector type.
    vec1T = TypeVector.new(:"bit1",Bit,0..0)
    # Generate one inner 1-bit-vector signal per read output.
    bit2inner = {}
    bits2vectors.each do |node|
        # Generate the inner variable.
        sig = self.scope.add_inner(SignalI.new(HDLRuby::uniq_name,vec1T))
        ref = RefName.new(vec1T,RefThis.new,sig.name)
        bit2inner[node] = 
            [ ref, RefIndex.new(Bit,ref,Value.new(Integer,0)) ]
        # puts "new inner=#{out2inner[name].name}"
    end

    # Apply the replacement procedure on the code
    self.scope.each_scope_deep do |scope|
        scope.each_connection.to_a.each do |connection|
            connection.reassign_expressions!(bit2inner)
        end
        scope.each_behavior do |behavior|
            behavior.each_event do |event|
                event.reassign_expressions!(bit2inner)
            end
            behavior.block.reassign_expressions!(bit2inner)
        end
    end

    return self
end

#blocks2seq!Object

Converts the par sub blocks to seq.



21
22
23
24
25
# File 'lib/HDLRuby/hruby_low2seq.rb', line 21

def blocks2seq!
    # Recurse on the scope.
    self.scope.to_seq!
    return self
end

#boolean_in_assign2select!Object

Converts booleans in assignments to select operators.



22
23
24
25
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 22

def boolean_in_assign2select!
    self.scope.boolean_in_assign2select!
    return self
end

#break_concat_assigns!Object

Breaks the assignments to concats.



21
22
23
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 21

def break_concat_assigns!
    self.scope.break_concat_assigns!
end

#break_types!Object

Breaks the hierarchical types into sequences of type definitions.



74
75
76
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 74

def break_types!
    self.scope.break_types!
end

#c_code_allocate(allocator) ⇒ Object

Allocates signals within C code using +allocator+.



18
19
20
# File 'lib/HDLRuby/backend/hruby_c_allocator.rb', line 18

def c_code_allocate(allocator)
    self.scope.c_code_allocate(allocator)
end

#cleanup!Object

Cleans up.



22
23
24
25
26
27
28
# File 'lib/HDLRuby/hruby_low_cleanup.rb', line 22

def cleanup!
    # Gather the output and inout signals' names, they are used to
    # identify the signals that can be removed.
    keep = self.each_output.map {|sig| sig.name } +
           self.each_inout.map {|sig| sig.name }
    self.scope.cleanup!(keep)
end

#connections_to_behaviors!Object

Remove the connections and replace them by behaviors. NOTE: one behavior is created for input connections and one for output ones while inout/inner-only connections are copied in both behaviors.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/HDLRuby/hruby_low_without_connection.rb', line 25

def connections_to_behaviors!
    # Process the connections: create a behavior containing
    # them all within a par block.
    self.scope.each_scope_deep do |scope|
        if scope.each_connection.to_a.any? then
            inputs_blk = Block.new(:par)
            outputs_blk = Block.new(:par)
            timed_blk = TimeBlock.new(:seq)
            scope.each_connection do |connection|
                # puts "For connection: #{connection}"
                # Check the left and right of the connection
                # for input or output port.
                left = connection.left
                left_r = left.resolve
                # puts "left_r=#{left_r.name}" if left_r
                # puts "left_r.parent=#{left_r.parent.name}" if left_r && left_r.parent
                right = connection.right
                right_r = right.resolve if right.respond_to?(:resolve)
                # puts "right_r=#{right_r.name}" if right_r
                # puts "right_r.parent=#{right_r.parent.name}" if right_r && right_r.parent
                if right.is_a?(Value) then
                    # Right is value, the new transmit is to add
                    # to the timed block.
                    timed_blk.add_statement(
                        Transmit.new(left.clone,right.clone))
                    # No more process for this connection.
                    next
                end

                # Check if left is an input or an output.
                left_is_i = left_is_o = false
                if left_r && left_r.parent.is_a?(SystemT) then
                    if left_r.parent.each_input.include?(left_r) then
                        # puts "Left is input."
                        # puts "Left is from systemI: #{left.from_systemI?}"
                        left_is_i = left.from_systemI?
                        left_is_o = !left_is_i
                    elsif left_r.parent.each_output.include?(left_r) then
                        # puts "Left is output."
                        # puts "Left is from systemI: #{left.from_systemI?}"
                        left_is_o = left.from_systemI?
                        left_is_i = !left_is_o
                    end
                end
                # Check if right is an input or an output.
                right_is_i = right_is_o = false
                if right_r && right_r.parent.is_a?(SystemT) then
                    if right_r.parent.each_input.include?(right_r) then
                        # puts "Right is input."
                        # puts "Right is from systemI: #{right.from_systemI?}"
                        right_is_i = right.from_systemI?
                        right_is_o = !right_is_i
                    elsif right_r.parent.each_output.include?(right_r) then
                        # puts "Right is output."
                        # puts "Right is from systemI: #{right.from_systemI?}"
                        right_is_o = right.from_systemI?
                        right_is_i = !right_is_o
                    end
                end
                # puts "left_is_i=#{left_is_i} left_is_o=#{left_is_o}"
                # puts "right_is_i=#{right_is_i} right_is_o=#{right_is_o}"
                # Fills the relevant block.
                if (left_is_i) then
                    inputs_blk.add_statement(
                        Transmit.new(left.clone,right.clone))
                elsif (right_is_i) then
                    inputs_blk.add_statement(
                        Transmit.new(right.clone,left.clone))
                elsif (left_is_o) then
                    outputs_blk.add_statement(
                        Transmit.new(right.clone,left.clone))
                elsif (right_is_o) then
                    outputs_blk.add_statement(
                        Transmit.new(left.clone,right.clone))
                else
                    # # puts "left/right is inout"
                    # if (left.is_a?(Ref)) then
                    #     inputs_blk.add_statement(
                    #         Transmit.new(left.clone,right.clone))
                    # end
                    # if (right.is_a?(Ref)) then
                    #     outputs_blk.add_statement(
                    #         Transmit.new(right.clone,left.clone))
                    # end
                    # Both or neither input/output, make a behavior
                    # for each.
                    if (left.is_a?(Ref)) then
                        blk = Block.new(:par)
                        blk.add_statement(
                            Transmit.new(left.clone,right.clone))
                        scope.add_behavior(Behavior.new(blk))
                    end
                    if (right.is_a?(Ref)) then
                        blk = Block.new(:par)
                        blk.add_statement(
                            Transmit.new(right.clone,left.clone))
                        scope.add_behavior(Behavior.new(blk))
                    end
                end
            end
            # Adds the behaviors.
            if inputs_blk.each_statement.any? then
                scope.add_behavior(Behavior.new(inputs_blk))
            end
            if outputs_blk.each_statement.any? then
                scope.add_behavior(Behavior.new(outputs_blk))
            end
            if timed_blk.each_statement.any? then
                scope.add_behavior(TimeBehavior.new(timed_blk))
            end
        end
    end
end

#delete_inout!(signal) ⇒ Object

Deletes an inout.



87
88
89
90
91
92
93
94
95
96
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 87

def delete_inout!(signal)
    if @inouts.key?(signal.name) then
        # The signal is present, delete it.
        @inouts.delete(signal.name)
        @interface.delete(signal)
        # And remove its parent.
        signal.parent = nil
    end
    signal
end

#delete_input!(signal) ⇒ Object

Deletes an input.



63
64
65
66
67
68
69
70
71
72
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 63

def delete_input!(signal)
    if @inputs.key?(signal.name) then
        # The signal is present, delete it.
        @inputs.delete(signal.name)
        @interface.delete(signal)
        # And remove its parent.
        signal.parent = nil
    end
    signal
end

#delete_output!(signal) ⇒ Object

Deletes an output.



75
76
77
78
79
80
81
82
83
84
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 75

def delete_output!(signal)
    if @outputs.key?(signal.name) then
        # The signal is present, delete it.
        @outputs.delete(signal.name)
        @interface.delete(signal)
        # And remove its parent.
        signal.parent = nil
    end
    signal
end

#each_inout(&ruby_block) ⇒ Object

Iterates over the inout signals.

Returns an enumerator if no ruby block is given.



229
230
231
232
233
234
# File 'lib/HDLRuby/hruby_low.rb', line 229

def each_inout(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_inout) unless ruby_block
    # A ruby block? Apply it on each inout signal instance.
    @inouts.each(&ruby_block)
end

#each_input(&ruby_block) ⇒ Object

Iterates over the input signals.

Returns an enumerator if no ruby block is given.



209
210
211
212
213
214
# File 'lib/HDLRuby/hruby_low.rb', line 209

def each_input(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_input) unless ruby_block
    # A ruby block? Apply it on each input signal instance.
    @inputs.each(&ruby_block)
end

#each_output(&ruby_block) ⇒ Object

Iterates over the output signals.

Returns an enumerator if no ruby block is given.



219
220
221
222
223
224
# File 'lib/HDLRuby/hruby_low.rb', line 219

def each_output(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_output) unless ruby_block
    # A ruby block? Apply it on each output signal instance.
    @outputs.each(&ruby_block)
end

#each_signal(&ruby_block) ⇒ Object

Iterates over all the signals of the interface of the system.

Returns an enumerator if no ruby block is given.



240
241
242
243
244
245
# File 'lib/HDLRuby/hruby_low.rb', line 240

def each_signal(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_signal) unless ruby_block
    # A ruby block? Apply it on each signal instance.
    @interface.each(&ruby_block)
end

#each_signal_all(&ruby_block) ⇒ Object

Iterates over all the signals of the system including its scope (input, output, inout, inner).

Returns an enumerator if no ruby block is given.



251
252
253
254
255
256
257
258
# File 'lib/HDLRuby/hruby_low.rb', line 251

def each_signal_all(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_signal) unless ruby_block
    # A ruby block? Apply it on each signal instance.
    @inputs.each(&ruby_block)
    @outputs.each(&ruby_block)
    @inouts.each(&ruby_block)
end

#each_signal_deep(&ruby_block) ⇒ Object

Iterates over all the signals of the system type and its scope.



261
262
263
264
265
266
267
268
269
270
# File 'lib/HDLRuby/hruby_low.rb', line 261

def each_signal_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_signal_deep) unless ruby_block
    # A ruby block?
    # First iterate over the current system type's signals.
    self.each_signal_all(&ruby_block)
    # Then apply on the behaviors (since in HDLRuby:High, blocks can
    # include signals).
    @scope.each_signal_deep(&ruby_block)
end

#each_systemT_deep(&ruby_block) ⇒ Object

Iterates over the systemT deeply if any.



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/HDLRuby/hruby_low.rb', line 381

def each_systemT_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_systemT_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the systemT accessible through the instances.
    self.scope.each_scope_deep do |scope|
        scope.each_systemI do |systemI|
            # systemI.systemT.each_systemT_deep(&ruby_block)
            systemI.each_systemT do |systemT|
                systemT.each_systemT_deep(&ruby_block)
            end
        end
    end
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/HDLRuby/hruby_low.rb', line 117

def eql?(obj)
    return false unless obj.is_a?(SystemT)
    return false unless @name.eql?(obj.name)
    return false unless @scope.eql?(obj.scope)
    idx = 0
    obj.each_input do |input|
        return false unless @inputs[input.name].eql?(input)
        idx += 1
    end
    return false unless idx == @inputs.size
    idx = 0
    obj.each_output do |output|
        return false unless @outputs[output.name].eql?(output)
        idx += 1
    end
    return false unless idx == @outputs.size
    idx = 0
    obj.each_inout do |inout|
        return false unless @inouts[inout.name].eql?(inout)
        idx += 1
    end
    return false unless idx == @inouts.size
    return true
end

#explicit_types!Object

Explicit the types conversions in the system.



18
19
20
21
22
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 18

def explicit_types!
    # No direct fix required in the system, recurse on the scope.
    self.scope.explicit_types!
    return self
end

#extract_port_assign!(systemI, signal) ⇒ Object

Extracts the assignments to port +systemI.signal+ and returns the resulting reference to a port wire.

NOTE: assumes to_upper_space! and with_port! has been called.



1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
# File 'lib/HDLRuby/hruby_verilog.rb', line 1704

def extract_port_assign!(systemI,signal)
    # Extract the assignment.
    assign = nil
    self.each_connection.to_a.each do |connection|
        if self.port_assign?(connection.left,systemI,signal) then
            # The left is the port.
            # Delete the connection.
            self.scope.delete_connection!(connection)
            # And return a copy of the right.
            return connection.right.clone
        elsif self.port_assign?(connection.right,systemI,signal) then
            # The right is the port.
            # Delete the connection.
            self.scope.delete_connection!(connection)
            # And return a copy of the left.
            return connection.left.clone
        end
    end
    # No port found, nothing to do
    return nil
end

#get_all_inoutsObject

Gets an array containing all the inout signals.



304
305
306
# File 'lib/HDLRuby/hruby_low.rb', line 304

def get_all_inouts
    return each_inout.to_a
end

#get_all_inputsObject

Gets an array containing all the input signals.



294
295
296
# File 'lib/HDLRuby/hruby_low.rb', line 294

def get_all_inputs
    return each_input.to_a
end

#get_all_outputsObject

Gets an array containing all the output signals.



299
300
301
# File 'lib/HDLRuby/hruby_low.rb', line 299

def get_all_outputs
    return each_output.to_a
end

#get_all_signalsObject

Gets an array containing all the signals.



309
310
311
# File 'lib/HDLRuby/hruby_low.rb', line 309

def get_all_signals
    return each_signal.to_a
end

#get_by_name(name) ⇒ Object

Find an inner object by +name+. NOTE: return nil if not found.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 20

def get_by_name(name)
    # Ensure the name is a symbol.
    name = name.to_sym
    # Look in the interface.
    found = self.get_signal(name)
    return found if found
    # Maybe it is the scope.
    return self.scope if self.scope.name == name
    # Look in the scope.
    return self.scope.get_by_name(name)
end

#get_inout(name) ⇒ Object

Gets an inout signal by +name+.



324
325
326
# File 'lib/HDLRuby/hruby_low.rb', line 324

def get_inout(name)
    return @inouts[name.to_sym]
end

#get_input(name) ⇒ Object

Gets an input signal by +name+.



314
315
316
# File 'lib/HDLRuby/hruby_low.rb', line 314

def get_input(name)
    return @inputs[name.to_sym]
end

#get_interface(i) ⇒ Object

Gets an interface signal by order of declaration +i+.



340
341
342
# File 'lib/HDLRuby/hruby_low.rb', line 340

def get_interface(i)
    return @interface[i]
end

#get_output(name) ⇒ Object

Gets an output signal by +name+.



319
320
321
# File 'lib/HDLRuby/hruby_low.rb', line 319

def get_output(name)
    return @outputs[name.to_sym]
end

#get_signal(name) ⇒ Object

Gets a signal by +name+.



334
335
336
337
# File 'lib/HDLRuby/hruby_low.rb', line 334

def get_signal(name)
    return get_input(name) || get_output(name) || get_inout(name) # ||
           # get_inner(name)
end

#has_inout?Boolean

Tells if there is any output signal.



283
284
285
# File 'lib/HDLRuby/hruby_low.rb', line 283

def has_inout?
    return !@inouts.empty?
end

#has_input?Boolean

Tells if there is any input signal.



273
274
275
# File 'lib/HDLRuby/hruby_low.rb', line 273

def has_input?
    return !@inputs.empty?
end

#has_output?Boolean

Tells if there is any output signal.



278
279
280
# File 'lib/HDLRuby/hruby_low.rb', line 278

def has_output?
    return !@outputs.empty?
end

#has_signal?Boolean

Tells if there is any signal (including in the scope of the system).



288
289
290
291
# File 'lib/HDLRuby/hruby_low.rb', line 288

def has_signal?
    return ( self.has_input? or self.has_output? or self.has_inout? or
             self.has_inner? )
end

#hashObject

Hash function.



143
144
145
# File 'lib/HDLRuby/hruby_low.rb', line 143

def hash
    return [@name,@scope,@inputs,@outputs,@inouts].hash
end

#initial_concat_to_timed!Object

Converts initial concat of values of signals to assignment in timed blocks (for making the code compatible with verilog translation).

NOTE: Assumes such array as at the top level.



30
31
32
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 30

def initial_concat_to_timed!
    self.scope.initial_concat_to_timed!
end

#map_inouts!(&ruby_block) ⇒ Object

Maps on the inouts.



54
55
56
57
58
59
60
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 54

def map_inouts!(&ruby_block)
    @inouts.map! do |inout|
        inout = ruby_block.call(inout)
        inout.parent = self unless inout.parent
        inout
    end
end

#map_inputs!(&ruby_block) ⇒ Object

Maps on the inputs.



36
37
38
39
40
41
42
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 36

def map_inputs!(&ruby_block)
    @inputs.map! do |input|
        input = ruby_block.call(input)
        input.parent = self unless input.parent
        input
    end
end

#map_outputs!(&ruby_block) ⇒ Object

Maps on the outputs.



45
46
47
48
49
50
51
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 45

def map_outputs!(&ruby_block)
    @outputs.map! do |output|
        output = ruby_block.call(output)
        output.parent = self unless output.parent
        output
    end
end

#mixblocks2seq!Object

Converts the par sub blocks to seq if they are not full par.



28
29
30
31
# File 'lib/HDLRuby/hruby_low2seq.rb', line 28

def mixblocks2seq!
    # Recurse on the scope.
    self.scope.mixblocks2seq!
end

#outread2inner!Object

Replace read of output signal to read of intermediate inner signal.

NOTE: the result is the same systemT.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/HDLRuby/hruby_low_without_outread.rb', line 23

def outread2inner!
    # puts "For system: #{self.name}"
    # First gather the read on output signals.
    outreads = {}
    gather_outreads = proc do |node|
        # puts "node=#{node.name}" if node.is_a?(RefName)
        if node.is_a?(RefName) && !node.leftvalue? then
            name = node.name
            # puts "name=#{name}"
            sig = self.get_output(name)
            outreads[node.name] = node if sig
        end
    end
    # Apply the procedure for gathering the read on outputs signals.
    self.scope.each_scope_deep do |scope|
        scope.each_connection do |connection|
            connection.each_node_deep(&gather_outreads)
        end
        scope.each_behavior do |behavior|
            behavior.each_event do |event|
                gather_outreads.(event.ref)
            end
            behavior.each_statement do |statement|
                # puts "statement=#{statement.class}"
                statement.each_node_deep(&gather_outreads)
            end
        end
    end
    # puts "outreads=#{outreads.keys}"

    # Generate one inner signal per read output.
    out2inner = {}
    outreads.each do |name,node|
        # Generate the inner variable.
        out2inner[name] = 
         self.scope.add_inner(SignalI.new(HDLRuby::uniq_name,node.type))
        # puts "new inner=#{out2inner[name].name}"
    end

    # Replace the output by the corresponding inner in the
    # expressions.
    replace_name = proc do |node| # The replacement procedure.
        # Only single name reference are to be replaced, the others
        # cannot correspond to output signal.
        if node.is_a?(RefName) && node.ref.is_a?(RefThis) &&
                !node.parent.is_a?(RefName) then
            inner = out2inner[node.name]
            # puts "node=#{node.name} inner=#{inner}"
            # puts "Replace name: #{node.name} by #{inner.name}" if inner
            node.set_name!(inner.name) if inner
        end
    end
    # Apply the replacement procedure on the code
    self.scope.each_scope_deep do |scope|
        scope.each_connection do |connection|
            connection.each_node_deep do |node|
                replace_name.(node)
            end
        end
        scope.each_behavior do |behavior|
            behavior.each_event do |event|
                event.ref.each_node_deep do |node|
                    replace_name.(node)
                end
            end
            behavior.each_statement do |statement|
                statement.each_node_deep do |node|
                    replace_name.(node)
                end
            end
        end
    end

    # Finally connect the inner to the output.
    out2inner.each do |out,inner|
        self.scope.add_connection(
         Connection.new(RefName.new(inner.type,RefThis.new,out),
                        RefName.new(inner.type,RefThis.new,inner.name)))
    end

    return self
end

#port_assign?(expr, systemI, signal) ⇒ Boolean

Tells if an expression is a reference to port +systemI.signal+.



1695
1696
1697
1698
# File 'lib/HDLRuby/hruby_verilog.rb', line 1695

def port_assign?(expr, systemI, signal)
    return expr.is_a?(RefName) && expr.name == signal.name &&
        expr.ref.is_a?(RefName) && expr.ref.name == systemI.name
end

#replace_names!(former, nname) ⇒ Object

Replaces recursively +former+ name by +nname+ until it is redeclared.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 60

def replace_names!(former,nname)
    # Replace owns name if required.
    if self.name == former then
        self.set_name!(nname)
    end
    # Recurse on the interface.
    self.each_input {|input| input.replace_names!(former,nname) }
    self.each_output {|output| output.replace_names!(former,nname) }
    self.each_inout {|inout| inout.replace_names!(former,nname) }
    # Recurse on the scope.
    self.scope.replace_names!(former,nname)
end

#select2case!Object

Converts the Select expressions to Case statements.



60
61
62
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 60

def select2case!
    self.scope.select2case!
end

#set_name!(name) ⇒ Object

Sets the +name+.



22
23
24
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 22

def set_name!(name)
    @name = name.to_sym
end

#set_scope!(scope) ⇒ Object

Sets the +scope+.



27
28
29
30
31
32
33
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 27

def set_scope!(scope)
    unless scope.is_a?(Scope) then
        raise AnyError, "Invalid class for a scope: #{scope.class}"
    end
    scope.parent = self
    @scope = scope
end

#to_c(level = 0, *hnames) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object and +hnames+ is the list of extra h files to include.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/HDLRuby/hruby_low2c.rb', line 148

def to_c(level = 0, *hnames)
    # The header
    res = Low2C.includes(*hnames)

    # Declare the global variable holding the system.
    res << "SystemT #{Low2C.obj_name(self)};\n\n"

    # Generate the signals of the system.
    self.each_signal { |signal| res << signal.to_c(level) }

    # Generate the code for all the blocks included in the system.
    self.scope.each_scope_deep do |scope|
        scope.each_behavior do |behavior|
            res << behavior.block.to_c_code(level)
        end
    end

    # Generate the code for all the values included in the system.
    self.each_signal do |signal|
        # res << signal.value.to_c_make(level) if signal.value
        signal.value.each_node_deep do |node|
            res << node.to_c_make(level) if node.respond_to?(:to_c_make)
        end if signal.value
    end
    self.scope.each_scope_deep do |scope|
        scope.each_inner do |signal|
            # res << signal.value.to_c_make(level) if signal.value
            signal.value.each_node_deep do |node|
                res << node.to_c_make(level) if node.respond_to?(:to_c_make)
            end if signal.value
        end
    end
    self.scope.each_block_deep do |block|
        block.each_inner do |signal|
            # res << signal.value.to_c_make(level) if signal.value
            signal.value.each_node_deep do |node|
                res << node.to_c_make(level) if node.respond_to?(:to_c_make)
            end if signal.value
        end
    end
    self.scope.each_node_deep do |node|
        res << node.to_c_make(level) if node.is_a?(Value)
    end

    # Generate the scope.
    res << self.scope.to_c(level)

    # Generate the entity
    res << "SystemT #{Low2C.make_name(self)}() {\n"
    # Creates the structure.
    res << " " * (level+1)*3
    res << "SystemT systemT = malloc(sizeof(SystemTS));\n"
    res << " " * (level+1)*3
    res << "systemT->kind = SYSTEMT;\n";

    # Sets the global variable of the system.
    res << "\n"
    res << " " * (level+1)*3
    res << "#{Low2C.obj_name(self)} = systemT;\n"

    # Set the owner if any.
    if @owner then
        res << " " * (level+1)*3
        res << "systemT->owner = (Object)" + 
               "#{Low2C.obj_name(@owner)};\n"
    else
        res << "systemT->owner = NULL;\n"
    end

    # The name
    res << " " * (level+1)*3
    res << "systemT->name = \"#{self.name}\";\n"

    # The ports
    # Inputs
    res << " " * (level+1)*3
    res << "systemT->num_inputs = #{self.each_input.to_a.size};\n"
    res << " " * (level+1)*3
    res << "systemT->inputs = calloc(sizeof(SignalI)," +
           "systemT->num_inputs);\n"
    self.each_input.with_index do |input,i|
        res << " " * (level+1)*3
        res << "systemT->inputs[#{i}] = " +
               "#{Low2C.make_name(input)}();\n"
    end
    # Outputs
    res << " " * (level+1)*3
    res << "systemT->num_outputs = #{self.each_output.to_a.size};\n"
    res << " " * (level+1)*3
    res << "systemT->outputs = calloc(sizeof(SignalI)," +
           "systemT->num_outputs);\n"
    self.each_output.with_index do |output,i|
        res << " " * (level+1)*3
        res << "systemT->outputs[#{i}] = " +
               "#{Low2C.make_name(output)}();\n"
    end
    # Inouts
    res << " " * (level+1)*3
    res << "systemT->num_inouts = #{self.each_inout.to_a.size};\n"
    res << " " * (level+1)*3
    res << "systemT->inouts = calloc(sizeof(SignalI)," +
           "systemT->num_inouts);\n"
    self.each_inout.with_index do |inout,i|
        res << " " * (level+1)*3
        res << "systemT->inouts[#{i}] = " +
               "#{Low2C.make_name(inout)}();\n"
    end

    # Adds the scope.
    res << "\n"
    res << " " * (level+1)*3
    res << "systemT->scope = #{Low2C.make_name(self.scope)}();\n"

    # Generate the Returns of the result.
    res << "\n"
    res << " " * (level+1)*3
    res << "return systemT;\n"
    # End of the system.
    res << " " * level*3
    res << "}"
    # Return the result.
    return res
end

#to_c_code(level) ⇒ Object

Generates the code for an execution starting from the system. +level+ is the hierachical level of the object.



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/HDLRuby/hruby_low2c.rb', line 275

def to_c_code(level)
    res << " " * (level*3)
    res << "#{Low2C.code_name(self)}() {\n"
    # res << "printf(\"Executing #{Low2C.code_name(self)}...\\n\");"
    # Launch the execution of all the time behaviors of the
    # system.
    self.each_behavior_deep do |behavior|
        if behavior.is_a?(HDLRuby::Low::TimeBehavior) then
            res << " " * (level+1)*3
            res << "#{Low2C.code_name(behavior.block)}();\n"
        end
    end
    # Close the execution procedure.
    res << " " * level*3
    res << "}\n"
    # Return the result.
    return res
end

#to_chObject

Generates the content of the h file.



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/HDLRuby/hruby_low2c.rb', line 296

def to_ch
    res = ""
    # Declare the global variable holding the signal.
    res << "extern SystemT #{Low2C.obj_name(self)};\n\n"

    # Generate the access to the function making the systemT. */
    res << "extern SystemT #{Low2C.make_name(self)}();\n\n"

    # Generate the accesses to the values.
    self.each_signal do |signal|
        # res << signal.value.to_ch if signal.value
        if signal.value then
            signal.value.each_node_deep do |node|
                res << node.to_ch if node.is_a?(Value)
            end
        end
    end
    self.scope.each_scope_deep do |scope|
        scope.each_inner do |signal|
            # res << signal.value.to_ch if signal.value
            if signal.value then
                signal.value.each_node_deep do |node|
                    res << node.to_ch if node.is_a?(Value)
                end
            end
        end
    end
    self.scope.each_block_deep do |block|
        block.each_inner do |signal|
            res << signal.value.to_ch if signal.value
        end
        block.each_node_deep do |node|
            res << node.to_ch if node.is_a?(Value)
        end
    end

    # Generate the accesses to the ports.
    self.each_input  { |input|  res << input.to_ch }
    self.each_output { |output| res << output.to_ch }
    self.each_inout  { |inout|  res << inout.to_ch }

    # Generate the accesses to the scope.
    res << self.scope.to_ch << "\n"


    return res;
end

#to_global_systemTs!Object

Moves local systemTs to global.

NOTE: assumes to_upper_space! has been called.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 44

def to_global_systemTs!
    # Force a name if not.
    self.force_name!
    # For each local systemT
    self.scope.each_systemT.to_a.each do |systemT|
        # Rename it for globalization.
        former = systemT.name
        self.extend_name!(systemT)
        # Apply the renaming to all the inner objects.
        self.scope.replace_names_subs!(former,systemT.name)
        # Remove it.
        self.scope.delete_systemT!(systemT)
    end
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/HDLRuby/hruby_low2high.rb', line 64

def to_high(level = 0)
    # The resulting string.
    res = ""
    # Generate the header.
    res << " " * (level*3)
    res << "system :#{Low2High.high_decl_name(self.name)} do\n"
    # Generate the interface.
    # Inputs.
    self.each_input do |input|
        res << " " * ((level+1)*3)
        res << input.type.to_high(level+1) 
        res << ".input :" << Low2High.high_decl_name(input.name)
        res << "\n"
    end
    # Outputs.
    self.each_output do |output|
        res << " " * ((level+1)*3)
        res << output.type.to_high(level+1) 
        res << ".output :" << Low2High.high_decl_name(output.name)
        res << "\n"
    end
    # Inouts.
    self.each_inout do |inout|
        res << " " * ((level+1)*3)
        res << inout.type.to_high(level+1) 
        res << ".inout :" << Low2High.high_decl_name(inout.name)
        res << "\n"
    end
    # Generate the scope.
    res << " " * (level*3)
    res << "\n"
    res << self.scope.to_high(level+1,false)
    # End of the system.
    res << " " * (level*3)
    res << "end\n\n"
    # Return the result.
    return res
end

#to_upper_space!Object

Moves the declarations to the upper namespace.



37
38
39
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 37

def to_upper_space!
    self.scope.to_upper_space!
end

#to_verilogObject

Converts the system to Verilog code.



1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
# File 'lib/HDLRuby/hruby_verilog.rb', line 1729

def to_verilog
    # Preprocessing
    # Detect the registers
    regs = []
    # The left values.
    self.each_behavior do |behavior|
        # behavior.block.each_statement do |statement|
        #     regs << statement.left.to_verilog if statement.is_a?(Transmit)
        # end
        behavior.each_block_deep do |block|
            block.each_statement do |statement|
                regs << statement.left.to_verilog if statement.is_a?(Transmit)
            end
        end
    end
    # And the initialized signals.
    self.each_output do |output|
        regs << output.to_verilog if output.value
    end
    self.each_inner do |inner|
        regs << inner.to_verilog if inner.value
    end
    # And the array types signals.
    self.each_signal do |sig|
        regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
    end
    self.each_inner do |sig|
        regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
    end

    # Code generation
    inputs = 0
    outputs = 0
    inout = 0

    inputs = self.each_input.to_a
    outputs = self.each_output.to_a
    inout = self.each_inout.to_a

    # Spelling necessary for simulation.
    code = "`timescale 1ps/1ps\n\n"
    # Output the module name.
    code << "module #{name_to_verilog(self.name)}("

    # Output the last two to the input. 
    inputs[0..-2].each do |input|
        code << " #{input.to_verilog},"
    end
    # When only input is used, it is necessary to close (), so it branches with if.
    if outputs.empty? && inout.empty? then
        # code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
        if (inputs.empty?)
            code << " ); \n"
        end
    else
        code << " #{inputs.last.to_verilog}," unless inputs.empty?
    end

    # Output the last two to the output. 
    outputs[0..-2].each do |output|
        code << " #{output.to_verilog},"
    end
    # When only input and output are used, it is necessary to close (), so it branches with if.
    if inout.empty? then
        code << " #{outputs.last.to_verilog} ); \n" unless outputs.empty?
    else
        code << " #{outputs.last.to_verilog}," unless outputs.empty?
    end

    # Output the last two to the inout. 
    inout[0..-2].each do |inout|
        code << " #{inout.to_verilog},"
    end
    # There is no comma as it is the last one
    code << " #{inout.last.to_verilog} ); \n" unless inout.empty?

    # Declare "input"
    self.each_input do |input|
        if input.type.respond_to? (:each_type) then
            $vector_reg = "#{input.to_verilog}"
            $vector_cnt = 0
            input.type.each_type do |type|
                code << "input #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
                $vector_cnt += 1
            end        
        else
            code << "   input#{input.type.to_verilog} #{input.to_verilog};\n"
        end
    end

    # Declare "output"
    self.each_output do |output|
        if output.type.respond_to? (:each_type) then
            $vector_reg = "#{output.to_verilog}"
            $vector_cnt = 0
            output.type.each_type do |type|
                if regs.include?(type.name) then
                    code << "   output reg"
                else
                    code << "   output"
                end
                # code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
                code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt}"
                if output.value then
                    # There is an initial value.
                    code << " = #{output.value.to_verilog}"
                end
                code << ";\n"
                $vector_cnt += 1
            end        
        else
            # if regs.include?(output.name) then
            if regs.include?(output.to_verilog) then
                code << "   output reg"
            else
                code << "   output"
            end
            # code << "#{output.type.to_verilog} #{output.to_verilog};\n"
            code << "#{output.type.to_verilog} #{output.to_verilog}"
            if output.value then
                # There is an initial value.
                code << " = #{output.value.to_verilog}"
            end
            code << ";\n"
        end
    end

    # Declare "inout"
    self.each_inout do |inout|
        if inout.type.respond_to? (:each_type) then
            $vector_reg = "#{inout.to_verilog}"
            $vector_cnt = 0
            inout.type.each_type do |type|
                code << "inout #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
                $vector_cnt += 1
            end        
        else
            code << "   inout#{inout.type.to_verilog} #{inout.to_verilog};\n"
        end
    end

    # Declare "inner".
    self.each_inner do |inner|
        # if regs.include?(inner.name) then
        if regs.include?(inner.to_verilog) then
            code << "   reg"
        else
            code << "   wire"
        end

        if inner.type.base? 
            if inner.type.base.base? 
                # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
                code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
            else
                # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
                code << "#{inner.type.to_verilog} #{inner.to_verilog}"
            end
        else
            # code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
            code << " #{inner.type.to_verilog}#{inner.to_verilog}"
        end
        if inner.value then
            # There is an initial value.
            code << " = #{inner.value.to_verilog}"
        end
        code << ";\n"
    end

    # If there is scope in scope, translate it.
    self.each_scope do |scope|
        scope.each_inner do |inner|
            # if regs.include?(inner.name) then
            if regs.include?(inner.to_verilog) then
                code << "   reg "
            else
                code << "   wire "
            end

            if inner.type.respond_to? (:base) 
                if inner.type.base.base?
                    # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
                    code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
                else
                    # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
                    code << "#{inner.type.to_verilog} #{inner.to_verilog}"
                end
            else
                # code << "inner #{inner.type.to_verilog} #{inner.to_verilog};\n"
                code << "inner #{inner.type.to_verilog} #{inner.to_verilog}"
            end
            if inner.value then
                # There is an initial value.
                code << " = #{inner.value.to_verilog}"
            end
            code << ";\n"
        end    

        scope.each_connection do |connection|
            code << "\n" 
            code << "#{connection.to_verilog}"
        end
    end

    code << "\n"

    # transliation of the instantiation part.
    # Generate the instances connections.
    self.each_systemI do |systemI| 
        # Its Declaration.
        code << " " * 3
        systemT = systemI.systemT
        code << name_to_verilog(systemT.name) << " "
        code << name_to_verilog(systemI.name) << "("
        # Its ports connections
        # Inputs
        systemT.each_input do |input|
            ref = self.extract_port_assign!(systemI,input)
            if ref then
                code << "." << name_to_verilog(input.name) << "(" 
                code << ref.to_verilog
                code << "),"
            end
        end
        # Outputs
        systemT.each_output do |output|
            ref = self.extract_port_assign!(systemI,output)
            if ref then
                code << "." << name_to_verilog(output.name) << "(" 
                code << ref.to_verilog
                code << "),"
            end
        end
        # Inouts
        systemT.each_inout do |inout|
            ref = self.extract_port_assign!(systemI,inout)
            if ref then
                code << "." << name_to_verilog(inout.name) << "(" 
                code << ref.to_verilog
                code << "),"
            end
        end
        # Remove the last "," for conforming with Verilog syntax.
        # and close the port connection.
        code[-1] = ");\n"
    end



    # translation of the connection part (assigen).
    self.each_connection do |connection|
        code << "#{connection.to_verilog}\n"
    end

    # Translation of behavior part (always).
    self.each_behavior do |behavior|
        if behavior.block.is_a?(TimeBlock) then
            # Extract and translate the TimeRepeat separately.
            behavior.each_block_deep do |blk|
                code << blk.repeat_to_verilog!
            end
            # And generate an initial block.
            code << "   initial begin\n"
        else
            # Generate a standard process.
            code << "   always @( "
            # If there is no "always" condition, it is always @("*").
            if behavior.each_event.to_a.empty? then
                code << "*"
            else
                event = behavior.each_event.to_a
                event[0..-2].each do |event|
                    # If "posedge" or "negedge" does not exist, the variable is set to condition.
                    if (event.type.to_s != "posedge" && event.type.to_s != "negedge") then
                        code << "#{event.ref.to_verilog}, "
                    else
                        # Otherwise, it outputs "psoedge" or "negedge" as a condition.
                        code << "#{event.type.to_s} #{event.ref.to_verilog}, "
                    end
                end
                # Since no comma is necessary at the end, we try not to separate commas separately at the end.
                if (event.last.type.to_s != "posedge" && event.last.type.to_s != "negedge") then
                    code << "#{event.last.ref.to_verilog}"
                else
                    code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
                end
            end
            code << " ) begin\n"
        end

        # Perform "scheduling" using the method "flatten".
        block = behavior.block.flatten(behavior.block.mode.to_s)

        # Declaration of "inner" part within "always".
        block.each_inner do |inner|
            # if regs.include?(inner.name) then
            if regs.include?(inner.to_verilog) then
                code << "      reg"
            else
                code << "      wire"
            end

            # Variable has "base", but if there is width etc, it is not in "base".
            # It is determined by an if.
            if inner.type.base? 
                if inner.type.base.base? 
                    # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
                    code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
                else
                    # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
                    code << "#{inner.type.to_verilog} #{inner.to_verilog}"
                end
            else
                # code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
                code << " #{inner.type.to_verilog}#{inner.to_verilog}"
            end
            if inner.value then
                # There is an initial value.
                code << " = #{inner.value.to_verilog}"
            end
            code << ";\n"
        end

        # Translate the block that finished scheduling.
        block.each_statement do |statement|
            code  << "\n      #{statement.to_verilog(behavior.block.mode.to_s)}"
        end

        $fm.fm_par.clear()

        code << "\n   end\n\n"
    end

    # Conclusion.
    code << "endmodule"
    return code
end

#to_vhdl(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 339

def to_vhdl(level = 0)
    # The resulting string.
    res = ""
    # Generate the entity
    # The header
    res << Low2VHDL.packages(" " * (level*3))
    res << " " * (level*3)
    res << "entity #{Low2VHDL.entity_name(self.name)} is\n"
    # The ports
    if self.each_input.any? || self.each_output.any? ||
           self.each_inout.any? then
        res << " " * ((level+1)*3)
        res << "port (\n"
        # Inputs
        self.each_input do |input|
            res << " " * ((level+2)*3)
            res << Low2VHDL.vhdl_name(input.name) << ": in " 
            res << input.type.to_vhdl << ";\n"
        end
        # Outputs
        self.each_output do |output|
            res << " " * ((level+2)*3)
            res << Low2VHDL.vhdl_name(output.name) << ": out " 
            res << output.type.to_vhdl << ";\n"
        end
        # Inouts
        self.each_inout do |inout|
            res << " " * ((level+2)*3)
            res << Low2VHDL.vhdl_name(inout.name) << ": inout " 
            res << inout.type.to_vhdl << ";\n"
        end
        # Remove the last ";" for conforming with VHDL syntax.
        res[-2..-1] = "\n" if res[-2] == ";"
        res << " " * ((level+1)*3)
        # Close the port declaration.
        res << ");\n"
    end
    # Close the entity
    res << " " * (level*3)
    res << "end #{Low2VHDL.entity_name(self.name)};\n\n"


    # Generate the architecture.
    res << " " * (level*3)
    res << "architecture #{Low2VHDL.architecture_name(self.name)} "
    res << "of #{Low2VHDL.entity_name(self.name)} is\n"
    # Generate the scope.
    res << "\n"
    res << self.scope.to_vhdl(level+1)
    # End of the system.
    res << " " * (level*3)
    res << "end #{Low2VHDL.architecture_name(self.name)};\n\n"
    # Return the result.
    return res
end

#with_boolean!Object

Converts to a variable-compatible system.

NOTE: the result is the same systemT.



59
60
61
62
63
64
65
# File 'lib/HDLRuby/hruby_low_with_bool.rb', line 59

def with_boolean!
    self.scope.each_scope_deep do |scope|
        scope.each_connection { |connection| connection.with_boolean! }
        scope.each_behavior   { |behavior|   behavior.with_boolean! }
    end
    return self
end

#with_port!Object

Converts to a port-compatible system.

NOTE: the result is the same systemT.



27
28
29
30
# File 'lib/HDLRuby/hruby_low_with_port.rb', line 27

def with_port!
    self.scope.with_port!
    return self
end

#with_var!Object

Converts to a variable-compatible system.

NOTE: the result is the same systemT.



21
22
23
24
# File 'lib/HDLRuby/hruby_low_with_var.rb', line 21

def with_var!
    self.each_behavior { |behavior| behavior.with_var! }
    return self
end