⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 66_signed.vhd

📁 vhdl编程100例,有需要的就下吧
💻 VHD
📖 第 1 页 / 共 5 页
字号:
	variable one_bit : STD_ULOGIC;
	variable result : STD_LOGIC_VECTOR (A'range);
    begin
	    for i in A'range loop
	        if (IS_X(A(i))) then
		    assert false 
		    report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
		    severity warning;
		    result := (others => 'X');
	            return result;
	        end if;
		result(i) := tbl_BINARY(A(i));
	    end loop;
	    return result;
    end;



    -- Type propagation function which returns a signed type with the
    -- size of the left arg.
    function LEFT_SIGNED_ARG(A,B: SIGNED) return SIGNED is
      variable Z: SIGNED (A'left downto 0);
      -- pragma return_port_name Z
    begin
      return(Z);
    end;
	
    -- Type propagation function which returns an unsigned type with the
    -- size of the left arg.
    function LEFT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is
      variable Z: UNSIGNED (A'left downto 0);
      -- pragma return_port_name Z
    begin
      return(Z);
    end;
	
    -- Type propagation function which returns a signed type with the
    -- size of the result of a signed multiplication
    function MULT_SIGNED_ARG(A,B: SIGNED) return SIGNED is
      variable Z: SIGNED ((A'length+B'length-1) downto 0);
      -- pragma return_port_name Z
    begin
      return(Z);
    end;
	
    -- Type propagation function which returns an unsigned type with the
    -- size of the result of a unsigned multiplication
    function MULT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is
      variable Z: UNSIGNED ((A'length+B'length-1) downto 0);
      -- pragma return_port_name Z
    begin
      return(Z);
    end;



    function mult(A,B: SIGNED) return SIGNED is

      variable BA: SIGNED((A'length+B'length-1) downto 0);
      variable PA: SIGNED((A'length+B'length-1) downto 0);
      variable AA: SIGNED(A'length downto 0);
      variable neg: STD_ULOGIC;
      constant one : UNSIGNED(1 downto 0) := "01";
      
      -- pragma map_to_operator MULT_TC_OP
      -- pragma type_function MULT_SIGNED_ARG
      -- pragma return_port_name Z

      begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            PA := (others => 'X');
            return(PA);
	end if;
        PA := (others => '0');
        neg := B(B'left) xor A(A'left);
        BA := CONV_SIGNED(('0' & SIGNED' (ABS(B))),(A'length+B'length));
        AA := '0' & ABS(A);
        for i in 0 to A'length-1 loop
          if AA(i) = '1' then
            PA := PA+BA;
          end if;
          BA := SHL(BA,one);
        end loop;
        if (neg= '1') then
          return(-PA);
        else 
          return(PA);
        end if;
      end;

    function mult(A,B: UNSIGNED) return UNSIGNED is

      variable BA: UNSIGNED((A'length+B'length-1) downto 0);
      variable PA: UNSIGNED((A'length+B'length-1) downto 0);
      constant one : UNSIGNED(1 downto 0) := "01";
      
      -- pragma map_to_operator MULT_UNS_OP
      -- pragma type_function MULT_UNSIGNED_ARG
      -- pragma return_port_name Z

      begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            PA := (others => 'X');
            return(PA);
	end if;
        PA := (others => '0');
        BA := CONV_UNSIGNED(B,(A'length+B'length));
        for i in 0 to A'length-1 loop
          if A(i) = '1' then
            PA := PA+BA;
          end if;
          BA := SHL(BA,one);
        end loop;
        return(PA);
      end;

    -- subtract two signed numbers of the same length
    -- both arrays must have range (msb downto 0)
    function minus(A, B: SIGNED) return SIGNED is
	variable carry: STD_ULOGIC;
	variable BV: STD_ULOGIC_VECTOR (A'left downto 0);
	variable sum: SIGNED (A'left downto 0);

	-- pragma map_to_operator SUB_TC_OP

	-- pragma type_function LEFT_SIGNED_ARG
        -- pragma return_port_name Z

    begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            sum := (others => 'X');
            return(sum);
	end if;
	carry := '1';
	BV := not STD_ULOGIC_VECTOR(B);

	for i in 0 to A'left loop
	    sum(i) := A(i) xor BV(i) xor carry;
	    carry := (A(i) and BV(i)) or
		    (A(i) and carry) or
		    (carry and BV(i));
	end loop;
	return sum;
    end;

    -- add two signed numbers of the same length
    -- both arrays must have range (msb downto 0)
    function plus(A, B: SIGNED) return SIGNED is
	variable carry: STD_ULOGIC;
	variable BV, sum: SIGNED (A'left downto 0);

	-- pragma map_to_operator ADD_TC_OP
	-- pragma type_function LEFT_SIGNED_ARG
        -- pragma return_port_name Z

    begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            sum := (others => 'X');
            return(sum);
	end if;
	carry := '0';
	BV := B;

	for i in 0 to A'left loop
	    sum(i) := A(i) xor BV(i) xor carry;
	    carry := (A(i) and BV(i)) or
		    (A(i) and carry) or
		    (carry and BV(i));
	end loop;
	return sum;
    end;


    -- subtract two unsigned numbers of the same length
    -- both arrays must have range (msb downto 0)
    function unsigned_minus(A, B: UNSIGNED) return UNSIGNED is
	variable carry: STD_ULOGIC;
	variable BV: STD_ULOGIC_VECTOR (A'left downto 0);
	variable sum: UNSIGNED (A'left downto 0);

	-- pragma map_to_operator SUB_UNS_OP
	-- pragma type_function LEFT_UNSIGNED_ARG
        -- pragma return_port_name Z

    begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            sum := (others => 'X');
            return(sum);
	end if;
	carry := '1';
	BV := not STD_ULOGIC_VECTOR(B);

	for i in 0 to A'left loop
	    sum(i) := A(i) xor BV(i) xor carry;
	    carry := (A(i) and BV(i)) or
		    (A(i) and carry) or
		    (carry and BV(i));
	end loop;
	return sum;
    end;

    -- add two unsigned numbers of the same length
    -- both arrays must have range (msb downto 0)
    function unsigned_plus(A, B: UNSIGNED) return UNSIGNED is
	variable carry: STD_ULOGIC;
	variable BV, sum: UNSIGNED (A'left downto 0);

	-- pragma map_to_operator ADD_UNS_OP
	-- pragma type_function LEFT_UNSIGNED_ARG
        -- pragma return_port_name Z

    begin
	if (A(A'left) = 'X' or B(B'left) = 'X') then
            sum := (others => 'X');
            return(sum);
	end if;
	carry := '0';
	BV := B;

	for i in 0 to A'left loop
	    sum(i) := A(i) xor BV(i) xor carry;
	    carry := (A(i) and BV(i)) or
		    (A(i) and carry) or
		    (carry and BV(i));
	end loop;
	return sum;
    end;



    function "*"(L: SIGNED; R: SIGNED) return SIGNED is
	-- pragma label_applies_to mult
    begin
          return     mult(CONV_SIGNED(L, L'length),
		          CONV_SIGNED(R, R'length)); -- pragma label mult 
    end;
      
    function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is
	-- pragma label_applies_to mult
    begin
          return   mult(CONV_UNSIGNED(L, L'length),
                        CONV_UNSIGNED(R, R'length)); -- pragma label mult 
    end;
        
    function "*"(L: UNSIGNED; R: SIGNED) return SIGNED is
	-- pragma label_applies_to plus
    begin
 	return       mult(CONV_SIGNED(L, L'length+1),
		          CONV_SIGNED(R, R'length)); -- pragma label mult 
    end;

    function "*"(L: SIGNED; R: UNSIGNED) return SIGNED is
	-- pragma label_applies_to plus
    begin
	return      mult(CONV_SIGNED(L, L'length),
		         CONV_SIGNED(R, R'length+1)); -- pragma label mult 
    end;


    function "*"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
	-- pragma label_applies_to mult
    begin
          return STD_LOGIC_VECTOR (mult(CONV_SIGNED(L, L'length),
		          CONV_SIGNED(R, R'length))); -- pragma label mult 
    end;
      
    function "*"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
	-- pragma label_applies_to mult
    begin
          return STD_LOGIC_VECTOR (mult(CONV_UNSIGNED(L, L'length),
                        CONV_UNSIGNED(R, R'length))); -- pragma label mult 
    end;
        
    function "*"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
	-- pragma label_applies_to plus
    begin
 	return STD_LOGIC_VECTOR (mult(CONV_SIGNED(L, L'length+1),
		          CONV_SIGNED(R, R'length))); -- pragma label mult 
    end;

    function "*"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
	-- pragma label_applies_to plus
    begin
	return STD_LOGIC_VECTOR (mult(CONV_SIGNED(L, L'length),
		         CONV_SIGNED(R, R'length+1))); -- pragma label mult 
    end;


    function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := max(L'length, R'length);
    begin
	return unsigned_plus(CONV_UNSIGNED(L, length),
			     CONV_UNSIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: SIGNED; R: SIGNED) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := max(L'length, R'length);
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: UNSIGNED; R: SIGNED) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := max(L'length + 1, R'length);
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: SIGNED; R: UNSIGNED) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := max(L'length, R'length + 1);
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := L'length + 1;
    begin
	return CONV_UNSIGNED(
		plus( -- pragma label plus
		    CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)),
		length-1);
    end;


    function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := R'length + 1;
    begin
	return CONV_UNSIGNED(
		plus( -- pragma label plus
		    CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)),
		length-1);
    end;


    function "+"(L: SIGNED; R: INTEGER) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := L'length;
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: INTEGER; R: SIGNED) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := R'length;
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := L'length;
    begin
	return unsigned_plus(CONV_UNSIGNED(L, length),
		     CONV_UNSIGNED(R, length)) ; -- pragma label plus
    end;


    function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := R'length;
    begin
	return unsigned_plus(CONV_UNSIGNED(L, length),
		     CONV_UNSIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED is
	-- pragma label_applies_to plus
	constant length: INTEGER := L'length;
    begin
	return plus(CONV_SIGNED(L, length),
		    CONV_SIGNED(R, length)); -- pragma label plus
    end;


    function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED is

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -