OpenCores
URL https://opencores.org/ocsvn/core_arm/core_arm/trunk

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [libs/] [int.vhd] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned.conv_integer;
use IEEE.std_logic_arith.conv_unsigned;
use IEEE.std_logic_arith.all;
 
-- PREFIX: lin_xxx
package int is
 
constant LIN_ZERO    : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
constant LIN_ONE     : std_logic_vector(31 downto 0) := "00000000000000000000000000000001";
constant LIN_TWO     : std_logic_vector(31 downto 0) := "00000000000000000000000000000010";
constant LIN_THREE   : std_logic_vector(31 downto 0) := "00000000000000000000000000000011";
constant LIN_FOUR    : std_logic_vector(31 downto 0) := "00000000000000000000000000000100";
constant LIN_MINFOUR : std_logic_vector(31 downto 0) := "11111111111111111111111111111100";
 
-- increment/decrement wrapper
procedure lin_incdec(
  source : in    std_logic_vector;
  dest   : inout std_logic_vector;
  do     : in    std_logic;
  inc    : in    std_logic
);
 
-- convert std_logic_vector to integer
function lin_convint(
  op   : in std_logic_vector
) return integer;
 
-- set bit integer(v)
function lin_decode(
  v : std_logic_vector
) return std_logic_vector;
 
-- pos of first '1' from left
function lin_countzero(
  data : in    std_logic_vector
) return std_logic_vector;
 
-- adder with carryin
procedure lin_adder(
  op1   : in std_logic_vector(31 downto 0);
  op2   : in std_logic_vector(31 downto 0);
  carry : in std_logic;
  sub   : in std_logic;
  sum   : out std_logic_vector(31 downto 0)
);
 
----------------------------------------------------------------------------
-- log2 tables
----------------------------------------------------------------------------
 
type lin_log2arr is array(1 to 64) of integer;
constant lin_log2  : lin_log2arr := (0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
				5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,others => 6);
constant lin_log2x : lin_log2arr := (1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
				5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,others => 6);
 
end int;
 
package body int is
 
procedure lin_incdec(
  source : in    std_logic_vector;
  dest   : inout std_logic_vector;
  do     : in    std_logic;
  inc    : in    std_logic
) is
variable tmp : std_logic_vector(source'range);
begin
 
  tmp := (others => '0');
-- pragma translate_off
    if not is_x(source) then
-- pragma translate_on
      if inc = '1' then
        tmp := source(source'range) + 1;
      else
        tmp := source(source'range) - 1;
      end if;
-- pragma translate_off
    else
      tmp := (others => 'X');
    end if;
-- pragma translate_on
 
    if (do) = '1' then
      dest := tmp;
    end if;
 
end;
 
 
function lin_countzero(
  data : in    std_logic_vector
) return std_logic_vector is
variable z02 : std_logic_vector((data'length/2)-1 downto 0);
variable z04 : std_logic_vector((data'length/4)-1 downto 0);
variable d04 : std_logic_vector(3 downto 0);
variable z08 : std_logic_vector((data'length/8)-1 downto 0);
variable d08 : std_logic_vector(7 downto 0);
variable z16 : std_logic_vector((data'length/16)-1 downto 0);
variable d16 : std_logic_vector(15 downto 0);
variable z32 : std_logic_vector((data'length/32)-1 downto 0);
variable d32 : std_logic_vector(31 downto 0);
variable z64 : std_logic_vector((data'length/64)-1 downto 0);
variable d64 : std_logic_vector(63 downto 0);
variable res : std_logic_vector(lin_log2x(data'length)-1 downto 0);
variable length : integer;
variable tmp : integer;
begin
 
  res := (others => '0');
  z32 := (others => '0');
  z02 := (others => '0');
  z04 := (others => '0');
  length := data'length;
 
  if (length / 2) >= 1 then
    tmp := 0;
L02:
    for i in (length/2)-1 downto 0 loop
      tmp := i;
      if    (data((i*2)+0) = '1') then
        z02(i) := '1';
        exit L02;
      elsif (data((i*2)+1) = '1') then
        z02(i) := '0';
        exit L02;
      else
        z02(i) := '0';
      end if;
    end loop;  -- i
    if (length = 2) then
      res(0) := z02(tmp);
    end if;
  end if;
 
  if (length / 4) >= 1 then
    tmp := 0;
L04:
    for i in (length/4)-1 downto 0 loop
      tmp := i;
      d04 := data((i*4)+3 downto i*4);
      z04(i) := '1';
      if    not (d04(3 downto 2) = "00") then
        z04(i) := '1';
        res(0) := z02(i*2);
        exit L04;
      elsif not (d04(1 downto 0) = "00") then
        z04(i) := '0';
        res(0) := z02((i*2)+1);
        exit L04;
      else
        z04(i) := '0';
      end if;
    end loop;  -- i
    if (length = 4) then
      res(1) := z04(tmp);
    end if;
  end if;
 
  if (length / 8) >= 1 then
    tmp := 0;
L08:
    for i in (length/8)-1 downto 0 loop
      tmp := i;
      d08 := data((i*8)+7 downto i*8);
      z08(i) := '1';
      if    not (d08(7 downto 4) = "0000") then
        z08(i) := '1';
        res(1) := z04(i*2);
        exit L08;
      elsif not (d08(3 downto 0) = "0000") then
        z08(i) := '0';
        res(1) := z04((i*2)+1);
        exit L08;
      else
        z08(i) := '0';
      end if;
    end loop;  -- i
    if (length = 8) then
      res(2) := z08(tmp);
    end if;
  end if;
 
  if (length / 16) >= 1 then
    tmp := 0;
L16:
    for i in (length/16)-1 downto 0 loop
      tmp := i;
      d16 := data((i*16)+15 downto i*16);
      z16(i) := '1';
      if    not (d16(15 downto 8) = "00000000") then
        z16(i) := '1';
        res(2) := z08(i*2);
        exit L16;
      elsif not (d16(7 downto 0) = "00000000") then
        z16(i) := '0';
        res(2) := z08((i*2)+1);
        exit L16;
      else
        z16(i) := '0';
      end if;
    end loop;  -- i
    if (length = 16) then
      res(3) := z16(tmp);
    end if;
  end if;
 
  if (length / 32) >= 1 then
    tmp := 0;
L32:
    for i in (length/32)-1 downto 0 loop
      tmp := i;
      d32 := data((i*32)+31 downto i*32);
      z32(i) := '1';
      if    not (d32(31 downto 16) = "0000000000000000") then
        z32(i) := '1';
        res(3) := z16(i*2);
        exit L32;
      elsif not (d32(15 downto 0) = "0000000000000000") then
        z32(i) := '0';
        res(3) := z16((i*2)+1);
        exit L32;
      else
        z32(i) := '0';
      end if;
    end loop;  -- i
    if (length = 32) then
      res(4) := z32(tmp);
    end if;
  end if;
 
  if (length / 64) >= 1 then
    tmp := 0;
L64:
    for i in (length/64)-1 downto 0 loop
      tmp := i;
      d64 := data((i*64)+63 downto i*64);
      z64(i) := '1';
      if    not (d64(63 downto 32) = "00000000000000000000000000000000") then
        z64(i) := '1';
        res(4) := z32(i*2);
        exit L64;
      elsif not (d64(31 downto 0) = "00000000000000000000000000000000") then
        z64(i) := '0';
        res(4) := z32((i*2)+1);
        exit L64;
      else
        z64(i) := '0';
      end if;
    end loop;  -- i
    if (length = 64) then
      res(5) := z64(tmp);
    end if;
  end if;
 
  return res;
end;
 
function lin_convint (
  op   : in std_logic_vector
) return integer is
variable tmp : integer;
begin
  tmp := 0;
-- pragma translate_off
    if not (is_x(op)) then
-- pragma translate_on
      tmp := conv_integer(op);
-- pragma translate_off
    end if;
-- pragma translate_on
  return tmp;
end;
 
function lin_decode(
  v : std_logic_vector
) return std_logic_vector is
variable res : std_logic_vector((2**v'length)-1 downto 0); --'
variable i : natural;
begin
  res := (others => '0');
-- pragma translate_off
  i := 0;
  if not is_x(v) then
-- pragma translate_on
    i := conv_integer(unsigned(v));
    res(i) := '1';
-- pragma translate_off
  else
    res := (others => 'X');
  end if;
-- pragma translate_on
  return(res);
end;
 
procedure lin_adder(
  op1   : in std_logic_vector(31 downto 0);
  op2   : in std_logic_vector(31 downto 0);
  carry : in std_logic;
  sub   : in std_logic;
  sum   : out std_logic_vector(31 downto 0)
) is
begin
-- pragma translate_off
    if not (is_x(op1) or is_x(op2) or is_x(carry)) then
-- pragma translate_on
      if sub = '1' then
        sum := op1 - op2 - carry;
      else
        sum := op1 + op2 + carry;
      end if;
-- pragma translate_off
    else
      sum := (others => 'X');
    end if;
-- pragma translate_on
 
end;
 
end int;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.