Class: HDLRuby::Low::RefIndex

Inherits:
Ref show all
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_resolve.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 RefIndex class with functionality for converting booleans in assignments to select operators.

Direct Known Subclasses

High::RefIndex

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods inherited from Expression

#boolean?, #break_types!, #each_ref_deep, #extract_selects_to!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #statement

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #scope

Constructor Details

#initialize(type, ref, index) ⇒ RefIndex

Create a new index reference with +type+ accessing +ref+ at +index+. def initialize(ref,index)



5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
# File 'lib/HDLRuby/hruby_low.rb', line 5342

def initialize(type,ref,index)
    super(type)
    # Check and set the accessed reference.
    unless ref.is_a?(Ref) then
        raise AnyError, "Invalid class for a reference: #{ref.class}."
    end
    @ref = ref
    # And set its parent.
    ref.parent = self
    # Check and set the index.
    unless index.is_a?(Expression) then
        raise AnyError,
              "Invalid class for an index reference: #{index.class}."
    end
    @index = index
    # And set its parent.
    index.parent = self
end

Instance Attribute Details

#indexObject (readonly)

The access index.



5338
5339
5340
# File 'lib/HDLRuby/hruby_low.rb', line 5338

def index
  @index
end

#refObject (readonly)

The accessed reference.



5335
5336
5337
# File 'lib/HDLRuby/hruby_low.rb', line 5335

def ref
  @ref
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



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

def boolean_in_assign2select
    # Recurse on the sub references.
    return RefIndex.new(self.type,
                        self.ref.boolean_in_assign2select,
                        self.index.boolean_in_assign2select)
end

#casts_without_expression!Object

Extracts the expressions from the casts.



307
308
309
310
311
312
313
314
315
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 307

def casts_without_expression!
    # Recurse on the sub references.
    # return RefIndex.new(self.type,
    #                     self.ref.casts_without_expression,
    #                     self.index.casts_without_expression)
    self.set_ref!(self.ref.casts_without_expression!)
    self.set_index!(self.index.casts_without_expression!)
    return self
end

#cloneObject

Clones the indexed references (deeply)



5438
5439
5440
# File 'lib/HDLRuby/hruby_low.rb', line 5438

def clone
    return RefIndex.new(@type, @ref.clone, @index.clone)
end

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
# File 'lib/HDLRuby/hruby_low.rb', line 5370

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 reference.
    self.ref.each_deep(&ruby_block)
    # Then apply on the index if possible.
    if self.index.respond_to?(:each_deep) then
        self.index.each_deep(&ruby_block)
    end
end

#each_node(&ruby_block) ⇒ Object Also known as: each_expression

Iterates over the reference children if any.



5410
5411
5412
5413
5414
5415
5416
# File 'lib/HDLRuby/hruby_low.rb', line 5410

def each_node(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node) unless ruby_block
    # A ruby block? Apply it on the index and the ref.
    ruby_block.call(@index)
    ruby_block.call(@ref)
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



5421
5422
5423
5424
5425
5426
5427
5428
5429
# File 'lib/HDLRuby/hruby_low.rb', line 5421

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 children.
    @index.each_node_deep(&ruby_block)
    @ref.each_node_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


5386
5387
5388
5389
5390
5391
5392
5393
5394
# File 'lib/HDLRuby/hruby_low.rb', line 5386

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(RefIndex)
    return false unless @index.eql?(obj.index)
    return false unless @ref.eql?(obj.ref)
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the index ref where +type+ is the expected type of the condition if any.



384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 384

def explicit_types(type = nil)
    # Is there a type to match ?
    if type then
        # Regenerate the reference and cast it
        return Cast.new(type,
                RefIndex.new(self.type,self.ref.explicit_types,
                            self.index.explicit_types))
    else
        # No, recurse with the type of the current index ref.
        return RefIndex.new(self.type,
                            self.ref.explicit_types,
                            self.index.explicit_types)
    end
end

#from_systemI?Boolean

Tells if it is a reference to a systemI signal.

Returns:

  • (Boolean)


107
108
109
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 107

def from_systemI?
    return self.ref.from_systemI?
end

#hashObject

Hash function.



5397
5398
5399
# File 'lib/HDLRuby/hruby_low.rb', line 5397

def hash
    return [super,@index,@ref].hash
end

#immutable?Boolean

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

Returns:

  • (Boolean)


5362
5363
5364
5365
# File 'lib/HDLRuby/hruby_low.rb', line 5362

def immutable?
    # Immutable if the ref is immutable.
    return self.ref.immutable?
end

#map_nodes!(&ruby_block) ⇒ Object

Maps on the children.



1771
1772
1773
1774
1775
1776
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1771

def map_nodes!(&ruby_block)
    @index = ruby_block.call(@index)
    @index.parent = self unless @index.parent
    @ref   = ruby_block.call(@ref)
    @ref.parent = self unless @ref.parent
end

#path_each(&ruby_block) ⇒ Object

Iterates over the names of the path indicated by the reference.

Returns an enumerator if no ruby block is given.



5404
5405
5406
5407
# File 'lib/HDLRuby/hruby_low.rb', line 5404

def path_each(&ruby_block)
    # Recurse on the base reference.
    return ref.path_each(&ruby_block)
end

#replace_expressions!(node2rep) ⇒ Object

Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.



1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1784

def replace_expressions!(node2rep)
    # First recurse on the ref.
    res = self.ref.replace_expressions!(node2rep)
    # And and the index.
    res = self.index.replace_expressions!(node2rep)
    
    # Is there a replacement to on the ref?
    rep = node2rep[self.ref]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.ref
        # node.set_parent!(nil)
        self.set_ref!(rep)
        # And register the replacement.
        res[node] = rep
    end
    # Is there a replacement to on the index?
    rep = node2rep[self.index]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.index
        # node.set_parent!(nil)
        self.set_index!(rep)
        # And register the replacement.
        res[node] = rep
    end
    return res
end

#resolveObject

Resolves the name of the reference (if any) and return the corresponding object. NOTE: return nil if could not resolve.



114
115
116
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 114

def resolve
    return self.ref.resolve
end

#set_index!(ref) ⇒ Object

Sets the index.



1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1759

def set_index!(ref)
    # Check and set the index.
    unless index.is_a?(Expression) then
        raise AnyError,
              "Invalid class for an index reference: #{index.class}."
    end
    @index = index
    # And set its parent.
    index.parent = self
end

#set_ref!(ref) ⇒ Object

Sets the base reference.



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

def set_ref!(ref)
    # Check and set the accessed reference.
    unless ref.is_a?(Ref) then
        raise AnyError, "Invalid class for a reference: #{ref.class}."
    end
    @ref = ref
    # And set its parent.
    ref.parent = self
end

#to_c(res, level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby code.

+level+ is thehierachical level of the object and

+left+ tells if it is a left value or not.

def to_c(level = 0, left = false)

def to_c(res,level = 0, left = false) # res = "( res << "({\n" # And allocates a new value for dst. res << (" " * ((level+1)*3)) res << "Value ref,dst = get_value();\n" res << (" " * ((level+1)*3)) res << "unsigned long long idx;\n" # Save the state of the value pool. res << (" " * ((level+1)*3)) res << "unsigned int pool_state = get_value_pos();\n" # Compute the reference. res << (" " * ((level+1)*3)) # res << "ref = #{self.ref.to_c(level+2);\n" res << "ref = " self.ref.to_c(res,level+2) res << ";\n" # Compute the index. res << (" " * ((level+1)*3)) # res << "idx = value2integer(#HDLRuby::Low::RefIndex.selfself.indexself.index.to_c(level+2));\n" res << "idx = value2integer(" self.index.to_c(res,level+2) res << ");\n" # Make the access. res << (" " * ((level+1)*3)) # puts "self.type.width=#HDLRuby::Low::RefIndex.selfself.typeself.type.width" # res << "dst = read_range(ref,idx,idx,#HDLRuby::Low::RefIndex.selfself.typeself.type.to_c(level),dst);\n" res << "dst = read_range(ref,idx,idx," # res << self.type.to_c(level) self.type.to_c(res,level) res << ",dst);\n" # Restore the state of the value pool. res << (" " * ((level+1)*3)) res << "set_value_pos(pool_state);\n" # Close the computation. res << (" " * (level*3)) res << "dst; })" return res end Generates the C text of the equivalent HDLRuby code. +level+ is thehierachical level of the object and +left+ tells if it is a left value or not.



2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
# File 'lib/HDLRuby/hruby_low2c.rb', line 2605

def to_c(res,level = 0, left = false)
    # Save the value pool state.
    res << (" " * (level*3)) << "SV;\n"
    # Compute the reference.
    self.ref.to_c(res,level)
    # Compute the index.
    self.index.to_c(res,level)
    res << (" " * (level*3))
    # Make the access.
    res << (" " * (level*3))
    if (left) then
        res << "swriteI("
    else
        res << "sreadI("
    end
    self.type.to_c(res,level)
    res << ");\n"
    # Restore the value pool state.
    res << (" " * (level*3)) << "RV;\n"
    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)

def to_c_signal(res,level = 0) # puts "to_c_signal for RefIndex" res << "make_ref_rangeS(" self.ref.to_c_signal(res,level) res << "," self.type.to_c(res,level) res << ",value2integer(" self.index.to_c(res,level) res << "),value2integer(" self.index.to_c(res,level) res << "))" return res end 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)



2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
# File 'lib/HDLRuby/hruby_low2c.rb', line 2646

def to_c_signal(res,level = 0)
    # puts "to_c_signal for RefIndex"
    res << "make_ref_rangeS("
    self.ref.to_c_signal(res,level)
    res << ","
    self.type.to_c(res,level)
    res << ",value2integer(({\n"
    self.index.to_c(res,level)
    res << " " * ((level+1)*3)
    res << "pop();})"
    res << "),value2integer(({\n"
    self.index.to_c(res,level)
    res << " " * ((level+1)*3)
    res << "pop();})"
    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
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 685

def to_hdr(level = 0)
    return self.ref.to_hdr(level) + "[#{self.index.to_hdr(level)}]"
end

#to_highObject

Creates a new high index reference.



473
474
475
476
477
# File 'lib/HDLRuby/hruby_low2high.rb', line 473

def to_high
    return HDLRuby::High::RefIndex.new(self.type.to_high,
                                       self.ref.to_high,
                                       self.index.to_high)
end

#to_verilogObject

Converts the system to Verilog code.



1453
1454
1455
# File 'lib/HDLRuby/hruby_verilog.rb', line 1453

def to_verilog
    return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
end

#to_vhdl(level = 0, std_logic = false) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object. +std_logic+ tells if std_logic computation is to be done.



1445
1446
1447
1448
1449
1450
1451
1452
1453
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1445

def to_vhdl(level = 0, std_logic = false)
    if self.index.is_a?(Value) then
        return self.ref.to_vhdl(level,std_logic) + 
            "(#{self.index.to_vhdl(level)})"
    else
        return self.ref.to_vhdl(level,std_logic) +
            "(to_integer(unsigned(#{self.index.to_vhdl(level)})))"
    end
end

#use_name?(*names) ⇒ Boolean

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

Returns:

  • (Boolean)


5432
5433
5434
5435
# File 'lib/HDLRuby/hruby_low.rb', line 5432

def use_name?(*names)
    # Recurse on the index and the reference.
    return @index.use_name?(names) || @ref.use_name?(*names)
end