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.



2527
2528
2529
# File 'lib/HDLRuby/hruby_high.rb', line 2527

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2529
2530
2531
# File 'lib/HDLRuby/hruby_high.rb', line 2529

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



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

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.



2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
# File 'lib/HDLRuby/hruby_high.rb', line 2773

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



2627
2628
2629
2630
2631
2632
2633
# File 'lib/HDLRuby/hruby_high.rb', line 2627

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.



2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
# File 'lib/HDLRuby/hruby_high.rb', line 2743

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)


2605
2606
2607
2608
2609
2610
2611
# File 'lib/HDLRuby/hruby_high.rb', line 2605

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.



2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
# File 'lib/HDLRuby/hruby_high.rb', line 2572

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.



2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
# File 'lib/HDLRuby/hruby_high.rb', line 2532

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.



2651
2652
2653
# File 'lib/HDLRuby/hruby_high.rb', line 2651

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



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

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.



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

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.


2674
2675
2676
2677
2678
2679
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 2674

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.



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

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



2703
2704
2705
# File 'lib/HDLRuby/hruby_high.rb', line 2703

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

#output(name) ⇒ Object

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



2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
# File 'lib/HDLRuby/hruby_high.rb', line 2552

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.



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

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



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

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.



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

def rs(n)
    return self >> n
end

#sext(n) ⇒ Object

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



2666
2667
2668
# File 'lib/HDLRuby/hruby_high.rb', line 2666

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

#to_bitObject

Casts to a bit vector type.



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

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:



2617
2618
2619
# File 'lib/HDLRuby/hruby_high.rb', line 2617

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.



2641
2642
2643
# File 'lib/HDLRuby/hruby_high.rb', line 2641

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

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2599
2600
2601
2602
# File 'lib/HDLRuby/hruby_high.rb', line 2599

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)


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

def to_value?
    return false
end

#zext(n) ⇒ Object

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



2661
2662
2663
# File 'lib/HDLRuby/hruby_high.rb', line 2661

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