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, #scope

Constructor Details

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

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



5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
# File 'lib/HDLRuby/hruby_low.rb', line 5428

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.



5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
# File 'lib/HDLRuby/hruby_low.rb', line 5500

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)



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

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.



5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
# File 'lib/HDLRuby/hruby_low.rb', line 5454

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.



5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
# File 'lib/HDLRuby/hruby_low.rb', line 5514

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.



5491
5492
5493
5494
5495
5496
# File 'lib/HDLRuby/hruby_low.rb', line 5491

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)


5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
# File 'lib/HDLRuby/hruby_low.rb', line 5468

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.



5484
5485
5486
# File 'lib/HDLRuby/hruby_low.rb', line 5484

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

#immutable?Boolean

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

Returns:

  • (Boolean)


5444
5445
5446
5447
5448
5449
# File 'lib/HDLRuby/hruby_low.rb', line 5444

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)



2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
# File 'lib/HDLRuby/hruby_low2c.rb', line 2650

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)



2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
# File 'lib/HDLRuby/hruby_low2c.rb', line 2664

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



1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
# File 'lib/HDLRuby/hruby_verilog.rb', line 1490

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)


5526
5527
5528
5529
# File 'lib/HDLRuby/hruby_low.rb', line 5526

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