summaryrefslogtreecommitdiff
path: root/libraries/redist1164/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/redist1164/build.py')
-rw-r--r--libraries/redist1164/build.py361
1 files changed, 361 insertions, 0 deletions
diff --git a/libraries/redist1164/build.py b/libraries/redist1164/build.py
new file mode 100644
index 0000000..6255938
--- /dev/null
+++ b/libraries/redist1164/build.py
@@ -0,0 +1,361 @@
+#!/usr/bin/env python
+# Generate the body of ieee.std_logic_1164 from a template.
+# This file is part of GHDL.
+# 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+
+binary_funcs = [ "and", "nand", "or", "nor", "xor" ]
+
+# Python modelisation of std_ulogic type.
+std_logic = "UX01ZWLH-"
+
+# Normalization map.
+ux01_map = { 'U': 'U',
+ 'X': 'X', 'Z': 'X', 'W': 'X', '-': 'X',
+ '0': '0', 'L': '0',
+ '1': '1', 'H': '1' }
+
+def sl_and(a,b):
+ """and definition"""
+ na = ux01_map[a]
+ nb = ux01_map[b]
+ if na == '0' or nb == '0':
+ return '0'
+ if na == 'U' or nb == 'U':
+ return 'U'
+ if na == 'X' or nb == 'X':
+ return 'X'
+ return '1'
+
+def sl_not(a):
+ """not definition"""
+ na = ux01_map[a]
+ if na == 'U':
+ return 'U'
+ if na == 'X':
+ return 'X'
+ if na == '1':
+ return '0'
+ else:
+ return '1'
+
+def sl_or(a,b):
+ "or definition"
+ return sl_not(sl_and (sl_not(a), sl_not(b)))
+
+def sl_xor(a,b):
+ "xor definition"
+ return sl_or(sl_and(a, sl_not(b)),
+ sl_and(sl_not(a), b))
+
+# Stream to write.
+out=sys.stdout
+
+def w(s):
+ "Write S to the output"
+ out.write(s)
+
+def gen_log_table2(name, func):
+ "Generate a logic table for binary operator NAME using its model FUNC"
+ w("""
+ constant {0}_table : table_2d :=
+ -- UX01ZWLH-
+ (""".format(name))
+ for a in std_logic:
+ w('"')
+ for b in std_logic:
+ w(func (a, b))
+ w('"')
+ if a != '-':
+ w(',')
+ else:
+ w(' ')
+ w(' -- {}\n'.format(a))
+ w(' ')
+ w(');\n')
+
+def gen_log_table1(name, func):
+ "Generate a logic table for unary operator NAME using its model FUNC"
+ w("""
+ constant {0}_table : table_1d :=
+ -- UX01ZWLH-
+ """.format(name))
+ w('"')
+ for b in std_logic:
+ w(func (b))
+ w('";\n')
+
+def disp_tables():
+ "Generate logic tables"
+ gen_log_table2("and", sl_and)
+ gen_log_table2("nand", lambda a,b : sl_not(sl_and(a, b)))
+ gen_log_table2("or", sl_or)
+ gen_log_table2("nor", lambda a,b : sl_not(sl_or(a,b)))
+ gen_log_table2("xor", sl_xor)
+ if "xnor" in binary_funcs:
+ gen_log_table2("xnor", lambda a,b : sl_not(sl_xor(a,b)))
+ gen_log_table1("not", sl_not)
+
+vec_types = ['ulogic', 'logic']
+
+def disp_scalar_binary(fun):
+ "Generate scalar binary function body"
+ w("""
+ function "{0}" (l, r : std_ulogic) return UX01 is
+ begin
+ return {0}_table (l, r);
+ end "{0}";\n""".format(fun))
+
+def disp_scalar_unary(fun):
+ "Generate scalar unary function body"
+ w("""
+ function "{0}" (l : std_ulogic) return UX01 is
+ begin
+ return {0}_table (l);
+ end "{0}";\n""".format(fun))
+
+def disp_vec_binary(func, typ):
+ "Generate vector binary function body"
+ w("""
+ function "{0}" (l, r : std_{1}_vector) return std_{1}_vector
+ is
+ subtype res_type is std_{1}_vector (1 to l'length);
+ alias la : res_type is l;
+ alias ra : std_{1}_vector (1 to r'length) is r;
+ variable res : res_type;
+ begin
+ if la'length /= ra'length then
+ assert false
+ report "arguments of overloaded '{0}' operator are not of the same length"
+ severity failure;
+ else
+ for I in res_type'range loop
+ res (I) := {0}_table (la (I), ra (I));
+ end loop;
+ end if;
+ return res;
+ end "{0}";\n""".format(func, typ))
+
+def disp_vec_unary(func, typ):
+ "Generate vector unary function body"
+ w("""
+ function "{0}" (l : std_{1}_vector) return std_{1}_vector
+ is
+ subtype res_type is std_{1}_vector (1 to l'length);
+ alias la : res_type is l;
+ variable res : res_type;
+ begin
+ for I in res_type'range loop
+ res (I) := {0}_table (la (I));
+ end loop;
+ return res;
+ end "{0}";\n""".format(func, typ))
+
+def disp_all_log_funcs():
+ "Generate all function bodies for logic operators"
+ for f in binary_funcs:
+ disp_scalar_binary(f)
+ disp_scalar_unary("not")
+ for v in vec_types:
+ typ = "std_" + v + "_vector"
+ for f in binary_funcs:
+ disp_vec_binary(f, v)
+ disp_vec_unary("not", v)
+
+def disp_sv_to_bv_conv(typ):
+ "Generate logic vector to bit vector function body"
+ w("""
+ function to_bitvector (s : std_{0}_vector; xmap : bit := '0')
+ return bit_vector
+ is
+ subtype res_range is natural range s'length - 1 downto 0;
+ alias as : std_{0}_vector (res_range) is s;
+ variable res : bit_vector (res_range);
+ variable b : bit;
+ begin
+ for I in res_range loop
+ -- Inline for efficiency.
+ case as (I) is
+ when '0' | 'L' =>
+ b := '0';
+ when '1' | 'H' =>
+ b := '1';
+ when others =>
+ b := xmap;
+ end case;
+ res (I) := b;
+ end loop;
+ return res;
+ end to_bitvector;\n""".format(typ))
+
+def disp_bv_to_sv_conv(typ):
+ "Generate bit vector to logic vector function body"
+ w("""
+ function to_std{0}vector (b : bit_vector) return std_{0}_vector is
+ subtype res_range is natural range b'length - 1 downto 0;
+ alias ab : bit_vector (res_range) is b;
+ variable res : std_{0}_vector (res_range);
+ begin
+ for I in res_range loop
+ res (I) := bit_to_std (ab (I));
+ end loop;
+ return res;
+ end to_std{0}vector;\n""".format(typ))
+
+def disp_sv_to_sv_conv(s,d):
+ "Generate logic vector to logic vector function body"
+ w("""
+ function to_std{1}vector (b : std_{0}_vector) return std_{1}_vector
+ is
+ subtype res_type is std_{1}_vector (b'length - 1 downto 0);
+ begin
+ return res_type (b);
+ end to_std{1}vector;\n""".format(s,d))
+
+def disp_all_conv_funcs():
+ "Generate conversion function bodies"
+ for v in vec_types:
+ disp_sv_to_bv_conv(v)
+ for v in vec_types:
+ disp_bv_to_sv_conv(v)
+ disp_sv_to_sv_conv('logic', 'ulogic')
+ disp_sv_to_sv_conv('ulogic', 'logic')
+
+def disp_conv_vec_vec(typ, v):
+ "Generate function body for vector conversion"
+ utyp = typ.upper();
+ w("""
+ function to_{1} (s : std_{2}_vector) return std_{2}_vector
+ is
+ subtype res_type is std_{2}_vector (1 to s'length);
+ alias sa : res_type is s;
+ variable res : res_type;
+ begin
+ for i in res_type'range loop
+ res (i) := std_to_{0} (sa (i));
+ end loop;
+ return res;
+ end to_{1};\n""".format(typ, utyp, v))
+
+def disp_conv_std(typ):
+ "Generate function body for scalar conversion"
+ utyp = typ.upper();
+ w("""
+ function to_{1} (s : std_ulogic) return {1} is
+ begin
+ return std_to_{0} (s);
+ end to_{1};\n""".format(typ, utyp))
+
+def disp_conv_bv_vec(typ, v):
+ "Generate function body for bit vector conversion"
+ utyp = typ.upper();
+ w("""
+ function to_{1} (b : bit_vector) return std_{2}_vector
+ is
+ subtype res_range is natural range 1 to b'length;
+ alias ba : bit_vector (res_range) is b;
+ variable res : std_{2}_vector (res_range);
+ begin
+ for i in res_range loop
+ res (i) := bit_to_x01 (ba (i));
+ end loop;
+ return res;
+ end to_{1};\n""".format(typ, utyp, v))
+
+def disp_conv_b_t(typ):
+ "Generate function body for bit conversion"
+ utyp = typ.upper();
+ w("""
+ function to_{1} (b : bit) return {1} is
+ begin
+ return bit_to_x01 (b);
+ end to_{1};\n""".format(typ, utyp))
+
+def disp_all_norm_funcs():
+ "Generate all function bodies for conversion"
+ for typ in [ "x01", "x01z", "ux01" ]:
+ for v in vec_types:
+ disp_conv_vec_vec(typ, v)
+ disp_conv_std (typ)
+ for v in vec_types:
+ disp_conv_bv_vec(typ, v)
+ disp_conv_b_t(typ)
+
+def disp_all_isx_funcs():
+ "Generate all function bodies for isx functions"
+ for v in vec_types:
+ w("""
+ function is_X (s : std_{0}_vector) return boolean is
+ begin
+ for i in s'range loop
+ if std_x (s (i)) then
+ return true;
+ end if;
+ end loop;
+ return false;
+ end is_X;\n""".format(v))
+
+ w("""
+ function is_X (s : std_ulogic) return boolean is
+ begin
+ return std_x (s);
+ end is_X;\n""")
+
+
+# Patterns to replace
+pats = {' @TAB\n' : disp_tables,
+ ' @LOG\n' : disp_all_log_funcs,
+ ' @CONV\n': disp_all_conv_funcs,
+ ' @NORM\n': disp_all_norm_funcs,
+ ' @ISX\n' : disp_all_isx_funcs }
+
+spec_file='std_logic_1164.vhdl'
+proto_file='std_logic_1164-body.proto'
+
+def gen_body():
+ w('-- This file was generated from ' + proto_file + '\n')
+ for line in open(proto_file):
+ if line in pats:
+ pats[line]()
+ continue
+ w(line)
+
+# Copy spec
+out=open('std_logic_1164.v87', 'w')
+for line in open(spec_file):
+ if '"xnor"' in line:
+ w("--" + line[2:])
+ else:
+ w(line)
+out.close()
+
+out=open('std_logic_1164.v93', 'w')
+for line in open(spec_file):
+ w(line)
+out.close()
+
+# Generate bodies
+out=open('std_logic_1164-body.v87', 'w')
+gen_body()
+out.close()
+
+binary_funcs.append("xnor")
+out=open('std_logic_1164-body.v93', 'w')
+gen_body()
+out.close()