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



5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
# File 'lib/HDLRuby/hruby_low.rb', line 5477

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.



5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
# File 'lib/HDLRuby/hruby_low.rb', line 5549

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)



5581
5582
5583
# File 'lib/HDLRuby/hruby_low.rb', line 5581

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

#delete_ref!(ref) ⇒ Object

Delete a reference.



1730
1731
1732
1733
1734
1735
1736
1737
1738
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1730

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.



5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
# File 'lib/HDLRuby/hruby_low.rb', line 5503

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.



5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
# File 'lib/HDLRuby/hruby_low.rb', line 5563

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.



5540
5541
5542
5543
5544
5545
# File 'lib/HDLRuby/hruby_low.rb', line 5540

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)


5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
# File 'lib/HDLRuby/hruby_low.rb', line 5517

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
# 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| 
            ref.explicit_types(self.type.get_type(i))
        end)
    end
end

#hashObject

Hash function.



5533
5534
5535
# File 'lib/HDLRuby/hruby_low.rb', line 5533

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

#immutable?Boolean

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

Returns:

  • (Boolean)


5493
5494
5495
5496
5497
5498
# File 'lib/HDLRuby/hruby_low.rb', line 5493

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.



1719
1720
1721
1722
1723
1724
1725
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1719

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)



2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
# File 'lib/HDLRuby/hruby_low2c.rb', line 2681

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)



2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
# File 'lib/HDLRuby/hruby_low2c.rb', line 2695

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.



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

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)


5575
5576
5577
5578
# File 'lib/HDLRuby/hruby_low.rb', line 5575

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