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 + -
显示快捷键?