📄 numeric_std-body.vhdl
字号:
begin return L + TO_UNSIGNED(R, L'LENGTH); end "+"; -- Id: A.6 function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED(L, R'LENGTH) + R; end "+"; -- Id: A.7 function "+" (L: SIGNED; R: INTEGER) return SIGNED is begin return L + TO_SIGNED(R, L'LENGTH); end "+"; -- Id: A.8 function "+" (L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED(L, R'LENGTH) + R; end "+"; --============================================================================ -- Id: A.9 function "-" (L, R: UNSIGNED) return UNSIGNED is constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH); variable L01 : UNSIGNED(SIZE-1 downto 0); variable R01 : UNSIGNED(SIZE-1 downto 0); begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; end if; L01 := TO_01(RESIZE(L, SIZE), 'X'); if (L01(L01'LEFT)='X') then return L01; end if; R01 := TO_01(RESIZE(R, SIZE), 'X'); if (R01(R01'LEFT)='X') then return R01; end if; return ADD_UNSIGNED(L01, not(R01), '1'); end "-"; -- Id: A.10 function "-" (L, R: SIGNED) return SIGNED is constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH); variable L01 : SIGNED(SIZE-1 downto 0); variable R01 : SIGNED(SIZE-1 downto 0); begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; end if; L01 := TO_01(RESIZE(L, SIZE), 'X'); if (L01(L01'LEFT)='X') then return L01; end if; R01 := TO_01(RESIZE(R, SIZE), 'X'); if (R01(R01'LEFT)='X') then return R01; end if; return ADD_SIGNED(L01, not(R01), '1'); end "-"; -- Id: A.11 function "-" (L: UNSIGNED; R: NATURAL) return UNSIGNED is begin return L - TO_UNSIGNED(R, L'LENGTH); end "-"; -- Id: A.12 function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED(L, R'LENGTH) - R; end "-"; -- Id: A.13 function "-" (L: SIGNED; R: INTEGER) return SIGNED is begin return L - TO_SIGNED(R, L'LENGTH); end "-"; -- Id: A.14 function "-" (L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED(L, R'LENGTH) - R; end "-"; --============================================================================ -- Id: A.15 function "*" (L, R: UNSIGNED) return UNSIGNED is constant L_LEFT: INTEGER := L'LENGTH-1; constant R_LEFT: INTEGER := R'LENGTH-1; alias XXL: UNSIGNED(L_LEFT downto 0) is L; alias XXR: UNSIGNED(R_LEFT downto 0) is R; variable XL: UNSIGNED(L_LEFT downto 0); variable XR: UNSIGNED(R_LEFT downto 0); variable RESULT: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0) := (others => '0'); variable ADVAL: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0); begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; end if; XL := TO_01(XXL, 'X'); XR := TO_01(XXR, 'X'); if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then RESULT := (others => 'X'); return RESULT; end if; ADVAL := RESIZE(XR, RESULT'LENGTH); for I in 0 to L_LEFT loop if XL(I)='1' then RESULT := RESULT + ADVAL; end if; ADVAL := SHIFT_LEFT(ADVAL, 1); end loop; return RESULT; end "*"; -- 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 "*"; -- Id: A.17 function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED is begin return L * TO_UNSIGNED(R, L'LENGTH); end "*"; -- Id: A.18 function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED is begin return TO_UNSIGNED(L, R'LENGTH) * R; end "*"; -- Id: A.19 function "*" (L: SIGNED; R: INTEGER) return SIGNED is begin return L * TO_SIGNED(R, L'LENGTH); end "*"; -- Id: A.20 function "*" (L: INTEGER; R: SIGNED) return SIGNED is begin return TO_SIGNED(L, R'LENGTH) * R; end "*"; --============================================================================ -- Id: A.21 function "/" (L, R: UNSIGNED) return UNSIGNED is constant L_LEFT: INTEGER := L'LENGTH-1; constant R_LEFT: INTEGER := R'LENGTH-1; alias XXL: UNSIGNED(L_LEFT downto 0) is L; alias XXR: UNSIGNED(R_LEFT downto 0) is R; variable XL: UNSIGNED(L_LEFT downto 0); variable XR: UNSIGNED(R_LEFT downto 0); variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0); variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; end if; XL := TO_01(XXL, 'X'); XR := TO_01(XXR, 'X'); if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then FQUOT := (others => 'X'); return FQUOT; end if; DIVMOD(XL, XR, FQUOT, FREMAIN); return FQUOT; end "/"; -- Id: A.22 function "/" (L, R: SIGNED) return SIGNED is constant L_LEFT: INTEGER := L'LENGTH-1; constant R_LEFT: INTEGER := R'LENGTH-1; alias XXL: SIGNED(L_LEFT downto 0) is L; alias XXR: SIGNED(R_LEFT downto 0) is R; variable XL: SIGNED(L_LEFT downto 0); variable XR: SIGNED(R_LEFT downto 0); variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0); variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); variable XNUM: UNSIGNED(L'LENGTH-1 downto 0); variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0); variable QNEG: BOOLEAN := FALSE; begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; end if; XL := TO_01(XXL, 'X'); XR := TO_01(XXR, 'X'); if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then FQUOT := (others => 'X'); return SIGNED(FQUOT); end if; if XL(XL'LEFT)='1' then XNUM := UNSIGNED(-XL); QNEG := TRUE; else XNUM := UNSIGNED(XL); end if; if XR(XR'LEFT)='1' then XDENOM := UNSIGNED(-XR); QNEG := not QNEG; else XDENOM := UNSIGNED(XR); end if; DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); if QNEG then FQUOT := "0"-FQUOT; end if; return SIGNED(FQUOT); end "/"; -- Id: A.23 function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED is constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R)); variable XR, QUOT: UNSIGNED(R_LENGTH-1 downto 0); begin if (L'LENGTH < 1) then return NAU; end if; if (R_LENGTH > L'LENGTH) then QUOT := (others => '0'); return RESIZE(QUOT, L'LENGTH); end if; XR := TO_UNSIGNED(R, R_LENGTH); QUOT := RESIZE((L / XR), QUOT'LENGTH); return RESIZE(QUOT, L'LENGTH); end "/"; -- Id: A.24 function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED is constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH); variable XL, QUOT: UNSIGNED(L_LENGTH-1 downto 0); begin if (R'LENGTH < 1) then return NAU; end if; XL := TO_UNSIGNED(L, L_LENGTH); QUOT := RESIZE((XL / R), QUOT'LENGTH); if L_LENGTH > R'LENGTH and QUOT(0)/='X' and QUOT(L_LENGTH-1 downto R'LENGTH) /= (L_LENGTH-1 downto R'LENGTH => '0') then assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" severity WARNING; end if; return RESIZE(QUOT, R'LENGTH); end "/"; -- Id: A.25 function "/" (L: SIGNED; R: INTEGER) return SIGNED is constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R)); variable XR, QUOT: SIGNED(R_LENGTH-1 downto 0); begin if (L'LENGTH < 1) then return NAS; end if; if (R_LENGTH > L'LENGTH) then QUOT := (others => '0'); return RESIZE(QUOT, L'LENGTH); end if; XR := TO_SIGNED(R, R_LENGTH); QUOT := RESIZE((L / XR), QUOT'LENGTH); return RESIZE(QUOT, L'LENGTH); end "/"; -- Id: A.26 function "/" (L: INTEGER; R: SIGNED) return SIGNED is constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH); variable XL, QUOT: SIGNED(L_LENGTH-1 downto 0); begin if (R'LENGTH < 1) then return NAS; end if; XL := TO_SIGNED(L, L_LENGTH); QUOT := RESIZE((XL / R), QUOT'LENGTH); if L_LENGTH > R'LENGTH and QUOT(0)/='X' and QUOT(L_LENGTH-1 downto R'LENGTH) /= (L_LENGTH-1 downto R'LENGTH => QUOT(R'LENGTH-1)) then assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated" severity WARNING; end if; return RESIZE(QUOT, R'LENGTH); end "/"; --============================================================================ -- Id: A.27 function "rem" (L, R: UNSIGNED) return UNSIGNED is constant L_LEFT: INTEGER := L'LENGTH-1; constant R_LEFT: INTEGER := R'LENGTH-1; alias XXL: UNSIGNED(L_LEFT downto 0) is L; alias XXR: UNSIGNED(R_LEFT downto 0) is R; variable XL: UNSIGNED(L_LEFT downto 0); variable XR: UNSIGNED(R_LEFT downto 0); variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0); variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; end if; XL := TO_01(XXL, 'X'); XR := TO_01(XXR, 'X'); if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then FREMAIN := (others => 'X'); return FREMAIN; end if; DIVMOD(XL, XR, FQUOT, FREMAIN); return FREMAIN; end "rem"; -- Id: A.28 function "rem" (L, R: SIGNED) return SIGNED is constant L_LEFT: INTEGER := L'LENGTH-1; constant R_LEFT: INTEGER := R'LENGTH-1; alias XXL: SIGNED(L_LEFT downto 0) is L; alias XXR: SIGNED(R_LEFT downto 0) is R; variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0); variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0); variable XNUM: UNSIGNED(L'LENGTH-1 downto 0); variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0); variable RNEG: BOOLEAN := FALSE; begin if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS; end if; XNUM := UNSIGNED(TO_01(XXL, 'X')); XDENOM := UNSIGNED(TO_01(XXR, 'X')); if ((XNUM(XNUM'LEFT)='X') or (XDENOM(XDENOM'LEFT)='X')) then FREMAIN := (others => 'X'); return SIGNED(FREMAIN); end if; if XNUM(XNUM'LEFT)='1' then XNUM := UNSIGNED(-SIGNED(XNUM)); RNEG := TRUE; else XNUM := UNSIGNED(XNUM); end if; if XDENOM(XDENOM'LEFT)='1' then XDENOM := UNSIGNED(-SIGNED(XDENOM)); else XDENOM := UNSIGNED(XDENOM); end if; DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN); if RNEG then FREMAIN := "0"-FREMAIN; end if; return SIGNED(FREMAIN); end "rem"; -- Id: A.29 function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED is constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R)); variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0); begin if (L'LENGTH < 1) then return NAU; end if; XR := TO_UNSIGNED(R, R_LENGTH); XREM := L rem XR; if R_LENGTH > L'LENGTH and XREM(0)/='X' and XREM(R_LENGTH-1 downto L'LENGTH) /= (R_LENGTH-1 downto L'LENGTH => '0') then assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" severity WARNING; end if; return RESIZE(XREM, L'LENGTH); end "rem"; -- Id: A.30 function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED is constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH); variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0); begin XL := TO_UNSIGNED(L, L_LENGTH); XREM := XL rem R; if L_LENGTH > R'LENGTH and XREM(0)/='X' and XREM(L_LENGTH-1 downto R'LENGTH) /= (L_LENGTH-1 downto R'LENGTH => '0') then assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated" severity WARNING; end if; return RESIZE(XREM, R'LENGTH); end "rem";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -