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

📄 std_logic_class.bdy

📁 6端口寄存器IP内核VHDL源代码
💻 BDY
📖 第 1 页 / 共 3 页
字号:
    a, b: std_logic_vector 
  ) 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;
  

  -- hardware functions
  function posedge (
    signal a: std_ulogic
  ) return boolean is
    variable y: boolean;
  begin
    if (a = '1') and a'event then
      y := true;
    else
  	   y := false;
    end if;
    return y; 
  end posedge;
  
  function negedge (
    signal a: std_ulogic
  ) return boolean is
    variable y: boolean;
  begin
    if (a = '0') and a'event then
      y := true;
    else
  	  y := false;
    end if;
    return y; 
  end negedge;

  -- mathematical functions
  function log_2 (a: std_ulogic_vector) return integer is       -- 15.11.95
    variable index : integer;
  begin
    index := a'length - 1;
    while index > -1 loop
      if a(index) = '1' then
        return index;
        index := -1; -- required in order to exit the loop
      else
        index := index - 1;
        if index = -1 then  -- catches the case when a has no '1's in it
          assert FALSE
            report "log_2(a) returns an out-of-range value"
            severity warning;
          return integer'low; -- a stupid value => a 2**32-bit vector 
                              -- with an LSB of 1 !!!
        end if;
      end if;
        -- if a >= 1, index goes to -1 in order to exit the loop after returning index=0
        -- if a = 0, index goes to -1, return value = -integer'low
        -- if a is not bit_vector pattern, (i.e., contains non-0,1 values)
        --   the U,X,W,H,L,Z,- are also treated as 0
    end loop;
  end log_2;

  -- (ii)
  -- arithmetic array type definitions
  -- std_ulogic is defined in std_logic_1164
  -- arithmetic arrays of std_logic are defined in IEEE.numeric_std

  -- twos_complement functions
  -- logical operators

  function "not" (                      -- 25.11.92
    a: twos_complement 
  ) return twos_complement is
    variable yi: twos_complement(a'length-1 downto 0);
  begin
    for i in 0 to a'length-1 loop
      yi(i) := not (a(i));
    end loop;
    return yi;
  end "not";
      
  function "and" (                      -- 24.11.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    if (a'length /= b'length) then
      assert false
        report "Error 0000." & 
               "Library = vfp." & 
               "Package Body = twos_complement_operators." & 
               "Function = and." & 
               "The wordlength of a and b MUST be the same."
        severity error;
    else
      for i in 0 to a'length-1 loop
        y(i) := a(i) and b(i);
      end loop;
    end if;
    return y;
  end "and";
      
  function "or" (                           -- 25.11.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    if (a'length /= b'length) then
      assert false
        report "Error 0001." & 
               "Library = vfp." & 
               "Package Body = twos_complement_operators." & 
               "Function = or." & 
               "The wordlength of a and b MUST be the same."
        severity error;
    else
      for i in 0 to a'length-1 loop
        y(i) := a(i) or b(i);
      end loop;
    end if;
    return y;
  end "or";
      
  function "xor" (                           -- 25.11.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    if (a'length /= b'length) then
      assert false
        report "Error 0001." & 
               "Library = vfp." & 
               "Package Body = twos_complement_operators." & 
               "Function = xor." & 
               "The wordlength of a and b MUST be the same."
        severity error;
    else
      for i in 0 to a'length-1 loop
        y(i) := a(i) xor b(i);
      end loop;
    end if;
    return y;
  end "xor";
  
  function "nand" (                           -- 25.11.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    if (a'length /= b'length) then
      assert false
        report "Error 0001." & 
               "Library = vfp." & 
               "Package Body = twos_complement_operators." & 
               "Function = nand." & 
               "The wordlength of a and b MUST be the same."
        severity error;
    else
      for i in 0 to a'length-1 loop
        y(i) := a(i) nand b(i);
      end loop;
    end if;
    return y;
  end "nand";
  
  function "nor" (                           -- 25.11.92
    a, b: twos_complement 
  ) return twos_complement is
    variable y: twos_complement(a'length-1 downto 0);
  begin
    if (a'length /= b'length) then
      assert false
        report "Error 0001." & 
               "Library = vfp." & 
               "Package Body = twos_complement_operators." & 
               "Function = nor." & 
               "The wordlength of a and b MUST be the same."
        severity error;
    else
      for i in 0 to a'length-1 loop
        y(i) := a(i) nor b(i);
      end loop;
    end if;
    return y;
  end "nor";
  
  -- function "xnor" (                           -- 25.11.92
  --   a, b: twos_complement 
  -- ) return twos_complement is
  --   variable y: twos_complement(a'length-1 downto 0);
  -- begin
  --   if (a'length /= b'length) then
  --     assert false
  --       report "Error 0001." & 
  --              "Library = vfp." & 
  --              "Package Body = twos_complement_operators." & 
  --              "Function = xnor." & 
  --              "The wordlength of a and b MUST be the same."
  --       severity error;
  --   else
  --     for i in 0 to a'length-1 loop
  --       y(i) := a(i) xnor b(i);
  --     end loop;
  --   end if;
  --   return y;
  -- end "xnor";
   
  -- arithmetic operators
  
  -- std_logic_class."+"(twos_complement, twos_complement) -> twos_complement
  function "+" (                      -- 25.11.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := longest (a, b);
    variable a_sign_extended, b_sign_extended: twos_complement(y_length-1 downto 0);
    variable y: twos_complement(y_length-1 downto 0);
    variable carry: std_ulogic;
  begin
    carry := '0';
    if (a'length < b'length) then
      for i in b'length-1 downto a'length loop
        a_sign_extended(i) := a(a'length-1);
      end loop;
      a_sign_extended(a'length-1 downto 0) := a;
      for i in 0 to b'length-1 loop
        y(i) := a_sign_extended(i) xor b(i) xor carry;
        carry := (a_sign_extended(i) and b(i)) or
                 (a_sign_extended(i) and carry) or
                 (b(i) and carry);
      end loop;
    elsif (a'length > b'length) then
      for i in a'length-1 downto b'length loop
        b_sign_extended(i) := b(b'length-1);
      end loop;
      b_sign_extended(b'length-1 downto 0) := b;
      for i in 0 to a'length-1 loop
        y(i) := a(i) xor b_sign_extended(i) xor carry;
        carry := (a(i) and b_sign_extended(i)) or
                 (a(i) and carry) or
                 (b_sign_extended(i) and carry);
      end loop;
    else                            -- i.e., (a'length = b'length)
      for i in 0 to a'length-1 loop
        y(i) := a(i) xor b(i) xor carry;
        carry := (a(i) and b(i)) or
                 (a(i) and carry) or
                 (b(i) and carry);
      end loop;
    end if;
    return y;
  end "+";
  
  function "-" (                      -- 29.11.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := longest (a, b);
    variable a_sign_extended, b_sign_extended: twos_complement(y_length-1 downto 0);
    variable y: twos_complement(y_length-1 downto 0);
    variable carry: std_ulogic;
  begin
    carry := '1';
    if (a'length < b'length) then
      for i in b'length-1 downto a'length loop
        a_sign_extended(i) := a(a'length-1);
      end loop;
      a_sign_extended(a'length-1 downto 0) := a;
      for i in 0 to b'length-1 loop
        y(i) := a_sign_extended(i) xor (not b(i)) xor carry;
        carry := (a_sign_extended(i) and (not b(i))) or
                 (a_sign_extended(i) and carry) or
                 (not (b(i)) and carry);
      end loop;
    elsif (a'length > b'length) then
      for i in a'length-1 downto b'length loop
        b_sign_extended(i) := b(b'length-1);
      end loop;
      b_sign_extended(b'length-1 downto 0) := b;
      for i in 0 to a'length-1 loop
        y(i) := a(i) xor (not b_sign_extended(i)) xor carry;
        carry := (a(i) and (not b_sign_extended(i))) or
                 (a(i) and carry) or
                 ((not b_sign_extended(i)) and carry);
      end loop;
    else                            -- i.e., (a'length = b'length)
      for i in 0 to a'length-1 loop
        y(i) := a(i) xor (not b(i)) xor carry;
        carry := (a(i) and (not b(i))) or
                 (a(i) and carry) or
                 ((not b(i)) and carry);
      end loop;
    end if;
    return y;
  end "-";
    
  function "*" (                      -- 30.11.92
    a, b: twos_complement 
  ) return twos_complement is
    constant y_length: integer := a'length + b'length;
    variable y_sign: std_ulogic;
    variable a_1sC, multiplicand: twos_complement(a'length-1 downto 0);
    variable b_1sC, multiplier: twos_complement(b'length-1 downto 0);
    variable carry: std_ulogic; 
    variable partial_product: twos_complement(a'length-1 downto 0);
    variable product_lsb: twos_complement(b'length-1 downto 0);
    variable product: twos_complement(y_length-1 downto 0);
    variable y_1sC: twos_complement(y_length-1 downto 0);
    variable y: twos_complement(y_length-1 downto 0);
  begin
  -- firstly, the sign of the result is extracted               --   BB x 02
    y_sign := a(a'length-1) xor b(b'length-1);                  --    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                             
        multiplicand(i) := a_1sC(i) xor carry;                  
        carry := a_1sC(i) and carry;                            
      end loop;                                                 
    else                                                        
      multiplicand := 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                             
        multiplier(i) := b_1sC(i) xor carry;                    
        carry := b_1sC(i) and carry;                            
      end loop;                                                 
    else                                                        
      multiplier := b;
    end if;                                                     --
  -- thirdly, the multiplication of the absolute values takes place
    for i in 0 to (multiplicand'length - 1) loop                
      partial_product(i) := '0';                                
    end loop;                                                   
    for i in 0 to multiplier'length-1 loop                      
      if (multiplier(i) = '1') then                             
        partial_product := partial_product + multiplicand;  -- 
        product_lsb(i) := partial_product(0);                          
        partial_product := '0' & partial_product(a'length-1 downto 1); 
      else                                                             
        product_lsb(i) := partial_product(0);                          
        partial_product := '0' & partial_product(a'length-1 downto 1); 
      end if;                                                          
    end loop;                                                          
  -- now the result's absolute value is converted to it's 2's complement value
    product :=  partial_product & product_lsb;   --  if all variables were 2scomp, there'd be no problem
    if (y_sign = '1') then                                          
      y_1sC := not product;                                         

⌨️ 快捷键说明

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