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

📄 std_logic_class.bdy

📁 6端口寄存器IP内核VHDL源代码
💻 BDY
📖 第 1 页 / 共 3 页
字号:
      carry := '1';                                                 
      for i in 0 to y_1sC'length-1 loop                             
        y(i) := y_1sC(i) xor carry;                                 
        carry := y_1sC(i) and carry;                                
      end loop;                                                     
    else                                                            
      y := product;                                                 
    end if;                                                         
    return y;                                                       
  end "*";
  
  function "/" (                      -- 29.11.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := a'length + b'length; 
    constant a_extended_length: integer := b'length-1;
    variable y_sign: std_ulogic;
    variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
    variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
    variable carry: std_ulogic; 
    variable a_extended: twos_complement(a_extended_length-1 downto 0);
    variable dividend_match: twos_complement(b'length-1 downto 0);
    variable quotient: twos_complement(a'length-1 downto 0);
    variable remainder: twos_complement(b'length-1 downto 0);
    variable quotient_abs, quotient_1sC: twos_complement(a'length-1 downto 0);
    variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
    variable y: twos_complement(y_length-1 downto 0);
  begin
  -- firstly, the sign of the result is extracted
    y_sign := a(a'length-1) xor b(b'length-1);
  -- second, the operands are converted to absolute values
    if (a(a'length-1) = '1') then
      a_1sC := not a;
      carry := '1';
      for i in 0 to a'length-1 loop
        a_abs(i) := a_1sC(i) xor carry;
        carry := a_1sC(i) and carry;
      end loop;
    else
      a_abs := a;
    end if;
    if (b(b'length-1) = '1') then
      b_1sC := not b;
      carry := '1';
      for i in 0 to b'length-1 loop
        b_abs(i) := b_1sC(i) xor carry;
        carry := b_1sC(i) and carry;
      end loop;
    else
      b_abs := b;
    end if;
  -- thirdly, the division of the absolute values takes place
    for i in a_extended_length-1 downto 0 loop
      a_extended(i) := '0';
    end loop;
    dividend_match(b_abs'length-1 downto 1) := a_extended;
    for i in a_abs'length-1 downto 0 loop
      dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
      if (b_abs <= dividend_match) then
        dividend_match := dividend_match - b_abs;
        quotient_abs(i) := '1';
      else
        quotient_abs(i) := '0';
      end if;
    end loop; 
    remainder_abs := dividend_match;
  -- now the result's absolute value is converted to it's 2's complement value
  -- note that the sign of the remainder follows the sign of the dividend
    if (y_sign = '1') then
      quotient_1sC := not quotient_abs;
      carry := '1';
      for i in 0 to quotient_1sC'length-1 loop
        quotient(i) := quotient_1sC(i) xor carry;
        carry := quotient_1sC(i) and carry;
      end loop;
    else
      quotient := quotient_abs;
    end if;    
    if (a(a'length-1) = '1') then
      remainder_1sC := not remainder_abs;
      carry := '1';
      for i in 0 to remainder_1sC'length-1 loop
        remainder(i) := remainder_1sC(i) xor carry;
        carry := remainder_1sC(i) and carry;
      end loop;
    else
      remainder := remainder_abs;
    end if;    
    y := quotient & remainder;
    return y;
  end "/";
      
  function "mod" (                      -- 2.12.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := a'length + b'length; 
    constant a_extended_length: integer := b'length-1;
    variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
    variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
    variable carry: std_ulogic; 
    variable a_extended: twos_complement(a_extended_length-1 downto 0);
    variable dividend_match: twos_complement(b'length-1 downto 0);
    variable remainder: twos_complement(b'length-1 downto 0);
    variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
    variable y: twos_complement(b'length-1 downto 0);
  begin
  -- firstly, the operands are converted to absolute values
    if (a(a'length-1) = '1') then
      a_1sC := not a;
      carry := '1';
      for i in 0 to a'length-1 loop
        a_abs(i) := a_1sC(i) xor carry;
        carry := a_1sC(i) and carry;
      end loop;
    else
      a_abs := a;
    end if;
    if (b(b'length-1) = '1') then
      b_1sC := not b;
      carry := '1';
      for i in 0 to b'length-1 loop
        b_abs(i) := b_1sC(i) xor carry;
        carry := b_1sC(i) and carry;
      end loop;
    else
      b_abs := b;
    end if;
  -- secondly, the division of the absolute values takes place
    for i in a_extended_length-1 downto 0 loop
      a_extended(i) := '0';
    end loop;
    dividend_match(b_abs'length-1 downto 1) := a_extended;
    for i in a_abs'length-1 downto 0 loop
      dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
      if (b_abs <= dividend_match) then
        dividend_match := dividend_match - b_abs;
      end if;
    end loop; 
    remainder_abs := dividend_match;
  -- now the result's absolute value is converted to it's 2's complement value
  -- note that the sign of the remainder follows the sign of the dividend
    if (a(a'length-1) = '1') then
      remainder_1sC := not remainder_abs;
      carry := '1';
      for i in 0 to remainder_1sC'length-1 loop
        remainder(i) := remainder_1sC(i) xor carry;
        carry := remainder_1sC(i) and carry;
      end loop;
    else
      remainder := remainder_abs;
    end if;    
    y := remainder;
    return y;
  end "mod";
      
  function "rem" (                      -- 2.12.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := a'length + b'length; 
    constant a_extended_length: integer := b'length-1;
    variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
    variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
    variable carry: std_ulogic; 
    variable a_extended: twos_complement(a_extended_length-1 downto 0);
    variable dividend_match: twos_complement(b'length-1 downto 0);
    variable remainder: twos_complement(b'length-1 downto 0);
    variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
    variable y: twos_complement(b'length-1 downto 0);
  begin
  -- firstly, the operands are converted to absolute values
    if (a(a'length-1) = '1') then
      a_1sC := not a;
      carry := '1';
      for i in 0 to a'length-1 loop
        a_abs(i) := a_1sC(i) xor carry;
        carry := a_1sC(i) and carry;
      end loop;
    else
      a_abs := a;
    end if;
    if (b(b'length-1) = '1') then
      b_1sC := not b;
      carry := '1';
      for i in 0 to b'length-1 loop
        b_abs(i) := b_1sC(i) xor carry;      
        carry := b_1sC(i) and carry;
      end loop;
    else
      b_abs := b;
    end if;
  -- secondly, the division of the absolute values takes place
    for i in a_extended_length-1 downto 0 loop
      a_extended(i) := '0';
    end loop;
    dividend_match(b_abs'length-1 downto 1) := a_extended;
    for i in a_abs'length-1 downto 0 loop
      dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
      if (b_abs <= dividend_match) then
        dividend_match := dividend_match - b_abs;
      end if;
    end loop; 
    remainder_abs := dividend_match;
  -- now the result's absolute value is converted to it's 2's complement value
  -- note that the sign of the remainder follows the sign of the dividend
    if (a(a'length-1) = '1') then
      remainder_1sC := not remainder_abs;
      carry := '1';
      for i in 0 to remainder_1sC'length-1 loop
        remainder(i) := remainder_1sC(i) xor carry;
        carry := remainder_1sC(i) and carry;
      end loop;
    else
      remainder := remainder_abs;
    end if;    
    y := remainder;
    return y;
  end "rem";        
  
  function "**" (                      -- 2.12.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    assert false
      report "Error 0001." &                                
             "Library = vfp." &                             
             "Package Body = twos_complement_operators." &   
             "Function = **." &                              
             "The function (twos_complement) ** (twos_complement) is not supported." &
             "However, to_twos_complement(to_integer(twos_complementy) ** to_integer(twos_complement)) is supported."                              
  -- See the to_integer and the to_twos_complement conversion functions
      severity error;
    y := a;
    return y;
  end "**";
  
  function "abs" (                      -- 2.12.92
    a: twos_complement 
  ) return twos_complement is
  -- the function abs_wordlength returns a'length+1 if a is
  -- -2(N-1) otherwise it returns a'length
    constant y_length: integer := abs_wordlength(a); 
    variable a_1sC: twos_complement(a'length-1 downto 0);
    variable carry: std_ulogic;
    variable y: twos_complement(y_length-1 downto 0);
  begin
    if (y_length = a'length+1) then
      y(a'length) := '1';
    end if;
    if (a(a'length-1) = '1') then
      a_1sC := not a;
      carry := '1';
      for i in 0 to a'length-1 loop
        y(i) := a_1sC(i) xor carry;
        carry := a_1sC(i) and carry;
      end loop;
    else
      y := a;
    end if;
    return y;
  end "abs";
  
  function "+" (                      -- 2.12.92
    a: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    assert false
      report "Warning 0001." &                                
             "Library = vfp." &                             
             "Package Body = twos_complement_operators." &   
             "Function = +." &                              
             "The function + (twos_complement) is defined as ... " &
             "    <return_value> := <actual_parameter>    " &
             "Thus there is no point in taking the positive value of a twos_complement object."                              
      severity warning;
    y := a;
    return y;
  end "+";
  
  function "-" (                      -- 2.12.92
    a: twos_complement 
  ) return twos_complement is
  -- the function abs_wordlength returns a'length+1 if a is
  -- -2(N-1) otherwise it returns a'length
    constant y_length: integer := abs_wordlength(a); 
    variable a_1sC: twos_complement(a'length-1 downto 0);
    variable carry: std_ulogic;
    variable y: twos_complement(y_length-1 downto 0);
  begin
    if (y_length = a'length+1) then
      y(a'length) := '0';
    end if;
    a_1sC := not a;
    carry := '1';
    for i in 0 to a'length-1 loop
      y(i) := a_1sC(i) xor carry;
      carry := a_1sC(i) and carry;
    end loop;
    return y;
  end "-";
  
  -- shift operators

  -- general purpose functions
  function longest (                      -- 25.11.92
    a, b: twos_complement 
  ) return integer is
    variable y: integer;
  begin
    if (a'length >= b'length) then
      y := a'length;
    else
      y := b'length;
    end if;
    return y;
  end longest;
  
  function abs_wordlength (
    a: twos_complement
  ) return integer is
    variable any_1s: std_ulogic;
    variable y: integer;
  begin
    any_1s := '0';
  -- all bits excpet the MSB are tested for being 1
  -- if none are 1, all bits are 0, and any_1s is 0
  -- hence either 0 or -2(N-1) has been found
  -- if this function is only called when a is -ve
  -- it finds if a is -2(N-1)
    for i in 0 to a'length-2 loop    -- unary OR operation
      any_1s := a(i) or any_1s; 
    end loop;
    if ((a(a'length-1) = '1') and (any_1s = '0')) then
      y := a'length + 1;
    else
      y := a'length;
    end if;
    return y;
  end abs_wordlength; 
    
  -- hardware functions
  -- none yet defined
  
  -- mathematical functions
  -- none yet defined

end std_logic_class;



⌨️ 快捷键说明

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