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.



2635
2636
2637
# File 'lib/HDLRuby/hruby_high.rb', line 2635

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2637
2638
2639
# File 'lib/HDLRuby/hruby_high.rb', line 2637

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



2808
2809
2810
# File 'lib/HDLRuby/hruby_high.rb', line 2808

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.



2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
# File 'lib/HDLRuby/hruby_high.rb', line 2881

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+.



2735
2736
2737
2738
2739
2740
2741
# File 'lib/HDLRuby/hruby_high.rb', line 2735

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.



2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
# File 'lib/HDLRuby/hruby_high.rb', line 2851

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)


2713
2714
2715
2716
2717
2718
2719
# File 'lib/HDLRuby/hruby_high.rb', line 2713

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.



2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
# File 'lib/HDLRuby/hruby_high.rb', line 2680

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.



2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
# File 'lib/HDLRuby/hruby_high.rb', line 2640

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.



2759
2760
2761
# File 'lib/HDLRuby/hruby_high.rb', line 2759

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



2839
2840
2841
2842
# File 'lib/HDLRuby/hruby_high.rb', line 2839

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.



2829
2830
2831
# File 'lib/HDLRuby/hruby_high.rb', line 2829

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.


2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
# File 'lib/HDLRuby/hruby_high.rb', line 2782

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.



2919
2920
2921
2922
2923
2924
2925
# File 'lib/HDLRuby/hruby_high.rb', line 2919

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



2811
2812
2813
# File 'lib/HDLRuby/hruby_high.rb', line 2811

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

#output(name) ⇒ Object

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



2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
# File 'lib/HDLRuby/hruby_high.rb', line 2660

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.



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

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



2845
2846
2847
2848
# File 'lib/HDLRuby/hruby_high.rb', line 2845

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.



2834
2835
2836
# File 'lib/HDLRuby/hruby_high.rb', line 2834

def rs(n)
    return self >> n
end

#sext(n) ⇒ Object

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



2774
2775
2776
# File 'lib/HDLRuby/hruby_high.rb', line 2774

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

#to_bitObject

Casts to a bit vector type.



2744
2745
2746
# File 'lib/HDLRuby/hruby_high.rb', line 2744

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:



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

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.



2749
2750
2751
# File 'lib/HDLRuby/hruby_high.rb', line 2749

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

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2707
2708
2709
2710
# File 'lib/HDLRuby/hruby_high.rb', line 2707

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)


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

def to_value?
    return false
end

#zext(n) ⇒ Object

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



2769
2770
2771
# File 'lib/HDLRuby/hruby_high.rb', line 2769

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