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.



2407
2408
2409
# File 'lib/HDLRuby/hruby_high.rb', line 2407

def systemT
  @systemT
end

#typeObject

The type of the expression if any.



2409
2410
2411
# File 'lib/HDLRuby/hruby_high.rb', line 2409

def type
  @type
end

Class Method Details

.orig_operator(op) ⇒ Object

Gets the origin method for operation +op+.



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

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.



2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
# File 'lib/HDLRuby/hruby_high.rb', line 2653

def [](rng)
    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+.



2507
2508
2509
2510
2511
2512
2513
# File 'lib/HDLRuby/hruby_high.rb', line 2507

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.



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

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)


2485
2486
2487
2488
2489
2490
2491
# File 'lib/HDLRuby/hruby_high.rb', line 2485

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.



2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
# File 'lib/HDLRuby/hruby_high.rb', line 2452

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.



2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
# File 'lib/HDLRuby/hruby_high.rb', line 2412

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.



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

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

#lr(n) ⇒ Object

Left rotate of +n+ bits.



2611
2612
2613
2614
# File 'lib/HDLRuby/hruby_high.rb', line 2611

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.



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

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.


2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
# File 'lib/HDLRuby/hruby_high.rb', line 2554

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.



2677
2678
2679
2680
2681
2682
2683
# File 'lib/HDLRuby/hruby_high.rb', line 2677

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



2583
2584
2585
# File 'lib/HDLRuby/hruby_high.rb', line 2583

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

#output(name) ⇒ Object

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



2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
# File 'lib/HDLRuby/hruby_high.rb', line 2432

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.



2536
2537
2538
# File 'lib/HDLRuby/hruby_high.rb', line 2536

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

#rr(n) ⇒ Object

Right rotate of +n+ bits.



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

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.



2606
2607
2608
# File 'lib/HDLRuby/hruby_high.rb', line 2606

def rs(n)
    return self >> n
end

#sext(n) ⇒ Object

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



2546
2547
2548
# File 'lib/HDLRuby/hruby_high.rb', line 2546

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

#to_bitObject

Casts to a bit vector type.



2516
2517
2518
# File 'lib/HDLRuby/hruby_high.rb', line 2516

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:



2497
2498
2499
# File 'lib/HDLRuby/hruby_high.rb', line 2497

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.



2521
2522
2523
# File 'lib/HDLRuby/hruby_high.rb', line 2521

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

#to_valueObject

Converts to a new value.

NOTE: to be redefined.

Raises:



2479
2480
2481
2482
# File 'lib/HDLRuby/hruby_high.rb', line 2479

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)


2472
2473
2474
# File 'lib/HDLRuby/hruby_high.rb', line 2472

def to_value?
    return false
end

#zext(n) ⇒ Object

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



2541
2542
2543
# File 'lib/HDLRuby/hruby_high.rb', line 2541

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