Re: resolved integers (was RE: [vhdl-200x] Update to proposal for arbitrary integers)

From: David Koontz <diogratia@gmail.com>
Date: Tue Oct 14 2014 - 14:00:40 PDT
On 15 Oct 2014, at 3:04 am, Martin.J Thompson <Martin.J.Thompson@trw.com> wrote:

> Adding out-of-band signalling like this to every integer would add a lot of cost and complexity and execution time penalty to a simulator."
> 
> I'd propose (if I were proposing this extension, which I'm not :) a separate type, so the overhead is not carried by normal ints (much like std_ulogic vs std_logic).

And I have no interest in such a type personally, either.  I found the implementation details and implications of interest.  

There is little overhead today for type integer. The amount of overhead for doing this isn't insignificant and can be modeled today.  The model below uses a record type consisting of an integer and boolean (signifying validity).

And as you might notice from the model there's no way to declare a subtype constraint for a record element in in VHDL prior to -2008.

6.3 Subtype declarations

subtype_declaration ::=
    subtype identifier is subtype_indication ;

subtype_indication ::=
    [ resolution_indication ] type_mark [ constraint ]

constraint ::= 
    range_constraint
    | array_constraint
    | record_constraint

element_constraint ::= 
    array_constraint
  | record_constraint

5.3.3 Record types

record_constraint ::=
    ( record_element_constraint { , record_element_constraint } )

record_element_constraint ::= record_element_simple_name element_constraint

A record constraint may be used to constrain a record type or subtype (see 6.3).

 --

And a record type subtype would work EXCEPT for the pesky problem that an element_constraint doesn't embrace a range_constraint for an integer type element.  (And perhaps should for appropriate numerical types, it'd be interesting to read how this came about, the expansion of subtype to reach into records appears to have been focused on resolution, see 6.3).

There are two classes of overhead compared to integer types.  Multiple element handing and in the case of the model functions calling functions which are generally anathema to performance and could be subsumed by an implementation directly implementing a package body.

And ya, it would be slower in all cases than integers the idea is to optimize that difference in performance.

A simple model:

package invalid_undriven_integer is
    type iv_integer is 
        record 
            int:  integer;
            iv:   boolean;  -- invalid or undriven
        end record;
            
    constant INVALID:   boolean := TRUE;
    constant UNDRIVEN:  boolean := TRUE;
    constant VALID:     boolean := FALSE;
    
    function "+" (l: iv_integer; r: iv_integer) return iv_integer;
    
    function is_iv(inp: iv_integer) return boolean;
    
    function val (int: integer) return iv_integer;
    
    function val (ivint: iv_integer; default: integer := 0) return integer;
    
end package;

package body invalid_undriven_integer is
    
    constant NO_WARNING:    boolean := FALSE;
    
    function "+" (l: iv_integer; r: iv_integer) return iv_integer is
        variable ret_val: iv_integer := (int => 0, iv => VALID);
    begin
        if l.iv /= INVALID and r.iv /= INVALID then
            ret_val.int := l.int + r.int;
        else
            ret_val.iv := INVALID;
        end if;
        return ret_val;   
    end function;
    
    function is_iv (inp: iv_integer) return boolean is
        variable isiv: boolean := FALSE;
    begin
        if inp.iv = INVALID then
            isiv := INVALID;
        end if;
        return isiv;
    end function;
    
    function val (int: integer) return iv_integer is
        variable ret_val: iv_integer;
    begin
        ret_val.int := int;
        return ret_val;
    end function;

    function val (ivint: iv_integer; default: integer := 0) return integer is
        variable ret_val: integer := default;
    begin
        if ivint.iv /= INVALID then
            ret_val := ivint.int;
        else
            if not NO_WARNING then
                report "val convert INVALID iv_integer to default " &
                    integer'IMAGE(ret_val);
            end if;
        end if;
        return ret_val;
    end function;

end package body invalid_undriven_integer;

use work.invalid_undriven_integer.all;

entity iv_integer_demo is
end entity;

architecture foo of iv_integer_demo is
    signal A: iv_integer := VAL(21);
    signal B: iv_integer := val(20);
    signal accum: iv_integer;
    
begin
    
TEST:
    process
    begin
        wait for 10 ns;
        accum <= A + B;
        wait for 10 ns;
        accum <= accum + val(1);
        B.iv <= INVALID;
        wait for 10 ns;
        accum <= accum + B;
        wait for 10 ns;
        accum <= val(40);
        wait for 10 ns;
        accum <= accum + val(2);
        wait for 10 ns;
        wait;
    end process;

MONITOR:
    process 
    begin
        wait on accum;
        wait for 1 ns;
        if accum.iv = VALID then 
            report "accum = " & integer'IMAGE(accum.int);
        else
            report "accum is INVALID";
        end if;
    end process;
MONITOR1:
    process (B)
    begin
        assert not is_iv(B)
            report "B is not valid";
    end process;
end architecture;

ghdl -a iv_integer.vhdl
ghdl -e iv_integer_demo
ghdl -r iv_integer_demo
iv_integer.vhdl:105:13:@11ns:(report note): accum = 41
iv_integer.vhdl:113:9:@20ns:(assertion error): B is not valid
iv_integer.vhdl:105:13:@21ns:(report note): accum = 42
iv_integer.vhdl:107:13:@31ns:(report note): accum is INVALID
iv_integer.vhdl:105:13:@41ns:(report note): accum = 40
iv_integer.vhdl:105:13:@51ns:(report note): accum = 42

 ---

Dealing with multiple drivers could be as simple as marking the resolved value invalid for more than one active driver in an added resolution function.  (Resolution would be faster than some other resolved types).




-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Tue Oct 14 14:01:31 2014

This archive was generated by hypermail 2.1.8 : Tue Oct 14 2014 - 14:02:13 PDT