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_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

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 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!, #leftvalue?, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #statement, #to_c_expr

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

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



5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
# File 'lib/HDLRuby/hruby_low.rb', line 5657

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.



5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
# File 'lib/HDLRuby/hruby_low.rb', line 5729

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.



286
287
288
289
290
291
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 286

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.



292
293
294
295
296
297
298
299
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 292

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)



5761
5762
5763
# File 'lib/HDLRuby/hruby_low.rb', line 5761

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

#delete_ref!(ref) ⇒ Object

Delete a reference.



1749
1750
1751
1752
1753
1754
1755
1756
1757
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1749

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.



5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
# File 'lib/HDLRuby/hruby_low.rb', line 5683

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.



5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
# File 'lib/HDLRuby/hruby_low.rb', line 5743

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.



5720
5721
5722
5723
5724
5725
# File 'lib/HDLRuby/hruby_low.rb', line 5720

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)


5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
# File 'lib/HDLRuby/hruby_low.rb', line 5697

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.



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 371

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.



5713
5714
5715
# File 'lib/HDLRuby/hruby_low.rb', line 5713

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

#immutable?Boolean

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

Returns:

  • (Boolean)


5673
5674
5675
5676
5677
5678
# File 'lib/HDLRuby/hruby_low.rb', line 5673

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.



1738
1739
1740
1741
1742
1743
1744
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1738

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)



2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
# File 'lib/HDLRuby/hruby_low2c.rb', line 2824

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)



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

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.



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

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.



463
464
465
466
# File 'lib/HDLRuby/hruby_low2high.rb', line 463

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

#to_verilogObject



1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
# File 'lib/HDLRuby/hruby_verilog.rb', line 1499

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.



1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1436

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)


5755
5756
5757
5758
# File 'lib/HDLRuby/hruby_low.rb', line 5755

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