Class: HDLRuby::Low::RefConcat

Inherits:
Ref show all
Includes:
MutableConcat
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb

Overview

Extends the RefConcat class with functionality for converting booleans in assignments to select operators.

Direct Known Subclasses

High::RefConcat

Constant Summary

Constants included from Low2Symbol

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

Instance Attribute Summary

Attributes inherited from Expression

#type

Attributes included from Hdecorator

#hdr_id

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from MutableConcat

#replace_expressions!

Methods inherited from Ref

#path_each

Methods inherited from Expression

#boolean?, #break_types!, #each_ref_deep, #extract_selects_to!, #leftvalue?, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #statement

Methods included from Low2Symbol

#to_sym

Methods included from Hdecorator

decorate_parent_id, dump, each, each_with_property, get, included, load, #properties

Methods included from Hparent

#scope

Constructor Details

#initialize(type, refs = []) ⇒ RefConcat

Creates a new reference with +type+ concatenating the references of +refs+ together. def initialize(refs = [])



4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
# File 'lib/HDLRuby/hruby_low.rb', line 4973

def initialize(type, refs = [])
    super(type)
    # Check and set the refs.
    refs.each do |ref|
        # puts "ref.class=#{ref.class}"
        unless ref.is_a?(Ref) then
            raise AnyError,
                  "Invalid class for an reference: #{ref.class}"
        end
    end
    @refs = refs
    # And set their parents.
    refs.each { |ref| ref.parent = self }
end

Instance Method Details

#add_ref(ref) ⇒ Object

Adds an +ref+ to concat.



5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
# File 'lib/HDLRuby/hruby_low.rb', line 5037

def add_ref(ref)
    # Check ref.
    unless ref.is_a?(Ref) then
        raise AnyError,
              "Invalid class for an ref: #{ref.class}"
    end
    # Add it.
    @refs << ref
    # And set its parent.
    ref.parent = self
    ref
end

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



260
261
262
263
264
265
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 260

def boolean_in_assign2select
    # Recurse on the sub references.
    return RefConcat.new(self.type,self.each_expression.map do |expr|
        expr.boolean_in_assign2select
    end )
end

#casts_without_expressionObject

Extracts the expressions from the casts.



268
269
270
271
272
273
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 268

def casts_without_expression
    # Recurse on the sub references.
    return RefConcat.new(self.type,self.each_expression.map do |expr|
        expr.casts_without_expression
    end )
end

#cloneObject

Clones the concatenated references (deeply)



5069
5070
5071
# File 'lib/HDLRuby/hruby_low.rb', line 5069

def clone
    return RefConcat.new(@type, @refs.map { |ref| ref.clone } )
end

#delete_ref!(ref) ⇒ Object

Delete a reference.



1648
1649
1650
1651
1652
1653
1654
1655
1656
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1648

def delete_ref!(ref)
    if @refs.include?(ref) then
        # The ref is present, delete it.
        @refs.delete(ref)
        # And remove its parent.
        ref.parent = nil
    end
    ref
end

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
# File 'lib/HDLRuby/hruby_low.rb', line 4991

def each_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # Then apply on the type.
    self.type.each_deep(&ruby_block)
    # Then apply on the sub references.
    self.each_ref do |ref|
        ref.each_deep(&ruby_block)
    end
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
# File 'lib/HDLRuby/hruby_low.rb', line 5051

def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the sub references.
    self.each_ref do |ref|
        ref.each_node_deep(&ruby_block)
    end
end

#each_ref(&ruby_block) ⇒ Object Also known as: each_node

Iterates over the concatenated references.

Returns an enumerator if no ruby block is given.



5028
5029
5030
5031
5032
5033
# File 'lib/HDLRuby/hruby_low.rb', line 5028

def each_ref(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_ref) unless ruby_block
    # A ruby block? Apply it on each children.
    @refs.each(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
# File 'lib/HDLRuby/hruby_low.rb', line 5005

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(RefConcat)
    idx = 0
    obj.each_ref do |ref|
        return false unless @refs[idx].eql?(ref)
        idx += 1
    end
    return false unless idx == @refs.size
    return false unless @refs.eql?(obj.instance_variable_get(:@refs))
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the concat ref where +type+ is the expected type of the condition if any.



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 338

def explicit_types(type = nil)
    # Is there a type to match?
    if type then
        # Yes, update the concat to the type.
        # Is it an array type?
        if type.is_a?(TypeVector) then
            # Yes, update the concat accordingly.
            return RefConcat.new(type,self.each_ref.map do |ref|
                ref.explicit_types(type.base)
            end)
        else
            # No, it should be a tuple.
            return RefConcat.new(type,self.each_ref.map.with_index do
                |ref,i|
                ref.explicit_types(type.get_type(i))
            end)
        end
    else
        # No, recurse on the sub expressions.
        return RefConcat.new(self.type,self.each_ref.map.with_index do
            |ref,i| 
            ref.explicit_types(self.type.get_type(i))
        end)
    end
end

#hashObject

Hash function.



5021
5022
5023
# File 'lib/HDLRuby/hruby_low.rb', line 5021

def hash
    return [super,@refs].hash
end

#map_refs!(&ruby_block) ⇒ Object Also known as: map_nodes!

Maps on the references.



1637
1638
1639
1640
1641
1642
1643
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1637

def map_refs!(&ruby_block)
    @refs.map! do |ref|
        ref = ruby_block.call(ref)
        ref.parent = self unless ref.parent
        ref
    end
end

#to_c(level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object and +left+ tells if it is a left value or not.



1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
# File 'lib/HDLRuby/hruby_low2c.rb', line 1914

def to_c(level = 0, left = false)
    raise "RefConcat cannot be converted to C directly, please use break_concat_assign!."
    # # The resulting string.
    # res = "ref_concat(#{self.each_ref.to_a.size}"
    # self.each_ref do |ref|
    #     res << ",#{ref.to_c(level,left)}"
    # end
    # res << ")"
    # return res
end

#to_c_signal(level = 0) ⇒ Object

Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object.



1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
# File 'lib/HDLRuby/hruby_low2c.rb', line 1927

def to_c_signal(level = 0)
    raise "RefConcat cannot be converted to C directly, please use break_concat_assign!."
    # # The resulting string.
    # res = "sig_concat(#{self.each_ref.to_a.size}"
    # self.each_ref do |ref|
    #     res << ",#{ref.to_c_signal(level)}"
    # end
    # res << ")"
    # return res
end

#to_high(level = 0) ⇒ Object

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



664
665
666
667
668
669
670
671
672
673
674
675
676
677
# File 'lib/HDLRuby/hruby_low2high.rb', line 664

def to_high(level = 0)
    # The resulting string.
    res = ""
    # Generate the header.
    res << "[ "
    # Generate the references.
    res << self.each_ref.map do |ref|
        ref.to_high(level+1)
    end.join(", ")
    # Close the select.
    res << " ]"
    # Return the resulting string.
    return res
end

#to_verilogObject



1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
# File 'lib/HDLRuby/hruby_verilog.rb', line 1445

def to_verilog    
    ref = self.each_ref.to_a

    result = "{"
    ref[0..-2].each do |ref|
        result << "#{ref.to_verilog},"
    end
    result << "#{ref.last.to_verilog}}"

    return result
end

#to_vhdl(level = 0) ⇒ Object

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



1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1398

def to_vhdl(level = 0)
    # The resulting string.
    res = ""
    # Generate the header.
    res << "( "
    # Generate the references.
    res << self.each_ref.map do |ref|
        ref.to_vhdl(level+1)
    end.join(", ")
    # Close the select.
    res << " )"
    # Return the resulting string.
    return res
end

#use_name?(*names) ⇒ Boolean

Tell if the expression includes a signal whose name is one of +names+.

Returns:

  • (Boolean)


5063
5064
5065
5066
# File 'lib/HDLRuby/hruby_low.rb', line 5063

def use_name?(*names)
    # Recurse on the references.
    return @refs.any? { |expr| expr.use_name?(*names) }
end