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