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.



2441
2442
2443
# File 'lib/HDLRuby/hruby_high.rb', line 2441

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2443
2444
2445
# File 'lib/HDLRuby/hruby_high.rb', line 2443

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



2614
2615
2616
# File 'lib/HDLRuby/hruby_high.rb', line 2614

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.



2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
# File 'lib/HDLRuby/hruby_high.rb', line 2687

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



2541
2542
2543
2544
2545
2546
2547
# File 'lib/HDLRuby/hruby_high.rb', line 2541

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.



2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
# File 'lib/HDLRuby/hruby_high.rb', line 2657

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)


2519
2520
2521
2522
2523
2524
2525
# File 'lib/HDLRuby/hruby_high.rb', line 2519

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.



2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
# File 'lib/HDLRuby/hruby_high.rb', line 2486

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.



2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
# File 'lib/HDLRuby/hruby_high.rb', line 2446

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.



2565
2566
2567
# File 'lib/HDLRuby/hruby_high.rb', line 2565

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



2645
2646
2647
2648
# File 'lib/HDLRuby/hruby_high.rb', line 2645

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.



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

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.


2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
# File 'lib/HDLRuby/hruby_high.rb', line 2588

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.



2725
2726
2727
2728
2729
2730
2731
# File 'lib/HDLRuby/hruby_high.rb', line 2725

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



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

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

#output(name) ⇒ Object

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



2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
# File 'lib/HDLRuby/hruby_high.rb', line 2466

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.



2570
2571
2572
# File 'lib/HDLRuby/hruby_high.rb', line 2570

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



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

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.



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

def rs(n)
    return self >> n
end

#sext(n) ⇒ Object

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



2580
2581
2582
# File 'lib/HDLRuby/hruby_high.rb', line 2580

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

#to_bitObject

Casts to a bit vector type.



2550
2551
2552
# File 'lib/HDLRuby/hruby_high.rb', line 2550

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:



2531
2532
2533
# File 'lib/HDLRuby/hruby_high.rb', line 2531

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.



2555
2556
2557
# File 'lib/HDLRuby/hruby_high.rb', line 2555

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

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2513
2514
2515
2516
# File 'lib/HDLRuby/hruby_high.rb', line 2513

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)


2506
2507
2508
# File 'lib/HDLRuby/hruby_high.rb', line 2506

def to_value?
    return false
end

#zext(n) ⇒ Object

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



2575
2576
2577
# File 'lib/HDLRuby/hruby_high.rb', line 2575

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