Module: HDLRuby::High::HExpression

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

Overview

class HDLRuby::High::Value

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.



2880
2881
2882
# File 'lib/HDLRuby/hruby_high.rb', line 2880

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2882
2883
2884
# File 'lib/HDLRuby/hruby_high.rb', line 2882

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



3062
3063
3064
# File 'lib/HDLRuby/hruby_high.rb', line 3062

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

Instance Method Details

#<=>(expr) ⇒ Object

The <=> operator is also supported by is transformed into a sub with a signed result.



3134
3135
3136
# File 'lib/HDLRuby/hruby_high.rb', line 3134

def <=>(expr)
    return (self.as(self.type.base[self.type.width+1])-expr).to_signed
end

#[](typ, rng = nil) ⇒ Object

Creates an access to elements of range +rng+ of the signal, and set the type of elements as +typ+ if given.

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



3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
# File 'lib/HDLRuby/hruby_high.rb', line 3143

def [](typ,rng=nil)
    # Treat the number of arguments
    rng, typ = typ, nil unless rng
    # Process the range.
    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
        if typ then
           return RefIndex.new(typ,self.to_expr,rng)
        else
           return RefIndex.new(self.type.base,self.to_expr,rng)
        end
    else
        # Range case, ensure it is made among expression.
        first = rng.first.to_expr
        last = rng.last.to_expr
        # And create the reference.
        if typ then
           return RefRange.new(typ,
                               self.to_expr,first..last)
        else
           return RefRange.new(self.type.slice(first..last),
                               self.to_expr,first..last)
        end
    end
end

#as(type) ⇒ Object

Casts as +type+.



2980
2981
2982
2983
2984
2985
2986
# File 'lib/HDLRuby/hruby_high.rb', line 2980

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.



3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
# File 'lib/HDLRuby/hruby_high.rb', line 3105

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)


2958
2959
2960
2961
2962
2963
2964
# File 'lib/HDLRuby/hruby_high.rb', line 2958

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.



2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
# File 'lib/HDLRuby/hruby_high.rb', line 2925

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.



2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
# File 'lib/HDLRuby/hruby_high.rb', line 2885

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.



3004
3005
3006
# File 'lib/HDLRuby/hruby_high.rb', line 3004

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



3093
3094
3095
3096
# File 'lib/HDLRuby/hruby_high.rb', line 3093

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.



3083
3084
3085
# File 'lib/HDLRuby/hruby_high.rb', line 3083

def ls(n)
    return self << n
end

#match_type(typ) ⇒ Object

Match the type with +typ+: cast if different type.



3053
3054
3055
3056
3057
3058
3059
# File 'lib/HDLRuby/hruby_high.rb', line 3053

def match_type(typ)
    if self.type.eql?(typ) then
        return self
    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.



3196
3197
3198
3199
3200
3201
3202
# File 'lib/HDLRuby/hruby_high.rb', line 3196

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



3065
3066
3067
# File 'lib/HDLRuby/hruby_high.rb', line 3065

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

#output(name) ⇒ Object

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



2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
# File 'lib/HDLRuby/hruby_high.rb', line 2905

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.



3009
3010
3011
# File 'lib/HDLRuby/hruby_high.rb', line 3009

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



3099
3100
3101
3102
# File 'lib/HDLRuby/hruby_high.rb', line 3099

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.



3088
3089
3090
# File 'lib/HDLRuby/hruby_high.rb', line 3088

def rs(n)
    return self >> n
end

#sdownto(val, &ruby_block) ⇒ Object

HW downto iteration.



2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
# File 'lib/HDLRuby/std/sequencer.rb', line 2153

def sdownto(val,&ruby_block)
    # Create the hardware iterator.
    # range = val..(self.to_i)
    range = AnyRange.new(val,self)
    hw_enum = SEnumeratorBase.new(signed[32],range.size) do |idx|
        range.last - idx
    end
    # Is there a ruby block?
    if(ruby_block) then
        # Yes, apply it.
        return hw_enum.seach(&ruby_block)
    else
        # No, return the resulting enumerator.
        return hw_enum
    end
end

#seach(&ruby_block) ⇒ Object

HW iteration on each element.



2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
# File 'lib/HDLRuby/std/sequencer.rb', line 2107

def seach(&ruby_block)
    # Create the hardware iterator.
    this = self
    hw_enum = SEnumeratorBase.new(this.type.base,this.type.size) do |idx,val = nil|
        if val then
            # Write access
            this[idx] <= val
        else
            # Read access
            this[idx]
        end
    end
    # Is there a ruby block?
    if(ruby_block) then
        # Yes, apply it.
        return hw_enum.seach(&ruby_block)
    else
        # No, return the resulting enumerator.
        return hw_enum
    end
end

#sext(n) ⇒ Object

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



3019
3020
3021
# File 'lib/HDLRuby/hruby_high.rb', line 3019

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

#stimes(&ruby_block) ⇒ Object

HW times iteration.



2141
2142
2143
2144
# File 'lib/HDLRuby/std/sequencer.rb', line 2141

def stimes(&ruby_block)
    # return (0..self-1).seach(&ruby_block)
    return AnyRange.new(0,self-1).seach(&ruby_block)
end

#supto(val, &ruby_block) ⇒ Object

HW upto iteration.



2147
2148
2149
2150
# File 'lib/HDLRuby/std/sequencer.rb', line 2147

def supto(val,&ruby_block)
    # return (self..val).seach(&ruby_block)
    return AnyRange.new(self,val).seach(&ruby_block)
end

#to_bitObject

Casts to a bit vector type.



2989
2990
2991
# File 'lib/HDLRuby/hruby_high.rb', line 2989

def to_bit
    return self.as(HDLRuby::High.top_user.bit[self.type.width])
end

#to_exprObject

Converts to a new expression.

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

Raises:



2970
2971
2972
# File 'lib/HDLRuby/hruby_high.rb', line 2970

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

#to_signedObject

Casts to a signed bit vector type.



2999
3000
3001
# File 'lib/HDLRuby/hruby_high.rb', line 2999

def to_signed
    return self.as(HDLRuby::High.top_user.signed[self.type.width])
end

#to_unsignedObject

Casts to an unsigned bit vector type.



2994
2995
2996
# File 'lib/HDLRuby/hruby_high.rb', line 2994

def to_unsigned
    return self.as(HDLRuby::High.top_user.unsigned[self.type.width])
end

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2952
2953
2954
2955
# File 'lib/HDLRuby/hruby_high.rb', line 2952

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)


2945
2946
2947
# File 'lib/HDLRuby/hruby_high.rb', line 2945

def to_value?
    return false
end

#zext(n) ⇒ Object

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



3014
3015
3016
# File 'lib/HDLRuby/hruby_high.rb', line 3014

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