This file contains information on changes for the numeric_std and numeric_bit packages. ***************************************************************** -- Modification history(numeric_std): -- -- REA: July 24 1994 Initial version from numeric_bit.vhd Rev 1.1 -- REA: August 9 1994 improved TO_01 message, fixed TO_INTEGER bug -- REA: August 19 1994 -- asserts made similar -- TO_01: time zero excepted in assert -- TO_01: alias used to force normalization -- REA: Sept. 6 1994 -- fixed function Id A.2 called from abs loop range -- fixed TO_01 assert, removed "now" function calls -- NO_WARNING constant in function body -- REA: Oct. 7 1994 R1.4 -- Fixed RESIZE function R.1, modified description -- Fixed overflow in TO_INTEGER(SIGNED) D.2 -- Fixed warning in TO_SIGNED(int,SIZE) D.4 -- REA: Oct. 27 1994 R1.5 -- Added Changes from CHK: -- made vector/number comparisons work even when the number -- can't be converted to a vector of the same SIZE, simplify -- divMod to use UNSIGNED instead of STD_LOGIC_VECTOR, simplify -- SIGNED_less and SIGNED_LESS_OR_EQUAL. -- Also changed return for metavalue to "XXX... for operators -- and made sure the error handling was uniform. -- Added STD_MATCH functions to this package. -- REA: Nov. 4 1994 R1.6 -- Added logical operators -- Fixed A.2 bug -- Added conversion functions -- Changed NO_WARNINGs constant to FALSE -- REA: Nov. 23 1994 R1.7 -- changes as noted by Chris Kingsley, DASC Nov meeting -- REA: Dec. 14 1994 R1.8 -- changes to fix bugs, per Kingsley, also adding -- To-01 visibility, std_match functions. Vote is -- not finished on these yet, taking best guess... -- -- REA: Jan 12 1995 R1.9 -- Formatted VHDL. -- REA: Jan 16 1995 R2.0 -- Format changes per James V. -- ---------------------------------------------------------------------------- -- Modification history(numeric_bit): -- -- JB: Jun 20 '94: Comment header and comments added to function declarations. -- REA: July 24 '94: -- Id: x.y placed on function bodies to replace older -- signatures. Function bodies reordered in file. -- Also fixed ABS function a.1. -- REA: August 19 1994 -- asserts made similar -- REA: Sept. 6 1994 -- fixed function Id A.2 called from abs loop range -- NO_WARNING constant in function body -- REA: Oct. 7 1994 R1.4 -- Fixed RESIZE function R.1, modified description -- Fixed overflow in TO_INTEGER(SIGNED) D.2 -- Fixed warning in TO_SIGNED(int,size) D.4 -- REA/CHK: Oct. 27 1994 R1.5 -- Added Changes from CHK (Kingsley): -- made vector/number comparisons work even when the number -- can't be converted to a vector of the same size, simplify -- divMod to use UNSIGNED instead of std_logic_vector, simplify -- SIGNED_less and SIGNED_less_or_equal. -- REA: Nov. 4 1994 R1.6 -- Fixed A.2 bug -- Added conversion functions -- Changed NO_WARNINGs constant to FALSE -- REA: Nov. 23 1994 R1.7 -- changes as noted by Chris Kingsley, DASC Nov meeting -- -- REA: Dec. 14 1994 R1.8 -- changes to fix bugs, per Kingsley, also adding -- To-01 visibility, std_match functions. Vote is -- not finished on these yet, taking best guess... -- -- REA: Jan 12 1995 R1.9 -- Formatted VHDL. -- REA: Jan 16 1995 R2.0 -- Format changes per James V. -- ---------------------------------------------------------------------------- Here are the changes per our DASC meeting and notes from Kingsley: Here is a list of minor changes and bugs in the packages. The ones that may be controversial I will list in the minutes, but these are small enough that I didn't want to clutter it up: 1. Remove the "limitations: none" from the packages. 2. In the descriptions of the functions, refer to Signed/Unsigned arguments as "vectors" (instead of "numbers"), and Integer/Natural arguments as "numbers". 3. In function headers, remove all "constant" declarations on the args. 4. In numeric_bit remove the "-" function for bit_vector, and in numeric_std remove the "-" for std_logic_vector. (They are left-overs from my divMod func). I'll send you a simplified form of divMod for the two packages; it's about half as long. 5. A.9 and A.10 (both packages) -- should be just not(resize(R,size)) (no conversions, and the resized result must be the arg for not, not the other way around) 6. A.16 numeric_bit doesn't compile. I'll send you a new body. 7. A.22 numeric_bit shouldn't negate L when L(L'Left) is not '1', negating fquot should use a single bit 0 constant. A.22 numeric_std sets xnum and xdenom incorrectly. I'll send new bodies. 8. I will send new bodies for Div/Mod/Rem for numbers with vectors that give the correct result when possible, and warn about overflow only when it must. A.23, A.24, A.25, A.26, A.29, A.30, A.31, A.32, A.35, A.36, A.37, A.38. 9. A.28 (both packages) uses uninitialized local variables, and should negate fremain with a one-bit zero. I'll send a corrected body. 10. A.34 (both packages) fails if L is 1 bit, should use a 1-bit 0 to negate fremain. 11. (from the IBM review) c.2, c.8, c.14, c.20, c.32: change the to_signed to just resize. 12. d.1 (both) remove the range test, and simplify the conversion. I'll send a new body. **13. L.nn (both) operations should be ordered by operation first, then arg type **next. ******* 13 was not done. It is not clear this is worth it. *************** 14. Remove the internal to_Signed(Unsigned) and to_signed(signed). 15. To_01 numeric_std has incorrect text for assertions. Suppress what it says the result will be? 16. (from meeting) C.31-C.36 "/=" must give True when there are metalogical values. Chris *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** NEW ISSUES, REV 1.8 DEC 14 1994 *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** Subject: issue number: 0022 to_01 Content-Length: 85 !summary: Should the function TO_01 be made visible to the user? ########### Vote looks like yes, so the change was made ############# *************************************************************************** Hi Rob, I just noticed that the description of S.3 says: -- Id: S.3 function shift_LEFT ( ARG : SIGNED; count : NATURAL) return SIGNED; -- Result subtype: SIGNED (ARG'LENGTH-1 downto 0) -- Result: Performs a shift-LEFT on a SIGNED vector COUNT times. -- All bits of ARG, except ARG'LEFT, are shifted LEFT COUNT times. -- The vacated positions are filled with Bit '0'. -- The COUNT LEFTmost bits, except ARG'LEFT, are lost. The behavior, though, does a logical shift: -- Id: S.3 function shift_LEFT ( ARG : SIGNED; count : NATURAL) return SIGNED is begin if (ARG'length<1) then return nas; end if; return SIGNED(xsll(bit_vector(ARG),count)); end; I think we discussed this once and determined that we wanted the behavior of the function body, and that the description is wrong. Can you fix it in 1.8? Chris #################### DONE ####################################### *************************************************************************** Here's another couple: -- Id: R.2 function RESIZE ( ARG : UNSIGNED; new_size : NATURAL) return UNSIGNED; -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0) -- Result: Resizes the UNSIGNED vector ARG to the specified size. -- To create a larger vector, the new [LEFTmost] bit positions -- are filled with '0'. When truncating, the LEFTmost bits -- are dropped. >>> The result subtype should be UNSIGNED(new_size-1 downto 0) -- Id: D.5 function TO_UNSIGNED ( ARG : BIT_VECTOR) return UNSIGNED; -- Result subtype: UNSIGNED, same range as input ARG -- Result: Converts BIT_VECTOR to UNSIGNED. -- Id: D.6 function TO_SIGNED ( ARG : BIT_VECTOR) return SIGNED; -- Result subtype: SIGNED, same range as input ARG -- Result: Converts BIT_VECTOR to SIGNED. -- Id: D.7 function TO_BITVECTOR ( ARG : UNSIGNED) return BIT_VECTOR; -- Result subtype: BIT_VECTOR, same range as input ARG -- Result: Converts UNSIGNED to BIT_VECTOR. -- Id: D.8 function TO_BITVECTOR ( ARG : SIGNED) return BIT_VECTOR; -- Result subtype: BIT_VECTOR, same range as input ARG -- Result: Converts SIGNED to BIT_VECTOR. >>> Can we make the result subtypes be something like: UNSIGNED(Arg'Range)? >>> All the rest of the result subtypes are written with legal vhdl syntax, >>> and I find it useful. Chris #################### DONE ####################################### *************************************************************************** It's not a big deal, but it's more convenient to me if all the functions have it. I could fix my program, so if you want to remove the result subtype for the boolean functions, that's okay too. Chris ################### ?? Clarification requested ?? ################### *************************************************************************** The line: if ((xnum(xnum'left)='X') or (xdenom(xnum'left)='X')) then ^^^^ should, of course, be: if ((xnum(xnum'left)='X') or (xdenom(xdenom'left)='X')) then ^^^^^^ (This is line 1498 of the package as I have it.) Numeric_bit doesn't have this bug. Chris #################### DONE ####################################### *************************************************************************** Hi Rob, Version 1.7 still has the buggy version of signed multiply. It gives incorrect results if L is negative. For example, signed'("1101")*"0001" gives "11111110", when it should give "11111101". Here is a correct version: -- Id: A.16 function "*" ( L,R: SIGNED) return SIGNED is constant L_left:INTEGER:= L'length-1; constant R_left:INTEGER:= R'length-1; variable xl : SIGNED(L_left downto 0); variable xr : SIGNED(R_left downto 0); variable RESULT: SIGNED((L_Left+R_Left+1) downto 0) :=(others=>'0'); variable adval : SIGNED((L_Left+R_Left+1) downto 0); begin if ((L_Left<0) or (R_Left<0)) then return NAS; end if; xl := TO_01(L,'X'); xr := TO_01(R,'X'); if ((xl(L_Left)='X') or (xr(R_Left)='X')) then RESULT:= (others=>'X'); return RESULT; end if; adval := RESIZE(xr,RESULT'length); for i in 0 to L_left-1 loop if xl(i)='1' then RESULT:= RESULT + adval; end if; adval := shift_left(adval,1); end loop; if xl(L_left)='1' then RESULT:= RESULT - adval; end if; return RESULT; end; Chris Kingsley #################### DONE ####################################### *************************************************************************** Hi Rob, Next bug .... The last test in A.34 currently is: elsif l(l'left)='1' then it should be: elsif l(l'left)='1' and fremain/="0" then Without this change, to_Signed(-60,8) mod "0100" gives 4. It should, of course, give 0. This fix is needed in both packages. While you are at it, can you put in my simpler version of divMod? It's about half the size of the present one (which I also wrote....) It should be easier for people to understand and it should run faster. -- this internal procedure computes UNSIGNED division -- giving the quotient and remainder. procedure divMod (num, XDENOM: UNSIGNED; xquot, xremain: out UNSIGNED) is variable TEMP: UNSIGNED(num'length downto 0); variable quot: UNSIGNED(MAX(num'length,XDENOM'length)-1 downto 0); alias DENOM : UNSIGNED (XDENOM'length-1 downto 0) is XDENOM; variable TOPBIT: integer; begin TEMP:="0"# quot:= (others =>'0'); TOPBIT:=-1; for j in DENOM'range loop if DENOM(j)='1' then TOPBIT:=j; exit; end if; end loop; assert TOPBIT>=0 report "DIV,MOD,or REM by zero" severity error; for j in num'length-(TOPBIT+1) downto 0 loop if TEMP(TOPBIT+j+1 downto j) >= "0"&DENOM(TOPBIT downto 0) then TEMP(TOPBIT+j+1 downto j) := (TEMP(TOPBIT+j+1 downto j)) -("0"&DENOM(TOPBIT downto 0)); quot(j):='1'; end if; assert TEMP(TOPBIT+j+1)='0' report "internal error in the division algorithm" severity error; end loop; xquot:=quot(num'length-1 downto 0); xremain:=TEMP(num'length-1 downto 0); end; Chris Kingsley #################### DONE ####################################### *************************************************************************** --============================================================================ -- Match Functions --============================================================================ -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN; -- Result: terms compared per STD_LOGIC_1164 intent -- Id: M.2 function STD_MATCH (L, R: UNSIGNED) return BOOLEAN; function STD_MATCH (L, R: SIGNED) return BOOLEAN; function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN; function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN; -- Result: termwise comparison per STD_LOGIC_1164 intent --============================================================================= -- support constants for STD_MATCH: TYPE boolean_table is array(std_ulogic, std_ulogic ) of boolean; CONSTANT match_table : boolean_table := ( ----------------------------------------------------------------------------- -- | U X 0 1 Z W L H - | | ----------------------------------------------------------------------------- ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ), -- | U | ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ), -- | X | ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE ), -- | 0 | ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE ), -- | 1 | ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ), -- | Z | ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ), -- | W | ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE ), -- | L | ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE ), -- | H | ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ) -- | - | ); -- Id: M.1 function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN is variable VALUE : STD_ULOGIC; begin return MATCH_TABLE(L, R); end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: UNSIGNED) return BOOLEAN is alias LV: UNSIGNED ( 1 to L'LENGTH ) is L; alias RV: UNSIGNED ( 1 to R'LENGTH ) is R; begin -- Check that both input vectors are the same length. if LV'LENGTH /= RV'LENGTH then assert NO_WARNING report "STD_MATCH input arguments are not of equal length" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not ( MATCH_TABLE ( LV(I), RV(I) ) ) then return FALSE; end if; end loop; return TRUE; end if; end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: SIGNED) return BOOLEAN is alias LV: SIGNED ( 1 to L'LENGTH ) is L; alias RV: SIGNED ( 1 to R'LENGTH ) is R; begin -- Check that both input vectors are the same length. if LV'LENGTH /= RV'LENGTH then assert NO_WARNING report "STD_MATCH input arguments are not of equal length" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not ( MATCH_TABLE ( LV(I), RV(I) ) ) then return FALSE; end if; end loop; return TRUE; end if; end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN is alias LV: STD_LOGIC_VECTOR ( 1 to L'LENGTH ) is L; alias RV: STD_LOGIC_VECTOR ( 1 to R'LENGTH ) is R; begin -- Check that both input vectors are the same length. if LV'LENGTH /= RV'LENGTH then assert NO_WARNING report "STD_MATCH input arguments are not of equal length" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not ( MATCH_TABLE ( LV(I), RV(I) ) ) then return FALSE; end if; end loop; return TRUE; end if; end STD_MATCH; -- Id: M.2 function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN is alias LV: STD_ULOGIC_VECTOR ( 1 to L'LENGTH ) is L; alias RV: STD_ULOGIC_VECTOR ( 1 to R'LENGTH ) is R; begin -- Check that both input vectors are the same length. if LV'LENGTH /= RV'LENGTH then assert NO_WARNING report "STD_MATCH input arguments are not of equal length" severity warning; return FALSE; else for I in LV'LOW to LV'HIGH loop if not ( MATCH_TABLE ( LV(I), RV(I) ) ) then return FALSE; end if; end loop; return TRUE; end if; end STD_MATCH; --============================================================================= end numeric_std; #################### DONE, except ################ ################### Pending vote on issue ########################### ***************************************************************************