Module: HDLRuby::High::HExpression

Included in:
Binary, Cast, Concat, Select, Std::PipelineT::PipeSignal, StringE, Unary, Value
Defined in:
lib/HDLRuby/hruby_high.rb

Overview

Module giving high-level expression properties

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#systemTObject (readonly)

The system type the expression has been resolved in, if any.



2591
2592
2593
# File 'lib/HDLRuby/hruby_high.rb', line 2591

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2593
2594
2595
# File 'lib/HDLRuby/hruby_high.rb', line 2593

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



2764
2765
2766
# File 'lib/HDLRuby/hruby_high.rb', line 2764

def self.orig_operator(op)
    return (op.to_s + "_orig").to_sym
end

Instance Method Details

#[](rng) ⇒ Object

Creates an access to elements of range +rng+ of the signal.

NOTE: +rng+ can be a single expression in which case it is an index.



2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
# File 'lib/HDLRuby/hruby_high.rb', line 2837

def [](rng)
    if rng.is_a?(::Range) then
        first = rng.first
        if (first.is_a?(::Integer)) then
            first = self.type.size+first if first < 0
        end
        last = rng.last
        if (last.is_a?(::Integer)) then
            last = self.type.size+last if last < 0
        end
        rng = first..last
    end
    if rng.is_a?(::Integer) && rng < 0 then
        rng = self.type.size+rng
    end
    if rng.respond_to?(:to_expr) then
        # Number range: convert it to an expression.
        rng = rng.to_expr
    end 
    if rng.is_a?(HDLRuby::Low::Expression) then
        # Index case
        return RefIndex.new(self.type.base,self.to_expr,rng)
    else
        # Range case, ensure it is made among expression.
        first = rng.first.to_expr
        last = rng.last.to_expr
        # Abd create the reference.
        return RefRange.new(self.type.slice(first..last),
                            self.to_expr,first..last)
    end
end

#as(type) ⇒ Object

Casts as +type+.



2691
2692
2693
2694
2695
2696
2697
# File 'lib/HDLRuby/hruby_high.rb', line 2691

def as(type)
    if (self.parent)
        return Cast.new(type.to_type,self.to_expr)
    else
        return Cast.new(type.to_type,self)
    end
end

#coerce(obj) ⇒ Object

Coerce by forcing convertion of obj to expression.



2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
# File 'lib/HDLRuby/hruby_high.rb', line 2807

def coerce(obj)
    if obj.is_a?(HDLRuby::Low::Expression) then
        # Already an expression, nothing to do.
        return [obj,self]
    elsif obj.respond_to?(:to_expr) then
        # Can be converted to an expression, do it.
        return [obj.to_expr, self]
    else
        return [obj,self]
    end
end

#constant?Boolean

Tell if the expression is constant.

Returns:

  • (Boolean)


2669
2670
2671
2672
2673
2674
2675
# File 'lib/HDLRuby/hruby_high.rb', line 2669

def constant?
    # By default not constant.
    return false unless self.each_node.any?
    # If any sub node, check if all of them are constants.
    self.each_node { |node| return false unless node.constant? }
    return true
end

#inout(name) ⇒ Object

Creates inout port +name+ and connect it to the expression.



2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
# File 'lib/HDLRuby/hruby_high.rb', line 2636

def inout(name)
    # Ensures the name is a symbol.
    name = name.to_sym
    # Get access to the current expression
    obj = self
    # Create the inout.
    port = nil
    HDLRuby::High.cur_system.open do
        port = obj.type.inout(name)
    end
    # Make the connection when the instance is ready.
    HDLRuby::High.cur_system.on_instance do |inst|
        obj.scope.open do
            RefObject.new(inst,port.to_ref) <= obj
        end
    end
    return port
end

#input(name) ⇒ Object

Creates input port +name+ and connect it to the expression.



2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
# File 'lib/HDLRuby/hruby_high.rb', line 2596

def input(name)
    # Ensures the name is a symbol.
    name = name.to_sym
    # Get access to the current expression
    obj = self
    # Create the input.
    port = nil
    HDLRuby::High.cur_system.open do
        port = obj.type.input(name)
    end
    # Make the connection when the instance is ready.
    HDLRuby::High.cur_system.on_instance do |inst|
        obj.scope.open do
            RefObject.new(inst,port.to_ref) <= obj
        end
    end
    return port
end

#ljust(n, v) ⇒ Object

Extends on the left to +n+ bits filling with +v+ bit values.



2715
2716
2717
# File 'lib/HDLRuby/hruby_high.rb', line 2715

def ljust(n,v)
    return [(v.to_s * (n-self.width)).to_expr, self]
end

#lr(n) ⇒ Object

Left rotate of +n+ bits.



2795
2796
2797
2798
# File 'lib/HDLRuby/hruby_high.rb', line 2795

def lr(n)
    w = self.type.width
    return [self[w-(n+1)..0], self[w-1..w-(n)]]
end

#ls(n) ⇒ Object

Left shift of +n+ bits.



2785
2786
2787
# File 'lib/HDLRuby/hruby_high.rb', line 2785

def ls(n)
    return self << n
end

#match_type(typ) ⇒ Object

Match the type with +typ+:

  • Recurse on the sub expr if hierachical type, raising an arror if the expression is not hierarchical.
  • Directly cast otherwise.


2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
# File 'lib/HDLRuby/hruby_high.rb', line 2738

def match_type(typ)
    # Has the type sub types?
    if typ.types? then
        unless self.is_a?(Concat) then
            raise AnyError,
                "Invalid class for assignment to hierarchical: #{self.class}."
        end
        return Concat.new(typ,
          self.each_expression.zip(typ.each_type).map do |e,t|
            e.match_type(t)
        end)
    elsif typ.vector? && typ.base.hierarchical? then
        unless self.is_a?(Concat) then
            raise AnyError,
                "Invalid class for assignment to hierarchical: #{self.class}."
        end
        return Concat.new(typ,
          self.each_expression.map do |e|
            e.match_type(typ.base)
        end)
    else
        return self.as(typ)
    end
end

#mux(*choices) ⇒ Object

Converts to a select operator using current expression as condition for one of the +choices+.

NOTE: +choices+ can either be a list of arguments or an array. If +choices+ has only two entries (and it is not a hash), +value+ will be converted to a boolean.



2875
2876
2877
2878
2879
2880
2881
# File 'lib/HDLRuby/hruby_high.rb', line 2875

def mux(*choices)
    # Process the choices.
    choices = choices.flatten(1) if choices.size == 1
    choices.map! { |choice| choice.to_expr }
    # Generate the select expression.
    return Select.new(choices[0].type,"?",self.to_expr,*choices)
end

#orig_operator(op) ⇒ Object



2767
2768
2769
# File 'lib/HDLRuby/hruby_high.rb', line 2767

def orig_operator(op)
    HExpression.orig_operator(op)
end

#output(name) ⇒ Object

Creates output port +name+ and connect it to the expression.



2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
# File 'lib/HDLRuby/hruby_high.rb', line 2616

def output(name)
    # Ensures the name is a symbol.
    name = name.to_sym
    # Get access to the current expression
    obj = self
    # Create the output.
    port = nil
    HDLRuby::High.cur_system.open do
        port = obj.type.output(name)
    end
    # Make the connection when the instance is ready.
    HDLRuby::High.cur_system.on_instance do |inst|
        obj.scope.open do
            obj <= RefObject.new(inst,port.to_ref)
        end
    end
    return port
end

#rjust(n, v) ⇒ Object

Extends on the right to +n+ bits filling with +v+ bit values.



2720
2721
2722
# File 'lib/HDLRuby/hruby_high.rb', line 2720

def rjust(n,v)
    return [self, (v.to_s * (n-self.width)).to_expr]
end

#rr(n) ⇒ Object

Right rotate of +n+ bits.



2801
2802
2803
2804
# File 'lib/HDLRuby/hruby_high.rb', line 2801

def rr(n)
    w = self.type.width
    return [self[(n-1)..0], self[w-1..n]]
end

#rs(n) ⇒ Object

Right shift of +n+ bits.



2790
2791
2792
# File 'lib/HDLRuby/hruby_high.rb', line 2790

def rs(n)
    return self >> n
end

#sext(n) ⇒ Object

Extends on the left to +n+ bits preserving the signe.



2730
2731
2732
# File 'lib/HDLRuby/hruby_high.rb', line 2730

def sext(n)
    return self.ljust(self[-1])
end

#to_bitObject

Casts to a bit vector type.



2700
2701
2702
# File 'lib/HDLRuby/hruby_high.rb', line 2700

def to_bit
    return self.as(bit[self.width])
end

#to_exprObject

Converts to a new expression.

NOTE: to be redefined in case of non-expression class.

Raises:



2681
2682
2683
# File 'lib/HDLRuby/hruby_high.rb', line 2681

def to_expr
    raise AnyError, "Internal error: to_expr not defined yet for class: #{self.class}"
end

#to_unsignedObject

Casts to a signed bit vector type.



2705
2706
2707
# File 'lib/HDLRuby/hruby_high.rb', line 2705

def to_unsigned
    return self.as(unsigned[self.width])
end

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2663
2664
2665
2666
# File 'lib/HDLRuby/hruby_high.rb', line 2663

def to_value
    raise AnyError,
          "Expression cannot be converted to a value: #{self.class}"
end

#to_value?Boolean

Tell if the expression can be converted to a value.

Returns:

  • (Boolean)


2656
2657
2658
# File 'lib/HDLRuby/hruby_high.rb', line 2656

def to_value?
    return false
end

#zext(n) ⇒ Object

Extends on the left to +n+ bits filling with 0.



2725
2726
2727
# File 'lib/HDLRuby/hruby_high.rb', line 2725

def zext(n)
    return self.ljust(n,0)
end