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.



2892
2893
2894
# File 'lib/HDLRuby/hruby_high.rb', line 2892

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2894
2895
2896
# File 'lib/HDLRuby/hruby_high.rb', line 2894

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



3074
3075
3076
# File 'lib/HDLRuby/hruby_high.rb', line 3074

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.



3146
3147
3148
# File 'lib/HDLRuby/hruby_high.rb', line 3146

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.



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
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
# File 'lib/HDLRuby/hruby_high.rb', line 3155

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



2992
2993
2994
2995
2996
2997
2998
# File 'lib/HDLRuby/hruby_high.rb', line 2992

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.



3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
# File 'lib/HDLRuby/hruby_high.rb', line 3117

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)


2970
2971
2972
2973
2974
2975
2976
# File 'lib/HDLRuby/hruby_high.rb', line 2970

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.



2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
# File 'lib/HDLRuby/hruby_high.rb', line 2937

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.



2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
# File 'lib/HDLRuby/hruby_high.rb', line 2897

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.



3016
3017
3018
# File 'lib/HDLRuby/hruby_high.rb', line 3016

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



3105
3106
3107
3108
# File 'lib/HDLRuby/hruby_high.rb', line 3105

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.



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

def ls(n)
    return self << n
end

#match_type(typ) ⇒ Object

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



3065
3066
3067
3068
3069
3070
3071
# File 'lib/HDLRuby/hruby_high.rb', line 3065

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.



3208
3209
3210
3211
3212
3213
3214
# File 'lib/HDLRuby/hruby_high.rb', line 3208

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



3077
3078
3079
# File 'lib/HDLRuby/hruby_high.rb', line 3077

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

#output(name) ⇒ Object

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



2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
# File 'lib/HDLRuby/hruby_high.rb', line 2917

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.



3021
3022
3023
# File 'lib/HDLRuby/hruby_high.rb', line 3021

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



3111
3112
3113
3114
# File 'lib/HDLRuby/hruby_high.rb', line 3111

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.



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

def rs(n)
    return self >> n
end

#sdownto(val, &ruby_block) ⇒ Object

HW downto iteration.



2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
# File 'lib/HDLRuby/std/sequencer.rb', line 2168

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.



2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
# File 'lib/HDLRuby/std/sequencer.rb', line 2122

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.



3031
3032
3033
# File 'lib/HDLRuby/hruby_high.rb', line 3031

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

#stimes(&ruby_block) ⇒ Object

HW times iteration.



2156
2157
2158
2159
# File 'lib/HDLRuby/std/sequencer.rb', line 2156

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.



2162
2163
2164
2165
# File 'lib/HDLRuby/std/sequencer.rb', line 2162

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.



3001
3002
3003
# File 'lib/HDLRuby/hruby_high.rb', line 3001

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:



2982
2983
2984
# File 'lib/HDLRuby/hruby_high.rb', line 2982

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.



3011
3012
3013
# File 'lib/HDLRuby/hruby_high.rb', line 3011

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

#to_unsignedObject

Casts to an unsigned bit vector type.



3006
3007
3008
# File 'lib/HDLRuby/hruby_high.rb', line 3006

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:



2964
2965
2966
2967
# File 'lib/HDLRuby/hruby_high.rb', line 2964

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)


2957
2958
2959
# File 'lib/HDLRuby/hruby_high.rb', line 2957

def to_value?
    return false
end

#zext(n) ⇒ Object

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



3026
3027
3028
# File 'lib/HDLRuby/hruby_high.rb', line 3026

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