std_logic_arith_body.vhdl
来自「vhdl集成电路设计软件.需要用gcc-4.0.2版本编译.」· VHDL 代码 · 共 1,959 行 · 第 1/5 页
VHDL
1,959 行
END IF; RETURN vector; END ; -- sign/zero extend functions -- FUNCTION zero_extend ( arg1 : STD_ULOGIC_VECTOR; size : NATURAL ) RETURN STD_ULOGIC_VECTOR IS VARIABLE answer : STD_ULOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN ASSERT arg1'length <= size REPORT "Vector is already larger then size." SEVERITY WARNING ; answer := (OTHERS => '0') ; answer(arg1'length-1 DOWNTO 0) := arg1; RETURN(answer) ; END ; FUNCTION zero_extend ( arg1 : STD_LOGIC_VECTOR; size : NATURAL ) RETURN STD_LOGIC_VECTOR IS VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN ASSERT arg1'length <= size REPORT "Vector is already larger then size." SEVERITY WARNING ; answer := (OTHERS => '0') ; answer(arg1'length-1 DOWNTO 0) := arg1; RETURN(answer) ; END ; FUNCTION zero_extend ( arg1 : STD_LOGIC; size : NATURAL ) RETURN STD_LOGIC_VECTOR IS VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN answer := (OTHERS => '0') ; answer(0) := arg1; RETURN(answer) ; END ; FUNCTION zero_extend ( arg1 : UNSIGNED; size : NATURAL ) RETURN UNSIGNED IS VARIABLE answer : UNSIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN ASSERT arg1'length <= size REPORT "Vector is already larger then size." SEVERITY WARNING ; answer := (OTHERS => '0') ; answer(arg1'length - 1 DOWNTO 0) := arg1; RETURN(answer) ; END ; FUNCTION sign_extend ( arg1 : SIGNED; size : NATURAL ) RETURN SIGNED IS VARIABLE answer : SIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN ASSERT arg1'length <= size REPORT "Vector is already larger then size." SEVERITY WARNING ; answer := (OTHERS => arg1(arg1'left)) ; answer(arg1'length - 1 DOWNTO 0) := arg1; RETURN(answer) ; END ; -- Some useful generic functions --//// Zero Extend //// -- -- Function zxt -- FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i); VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length); BEGIN qt := q; IF i < q'length THEN qs := qt( (q'length-i+1) TO qt'right); ELSIF i > q'length THEN qs := (OTHERS=>'0'); qs := qs(1 TO (i-q'length)) & qt; ELSE qs := qt; END IF; RETURN qs; END; --//// Zero Extend //// -- -- Function zxt -- FUNCTION zxt( q : STD_LOGIC_VECTOR; i : INTEGER ) RETURN STD_LOGIC_VECTOR IS VARIABLE qs : STD_LOGIC_VECTOR (1 TO i); VARIABLE qt : STD_LOGIC_VECTOR (1 TO q'length); BEGIN qt := q; IF i < q'length THEN qs := qt( (q'length-i+1) TO qt'right); ELSIF i > q'length THEN qs := (OTHERS=>'0'); qs := qs(1 TO (i-q'length)) & qt; ELSE qs := qt; END IF; RETURN qs; END; --//// Zero Extend //// -- -- Function zxt -- FUNCTION zxt( q : UNSIGNED; i : INTEGER ) RETURN UNSIGNED IS VARIABLE qs : UNSIGNED (1 TO i); VARIABLE qt : UNSIGNED (1 TO q'length); BEGIN qt := q; IF i < q'length THEN qs := qt( (q'length-i+1) TO qt'right); ELSIF i > q'length THEN qs := (OTHERS=>'0'); qs := qs(1 TO (i-q'length)) & qt; ELSE qs := qt; END IF; RETURN qs; END; ---------------------------------------- Synthesizable addition Functions ---------------------------------------- FUNCTION "+" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC IS -- truth table for "xor" function CONSTANT xor_table : stdlogic_table := ( -- ---------------------------------------------------- -- | U X 0 1 Z W L H D | | -- ---------------------------------------------------- ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D | ); BEGIN RETURN xor_table( arg1, arg2 ); END "+"; function maximum (arg1, arg2: integer) return integer is begin if arg1 > arg2 then return arg1; else return arg2; end if; end; FUNCTION "+" (arg1, arg2 :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE carry : STD_ULOGIC := '0'; VARIABLE a,b,s1 : STD_ULOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := rt(i); s1 := a + b; res(i) := s1 + carry; carry := (a AND b) OR (s1 AND carry); END LOOP; RETURN res; END; FUNCTION "+" (arg1, arg2 :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE res : STD_LOGIC_VECTOR(1 TO ml); VARIABLE carry : STD_LOGIC := '0'; VARIABLE a,b,s1 : STD_LOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := rt(i); s1 := a + b; res(i) := s1 + carry; carry := (a AND b) OR (s1 AND carry); END LOOP; RETURN res; END; FUNCTION "+" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : UNSIGNED(1 TO ml); VARIABLE rt : UNSIGNED(1 TO ml); VARIABLE res : UNSIGNED(1 TO ml); VARIABLE carry : STD_LOGIC := '0'; VARIABLE a,b,s1 : STD_LOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := rt(i); s1 := a + b; res(i) := s1 + carry; carry := (a AND b) OR (s1 AND carry); END LOOP; RETURN res; END; FUNCTION "+" (arg1, arg2:SIGNED) RETURN SIGNED IS CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ; VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ; VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN assert arg1'length > 1 AND arg2'length > 1 report "SIGNED vector must be atleast 2 bits wide" severity ERROR; a := (OTHERS => arg1(arg1'left)) ; a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1); b := (OTHERS => arg2(arg2'left)) ; b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2); answer := SIGNED(a + b); RETURN (answer); END ;------------------------------------------- Synthesizable subtraction Functions ------------------------------------------- FUNCTION "-" ( arg1, arg2 : std_logic ) RETURN std_logic IS -- truth table for "xor" function CONSTANT xor_table : stdlogic_table := ( -- ---------------------------------------------------- -- | U X 0 1 Z W L H D | | -- ---------------------------------------------------- ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W | ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L | ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D | ); BEGIN RETURN xor_table( arg1, arg2 ); END "-"; FUNCTION "-" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE borrow : STD_ULOGIC := '1'; VARIABLE a,b,s1 : STD_ULOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := NOT rt(i); s1 := a + b; res(i) := s1 + borrow; borrow := (a AND b) OR (s1 AND borrow); END LOOP; RETURN res; END "-"; FUNCTION "-" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE res : STD_LOGIC_VECTOR(1 TO ml); VARIABLE borrow : STD_LOGIC := '1'; VARIABLE a,b,s1 : STD_LOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := NOT rt(i); s1 := a + b; res(i) := s1 + borrow; borrow := (a AND b) OR (s1 AND borrow); END LOOP; RETURN res; END "-"; FUNCTION "-" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length); VARIABLE lt : UNSIGNED(1 TO ml); VARIABLE rt : UNSIGNED(1 TO ml); VARIABLE res : UNSIGNED(1 TO ml); VARIABLE borrow : STD_LOGIC := '1'; VARIABLE a,b,s1 : STD_LOGIC; BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN res'reverse_range LOOP a := lt(i); b := NOT rt(i); s1 := a + b; res(i) := s1 + borrow; borrow := (a AND b) OR (s1 AND borrow); END LOOP; RETURN res; END "-"; FUNCTION "-" (arg1, arg2:SIGNED) RETURN SIGNED IS CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ; VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ; VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ; BEGIN assert arg1'length > 1 AND arg2'length > 1 report "SIGNED vector must be atleast 2 bits wide" severity ERROR; a := (OTHERS => arg1(arg1'left)) ; a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1); b := (OTHERS => arg2(arg2'left)) ; b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2); answer := SIGNED( a - b ); RETURN (answer); END ;------------------------------------------- Unary subtract and add Functions ------------------------------------------- FUNCTION "+" (arg1:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS BEGIN RETURN (arg1); END; FUNCTION "+" (arg1:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS BEGIN RETURN (arg1); END; FUNCTION "+" (arg1:UNSIGNED) RETURN UNSIGNED IS BEGIN RETURN (arg1); END; FUNCTION "+" (arg1:SIGNED) RETURN SIGNED IS BEGIN RETURN (arg1); END; FUNCTION hasx( v : SIGNED ) RETURN BOOLEAN IS BEGIN FOR i IN v'range LOOP IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN NULL; ELSE RETURN TRUE; END IF; END LOOP; RETURN FALSE; END hasx; FUNCTION "-" (arg1:SIGNED) RETURN SIGNED IS constant len : integer := arg1'length; VARIABLE answer, tmp : SIGNED( len-1 downto 0 ) := (others=>'0'); VARIABLE index : integer := len; BEGIN assert arg1'length > 1 report "SIGNED vector must be atleast 2 bits wide" severity ERROR; IF hasx(arg1) THEN answer := (OTHERS => 'X'); ELSE tmp := arg1; lp1 : FOR i IN answer'REVERSE_RANGE LOOP IF (tmp(i) = '1' OR tmp(i) = 'H') THEN index := i+1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?