##// END OF EJS Templates
temp
temp

File last commit:

r100:fc97c34d69e3 martin
r249:279a122aaba5 JC
Show More
stdlib.vhd
601 lines | 17.2 KiB | text/x-vhdl | VhdlLexer
martin
Mise a jour Projets blanc
r100 ------------------------------------------------------------------------------
-- This file is a part of the GRLIB VHDL IP LIBRARY
-- Copyright (C) 2003 - 2008, Gaisler Research
-- Copyright (C) 2008 - 2010, Aeroflex Gaisler
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-----------------------------------------------------------------------------
-- Package: stdlib
-- File: stdlib.vhd
-- Author: Jiri Gaisler - Gaisler Research
-- Description: Package for common VHDL functions
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- pragma translate_off
use std.textio.all;
-- pragma translate_on
library grlib;
use grlib.version.all;
package stdlib is
constant LIBVHDL_VERSION : integer := grlib_version;
constant LIBVHDL_BUILD : integer := grlib_build;
-- pragma translate_off
constant LIBVHDL_DATE : string := grlib_date;
-- pragma translate_on
constant zero32 : std_logic_vector(31 downto 0) := (others => '0');
constant zero64 : std_logic_vector(63 downto 0) := (others => '0');
constant zero128 : std_logic_vector(127 downto 0) := (others => '0');
constant one32 : std_logic_vector(31 downto 0) := (others => '1');
constant one64 : std_logic_vector(63 downto 0) := (others => '1');
constant one128 : std_logic_vector(127 downto 0) := (others => '1');
type log2arr is array(0 to 512) of integer;
constant log2 : log2arr := (
0,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,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
others => 9);
constant log2x : log2arr := (
0,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,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
others => 9);
function decode(v : std_logic_vector) return std_logic_vector;
function genmux(s,v : std_logic_vector) return std_ulogic;
function xorv(d : std_logic_vector) return std_ulogic;
function orv(d : std_logic_vector) return std_ulogic;
function andv(d : std_logic_vector) return std_ulogic;
function notx(d : std_logic_vector) return boolean;
function notx(d : std_ulogic) return boolean;
function "-" (d : std_logic_vector; i : integer) return std_logic_vector;
function "-" (i : integer; d : std_logic_vector) return std_logic_vector;
function "+" (d : std_logic_vector; i : integer) return std_logic_vector;
function "+" (i : integer; d : std_logic_vector) return std_logic_vector;
function "-" (d : std_logic_vector; i : std_ulogic) return std_logic_vector;
function "+" (d : std_logic_vector; i : std_ulogic) return std_logic_vector;
function "-" (a, b : std_logic_vector) return std_logic_vector;
function "+" (a, b : std_logic_vector) return std_logic_vector;
function "*" (a, b : std_logic_vector) return std_logic_vector;
function unsigned_mul (a, b : std_logic_vector) return std_logic_vector;
function signed_mul (a, b : std_logic_vector) return std_logic_vector;
function mixed_mul (a, b : std_logic_vector; sign : std_logic) return std_logic_vector;
--function ">" (a, b : std_logic_vector) return boolean;
function "<" (i : integer; b : std_logic_vector) return boolean;
function conv_integer(v : std_logic_vector) return integer;
function conv_integer(v : std_logic) return integer;
function conv_std_logic_vector(i : integer; w : integer) return std_logic_vector;
function conv_std_logic_vector_signed(i : integer; w : integer) return std_logic_vector;
function conv_std_logic(b : boolean) return std_ulogic;
-- Reporting and diagnostics
-- pragma translate_off
function tost(v:std_logic_vector) return string;
function tost(v:std_logic) return string;
function tost(i : integer) return string;
function tost_any(s: std_ulogic) return string;
function tost_bits(s: std_logic_vector) return string;
function tost(b: boolean) return string;
function tost(r: real) return string;
procedure print(s : string);
component report_version
generic (msg1, msg2, msg3, msg4 : string := ""; mdel : integer := 4);
end component;
-- pragma translate_on
end;
package body stdlib is
function notx(d : std_logic_vector) return boolean is
variable res : boolean;
begin
res := true;
-- pragma translate_off
res := not is_x(d);
-- pragma translate_on
return (res);
end;
function notx(d : std_ulogic) return boolean is
variable res : boolean;
begin
res := true;
-- pragma translate_off
res := not is_x(d);
-- pragma translate_on
return (res);
end;
-- generic decoder
function decode(v : std_logic_vector) return std_logic_vector is
variable res : std_logic_vector((2**v'length)-1 downto 0);
variable i : integer range res'range;
begin
res := (others => '0'); i := 0;
if notx(v) then i := to_integer(unsigned(v)); end if;
res(i) := '1';
return(res);
end;
-- generic multiplexer
function genmux(s,v : std_logic_vector) return std_ulogic is
variable res : std_logic_vector(v'length-1 downto 0);
variable i : integer range res'range;
begin
res := v; i := 0;
if notx(s) then i := to_integer(unsigned(s)); end if;
return(res(i));
end;
-- vector XOR
function xorv(d : std_logic_vector) return std_ulogic is
variable tmp : std_ulogic;
begin
tmp := '0';
for i in d'range loop tmp := tmp xor d(i); end loop;
return(tmp);
end;
-- vector OR
function orv(d : std_logic_vector) return std_ulogic is
variable tmp : std_ulogic;
begin
tmp := '0';
for i in d'range loop tmp := tmp or d(i); end loop;
return(tmp);
end;
-- vector AND
function andv(d : std_logic_vector) return std_ulogic is
variable tmp : std_ulogic;
begin
tmp := '1';
for i in d'range loop tmp := tmp and d(i); end loop;
return(tmp);
end;
-- unsigned multiplication
function "*" (a, b : std_logic_vector) return std_logic_vector is
variable z : std_logic_vector(a'length+b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
return(std_logic_vector(unsigned(a) * unsigned(b)));
-- pragma translate_off
else
z := (others =>'X'); return(z);
end if;
-- pragma translate_on
end;
-- signed multiplication
function signed_mul (a, b : std_logic_vector) return std_logic_vector is
variable z : std_logic_vector(a'length+b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
return(std_logic_vector(signed(a) * signed(b)));
-- pragma translate_off
else
z := (others =>'X'); return(z);
end if;
-- pragma translate_on
end;
-- unsigned multiplication
function unsigned_mul (a, b : std_logic_vector) return std_logic_vector is
variable z : std_logic_vector(a'length+b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
return(std_logic_vector(unsigned(a) * unsigned(b)));
-- pragma translate_off
else
z := (others =>'X'); return(z);
end if;
-- pragma translate_on
end;
-- signed/unsigned multiplication
function mixed_mul (a, b : std_logic_vector; sign : std_logic) return std_logic_vector is
variable z : std_logic_vector(a'length+b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
if sign = '0' then
return(std_logic_vector(unsigned(a) * unsigned(b)));
else
return(std_logic_vector(signed(a) * signed(b)));
end if;
-- pragma translate_off
else
z := (others =>'X'); return(z);
end if;
-- pragma translate_on
end;
-- unsigned addition
function "+" (a, b : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(a'length-1 downto 0);
variable y : std_logic_vector(b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
return(std_logic_vector(unsigned(a) + unsigned(b)));
-- pragma translate_off
else
x := (others =>'X'); y := (others =>'X');
if (x'length > y'length) then return(x); else return(y); end if;
end if;
-- pragma translate_on
end;
function "+" (i : integer; d : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
begin
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(unsigned(d) + i));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
function "+" (d : std_logic_vector; i : integer) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
begin
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(unsigned(d) + i));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
function "+" (d : std_logic_vector; i : std_ulogic) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
variable y : std_logic_vector(0 downto 0);
begin
y(0) := i;
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(unsigned(d) + unsigned(y)));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
-- unsigned subtraction
function "-" (a, b : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(a'length-1 downto 0);
variable y : std_logic_vector(b'length-1 downto 0);
begin
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
return(std_logic_vector(unsigned(a) - unsigned(b)));
-- pragma translate_off
else
x := (others =>'X'); y := (others =>'X');
if (x'length > y'length) then return(x); else return(y); end if;
end if;
-- pragma translate_on
end;
function "-" (d : std_logic_vector; i : integer) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
begin
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(unsigned(d) - i));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
function "-" (i : integer; d : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
begin
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(i - unsigned(d)));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
function "-" (d : std_logic_vector; i : std_ulogic) return std_logic_vector is
variable x : std_logic_vector(d'length-1 downto 0);
variable y : std_logic_vector(0 downto 0);
begin
y(0) := i;
-- pragma translate_off
if notx(d) then
-- pragma translate_on
return(std_logic_vector(unsigned(d) - unsigned(y)));
-- pragma translate_off
else x := (others =>'X'); return(x);
end if;
-- pragma translate_on
end;
function ">=" (a, b : std_logic_vector) return boolean is
begin
return(unsigned(a) >= unsigned(b));
end;
function "<" (i : integer; b : std_logic_vector) return boolean is
begin
return( i < to_integer(unsigned(b)));
end;
function ">" (a, b : std_logic_vector) return boolean is
begin
return(unsigned(a) > unsigned(b));
end;
function conv_integer(v : std_logic_vector) return integer is
begin
if notx(v) then return(to_integer(unsigned(v)));
else return(0); end if;
end;
function conv_integer(v : std_logic) return integer is
begin
if notx(v) then
if v = '1' then return(1);
else return(0); end if;
else return(0); end if;
end;
function conv_std_logic_vector(i : integer; w : integer) return std_logic_vector is
variable tmp : std_logic_vector(w-1 downto 0);
begin
tmp := std_logic_vector(to_unsigned(i, w));
return(tmp);
end;
function conv_std_logic_vector_signed(i : integer; w : integer) return std_logic_vector is
variable tmp : std_logic_vector(w-1 downto 0);
begin
tmp := std_logic_vector(to_signed(i, w));
return(tmp);
end;
function conv_std_logic(b : boolean) return std_ulogic is
begin
if b then return('1'); else return('0'); end if;
end;
-- pragma translate_off
subtype nibble is std_logic_vector(3 downto 0);
function todec(i:integer) return character is
begin
case i is
when 0 => return('0');
when 1 => return('1');
when 2 => return('2');
when 3 => return('3');
when 4 => return('4');
when 5 => return('5');
when 6 => return('6');
when 7 => return('7');
when 8 => return('8');
when 9 => return('9');
when others => return('0');
end case;
end;
function tohex(n:nibble) return character is
begin
case n is
when "0000" => return('0');
when "0001" => return('1');
when "0010" => return('2');
when "0011" => return('3');
when "0100" => return('4');
when "0101" => return('5');
when "0110" => return('6');
when "0111" => return('7');
when "1000" => return('8');
when "1001" => return('9');
when "1010" => return('a');
when "1011" => return('b');
when "1100" => return('c');
when "1101" => return('d');
when "1110" => return('e');
when "1111" => return('f');
when others => return('X');
end case;
end;
function tost(v:std_logic_vector) return string is
constant vlen : natural := v'length; --'
constant slen : natural := (vlen+3)/4;
variable vv : std_logic_vector(0 to slen*4-1) := (others => '0');
variable s : string(1 to slen);
variable nz : boolean := false;
variable index : integer := -1;
begin
vv(slen*4-vlen to slen*4-1) := v;
for i in 0 to slen-1 loop
if (vv(i*4 to i*4+3) = "0000") and nz and (i /= (slen-1)) then
index := i;
else
nz := false;
s(i+1) := tohex(vv(i*4 to i*4+3));
end if;
end loop;
if ((index +2) = slen) then return(s(slen to slen));
else return(string'("0x") & s(index+2 to slen)); end if; --'
end;
function tost(v:std_logic) return string is
begin
if to_x01(v) = '1' then return("1"); else return("0"); end if;
end;
function tost_any(s: std_ulogic) return string is
begin
case s is
when '1' => return "1";
when '0' => return "0";
when '-' => return "-";
when 'U' => return "U";
when 'X' => return "X";
when 'Z' => return "Z";
when 'H' => return "H";
when 'L' => return "L";
when 'W' => return "W";
end case;
end;
function tost_bits(s: std_logic_vector) return string is
constant len: natural := s'length;
variable str: string(1 to len);
variable i: integer;
begin
i := 1;
for x in s'range loop
str(i to i) := tost_any(s(x));
i := i+1;
end loop;
return str;
end;
function tost(b: boolean) return string is
begin
if b then return "true"; else return "false"; end if;
end tost;
function tost(i : integer) return string is
variable L : line;
variable s, x : string(1 to 128);
variable n, tmp : integer := 0;
begin
tmp := i;
if i < 0 then tmp := -i; end if;
loop
s(128-n) := todec(tmp mod 10);
tmp := tmp / 10;
n := n+1;
if tmp = 0 then exit; end if;
end loop;
x(1 to n) := s(129-n to 128);
if i < 0 then return "-" & x(1 to n); end if;
return(x(1 to n));
end;
function tost(r: real) return string is
variable x: real;
variable i,j: integer;
variable s: string(1 to 30);
variable c: character;
begin
if r = 0.0 then
return "0.0000";
elsif r < 0.0 then
return "-" & tost(-r);
elsif r < 0.001 then
x:=r; i:=0;
while x<1.0 loop x:=x*10.0; i:=i+1; end loop;
return tost(x) & "e-" & tost(i);
elsif r >= 1000000.0 then
x:=10000000.0; i:=6;
while r>=x loop x:=x*10.0; i:=i+1; end loop;
return tost(10.0*r/x) & "e+" & tost(i);
else
i:=0; x:=r+0.00005;
while x >= 10.0 loop x:=x/10.0; i:=i+1; end loop;
j := 1;
while i > -5 loop
if x >= 9.0 then c:='9'; x:=x-9.0;
elsif x >= 8.0 then c:='8'; x:=x-8.0;
elsif x >= 7.0 then c:='7'; x:=x-7.0;
elsif x >= 6.0 then c:='6'; x:=x-6.0;
elsif x >= 5.0 then c:='5'; x:=x-5.0;
elsif x >= 4.0 then c:='4'; x:=x-4.0;
elsif x >= 3.0 then c:='3'; x:=x-3.0;
elsif x >= 2.0 then c:='2'; x:=x-2.0;
elsif x >= 1.0 then c:='1'; x:=x-1.0;
else c:='0';
end if;
s(j) := c;
j:=j+1;
if i=0 then s(j):='.'; j:=j+1; end if;
i:=i-1;
x := x * 10.0;
end loop;
return s(1 to j-1);
end if;
end tost;
procedure print(s : string) is
variable L : line;
begin
L := new string'(s); writeline(output, L);
end;
-- pragma translate_on
end;