Hello, I've been thinking about the last discussions about modular types and I have written yet another proposal. Let me know if I have overlooked anything ! Extension of the RANGE mechanism to provide MODULAR and SATURATED behaviour Complexity : low/medium (small code change, a thousand lines ? but checking for unwanted side effects depends on the tool's complexity) Summary There is already some discussion about this functionality at http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/ModularTypes This proposal describes another approach that provides MODULAR behaviour (as well as SATURATED as a bonus) with almost no runtime overhead and reduced code addition to the core VHDL definitions. Unlike other proposals, this does not require external packages and it reuses the mechanisms already in place in simulators/synthesisers for the RANGE contrain on the INTEGER type. This allows a better integration with the parser/compiler/simulator's internals, bringing better efficiency. Dependency and side effects This proposal should not create problems to synthesizers or simulators, since the semantic is rather straight-forward and existing optimisers try to guess the proper behaviour. Now the behaviour is explicit and benefits even non-optimising tools. The required changes do not affect or break existing code bases. However the addition of two keywords might affect code that uses these words as variable/package/signal names. In these cases, the files may be either compiled with earlier revision flags (compatible with VHDL'87 or '93) or rename the variables or signals (when it's not an interface name). This proposal is independent of actual any implementation and size of the INTEGER type, such that the proposals for large integers ( [ArbitraryInteger] and [LongInteger]) do not affect this proposal. Justifications Since modular and saturated arithmetic are widely used, and they use similar mechanics but not simultaneously, it makes sense to group them in a single proposal. * MODULAR behaviour is required, among other things, for wrap-around counters and to perform boolean and shift operations safely and practically (see http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/IntegerOperators ) * SATURATED behaviour is often used in signal processing (sound, image, etc.) and buffer/queue management (My designs use a lot of counters that saturate) Implementation details - Define two new keywords in the language : MODULAR and SATURATED (to be discussed) - Let the parser accept these two keywords instead of RANGE when source code constrains an integer type : subtype a : integer range 123 to 456; -- existing syntax subtype b : integer modular 789 to 101112; -- new syntax subtype c : integer saturated 131415 to 161618; -- new syntax - The 'ascending direction is preferred. The 'descending (downto) has no effect and makes no difference. - The lower and upper bounds are stored alongside the subtype of the variable(s), just as with RANGE. - The subtypes use internal flags that define the behaviour : (names are for explanation purposes and are not normative) * The following are the two already existing behaviours : UNBOUND : unconstrained integer, no range check RANGED : RANGE is defined, trap on under- or overflow on writes * These new behaviours are added : SATURATED : check against the range, modify the value to fit, and write the modified result MODULAR : check against the range, perform mod and write the modified result MODULAR_POW2 : it is a special case of MODULAR where the lower bound is 0 and the higher bound is (2**N)-1. It is required to safely perform boolean operations. - These internal flags may be queried by reading the corresponding attributes (names to be chosen) - Upon writing an integer variable, here is a typical algorithm (not optimised) : if (DESTINATION'behaviour != UNBOUND) and (( VALUE < DESTINATION'LOW) or ( VALUE > DESTINATION'HIGH)) then if (DESTINATION'behaviour = RANGED) then error ("VALUE out of bounds, aborting"); halt_and_scream; end if; if (DESTINATION'behaviour = SATURATED) then if ( VALUE < DESTINATION'LOW) VALUE = DESTINATION'LOW; else -- >'HIGH VALUE = DESTINATION'HIGH; end if; else -- it is MODULAR, but what kind ? if (DESTINATION'behaviour = MODULAR_POW2) then -- fast mod VALUE = VALUE and DESTINATION'HIGH; else -- slow, universal version VALUE = ((VALUE - DESTINATION'LOW) mod ((DESTINATION'HIGH - DESTINATION'LOW)+1)) + DESTINATION'LOW; end if; end if; end if; commit VALUE to DESTINATION; Other considerations * The operators must ensure that they return a valid value in the range of INTEGER, so the MOD operator or the saturation can also provide a valid value. For example, an addition might overflow the integer range, so the result value has no meaning. * These checks are (hopefully) already performed by the RANGE mechanism and can be reused and modified. * For the saturated behaviour, the addition can return a saturated value of INTEGER'HIGH or INTEGER'LOW which will get eventually chopped further during write. * For the MODULAR behaviour, the result can be re-normalised by substracting ModularVariable'High (so the eventual modulo during assignation will actually work) These checks are not necessary for MODULAR_POW2 because the mask works as expected (the modulo is congruent with the data size and returns an accurate value). * Should MODULAR_POW2 get its own keyword & attribute so better/optimised operator overloads can be written ? * Since no consensus exists (at the time of writing) about the desired syntax for modulars (only behaviour has been discussed), this proposal is not compatible with other proposals. This means that no easy temporary, interim or bootstrap replacement (such as a package) exists to provide the standard's compliant functionality until all tools and vendors implement it. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Sat Oct 25 14:58:23 2014
This archive was generated by hypermail 2.1.8 : Sat Oct 25 2014 - 14:59:53 PDT