Class: HDLRuby::Low::RefConcat

Inherits:
Ref show all
Includes:
MutableConcat
Defined in:
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_viz.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2hdr.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

Describes concatenation reference.

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 Hparent

#parent

Instance Method Summary collapse

Methods included from MutableConcat

#replace_expressions!

Methods inherited from Ref

#path_each, #resolve

Methods inherited from Expression

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

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#absolute_ref, #hierarchy, #no_parent!, #scope

Constructor Details

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

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



5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
# File 'lib/HDLRuby/hruby_low.rb', line 5828

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.



5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
# File 'lib/HDLRuby/hruby_low.rb', line 5900

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.



296
297
298
299
300
301
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 296

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_expression!Object

Extracts the expressions from the casts.



300
301
302
303
304
305
306
307
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 300

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 )
    self.map_expressions! {|expr| expr.casts_without_expression! }
    return self
end

#cloneObject

Clones the concatenated references (deeply)



5932
5933
5934
# File 'lib/HDLRuby/hruby_low.rb', line 5932

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

#delete_ref!(ref) ⇒ Object

Delete a reference.



1691
1692
1693
1694
1695
1696
1697
1698
1699
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1691

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.



5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
# File 'lib/HDLRuby/hruby_low.rb', line 5854

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.



5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
# File 'lib/HDLRuby/hruby_low.rb', line 5914

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.



5891
5892
5893
5894
5895
5896
# File 'lib/HDLRuby/hruby_low.rb', line 5891

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.



5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
# File 'lib/HDLRuby/hruby_low.rb', line 5868

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.



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 398

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| 
            puts "self.type=#{self.type}"
            ref.explicit_types(self.type.get_type(i))
        end)
    end
end

#hashObject

Hash function.



5884
5885
5886
# File 'lib/HDLRuby/hruby_low.rb', line 5884

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

#immutable?Boolean

Tells if the expression is immutable (cannot be written.)



5844
5845
5846
5847
5848
5849
# File 'lib/HDLRuby/hruby_low.rb', line 5844

def immutable?
    # Immutable if children are all immutable.
    return self.each_ref.reduce(true) do |r,c|
        r && c.immutable?
    end
end

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

Maps on the references.



1680
1681
1682
1683
1684
1685
1686
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1680

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(res, level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object and +left+ tells if it is a left value or not. def to_c(level = 0, left = false)



2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
# File 'lib/HDLRuby/hruby_low2c.rb', line 2838

def to_c(res,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(res, level = 0) ⇒ Object

Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object. def to_c_signal(level = 0)



2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
# File 'lib/HDLRuby/hruby_low2c.rb', line 2852

def to_c_signal(res,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_hdr(level = 0) ⇒ Object

Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.



685
686
687
688
689
690
691
692
693
694
695
696
697
698
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 685

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

#to_highObject

Creates a new high concat reference.



500
501
502
503
# File 'lib/HDLRuby/hruby_low2high.rb', line 500

def to_high
    return HDLRuby::High::Ref.new(self.type.to_high,
                            self.each_ref.map { |ref| ref.to_high })
end

#to_verilogObject

Enhances RefConcat with generation of verilog code.



1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
# File 'lib/HDLRuby/hruby_verilog.rb', line 1599

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.



1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1466

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

#to_viz_namesObject

Get the port names for visualization from the expression.



4942
4943
4944
# File 'lib/HDLRuby/hruby_viz.rb', line 4942

def to_viz_names
  return self.each_ref.map {|ref| ref.to_viz_names }.flatten
end

#to_viz_node(parent) ⇒ Object

Converts the index reference to a Viz flow node under +parent+.



4947
4948
4949
4950
4951
4952
4953
# File 'lib/HDLRuby/hruby_viz.rb', line 4947

def to_viz_node(parent)
  # Create the viz node.
  node = HDLRuby::Viz::Node.new(:concat,parent)
  # And generate the children.
  self.each_node {|child| child.to_viz_node(node) }
  return node
end

#use_name?(*names) ⇒ Boolean

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



5926
5927
5928
5929
# File 'lib/HDLRuby/hruby_low.rb', line 5926

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