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

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

Constructor Details

#initialize(type, ref, index) ⇒ RefIndex

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



4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
# File 'lib/HDLRuby/hruby_low.rb', line 4461

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.



4457
4458
4459
# File 'lib/HDLRuby/hruby_low.rb', line 4457

def index
  @index
end

#refObject (readonly)

The accessed reference.



4454
4455
4456
# File 'lib/HDLRuby/hruby_low.rb', line 4454

def ref
  @ref
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



250
251
252
253
254
255
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 250

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

#cloneObject

Clones the indexed references (deeply)



4527
4528
4529
# File 'lib/HDLRuby/hruby_low.rb', line 4527

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

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

Iterates over the reference children if any.



4505
4506
4507
4508
4509
4510
4511
# File 'lib/HDLRuby/hruby_low.rb', line 4505

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.



4516
4517
4518
4519
4520
4521
4522
4523
4524
# File 'lib/HDLRuby/hruby_low.rb', line 4516

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)


4481
4482
4483
4484
4485
4486
4487
4488
4489
# File 'lib/HDLRuby/hruby_low.rb', line 4481

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.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 366

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)


92
93
94
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 92

def from_systemI?
    return self.ref.from_systemI
end

#hashObject

Hash function.



4492
4493
4494
# File 'lib/HDLRuby/hruby_low.rb', line 4492

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

#map_nodes!(&ruby_block) ⇒ Object

Maps on the children.



1600
1601
1602
1603
1604
1605
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1600

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.



4499
4500
4501
4502
# File 'lib/HDLRuby/hruby_low.rb', line 4499

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.



1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1613

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

#set_index!(ref) ⇒ Object

Sets the index.



1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1588

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.



1577
1578
1579
1580
1581
1582
1583
1584
1585
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1577

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(level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is thehierachical level of the object and +left+ tells if it is a left value or not.



1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
# File 'lib/HDLRuby/hruby_low2c.rb', line 1848

def to_c(level = 0, left = false)
    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"
    # Compute the index.
    res << (" " * ((level+1)*3))
    # res << "idx = read64(#{self.index.to_c(level+2)});\n"
    res << "idx = value2integer(#{self.index.to_c(level+2)});\n"
    # Make the access.
    res << (" " * ((level+1)*3))
    res << "dst = read_range(ref,idx,idx,#{self.ref.type.base.to_c(level)},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; })"
end

#to_c_signal(level = 0) ⇒ Object

Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object.



1878
1879
1880
1881
# File 'lib/HDLRuby/hruby_low2c.rb', line 1878

def to_c_signal(level = 0)
    return "make_ref_rangeS(#{self.ref.to_c_signal(level)}," +
        "value2integer(#{self.index.to_c(level)}),value2integer(#{self.index.to_c(level)}))"
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



685
686
687
# File 'lib/HDLRuby/hruby_low2high.rb', line 685

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

#to_verilogObject

Converts the system to Verilog code.



1273
1274
1275
# File 'lib/HDLRuby/hruby_verilog.rb', line 1273

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.



1357
1358
1359
1360
1361
1362
1363
1364
1365
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1357

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