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 = [])



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

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.



5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
# File 'lib/HDLRuby/hruby_low.rb', line 5925

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)



5957
5958
5959
# File 'lib/HDLRuby/hruby_low.rb', line 5957

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.



5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
# File 'lib/HDLRuby/hruby_low.rb', line 5879

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.



5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
# File 'lib/HDLRuby/hruby_low.rb', line 5939

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.



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

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)


5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
# File 'lib/HDLRuby/hruby_low.rb', line 5893

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.



5909
5910
5911
# File 'lib/HDLRuby/hruby_low.rb', line 5909

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

#immutable?Boolean

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

Returns:

  • (Boolean)


5869
5870
5871
5872
5873
5874
# File 'lib/HDLRuby/hruby_low.rb', line 5869

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+.

Returns:

  • (Boolean)


5951
5952
5953
5954
# File 'lib/HDLRuby/hruby_low.rb', line 5951

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