aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlibraries/openieee/build_1164.py (renamed from libraries/redist1164/build.py)2
-rwxr-xr-xlibraries/openieee/build_numeric.py1112
-rw-r--r--libraries/openieee/math_real-body.vhdl86
-rw-r--r--libraries/openieee/math_real.vhdl44
-rw-r--r--libraries/openieee/numeric_bit-body.proto180
-rw-r--r--libraries/openieee/numeric_bit.proto24
-rw-r--r--libraries/openieee/numeric_common.proto190
-rw-r--r--libraries/openieee/numeric_std-body.proto275
-rw-r--r--libraries/openieee/numeric_std.proto41
-rw-r--r--libraries/openieee/std_logic_1164-body.proto (renamed from libraries/redist1164/std_logic_1164-body.proto)10
-rw-r--r--libraries/openieee/std_logic_1164-body.v87 (renamed from libraries/redist1164/std_logic_1164-body.v87)8
-rw-r--r--libraries/openieee/std_logic_1164-body.v93 (renamed from libraries/redist1164/std_logic_1164-body.v93)8
-rw-r--r--libraries/openieee/std_logic_1164.v87 (renamed from libraries/redist1164/std_logic_1164.v87)0
-rw-r--r--libraries/openieee/std_logic_1164.v93 (renamed from libraries/redist1164/std_logic_1164.v93)0
-rw-r--r--libraries/openieee/std_logic_1164.vhdl (renamed from libraries/redist1164/std_logic_1164.vhdl)2
-rw-r--r--src/ghdldrv/foreigns.adb38
-rw-r--r--src/ghdldrv/foreigns.ads17
17 files changed, 2021 insertions, 16 deletions
diff --git a/libraries/redist1164/build.py b/libraries/openieee/build_1164.py
index 6255938d8..20dd2dc3e 100755
--- a/libraries/redist1164/build.py
+++ b/libraries/openieee/build_1164.py
@@ -14,7 +14,7 @@
# for more details.
#
# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3. If not see
+# along with GCC; see the file COPYING2. If not see
# <http://www.gnu.org/licenses/>.
import re
diff --git a/libraries/openieee/build_numeric.py b/libraries/openieee/build_numeric.py
new file mode 100755
index 000000000..a8914d0ce
--- /dev/null
+++ b/libraries/openieee/build_numeric.py
@@ -0,0 +1,1112 @@
+#!/usr/bin/env python
+# Generate the body of ieee.numeric_std and numeric_bit from a template.
+# The implementation is based only on the specification and on testing (as
+# the specifications are often ambiguous).
+# The algorithms are very simple: carry ripple adder, restoring division.
+# This file is part of GHDL.
+# Both this file and the outputs of this file are copyrighted.
+# Copyright (C) 2015 Tristan Gingold
+#
+# GHDL 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, or (at your option) any later
+# version.
+#
+# GHDL 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 GCC; see the file COPYING2. If not see
+# <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+
+# My python 'style' and knowledge is basic... Do not hesitate to comment.
+
+binary_funcs = [ "and", "nand", "or", "nor", "xor" ]
+compare_funcs = [ "=", "/=", ">", ">=", "<", "<=" ]
+
+vec_types = ['UNSIGNED', 'SIGNED']
+
+logics = ['bit', 'std']
+logic_types = {'bit' : 'bit', 'std': 'sl_x01' }
+logic_undefs = {'bit' : "'0'", 'std': "'X'" }
+
+logic = 'xx' # Current logic, either bit or std
+
+# Stream to write.
+out=sys.stdout
+
+def w(s):
+ "Write S to the output"
+ out.write(s)
+
+def logic_type():
+ return logic_types[logic]
+
+def logic_undef():
+ return logic_undefs[logic]
+
+def disp_vec_binary(func, typ):
+ "Generate the body of a vector binary logic function"
+ res = """
+ function "{0}" (l, r : {1}) return {1}
+ is
+ subtype res_type is {1} (l'length - 1 downto 0);
+ alias la : res_type is l;
+ alias ra : {1} (r'length - 1 downto 0) is r;
+ variable res : res_type;
+ begin
+ if la'left /= ra'left then
+ assert false
+ report "NUMERIC_STD.""{0}"": arguments are not of the same length"
+ severity failure;
+ res := (others => """ + logic_undef() + """);
+ else
+ for I in res_type'range loop
+ res (I) := la (I) {0} ra (I);
+ end loop;
+ end if;
+ return res;
+ end "{0}";\n"""
+ w (res.format(func, typ))
+
+def disp_non_logical_warning(func):
+ return """
+ assert NO_WARNING
+ report "NUMERIC_STD.""{0}"": non logical value detected"
+ severity warning;""".format(func)
+
+def conv_bit(expr):
+ if logic == 'std':
+ return "sl_to_x01 (" + expr + ")"
+ else:
+ return expr
+
+def extract_bit(name):
+ res = "{0}b := " + conv_bit ("{0}a (i)") + ";"
+ return res.format(name)
+
+def init_carry(func):
+ if func == '+':
+ return """
+ carry := '0';"""
+ else:
+ return """
+ carry := '1';"""
+
+def extract_extend_bit(name,typ):
+ res = """
+ if i > {0}a'left then
+ {0}b := """
+ if typ == 'UNSIGNED':
+ res += "'0';"
+ else:
+ res += "{0} ({0}'left);"
+ res += """
+ else
+ """ + extract_bit(name) + """
+ end if;"""
+ return res.format(name)
+
+def disp_vec_vec_binary(func, typ):
+ "Generate vector binary function body"
+ res = """
+ function "{0}" (l : {1}; r : {1}) return {1}
+ is
+ constant lft : integer := MAX (l'length, r'length) - 1;
+ subtype res_type is {1} (lft downto 0);
+ alias la : {1} (l'length - 1 downto 0) is l;
+ alias ra : {1} (r'length - 1 downto 0) is r;
+ variable res : res_type;
+ variable lb, rb, carry : """ + logic_type () + """;
+ begin
+ if la'left < 0 or ra'left < 0 then
+ return null_{1};
+ end if;"""
+
+ res += init_carry(func)
+
+ res += """
+ for i in 0 to lft loop"""
+ res += extract_extend_bit('l', typ)
+ res += extract_extend_bit('r', typ)
+
+ if logic == 'std':
+ res += """
+ if lb = 'X' or rb = 'X' then""" + \
+ disp_non_logical_warning(func) + """
+ res := (others => 'X');
+ exit;
+ end if;"""
+ if func == '-':
+ res += """
+ rb := not rb;"""
+ res += """
+ res (i) := compute_sum (carry, rb, lb);
+ carry := compute_carry (carry, rb, lb);
+ end loop;
+ return res;
+ end "{0}";
+"""
+ w (res.format (func, typ))
+
+def declare_int_var(name, typ):
+ res = """
+ variable {0}1, {0}2 : {1};
+ variable {0}d : nat1;""";
+ if typ == "INTEGER":
+ res += """
+ constant {0}msb : nat1 := boolean'pos({0} < 0);"""
+ return res.format(name, typ)
+
+def init_int_var(name, typ):
+ return """
+ {0}1 := {0};""".format(name);
+
+def extract_int_lsb(name, typ):
+ res = """
+ {0}2 := {0}1 / 2;"""
+ if typ == "INTEGER":
+ res += """
+ if {0}1 < 0 then
+ {0}d := 2 * {0}2 - {0}1;
+ {0}1 := {0}2 - {0}d;
+ else
+ {0}d := {0}1 - 2 * {0}2;
+ {0}1 := {0}2;
+ end if;"""
+ else:
+ res += """
+ {0}d := {0}1 - 2 * {0}2;
+ {0}1 := {0}2;"""
+ res += """
+ {0}b := nat1_to_01 ({0}d);"""
+ return res.format(name,typ)
+
+def check_int_truncated(func, name, typ):
+ if typ == "INTEGER":
+ v = "-{0}msb".format(name)
+ else:
+ v = "0"
+ return """
+ if {1}1 /= {2} then
+ assert NO_WARNING
+ report "NUMERIC_STD.""{0}"": vector is truncated"
+ severity warning;
+ end if;""".format(func, name, v)
+
+def create_vec_int_dict(func, left, right):
+ if left in vec_types:
+ dic = {'vtype': left,
+ 'itype': right,
+ 'vparam': 'l',
+ 'iparam': 'r'}
+ else:
+ dic = {'vtype': right,
+ 'itype': left,
+ 'vparam': 'r',
+ 'iparam': 'l'}
+ dic.update({'ltype': left,
+ 'rtype': right,
+ 'func': func,
+ 'logic': logic_type()})
+ return dic
+
+def disp_vec_int_binary(func, left, right):
+ "Generate vector binary function body"
+ dic = create_vec_int_dict(func, left, right)
+ res = """
+ function "{func}" (l : {ltype}; r : {rtype}) return {vtype}
+ is
+ subtype res_type is {vtype} ({vparam}'length - 1 downto 0);
+ alias {vparam}a : res_type is {vparam};""" + \
+ declare_int_var (dic["iparam"], dic["itype"]) + """
+ variable res : res_type;
+ variable lb, rb, carry : {logic};
+ begin
+ if res'length < 0 then
+ return null_{vtype};
+ end if;"""
+
+ # Initialize carry. For subtraction, use 2-complement.
+ res += init_carry(func)
+
+ res += init_int_var(dic['iparam'], dic['itype']) + """
+ for i in res'reverse_range loop
+ """ + extract_bit(dic['vparam']) + "\n" + \
+ extract_int_lsb(dic['iparam'], dic['itype']);
+
+ if logic == 'std':
+ res += """
+ if {vparam}b = 'X' then""" + \
+ disp_non_logical_warning(func) + """
+ res := (others => 'X');
+ {iparam}1 := 0;
+ exit;
+ end if;"""
+
+ # 2-complement for subtraction
+ if func == '-':
+ res += """
+ rb := not rb;"""
+
+ res += """
+ res (i) := compute_sum (carry, rb, lb);
+ carry := compute_carry (carry, rb, lb);
+ end loop;""" + \
+ check_int_truncated(func, dic['iparam'], dic['itype']) + """
+ return res;
+ end "{func}";\n"""
+ w(res.format (**dic))
+
+def disp_vec_int_gcompare(func, left, right):
+ "Generate comparison function"
+ dic = create_vec_int_dict(func, left, right)
+ res = """
+ function {func} (l : {ltype}; r : {rtype}) return compare_type
+ is
+ subtype res_type is {vtype} ({vparam}'length - 1 downto 0);
+ alias la : res_type is l;""" + \
+ declare_int_var (dic['iparam'], dic['itype']) + """
+ variable lb, rb : {logic};
+ variable res : compare_type;
+ begin
+ res := compare_eq;""";
+
+ res += init_int_var(dic['iparam'], dic['itype']) + """
+ for i in {vparam}a'reverse_range loop
+ """ + extract_bit (dic['vparam']) + \
+ extract_int_lsb("r", right)
+
+ if logic == 'std':
+ res += """
+ if {vparam}b = 'X' then
+ return compare_unknown;
+ end if;"""
+
+ res += """
+ if lb = '1' and rb = '0' then
+ res := compare_gt;
+ elsif lb = '0' and rb = '1' then
+ res := compare_lt;
+ end if;
+ end loop;"""
+ if func == "ucompare":
+ res += """
+ if r1 /= 0 then
+ res := compare_lt;
+ end if;"""
+ else:
+ res += """
+ if """ + conv_bit ("l (l'left)") + """ = '1' then
+ if r >= 0 then
+ res := compare_lt;
+ end if;
+ else
+ if r < 0 then
+ res := compare_gt;
+ end if;
+ end if;"""
+ res += """
+ return res;
+ end {func};
+"""
+ w(res.format (**dic))
+
+def disp_vec_int_compare(func, left, right):
+ "Generate comparison function"
+ dic = create_vec_int_dict(func, left, right)
+ res = """
+ function "{func}" (l : {ltype}; r : {rtype}) return boolean
+ is
+ subtype res_type is {vtype} ({vparam}'length - 1 downto 0);
+ alias {vparam}a : res_type is {vparam};""" + \
+ declare_int_var (dic['iparam'], dic['itype']) + """
+ variable res : compare_type;
+ begin
+ if {vparam}'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.""{func}"": null argument, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+
+ res := """
+
+ if left == "SIGNED" or right == "SIGNED":
+ res += "scompare"
+ else:
+ res += "ucompare"
+ if left in vec_types:
+ res += " (l, r);"
+ else:
+ res += " (r, l);"
+ if logic == 'std':
+ res += """
+ if res = compare_unknown then""" + \
+ disp_non_logical_warning(func) + """
+ return false;
+ end if;"""
+
+ if left in vec_types:
+ res += """
+ return res {func} compare_eq;"""
+ else:
+ res += """
+ return compare_eq {func} res;"""
+ res += """
+ end "{func}";
+"""
+ w(res.format (**dic))
+
+def disp_vec_vec_gcompare(func, typ):
+ "Generate comparison function"
+ res = """
+ function {func} (l : {typ}; r : {typ}) return compare_type
+ is
+ constant sz : integer := MAX (l'length, r'length) - 1;
+ alias la : {typ} (l'length - 1 downto 0) is l;
+ alias ra : {typ} (r'length - 1 downto 0) is r;
+ variable lb, rb : {logic};
+ variable res : compare_type;
+ begin"""
+ if typ == 'SIGNED':
+ res += """
+ -- Consider sign bit as S * -(2**N).
+ lb := """ + conv_bit ("la (la'left)") + """;
+ rb := """ + conv_bit ("ra (ra'left)") + """;
+ if lb = '1' and rb = '0' then
+ return compare_lt;
+ elsif lb = '0' and rb = '1' then
+ return compare_gt;
+ else
+ res := compare_eq;
+ end if;"""
+ else:
+ res += """
+ res := compare_eq;"""
+ if typ == 'SIGNED':
+ res += """
+ for i in 0 to sz - 1 loop"""
+ else:
+ res += """
+ for i in 0 to sz loop"""
+ res += extract_extend_bit('l', typ)
+ res += extract_extend_bit('r', typ)
+ if logic == 'std':
+ res += """
+ if lb = 'X' or rb = 'X' then
+ return compare_unknown;
+ end if;"""
+
+ res += """
+ if lb = '1' and rb = '0' then
+ res := compare_gt;
+ elsif lb = '0' and rb = '1' then
+ res := compare_lt;
+ end if;
+ end loop;
+
+ return res;
+ end {func};\n"""
+ w(res.format (func=func, typ=typ, logic=logic_type()))
+
+def disp_vec_vec_compare(func, typ):
+ "Generate comparison function"
+ res = """
+ function "{func}" (l : {typ}; r : {typ}) return boolean
+ is
+ variable res : compare_type;
+ begin
+ if l'length = 0 or r'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.""{func}"": null argument, returning FALSE"
+ severity warning;
+ return false;
+ end if;
+
+ res := """
+ if typ == "SIGNED":
+ res += "scompare"
+ else:
+ res += "ucompare"
+ res += """ (l, r);"""
+
+ if logic == 'std':
+ res += """
+ if res = compare_unknown then""" + \
+ disp_non_logical_warning(func) + """
+ return false;
+ end if;"""
+
+ res += """
+ return res {func} compare_eq;
+ end "{func}";\n"""
+ w(res.format (func=func, typ=typ))
+
+def disp_vec_not(typ):
+ "Generate vector binary function body"
+ w("""
+ function "not" (l : {0}) return {0}
+ is
+ subtype res_type is {0} (l'length - 1 downto 0);
+ alias la : res_type is l;
+ variable res : res_type;
+ begin
+ for I in res_type'range loop
+ res (I) := not la (I);
+ end loop;
+ return res;
+ end "not";\n""".format(typ))
+
+def disp_resize(typ):
+ res = """
+ function resize (ARG : {0}; NEW_SIZE: natural) return {0}
+ is
+ alias arg1 : {0} (ARG'length - 1 downto 0) is arg;
+ variable res : {0} (new_size - 1 downto 0) := (others => '0');
+ begin
+ if new_size = 0 then
+ return null_{0};
+ end if;
+ if arg1'length = 0 then
+ return res;
+ end if;
+ if arg1'length > new_size then
+ -- Reduction."""
+ if typ == 'SIGNED':
+ res += """
+ res (res'left) := arg1 (arg1'left);
+ res (res'left - 1 downto 0) := arg1 (res'left - 1 downto 0);"""
+ else:
+ res += """
+ res := arg1 (res'range);"""
+ res += """
+ else
+ -- Expansion
+ res (arg1'range) := arg1;"""
+ if typ == 'SIGNED':
+ res += """
+ res (res'left downto arg1'length) := (others => arg1 (arg1'left));"""
+ res += """
+ end if;
+ return res;
+ end resize;\n"""
+ w(res.format(typ))
+
+def disp_shift(name, typ, dir):
+ res = """
+ function {0} (ARG : {1}; COUNT: NATURAL) return {1}
+ is
+ subtype res_type is {1} (ARG'length - 1 downto 0);
+ alias arg1 : res_type is arg;
+ variable res : res_type := (others => """
+ if typ == 'SIGNED' and dir == 'right':
+ res += "arg1 (arg1'left)"
+ else:
+ res += "'0'"
+ res += """);
+ begin
+ if res'length = 0 then
+ return null_{1};
+ end if;
+ if count <= arg1'left then"""
+ if dir == 'left':
+ res += """
+ res (res'left downto count) := arg1 (arg1'left - count downto 0);"""
+ else:
+ res += """
+ res (res'left - count downto 0) := arg1 (arg1'left downto count);"""
+ res += """
+ end if;
+ return res;
+ end {0};\n"""
+ w(res.format(name, typ))
+
+def disp_rotate(name, typ, dir):
+ res = """
+ function {0} (ARG : {1}; COUNT: NATURAL) return {1}
+ is
+ subtype res_type is {1} (ARG'length - 1 downto 0);
+ alias arg1 : res_type is arg;
+ variable res : res_type := (others => '0');
+ variable cnt : natural;
+ begin
+ if res'length = 0 then
+ return null_{1};
+ end if;
+ cnt := count rem res'length;"""
+ if dir == 'left':
+ res += """
+ res (res'left downto cnt) := arg1 (res'left - cnt downto 0);
+ res (cnt - 1 downto 0) := arg1 (res'left downto res'left - cnt + 1);"""
+ else:
+ res += """
+ res (res'left - cnt downto 0) := arg1 (res'left downto cnt);
+ res (res'left downto res'left - cnt + 1) := arg1 (cnt - 1 downto 0);"""
+ res += """
+ return res;
+ end {0};\n"""
+ w(res.format(name, typ))
+
+def disp_vec_vec_mul(func, typ):
+ res = """
+ function "{0}" (L : {1}; R : {1}) return {1}
+ is
+ alias la : {1} (L'Length - 1 downto 0) is l;
+ alias ra : {1} (R'Length - 1 downto 0) is r;
+ variable res : {1} (L'length + R'Length -1 downto 0) := (others => '0');
+ variable rb, lb, vb, carry : """ + logic_type() + """;
+ begin
+ if la'length = 0 or ra'length = 0 then
+ return null_{1};
+ end if;
+ -- Shift and add L.
+ for i in natural range 0 to ra'left """
+ if typ == 'SIGNED':
+ res += "- 1 "
+ res += """loop
+ """ + extract_bit ('r') + """
+ if rb = '1' then
+ -- Compute res := res + shift_left (l, i).
+ carry := '0';
+ for j in la'reverse_range loop
+ lb := la (j);
+ vb := res (i + j);
+ res (i + j) := compute_sum (carry, vb, lb);
+ carry := compute_carry (carry, vb, lb);
+ end loop;"""
+ if typ == 'UNSIGNED':
+ res += """
+ -- Propagate carry.
+ for j in i + la'length to res'left loop
+ exit when carry = '0';
+ vb := res (j);
+ res (j) := carry xor vb;
+ carry := carry and vb;
+ end loop;"""
+ else:
+ res += """
+ -- Sign extend and propagate carry.
+ lb := la (la'left);
+ for j in i + l'length to res'left loop
+ vb := res (j);
+ res (j) := compute_sum (carry, vb, lb);
+ carry := compute_carry (carry, vb, lb);
+ end loop;"""
+ if logic == 'std':
+ res += """
+ elsif rb = 'X' then""" + \
+ disp_non_logical_warning (func)
+ res += """
+ end if;
+ end loop;"""
+ if typ == 'SIGNED':
+ res += """
+ if ra (ra'left) = '1' then
+ -- R is a negative number. It is considered as:
+ -- -2**n + (Rn-1 Rn-2 ... R0).
+ -- Compute res := res - 2**n * l.
+ carry := '1';
+ for i in la'reverse_range loop
+ vb := res (ra'length - 1 + i);
+ lb := not la (i);
+ res (ra'length - 1+ i) := compute_sum (carry, vb, lb);
+ carry := compute_carry (carry, vb, lb);
+ end loop;
+ vb := res (res'left);
+ lb := not la (la'left);
+ res (res'left) := compute_sum (carry, vb, lb);
+ end if;"""
+ res += """
+ return res;
+ end "{0}";\n"""
+ w(res.format(func,typ))
+
+def disp_vec_int_mul(left, right):
+ res = """
+ function "*" (L : {0}; R : {1}) return {0}
+ is
+ constant size : natural := l'length;
+ begin
+ if size = 0 then
+ return null_{0};
+ end if;
+ return l * to_{0} (r, size);
+ end "*";\n"""
+ w (res.format(left,right))
+
+def disp_int_vec_mul(left, right):
+ res = """
+ function "*" (L : {0}; R : {1}) return {1}
+ is
+ constant size : natural := r'length;
+ begin
+ if size = 0 then
+ return null_{1};
+ end if;
+ return r * to_{1} (l, size);
+ end "*";\n"""
+ w (res.format(left,right))
+
+def disp_neg(func):
+ res = """
+ function "{func}" (ARG : SIGNED) return SIGNED
+ is
+ subtype arg_type is SIGNED (ARG'length - 1 downto 0);
+ alias arga : arg_type is arg;
+ variable res : arg_type;
+ variable carry, a : """ + logic_type() + """;
+ begin
+ if arga'length = 0 then
+ return null_signed;
+ end if;"""
+ if logic == 'std':
+ res += """
+ if has_0x (arga) = 'X' then""" + \
+ disp_non_logical_warning("-") + """
+ return arg_type'(others => 'X');
+ end if;"""
+ if func == 'abs':
+ res += """
+ if arga (arga'left) = '0' then
+ return arga;
+ end if;"""
+ res += """
+ carry := '1';
+ for i in arga'reverse_range loop
+ a := not arga (i);
+ res (i) := carry xor a;
+ carry := carry and a;
+ end loop;
+ return res;
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+def disp_has_0x(typ):
+ res = """
+ function has_0x (a : {0}) return {1}
+ is
+ variable res : {1} := '0';
+ begin
+ for i in a'range loop"""
+ if logic == 'std':
+ res += """
+ if a (i) = 'X' then
+ return 'X';
+ end if;"""
+ res += """
+ res := res or a (i);
+ end loop;
+ return res;
+ end has_0x;\n"""
+ w(res.format(typ, logic_type()))
+
+def disp_size():
+ w("""
+ function size_unsigned (n : natural) return natural
+ is
+ -- At least one bit (even for 0).
+ variable res : natural := 1;
+ variable n1 : natural := n;
+ begin
+ while n1 > 1 loop
+ res := res + 1;
+ n1 := n1 / 2;
+ end loop;
+ return res;
+ end size_unsigned;\n""")
+
+ w("""
+ function size_signed (n : integer) return natural
+ is
+ variable res : natural := 1;
+ variable n1 : natural;
+ begin
+ if n >= 0 then
+ n1 := n;
+ else
+ -- Use /N = -X -1 = -(X + 1) (No overflow).
+ n1 := -(n + 1);
+ end if;
+ while n1 /= 0 loop
+ res := res + 1;
+ n1 := n1 / 2;
+ end loop;
+ return res;
+ end size_signed;\n""")
+
+def disp_divmod():
+ w("""
+ -- All index range are normalized (N downto 0).
+ -- NUM and QUOT have the same range.
+ -- DEM and REMAIN have the same range.
+ -- No 'X'.
+ procedure divmod (num, dem : UNSIGNED; quot, remain : out UNSIGNED)
+ is
+ variable reg : unsigned (dem'left + 1 downto 0) := (others => '0');
+ variable sub : unsigned (dem'range) := (others => '0');
+ variable carry, d : """ + logic_type () + """;
+ begin
+ for i in num'range loop
+ -- Shift
+ reg (reg'left downto 1) := reg (reg'left - 1 downto 0);
+ reg (0) := num (i);
+ -- Substract
+ carry := '1';
+ for j in dem'reverse_range loop
+ d := not dem (j);
+ sub (j) := compute_sum (carry, reg (j), d);
+ carry := compute_carry (carry, reg (j), d);
+ end loop;
+ carry := compute_carry (carry, reg (reg'left), '1');
+ -- Test
+ if carry = '0' then
+ -- Greater than
+ quot (i) := '0';
+ else
+ quot (i) := '1';
+ reg (reg'left) := '0';
+ reg (sub'range) := sub;
+ end if;
+ end loop;
+ remain := reg (dem'range);
+ end divmod;
+ """)
+
+def disp_vec_vec_udiv(func):
+ res = """
+ function "{func}" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED
+ is
+ subtype l_type is UNSIGNED (L'length - 1 downto 0);
+ subtype r_type is UNSIGNED (R'length - 1 downto 0);
+ alias la : l_type is l;
+ alias ra : r_type is r;
+ variable quot : l_type;
+ variable rema : r_type;
+ variable r0 : """ + logic_type() + """ := has_0x (r);
+ begin
+ if la'length = 0 or ra'length = 0 then
+ return null_unsigned;
+ end if;"""
+ if logic == 'std':
+ res += """
+ if has_0x (l) = 'X' or r0 = 'X' then""" + \
+ disp_non_logical_warning ('/') + """
+ return l_type'(others => 'X');
+ end if;"""
+ res += """
+ assert r0 /= '0'
+ report "NUMERIC_STD.""{func}"": division by 0"
+ severity error;
+ divmod (la, ra, quot, rema);"""
+ if func == '/':
+ res += """
+ return quot;"""
+ else:
+ res += """
+ return rema;"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+def disp_vec_int_udiv(func):
+ res = """
+ function "{func}" (L : UNSIGNED; R : NATURAL) return UNSIGNED
+ is
+ constant r_size : natural := size_unsigned (r);
+ begin
+ if l'length = 0 then
+ return null_unsigned;
+ end if;"""
+ if func in ['mod', 'rem']:
+ res += """
+ return resize (l {func} to_unsigned (r, r_size), l'length);"""
+ else:
+ res += """
+ return l {func} to_unsigned (r, r_size);"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+ res = """
+ function "{func}" (L : NATURAL; R : UNSIGNED) return UNSIGNED
+ is
+ constant l_size : natural := size_unsigned (l);
+ begin
+ if r'length = 0 then
+ return null_unsigned;
+ end if;"""
+ if func == '/':
+ res += """
+ return resize (to_unsigned (l, l_size) {func} r, r'length);"""
+ else:
+ res += """
+ return to_unsigned (l, l_size) {func} r;"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+def disp_vec_vec_sdiv(func):
+ res = """
+ function "{func}" (L : SIGNED; R : SIGNED) return SIGNED
+ is
+ subtype l_type is SIGNED (L'length - 1 downto 0);
+ subtype r_type is SIGNED (R'length - 1 downto 0);
+ alias la : l_type is l;
+ alias ra : r_type is r;
+ subtype l_utype is UNSIGNED (l_type'range);
+ subtype r_utype is UNSIGNED (r_type'range);
+ variable lu : l_utype;
+ variable ru : r_utype;
+ variable quot : l_utype;
+ variable rema : r_utype;
+ variable r0 : """ + logic_type() + """ := has_0x (r);
+ begin
+ if la'length = 0 or ra'length = 0 then
+ return null_signed;
+ end if;"""
+ if logic == 'std':
+ res += """
+ if has_0x (l) = 'X' or r0 = 'X' then""" + \
+ disp_non_logical_warning (func) + """
+ return l_type'(others => 'X');
+ end if;"""
+ res += """
+ assert r0 /= '0'
+ report "NUMERIC_STD.""{func}"": division by 0"
+ severity error;"""
+ res += """
+ if la (la'left) = '1' then
+ lu := unsigned (-la);
+ else
+ lu := unsigned (la);
+ end if;
+ if ra (ra'left) = '1' then
+ ru := unsigned (-ra);
+ else
+ ru := unsigned (ra);
+ end if;
+ divmod (lu, ru, quot, rema);"""
+ if func == '/':
+ res += """
+ if (ra (ra'left) xor la (la'left)) = '1' then
+ return -signed (quot);
+ else
+ return signed (quot);
+ end if;"""
+ elif func == 'rem':
+ res += """
+ -- Result of rem has the sign of the dividend.
+ if la (la'left) = '1' then
+ return -signed (rema);
+ else
+ return signed (rema);
+ end if;"""
+ elif func == 'mod':
+ res += """
+ -- Result of mod has the sign of the divisor.
+ if rema = r_utype'(others => '0') then
+ -- If the remainder is 0, then the modulus is 0.
+ return signed (rema);
+ else
+ if ra (ra'left) = '1' then
+ if la (la'left) = '1' then
+ return -signed (rema);
+ else
+ return ra + signed (rema);
+ end if;
+ else
+ if la (la'left) = '1' then
+ return ra - signed (rema);
+ else
+ return signed (rema);
+ end if;
+ end if;
+ end if;"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+def disp_vec_int_sdiv(func):
+ res = """
+ function "{func}" (L : SIGNED; R : INTEGER) return SIGNED
+ is
+ constant r_size : natural := size_signed (r);
+ begin
+ if l'length = 0 then
+ return null_signed;
+ end if;"""
+ if func == '/':
+ res += """
+ return l {func} to_signed (r, r_size);"""
+ else:
+ res += """
+ return resize (l {func} to_signed (r, r_size), l'length);"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+ res = """
+ function "{func}" (L : INTEGER; R : SIGNED) return SIGNED
+ is
+ constant l_size : natural := size_signed (l);
+ begin
+ if r'length = 0 then
+ return null_signed;
+ end if;"""
+ if func == '/':
+ res += """
+ return resize (to_signed (l, max (l_size, r'length)) {func} r, r'length);"""
+ else:
+ res += """
+ return to_signed (l, l_size) {func} r;"""
+ res += """
+ end "{func}";\n"""
+ w(res.format(func=func))
+
+def disp_all_log_funcs():
+ "Generate all function bodies for logic operators"
+ for t in vec_types:
+ disp_resize(t)
+ for v in vec_types:
+ disp_vec_not(v)
+ for f in binary_funcs:
+ for v in vec_types:
+ disp_vec_binary(f, v)
+ disp_vec_vec_gcompare("ucompare", "UNSIGNED")
+ disp_vec_vec_gcompare("scompare", "SIGNED")
+ disp_vec_int_gcompare("ucompare", "UNSIGNED", "NATURAL")
+ disp_vec_int_gcompare("scompare", "SIGNED", "INTEGER")
+ for f in compare_funcs:
+ disp_vec_vec_compare(f, "UNSIGNED")
+ disp_vec_vec_compare(f, "SIGNED")
+ disp_vec_int_compare(f, "UNSIGNED", "NATURAL")
+ disp_vec_int_compare(f, "NATURAL", "UNSIGNED")
+ disp_vec_int_compare(f, "SIGNED", "INTEGER")
+ disp_vec_int_compare(f, "INTEGER", "SIGNED")
+ for t in vec_types:
+ for d in ['left', 'right']:
+ disp_shift('shift_' + d, t, d);
+ for d in ['left', 'right']:
+ disp_rotate('rotate_' + d, t, d);
+
+def disp_match(typ):
+ res = """
+ function std_match (l, r : {0}) return boolean
+ is
+ alias la : {0} (l'length downto 1) is l;
+ alias ra : {0} (r'length downto 1) is r;
+ begin
+ if la'left = 0 or ra'left = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: null argument, returning false"
+ severity warning;
+ return false;
+ elsif la'left /= ra'left then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: args length mismatch, returning false"
+ severity warning;
+ return false;
+ else
+ for i in la'range loop
+ if not match_table (la (i), ra (i)) then
+ return false;
+ end if;
+ end loop;
+ return true;
+ end if;
+ end std_match;\n"""
+ w(res.format(typ))
+
+
+def disp_all_match_funcs():
+ disp_match('std_ulogic_vector');
+ disp_match('std_logic_vector');
+ disp_match('UNSIGNED');
+ disp_match('SIGNED');
+
+def disp_all_arith_funcs():
+ "Generate all function bodies for logic operators"
+ for op in ['+', '-']:
+ disp_vec_vec_binary(op, "UNSIGNED")
+ disp_vec_vec_binary(op, "SIGNED")
+ disp_vec_int_binary(op, "UNSIGNED", "NATURAL")
+ disp_vec_int_binary(op, "NATURAL", "UNSIGNED")
+ disp_vec_int_binary(op, "SIGNED", "INTEGER")
+ disp_vec_int_binary(op, "INTEGER", "SIGNED")
+ disp_vec_vec_mul('*', 'UNSIGNED')
+ disp_vec_vec_mul('*', 'SIGNED')
+ disp_vec_int_mul('UNSIGNED', 'NATURAL')
+ disp_vec_int_mul('SIGNED', 'INTEGER')
+ disp_int_vec_mul('NATURAL', 'UNSIGNED')
+ disp_int_vec_mul('INTEGER', 'SIGNED')
+ disp_has_0x('UNSIGNED')
+ disp_divmod()
+ disp_size()
+ disp_vec_vec_udiv('/')
+ disp_vec_int_udiv('/')
+ disp_vec_vec_udiv('rem')
+ disp_vec_int_udiv('rem')
+ disp_vec_vec_udiv('mod')
+ disp_vec_int_udiv('mod')
+ disp_has_0x('SIGNED')
+ disp_neg("-")
+ disp_neg("abs")
+ disp_vec_vec_sdiv('/')
+ disp_vec_int_sdiv('/')
+ disp_vec_vec_sdiv('rem')
+ disp_vec_int_sdiv('rem')
+ disp_vec_vec_sdiv('mod')
+ disp_vec_int_sdiv('mod')
+
+# Patterns to replace
+pats = {' @LOG\n' : disp_all_log_funcs,
+ ' @ARITH\n' : disp_all_arith_funcs,
+ ' @MATCH\n' : disp_all_match_funcs }
+
+spec_file='numeric_std.vhdl'
+#proto_file='numeric_std-body.proto'
+
+def gen_body(proto_file):
+ w('-- This -*- vhdl -*- file was generated from ' + proto_file + '\n')
+ for line in open(proto_file):
+ if line in pats:
+ pats[line]()
+ continue
+ w(line)
+
+# Copy spec
+for log in logics:
+ for std in ['87', '93']:
+ out=open('numeric_' + log + '.v' + std, 'w')
+ for line in open('numeric_' + log + '.proto'):
+ if line == ' @COMMON\n':
+ for lcom in open('numeric_common.proto'):
+ if lcom[0:2] == '--':
+ pass
+ elif std == '87' and '"xnor"' in lcom:
+ w("--" + lcom[2:])
+ else:
+ w(lcom)
+ else:
+ w(line)
+ out.close()
+
+# Generate bodies
+for l in logics:
+ logic = l
+ out=open('numeric_{0}-body.v87'.format(l), 'w')
+ gen_body('numeric_{0}-body.proto'.format(l))
+ out.close()
+
+binary_funcs.append("xnor")
+for l in logics:
+ logic = l
+ out=open('numeric_{0}-body.v93'.format(l), 'w')
+ gen_body('numeric_{0}-body.proto'.format(l))
+ out.close()
diff --git a/libraries/openieee/math_real-body.vhdl b/libraries/openieee/math_real-body.vhdl
new file mode 100644
index 000000000..1d7a154af
--- /dev/null
+++ b/libraries/openieee/math_real-body.vhdl
@@ -0,0 +1,86 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.2 math_real package body.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+package body MATH_REAL is
+ function SIGN (X : REAL) return REAL is
+ begin
+ if X > 0.0 then
+ return 1.0;
+ elsif X < 0.0 then
+ return -1.0;
+ else
+ return 0.0;
+ end if;
+ end SIGN;
+
+ function CEIL (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end CEIL;
+
+ function FLOOR (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end FLOOR;
+
+ function ROUND (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end ROUND;
+
+ function TRUNC (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end TRUNC;
+
+ procedure UNIFORM (SEED1, SEED2 : inout POSITIVE; X : out REAL)
+ is
+ variable z, k : Integer;
+ begin
+ k := seed1 / 53668;
+ seed1 := 40014 * (seed1 - k * 53668) - k * 12211;
+ if seed1 < 0 then
+ seed1 := seed1 + 2147483563;
+ end if;
+
+ k := seed2 / 52774;
+ seed2 := 40692 * (seed2 - k * 52774) - k * 3791;
+ if seed2 < 0 then
+ seed2 := seed2 + 2147483399;
+ end if;
+
+ z := seed1 - seed2;
+ if z < 1 then
+ z := z + 2147483562;
+ end if;
+
+ x := real (z) * 4.656613e-10;
+ end UNIFORM;
+
+ function SIN (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end SIN;
+
+ function COS (X : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end COS;
+
+
+end MATH_REAL;
diff --git a/libraries/openieee/math_real.vhdl b/libraries/openieee/math_real.vhdl
new file mode 100644
index 000000000..b2814f534
--- /dev/null
+++ b/libraries/openieee/math_real.vhdl
@@ -0,0 +1,44 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.2 math_real package.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+package MATH_REAL is
+ constant math_pi : real := 3.14159_26535_89793_23846;
+ function SIGN (X : REAL) return REAL;
+
+ function CEIL (X : REAL) return REAL;
+ attribute foreign of ceil : function is "VHPIDIRECT ceil";
+
+ function FLOOR (X : REAL) return REAL;
+ attribute foreign of floor : function is "VHPIDIRECT floor";
+
+ function ROUND (X : REAL) return REAL;
+ attribute foreign of round : function is "VHPIDIRECT round";
+
+ function TRUNC (X : REAL) return REAL;
+ attribute foreign of trunc : function is "VHPIDIRECT trunc";
+
+ procedure UNIFORM (SEED1, SEED2 : inout POSITIVE; X : out REAL);
+ -- Algorithm from: Pierre L'Ecuyer, CACM June 1988 Volume 31 Number 6
+ -- page 747 figure 3.
+
+ function SIN (X : REAL) return REAL;
+ attribute foreign of SIN : function is "VHPIDIRECT sin";
+
+ function COS (X : REAL) return REAL;
+ attribute foreign of COS : function is "VHPIDIRECT cos";
+end MATH_REAL;
diff --git a/libraries/openieee/numeric_bit-body.proto b/libraries/openieee/numeric_bit-body.proto
new file mode 100644
index 000000000..715f9f573
--- /dev/null
+++ b/libraries/openieee/numeric_bit-body.proto
@@ -0,0 +1,180 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.3 compliant numeric bit package body.
+-- The implementation is based only on the specifications.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+package body NUMERIC_BIT is
+ constant NO_WARNING : Boolean := False;
+
+ constant null_unsigned : unsigned (0 downto 1) := (others => '0');
+ constant null_signed : signed (0 downto 1) := (others => '0');
+
+ subtype nat1 is natural range 0 to 1;
+
+ type nat1_to_sl_type is array (nat1) of bit;
+ constant nat1_to_01 : nat1_to_sl_type := (0 => '0', 1 => '1');
+
+ subtype sl_01 is bit;
+
+ type carry_array is array (sl_01, sl_01, sl_01) of sl_01;
+ constant compute_carry : carry_array :=
+ ('0' => ('0' => ('0' => '0', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')),
+ '1' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '1')));
+ constant compute_sum : carry_array :=
+ ('0' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '0')),
+ '1' => ('0' => ('0' => '1', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')));
+
+ type compare_type is (compare_unknown,
+ compare_lt,
+ compare_eq,
+ compare_gt);
+
+ function MAX (L, R : natural) return natural is
+ begin
+ if L > R then
+ return L;
+ else
+ return R;
+ end if;
+ end MAX;
+
+ function TO_INTEGER (ARG : UNSIGNED) return NATURAL
+ is
+ variable res : natural := 0;
+ begin
+ if arg'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_INTEGER: null array detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+
+ for i in arg'range loop
+ res := res + res;
+ if arg (i) = '1' then
+ res := res + 1;
+ end if;
+ end loop;
+
+ return res;
+ end TO_INTEGER;
+
+ function TO_INTEGER (ARG : SIGNED) return INTEGER
+ is
+ alias argn : SIGNED (ARG'Length -1 downto 0) is arg;
+ variable res : integer := 0;
+ variable b : bit;
+ begin
+ if argn'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_INTEGER: null array detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if argn (argn'left) = '1' then
+ -- Negative value
+ b := '0';
+ else
+ b := '1';
+ end if;
+
+ for i in argn'range loop
+ res := res + res;
+ if argn (i) = b then
+ res := res + 1;
+ end if;
+ end loop;
+
+ if b = '0' then
+ -- Avoid overflow.
+ res := -res - 1;
+ end if;
+
+ return res;
+ end TO_INTEGER;
+
+ function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED
+ is
+ variable res : UNSIGNED (SIZE - 1 downto 0);
+ variable a : natural := arg;
+ variable d : nat1;
+ begin
+ if size = 0 then
+ return null_unsigned;
+ end if;
+ for i in res'reverse_range loop
+ d := a rem 2;
+ res (i) := nat1_to_01 (d);
+ a := a / 2;
+ end loop;
+ if a /= 0 then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_UNSIGNED: vector is truncated"
+ severity warning;
+ end if;
+ return res;
+ end TO_UNSIGNED;
+
+ function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return SIGNED
+ is
+ variable res : SIGNED (SIZE - 1 downto 0);
+ variable v : integer := arg;
+ variable b0, b1 : bit;
+ variable d : nat1;
+ begin
+ if size = 0 then
+ return null_signed;
+ end if;
+ if arg < 0 then
+ -- Use one complement to avoid overflow:
+ -- -v = (not v) + 1
+ -- not v = -v - 1
+ -- not v = -(v + 1)
+ v := -(arg + 1);
+ b0 := '1';
+ b1 := '0';
+ else
+ v := arg;
+ b0 := '0';
+ b1 := '1';
+ end if;
+
+ for i in res'reverse_range loop
+ d := v rem 2;
+ v := v / 2;
+ if d = 0 then
+ res (i) := b0;
+ else
+ res (i) := b1;
+ end if;
+ end loop;
+ if v /= 0 or res (res'left) /= b0 then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_SIGNED: vector is truncated"
+ severity warning;
+ end if;
+ return res;
+ end TO_SIGNED;
+
+ @ARITH
+
+ @LOG
+end NUMERIC_BIT;
diff --git a/libraries/openieee/numeric_bit.proto b/libraries/openieee/numeric_bit.proto
new file mode 100644
index 000000000..8ece1bf19
--- /dev/null
+++ b/libraries/openieee/numeric_bit.proto
@@ -0,0 +1,24 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.3 compliant numeric bit package.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+package NUMERIC_BIT is
+ type UNSIGNED is array (natural range <>) of BIT;
+ type SIGNED is array (natural range <>) of BIT;
+
+ @COMMON
+end NUMERIC_BIT;
diff --git a/libraries/openieee/numeric_common.proto b/libraries/openieee/numeric_common.proto
new file mode 100644
index 000000000..a40e8a910
--- /dev/null
+++ b/libraries/openieee/numeric_common.proto
@@ -0,0 +1,190 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- Common part of numeric_bit and numeric_std defined by IEEE 1076.3
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+ function TO_INTEGER (ARG : UNSIGNED) return NATURAL;
+ function TO_INTEGER (ARG : SIGNED) return INTEGER;
+ -- Convert ARG to an integer.
+ -- Simulation is aborted in case of overflow.
+ -- Issue a warning in case of non-logical value.
+
+ function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED;
+ -- Convert ARG to unsigned.
+ -- Result index range is SIZE - 1 downto 0.
+ -- Issue a warning if value is truncated.
+
+ function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return SIGNED;
+ -- Convert ARG to signed.
+ -- Result index range is SIZE - 1 downto 0.
+ -- Issue a warning if value is truncated.
+
+ function resize (ARG : UNSIGNED; NEW_SIZE: natural) return UNSIGNED;
+ function resize (ARG : SIGNED; NEW_SIZE: natural) return SIGNED;
+ -- Result index range is NEW_SIZE - 1 downto 0 (unless null array).
+ -- For SIGNED, the sign of the result is the sign of ARG.
+
+ function "=" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function "=" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function "=" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+ function "/=" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function "/=" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function "/=" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+ function "<" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function "<" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function "<" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+ function "<=" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function "<=" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function "<=" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+ function ">" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function ">" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function ">" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+ function ">=" (L : UNSIGNED; R : UNSIGNED) return BOOLEAN;
+ function ">=" (L : UNSIGNED; R : NATURAL) return BOOLEAN;
+ function ">=" (L : NATURAL; R : UNSIGNED) return BOOLEAN;
+
+ function "=" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function "=" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function "=" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ function "/=" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function "/=" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function "/=" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ function "<" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function "<" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function "<" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ function "<=" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function "<=" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function "<=" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ function ">" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function ">" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function ">" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ function ">=" (L : SIGNED; R : SIGNED) return BOOLEAN;
+ function ">=" (L : SIGNED; R : INTEGER) return BOOLEAN;
+ function ">=" (L : INTEGER; R : SIGNED) return BOOLEAN;
+ -- Issue a warning in case of non-logical value.
+
+ function "-" (ARG : SIGNED) return SIGNED;
+ -- Compute -ARG.
+ -- Result index range is Arg'length - 1 downto 0.
+
+ function "abs" (ARG : SIGNED) return SIGNED;
+ -- Compute abs ARG.
+ -- Result index range is Arg'length - 1 downto 0.
+
+ function "+" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "+" (L : SIGNED; R : SIGNED) return SIGNED;
+ function "-" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "-" (L : SIGNED; R : SIGNED) return SIGNED;
+ -- Compute L +/- R.
+ -- Result index range is max (L'Length, R'Length) - 1 downto 0.
+ -- Issue a warning in case of non-logical value.
+
+ function "+" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "+" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "+" (L : SIGNED; R : INTEGER) return SIGNED;
+ function "+" (L : INTEGER; R : SIGNED) return SIGNED;
+ function "-" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "-" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "-" (L : SIGNED; R : INTEGER) return SIGNED;
+ function "-" (L : INTEGER; R : SIGNED) return SIGNED;
+ -- Compute L +/- R.
+ -- Result index range is V'Length - 1 downto 0, where V is the vector
+ -- parameter.
+ -- Issue a warning in case of non-logical value.
+ -- Issue a warning if value is truncated.
+
+ function "*" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "*" (L : SIGNED; R : SIGNED) return SIGNED;
+ -- Compute L * R
+ -- Result index range is L'Length + R'Length - 1 downto 0.
+
+ function "*" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "*" (L : SIGNED; R : INTEGER) return SIGNED;
+ -- Compute L * R
+ -- R is converted to a vector of length L'length
+
+ function "*" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "*" (L : INTEGER; R : SIGNED) return SIGNED;
+ -- Compute L * R
+ -- L is converted to a vector of length R'length
+
+ function "/" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "/" (L : SIGNED; R : SIGNED) return SIGNED;
+ function "rem" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "rem" (L : SIGNED; R : SIGNED) return SIGNED;
+ function "mod" (L : UNSIGNED; R : UNSIGNED) return UNSIGNED;
+ function "mod" (L : SIGNED; R : SIGNED) return SIGNED;
+ -- Compute L op R
+ -- Result index range is L'Length - 1 downto 0.
+ -- Issue a warning in case of non-logical value.
+ -- Issue an error if R is 0.
+
+ function "/" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "/" (L : SIGNED; R : INTEGER) return SIGNED;
+ function "rem" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "rem" (L : SIGNED; R : INTEGER) return SIGNED;
+ function "mod" (L : UNSIGNED; R : NATURAL) return UNSIGNED;
+ function "mod" (L : SIGNED; R : INTEGER) return SIGNED;
+ -- Compute L op R.
+ -- Result index range is L'Length - 1 downto 0.
+ -- Issue a warning in case of non-logical value.
+ -- Issue an error if R is 0.
+
+ function "/" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "/" (L : INTEGER; R : SIGNED) return SIGNED;
+ function "rem" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "rem" (L : INTEGER; R : SIGNED) return SIGNED;
+ function "mod" (L : NATURAL; R : UNSIGNED) return UNSIGNED;
+ function "mod" (L : INTEGER; R : SIGNED) return SIGNED;
+ -- Compute L op R.
+ -- Result index range is R'Length - 1 downto 0.
+ -- Issue a warning in case of non-logical value.
+ -- Issue an error if R is 0.
+ -- Result may be truncated.
+
+ function "not" (l : UNSIGNED) return UNSIGNED;
+ function "not" (l : SIGNED) return SIGNED;
+ function "and" (l, r : UNSIGNED) return UNSIGNED;
+ function "and" (l, r : SIGNED) return SIGNED;
+ function "nand" (l, r : UNSIGNED) return UNSIGNED;
+ function "nand" (l, r : SIGNED) return SIGNED;
+ function "or" (l, r : UNSIGNED) return UNSIGNED;
+ function "or" (l, r : SIGNED) return SIGNED;
+ function "nor" (l, r : UNSIGNED) return UNSIGNED;
+ function "nor" (l, r : SIGNED) return SIGNED;
+ function "xor" (l, r : UNSIGNED) return UNSIGNED;
+ function "xor" (l, r : SIGNED) return SIGNED;
+ function "xnor" (l, r : UNSIGNED) return UNSIGNED;
+ function "xnor" (l, r : SIGNED) return SIGNED;
+ -- Compute L OP R.
+ -- Result index range is L'Length - 1 downto 0.
+ -- No specific handling of null array: the index range of the result
+ -- would be -1 downto 0 (without warning). This it not what is specified
+ -- in 1076.3, but corresponds to the standard implementation.
+ -- No specific handling of non-logical values. Behaviour is compatible
+ -- with std_logic_1164.
+
+ function shift_left (ARG : UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ function shift_left (ARG : SIGNED; COUNT: NATURAL) return SIGNED;
+ function shift_right (ARG : UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ function shift_right (ARG : SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result index range is ARG'Length - 1 downto 0.
+
+ function rotate_left (ARG : UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ function rotate_left (ARG : SIGNED; COUNT: NATURAL) return SIGNED;
+ function rotate_right (ARG : UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ function rotate_right (ARG : SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result index range is ARG'Length - 1 downto 0.
diff --git a/libraries/openieee/numeric_std-body.proto b/libraries/openieee/numeric_std-body.proto
new file mode 100644
index 000000000..757db6299
--- /dev/null
+++ b/libraries/openieee/numeric_std-body.proto
@@ -0,0 +1,275 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.3 compliant numeric std package body.
+-- The implementation is based only on the specifications.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+package body NUMERIC_STD is
+ constant NO_WARNING : Boolean := False;
+
+ constant null_unsigned : unsigned (0 downto 1) := (others => '0');
+ constant null_signed : signed (0 downto 1) := (others => '0');
+
+ subtype nat1 is natural range 0 to 1;
+
+ type nat1_to_sl_type is array (nat1) of std_ulogic;
+ constant nat1_to_01 : nat1_to_sl_type := (0 => '0', 1 => '1');
+
+ subtype sl_01 is std_ulogic range '0' to '1';
+ subtype sl_x01 is std_ulogic range 'X' to '1';
+
+ type carry_array is array (sl_01, sl_01, sl_01) of sl_01;
+ constant compute_carry : carry_array :=
+ ('0' => ('0' => ('0' => '0', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')),
+ '1' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '1')));
+ constant compute_sum : carry_array :=
+ ('0' => ('0' => ('0' => '0', '1' => '1'),
+ '1' => ('0' => '1', '1' => '0')),
+ '1' => ('0' => ('0' => '1', '1' => '0'),
+ '1' => ('0' => '0', '1' => '1')));
+
+ type sl_to_x01_array is array (std_ulogic) of sl_x01;
+ constant sl_to_x01 : sl_to_x01_array :=
+ ('0' | 'L' => '0', '1' | 'H' => '1', others => 'X');
+
+ type compare_type is (compare_unknown,
+ compare_lt,
+ compare_eq,
+ compare_gt);
+
+ -- Match.
+ -- '-' matches with everything.
+ -- '0'/'L' matches, '1'/'H' matches.
+ type match_table_type is array (std_ulogic, std_ulogic) of boolean;
+ constant match_table: match_table_type :=
+ ('0' | 'L' => ('0' | 'L' | '-' => true, others => false),
+ '1' | 'H' => ('1' | 'H' | '-' => true, others => false),
+ '-' => (others => true),
+ others => ('-' => true, others => false));
+
+ function MAX (L, R : natural) return natural is
+ begin
+ if L > R then
+ return L;
+ else
+ return R;
+ end if;
+ end MAX;
+
+ function TO_INTEGER (ARG : UNSIGNED) return NATURAL
+ is
+ variable argn : UNSIGNED (ARG'Length -1 downto 0);
+ variable res : natural := 0;
+ begin
+ if argn'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: null array detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ argn := TO_01 (ARG, 'X');
+ if argn (0) = 'X' then
+ assert NO_WARNING
+ report
+ "NUMERIC_STD.TO_INTEGER: non logical value detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+
+ for i in argn'range loop
+ res := res + res;
+ if argn (i) = '1' then
+ res := res + 1;
+ end if;
+ end loop;
+
+ return res;
+ end TO_INTEGER;
+
+ function TO_INTEGER (ARG : SIGNED) return INTEGER
+ is
+ variable argn : SIGNED (ARG'Length -1 downto 0);
+ variable res : integer := 0;
+ variable b : STD_ULOGIC;
+ begin
+ if argn'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: null array detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ argn := TO_01 (ARG, 'X');
+ if argn (0) = 'X' then
+ assert NO_WARNING
+ report
+ "NUMERIC_STD.TO_INTEGER: non logical value detected, returning 0"
+ severity warning;
+ return 0;
+ end if;
+ if argn (argn'left) = '1' then
+ -- Negative value
+ b := '0';
+ else
+ b := '1';
+ end if;
+
+ for i in argn'range loop
+ res := res + res;
+ if argn (i) = b then
+ res := res + 1;
+ end if;
+ end loop;
+
+ if b = '0' then
+ -- Avoid overflow.
+ res := -res - 1;
+ end if;
+
+ return res;
+ end TO_INTEGER;
+
+ function TO_01 (S : SIGNED; XMAP : STD_LOGIC := '0') return SIGNED
+ is
+ subtype res_type is SIGNED (S'Length - 1 downto 0);
+ variable res : res_type;
+ alias snorm: res_type is S;
+ begin
+ if S'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: null array detected"
+ severity warning;
+ return null_signed;
+ else
+ for i in res_type'range loop
+ case snorm (i) is
+ when '0' | 'L' => res (i) := '0';
+ when '1' | 'H' => res (i) := '1';
+ when others =>
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: non logical value detected"
+ severity warning;
+ res := (others => XMAP);
+ exit;
+ end case;
+ end loop;
+ end if;
+ return res;
+ end TO_01;
+
+ function TO_01 (S : UNSIGNED; XMAP : STD_LOGIC := '0') return UNSIGNED
+ is
+ subtype res_type is UNSIGNED (S'Length - 1 downto 0);
+ variable res : res_type;
+ alias snorm: res_type is S;
+ begin
+ if S'length = 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: null array detected"
+ severity warning;
+ return null_unsigned;
+ else
+ for i in res_type'range loop
+ case snorm (i) is
+ when '0' | 'L' => res (i) := '0';
+ when '1' | 'H' => res (i) := '1';
+ when others =>
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: non logical value detected"
+ severity warning;
+ res := (others => XMAP);
+ exit;
+ end case;
+ end loop;
+ end if;
+ return res;
+ end TO_01;
+
+ function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED
+ is
+ variable res : UNSIGNED (SIZE - 1 downto 0);
+ variable a : natural := arg;
+ variable d : nat1;
+ begin
+ if size = 0 then
+ return null_unsigned;
+ end if;
+ for i in res'reverse_range loop
+ d := a rem 2;
+ res (i) := nat1_to_01 (d);
+ a := a / 2;
+ end loop;
+ if a /= 0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_UNSIGNED: vector is truncated"
+ severity warning;
+ end if;
+ return res;
+ end TO_UNSIGNED;
+
+ function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return SIGNED
+ is
+ variable res : SIGNED (SIZE - 1 downto 0);
+ variable v : integer := arg;
+ variable b0, b1 : std_ulogic;
+ variable d : nat1;
+ begin
+ if size = 0 then
+ return null_signed;
+ end if;
+ if arg < 0 then
+ -- Use one complement to avoid overflow:
+ -- -v = (not v) + 1
+ -- not v = -v - 1
+ -- not v = -(v + 1)
+ v := -(arg + 1);
+ b0 := '1';
+ b1 := '0';
+ else
+ v := arg;
+ b0 := '0';
+ b1 := '1';
+ end if;
+
+ for i in res'reverse_range loop
+ d := v rem 2;
+ v := v / 2;
+ if d = 0 then
+ res (i) := b0;
+ else
+ res (i) := b1;
+ end if;
+ end loop;
+ if v /= 0 or res (res'left) /= b0 then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_SIGNED: vector is truncated"
+ severity warning;
+ end if;
+ return res;
+ end TO_SIGNED;
+
+ function std_match (l, r : std_ulogic) return boolean is
+ begin
+ return match_table (l, r);
+ end std_match;
+
+ @MATCH
+
+ @ARITH
+
+ @LOG
+end NUMERIC_STD;
diff --git a/libraries/openieee/numeric_std.proto b/libraries/openieee/numeric_std.proto
new file mode 100644
index 000000000..83a7af76a
--- /dev/null
+++ b/libraries/openieee/numeric_std.proto
@@ -0,0 +1,41 @@
+-- This -*- vhdl -*- file is part of GHDL.
+-- IEEE 1076.3 compliant numeric std package.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING2. If not see
+-- <http://www.gnu.org/licenses/>.
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+package NUMERIC_STD is
+ type UNSIGNED is array (natural range <>) of STD_LOGIC;
+ type SIGNED is array (natural range <>) of STD_LOGIC;
+
+ function TO_01 (S : SIGNED; XMAP : STD_LOGIC := '0') return SIGNED;
+ function TO_01 (S : UNSIGNED; XMAP : STD_LOGIC := '0') return UNSIGNED;
+ -- Convert 'H' and '1' to '1', 'L' and '0' to '0'.
+ -- If any other value is present, return (others => XMAP)
+ -- Issue a warning in that case, and if S is a null array.
+ -- Result index range is S'Length - 1 downto 0.
+
+ function std_match (l, r : std_ulogic) return boolean;
+ function std_match (l, r : std_ulogic_vector) return boolean;
+ function std_match (l, r : std_logic_vector) return boolean;
+ function std_match (l, r : UNSIGNED) return boolean;
+ function std_match (l, r : SIGNED) return boolean;
+ -- Return True iff L and R matches.
+
+ @COMMON
+end NUMERIC_STD;
diff --git a/libraries/redist1164/std_logic_1164-body.proto b/libraries/openieee/std_logic_1164-body.proto
index aacf4c2b2..d214fb16d 100644
--- a/libraries/redist1164/std_logic_1164-body.proto
+++ b/libraries/openieee/std_logic_1164-body.proto
@@ -13,7 +13,7 @@
-- for more details.
--
-- You should have received a copy of the GNU General Public License
--- along with GCC; see the file COPYING3. If not see
+-- along with GCC; see the file COPYING2. If not see
-- <http://www.gnu.org/licenses/>.
-- This is a template file. To avoid errors and duplication, the python
@@ -88,10 +88,10 @@ package body std_logic_1164 is
type table_std_x01z is array (std_ulogic) of X01Z;
- constant std_to_x01z : table_std_x01 := ('U' | 'X' | 'W' | '-' => 'X',
- '0' | 'L' => '0',
- '1' | 'H' => '1',
- 'Z' => 'Z');
+ constant std_to_x01z : table_std_x01z := ('U' | 'X' | 'W' | '-' => 'X',
+ '0' | 'L' => '0',
+ '1' | 'H' => '1',
+ 'Z' => 'Z');
type table_std_ux01 is array (std_ulogic) of UX01;
constant std_to_ux01 : table_std_ux01 := ('U' => 'U',
diff --git a/libraries/redist1164/std_logic_1164-body.v87 b/libraries/openieee/std_logic_1164-body.v87
index 739cb9bd2..02bfb0ff3 100644
--- a/libraries/redist1164/std_logic_1164-body.v87
+++ b/libraries/openieee/std_logic_1164-body.v87
@@ -481,10 +481,10 @@ package body std_logic_1164 is
type table_std_x01z is array (std_ulogic) of X01Z;
- constant std_to_x01z : table_std_x01 := ('U' | 'X' | 'W' | '-' => 'X',
- '0' | 'L' => '0',
- '1' | 'H' => '1',
- 'Z' => 'Z');
+ constant std_to_x01z : table_std_x01z := ('U' | 'X' | 'W' | '-' => 'X',
+ '0' | 'L' => '0',
+ '1' | 'H' => '1',
+ 'Z' => 'Z');
type table_std_ux01 is array (std_ulogic) of UX01;
constant std_to_ux01 : table_std_ux01 := ('U' => 'U',
diff --git a/libraries/redist1164/std_logic_1164-body.v93 b/libraries/openieee/std_logic_1164-body.v93
index 7e5c4701e..fc93dacda 100644
--- a/libraries/redist1164/std_logic_1164-body.v93
+++ b/libraries/openieee/std_logic_1164-body.v93
@@ -537,10 +537,10 @@ package body std_logic_1164 is
type table_std_x01z is array (std_ulogic) of X01Z;
- constant std_to_x01z : table_std_x01 := ('U' | 'X' | 'W' | '-' => 'X',
- '0' | 'L' => '0',
- '1' | 'H' => '1',
- 'Z' => 'Z');
+ constant std_to_x01z : table_std_x01z := ('U' | 'X' | 'W' | '-' => 'X',
+ '0' | 'L' => '0',
+ '1' | 'H' => '1',
+ 'Z' => 'Z');
type table_std_ux01 is array (std_ulogic) of UX01;
constant std_to_ux01 : table_std_ux01 := ('U' => 'U',
diff --git a/libraries/redist1164/std_logic_1164.v87 b/libraries/openieee/std_logic_1164.v87
index 964ed956c..964ed956c 100644
--- a/libraries/redist1164/std_logic_1164.v87
+++ b/libraries/openieee/std_logic_1164.v87
diff --git a/libraries/redist1164/std_logic_1164.v93 b/libraries/openieee/std_logic_1164.v93
index 0ee62a1a6..0ee62a1a6 100644
--- a/libraries/redist1164/std_logic_1164.v93
+++ b/libraries/openieee/std_logic_1164.v93
diff --git a/libraries/redist1164/std_logic_1164.vhdl b/libraries/openieee/std_logic_1164.vhdl
index 0ee62a1a6..f05f8f08b 100644
--- a/libraries/redist1164/std_logic_1164.vhdl
+++ b/libraries/openieee/std_logic_1164.vhdl
@@ -13,7 +13,7 @@
-- for more details.
--
-- You should have received a copy of the GNU General Public License
--- along with GCC; see the file COPYING3. If not see
+-- along with GCC; see the file COPYING2. If not see
-- <http://www.gnu.org/licenses/>.
-- This package is valid for VHDL version until but not including 2008.
diff --git a/src/ghdldrv/foreigns.adb b/src/ghdldrv/foreigns.adb
index 15e3dd009..0d6b19aec 100644
--- a/src/ghdldrv/foreigns.adb
+++ b/src/ghdldrv/foreigns.adb
@@ -1,9 +1,41 @@
+-- GHDL driver - Foreign functions known by JIT.
+-- Copyright (C) 2002 - 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
with Interfaces.C; use Interfaces.C;
package body Foreigns is
+ function Ceil (Arg : double) return double;
+ pragma Import (C, Ceil);
+
+ function Floor (Arg : double) return double;
+ pragma Import (C, Floor);
+
+ function Round (Arg : double) return double;
+ pragma Import (C, Round);
+
+ function Trunc (Arg : double) return double;
+ pragma Import (C, Trunc);
+
function Sin (Arg : double) return double;
pragma Import (C, Sin);
+ function Cos (Arg : double) return double;
+ pragma Import (C, Cos);
+
function Log (Arg : double) return double;
pragma Import (C, Log);
@@ -37,10 +69,14 @@ package body Foreigns is
Addr : Address;
end record;
-
Foreign_Arr : constant array (Natural range <>) of Foreign_Record :=
(
+ (new String'("ceil"), Ceil'Address),
+ (new String'("floor"), Floor'Address),
+ (new String'("round"), Round'Address),
+ (new String'("trunc"), Trunc'Address),
(new String'("sin"), Sin'Address),
+ (new String'("cos"), Cos'Address),
(new String'("log"), Log'Address),
(new String'("exp"), Exp'Address),
(new String'("sqrt"), Sqrt'Address),
diff --git a/src/ghdldrv/foreigns.ads b/src/ghdldrv/foreigns.ads
index 5759ae4f5..15983115b 100644
--- a/src/ghdldrv/foreigns.ads
+++ b/src/ghdldrv/foreigns.ads
@@ -1,3 +1,20 @@
+-- GHDL driver - Foreign functions known by JIT.
+-- Copyright (C) 2002 - 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
with System; use System;
package Foreigns is