std_logic_arith_body.vhdl
来自「vhdl集成电路设计软件.需要用gcc-4.0.2版本编译.」· VHDL 代码 · 共 1,959 行 · 第 1/5 页
VHDL
1,959 行
answer(i downto 0) := tmp(i downto 0); exit; END IF; END LOOP lp1; answer(len-1 downto index) := NOT tmp(len-1 downto index); end if; RETURN (answer); END ;---------------------------------------------- Synthesizable multiplication Functions ---------------------------------------------- FUNCTION shift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS VARIABLE v1 : STD_ULOGIC_VECTOR( v'range ); BEGIN FOR i IN (v'left+1) TO v'right LOOP v1(i-1) := v(i); END LOOP; v1(v1'right) := '0'; RETURN v1; END shift; PROCEDURE copy(a : IN STD_ULOGIC_VECTOR; b : OUT STD_ULOGIC_VECTOR) IS VARIABLE bi : INTEGER := b'right; BEGIN FOR i IN a'reverse_range LOOP b(bi) := a(i); bi := bi - 1; END LOOP; END copy; FUNCTION shift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS VARIABLE v1 : STD_LOGIC_VECTOR( v'range ); BEGIN FOR i IN (v'left+1) TO v'right LOOP v1(i-1) := v(i); END LOOP; v1(v1'right) := '0'; RETURN v1; END shift; PROCEDURE copy(a : IN STD_LOGIC_VECTOR; b : OUT STD_LOGIC_VECTOR) IS VARIABLE bi : INTEGER := b'right; BEGIN FOR i IN a'reverse_range LOOP b(bi) := a(i); bi := bi - 1; END LOOP; END copy; FUNCTION shift( v : SIGNED ) RETURN SIGNED IS VARIABLE v1 : SIGNED( v'range ); BEGIN FOR i IN (v'left+1) TO v'right LOOP v1(i-1) := v(i); END LOOP; v1(v1'right) := '0'; RETURN v1; END shift; PROCEDURE copy(a : IN SIGNED; b : OUT SIGNED) IS VARIABLE bi : INTEGER := b'right; BEGIN FOR i IN a'reverse_range LOOP b(bi) := a(i); bi := bi - 1; END LOOP; END copy; FUNCTION shift( v : UNSIGNED ) RETURN UNSIGNED IS VARIABLE v1 : UNSIGNED( v'range ); BEGIN FOR i IN (v'left+1) TO v'right LOOP v1(i-1) := v(i); END LOOP; v1(v1'right) := '0'; RETURN v1; END shift; PROCEDURE copy(a : IN UNSIGNED; b : OUT UNSIGNED) IS VARIABLE bi : INTEGER := b'right; BEGIN FOR i IN a'reverse_range LOOP b(bi) := a(i); bi := bi - 1; END LOOP; END copy; FUNCTION "*" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS VARIABLE ml : INTEGER := arg1'length + arg2'length; VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE prod : STD_ULOGIC_VECTOR(1 TO ml) := (OTHERS=>'0'); BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN rt'reverse_range LOOP IF rt(i) = '1' THEN prod := prod + lt; END IF; lt := shift(lt); END LOOP; RETURN prod; END "*"; FUNCTION "*" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS VARIABLE ml : INTEGER := arg1'length + arg2'length; VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml); VARIABLE prod : STD_LOGIC_VECTOR(1 TO ml) := (OTHERS=>'0'); BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN rt'reverse_range LOOP IF rt(i) = '1' THEN prod := prod + lt; END IF; lt := shift(lt); END LOOP; RETURN prod; END "*"; FUNCTION "*" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS VARIABLE ml : INTEGER := arg1'length + arg2'length; VARIABLE lt : UNSIGNED(1 TO ml); VARIABLE rt : UNSIGNED(1 TO ml); VARIABLE prod : UNSIGNED(1 TO ml) := (OTHERS=>'0'); BEGIN lt := zxt( arg1, ml ); rt := zxt( arg2, ml ); FOR i IN rt'reverse_range LOOP IF rt(i) = '1' THEN prod := prod + lt; END IF; lt := shift(lt); END LOOP; RETURN prod; END "*"; --//// Sign Extend //// -- -- Function sxt -- FUNCTION sxt( q : SIGNED; i : INTEGER ) RETURN SIGNED IS VARIABLE qs : SIGNED (1 TO i); VARIABLE qt : SIGNED (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=>q(q'left)); qs := qs(1 TO (i-q'length)) & qt; ELSE qs := qt; END IF; RETURN qs; END; FUNCTION "*" (arg1, arg2:SIGNED) RETURN SIGNED IS VARIABLE ml : INTEGER := arg1'length + arg2'length; VARIABLE lt : SIGNED(1 TO ml); VARIABLE rt : SIGNED(1 TO ml); VARIABLE prod : SIGNED(1 TO ml) := (OTHERS=>'0'); BEGIN assert arg1'length > 1 AND arg2'length > 1 report "SIGNED vector must be atleast 2 bits wide" severity ERROR; lt := sxt( arg1, ml ); rt := sxt( arg2, ml ); FOR i IN rt'reverse_range LOOP IF rt(i) = '1' THEN prod := prod + lt; END IF; lt := shift(lt); END LOOP; RETURN prod; END "*"; FUNCTION rshift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS VARIABLE v1 : STD_ULOGIC_VECTOR( v'range ); BEGIN FOR i IN v'left TO v'right-1 LOOP v1(i+1) := v(i); END LOOP; v1(v1'left) := '0'; RETURN v1; END rshift; FUNCTION hasx( v : STD_ULOGIC_VECTOR ) 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 rshift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS VARIABLE v1 : STD_LOGIC_VECTOR( v'range ); BEGIN FOR i IN v'left TO v'right-1 LOOP v1(i+1) := v(i); END LOOP; v1(v1'left) := '0'; RETURN v1; END rshift; FUNCTION hasx( v : STD_LOGIC_VECTOR ) 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 rshift( v : UNSIGNED ) RETURN UNSIGNED IS VARIABLE v1 : UNSIGNED( v'range ); BEGIN FOR i IN v'left TO v'right-1 LOOP v1(i+1) := v(i); END LOOP; v1(v1'left) := '0'; RETURN v1; END rshift; FUNCTION hasx( v : UNSIGNED ) 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 rshift( v : SIGNED ) RETURN SIGNED IS VARIABLE v1 : SIGNED( v'range ); BEGIN FOR i IN v'left TO v'right-1 LOOP v1(i+1) := v(i); END LOOP; v1(v1'left) := '0'; RETURN v1; END rshift; FUNCTION "/" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(l'length,r'length); VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1); VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1); VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml); VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0'); VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0'); BEGIN ASSERT NOT (r = "0") REPORT "Attempted divide by ZERO" SEVERITY ERROR; IF hasx(l) OR hasx(r) THEN FOR i IN quote'range LOOP quote(i) := 'X'; END LOOP; ELSE lt := zxt( l, ml+2 ); WHILE lt >= r LOOP rt := zxt( r, ml+2 ); n := (OTHERS=>'0'); n(n'right) := '1'; WHILE rt <= lt LOOP rt := shift(rt); n := shift(n); END LOOP; rt := rshift(rt); lt := lt - rt; n := rshift(n); tmp := tmp + n; END LOOP; END IF; quote := tmp(2 TO ml+1); RETURN quote; END "/"; FUNCTION "/" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS CONSTANT ml : INTEGER := maximum(l'length,r'length); VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1); VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1); VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml); VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0'); VARIABLE n : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0'); BEGIN ASSERT NOT (r = "0") REPORT "Attempted divide by ZERO" SEVERITY ERROR; IF hasx(l) OR hasx(r) THEN FOR i IN quote'range LOOP quote(i) := 'X'; END LOOP; ELSE lt := zxt( l, ml+2 ); WHILE lt >= r LOOP rt := zxt( r, ml+2 ); n := (OTHERS=>'0'); n(n'right) := '1'; WHILE rt <= lt LOOP rt := shift(rt); n := shift(n); END LOOP; rt := rshift(rt); lt := lt - rt; n := rshift(n); tmp := tmp + n; END LOOP; END IF; quote := tmp(2 TO ml+1); RETURN quote; END "/"; FUNCTION "/" (l, r :UNSIGNED) RETURN UNSIGNED IS CONSTANT ml : INTEGER := maximum(l'length,r'length); VARIABLE lt : UNSIGNED(0 TO ml+1); VARIABLE rt : UNSIGNED(0 TO ml+1); VARIABLE quote : UNSIGNED(1 TO ml); VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0'); VARIABLE n : UNSIGNED(0 TO ml+1) := (OTHERS=>'0'); BEGIN ASSERT NOT (r = "0") REPORT "Attempted divide by ZERO" SEVERITY ERROR; IF hasx(l) OR hasx(r) THEN FOR i IN quote'range LOOP quote(i) := 'X'; END LOOP; ELSE lt := zxt( l, ml+2 ); WHILE lt >= r LOOP rt := zxt( r, ml+2 ); n := (OTHERS=>'0'); n(n'right) := '1'; WHILE rt <= lt LOOP rt := shift(rt); n := shift(n); END LOOP; rt := rshift(rt); lt := lt - rt; n := rshift(n); tmp := tmp + n; END LOOP; END IF; quote := tmp(2 TO ml+1); RETURN quote; END "/"; FUNCTION "/" (l, r :SIGNED) RETURN SIGNED IS CONSTANT ml : INTEGER := maximum(l'length,r'length); VARIABLE lt : SIGNED(0 TO ml+1); VARIABLE rt : SIGNED(0 TO ml+1); VARIABLE quote : SIGNED(1 TO ml); VARIABLE tmp : SIGNED(0 TO ml+1) := (OTHERS=>'0'); VARIABLE n : SIGNED(0 TO ml+1) := (OTHERS=>'0'); BEGIN assert l'length > 1 AND r'length > 1 report "SIGNED vector must be atleast 2 bits wide" severity ERROR; ASSERT NOT (r = "0") REPORT "Attempted divide by ZERO" SEVERITY ERROR; IF hasx(l) OR hasx(r) THEN FOR i IN quote'range LOOP quote(i) := 'X'; END LOOP; ELSE lt := sxt( l, ml+2 ); WHILE lt >= r LOOP rt := sxt( r, ml+2 ); n := (OTHERS=>'0'); n(n'right) := '1';
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?