aboutsummaryrefslogtreecommitdiffstats
path: root/libraries
diff options
context:
space:
mode:
authorgingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2005-09-24 05:10:24 +0000
committergingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2005-09-24 05:10:24 +0000
commit977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849 (patch)
tree7bcf8e7aff40a8b54d4af83e90cccd73568e77bb /libraries
downloadghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.gz
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.bz2
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.zip
First import from sources
Diffstat (limited to 'libraries')
-rw-r--r--libraries/Makefile.inc169
-rw-r--r--libraries/README27
-rw-r--r--libraries/ieee/math_complex-body.vhdl394
-rw-r--r--libraries/ieee/math_complex.vhdl126
-rw-r--r--libraries/ieee/math_real-body.vhdl410
-rw-r--r--libraries/ieee/math_real.vhdl223
-rw-r--r--libraries/ieee/numeric_bit-body.vhdl1818
-rw-r--r--libraries/ieee/numeric_bit.vhdl813
-rw-r--r--libraries/ieee/numeric_std-body.vhdl2545
-rw-r--r--libraries/ieee/numeric_std.vhdl853
-rw-r--r--libraries/ieee/std_logic_1164.vhdl175
-rw-r--r--libraries/ieee/std_logic_1164_body.vhdl830
-rw-r--r--libraries/mentor/std_logic_arith.vhdl254
-rw-r--r--libraries/mentor/std_logic_arith_body.vhdl2915
-rw-r--r--libraries/std/textio.vhdl130
-rw-r--r--libraries/std/textio_body.vhdl1320
-rw-r--r--libraries/synopsys/std_logic_arith.vhdl2391
-rw-r--r--libraries/synopsys/std_logic_misc-body.vhdl811
-rw-r--r--libraries/synopsys/std_logic_misc.vhdl170
-rw-r--r--libraries/synopsys/std_logic_signed.vhdl343
-rw-r--r--libraries/synopsys/std_logic_textio.vhdl634
-rw-r--r--libraries/synopsys/std_logic_unsigned.vhdl329
-rw-r--r--libraries/vital2000/memory_b.vhdl7151
-rw-r--r--libraries/vital2000/memory_p.vhdl1729
-rw-r--r--libraries/vital2000/prmtvs_b.vhdl5622
-rw-r--r--libraries/vital2000/prmtvs_p.vhdl1413
-rw-r--r--libraries/vital2000/timing_b.vhdl2187
-rw-r--r--libraries/vital2000/timing_p.vhdl1202
-rw-r--r--libraries/vital95/vital_primitives.vhdl1410
-rw-r--r--libraries/vital95/vital_primitives_body.vhdl5614
-rw-r--r--libraries/vital95/vital_timing.vhdl880
-rw-r--r--libraries/vital95/vital_timing_body.vhdl1275
32 files changed, 46163 insertions, 0 deletions
diff --git a/libraries/Makefile.inc b/libraries/Makefile.inc
new file mode 100644
index 000000000..e1557c603
--- /dev/null
+++ b/libraries/Makefile.inc
@@ -0,0 +1,169 @@
+# -*- Makefile -*- for the VHDL libraries.
+# Copyright (C) 2002, 2003, 2004, 2005 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.
+
+# Variable to be defined:
+# LIB93_DIR
+# LIB87_DIR
+# REL_DIR
+# LIBSRC_DIR
+# ANALYZE
+# LN
+# CP
+#
+# Note: the source files are analyzed in the LIBxx_DIR. So LIBSRC_DIR must be
+# relative to the target directory.
+
+STD_SRCS := std/textio.vhdl std/textio_body.vhdl
+IEEE_SRCS := ieee/std_logic_1164.vhdl ieee/std_logic_1164_body.vhdl \
+ ieee/numeric_bit.vhdl ieee/numeric_bit-body.vhdl \
+ ieee/numeric_std.vhdl ieee/numeric_std-body.vhdl
+MATH_SRCS := ieee/math_real.vhdl ieee/math_real-body.vhdl \
+ ieee/math_complex.vhdl ieee/math_complex-body.vhdl
+VITAL95_BSRCS := vital95/vital_timing.vhdl vital95/vital_timing_body.vhdl \
+ vital95/vital_primitives.vhdl vital95/vital_primitives_body.vhdl
+VITAL2000_BSRCS := vital2000/timing_p.vhdl vital2000/timing_b.vhdl \
+ vital2000/prmtvs_p.vhdl vital2000/prmtvs_b.vhdl \
+ vital2000/memory_p.vhdl vital2000/memory_b.vhdl
+SYNOPSYS_BSRCS := synopsys/std_logic_arith.vhdl \
+ synopsys/std_logic_textio.vhdl synopsys/std_logic_unsigned.vhdl \
+ synopsys/std_logic_signed.vhdl \
+ synopsys/std_logic_misc.vhdl synopsys/std_logic_misc-body.vhdl
+MENTOR_BSRCS := mentor/std_logic_arith.vhdl mentor/std_logic_arith_body.vhdl
+
+STD87_BSRCS := $(STD_SRCS:.vhdl=.v87)
+STD93_BSRCS := $(STD_SRCS:.vhdl=.v93)
+IEEE87_BSRCS := $(IEEE_SRCS:.vhdl=.v87)
+IEEE93_BSRCS := $(IEEE_SRCS:.vhdl=.v93) $(MATH_SRCS)
+SYNOPSYS87_BSRCS := $(SYNOPSYS_BSRCS)
+SYNOPSYS93_BSRCS := $(SYNOPSYS_BSRCS)
+MENTOR93_BSRCS := $(MENTOR_BSRCS)
+
+.PREFIXES: .vhdl .v93 .v87
+
+%.v93: %.vhdl
+ sed -e '/--V87/s/^/ --/' < $< > $@
+
+%.v87: %.vhdl
+ sed -e '/--V93/s/^/ --/' -e '/--START-V93/,/--END-V93/s/^/--/' \
+ < $< > $@
+
+STD93_DIR:=$(LIB93_DIR)/std
+IEEE93_DIR:=$(LIB93_DIR)/ieee
+SYN93_DIR:=$(LIB93_DIR)/synopsys
+MENTOR93_DIR:=$(LIB93_DIR)/mentor
+
+STD87_DIR:=$(LIB87_DIR)/std
+IEEE87_DIR:=$(LIB87_DIR)/ieee
+SYN87_DIR:=$(LIB87_DIR)/synopsys
+
+ANALYZE93:=$(ANALYZE) --std=93
+ANALYZE87:=$(ANALYZE) --std=87
+
+STD87_SRCS=$(addprefix $(LIBSRC_DIR)/,$(STD87_BSRCS))
+STD93_SRCS=$(addprefix $(LIBSRC_DIR)/,$(STD93_BSRCS))
+IEEE93_SRCS=$(addprefix $(LIBSRC_DIR)/,$(IEEE93_BSRCS))
+IEEE87_SRCS=$(addprefix $(LIBSRC_DIR)/,$(IEEE87_BSRCS))
+SYNOPSYS_SRCS=$(addprefix $(LIBSRC_DIR)/,$(SYNOPSYS_BSRCS))
+MENTOR93_SRCS=$(addprefix $(LIBSRC_DIR)/,$(MENTOR93_BSRCS))
+VITAL95_SRCS=$(addprefix $(LIBSRC_DIR)/,$(VITAL95_BSRCS))
+VITAL2000_SRCS=$(addprefix $(LIBSRC_DIR)/,$(VITAL2000_BSRCS))
+
+std.v93: $(LIB93_DIR) $(STD93_SRCS) force
+ $(RM) -rf $(STD93_DIR)
+ mkdir $(STD93_DIR)
+ prev=`pwd`; cd $(STD93_DIR); \
+ for i in $(STD93_SRCS); do \
+ echo $$i; \
+ $(ANALYZE93) --bootstrap --work=std $(REL_DIR)/$$i || exit 1; \
+ done; \
+ cd $$prev
+
+ANALYZE_IEEE93=$(ANALYZE93) -P../std --work=ieee
+
+ieee.v93: $(LIB93_DIR) $(IEEE93_SRCS) force
+ $(RM) -rf $(IEEE93_DIR)
+ mkdir $(IEEE93_DIR)
+ prev=`pwd`; cd $(IEEE93_DIR); \
+ for i in $(IEEE93_BSRCS) $(VITAL2000_BSRCS); do \
+ cmd="$(ANALYZE_IEEE93) $(REL_DIR)/$(LIBSRC_DIR)/$$i"; \
+ echo $$cmd; eval $$cmd || exit 1; \
+ done; \
+ cd $$prev
+
+synopsys.v93: $(LIB93_DIR) $(SYNOPSYS_SRCS) force
+ $(RM) -rf $(SYN93_DIR)
+ mkdir $(SYN93_DIR)
+ prev=`pwd`; cd $(SYN93_DIR); \
+ $(CP) ../ieee/ieee-obj93.cf .; \
+ for i in $(IEEE_SRCS) $(VITAL2000_SRCS); do \
+ b=`basename $$i .vhdl`; $(LN) ../ieee/$$b.o $$b.o || exit 1; \
+ done; \
+ for i in $(SYNOPSYS93_BSRCS); do \
+ cmd="$(ANALYZE_IEEE93) $(REL_DIR)/$(LIBSRC_DIR)/$$i"; \
+ echo $$cmd; eval $$cmd || exit 1; \
+ done; \
+ cd $$prev
+
+mentor.v93: $(LIB93_DIR) $(MENTOR93_SRCS) force
+ $(RM) -rf $(MENTOR93_DIR)
+ mkdir $(MENTOR93_DIR)
+ prev=`pwd`; cd $(MENTOR93_DIR); \
+ $(CP) ../ieee/ieee-obj93.cf . ;\
+ for i in $(IEEE_SRCS) $(VITAL2000_SRCS); do \
+ b=`basename $$i .vhdl`; $(LN) ../ieee/$$b.o $$b.o || exit 1; \
+ done ; \
+ for i in $(MENTOR93_BSRCS); do \
+ cmd="$(ANALYZE_IEEE93) $(REL_DIR)/$(LIBSRC_DIR)/$$i";\
+ echo $$cmd; eval $$cmd || exit 1; \
+ done
+
+std.v87: $(LIB87_DIR) $(STD87_SRCS) force
+ $(RM) -rf $(STD87_DIR)
+ mkdir $(STD87_DIR)
+ prev=`pwd`; cd $(STD87_DIR); \
+ for i in $(STD87_SRCS); do \
+ echo $$i; \
+ $(ANALYZE87) --bootstrap --work=std $(REL_DIR)/$$i || exit 1; \
+ done; \
+ cd $$prev
+
+ANALYZE_IEEE87=$(ANALYZE87) -P../std --work=ieee
+
+ieee.v87: $(LIB87_DIR) $(IEEE87_SRCS) force
+ $(RM) -rf $(IEEE87_DIR)
+ mkdir $(IEEE87_DIR)
+ prev=`pwd`; cd $(IEEE87_DIR); \
+ for i in $(IEEE87_BSRCS) $(VITAL95_BSRCS); do \
+ cmd="$(ANALYZE_IEEE87) $(REL_DIR)/$(LIBSRC_DIR)/$$i";\
+ echo $$cmd; eval $$cmd || exit 1; \
+ done; \
+ cd $$prev
+
+synopsys.v87: $(LIB87_DIR) $(SYNOPSYS_SRCS) force
+ $(RM) -rf $(SYN87_DIR)
+ mkdir $(SYN87_DIR)
+ prev=`pwd`; cd $(SYN87_DIR); \
+ $(CP) ../ieee/ieee-obj87.cf . ; \
+ for i in $(IEEE_SRCS) $(VITAL95_SRCS); do \
+ b=`basename $$i .vhdl`; $(LN) ../ieee/$$b.o $$b.o || exit 1; \
+ done; \
+ for i in $(SYNOPSYS87_BSRCS); do \
+ cmd="$(ANALYZE_IEEE87) $(REL_DIR)/$(LIBSRC_DIR)/$$i";\
+ echo $$cmd; eval $$cmd || exit 1; \
+ done; \
+ cd $$prev
diff --git a/libraries/README b/libraries/README
new file mode 100644
index 000000000..d569a25a1
--- /dev/null
+++ b/libraries/README
@@ -0,0 +1,27 @@
+VHDL libraries.
+---------------
+
+* Filename convention:
+
+For a package XXXX, the file containing the declaration must be named XXXX.vhdl
+and the file containing the body must be named XXXX-body.vhdl
+
+Note: this is not completly followed!
+
+
+* Using Vhdl-87 or Vhdl-93:
+
+Lines that must be compiled only for vhdl-87 must have a --V87 comment at the
+end, lines for vhdl-93 must a a --V93 comment.
+Example:
+ procedure readline (variable f: in text; l: out line) --V87
+ procedure readline (file f: text; l: out line) --V93
+For group of lines that must be compiled only for vhdl-93 (such as xnor
+functions), use this:
+ --START-V93
+ ...[lines to compile only with vhdl-93]...
+ --END-V93
+Makefile rules create .v87 and .v93 files from .vhdl files, and compile them
+with the correct version.
+
+# Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
diff --git a/libraries/ieee/math_complex-body.vhdl b/libraries/ieee/math_complex-body.vhdl
new file mode 100644
index 000000000..9b8b75ad4
--- /dev/null
+++ b/libraries/ieee/math_complex-body.vhdl
@@ -0,0 +1,394 @@
+---------------------------------------------------------------
+--
+-- This source file may be used and distributed without restriction.
+-- No declarations or definitions shall be included in this package.
+-- This package cannot be sold or distributed for profit.
+--
+-- ****************************************************************
+-- * *
+-- * W A R N I N G *
+-- * *
+-- * This DRAFT version IS NOT endorsed or approved by IEEE *
+-- * *
+-- ****************************************************************
+--
+-- Title: PACKAGE BODY MATH_COMPLEX
+--
+-- Purpose: VHDL declarations for mathematical package MATH_COMPLEX
+-- which contains common complex constants and basic complex
+-- functions and operations.
+--
+-- Author: IEEE VHDL Math Package Study Group
+--
+-- Notes:
+-- The package body uses package IEEE.MATH_REAL
+--
+-- The package body shall be considered the formal definition of
+-- the semantics of this package. Tool developers may choose to implement
+-- the package body in the most efficient manner available to them.
+--
+-- Source code for this package body comes from the following
+-- following sources:
+-- IEEE VHDL Math Package Study Group participants,
+-- U. of Mississippi, Mentor Graphics, Synopsys,
+-- Viewlogic/Vantage, Communications of the ACM (June 1988, Vol
+-- 31, Number 6, pp. 747, Pierre L'Ecuyer, Efficient and Portable
+-- Random Number Generators, Handbook of Mathematical Functions
+-- by Milton Abramowitz and Irene A. Stegun (Dover).
+--
+-- History:
+-- Version 0.1 Jose A. Torres 4/23/93 First draft
+-- Version 0.2 Jose A. Torres 5/28/93 Fixed potentially illegal code
+--
+-------------------------------------------------------------
+Library IEEE;
+
+Use IEEE.MATH_REAL.all; -- real trascendental operations
+
+Package body MATH_COMPLEX is
+
+ function CABS(Z: in complex ) return real is
+ -- returns absolute value (magnitude) of Z
+ variable ztemp : complex_polar;
+ begin
+ ztemp := COMPLEX_TO_POLAR(Z);
+ return ztemp.mag;
+ end CABS;
+
+ function CARG(Z: in complex ) return real is
+ -- returns argument (angle) in radians of a complex number
+ variable ztemp : complex_polar;
+ begin
+ ztemp := COMPLEX_TO_POLAR(Z);
+ return ztemp.arg;
+ end CARG;
+
+ function CMPLX(X: in real; Y: in real := 0.0 ) return complex is
+ -- returns complex number X + iY
+ begin
+ return COMPLEX'(X, Y);
+ end CMPLX;
+
+ function "-" (Z: in complex ) return complex is
+ -- unary minus; returns -x -jy for z= x + jy
+ begin
+ return COMPLEX'(-z.Re, -z.Im);
+ end "-";
+
+ function "-" (Z: in complex_polar ) return complex_polar is
+ -- unary minus; returns (z.mag, z.arg + MATH_PI)
+ begin
+ return COMPLEX_POLAR'(z.mag, z.arg + MATH_PI);
+ end "-";
+
+ function CONJ (Z: in complex) return complex is
+ -- returns complex conjugate (x-jy for z = x+ jy)
+ begin
+ return COMPLEX'(z.Re, -z.Im);
+ end CONJ;
+
+ function CONJ (Z: in complex_polar) return complex_polar is
+ -- returns complex conjugate (z.mag, -z.arg)
+ begin
+ return COMPLEX_POLAR'(z.mag, -z.arg);
+ end CONJ;
+
+ function CSQRT(Z: in complex ) return complex_vector is
+ -- returns square root of Z; 2 values
+ variable ztemp : complex_polar;
+ variable zout : complex_vector (0 to 1);
+ variable temp : real;
+ begin
+ ztemp := COMPLEX_TO_POLAR(Z);
+ temp := SQRT(ztemp.mag);
+ zout(0).re := temp*COS(ztemp.arg/2.0);
+ zout(0).im := temp*SIN(ztemp.arg/2.0);
+
+ zout(1).re := temp*COS(ztemp.arg/2.0 + MATH_PI);
+ zout(1).im := temp*SIN(ztemp.arg/2.0 + MATH_PI);
+
+ return zout;
+ end CSQRT;
+
+ function CEXP(Z: in complex ) return complex is
+ -- returns e**Z
+ begin
+ return COMPLEX'(EXP(Z.re)*COS(Z.im), EXP(Z.re)*SIN(Z.im));
+ end CEXP;
+
+ function COMPLEX_TO_POLAR(Z: in complex ) return complex_polar is
+ -- converts complex to complex_polar
+ begin
+ return COMPLEX_POLAR'(sqrt(z.re**2 + z.im**2),atan2(z.re,z.im));
+ end COMPLEX_TO_POLAR;
+
+ function POLAR_TO_COMPLEX(Z: in complex_polar ) return complex is
+ -- converts complex_polar to complex
+ begin
+ return COMPLEX'( z.mag*cos(z.arg), z.mag*sin(z.arg) );
+ end POLAR_TO_COMPLEX;
+
+
+ --
+ -- arithmetic operators
+ --
+
+ function "+" ( L: in complex; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L.Re + R.Re, L.Im + R.Im);
+ end "+";
+
+ function "+" (L: in complex_polar; R: in complex_polar) return complex is
+ variable zL, zR : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(zL.Re + zR.Re, zL.Im + zR.Im);
+ end "+";
+
+ function "+" ( L: in complex_polar; R: in complex ) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re + R.Re, zL.Im + R.Im);
+ end "+";
+
+ function "+" ( L: in complex; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L.Re + zR.Re, L.Im + zR.Im);
+ end "+";
+
+ function "+" ( L: in real; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L + R.Re, R.Im);
+ end "+";
+
+ function "+" ( L: in complex; R: in real ) return complex is
+ begin
+ return COMPLEX'(L.Re + R, L.Im);
+ end "+";
+
+ function "+" ( L: in real; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L + zR.Re, zR.Im);
+ end "+";
+
+ function "+" ( L: in complex_polar; R: in real) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re + R, zL.Im);
+ end "+";
+
+ function "-" ( L: in complex; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L.Re - R.Re, L.Im - R.Im);
+ end "-";
+
+ function "-" ( L: in complex_polar; R: in complex_polar) return complex is
+ variable zL, zR : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(zL.Re - zR.Re, zL.Im - zR.Im);
+ end "-";
+
+ function "-" ( L: in complex_polar; R: in complex ) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re - R.Re, zL.Im - R.Im);
+ end "-";
+
+ function "-" ( L: in complex; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L.Re - zR.Re, L.Im - zR.Im);
+ end "-";
+
+ function "-" ( L: in real; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L - R.Re, -1.0 * R.Im);
+ end "-";
+
+ function "-" ( L: in complex; R: in real ) return complex is
+ begin
+ return COMPLEX'(L.Re - R, L.Im);
+ end "-";
+
+ function "-" ( L: in real; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L - zR.Re, -1.0*zR.Im);
+ end "-";
+
+ function "-" ( L: in complex_polar; R: in real) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re - R, zL.Im);
+ end "-";
+
+ function "*" ( L: in complex; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L.Re * R.Re - L.Im * R.Im, L.Re * R.Im + L.Im * R.Re);
+ end "*";
+
+ function "*" ( L: in complex_polar; R: in complex_polar) return complex is
+ variable zout : complex_polar;
+ begin
+ zout.mag := L.mag * R.mag;
+ zout.arg := L.arg + R.arg;
+ return POLAR_TO_COMPLEX(zout);
+ end "*";
+
+ function "*" ( L: in complex_polar; R: in complex ) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re*R.Re - zL.Im * R.Im, zL.Re * R.Im + zL.Im*R.Re);
+ end "*";
+
+ function "*" ( L: in complex; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L.Re*zR.Re - L.Im * zR.Im, L.Re * zR.Im + L.Im*zR.Re);
+ end "*";
+
+ function "*" ( L: in real; R: in complex ) return complex is
+ begin
+ return COMPLEX'(L * R.Re, L * R.Im);
+ end "*";
+
+ function "*" ( L: in complex; R: in real ) return complex is
+ begin
+ return COMPLEX'(L.Re * R, L.Im * R);
+ end "*";
+
+ function "*" ( L: in real; R: in complex_polar) return complex is
+ variable zR : complex;
+ begin
+ zR := POLAR_TO_COMPLEX( R );
+ return COMPLEX'(L * zR.Re, L * zR.Im);
+ end "*";
+
+ function "*" ( L: in complex_polar; R: in real) return complex is
+ variable zL : complex;
+ begin
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'(zL.Re * R, zL.Im * R);
+ end "*";
+
+ function "/" ( L: in complex; R: in complex ) return complex is
+ variable magrsq : REAL := R.Re ** 2 + R.Im ** 2;
+ begin
+ if (magrsq = 0.0) then
+ assert FALSE report "Attempt to divide by (0,0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ return COMPLEX'( (L.Re * R.Re + L.Im * R.Im) / magrsq,
+ (L.Im * R.Re - L.Re * R.Im) / magrsq);
+ end if;
+ end "/";
+
+ function "/" ( L: in complex_polar; R: in complex_polar) return complex is
+ variable zout : complex_polar;
+ begin
+ if (R.mag = 0.0) then
+ assert FALSE report "Attempt to divide by (0,0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ zout.mag := L.mag/R.mag;
+ zout.arg := L.arg - R.arg;
+ return POLAR_TO_COMPLEX(zout);
+ end if;
+ end "/";
+
+ function "/" ( L: in complex_polar; R: in complex ) return complex is
+ variable zL : complex;
+ variable temp : REAL := R.Re ** 2 + R.Im ** 2;
+ begin
+ if (temp = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ zL := POLAR_TO_COMPLEX( L );
+ return COMPLEX'( (zL.Re * R.Re + zL.Im * R.Im) / temp,
+ (zL.Im * R.Re - zL.Re * R.Im) / temp);
+ end if;
+ end "/";
+
+ function "/" ( L: in complex; R: in complex_polar) return complex is
+ variable zR : complex := POLAR_TO_COMPLEX( R );
+ variable temp : REAL := zR.Re ** 2 + zR.Im ** 2;
+ begin
+ if (R.mag = 0.0) or (temp = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ return COMPLEX'( (L.Re * zR.Re + L.Im * zR.Im) / temp,
+ (L.Im * zR.Re - L.Re * zR.Im) / temp);
+ end if;
+ end "/";
+
+ function "/" ( L: in real; R: in complex ) return complex is
+ variable temp : REAL := R.Re ** 2 + R.Im ** 2;
+ begin
+ if (temp = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ temp := L / temp;
+ return COMPLEX'( temp * R.Re, -temp * R.Im );
+ end if;
+ end "/";
+
+ function "/" ( L: in complex; R: in real ) return complex is
+ begin
+ if (R = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ return COMPLEX'(L.Re / R, L.Im / R);
+ end if;
+ end "/";
+
+ function "/" ( L: in real; R: in complex_polar) return complex is
+ variable zR : complex := POLAR_TO_COMPLEX( R );
+ variable temp : REAL := zR.Re ** 2 + zR.Im ** 2;
+ begin
+ if (R.mag = 0.0) or (temp = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ temp := L / temp;
+ return COMPLEX'( temp * zR.Re, -temp * zR.Im );
+ end if;
+ end "/";
+
+ function "/" ( L: in complex_polar; R: in real) return complex is
+ variable zL : complex := POLAR_TO_COMPLEX( L );
+ begin
+ if (R = 0.0) then
+ assert FALSE report "Attempt to divide by (0.0,0.0)"
+ severity ERROR;
+ return COMPLEX'(REAL'RIGHT, REAL'RIGHT);
+ else
+ return COMPLEX'(zL.Re / R, zL.Im / R);
+ end if;
+ end "/";
+end MATH_COMPLEX;
diff --git a/libraries/ieee/math_complex.vhdl b/libraries/ieee/math_complex.vhdl
new file mode 100644
index 000000000..2f9376bfb
--- /dev/null
+++ b/libraries/ieee/math_complex.vhdl
@@ -0,0 +1,126 @@
+---------------------------------------------------------------
+--
+-- This source file may be used and distributed without restriction.
+-- No declarations or definitions shall be included in this package.
+-- This package cannot be sold or distributed for profit.
+--
+-- ****************************************************************
+-- * *
+-- * W A R N I N G *
+-- * *
+-- * This DRAFT version IS NOT endorsed or approved by IEEE *
+-- * *
+-- ****************************************************************
+--
+-- Title: PACKAGE MATH_COMPLEX
+--
+-- Purpose: VHDL declarations for mathematical package MATH_COMPLEX
+-- which contains common complex constants and basic complex
+-- functions and operations.
+--
+-- Author: IEEE VHDL Math Package Study Group
+--
+-- Notes:
+-- The package body uses package IEEE.MATH_REAL
+--
+-- The package body shall be considered the formal definition of
+-- the semantics of this package. Tool developers may choose to implement
+-- the package body in the most efficient manner available to them.
+--
+-- History:
+-- Version 0.1 (Strawman) Jose A. Torres 6/22/92
+-- Version 0.2 Jose A. Torres 1/15/93
+-- Version 0.3 Jose A. Torres 4/13/93
+-- Version 0.4 Jose A. Torres 4/19/93
+-- Version 0.5 Jose A. Torres 4/20/93
+-- Version 0.6 Jose A. Torres 4/23/93 Added unary minus
+-- and CONJ for polar
+-- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility
+-- with package body.
+-------------------------------------------------------------
+Library IEEE;
+
+Package MATH_COMPLEX is
+
+
+ type COMPLEX is record RE, IM: real; end record;
+ type COMPLEX_VECTOR is array (integer range <>) of COMPLEX;
+ type COMPLEX_POLAR is record MAG: real; ARG: real; end record;
+
+ constant CBASE_1: complex := COMPLEX'(1.0, 0.0);
+ constant CBASE_j: complex := COMPLEX'(0.0, 1.0);
+ constant CZERO: complex := COMPLEX'(0.0, 0.0);
+
+ function CABS(Z: in complex ) return real;
+ -- returns absolute value (magnitude) of Z
+
+ function CARG(Z: in complex ) return real;
+ -- returns argument (angle) in radians of a complex number
+
+ function CMPLX(X: in real; Y: in real:= 0.0 ) return complex;
+ -- returns complex number X + iY
+
+ function "-" (Z: in complex ) return complex;
+ -- unary minus
+
+ function "-" (Z: in complex_polar ) return complex_polar;
+ -- unary minus
+
+ function CONJ (Z: in complex) return complex;
+ -- returns complex conjugate
+
+ function CONJ (Z: in complex_polar) return complex_polar;
+ -- returns complex conjugate
+
+ function CSQRT(Z: in complex ) return complex_vector;
+ -- returns square root of Z; 2 values
+
+ function CEXP(Z: in complex ) return complex;
+ -- returns e**Z
+
+ function COMPLEX_TO_POLAR(Z: in complex ) return complex_polar;
+ -- converts complex to complex_polar
+
+ function POLAR_TO_COMPLEX(Z: in complex_polar ) return complex;
+ -- converts complex_polar to complex
+
+
+ -- arithmetic operators
+
+ function "+" ( L: in complex; R: in complex ) return complex;
+ function "+" ( L: in complex_polar; R: in complex_polar) return complex;
+ function "+" ( L: in complex_polar; R: in complex ) return complex;
+ function "+" ( L: in complex; R: in complex_polar) return complex;
+ function "+" ( L: in real; R: in complex ) return complex;
+ function "+" ( L: in complex; R: in real ) return complex;
+ function "+" ( L: in real; R: in complex_polar) return complex;
+ function "+" ( L: in complex_polar; R: in real) return complex;
+
+ function "-" ( L: in complex; R: in complex ) return complex;
+ function "-" ( L: in complex_polar; R: in complex_polar) return complex;
+ function "-" ( L: in complex_polar; R: in complex ) return complex;
+ function "-" ( L: in complex; R: in complex_polar) return complex;
+ function "-" ( L: in real; R: in complex ) return complex;
+ function "-" ( L: in complex; R: in real ) return complex;
+ function "-" ( L: in real; R: in complex_polar) return complex;
+ function "-" ( L: in complex_polar; R: in real) return complex;
+
+ function "*" ( L: in complex; R: in complex ) return complex;
+ function "*" ( L: in complex_polar; R: in complex_polar) return complex;
+ function "*" ( L: in complex_polar; R: in complex ) return complex;
+ function "*" ( L: in complex; R: in complex_polar) return complex;
+ function "*" ( L: in real; R: in complex ) return complex;
+ function "*" ( L: in complex; R: in real ) return complex;
+ function "*" ( L: in real; R: in complex_polar) return complex;
+ function "*" ( L: in complex_polar; R: in real) return complex;
+
+
+ function "/" ( L: in complex; R: in complex ) return complex;
+ function "/" ( L: in complex_polar; R: in complex_polar) return complex;
+ function "/" ( L: in complex_polar; R: in complex ) return complex;
+ function "/" ( L: in complex; R: in complex_polar) return complex;
+ function "/" ( L: in real; R: in complex ) return complex;
+ function "/" ( L: in complex; R: in real ) return complex;
+ function "/" ( L: in real; R: in complex_polar) return complex;
+ function "/" ( L: in complex_polar; R: in real) return complex;
+end MATH_COMPLEX;
diff --git a/libraries/ieee/math_real-body.vhdl b/libraries/ieee/math_real-body.vhdl
new file mode 100644
index 000000000..1473f6787
--- /dev/null
+++ b/libraries/ieee/math_real-body.vhdl
@@ -0,0 +1,410 @@
+---------------------------------------------------------------
+--
+-- This source file may be used and distributed without restriction.
+-- No declarations or definitions shall be added to this package.
+-- This package cannot be sold or distributed for profit.
+--
+-- ****************************************************************
+-- * *
+-- * W A R N I N G *
+-- * *
+-- * This DRAFT version IS NOT endorsed or approved by IEEE *
+-- * *
+-- ****************************************************************
+--
+-- Title: PACKAGE BODY MATH_REAL
+--
+-- Library: This package shall be compiled into a library
+-- symbolically named IEEE.
+--
+-- Purpose: VHDL declarations for mathematical package MATH_REAL
+-- which contains common real constants, common real
+-- functions, and real trascendental functions.
+--
+-- Author: IEEE VHDL Math Package Study Group
+--
+-- Notes:
+-- The package body shall be considered the formal definition of
+-- the semantics of this package. Tool developers may choose to implement
+-- the package body in the most efficient manner available to them.
+--
+-- Source code and algorithms for this package body comes from the
+-- following sources:
+-- IEEE VHDL Math Package Study Group participants,
+-- U. of Mississippi, Mentor Graphics, Synopsys,
+-- Viewlogic/Vantage, Communications of the ACM (June 1988, Vol
+-- 31, Number 6, pp. 747, Pierre L'Ecuyer, Efficient and Portable
+-- Random Number Generators), Handbook of Mathematical Functions
+-- by Milton Abramowitz and Irene A. Stegun (Dover).
+--
+-- History:
+-- Version 0.1 Jose A. Torres 4/23/93 First draft
+-- Version 0.2 Jose A. Torres 5/28/93 Fixed potentially illegal code
+--
+-- GHDL history
+-- 2005-04-07 Initial version.
+-------------------------------------------------------------
+Library IEEE;
+
+Package body MATH_REAL is
+ --
+ -- non-trascendental functions
+ --
+ function SIGN (X: real ) return real is
+ -- returns 1.0 if X > 0.0; 0.0 if X == 0.0; -1.0 if X < 0.0
+ begin
+ assert false severity failure;
+ 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 FMAX (X, Y : real ) return real is
+ begin
+ assert false severity failure;
+ end FMAX;
+
+ function FMIN (X, Y : real ) return real is
+ begin
+ assert false severity failure;
+ end FMIN;
+
+ --
+ -- Pseudo-random number generators
+ --
+
+ procedure UNIFORM(variable Seed1,Seed2:inout integer;variable X:out real) is
+ -- returns a pseudo-random number with uniform distribution in the
+ -- interval (0.0, 1.0).
+ -- Before the first call to UNIFORM, the seed values (Seed1, Seed2) must
+ -- be initialized to values in the range [1, 2147483562] and
+ -- [1, 2147483398] respectively. The seed values are modified after
+ -- each call to UNIFORM.
+ -- This random number generator is portable for 32-bit computers, and
+ -- it has period ~2.30584*(10**18) for each set of seed values.
+ --
+ -- For VHDL-1992, the seeds will be global variables, functions to
+ -- initialize their values (INIT_SEED) will be provided, and the UNIFORM
+ -- procedure call will be modified accordingly.
+
+ 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 SRAND (seed: in integer ) return integer is
+ begin
+ assert false severity failure;
+ end SRAND;
+
+ function RAND return integer is
+ begin
+ assert false severity failure;
+ end RAND;
+
+ function GET_RAND_MAX return integer is
+ -- The value this function returns should be the same as
+ -- RAND_MAX in /usr/include/stdlib.h
+ begin
+ assert false
+ report "Be sure to update GET_RAND_MAX in mathpack.vhd"
+ severity note;
+ return 2147483647; -- i386 linux
+ end GET_RAND_MAX;
+
+ --
+ -- trascendental and trigonometric functions
+ --
+ function c_sqrt (x : real ) return real;
+ attribute foreign of c_sqrt : function is "VHPIDIRECT sqrt";
+
+ function c_sqrt (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_sqrt;
+
+ function SQRT (X : real ) return real is
+ begin
+ -- check validity of argument
+ if ( X < 0.0 ) then
+ assert false report "X < 0 in SQRT(X)"
+ severity ERROR;
+ return (0.0);
+ end if;
+ return c_sqrt(X);
+ end SQRT;
+
+ function CBRT (X : real ) return real is
+ begin
+ assert false severity failure;
+ end CBRT;
+
+ function "**" (X : integer; Y : real) return real is
+ -- returns Y power of X ==> X**Y;
+ -- error if X = 0 and Y <= 0.0
+ -- error if X < 0 and Y does not have an integer value
+ begin
+ -- check validity of argument
+ if ( X = 0 ) and ( Y <= 0.0 ) then
+ assert false report "X = 0 and Y <= 0.0 in X**Y"
+ severity ERROR;
+ return (0.0);
+ end if;
+
+ if ( X < 0 ) and ( Y /= REAL(INTEGER(Y)) ) then
+ assert false
+ report "X < 0 and Y \= integer in X**Y"
+ severity ERROR;
+ return (0.0);
+ end if;
+
+ -- compute the result
+ return EXP (Y * LOG (REAL(X)));
+ end "**";
+
+ function "**" (X : real; Y : real) return real is
+ -- returns Y power of X ==> X**Y;
+ -- error if X = 0.0 and Y <= 0.0
+ -- error if X < 0.0 and Y does not have an integer value
+ begin
+ -- check validity of argument
+ if ( X = 0.0 ) and ( Y <= 0.0 ) then
+ assert false report "X = 0.0 and Y <= 0.0 in X**Y"
+ severity ERROR;
+ return (0.0);
+ end if;
+
+ if ( X < 0.0 ) and ( Y /= REAL(INTEGER(Y)) ) then
+ assert false report "X < 0.0 and Y \= integer in X**Y"
+ severity ERROR;
+ return (0.0);
+ end if;
+
+ -- compute the result
+ return EXP (Y * LOG (X));
+ end "**";
+
+ function EXP (X : real ) return real is
+ begin
+ assert false severity failure;
+ end EXP;
+
+ function c_log (x : real ) return real;
+ attribute foreign of c_log : function is "VHPIDIRECT log";
+
+ function c_log (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_log;
+
+ function LOG (X : real ) return real is
+ -- returns natural logarithm of X; X > 0
+ --
+ -- This function computes the exponential using the following series:
+ -- log(x) = 2[ (x-1)/(x+1) + (((x-1)/(x+1))**3)/3.0 + ...] ; x > 0
+ --
+ begin
+ -- check validity of argument
+ if ( x <= 0.0 ) then
+ assert false report "X <= 0 in LOG(X)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+ return c_log(x);
+ end LOG;
+
+ function LOG (BASE: positive; X : real) return real is
+ -- returns logarithm base BASE of X; X > 0
+ begin
+ -- check validity of argument
+ if ( BASE <= 0 ) or ( x <= 0.0 ) then
+ assert false report "BASE <= 0 or X <= 0.0 in LOG(BASE, X)"
+ severity ERROR;
+ return(REAL'LOW);
+ end if;
+ -- compute the value
+ return (LOG(X)/LOG(REAL(BASE)));
+ end LOG;
+
+ 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;
+
+ function TAN (x : REAL) return REAL is
+ begin
+ assert false severity failure;
+ end TAN;
+
+ function c_asin (x : real ) return real;
+ attribute foreign of c_asin : function is "VHPIDIRECT asin";
+
+ function c_asin (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_asin;
+
+ function ASIN (x : real ) return real is
+ -- returns -PI/2 < asin X < PI/2; | X | <= 1
+ begin
+ if abs x > 1.0 then
+ assert false
+ report "Out of range parameter passed to ASIN"
+ severity ERROR;
+ return x;
+ else
+ return c_asin(x);
+ end if;
+ end ASIN;
+
+ function c_acos (x : real ) return real;
+ attribute foreign of c_acos : function is "VHPIDIRECT acos";
+
+ function c_acos (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_acos;
+
+ function ACOS (x : REAL) return REAL is
+ -- returns 0 < acos X < PI; | X | <= 1
+ begin
+ if abs x > 1.0 then
+ assert false
+ report "Out of range parameter passed to ACOS"
+ severity ERROR;
+ return x;
+ else
+ return c_acos(x);
+ end if;
+ end ACOS;
+
+ function ATAN (x : REAL) return REAL is
+ -- returns -PI/2 < atan X < PI/2
+ begin
+ assert false severity failure;
+ end ATAN;
+
+ function c_atan2 (x : real; y : real) return real;
+ attribute foreign of c_atan2 : function is "VHPIDIRECT atan2";
+
+ function c_atan2 (x : real; y: real) return real is
+ begin
+ assert false severity failure;
+ end c_atan2;
+
+ function ATAN2 (x : REAL; y : REAL) return REAL is
+ -- returns atan (X/Y); -PI < atan2(X,Y) < PI; Y /= 0.0
+ begin
+ if y = 0.0 and x = 0.0 then
+ assert false
+ report "atan2(0.0, 0.0) is undetermined, returned 0,0"
+ severity NOTE;
+ return 0.0;
+ else
+ return c_atan2(x,y);
+ end if;
+ end ATAN2;
+
+
+ function SINH (X : real) return real is
+ -- hyperbolic sine; returns (e**X - e**(-X))/2
+ begin
+ assert false severity failure;
+ end SINH;
+
+ function COSH (X : real) return real is
+ -- hyperbolic cosine; returns (e**X + e**(-X))/2
+ begin
+ assert false severity failure;
+ end COSH;
+
+ function TANH (X : real) return real is
+ -- hyperbolic tangent; -- returns (e**X - e**(-X))/(e**X + e**(-X))
+ begin
+ assert false severity failure;
+ end TANH;
+
+ function ASINH (X : real) return real is
+ -- returns ln( X + sqrt( X**2 + 1))
+ begin
+ assert false severity failure;
+ end ASINH;
+
+ function c_acosh (x : real ) return real;
+ attribute foreign of c_acosh : function is "VHPIDIRECT acosh";
+
+ function c_acosh (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_acosh;
+
+ function ACOSH (X : real) return real is
+ -- returns ln( X + sqrt( X**2 - 1)); X >= 1
+ begin
+ if abs x >= 1.0 then
+ assert false report "Out of range parameter passed to ACOSH"
+ severity ERROR;
+ return x;
+ end if;
+ return c_acosh(x);
+ end ACOSH;
+
+ function c_atanh (x : real ) return real;
+ attribute foreign of c_atanh : function is "VHPIDIRECT atanh";
+
+ function c_atanh (x : real ) return real is
+ begin
+ assert false severity failure;
+ end c_atanh;
+
+ function ATANH (X : real) return real is
+ -- returns (ln( (1 + X)/(1 - X)))/2 ; | X | < 1
+ begin
+ if abs x < 1.0 then
+ assert false report "Out of range parameter passed to ATANH"
+ severity ERROR;
+ return x;
+ end if;
+ return c_atanh(x);
+ end ATANH;
+
+end MATH_REAL;
diff --git a/libraries/ieee/math_real.vhdl b/libraries/ieee/math_real.vhdl
new file mode 100644
index 000000000..c70d2160b
--- /dev/null
+++ b/libraries/ieee/math_real.vhdl
@@ -0,0 +1,223 @@
+------------------------------------------------------------------------
+--
+-- This source file may be used and distributed without restriction.
+-- No declarations or definitions shall be added to this package.
+-- This package cannot be sold or distributed for profit.
+--
+-- ****************************************************************
+-- * *
+-- * W A R N I N G *
+-- * *
+-- * This DRAFT version IS NOT endorsed or approved by IEEE *
+-- * *
+-- ****************************************************************
+--
+-- Title: PACKAGE MATH_REAL
+--
+-- Library: This package shall be compiled into a library
+-- symbolically named IEEE.
+--
+-- Purpose: VHDL declarations for mathematical package MATH_REAL
+-- which contains common real constants, common real
+-- functions, and real trascendental functions.
+--
+-- Author: IEEE VHDL Math Package Study Group
+--
+-- Notes:
+-- The package body shall be considered the formal definition of
+-- the semantics of this package. Tool developers may choose to implement
+-- the package body in the most efficient manner available to them.
+--
+-- History:
+-- Version 0.1 (Strawman) Jose A. Torres 6/22/92
+-- Version 0.2 Jose A. Torres 1/15/93
+-- Version 0.3 Jose A. Torres 4/13/93
+-- Version 0.4 Jose A. Torres 4/19/93
+-- Version 0.5 Jose A. Torres 4/20/93 Added RANDOM()
+-- Version 0.6 Jose A. Torres 4/23/93 Renamed RANDOM as
+-- UNIFORM. Modified
+-- rights banner.
+-- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility
+-- with package body.
+--
+-- GHDL history
+-- 2005-04-07 Initial version.
+-- 2005-09-01 Some PI constants added.
+-------------------------------------------------------------
+Library IEEE;
+
+Package MATH_REAL is
+
+ --
+ -- commonly used constants
+ --
+ constant MATH_E : real := 2.71828_18284_59045_23536; -- e
+ constant MATH_1_OVER_E : real := 0.36787_94411_71442_32160; -- 1/e
+ constant MATH_PI : real := 3.14159_26535_89793_23846; -- pi
+ constant MATH_2_PI : real := 2.0 * MATH_PI; -- 2 * pi
+ constant MATH_1_OVER_PI : real := 0.31830_98861_83790_67154; -- 1/pi
+ constant MATH_PI_OVER_2 : real := 1.57079_63267_94896_61923; -- pi / 2
+ constant MATH_PI_OVER_4 : real := 0.78539_81633_97448_30962; -- pi / 4
+ constant MATH_LOG_OF_2 : real := 0.69314_71805_59945_30942;
+ -- natural log of 2
+ constant MATH_LOG_OF_10: real := 2.30258_50929_94045_68402;
+ -- natural log of10
+ constant MATH_LOG2_OF_E: real := 1.44269_50408_88963_4074;
+ -- log base 2 of e
+ constant MATH_LOG10_OF_E: real := 0.43429_44819_03251_82765;
+ -- log base 10 of e
+ constant MATH_SQRT2: real := 1.41421_35623_73095_04880;
+ -- sqrt of 2
+ constant MATH_SQRT1_2: real := 0.70710_67811_86547_52440;
+ -- sqrt of 1/2
+ constant MATH_SQRT_PI: real := 1.77245_38509_05516_02730;
+ -- sqrt of pi
+ constant MATH_DEG_TO_RAD: real := 0.01745_32925_19943_29577;
+ -- conversion factor from degree to radian
+ constant MATH_RAD_TO_DEG: real := 57.29577_95130_82320_87685;
+ -- conversion factor from radian to degree
+
+ --
+ -- function declarations
+ --
+ function SIGN (X: real ) return real;
+ -- returns 1.0 if X > 0.0; 0.0 if X == 0.0; -1.0 if X < 0.0
+
+ function CEIL (X : real ) return real;
+ attribute foreign of ceil : function is "VHPIDIRECT ceil";
+ -- returns smallest integer value (as real) not less than X
+
+ function FLOOR (X : real ) return real;
+ attribute foreign of floor : function is "VHPIDIRECT floor";
+ -- returns largest integer value (as real) not greater than X
+
+ function ROUND (X : real ) return real;
+ attribute foreign of round : function is "VHPIDIRECT round";
+ -- returns integer FLOOR(X + 0.5) if X > 0;
+ -- return integer CEIL(X - 0.5) if X < 0
+
+ function FMAX (X, Y : real ) return real;
+ attribute foreign of fmax : function is "VHPIDIRECT fmax";
+ -- returns the algebraically larger of X and Y
+
+ function FMIN (X, Y : real ) return real;
+ attribute foreign of fmin : function is "VHPIDIRECT fmin";
+ -- returns the algebraically smaller of X and Y
+
+ procedure UNIFORM (variable Seed1,Seed2:inout integer; variable X:out real);
+ -- returns a pseudo-random number with uniform distribution in the
+ -- interval (0.0, 1.0).
+ -- Before the first call to UNIFORM, the seed values (Seed1, Seed2) must
+ -- be initialized to values in the range [1, 2147483562] and
+ -- [1, 2147483398] respectively. The seed values are modified after
+ -- each call to UNIFORM.
+ -- This random number generator is portable for 32-bit computers, and
+ -- it has period ~2.30584*(10**18) for each set of seed values.
+ --
+ -- For VHDL-1992, the seeds will be global variables, functions to
+ -- initialize their values (INIT_SEED) will be provided, and the UNIFORM
+ -- procedure call will be modified accordingly.
+
+ function SRAND (seed: in integer ) return integer;
+ attribute foreign of srand : function is "VHPIDIRECT srand";
+ --
+ -- sets value of seed for sequence of
+ -- pseudo-random numbers.
+ -- It uses the foreign native C function srand().
+
+ function RAND return integer;
+ attribute foreign of rand : function is "VHPIDIRECT rand";
+ --
+ -- returns an integer pseudo-random number with uniform distribution.
+ -- It uses the foreign native C function rand().
+ -- Seed for the sequence is initialized with the
+ -- SRAND() function and value of the seed is changed every
+ -- time SRAND() is called, but it is not visible.
+ -- The range of generated values is platform dependent.
+
+ function GET_RAND_MAX return integer;
+ --
+ -- returns the upper bound of the range of the
+ -- pseudo-random numbers generated by RAND().
+ -- The support for this function is platform dependent, and
+ -- it uses foreign native C functions or constants.
+ -- It may not be available in some platforms.
+ -- Note: the value of (RAND() / GET_RAND_MAX()) is a
+ -- pseudo-random number distributed between 0 & 1.
+
+ function SQRT (X : real ) return real;
+ -- returns square root of X; X >= 0
+
+ function CBRT (X : real ) return real;
+ attribute foreign of cbrt : function is "VHPIDIRECT cbrt";
+ -- returns cube root of X
+
+ function "**" (X : integer; Y : real) return real;
+ -- returns Y power of X ==> X**Y;
+ -- error if X = 0 and Y <= 0.0
+ -- error if X < 0 and Y does not have an integer value
+
+ function "**" (X : real; Y : real) return real;
+ -- returns Y power of X ==> X**Y;
+ -- error if X = 0.0 and Y <= 0.0
+ -- error if X < 0.0 and Y does not have an integer value
+
+ function EXP (X : real ) return real;
+ attribute foreign of exp : function is "VHPIDIRECT exp";
+ -- returns e**X; where e = MATH_E
+
+ function LOG (X : real ) return real;
+ -- returns natural logarithm of X; X > 0
+
+ function LOG (BASE: positive; X : real) return real;
+ -- returns logarithm base BASE of X; X > 0
+
+ function SIN (X : real ) return real;
+ attribute foreign of sin : function is "VHPIDIRECT sin";
+ -- returns sin X; X in radians
+
+ function COS ( X : real ) return real;
+ attribute foreign of cos : function is "VHPIDIRECT cos";
+ -- returns cos X; X in radians
+
+ function TAN (X : real ) return real;
+ attribute foreign of tan : function is "VHPIDIRECT tan";
+ -- returns tan X; X in radians
+ -- X /= ((2k+1) * PI/2), where k is an integer
+
+ function ASIN (X : real ) return real;
+ -- returns -PI/2 < asin X < PI/2; | X | <= 1
+
+ function ACOS (X : real ) return real;
+ -- returns 0 < acos X < PI; | X | <= 1
+
+ function ATAN (X : real) return real;
+ attribute foreign of atan : function is "VHPIDIRECT atan";
+ -- returns -PI/2 < atan X < PI/2
+
+ function ATAN2 (X : real; Y : real) return real;
+ -- returns atan (X/Y); -PI < atan2(X,Y) < PI; Y /= 0.0
+
+ function SINH (X : real) return real;
+ attribute foreign of sinh : function is "VHPIDIRECT sinh";
+ -- hyperbolic sine; returns (e**X - e**(-X))/2
+
+ function COSH (X : real) return real;
+ attribute foreign of cosh : function is "VHPIDIRECT cosh";
+ -- hyperbolic cosine; returns (e**X + e**(-X))/2
+
+ function TANH (X : real) return real;
+ attribute foreign of tanh : function is "VHPIDIRECT tanh";
+ -- hyperbolic tangent; -- returns (e**X - e**(-X))/(e**X + e**(-X))
+
+ function ASINH (X : real) return real;
+ attribute foreign of asinh : function is "VHPIDIRECT asinh";
+ -- returns ln( X + sqrt( X**2 + 1))
+
+ function ACOSH (X : real) return real;
+ -- returns ln( X + sqrt( X**2 - 1)); X >= 1
+
+ function ATANH (X : real) return real;
+ -- returns (ln( (1 + X)/(1 - X)))/2 ; | X | < 1
+
+end MATH_REAL;
diff --git a/libraries/ieee/numeric_bit-body.vhdl b/libraries/ieee/numeric_bit-body.vhdl
new file mode 100644
index 000000000..895594631
--- /dev/null
+++ b/libraries/ieee/numeric_bit-body.vhdl
@@ -0,0 +1,1818 @@
+-- -----------------------------------------------------------------------------
+--
+-- Copyright 1995 by IEEE. All rights reserved.
+--
+-- This source file is considered by the IEEE to be an essential part of the use
+-- of the standard 1076.3 and as such may be distributed without change, except
+-- as permitted by the standard. This source file may not be sold or distributed
+-- for profit. This package may be modified to include additional data required
+-- by tools, but must in no way change the external interfaces or simulation
+-- behaviour of the description. It is permissible to add comments and/or
+-- attributes to the package declarations, but not to change or delete any
+-- original lines of the approved package declaration. The package body may be
+-- changed only in accordance with the terms of clauses 7.1 and 7.2 of the
+-- standard.
+--
+-- Title : Standard VHDL Synthesis Package (1076.3, NUMERIC_BIT)
+--
+-- Library : This package shall be compiled into a library symbolically
+-- : named IEEE.
+--
+-- Developers : IEEE DASC Synthesis Working Group, PAR 1076.3
+--
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Two numeric types are defined:
+-- : -- > UNSIGNED: represents an UNSIGNED number in vector form
+-- : -- > SIGNED: represents a SIGNED number in vector form
+-- : The base element type is type BIT.
+-- : The leftmost bit is treated as the most significant bit.
+-- : Signed vectors are represented in two's complement form.
+-- : This package contains overloaded arithmetic operators on
+-- : the SIGNED and UNSIGNED types. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array is
+-- : returned (exceptions, if any, are noted individually).
+--
+-- Limitation :
+--
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : NUMERIC_BIT. The NUMERIC_BIT package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+-- :
+-- -----------------------------------------------------------------------------
+-- Version : 2.4
+-- Date : 12 April 1995
+-- -----------------------------------------------------------------------------
+
+--==============================================================================
+--======================= Package Body =========================================
+--==============================================================================
+
+package body NUMERIC_BIT is
+
+ -- null range array constants
+
+ constant NAU: UNSIGNED(0 downto 1) := (others => '0');
+ constant NAS: SIGNED(0 downto 1) := (others => '0');
+
+ -- implementation controls
+
+ constant NO_WARNING: BOOLEAN := FALSE; -- default to emit warnings
+
+ --=========================Local Subprograms =================================
+
+ function MAX (LEFT, RIGHT: INTEGER) return INTEGER is
+ begin
+ if LEFT > RIGHT then return LEFT;
+ else return RIGHT;
+ end if;
+ end MAX;
+
+ function MIN (LEFT, RIGHT: INTEGER) return INTEGER is
+ begin
+ if LEFT < RIGHT then return LEFT;
+ else return RIGHT;
+ end if;
+ end MIN;
+
+ function SIGNED_NUM_BITS (ARG: INTEGER) return NATURAL is
+ variable NBITS: NATURAL;
+ variable N: NATURAL;
+ begin
+ if ARG >= 0 then
+ N := ARG;
+ else
+ N := -(ARG+1);
+ end if;
+ NBITS := 1;
+ while N > 0 loop
+ NBITS := NBITS+1;
+ N := N / 2;
+ end loop;
+ return NBITS;
+ end SIGNED_NUM_BITS;
+
+ function UNSIGNED_NUM_BITS (ARG: NATURAL) return NATURAL is
+ variable NBITS: NATURAL;
+ variable N: NATURAL;
+ begin
+ N := ARG;
+ NBITS := 1;
+ while N > 1 loop
+ NBITS := NBITS+1;
+ N := N / 2;
+ end loop;
+ return NBITS;
+ end UNSIGNED_NUM_BITS;
+
+ ------------------------------------------------------------------------------
+ -- this internal function computes the addition of two UNSIGNED
+ -- with input carry
+ -- * the two arguments are of the same length
+
+ function ADD_UNSIGNED (L, R: UNSIGNED; C: BIT) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(L_LEFT downto 0) is R;
+ variable RESULT: UNSIGNED(L_LEFT downto 0);
+ variable CBIT: BIT := C;
+ begin
+ for I in 0 to L_LEFT loop
+ RESULT(I) := CBIT xor XL(I) xor XR(I);
+ CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
+ end loop;
+ return RESULT;
+ end ADD_UNSIGNED;
+
+ -- this internal function computes the addition of two SIGNED
+ -- with input carry
+ -- * the two arguments are of the same length
+
+ function ADD_SIGNED (L, R: SIGNED; C: BIT) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(L_LEFT downto 0) is R;
+ variable RESULT: SIGNED(L_LEFT downto 0);
+ variable CBIT: BIT := C;
+ begin
+ for I in 0 to L_LEFT loop
+ RESULT(I) := CBIT xor XL(I) xor XR(I);
+ CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
+ end loop;
+ return RESULT;
+ end ADD_SIGNED;
+
+ ------------------------------------------------------------------------------
+
+ -- this internal procedure computes UNSIGNED division
+ -- giving the quotient and remainder.
+ procedure DIVMOD (NUM, XDENOM: UNSIGNED; XQUOT, XREMAIN: out UNSIGNED) is
+ variable TEMP: UNSIGNED(NUM'LENGTH downto 0);
+ variable QUOT: UNSIGNED(MAX(NUM'LENGTH, XDENOM'LENGTH)-1 downto 0);
+ alias DENOM: UNSIGNED(XDENOM'LENGTH-1 downto 0) is XDENOM;
+ variable TOPBIT: INTEGER;
+ begin
+ TEMP := "0"&NUM;
+ QUOT := (others => '0');
+ TOPBIT := -1;
+ for J in DENOM'RANGE loop
+ if DENOM(J)='1' then
+ TOPBIT := J;
+ exit;
+ end if;
+ end loop;
+ assert TOPBIT >= 0 report "DIV, MOD, or REM by zero" severity ERROR;
+
+ for J in NUM'LENGTH-(TOPBIT+1) downto 0 loop
+ if TEMP(TOPBIT+J+1 downto J) >= "0"&DENOM(TOPBIT downto 0) then
+ TEMP(TOPBIT+J+1 downto J) := (TEMP(TOPBIT+J+1 downto J))
+ -("0"&DENOM(TOPBIT downto 0));
+ QUOT(J) := '1';
+ end if;
+ assert TEMP(TOPBIT+J+1)='0'
+ report "internal error in the division algorithm"
+ severity ERROR;
+ end loop;
+ XQUOT := RESIZE(QUOT, XQUOT'LENGTH);
+ XREMAIN := RESIZE(TEMP, XREMAIN'LENGTH);
+ end DIVMOD;
+
+ -----------------Local Subprograms - shift/rotate ops-------------------------
+
+ function XSLL (ARG: BIT_VECTOR; COUNT: NATURAL) return BIT_VECTOR is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: BIT_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: BIT_VECTOR(ARG_L downto 0) := (others => '0');
+ begin
+ if COUNT <= ARG_L then
+ RESULT(ARG_L downto COUNT) := XARG(ARG_L-COUNT downto 0);
+ end if;
+ return RESULT;
+ end XSLL;
+
+ function XSRL (ARG: BIT_VECTOR; COUNT: NATURAL) return BIT_VECTOR is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: BIT_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: BIT_VECTOR(ARG_L downto 0) := (others => '0');
+ begin
+ if COUNT <= ARG_L then
+ RESULT(ARG_L-COUNT downto 0) := XARG(ARG_L downto COUNT);
+ end if;
+ return RESULT;
+ end XSRL;
+
+ function XSRA (ARG: BIT_VECTOR; COUNT: NATURAL) return BIT_VECTOR is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: BIT_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: BIT_VECTOR(ARG_L downto 0);
+ variable XCOUNT: NATURAL := COUNT;
+ begin
+ if ((ARG'LENGTH <= 1) or (XCOUNT = 0)) then return ARG;
+ else
+ if (XCOUNT > ARG_L) then XCOUNT := ARG_L;
+ end if;
+ RESULT(ARG_L-XCOUNT downto 0) := XARG(ARG_L downto XCOUNT);
+ RESULT(ARG_L downto (ARG_L - XCOUNT + 1)) := (others => XARG(ARG_L));
+ end if;
+ return RESULT;
+ end XSRA;
+
+ function XROL (ARG: BIT_VECTOR; COUNT: NATURAL) return BIT_VECTOR is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: BIT_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: BIT_VECTOR(ARG_L downto 0) := XARG;
+ variable COUNTM: INTEGER;
+ begin
+ COUNTM := COUNT mod (ARG_L + 1);
+ if COUNTM /= 0 then
+ RESULT(ARG_L downto COUNTM) := XARG(ARG_L-COUNTM downto 0);
+ RESULT(COUNTM-1 downto 0) := XARG(ARG_L downto ARG_L-COUNTM+1);
+ end if;
+ return RESULT;
+ end XROL;
+
+ function XROR (ARG: BIT_VECTOR; COUNT: NATURAL) return BIT_VECTOR is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: BIT_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: BIT_VECTOR(ARG_L downto 0) := XARG;
+ variable COUNTM: INTEGER;
+ begin
+ COUNTM := COUNT mod (ARG_L + 1);
+ if COUNTM /= 0 then
+ RESULT(ARG_L-COUNTM downto 0) := XARG(ARG_L downto COUNTM);
+ RESULT(ARG_L downto ARG_L-COUNTM+1) := XARG(COUNTM-1 downto 0);
+ end if;
+ return RESULT;
+ end XROR;
+
+ ---------------- Local Subprograms - Relational Operators --------------------
+
+ -- General "=" for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_EQUAL (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return BIT_VECTOR(L) = BIT_VECTOR(R);
+ end UNSIGNED_EQUAL;
+
+ --
+ -- General "=" for SIGNED vectors, same length
+ --
+ function SIGNED_EQUAL (L, R: SIGNED) return BOOLEAN is
+ begin
+ return BIT_VECTOR(L) = BIT_VECTOR(R);
+ end SIGNED_EQUAL;
+
+ --
+ -- General "<" for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_LESS (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return BIT_VECTOR(L) < BIT_VECTOR(R);
+ end UNSIGNED_LESS;
+
+ --
+ -- General "<" function for SIGNED vectors, same length
+ --
+ function SIGNED_LESS (L, R: SIGNED) return BOOLEAN is
+ -- Need aliases to assure index direction
+ variable INTERN_L: SIGNED(0 to L'LENGTH-1);
+ variable INTERN_R: SIGNED(0 to R'LENGTH-1);
+ begin
+ INTERN_L := L;
+ INTERN_R := R;
+ INTERN_L(0) := not INTERN_L(0);
+ INTERN_R(0) := not INTERN_R(0);
+ return BIT_VECTOR(INTERN_L) < BIT_VECTOR(INTERN_R);
+ end SIGNED_LESS;
+
+ --
+ -- General "<=" function for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_LESS_OR_EQUAL (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return BIT_VECTOR(L) <= BIT_VECTOR(R);
+ end UNSIGNED_LESS_OR_EQUAL;
+
+ --
+ -- General "<=" function for SIGNED vectors, same length
+ --
+ function SIGNED_LESS_OR_EQUAL (L, R: SIGNED) return BOOLEAN is
+ -- Need aliases to assure index direction
+ variable INTERN_L: SIGNED(0 to L'LENGTH-1);
+ variable INTERN_R: SIGNED(0 to R'LENGTH-1);
+ begin
+ INTERN_L := L;
+ INTERN_R := R;
+ INTERN_L(0) := not INTERN_L(0);
+ INTERN_R(0) := not INTERN_R(0);
+ return BIT_VECTOR(INTERN_L) <= BIT_VECTOR(INTERN_R);
+ end SIGNED_LESS_OR_EQUAL;
+
+ --====================== Exported Functions ==================================
+
+ -- Id: A.1
+ function "abs" (ARG: SIGNED) return SIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ variable RESULT: SIGNED(ARG_LEFT downto 0);
+ begin
+ if ARG'LENGTH < 1 then return NAS;
+ end if;
+ RESULT := ARG;
+ if RESULT(RESULT'LEFT) = '1' then
+ RESULT := -RESULT;
+ end if;
+ return RESULT;
+ end "abs";
+
+ -- Id: A.2
+ function "-" (ARG: SIGNED) return SIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: SIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT: SIGNED(ARG_LEFT downto 0);
+ variable CBIT: BIT := '1';
+ begin
+ if ARG'LENGTH < 1 then return NAS;
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ RESULT(I) := not(XARG(I)) xor CBIT;
+ CBIT := CBIT and not(XARG(I));
+ end loop;
+ return RESULT;
+ end "-";
+
+ --============================================================================
+
+ -- Id: A.3
+ function "+" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ return ADD_UNSIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0');
+ end "+";
+
+ -- Id: A.4
+ function "+" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ return ADD_SIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0');
+ end "+";
+
+ -- Id: A.5
+ function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L + TO_UNSIGNED(R, L'LENGTH);
+ end "+";
+
+ -- Id: A.6
+ function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) + R;
+ end "+";
+
+ -- Id: A.7
+ function "+" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L + TO_SIGNED(R, L'LENGTH);
+ end "+";
+
+ -- Id: A.8
+ function "+" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) + R;
+ end "+";
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ return ADD_UNSIGNED(RESIZE(L, SIZE),
+ not(RESIZE(R, SIZE)),
+ '1');
+ end "-";
+
+ -- Id: A.10
+ function "-" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ return ADD_SIGNED(RESIZE(L, SIZE),
+ not(RESIZE(R, SIZE)),
+ '1');
+ end "-";
+
+ -- Id: A.11
+ function "-" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L - TO_UNSIGNED(R, L'LENGTH);
+ end "-";
+
+ -- Id: A.12
+ function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) - R;
+ end "-";
+
+ -- Id: A.13
+ function "-" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L - TO_SIGNED(R, L'LENGTH);
+ end "-";
+
+ -- Id: A.14
+ function "-" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) - R;
+ end "-";
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable RESULT: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0) := (others => '0');
+ variable ADVAL: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ ADVAL := RESIZE(XR, RESULT'LENGTH);
+ for I in 0 to L_LEFT loop
+ if XL(I)='1' then RESULT := RESULT + ADVAL;
+ end if;
+ ADVAL := SHIFT_LEFT(ADVAL, 1);
+ end loop;
+ return RESULT;
+ end "*";
+
+ -- Id: A.16
+ function "*" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ variable XL: SIGNED(L_LEFT downto 0);
+ variable XR: SIGNED(R_LEFT downto 0);
+ variable RESULT: SIGNED((L_LEFT+R_LEFT+1) downto 0) := (others => '0');
+ variable ADVAL: SIGNED((L_LEFT+R_LEFT+1) downto 0);
+ begin
+ if ((L_LEFT < 0) or (R_LEFT < 0)) then return NAS;
+ end if;
+ XL := L;
+ XR := R;
+ ADVAL := RESIZE(XR, RESULT'LENGTH);
+ for I in 0 to L_LEFT-1 loop
+ if XL(I)='1' then RESULT := RESULT + ADVAL;
+ end if;
+ ADVAL := SHIFT_LEFT(ADVAL, 1);
+ end loop;
+ if XL(L_LEFT)='1' then
+ RESULT := RESULT - ADVAL;
+ end if;
+ return RESULT;
+ end "*";
+
+ -- Id: A.17
+ function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L * TO_UNSIGNED(R, L'LENGTH);
+ end "*";
+
+ -- Id: A.18
+ function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) * R;
+ end "*";
+
+ -- Id: A.19
+ function "*" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L * TO_SIGNED(R, L'LENGTH);
+ end "*";
+
+ -- Id: A.20
+ function "*" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) * R;
+ end "*";
+
+ --============================================================================
+
+ -- Id: A.21
+ function "/" (L, R: UNSIGNED) return UNSIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ DIVMOD(L, R, FQUOT, FREMAIN);
+ return FQUOT;
+ end "/";
+
+ -- Id: A.22
+ function "/" (L, R: SIGNED) return SIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable QNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ if L(L'LEFT)='1' then
+ XNUM := UNSIGNED(-L);
+ QNEG := TRUE;
+ else
+ XNUM := UNSIGNED(L);
+ end if;
+ if R(R'LEFT)='1' then
+ XDENOM := UNSIGNED(-R);
+ QNEG := not QNEG;
+ else
+ XDENOM := UNSIGNED(R);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if QNEG then FQUOT := "0"-FQUOT;
+ end if;
+ return SIGNED(FQUOT);
+ end "/";
+
+ -- Id: A.23
+ function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, QUOT: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ if (R_LENGTH > L'LENGTH) then
+ QUOT := (others => '0');
+ return RESIZE(QUOT, L'LENGTH);
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ QUOT := RESIZE((L / XR), QUOT'LENGTH);
+ return RESIZE(QUOT, L'LENGTH);
+ end "/";
+
+ -- Id: A.24
+ function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, QUOT: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAU;
+ end if;
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ QUOT := RESIZE((XL / R), QUOT'LENGTH);
+ if L_LENGTH > R'LENGTH
+ and QUOT(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""/"": Quotient Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(QUOT, R'LENGTH);
+ end "/";
+
+ -- Id: A.25
+ function "/" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, QUOT: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ if (R_LENGTH > L'LENGTH) then
+ QUOT := (others => '0');
+ return RESIZE(QUOT, L'LENGTH);
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ QUOT := RESIZE((L / XR), QUOT'LENGTH);
+ return RESIZE(QUOT, L'LENGTH);
+ end "/";
+
+ -- Id: A.26
+ function "/" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, QUOT: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ QUOT := RESIZE((XL / R), QUOT'LENGTH);
+ if L_LENGTH > R'LENGTH and QUOT(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => QUOT(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""/"": Quotient Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(QUOT, R'LENGTH);
+ end "/";
+
+ --============================================================================
+
+ -- Id: A.27
+ function "rem" (L, R: UNSIGNED) return UNSIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ DIVMOD(L, R, FQUOT, FREMAIN);
+ return FREMAIN;
+ end "rem";
+
+ -- Id: A.28
+ function "rem" (L, R: SIGNED) return SIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable RNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ if L(L'LEFT)='1' then
+ XNUM := UNSIGNED(-L);
+ RNEG := TRUE;
+ else
+ XNUM := UNSIGNED(L);
+ end if;
+ if R(R'LEFT)='1' then
+ XDENOM := UNSIGNED(-R);
+ else
+ XDENOM := UNSIGNED(R);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if RNEG then
+ FREMAIN := "0"-FREMAIN;
+ end if;
+ return SIGNED(FREMAIN);
+ end "rem";
+
+ -- Id: A.29
+ function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ XREM := RESIZE((L rem XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "rem";
+
+ -- Id: A.30
+ function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAU;
+ end if;
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL rem R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "rem";
+
+ -- Id: A.31
+ function "rem" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, XREM: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ XREM := RESIZE((L rem XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "rem";
+
+ -- Id: A.32
+ function "rem" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL rem R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "rem";
+
+ --============================================================================
+
+ -- Id: A.33
+ function "mod" (L, R: UNSIGNED) return UNSIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ DIVMOD(L, R, FQUOT, FREMAIN);
+ return FREMAIN;
+ end "mod";
+
+ -- Id: A.34
+ function "mod" (L, R: SIGNED) return SIGNED is
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable RNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ if L(L'LEFT)='1' then
+ XNUM := UNSIGNED(-L);
+ else
+ XNUM := UNSIGNED(L);
+ end if;
+ if R(R'LEFT)='1' then
+ XDENOM := UNSIGNED(-R);
+ RNEG := TRUE;
+ else
+ XDENOM := UNSIGNED(R);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if RNEG and L(L'LEFT)='1' then
+ FREMAIN := "0"-FREMAIN;
+ elsif RNEG and FREMAIN/="0" then
+ FREMAIN := FREMAIN-XDENOM;
+ elsif L(L'LEFT)='1' and FREMAIN/="0" then
+ FREMAIN := XDENOM-FREMAIN;
+ end if;
+ return SIGNED(FREMAIN);
+ end "mod";
+
+ -- Id: A.35
+ function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ XREM := RESIZE((L mod XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""mod"": modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "mod";
+
+ -- Id: A.36
+ function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAU;
+ end if;
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL mod R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""mod"": modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "mod";
+
+ -- Id: A.37
+ function "mod" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, XREM: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ XREM := RESIZE((L mod XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""mod"": modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "mod";
+
+ -- Id: A.38
+ function "mod" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL mod R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_BIT.""mod"": modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "mod";
+
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end ">";
+
+ -- Id: C.2
+ function ">" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end ">";
+
+ -- Id: C.3
+ function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R'LENGTH), R);
+ end ">";
+
+ -- Id: C.4
+ function ">" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R'LENGTH), R);
+ end ">";
+
+ -- Id: C.5
+ function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(L, TO_UNSIGNED(R, L'LENGTH));
+ end ">";
+
+ -- Id: C.6
+ function ">" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(L, TO_SIGNED(R, L'LENGTH));
+ end ">";
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "<";
+
+ -- Id: C.8
+ function "<" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "<";
+
+ -- Id: C.9
+ function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return UNSIGNED_LESS(TO_UNSIGNED(L, R'LENGTH), R);
+ end "<";
+
+ -- Id: C.10
+ function "<" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return SIGNED_LESS(TO_SIGNED(L, R'LENGTH), R);
+ end "<";
+
+ -- Id: C.11
+ function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return UNSIGNED_LESS(L, TO_UNSIGNED(R, L'LENGTH));
+ end "<";
+
+ -- Id: C.12
+ function "<" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return SIGNED_LESS(L, TO_SIGNED(R, L'LENGTH));
+ end "<";
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "<=";
+
+ -- Id: C.14
+ function "<=" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "<=";
+
+ -- Id: C.15
+ function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R'LENGTH), R);
+ end "<=";
+
+ -- Id: C.16
+ function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R'LENGTH), R);
+ end "<=";
+
+ -- Id: C.17
+ function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(L, TO_UNSIGNED(R, L'LENGTH));
+ end "<=";
+
+ -- Id: C.18
+ function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(L, TO_SIGNED(R, L'LENGTH));
+ end "<=";
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not UNSIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end ">=";
+
+ -- Id: C.20
+ function ">=" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not SIGNED_LESS(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end ">=";
+
+ -- Id: C.21
+ function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not UNSIGNED_LESS(TO_UNSIGNED(L, R'LENGTH), R);
+ end ">=";
+
+ -- Id: C.22
+ function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not SIGNED_LESS(TO_SIGNED(L, R'LENGTH), R);
+ end ">=";
+
+ -- Id: C.23
+ function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not UNSIGNED_LESS(L, TO_UNSIGNED(R, L'LENGTH));
+ end ">=";
+
+ -- Id: C.24
+ function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not SIGNED_LESS(L, TO_SIGNED(R, L'LENGTH));
+ end ">=";
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "=";
+
+ -- Id: C.26
+ function "=" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE));
+ end "=";
+
+ -- Id: C.27
+ function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(TO_UNSIGNED(L, R'LENGTH), R);
+ end "=";
+
+ -- Id: C.28
+ function "=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return FALSE;
+ end if;
+ return SIGNED_EQUAL(TO_SIGNED(L, R'LENGTH), R);
+ end "=";
+
+ -- Id: C.29
+ function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(L, TO_UNSIGNED(R, L'LENGTH));
+ end "=";
+
+ -- Id: C.30
+ function "=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return SIGNED_EQUAL(L, TO_SIGNED(R, L'LENGTH));
+ end "=";
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R: UNSIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)));
+ end "/=";
+
+ -- Id: C.32
+ function "/=" (L, R: SIGNED) return BOOLEAN is
+ variable SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(RESIZE(L, SIZE), RESIZE(R, SIZE)));
+ end "/=";
+
+ -- Id: C.33
+ function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(TO_UNSIGNED(L, R'LENGTH), R));
+ end "/=";
+
+ -- Id: C.34
+ function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(TO_SIGNED(L, R'LENGTH), R));
+ end "/=";
+
+ -- Id: C.35
+ function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(L, TO_UNSIGNED(R, L'LENGTH)));
+ end "/=";
+
+ -- Id: C.36
+ function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(L, TO_SIGNED(R, L'LENGTH)));
+ end "/=";
+
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XSLL(BIT_VECTOR(ARG), COUNT));
+ end SHIFT_LEFT;
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XSRL(BIT_VECTOR(ARG), COUNT));
+ end SHIFT_RIGHT;
+
+ -- Id: S.3
+ function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XSLL(BIT_VECTOR(ARG), COUNT));
+ end SHIFT_LEFT;
+
+ -- Id: S.4
+ function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XSRA(BIT_VECTOR(ARG), COUNT));
+ end SHIFT_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XROL(BIT_VECTOR(ARG), COUNT));
+ end ROTATE_LEFT;
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XROR(BIT_VECTOR(ARG), COUNT));
+ end ROTATE_RIGHT;
+
+ -- Id: S.7
+ function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XROL(BIT_VECTOR(ARG), COUNT));
+ end ROTATE_LEFT;
+
+ -- Id: S.8
+ function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XROR(BIT_VECTOR(ARG), COUNT));
+ end ROTATE_RIGHT;
+
+ --============================================================================
+
+--START-V93
+ ------------------------------------------------------------------------------
+ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.9
+ function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_LEFT(ARG, COUNT);
+ else
+ return SHIFT_RIGHT(ARG, -COUNT);
+ end if;
+ end "sll";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.10
+ function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_LEFT(ARG, COUNT);
+ else
+ return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), -COUNT));
+ end if;
+ end "sll";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.11
+ function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_RIGHT(ARG, COUNT);
+ else
+ return SHIFT_LEFT(ARG, -COUNT);
+ end if;
+ end "srl";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.12
+ function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT));
+ else
+ return SHIFT_LEFT(ARG, -COUNT);
+ end if;
+ end "srl";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.13
+ function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_LEFT(ARG, COUNT);
+ else
+ return ROTATE_RIGHT(ARG, -COUNT);
+ end if;
+ end "rol";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.14
+ function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_LEFT(ARG, COUNT);
+ else
+ return ROTATE_RIGHT(ARG, -COUNT);
+ end if;
+ end "rol";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.15
+ function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_RIGHT(ARG, COUNT);
+ else
+ return ROTATE_LEFT(ARG, -COUNT);
+ end if;
+ end "ror";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.16
+ function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_RIGHT(ARG, COUNT);
+ else
+ return ROTATE_LEFT(ARG, -COUNT);
+ end if;
+ end "ror";
+
+--END-V93
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG: UNSIGNED) return NATURAL is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: UNSIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT: NATURAL := 0;
+ begin
+ if (ARG'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_INTEGER: null detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ for I in XARG'RANGE loop
+ RESULT := RESULT+RESULT;
+ if XARG(I) = '1' then
+ RESULT := RESULT + 1;
+ end if;
+ end loop;
+ return RESULT;
+ end TO_INTEGER;
+
+ -- Id: D.2
+ function TO_INTEGER (ARG: SIGNED) return INTEGER is
+ begin
+ if (ARG'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_INTEGER: null detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ if ARG(ARG'LEFT) = '0' then
+ return TO_INTEGER(UNSIGNED(ARG));
+ else
+ return (- (TO_INTEGER(UNSIGNED(- (ARG + 1)))) -1);
+ end if;
+ end TO_INTEGER;
+
+ -- Id: D.3
+ function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED is
+ variable RESULT: UNSIGNED(SIZE-1 downto 0);
+ variable I_VAL: NATURAL := ARG;
+ begin
+ if (SIZE < 1) then return NAU;
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ if (I_VAL mod 2) = 0 then
+ RESULT(I) := '0';
+ else RESULT(I) := '1';
+ end if;
+ I_VAL := I_VAL/2;
+ end loop;
+ if not(I_VAL =0) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_UNSIGNED: vector truncated"
+ severity WARNING;
+ end if;
+ return RESULT;
+ end TO_UNSIGNED;
+
+ -- Id: D.4
+ function TO_SIGNED (ARG: INTEGER;
+ SIZE: NATURAL) return SIGNED is
+ variable RESULT: SIGNED(SIZE-1 downto 0);
+ variable B_VAL: BIT := '0';
+ variable I_VAL: INTEGER := ARG;
+ begin
+ if (SIZE < 1) then return NAS;
+ end if;
+ if (ARG < 0) then
+ B_VAL := '1';
+ I_VAL := -(ARG+1);
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ if (I_VAL mod 2) = 0 then
+ RESULT(I) := B_VAL;
+ else
+ RESULT(I) := not B_VAL;
+ end if;
+ I_VAL := I_VAL/2;
+ end loop;
+ if ((I_VAL/=0) or (B_VAL/=RESULT(RESULT'LEFT))) then
+ assert NO_WARNING
+ report "NUMERIC_BIT.TO_SIGNED: vector truncated"
+ severity WARNING;
+ end if;
+ return RESULT;
+ end TO_SIGNED;
+
+ --============================================================================
+
+ -- Id: R.1
+ function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED is
+ alias INVEC: SIGNED(ARG'LENGTH-1 downto 0) is ARG;
+ variable RESULT: SIGNED(NEW_SIZE-1 downto 0) := (others => '0');
+ constant BOUND: INTEGER := MIN(ARG'LENGTH, RESULT'LENGTH)-2;
+ begin
+ if (NEW_SIZE < 1) then return NAS;
+ end if;
+ if (ARG'LENGTH = 0) then return RESULT;
+ end if;
+ RESULT := (others => ARG(ARG'LEFT));
+ if BOUND >= 0 then
+ RESULT(BOUND downto 0) := INVEC(BOUND downto 0);
+ end if;
+ return RESULT;
+ end RESIZE;
+
+ -- Id: R.2
+ function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: UNSIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT: UNSIGNED(NEW_SIZE-1 downto 0) := (others => '0');
+ begin
+ if (NEW_SIZE < 1) then return NAU;
+ end if;
+ if XARG'LENGTH =0 then return RESULT;
+ end if;
+ if (RESULT'LENGTH < ARG'LENGTH) then
+ RESULT(RESULT'LEFT downto 0) := XARG(RESULT'LEFT downto 0);
+ else
+ RESULT(RESULT'LEFT downto XARG'LEFT+1) := (others => '0');
+ RESULT(XARG'LEFT downto 0) := XARG;
+ end if;
+ return RESULT;
+ end RESIZE;
+
+ --============================================================================
+
+ -- Id: L.1
+ function "not" (L: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(not(BIT_VECTOR(L)));
+ return RESULT;
+ end "not";
+
+ -- Id: L.2
+ function "and" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) and BIT_VECTOR(R));
+ return RESULT;
+ end "and";
+
+ -- Id: L.3
+ function "or" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) or BIT_VECTOR(R));
+ return RESULT;
+ end "or";
+
+ -- Id: L.4
+ function "nand" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) nand BIT_VECTOR(R));
+ return RESULT;
+ end "nand";
+
+ -- Id: L.5
+ function "nor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) nor BIT_VECTOR(R));
+ return RESULT;
+ end "nor";
+
+ -- Id: L.6
+ function "xor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) xor BIT_VECTOR(R));
+ return RESULT;
+ end "xor";
+
+--START-V93
+ ------------------------------------------------------------------------------
+ -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.7
+ function "xnor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(BIT_VECTOR(L) xnor BIT_VECTOR(R));
+ return RESULT;
+ end "xnor";
+--END-V93
+
+ -- Id: L.8
+ function "not" (L: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(not(BIT_VECTOR(L)));
+ return RESULT;
+ end "not";
+
+ -- Id: L.9
+ function "and" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) and BIT_VECTOR(R));
+ return RESULT;
+ end "and";
+
+ -- Id: L.10
+ function "or" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) or BIT_VECTOR(R));
+ return RESULT;
+ end "or";
+
+ -- Id: L.11
+ function "nand" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) nand BIT_VECTOR(R));
+ return RESULT;
+ end "nand";
+
+ -- Id: L.12
+ function "nor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) nor BIT_VECTOR(R));
+ return RESULT;
+ end "nor";
+
+ -- Id: L.13
+ function "xor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) xor BIT_VECTOR(R));
+ return RESULT;
+ end "xor";
+
+--START-V93
+ ------------------------------------------------------------------------------
+ -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.14
+ function "xnor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(BIT_VECTOR(L) xnor BIT_VECTOR(R));
+ return RESULT;
+ end "xnor";
+--END-V93
+
+ --============================================================================
+
+ -- Id: E.1
+ function RISING_EDGE (signal S: BIT) return BOOLEAN is
+ begin
+ return S'EVENT and S = '1';
+ end RISING_EDGE;
+
+ -- Id: E.2
+ function FALLING_EDGE (signal S: BIT) return BOOLEAN is
+ begin
+ return S'EVENT and S = '0';
+ end FALLING_EDGE;
+
+ --============================================================================
+end NUMERIC_BIT;
diff --git a/libraries/ieee/numeric_bit.vhdl b/libraries/ieee/numeric_bit.vhdl
new file mode 100644
index 000000000..8f049f21a
--- /dev/null
+++ b/libraries/ieee/numeric_bit.vhdl
@@ -0,0 +1,813 @@
+-- -----------------------------------------------------------------------------
+--
+-- Copyright 1995 by IEEE. All rights reserved.
+--
+-- This source file is considered by the IEEE to be an essential part of the use
+-- of the standard 1076.3 and as such may be distributed without change, except
+-- as permitted by the standard. This source file may not be sold or distributed
+-- for profit. This package may be modified to include additional data required
+-- by tools, but must in no way change the external interfaces or simulation
+-- behaviour of the description. It is permissible to add comments and/or
+-- attributes to the package declarations, but not to change or delete any
+-- original lines of the approved package declaration. The package body may be
+-- changed only in accordance with the terms of clauses 7.1 and 7.2 of the
+-- standard.
+--
+-- Title : Standard VHDL Synthesis Package (1076.3, NUMERIC_BIT)
+--
+-- Library : This package shall be compiled into a library symbolically
+-- : named IEEE.
+--
+-- Developers : IEEE DASC Synthesis Working Group, PAR 1076.3
+--
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Two numeric types are defined:
+-- : -- > UNSIGNED: represents an UNSIGNED number in vector form
+-- : -- > SIGNED: represents a SIGNED number in vector form
+-- : The base element type is type BIT.
+-- : The leftmost bit is treated as the most significant bit.
+-- : Signed vectors are represented in two's complement form.
+-- : This package contains overloaded arithmetic operators on
+-- : the SIGNED and UNSIGNED types. The package also contains
+-- : useful type conversions functions, clock detection
+-- : functions, and other utility functions.
+-- :
+-- : If any argument to a function is a null array, a null array is
+-- : returned (exceptions, if any, are noted individually).
+--
+-- Limitation :
+--
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : NUMERIC_BIT. The NUMERIC_BIT package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+-- :
+-- -----------------------------------------------------------------------------
+-- Version : 2.4
+-- Date : 12 April 1995
+-- -----------------------------------------------------------------------------
+
+package NUMERIC_BIT is
+ constant CopyRightNotice: STRING
+ := "Copyright 1995 IEEE. All rights reserved.";
+
+ --============================================================================
+ -- Numeric array type definitions
+ --============================================================================
+
+ type UNSIGNED is array (NATURAL range <> ) of BIT;
+ type SIGNED is array (NATURAL range <> ) of BIT;
+
+ --============================================================================
+ -- Arithmetic Operators:
+ --============================================================================
+
+ -- Id: A.1
+ function "abs" (ARG: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0).
+ -- Result: Returns the absolute value of a SIGNED vector ARG.
+
+ -- Id: A.2
+ function "-" (ARG: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0).
+ -- Result: Returns the value of the unary minus operation on a
+ -- SIGNED vector ARG.
+
+ --============================================================================
+
+ -- Id: A.3
+ function "+" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.4
+ function "+" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two SIGNED vectors that may be of different lengths.
+
+ -- Id: A.5
+ function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
+ -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
+
+ -- Id: A.6
+ function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
+ -- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
+
+ -- Id: A.7
+ function "+" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0).
+ -- Result: Adds an INTEGER, L(may be positive or negative), to a SIGNED
+ -- vector, R.
+
+ -- Id: A.8
+ function "+" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0).
+ -- Result: Adds a SIGNED vector, L, to an INTEGER, R.
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.10
+ function "-" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts a SIGNED vector, R, from another SIGNED vector, L,
+ -- that may possibly be of different lengths.
+
+ -- Id: A.11
+ function "-" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
+ -- Result: Subtracts a non-negative INTEGER, R, from an UNSIGNED vector, L.
+
+ -- Id: A.12
+ function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
+ -- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L.
+
+ -- Id: A.13
+ function "-" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0).
+ -- Result: Subtracts an INTEGER, R, from a SIGNED vector, L.
+
+ -- Id: A.14
+ function "-" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0).
+ -- Result: Subtracts a SIGNED vector, R, from an INTEGER, L.
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Performs the multiplication operation on two UNSIGNED vectors
+ -- that may possibly be of different lengths.
+
+ -- Id: A.16
+ function "*" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED((L'LENGTH+R'LENGTH-1) downto 0)
+ -- Result: Multiplies two SIGNED vectors that may possibly be of
+ -- different lengths.
+
+ -- Id: A.17
+ function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, L, with a non-negative
+ -- INTEGER, R. R is converted to an UNSIGNED vector of
+ -- size L'LENGTH before multiplication.
+
+ -- Id: A.18
+ function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, R, with a non-negative
+ -- INTEGER, L. L is converted to an UNSIGNED vector of
+ -- size R'LENGTH before multiplication.
+
+ -- Id: A.19
+ function "*" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED((L'LENGTH+L'LENGTH-1) downto 0)
+ -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is
+ -- converted to a SIGNED vector of size L'LENGTH before
+ -- multiplication.
+
+ -- Id: A.20
+ function "*" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED((R'LENGTH+R'LENGTH-1) downto 0)
+ -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is
+ -- converted to a SIGNED vector of size R'LENGTH before
+ -- multiplication.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "/" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.21
+ function "/" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R.
+
+ -- Id: A.22
+ function "/" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an SIGNED vector, L, by another SIGNED vector, R.
+
+ -- Id: A.23
+ function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by a non-negative INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.24
+ function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Divides a non-negative INTEGER, L, by an UNSIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.25
+ function "/" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides a SIGNED vector, L, by an INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.26
+ function "/" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Divides an INTEGER, L, by a SIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "rem" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.27
+ function "rem" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.28
+ function "rem" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are SIGNED vectors.
+
+ -- Id: A.29
+ function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.30
+ function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.31
+ function "rem" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is SIGNED vector and R is an INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.32
+ function "rem" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is SIGNED vector and L is an INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "mod" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.33
+ function "mod" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.34
+ function "mod" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are SIGNED vectors.
+
+ -- Id: A.35
+ function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an UNSIGNED vector and R
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.36
+ function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where R is an UNSIGNED vector and L
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.37
+ function "mod" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.38
+ function "mod" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ -- Comparison Operators
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.2
+ function ">" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.3
+ function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.4
+ function ">" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.5
+ function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.6
+ function ">" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a SIGNED vector and
+ -- R is a INTEGER.
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.8
+ function "<" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.9
+ function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.10
+ function "<" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.11
+ function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.12
+ function "<" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.14
+ function "<=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.15
+ function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.16
+ function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.17
+ function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.18
+ function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.20
+ function ">=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.21
+ function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.22
+ function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.23
+ function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.24
+ function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.26
+ function "=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.27
+ function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.28
+ function "=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.29
+ function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.30
+ function "=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.32
+ function "/=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.33
+ function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.34
+ function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.35
+ function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.36
+ function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+ -- Shift and Rotate Functions
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with Bit '0'.
+ -- The COUNT leftmost bits are lost.
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with Bit '0'.
+ -- The COUNT rightmost bits are lost.
+
+ -- Id: S.3
+ function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on a SIGNED vector COUNT times.
+ -- The vacated positions are filled with Bit '0'.
+ -- The COUNT leftmost bits, except ARG'LEFT, are lost.
+
+ -- Id: S.4
+ function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on a SIGNED vector COUNT times.
+ -- The vacated positions are filled with the leftmost bit, ARG'LEFT.
+ -- The COUNT rightmost bits are lost.
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times.
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times.
+
+ -- Id: S.7
+ function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a logical rotate-left of a SIGNED vector COUNT times.
+
+ -- Id: S.8
+ function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a logical rotate-right of a SIGNED vector COUNT times.
+
+ --============================================================================
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.9
+ function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.10
+ function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.11
+ function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.12
+ function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT))
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.13
+ function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.14
+ function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.15
+ function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.16
+ function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_RIGHT(ARG, COUNT)
+
+ --============================================================================
+ -- RESIZE Functions
+ --============================================================================
+
+ -- Id: R.1
+ function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the SIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with the sign bit (ARG'LEFT). When truncating,
+ -- the sign bit is retained along with the rightmost part.
+
+ -- Id: R.2
+ function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the UNSIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with '0'. When truncating, the leftmost bits
+ -- are dropped.
+
+ --============================================================================
+ -- Conversion Functions
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
+ -- Result subtype: NATURAL. Value cannot be negative since parameter is an
+ -- UNSIGNED vector.
+ -- Result: Converts the UNSIGNED vector to an INTEGER.
+
+ -- Id: D.2
+ function TO_INTEGER (ARG: SIGNED) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Converts a SIGNED vector to an INTEGER.
+
+ -- Id: D.3
+ function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(SIZE-1 downto 0)
+ -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
+ -- the specified size.
+
+ -- Id: D.4
+ function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(SIZE-1 downto 0)
+ -- Result: Converts an INTEGER to a SIGNED vector of the specified size.
+
+ --============================================================================
+ -- Logical Operators
+ --============================================================================
+
+ -- Id: L.1
+ function "not" (L: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Termwise inversion
+
+ -- Id: L.2
+ function "and" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector AND operation
+
+ -- Id: L.3
+ function "or" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector OR operation
+
+ -- Id: L.4
+ function "nand" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NAND operation
+
+ -- Id: L.5
+ function "nor" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NOR operation
+
+ -- Id: L.6
+ function "xor" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XOR operation
+
+ ------------------------------------------------------------------------------
+ -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.7
+ function "xnor" (L, R: UNSIGNED) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XNOR operation
+
+ -- Id: L.8
+ function "not" (L: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Termwise inversion
+
+ -- Id: L.9
+ function "and" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector AND operation
+
+ -- Id: L.10
+ function "or" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector OR operation
+
+ -- Id: L.11
+ function "nand" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NAND operation
+
+ -- Id: L.12
+ function "nor" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NOR operation
+
+ -- Id: L.13
+ function "xor" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XOR operation
+
+ ------------------------------------------------------------------------------
+ -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.14
+ function "xnor" (L, R: SIGNED) return SIGNED; --V93
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XNOR operation
+
+ --============================================================================
+ -- Edge Detection Functions
+ --============================================================================
+
+ -- Id: E.1
+ function RISING_EDGE (signal S: BIT) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Returns TRUE if an event is detected on signal S and the
+ -- value changed from a '0' to a '1'.
+
+ -- Id: E.2
+ function FALLING_EDGE (signal S: BIT) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Returns TRUE if an event is detected on signal S and the
+ -- value changed from a '1' to a '0'.
+
+end NUMERIC_BIT;
diff --git a/libraries/ieee/numeric_std-body.vhdl b/libraries/ieee/numeric_std-body.vhdl
new file mode 100644
index 000000000..a5d609dc3
--- /dev/null
+++ b/libraries/ieee/numeric_std-body.vhdl
@@ -0,0 +1,2545 @@
+-- --------------------------------------------------------------------
+--
+-- Copyright 1995 by IEEE. All rights reserved.
+--
+-- This source file is considered by the IEEE to be an essential part of the use
+-- of the standard 1076.3 and as such may be distributed without change, except
+-- as permitted by the standard. This source file may not be sold or distributed
+-- for profit. This package may be modified to include additional data required
+-- by tools, but must in no way change the external interfaces or simulation
+-- behaviour of the description. It is permissible to add comments and/or
+-- attributes to the package declarations, but not to change or delete any
+-- original lines of the approved package declaration. The package body may be
+-- changed only in accordance with the terms of clauses 7.1 and 7.2 of the
+-- standard.
+--
+-- Title : Standard VHDL Synthesis Package (1076.3, NUMERIC_STD)
+--
+-- Library : This package shall be compiled into a library symbolically
+-- : named IEEE.
+--
+-- Developers : IEEE DASC Synthesis Working Group, PAR 1076.3
+--
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Two numeric types are defined:
+-- : -- > UNSIGNED: represents UNSIGNED number in vector form
+-- : -- > SIGNED: represents a SIGNED number in vector form
+-- : The base element type is type STD_LOGIC.
+-- : The leftmost bit is treated as the most significant bit.
+-- : Signed vectors are represented in two's complement form.
+-- : This package contains overloaded arithmetic operators on
+-- : the SIGNED and UNSIGNED types. The package also contains
+-- : useful type conversions functions.
+-- :
+-- : If any argument to a function is a null array, a null array is
+-- : returned (exceptions, if any, are noted individually).
+--
+-- Limitation :
+--
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : NUMERIC_STD. The NUMERIC_STD package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+--
+-- --------------------------------------------------------------------
+-- modification history :
+-- --------------------------------------------------------------------
+-- Version: 2.4
+-- Date : 12 April 1995
+-- -----------------------------------------------------------------------------
+
+--==============================================================================
+--============================= Package Body ===================================
+--==============================================================================
+
+package body NUMERIC_STD is
+
+ -- null range array constants
+
+ constant NAU: UNSIGNED(0 downto 1) := (others => '0');
+ constant NAS: SIGNED(0 downto 1) := (others => '0');
+
+ -- implementation controls
+
+ constant NO_WARNING: BOOLEAN := FALSE; -- default to emit warnings
+
+ --=========================Local Subprograms =================================
+
+ function MAX (LEFT, RIGHT: INTEGER) return INTEGER is
+ begin
+ if LEFT > RIGHT then return LEFT;
+ else return RIGHT;
+ end if;
+ end MAX;
+
+ function MIN (LEFT, RIGHT: INTEGER) return INTEGER is
+ begin
+ if LEFT < RIGHT then return LEFT;
+ else return RIGHT;
+ end if;
+ end MIN;
+
+ function SIGNED_NUM_BITS (ARG: INTEGER) return NATURAL is
+ variable NBITS: NATURAL;
+ variable N: NATURAL;
+ begin
+ if ARG >= 0 then
+ N := ARG;
+ else
+ N := -(ARG+1);
+ end if;
+ NBITS := 1;
+ while N > 0 loop
+ NBITS := NBITS+1;
+ N := N / 2;
+ end loop;
+ return NBITS;
+ end SIGNED_NUM_BITS;
+
+ function UNSIGNED_NUM_BITS (ARG: NATURAL) return NATURAL is
+ variable NBITS: NATURAL;
+ variable N: NATURAL;
+ begin
+ N := ARG;
+ NBITS := 1;
+ while N > 1 loop
+ NBITS := NBITS+1;
+ N := N / 2;
+ end loop;
+ return NBITS;
+ end UNSIGNED_NUM_BITS;
+
+ ------------------------------------------------------------------------
+
+ -- this internal function computes the addition of two UNSIGNED
+ -- with input CARRY
+ -- * the two arguments are of the same length
+
+ function ADD_UNSIGNED (L, R: UNSIGNED; C: STD_LOGIC) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(L_LEFT downto 0) is R;
+ variable RESULT: UNSIGNED(L_LEFT downto 0);
+ variable CBIT: STD_LOGIC := C;
+ begin
+ for I in 0 to L_LEFT loop
+ RESULT(I) := CBIT xor XL(I) xor XR(I);
+ CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
+ end loop;
+ return RESULT;
+ end ADD_UNSIGNED;
+
+ -- this internal function computes the addition of two SIGNED
+ -- with input CARRY
+ -- * the two arguments are of the same length
+
+ function ADD_SIGNED (L, R: SIGNED; C: STD_LOGIC) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(L_LEFT downto 0) is R;
+ variable RESULT: SIGNED(L_LEFT downto 0);
+ variable CBIT: STD_LOGIC := C;
+ begin
+ for I in 0 to L_LEFT loop
+ RESULT(I) := CBIT xor XL(I) xor XR(I);
+ CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
+ end loop;
+ return RESULT;
+ end ADD_SIGNED;
+
+ -----------------------------------------------------------------------------
+
+ -- this internal procedure computes UNSIGNED division
+ -- giving the quotient and remainder.
+ procedure DIVMOD (NUM, XDENOM: UNSIGNED; XQUOT, XREMAIN: out UNSIGNED) is
+ variable TEMP: UNSIGNED(NUM'LENGTH downto 0);
+ variable QUOT: UNSIGNED(MAX(NUM'LENGTH, XDENOM'LENGTH)-1 downto 0);
+ alias DENOM: UNSIGNED(XDENOM'LENGTH-1 downto 0) is XDENOM;
+ variable TOPBIT: INTEGER;
+ begin
+ TEMP := "0"&NUM;
+ QUOT := (others => '0');
+ TOPBIT := -1;
+ for J in DENOM'RANGE loop
+ if DENOM(J)='1' then
+ TOPBIT := J;
+ exit;
+ end if;
+ end loop;
+ assert TOPBIT >= 0 report "DIV, MOD, or REM by zero" severity ERROR;
+
+ for J in NUM'LENGTH-(TOPBIT+1) downto 0 loop
+ if TEMP(TOPBIT+J+1 downto J) >= "0"&DENOM(TOPBIT downto 0) then
+ TEMP(TOPBIT+J+1 downto J) := (TEMP(TOPBIT+J+1 downto J))
+ -("0"&DENOM(TOPBIT downto 0));
+ QUOT(J) := '1';
+ end if;
+ assert TEMP(TOPBIT+J+1)='0'
+ report "internal error in the division algorithm"
+ severity ERROR;
+ end loop;
+ XQUOT := RESIZE(QUOT, XQUOT'LENGTH);
+ XREMAIN := RESIZE(TEMP, XREMAIN'LENGTH);
+ end DIVMOD;
+
+ -----------------Local Subprograms - shift/rotate ops-------------------------
+
+ function XSLL (ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR
+ is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := (others => '0');
+ begin
+ if COUNT <= ARG_L then
+ RESULT(ARG_L downto COUNT) := XARG(ARG_L-COUNT downto 0);
+ end if;
+ return RESULT;
+ end XSLL;
+
+ function XSRL (ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR
+ is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := (others => '0');
+ begin
+ if COUNT <= ARG_L then
+ RESULT(ARG_L-COUNT downto 0) := XARG(ARG_L downto COUNT);
+ end if;
+ return RESULT;
+ end XSRL;
+
+ function XSRA (ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR
+ is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0);
+ variable XCOUNT: NATURAL := COUNT;
+ begin
+ if ((ARG'LENGTH <= 1) or (XCOUNT = 0)) then return ARG;
+ else
+ if (XCOUNT > ARG_L) then XCOUNT := ARG_L;
+ end if;
+ RESULT(ARG_L-XCOUNT downto 0) := XARG(ARG_L downto XCOUNT);
+ RESULT(ARG_L downto (ARG_L - XCOUNT + 1)) := (others => XARG(ARG_L));
+ end if;
+ return RESULT;
+ end XSRA;
+
+ function XROL (ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR
+ is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := XARG;
+ variable COUNTM: INTEGER;
+ begin
+ COUNTM := COUNT mod (ARG_L + 1);
+ if COUNTM /= 0 then
+ RESULT(ARG_L downto COUNTM) := XARG(ARG_L-COUNTM downto 0);
+ RESULT(COUNTM-1 downto 0) := XARG(ARG_L downto ARG_L-COUNTM+1);
+ end if;
+ return RESULT;
+ end XROL;
+
+ function XROR (ARG: STD_LOGIC_VECTOR; COUNT: NATURAL) return STD_LOGIC_VECTOR
+ is
+ constant ARG_L: INTEGER := ARG'LENGTH-1;
+ alias XARG: STD_LOGIC_VECTOR(ARG_L downto 0) is ARG;
+ variable RESULT: STD_LOGIC_VECTOR(ARG_L downto 0) := XARG;
+ variable COUNTM: INTEGER;
+ begin
+ COUNTM := COUNT mod (ARG_L + 1);
+ if COUNTM /= 0 then
+ RESULT(ARG_L-COUNTM downto 0) := XARG(ARG_L downto COUNTM);
+ RESULT(ARG_L downto ARG_L-COUNTM+1) := XARG(COUNTM-1 downto 0);
+ end if;
+ return RESULT;
+ end XROR;
+
+ -----------------Local Subprograms - Relational ops---------------------------
+
+ --
+ -- General "=" for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_EQUAL (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return STD_LOGIC_VECTOR(L) = STD_LOGIC_VECTOR(R);
+ end UNSIGNED_EQUAL;
+
+ --
+ -- General "=" for SIGNED vectors, same length
+ --
+ function SIGNED_EQUAL (L, R: SIGNED) return BOOLEAN is
+ begin
+ return STD_LOGIC_VECTOR(L) = STD_LOGIC_VECTOR(R);
+ end SIGNED_EQUAL;
+
+ --
+ -- General "<" for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_LESS (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return STD_LOGIC_VECTOR(L) < STD_LOGIC_VECTOR(R);
+ end UNSIGNED_LESS;
+
+ --
+ -- General "<" function for SIGNED vectors, same length
+ --
+ function SIGNED_LESS (L, R: SIGNED) return BOOLEAN is
+ variable INTERN_L: SIGNED(0 to L'LENGTH-1);
+ variable INTERN_R: SIGNED(0 to R'LENGTH-1);
+ begin
+ INTERN_L := L;
+ INTERN_R := R;
+ INTERN_L(0) := not INTERN_L(0);
+ INTERN_R(0) := not INTERN_R(0);
+ return STD_LOGIC_VECTOR(INTERN_L) < STD_LOGIC_VECTOR(INTERN_R);
+ end SIGNED_LESS;
+
+ --
+ -- General "<=" function for UNSIGNED vectors, same length
+ --
+ function UNSIGNED_LESS_OR_EQUAL (L, R: UNSIGNED) return BOOLEAN is
+ begin
+ return STD_LOGIC_VECTOR(L) <= STD_LOGIC_VECTOR(R);
+ end UNSIGNED_LESS_OR_EQUAL;
+
+ --
+ -- General "<=" function for SIGNED vectors, same length
+ --
+ function SIGNED_LESS_OR_EQUAL (L, R: SIGNED) return BOOLEAN is
+ -- Need aliases to assure index direction
+ variable INTERN_L: SIGNED(0 to L'LENGTH-1);
+ variable INTERN_R: SIGNED(0 to R'LENGTH-1);
+ begin
+ INTERN_L := L;
+ INTERN_R := R;
+ INTERN_L(0) := not INTERN_L(0);
+ INTERN_R(0) := not INTERN_R(0);
+ return STD_LOGIC_VECTOR(INTERN_L) <= STD_LOGIC_VECTOR(INTERN_R);
+ end SIGNED_LESS_OR_EQUAL;
+
+ --=========================Exported Functions ==========================
+
+ -- Id: A.1
+ function "abs" (ARG: SIGNED) return SIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: SIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT: SIGNED(ARG_LEFT downto 0);
+ begin
+ if ARG'LENGTH < 1 then return NAS;
+ end if;
+ RESULT := TO_01(XARG, 'X');
+ if (RESULT(RESULT'LEFT)='X') then return RESULT;
+ end if;
+ if RESULT(RESULT'LEFT) = '1' then
+ RESULT := -RESULT;
+ end if;
+ return RESULT;
+ end "abs";
+
+ -- Id: A.2
+ function "-" (ARG: SIGNED) return SIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: SIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT, XARG01 : SIGNED(ARG_LEFT downto 0);
+ variable CBIT: STD_LOGIC := '1';
+ begin
+ if ARG'LENGTH < 1 then return NAS;
+ end if;
+ XARG01 := TO_01(ARG, 'X');
+ if (XARG01(XARG01'LEFT)='X') then return XARG01;
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ RESULT(I) := not(XARG01(I)) xor CBIT;
+ CBIT := CBIT and not(XARG01(I));
+ end loop;
+ return RESULT;
+ end "-";
+
+ --============================================================================
+
+ -- Id: A.3
+ function "+" (L, R: UNSIGNED) return UNSIGNED is
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(SIZE-1 downto 0);
+ variable R01 : UNSIGNED(SIZE-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ L01 := TO_01(RESIZE(L, SIZE), 'X');
+ if (L01(L01'LEFT)='X') then return L01;
+ end if;
+ R01 := TO_01(RESIZE(R, SIZE), 'X');
+ if (R01(R01'LEFT)='X') then return R01;
+ end if;
+ return ADD_UNSIGNED(L01, R01, '0');
+ end "+";
+
+ -- Id: A.4
+ function "+" (L, R: SIGNED) return SIGNED is
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(SIZE-1 downto 0);
+ variable R01 : SIGNED(SIZE-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ L01 := TO_01(RESIZE(L, SIZE), 'X');
+ if (L01(L01'LEFT)='X') then return L01;
+ end if;
+ R01 := TO_01(RESIZE(R, SIZE), 'X');
+ if (R01(R01'LEFT)='X') then return R01;
+ end if;
+ return ADD_SIGNED(L01, R01, '0');
+ end "+";
+
+ -- Id: A.5
+ function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L + TO_UNSIGNED(R, L'LENGTH);
+ end "+";
+
+ -- Id: A.6
+ function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) + R;
+ end "+";
+
+ -- Id: A.7
+ function "+" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L + TO_SIGNED(R, L'LENGTH);
+ end "+";
+
+ -- Id: A.8
+ function "+" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) + R;
+ end "+";
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R: UNSIGNED) return UNSIGNED is
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(SIZE-1 downto 0);
+ variable R01 : UNSIGNED(SIZE-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ L01 := TO_01(RESIZE(L, SIZE), 'X');
+ if (L01(L01'LEFT)='X') then return L01;
+ end if;
+ R01 := TO_01(RESIZE(R, SIZE), 'X');
+ if (R01(R01'LEFT)='X') then return R01;
+ end if;
+ return ADD_UNSIGNED(L01, not(R01), '1');
+ end "-";
+
+ -- Id: A.10
+ function "-" (L, R: SIGNED) return SIGNED is
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(SIZE-1 downto 0);
+ variable R01 : SIGNED(SIZE-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ L01 := TO_01(RESIZE(L, SIZE), 'X');
+ if (L01(L01'LEFT)='X') then return L01;
+ end if;
+ R01 := TO_01(RESIZE(R, SIZE), 'X');
+ if (R01(R01'LEFT)='X') then return R01;
+ end if;
+ return ADD_SIGNED(L01, not(R01), '1');
+ end "-";
+
+ -- Id: A.11
+ function "-" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L - TO_UNSIGNED(R, L'LENGTH);
+ end "-";
+
+ -- Id: A.12
+ function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) - R;
+ end "-";
+
+ -- Id: A.13
+ function "-" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L - TO_SIGNED(R, L'LENGTH);
+ end "-";
+
+ -- Id: A.14
+ function "-" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) - R;
+ end "-";
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XXR: UNSIGNED(R_LEFT downto 0) is R;
+ variable XL: UNSIGNED(L_LEFT downto 0);
+ variable XR: UNSIGNED(R_LEFT downto 0);
+ variable RESULT: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0) :=
+ (others => '0');
+ variable ADVAL: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ RESULT := (others => 'X');
+ return RESULT;
+ end if;
+ ADVAL := RESIZE(XR, RESULT'LENGTH);
+ for I in 0 to L_LEFT loop
+ if XL(I)='1' then RESULT := RESULT + ADVAL;
+ end if;
+ ADVAL := SHIFT_LEFT(ADVAL, 1);
+ end loop;
+ return RESULT;
+ end "*";
+
+ -- Id: A.16
+ function "*" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ variable XL: SIGNED(L_LEFT downto 0);
+ variable XR: SIGNED(R_LEFT downto 0);
+ variable RESULT: SIGNED((L_LEFT+R_LEFT+1) downto 0) := (others => '0');
+ variable ADVAL: SIGNED((L_LEFT+R_LEFT+1) downto 0);
+ begin
+ if ((L_LEFT < 0) or (R_LEFT < 0)) then return NAS;
+ end if;
+ XL := TO_01(L, 'X');
+ XR := TO_01(R, 'X');
+ if ((XL(L_LEFT)='X') or (XR(R_LEFT)='X')) then
+ RESULT := (others => 'X');
+ return RESULT;
+ end if;
+ ADVAL := RESIZE(XR, RESULT'LENGTH);
+ for I in 0 to L_LEFT-1 loop
+ if XL(I)='1' then RESULT := RESULT + ADVAL;
+ end if;
+ ADVAL := SHIFT_LEFT(ADVAL, 1);
+ end loop;
+ if XL(L_LEFT)='1' then
+ RESULT := RESULT - ADVAL;
+ end if;
+ return RESULT;
+ end "*";
+
+ -- Id: A.17
+ function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ begin
+ return L * TO_UNSIGNED(R, L'LENGTH);
+ end "*";
+
+ -- Id: A.18
+ function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ begin
+ return TO_UNSIGNED(L, R'LENGTH) * R;
+ end "*";
+
+ -- Id: A.19
+ function "*" (L: SIGNED; R: INTEGER) return SIGNED is
+ begin
+ return L * TO_SIGNED(R, L'LENGTH);
+ end "*";
+
+ -- Id: A.20
+ function "*" (L: INTEGER; R: SIGNED) return SIGNED is
+ begin
+ return TO_SIGNED(L, R'LENGTH) * R;
+ end "*";
+
+ --============================================================================
+
+ -- Id: A.21
+ function "/" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XXR: UNSIGNED(R_LEFT downto 0) is R;
+ variable XL: UNSIGNED(L_LEFT downto 0);
+ variable XR: UNSIGNED(R_LEFT downto 0);
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ FQUOT := (others => 'X');
+ return FQUOT;
+ end if;
+ DIVMOD(XL, XR, FQUOT, FREMAIN);
+ return FQUOT;
+ end "/";
+
+ -- Id: A.22
+ function "/" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: SIGNED(L_LEFT downto 0) is L;
+ alias XXR: SIGNED(R_LEFT downto 0) is R;
+ variable XL: SIGNED(L_LEFT downto 0);
+ variable XR: SIGNED(R_LEFT downto 0);
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable QNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ FQUOT := (others => 'X');
+ return SIGNED(FQUOT);
+ end if;
+ if XL(XL'LEFT)='1' then
+ XNUM := UNSIGNED(-XL);
+ QNEG := TRUE;
+ else
+ XNUM := UNSIGNED(XL);
+ end if;
+ if XR(XR'LEFT)='1' then
+ XDENOM := UNSIGNED(-XR);
+ QNEG := not QNEG;
+ else
+ XDENOM := UNSIGNED(XR);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if QNEG then FQUOT := "0"-FQUOT;
+ end if;
+ return SIGNED(FQUOT);
+ end "/";
+
+ -- Id: A.23
+ function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, QUOT: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ if (R_LENGTH > L'LENGTH) then
+ QUOT := (others => '0');
+ return RESIZE(QUOT, L'LENGTH);
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ QUOT := RESIZE((L / XR), QUOT'LENGTH);
+ return RESIZE(QUOT, L'LENGTH);
+ end "/";
+
+ -- Id: A.24
+ function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, QUOT: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAU;
+ end if;
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ QUOT := RESIZE((XL / R), QUOT'LENGTH);
+ if L_LENGTH > R'LENGTH and QUOT(0)/='X'
+ and QUOT(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(QUOT, R'LENGTH);
+ end "/";
+
+ -- Id: A.25
+ function "/" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, QUOT: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ if (R_LENGTH > L'LENGTH) then
+ QUOT := (others => '0');
+ return RESIZE(QUOT, L'LENGTH);
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ QUOT := RESIZE((L / XR), QUOT'LENGTH);
+ return RESIZE(QUOT, L'LENGTH);
+ end "/";
+
+ -- Id: A.26
+ function "/" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, QUOT: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ QUOT := RESIZE((XL / R), QUOT'LENGTH);
+ if L_LENGTH > R'LENGTH and QUOT(0)/='X'
+ and QUOT(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => QUOT(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_STD.""/"": Quotient Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(QUOT, R'LENGTH);
+ end "/";
+
+ --============================================================================
+
+ -- Id: A.27
+ function "rem" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XXR: UNSIGNED(R_LEFT downto 0) is R;
+ variable XL: UNSIGNED(L_LEFT downto 0);
+ variable XR: UNSIGNED(R_LEFT downto 0);
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ FREMAIN := (others => 'X');
+ return FREMAIN;
+ end if;
+ DIVMOD(XL, XR, FQUOT, FREMAIN);
+ return FREMAIN;
+ end "rem";
+
+ -- Id: A.28
+ function "rem" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: SIGNED(L_LEFT downto 0) is L;
+ alias XXR: SIGNED(R_LEFT downto 0) is R;
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable RNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ XNUM := UNSIGNED(TO_01(XXL, 'X'));
+ XDENOM := UNSIGNED(TO_01(XXR, 'X'));
+ if ((XNUM(XNUM'LEFT)='X') or (XDENOM(XDENOM'LEFT)='X')) then
+ FREMAIN := (others => 'X');
+ return SIGNED(FREMAIN);
+ end if;
+ if XNUM(XNUM'LEFT)='1' then
+ XNUM := UNSIGNED(-SIGNED(XNUM));
+ RNEG := TRUE;
+ else
+ XNUM := UNSIGNED(XNUM);
+ end if;
+ if XDENOM(XDENOM'LEFT)='1' then
+ XDENOM := UNSIGNED(-SIGNED(XDENOM));
+ else
+ XDENOM := UNSIGNED(XDENOM);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if RNEG then
+ FREMAIN := "0"-FREMAIN;
+ end if;
+ return SIGNED(FREMAIN);
+ end "rem";
+
+ -- Id: A.29
+ function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ XREM := L rem XR;
+ if R_LENGTH > L'LENGTH and XREM(0)/='X'
+ and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "rem";
+
+ -- Id: A.30
+ function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ XREM := XL rem R;
+ if L_LENGTH > R'LENGTH and XREM(0)/='X'
+ and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "rem";
+
+ -- Id: A.31
+ function "rem" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, XREM: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ XREM := RESIZE((L rem XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(0)/='X'
+ and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "rem";
+
+ -- Id: A.32
+ function "rem" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL rem R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(0)/='X'
+ and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_STD.""rem"": Remainder Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "rem";
+
+ --============================================================================
+
+ -- Id: A.33
+ function "mod" (L, R: UNSIGNED) return UNSIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XXR: UNSIGNED(R_LEFT downto 0) is R;
+ variable XL: UNSIGNED(L_LEFT downto 0);
+ variable XR: UNSIGNED(R_LEFT downto 0);
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ FREMAIN := (others => 'X');
+ return FREMAIN;
+ end if;
+ DIVMOD(XL, XR, FQUOT, FREMAIN);
+ return FREMAIN;
+ end "mod";
+
+ -- Id: A.34
+ function "mod" (L, R: SIGNED) return SIGNED is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XXL: SIGNED(L_LEFT downto 0) is L;
+ alias XXR: SIGNED(R_LEFT downto 0) is R;
+ variable XL: SIGNED(L_LEFT downto 0);
+ variable XR: SIGNED(R_LEFT downto 0);
+ variable FQUOT: UNSIGNED(L'LENGTH-1 downto 0);
+ variable FREMAIN: UNSIGNED(R'LENGTH-1 downto 0);
+ variable XNUM: UNSIGNED(L'LENGTH-1 downto 0);
+ variable XDENOM: UNSIGNED(R'LENGTH-1 downto 0);
+ variable RNEG: BOOLEAN := FALSE;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAS;
+ end if;
+ XL := TO_01(XXL, 'X');
+ XR := TO_01(XXR, 'X');
+ if ((XL(XL'LEFT)='X') or (XR(XR'LEFT)='X')) then
+ FREMAIN := (others => 'X');
+ return SIGNED(FREMAIN);
+ end if;
+ if XL(XL'LEFT)='1' then
+ XNUM := UNSIGNED(-XL);
+ else
+ XNUM := UNSIGNED(XL);
+ end if;
+ if XR(XR'LEFT)='1' then
+ XDENOM := UNSIGNED(-XR);
+ RNEG := TRUE;
+ else
+ XDENOM := UNSIGNED(XR);
+ end if;
+ DIVMOD(XNUM, XDENOM, FQUOT, FREMAIN);
+ if RNEG and L(L'LEFT)='1' then
+ FREMAIN := "0"-FREMAIN;
+ elsif RNEG and FREMAIN/="0" then
+ FREMAIN := FREMAIN-XDENOM;
+ elsif L(L'LEFT)='1' and FREMAIN/="0" then
+ FREMAIN := XDENOM-FREMAIN;
+ end if;
+ return SIGNED(FREMAIN);
+ end "mod";
+
+ -- Id: A.35
+ function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, UNSIGNED_NUM_BITS(R));
+ variable XR, XREM: UNSIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAU;
+ end if;
+ XR := TO_UNSIGNED(R, R_LENGTH);
+ XREM := RESIZE((L mod XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(0)/='X'
+ and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "mod";
+
+ -- Id: A.36
+ function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED is
+ constant L_LENGTH: NATURAL := MAX(UNSIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: UNSIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAU;
+ end if;
+ XL := TO_UNSIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL mod R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(0)/='X'
+ and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => '0')
+ then
+ assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "mod";
+
+ -- Id: A.37
+ function "mod" (L: SIGNED; R: INTEGER) return SIGNED is
+ constant R_LENGTH: NATURAL := MAX(L'LENGTH, SIGNED_NUM_BITS(R));
+ variable XR, XREM: SIGNED(R_LENGTH-1 downto 0);
+ begin
+ if (L'LENGTH < 1) then return NAS;
+ end if;
+ XR := TO_SIGNED(R, R_LENGTH);
+ XREM := RESIZE((L mod XR), XREM'LENGTH);
+ if R_LENGTH > L'LENGTH and XREM(0)/='X'
+ and XREM(R_LENGTH-1 downto L'LENGTH)
+ /= (R_LENGTH-1 downto L'LENGTH => XREM(L'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, L'LENGTH);
+ end "mod";
+
+ -- Id: A.38
+ function "mod" (L: INTEGER; R: SIGNED) return SIGNED is
+ constant L_LENGTH: NATURAL := MAX(SIGNED_NUM_BITS(L), R'LENGTH);
+ variable XL, XREM: SIGNED(L_LENGTH-1 downto 0);
+ begin
+ if (R'LENGTH < 1) then return NAS;
+ end if;
+ XL := TO_SIGNED(L, L_LENGTH);
+ XREM := RESIZE((XL mod R), XREM'LENGTH);
+ if L_LENGTH > R'LENGTH and XREM(0)/='X'
+ and XREM(L_LENGTH-1 downto R'LENGTH)
+ /= (L_LENGTH-1 downto R'LENGTH => XREM(R'LENGTH-1))
+ then
+ assert NO_WARNING report "NUMERIC_STD.""mod"": Modulus Truncated"
+ severity WARNING;
+ end if;
+ return RESIZE(XREM, R'LENGTH);
+ end "mod";
+
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end ">";
+
+ -- Id: C.2
+ function ">" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end ">";
+
+ -- Id: C.3
+ function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R01'LENGTH), R01);
+ end ">";
+
+ -- Id: C.4
+ function ">" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R01'LENGTH), R01);
+ end ">";
+
+ -- Id: C.5
+ function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return not UNSIGNED_LESS_OR_EQUAL(L01, TO_UNSIGNED(R, L01'LENGTH));
+ end ">";
+
+ -- Id: C.6
+ function ">" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not SIGNED_LESS_OR_EQUAL(L01, TO_SIGNED(R, L01'LENGTH));
+ end ">";
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "<";
+
+ -- Id: C.8
+ function "<" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "<";
+
+ -- Id: C.9
+ function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return UNSIGNED_LESS(TO_UNSIGNED(L, R01'LENGTH), R01);
+ end "<";
+
+ -- Id: C.10
+ function "<" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return SIGNED_LESS(TO_SIGNED(L, R01'LENGTH), R01);
+ end "<";
+
+ -- Id: C.11
+ function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return UNSIGNED_LESS(L01, TO_UNSIGNED(R, L01'LENGTH));
+ end "<";
+
+ -- Id: C.12
+ function "<" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<"": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return SIGNED_LESS(L01, TO_SIGNED(R, L01'LENGTH));
+ end "<";
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "<=";
+
+ -- Id: C.14
+ function "<=" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "<=";
+
+ -- Id: C.15
+ function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(TO_UNSIGNED(L, R01'LENGTH), R01);
+ end "<=";
+
+ -- Id: C.16
+ function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L < 0;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(TO_SIGNED(L, R01'LENGTH), R01);
+ end "<=";
+
+ -- Id: C.17
+ function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L_LEFT < 0) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return UNSIGNED_LESS_OR_EQUAL(L01, TO_UNSIGNED(R, L01'LENGTH));
+ end "<=";
+
+ -- Id: C.18
+ function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L_LEFT < 0) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""<="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 < R;
+ end if;
+ return SIGNED_LESS_OR_EQUAL(L01, TO_SIGNED(R, L01'LENGTH));
+ end "<=";
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not UNSIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end ">=";
+
+ -- Id: C.20
+ function ">=" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return not SIGNED_LESS(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end ">=";
+
+ -- Id: C.21
+ function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not UNSIGNED_LESS(TO_UNSIGNED(L, R01'LENGTH), R01);
+ end ">=";
+
+ -- Id: C.22
+ function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return L > 0;
+ end if;
+ return not SIGNED_LESS(TO_SIGNED(L, R01'LENGTH), R01);
+ end ">=";
+
+ -- Id: C.23
+ function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not UNSIGNED_LESS(L01, TO_UNSIGNED(R, L01'LENGTH));
+ end ">=";
+
+ -- Id: C.24
+ function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD."">="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return 0 > R;
+ end if;
+ return not SIGNED_LESS(L01, TO_SIGNED(R, L01'LENGTH));
+ end ">=";
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "=";
+
+ -- Id: C.26
+ function "=" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ return SIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE));
+ end "=";
+
+ -- Id: C.27
+ function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(TO_UNSIGNED(L, R01'LENGTH), R01);
+ end "=";
+
+ -- Id: C.28
+ function "=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return FALSE;
+ end if;
+ return SIGNED_EQUAL(TO_SIGNED(L, R01'LENGTH), R01);
+ end "=";
+
+ -- Id: C.29
+ function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return UNSIGNED_EQUAL(L01, TO_UNSIGNED(R, L01'LENGTH));
+ end "=";
+
+ -- Id: C.30
+ function "=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": null argument detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""="": metavalue detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return FALSE;
+ end if;
+ return SIGNED_EQUAL(L01, TO_SIGNED(R, L01'LENGTH));
+ end "=";
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R: UNSIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)));
+ end "/=";
+
+ -- Id: C.32
+ function "/=" (L, R: SIGNED) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
+ variable L01 : SIGNED(L_LEFT downto 0);
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ R01 := TO_01(XR, 'X');
+ if ((L01(L01'LEFT)='X') or (R01(R01'LEFT)='X')) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(RESIZE(L01, SIZE), RESIZE(R01, SIZE)));
+ end "/=";
+
+ -- Id: C.33
+ function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: UNSIGNED(R_LEFT downto 0) is R;
+ variable R01 : UNSIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if UNSIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(TO_UNSIGNED(L, R01'LENGTH), R01));
+ end "/=";
+
+ -- Id: C.34
+ function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN is
+ constant R_LEFT: INTEGER := R'LENGTH-1;
+ alias XR: SIGNED(R_LEFT downto 0) is R;
+ variable R01 : SIGNED(R_LEFT downto 0);
+ begin
+ if (R'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ R01 := TO_01(XR, 'X');
+ if (R01(R01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if SIGNED_NUM_BITS(L) > R'LENGTH then return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(TO_SIGNED(L, R01'LENGTH), R01));
+ end "/=";
+
+ -- Id: C.35
+ function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: UNSIGNED(L_LEFT downto 0) is L;
+ variable L01 : UNSIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if UNSIGNED_NUM_BITS(R) > L'LENGTH then return TRUE;
+ end if;
+ return not(UNSIGNED_EQUAL(L01, TO_UNSIGNED(R, L01'LENGTH)));
+ end "/=";
+
+ -- Id: C.36
+ function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN is
+ constant L_LEFT: INTEGER := L'LENGTH-1;
+ alias XL: SIGNED(L_LEFT downto 0) is L;
+ variable L01 : SIGNED(L_LEFT downto 0);
+ begin
+ if (L'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": null argument detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ L01 := TO_01(XL, 'X');
+ if (L01(L01'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.""/="": metavalue detected, returning TRUE"
+ severity WARNING;
+ return TRUE;
+ end if;
+ if SIGNED_NUM_BITS(R) > L'LENGTH then return TRUE;
+ end if;
+ return not(SIGNED_EQUAL(L01, TO_SIGNED(R, L01'LENGTH)));
+ end "/=";
+
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XSLL(STD_LOGIC_VECTOR(ARG), COUNT));
+ end SHIFT_LEFT;
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XSRL(STD_LOGIC_VECTOR(ARG), COUNT));
+ end SHIFT_RIGHT;
+
+ -- Id: S.3
+ function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XSLL(STD_LOGIC_VECTOR(ARG), COUNT));
+ end SHIFT_LEFT;
+
+ -- Id: S.4
+ function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XSRA(STD_LOGIC_VECTOR(ARG), COUNT));
+ end SHIFT_RIGHT;
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XROL(STD_LOGIC_VECTOR(ARG), COUNT));
+ end ROTATE_LEFT;
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAU;
+ end if;
+ return UNSIGNED(XROR(STD_LOGIC_VECTOR(ARG), COUNT));
+ end ROTATE_RIGHT;
+
+
+ -- Id: S.7
+ function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XROL(STD_LOGIC_VECTOR(ARG), COUNT));
+ end ROTATE_LEFT;
+
+ -- Id: S.8
+ function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED is
+ begin
+ if (ARG'LENGTH < 1) then return NAS;
+ end if;
+ return SIGNED(XROR(STD_LOGIC_VECTOR(ARG), COUNT));
+ end ROTATE_RIGHT;
+
+ --============================================================================
+--START-V93
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.9
+ function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_LEFT(ARG, COUNT);
+ else
+ return SHIFT_RIGHT(ARG, -COUNT);
+ end if;
+ end "sll";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.10
+ function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_LEFT(ARG, COUNT);
+ else
+ return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), -COUNT));
+ end if;
+ end "sll";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.11
+ function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SHIFT_RIGHT(ARG, COUNT);
+ else
+ return SHIFT_LEFT(ARG, -COUNT);
+ end if;
+ end "srl";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.12
+ function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT));
+ else
+ return SHIFT_LEFT(ARG, -COUNT);
+ end if;
+ end "srl";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.13
+ function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_LEFT(ARG, COUNT);
+ else
+ return ROTATE_RIGHT(ARG, -COUNT);
+ end if;
+ end "rol";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.14
+ function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_LEFT(ARG, COUNT);
+ else
+ return ROTATE_RIGHT(ARG, -COUNT);
+ end if;
+ end "rol";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.15
+ function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_RIGHT(ARG, COUNT);
+ else
+ return ROTATE_LEFT(ARG, -COUNT);
+ end if;
+ end "ror";
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.16
+ function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED is
+ begin
+ if (COUNT >= 0) then
+ return ROTATE_RIGHT(ARG, COUNT);
+ else
+ return ROTATE_LEFT(ARG, -COUNT);
+ end if;
+ end "ror";
+
+--END-V93
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG: UNSIGNED) return NATURAL is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XXARG: UNSIGNED(ARG_LEFT downto 0) is ARG;
+ variable XARG: UNSIGNED(ARG_LEFT downto 0);
+ variable RESULT: NATURAL := 0;
+ begin
+ if (ARG'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: null detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ XARG := TO_01(XXARG, 'X');
+ if (XARG(XARG'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ for I in XARG'RANGE loop
+ RESULT := RESULT+RESULT;
+ if XARG(I) = '1' then
+ RESULT := RESULT + 1;
+ end if;
+ end loop;
+ return RESULT;
+ end TO_INTEGER;
+
+ -- Id: D.2
+ function TO_INTEGER (ARG: SIGNED) return INTEGER is
+ variable XARG: SIGNED(ARG'LENGTH-1 downto 0);
+ begin
+ if (ARG'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: null detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ XARG := TO_01(ARG, 'X');
+ if (XARG(XARG'LEFT)='X') then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0"
+ severity WARNING;
+ return 0;
+ end if;
+ if XARG(XARG'LEFT) = '0' then
+ return TO_INTEGER(UNSIGNED(XARG));
+ else
+ return (- (TO_INTEGER(UNSIGNED(- (XARG + 1)))) -1);
+ end if;
+ end TO_INTEGER;
+
+ -- Id: D.3
+ function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED is
+ variable RESULT: UNSIGNED(SIZE-1 downto 0);
+ variable I_VAL: NATURAL := ARG;
+ begin
+ if (SIZE < 1) then return NAU;
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ if (I_VAL mod 2) = 0 then
+ RESULT(I) := '0';
+ else RESULT(I) := '1';
+ end if;
+ I_VAL := I_VAL/2;
+ end loop;
+ if not(I_VAL =0) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_UNSIGNED: vector truncated"
+ severity WARNING;
+ end if;
+ return RESULT;
+ end TO_UNSIGNED;
+
+ -- Id: D.4
+ function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED is
+ variable RESULT: SIGNED(SIZE-1 downto 0);
+ variable B_VAL: STD_LOGIC := '0';
+ variable I_VAL: INTEGER := ARG;
+ begin
+ if (SIZE < 1) then return NAS;
+ end if;
+ if (ARG < 0) then
+ B_VAL := '1';
+ I_VAL := -(ARG+1);
+ end if;
+ for I in 0 to RESULT'LEFT loop
+ if (I_VAL mod 2) = 0 then
+ RESULT(I) := B_VAL;
+ else
+ RESULT(I) := not B_VAL;
+ end if;
+ I_VAL := I_VAL/2;
+ end loop;
+ if ((I_VAL/=0) or (B_VAL/=RESULT(RESULT'LEFT))) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_SIGNED: vector truncated"
+ severity WARNING;
+ end if;
+ return RESULT;
+ end TO_SIGNED;
+
+ --============================================================================
+
+ -- Id: R.1
+ function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED is
+ alias INVEC: SIGNED(ARG'LENGTH-1 downto 0) is ARG;
+ variable RESULT: SIGNED(NEW_SIZE-1 downto 0) := (others => '0');
+ constant BOUND: INTEGER := MIN(ARG'LENGTH, RESULT'LENGTH)-2;
+ begin
+ if (NEW_SIZE < 1) then return NAS;
+ end if;
+ if (ARG'LENGTH = 0) then return RESULT;
+ end if;
+ RESULT := (others => ARG(ARG'LEFT));
+ if BOUND >= 0 then
+ RESULT(BOUND downto 0) := INVEC(BOUND downto 0);
+ end if;
+ return RESULT;
+ end RESIZE;
+
+ -- Id: R.2
+ function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED is
+ constant ARG_LEFT: INTEGER := ARG'LENGTH-1;
+ alias XARG: UNSIGNED(ARG_LEFT downto 0) is ARG;
+ variable RESULT: UNSIGNED(NEW_SIZE-1 downto 0) := (others => '0');
+ begin
+ if (NEW_SIZE < 1) then return NAU;
+ end if;
+ if XARG'LENGTH =0 then return RESULT;
+ end if;
+ if (RESULT'LENGTH < ARG'LENGTH) then
+ RESULT(RESULT'LEFT downto 0) := XARG(RESULT'LEFT downto 0);
+ else
+ RESULT(RESULT'LEFT downto XARG'LEFT+1) := (others => '0');
+ RESULT(XARG'LEFT downto 0) := XARG;
+ end if;
+ return RESULT;
+ end RESIZE;
+
+ --============================================================================
+
+ -- Id: L.1
+ function "not" (L: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(not(STD_LOGIC_VECTOR(L)));
+ return RESULT;
+ end "not";
+
+ -- Id: L.2
+ function "and" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) and STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "and";
+
+ -- Id: L.3
+ function "or" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) or STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "or";
+
+ -- Id: L.4
+ function "nand" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) nand STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "nand";
+
+ -- Id: L.5
+ function "nor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) nor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "nor";
+
+ -- Id: L.6
+ function "xor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) xor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "xor";
+
+--START-V93
+ ------------------------------------------------------------------------------
+ -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.7
+ function "xnor" (L, R: UNSIGNED) return UNSIGNED is
+ variable RESULT: UNSIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := UNSIGNED(STD_LOGIC_VECTOR(L) xnor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "xnor";
+--END-V93
+
+ -- Id: L.8
+ function "not" (L: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(not(STD_LOGIC_VECTOR(L)));
+ return RESULT;
+ end "not";
+
+ -- Id: L.9
+ function "and" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) and STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "and";
+
+ -- Id: L.10
+ function "or" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) or STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "or";
+
+ -- Id: L.11
+ function "nand" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) nand STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "nand";
+
+ -- Id: L.12
+ function "nor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) nor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "nor";
+
+ -- Id: L.13
+ function "xor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) xor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "xor";
+
+--START-V93
+ ------------------------------------------------------------------------------
+ -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: L.14
+ function "xnor" (L, R: SIGNED) return SIGNED is
+ variable RESULT: SIGNED(L'LENGTH-1 downto 0);
+ begin
+ RESULT := SIGNED(STD_LOGIC_VECTOR(L) xnor STD_LOGIC_VECTOR(R));
+ return RESULT;
+ end "xnor";
+--END-V93
+
+ --============================================================================
+
+ -- support constants for STD_MATCH:
+
+ type BOOLEAN_TABLE is array(STD_ULOGIC, STD_ULOGIC) of BOOLEAN;
+
+ constant MATCH_TABLE: BOOLEAN_TABLE := (
+ --------------------------------------------------------------------------
+ -- U X 0 1 Z W L H -
+ --------------------------------------------------------------------------
+ (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | U |
+ (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | X |
+ (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | 0 |
+ (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | 1 |
+ (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | Z |
+ (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | W |
+ (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | L |
+ (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | H |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) -- | - |
+ );
+
+ -- Id: M.1
+ function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN is
+ variable VALUE: STD_ULOGIC;
+ begin
+ return MATCH_TABLE(L, R);
+ end STD_MATCH;
+
+ -- Id: M.2
+ function STD_MATCH (L, R: UNSIGNED) return BOOLEAN is
+ alias LV: UNSIGNED(1 to L'LENGTH) is L;
+ alias RV: UNSIGNED(1 to R'LENGTH) is R;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if LV'LENGTH /= RV'LENGTH then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ else
+ for I in LV'LOW to LV'HIGH loop
+ if not (MATCH_TABLE(LV(I), RV(I))) then
+ return FALSE;
+ end if;
+ end loop;
+ return TRUE;
+ end if;
+ end STD_MATCH;
+
+ -- Id: M.3
+ function STD_MATCH (L, R: SIGNED) return BOOLEAN is
+ alias LV: SIGNED(1 to L'LENGTH) is L;
+ alias RV: SIGNED(1 to R'LENGTH) is R;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if LV'LENGTH /= RV'LENGTH then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ else
+ for I in LV'LOW to LV'HIGH loop
+ if not (MATCH_TABLE(LV(I), RV(I))) then
+ return FALSE;
+ end if;
+ end loop;
+ return TRUE;
+ end if;
+ end STD_MATCH;
+
+ -- Id: M.4
+ function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN is
+ alias LV: STD_LOGIC_VECTOR(1 to L'LENGTH) is L;
+ alias RV: STD_LOGIC_VECTOR(1 to R'LENGTH) is R;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if LV'LENGTH /= RV'LENGTH then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ else
+ for I in LV'LOW to LV'HIGH loop
+ if not (MATCH_TABLE(LV(I), RV(I))) then
+ return FALSE;
+ end if;
+ end loop;
+ return TRUE;
+ end if;
+ end STD_MATCH;
+
+ -- Id: M.5
+ function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN is
+ alias LV: STD_ULOGIC_VECTOR(1 to L'LENGTH) is L;
+ alias RV: STD_ULOGIC_VECTOR(1 to R'LENGTH) is R;
+ begin
+ if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: null detected, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ end if;
+ if LV'LENGTH /= RV'LENGTH then
+ assert NO_WARNING
+ report "NUMERIC_STD.STD_MATCH: L'LENGTH /= R'LENGTH, returning FALSE"
+ severity WARNING;
+ return FALSE;
+ else
+ for I in LV'LOW to LV'HIGH loop
+ if not (MATCH_TABLE(LV(I), RV(I))) then
+ return FALSE;
+ end if;
+ end loop;
+ return TRUE;
+ end if;
+ end STD_MATCH;
+
+ --============================================================================
+
+ -- function TO_01 is used to convert vectors to the
+ -- correct form for exported functions,
+ -- and to report if there is an element which
+ -- is not in (0, 1, H, L).
+
+ -- Id: T.1
+ function TO_01 (S: UNSIGNED; XMAP: STD_LOGIC := '0') return UNSIGNED is
+ variable RESULT: UNSIGNED(S'LENGTH-1 downto 0);
+ variable BAD_ELEMENT: BOOLEAN := FALSE;
+ alias XS: UNSIGNED(S'LENGTH-1 downto 0) is S;
+ begin
+ if (S'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: null detected, returning NAU"
+ severity WARNING;
+ return NAU;
+ end if;
+ for I in RESULT'RANGE loop
+ case XS(I) is
+ when '0' | 'L' => RESULT(I) := '0';
+ when '1' | 'H' => RESULT(I) := '1';
+ when others => BAD_ELEMENT := TRUE;
+ end case;
+ end loop;
+ if BAD_ELEMENT then
+ for I in RESULT'RANGE loop
+ RESULT(I) := XMAP; -- standard fixup
+ end loop;
+ end if;
+ return RESULT;
+ end TO_01;
+
+ -- Id: T.2
+ function TO_01 (S: SIGNED; XMAP: STD_LOGIC := '0') return SIGNED is
+ variable RESULT: SIGNED(S'LENGTH-1 downto 0);
+ variable BAD_ELEMENT: BOOLEAN := FALSE;
+ alias XS: SIGNED(S'LENGTH-1 downto 0) is S;
+ begin
+ if (S'LENGTH < 1) then
+ assert NO_WARNING
+ report "NUMERIC_STD.TO_01: null detected, returning NAS"
+ severity WARNING;
+ return NAS;
+ end if;
+ for I in RESULT'RANGE loop
+ case XS(I) is
+ when '0' | 'L' => RESULT(I) := '0';
+ when '1' | 'H' => RESULT(I) := '1';
+ when others => BAD_ELEMENT := TRUE;
+ end case;
+ end loop;
+ if BAD_ELEMENT then
+ for I in RESULT'RANGE loop
+ RESULT(I) := XMAP; -- standard fixup
+ end loop;
+ end if;
+ return RESULT;
+ end TO_01;
+
+ --============================================================================
+
+end NUMERIC_STD;
diff --git a/libraries/ieee/numeric_std.vhdl b/libraries/ieee/numeric_std.vhdl
new file mode 100644
index 000000000..da22c32b0
--- /dev/null
+++ b/libraries/ieee/numeric_std.vhdl
@@ -0,0 +1,853 @@
+-- --------------------------------------------------------------------
+--
+-- Copyright 1995 by IEEE. All rights reserved.
+--
+-- This source file is considered by the IEEE to be an essential part of the use
+-- of the standard 1076.3 and as such may be distributed without change, except
+-- as permitted by the standard. This source file may not be sold or distributed
+-- for profit. This package may be modified to include additional data required
+-- by tools, but must in no way change the external interfaces or simulation
+-- behaviour of the description. It is permissible to add comments and/or
+-- attributes to the package declarations, but not to change or delete any
+-- original lines of the approved package declaration. The package body may be
+-- changed only in accordance with the terms of clauses 7.1 and 7.2 of the
+-- standard.
+--
+-- Title : Standard VHDL Synthesis Package (1076.3, NUMERIC_STD)
+--
+-- Library : This package shall be compiled into a library symbolically
+-- : named IEEE.
+--
+-- Developers : IEEE DASC Synthesis Working Group, PAR 1076.3
+--
+-- Purpose : This package defines numeric types and arithmetic functions
+-- : for use with synthesis tools. Two numeric types are defined:
+-- : -- > UNSIGNED: represents UNSIGNED number in vector form
+-- : -- > SIGNED: represents a SIGNED number in vector form
+-- : The base element type is type STD_LOGIC.
+-- : The leftmost bit is treated as the most significant bit.
+-- : Signed vectors are represented in two's complement form.
+-- : This package contains overloaded arithmetic operators on
+-- : the SIGNED and UNSIGNED types. The package also contains
+-- : useful type conversions functions.
+-- :
+-- : If any argument to a function is a null array, a null array is
+-- : returned (exceptions, if any, are noted individually).
+--
+-- Limitation :
+--
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : NUMERIC_STD. The NUMERIC_STD package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+--
+-- --------------------------------------------------------------------
+-- modification history :
+-- --------------------------------------------------------------------
+-- Version: 2.4
+-- Date : 12 April 1995
+-- -----------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+package NUMERIC_STD is
+ constant CopyRightNotice: STRING
+ := "Copyright 1995 IEEE. All rights reserved.";
+
+ --============================================================================
+ -- Numeric array type definitions
+ --============================================================================
+
+ type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
+ type SIGNED is array (NATURAL range <>) of STD_LOGIC;
+
+ --============================================================================
+ -- Arithmetic Operators:
+ --===========================================================================
+
+ -- Id: A.1
+ function "abs" (ARG: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0).
+ -- Result: Returns the absolute value of a SIGNED vector ARG.
+
+ -- Id: A.2
+ function "-" (ARG: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0).
+ -- Result: Returns the value of the unary minus operation on a
+ -- SIGNED vector ARG.
+
+ --============================================================================
+
+ -- Id: A.3
+ function "+" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.4
+ function "+" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Adds two SIGNED vectors that may be of different lengths.
+
+ -- Id: A.5
+ function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
+ -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
+
+ -- Id: A.6
+ function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
+ -- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
+
+ -- Id: A.7
+ function "+" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0).
+ -- Result: Adds an INTEGER, L(may be positive or negative), to a SIGNED
+ -- vector, R.
+
+ -- Id: A.8
+ function "+" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0).
+ -- Result: Adds a SIGNED vector, L, to an INTEGER, R.
+
+ --============================================================================
+
+ -- Id: A.9
+ function "-" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts two UNSIGNED vectors that may be of different lengths.
+
+ -- Id: A.10
+ function "-" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
+ -- Result: Subtracts a SIGNED vector, R, from another SIGNED vector, L,
+ -- that may possibly be of different lengths.
+
+ -- Id: A.11
+ function "-" (L: UNSIGNED;R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
+ -- Result: Subtracts a non-negative INTEGER, R, from an UNSIGNED vector, L.
+
+ -- Id: A.12
+ function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
+ -- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L.
+
+ -- Id: A.13
+ function "-" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0).
+ -- Result: Subtracts an INTEGER, R, from a SIGNED vector, L.
+
+ -- Id: A.14
+ function "-" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0).
+ -- Result: Subtracts a SIGNED vector, R, from an INTEGER, L.
+
+ --============================================================================
+
+ -- Id: A.15
+ function "*" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Performs the multiplication operation on two UNSIGNED vectors
+ -- that may possibly be of different lengths.
+
+ -- Id: A.16
+ function "*" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED((L'LENGTH+R'LENGTH-1) downto 0)
+ -- Result: Multiplies two SIGNED vectors that may possibly be of
+ -- different lengths.
+
+ -- Id: A.17
+ function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, L, with a non-negative
+ -- INTEGER, R. R is converted to an UNSIGNED vector of
+ -- SIZE L'LENGTH before multiplication.
+
+ -- Id: A.18
+ function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0).
+ -- Result: Multiplies an UNSIGNED vector, R, with a non-negative
+ -- INTEGER, L. L is converted to an UNSIGNED vector of
+ -- SIZE R'LENGTH before multiplication.
+
+ -- Id: A.19
+ function "*" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED((L'LENGTH+L'LENGTH-1) downto 0)
+ -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is
+ -- converted to a SIGNED vector of SIZE L'LENGTH before
+ -- multiplication.
+
+ -- Id: A.20
+ function "*" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED((R'LENGTH+R'LENGTH-1) downto 0)
+ -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is
+ -- converted to a SIGNED vector of SIZE R'LENGTH before
+ -- multiplication.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "/" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.21
+ function "/" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by another UNSIGNED vector, R.
+
+ -- Id: A.22
+ function "/" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an SIGNED vector, L, by another SIGNED vector, R.
+
+ -- Id: A.23
+ function "/" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides an UNSIGNED vector, L, by a non-negative INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.24
+ function "/" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Divides a non-negative INTEGER, L, by an UNSIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.25
+ function "/" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Divides a SIGNED vector, L, by an INTEGER, R.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.26
+ function "/" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Divides an INTEGER, L, by a SIGNED vector, R.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "rem" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.27
+ function "rem" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.28
+ function "rem" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L and R are SIGNED vectors.
+
+ -- Id: A.29
+ function "rem" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is an UNSIGNED vector and R is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.30
+ function "rem" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is an UNSIGNED vector and L is a
+ -- non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.31
+ function "rem" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where L is SIGNED vector and R is an INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.32
+ function "rem" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L rem R" where R is SIGNED vector and L is an INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ --
+ -- NOTE: If second argument is zero for "mod" operator, a severity level
+ -- of ERROR is issued.
+
+ -- Id: A.33
+ function "mod" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are UNSIGNED vectors.
+
+ -- Id: A.34
+ function "mod" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L and R are SIGNED vectors.
+
+ -- Id: A.35
+ function "mod" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an UNSIGNED vector and R
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.36
+ function "mod" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where R is an UNSIGNED vector and L
+ -- is a non-negative INTEGER.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ -- Id: A.37
+ function "mod" (L: SIGNED; R: INTEGER) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+ -- If NO_OF_BITS(R) > L'LENGTH, result is truncated to L'LENGTH.
+
+ -- Id: A.38
+ function "mod" (L: INTEGER; R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(R'LENGTH-1 downto 0)
+ -- Result: Computes "L mod R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+ -- If NO_OF_BITS(L) > R'LENGTH, result is truncated to R'LENGTH.
+
+ --============================================================================
+ -- Comparison Operators
+ --============================================================================
+
+ -- Id: C.1
+ function ">" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.2
+ function ">" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.3
+ function ">" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.4
+ function ">" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.5
+ function ">" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.6
+ function ">" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L > R" where L is a SIGNED vector and
+ -- R is a INTEGER.
+
+ --============================================================================
+
+ -- Id: C.7
+ function "<" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.8
+ function "<" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.9
+ function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.10
+ function "<" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.11
+ function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.12
+ function "<" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L < R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.13
+ function "<=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.14
+ function "<=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.15
+ function "<=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.16
+ function "<=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.17
+ function "<=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.18
+ function "<=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L <= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.19
+ function ">=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.20
+ function ">=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.21
+ function ">=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.22
+ function ">=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.23
+ function ">=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.24
+ function ">=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L >= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.25
+ function "=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.26
+ function "=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.27
+ function "=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.28
+ function "=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.29
+ function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.30
+ function "=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L = R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+
+ -- Id: C.31
+ function "/=" (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are UNSIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.32
+ function "/=" (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L and R are SIGNED vectors possibly
+ -- of different lengths.
+
+ -- Id: C.33
+ function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a non-negative INTEGER and
+ -- R is an UNSIGNED vector.
+
+ -- Id: C.34
+ function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an INTEGER and
+ -- R is a SIGNED vector.
+
+ -- Id: C.35
+ function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is an UNSIGNED vector and
+ -- R is a non-negative INTEGER.
+
+ -- Id: C.36
+ function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: Computes "L /= R" where L is a SIGNED vector and
+ -- R is an INTEGER.
+
+ --============================================================================
+ -- Shift and Rotate Functions
+ --============================================================================
+
+ -- Id: S.1
+ function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT leftmost elements are lost.
+
+ -- Id: S.2
+ function SHIFT_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on an UNSIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT rightmost elements are lost.
+
+ -- Id: S.3
+ function SHIFT_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-left on a SIGNED vector COUNT times.
+ -- The vacated positions are filled with '0'.
+ -- The COUNT leftmost elements are lost.
+
+ -- Id: S.4
+ function SHIFT_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a shift-right on a SIGNED vector COUNT times.
+ -- The vacated positions are filled with the leftmost
+ -- element, ARG'LEFT. The COUNT rightmost elements are lost.
+
+ --============================================================================
+
+ -- Id: S.5
+ function ROTATE_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-left of an UNSIGNED vector COUNT times.
+
+ -- Id: S.6
+ function ROTATE_RIGHT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a rotate-right of an UNSIGNED vector COUNT times.
+
+ -- Id: S.7
+ function ROTATE_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a logical rotate-left of a SIGNED
+ -- vector COUNT times.
+
+ -- Id: S.8
+ function ROTATE_RIGHT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: Performs a logical rotate-right of a SIGNED
+ -- vector COUNT times.
+
+ --============================================================================
+
+ --============================================================================
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.9 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.9
+ function "sll" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.10 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.10
+ function "sll" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.11 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.11
+ function "srl" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SHIFT_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.12 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.12
+ function "srl" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: SIGNED(SHIFT_RIGHT(UNSIGNED(ARG), COUNT))
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.13 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.13
+ function "rol" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.14
+ function "rol" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_LEFT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.15 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.15
+ function "ror" (ARG: UNSIGNED; COUNT: INTEGER) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_RIGHT(ARG, COUNT)
+
+ ------------------------------------------------------------------------------
+ -- Note : Function S.16 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ ------------------------------------------------------------------------------
+ -- Id: S.16
+ function "ror" (ARG: SIGNED; COUNT: INTEGER) return SIGNED; --V93
+ -- Result subtype: SIGNED(ARG'LENGTH-1 downto 0)
+ -- Result: ROTATE_RIGHT(ARG, COUNT)
+
+ --============================================================================
+ -- RESIZE Functions
+ --============================================================================
+
+ -- Id: R.1
+ function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the SIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with the sign bit (ARG'LEFT). When truncating,
+ -- the sign bit is retained along with the rightmost part.
+
+ -- Id: R.2
+ function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(NEW_SIZE-1 downto 0)
+ -- Result: Resizes the SIGNED vector ARG to the specified size.
+ -- To create a larger vector, the new [leftmost] bit positions
+ -- are filled with '0'. When truncating, the leftmost bits
+ -- are dropped.
+
+ --============================================================================
+ -- Conversion Functions
+ --============================================================================
+
+ -- Id: D.1
+ function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
+ -- Result subtype: NATURAL. Value cannot be negative since parameter is an
+ -- UNSIGNED vector.
+ -- Result: Converts the UNSIGNED vector to an INTEGER.
+
+ -- Id: D.2
+ function TO_INTEGER (ARG: SIGNED) return INTEGER;
+ -- Result subtype: INTEGER
+ -- Result: Converts a SIGNED vector to an INTEGER.
+
+ -- Id: D.3
+ function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
+ -- Result subtype: UNSIGNED(SIZE-1 downto 0)
+ -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
+ -- the specified SIZE.
+
+ -- Id: D.4
+ function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
+ -- Result subtype: SIGNED(SIZE-1 downto 0)
+ -- Result: Converts an INTEGER to a SIGNED vector of the specified SIZE.
+
+ --============================================================================
+ -- Logical Operators
+ --============================================================================
+
+ -- Id: L.1
+ function "not" (L: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Termwise inversion
+
+ -- Id: L.2
+ function "and" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector AND operation
+
+ -- Id: L.3
+ function "or" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector OR operation
+
+ -- Id: L.4
+ function "nand" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NAND operation
+
+ -- Id: L.5
+ function "nor" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NOR operation
+
+ -- Id: L.6
+ function "xor" (L, R: UNSIGNED) return UNSIGNED;
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XOR operation
+
+ -- ---------------------------------------------------------------------------
+ -- Note : Function L.7 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ -- ---------------------------------------------------------------------------
+ -- Id: L.7
+ function "xnor" (L, R: UNSIGNED) return UNSIGNED; --V93
+ -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XNOR operation
+
+ -- Id: L.8
+ function "not" (L: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Termwise inversion
+
+ -- Id: L.9
+ function "and" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector AND operation
+
+ -- Id: L.10
+ function "or" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector OR operation
+
+ -- Id: L.11
+ function "nand" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NAND operation
+
+ -- Id: L.12
+ function "nor" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector NOR operation
+
+ -- Id: L.13
+ function "xor" (L, R: SIGNED) return SIGNED;
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XOR operation
+
+ -- ---------------------------------------------------------------------------
+ -- Note : Function L.14 is not compatible with VHDL 1076-1987. Comment
+ -- out the function (declaration and body) for VHDL 1076-1987 compatibility.
+ -- ---------------------------------------------------------------------------
+ -- Id: L.14
+ function "xnor" (L, R: SIGNED) return SIGNED; --V93
+ -- Result subtype: SIGNED(L'LENGTH-1 downto 0)
+ -- Result: Vector XNOR operation
+
+ --============================================================================
+ -- Match Functions
+ --============================================================================
+
+ -- Id: M.1
+ function STD_MATCH (L, R: STD_ULOGIC) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: terms compared per STD_LOGIC_1164 intent
+
+ -- Id: M.2
+ function STD_MATCH (L, R: UNSIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: terms compared per STD_LOGIC_1164 intent
+
+ -- Id: M.3
+ function STD_MATCH (L, R: SIGNED) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: terms compared per STD_LOGIC_1164 intent
+
+ -- Id: M.4
+ function STD_MATCH (L, R: STD_LOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: terms compared per STD_LOGIC_1164 intent
+
+ -- Id: M.5
+ function STD_MATCH (L, R: STD_ULOGIC_VECTOR) return BOOLEAN;
+ -- Result subtype: BOOLEAN
+ -- Result: terms compared per STD_LOGIC_1164 intent
+
+ --============================================================================
+ -- Translation Functions
+ --============================================================================
+
+ -- Id: T.1
+ function TO_01 (S: UNSIGNED; XMAP: STD_LOGIC := '0') return UNSIGNED;
+ -- Result subtype: UNSIGNED(S'RANGE)
+ -- Result: Termwise, 'H' is translated to '1', and 'L' is translated
+ -- to '0'. If a value other than '0'|'1'|'H'|'L' is found,
+ -- the array is set to (others => XMAP), and a warning is
+ -- issued.
+
+ -- Id: T.2
+ function TO_01 (S: SIGNED; XMAP: STD_LOGIC := '0') return SIGNED;
+ -- Result subtype: SIGNED(S'RANGE)
+ -- Result: Termwise, 'H' is translated to '1', and 'L' is translated
+ -- to '0'. If a value other than '0'|'1'|'H'|'L' is found,
+ -- the array is set to (others => XMAP), and a warning is
+ -- issued.
+
+end NUMERIC_STD;
diff --git a/libraries/ieee/std_logic_1164.vhdl b/libraries/ieee/std_logic_1164.vhdl
new file mode 100644
index 000000000..c53113be9
--- /dev/null
+++ b/libraries/ieee/std_logic_1164.vhdl
@@ -0,0 +1,175 @@
+-- --------------------------------------------------------------------
+--
+-- Title : std_logic_1164 multi-value logic system
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: IEEE model standards group (par 1164)
+-- Purpose : This packages defines a standard for designers
+-- : to use in describing the interconnection data types
+-- : used in vhdl modeling.
+-- :
+-- Limitation: The logic system defined in this package may
+-- : be insufficient for modeling switched transistors,
+-- : since such a requirement is out of the scope of this
+-- : effort. Furthermore, mathematics, primitives,
+-- : timing standards, etc. are considered orthogonal
+-- : issues as it relates to this package and are therefore
+-- : beyond the scope of this effort.
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : std_logic_1164. The std_logic_1164 package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+-- :
+-- --------------------------------------------------------------------
+-- modification history :
+-- --------------------------------------------------------------------
+-- version | mod. date:|
+-- v4.200 | 01/02/92 |
+-- --------------------------------------------------------------------
+
+PACKAGE std_logic_1164 IS
+
+ -------------------------------------------------------------------
+ -- logic state system (unresolved)
+ -------------------------------------------------------------------
+ TYPE std_ulogic IS ( 'U', -- Uninitialized
+ 'X', -- Forcing Unknown
+ '0', -- Forcing 0
+ '1', -- Forcing 1
+ 'Z', -- High Impedance
+ 'W', -- Weak Unknown
+ 'L', -- Weak 0
+ 'H', -- Weak 1
+ '-' -- Don't care
+ );
+ -------------------------------------------------------------------
+ -- unconstrained array of std_ulogic for use with the resolution function
+ -------------------------------------------------------------------
+ TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
+
+ -------------------------------------------------------------------
+ -- resolution function
+ -------------------------------------------------------------------
+ FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic;
+
+ -------------------------------------------------------------------
+ -- *** industry standard logic type ***
+ -------------------------------------------------------------------
+ SUBTYPE std_logic IS resolved std_ulogic;
+
+ -------------------------------------------------------------------
+ -- unconstrained array of std_logic for use in declaring signal arrays
+ -------------------------------------------------------------------
+ TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;
+
+ -------------------------------------------------------------------
+ -- common subtypes
+ -------------------------------------------------------------------
+ SUBTYPE X01 IS resolved std_ulogic RANGE 'X' TO '1'; -- ('X','0','1')
+ SUBTYPE X01Z IS resolved std_ulogic RANGE 'X' TO 'Z'; -- ('X','0','1','Z')
+ SUBTYPE UX01 IS resolved std_ulogic RANGE 'U' TO '1'; -- ('U','X','0','1')
+ SUBTYPE UX01Z IS resolved std_ulogic RANGE 'U' TO 'Z'; -- ('U','X','0','1','Z')
+
+ -------------------------------------------------------------------
+ -- overloaded logical operators
+ -------------------------------------------------------------------
+
+ FUNCTION "and" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
+ FUNCTION "nand" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
+ FUNCTION "or" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
+ FUNCTION "nor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
+ FUNCTION "xor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01;
+ FUNCTION "xnor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01; --V93
+ FUNCTION "not" ( l : std_ulogic ) RETURN UX01;
+
+ -------------------------------------------------------------------
+ -- vectorized overloaded logical operators
+ -------------------------------------------------------------------
+ FUNCTION "and" ( l, r : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "and" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+ FUNCTION "nand" ( l, r : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "nand" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+ FUNCTION "or" ( l, r : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "or" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+ FUNCTION "nor" ( l, r : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "nor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+ FUNCTION "xor" ( l, r : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "xor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+-- -----------------------------------------------------------------------
+-- Note : The declaration and implementation of the "xnor" function is
+-- specifically commented until at which time the VHDL language has been
+-- officially adopted as containing such a function. At such a point,
+-- the following comments may be removed along with this notice without
+-- further "official" ballotting of this std_logic_1164 package. It is
+-- the intent of this effort to provide such a function once it becomes
+-- available in the VHDL standard.
+-- -----------------------------------------------------------------------
+ FUNCTION "xnor" ( l, r : std_logic_vector ) RETURN std_logic_vector; --V93
+ FUNCTION "xnor" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;--V93
+
+ FUNCTION "not" ( l : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION "not" ( l : std_ulogic_vector ) RETURN std_ulogic_vector;
+
+ -------------------------------------------------------------------
+ -- conversion functions
+ -------------------------------------------------------------------
+ FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT;
+ FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
+ FUNCTION To_bitvector ( s : std_ulogic_vector; xmap : BIT := '0') RETURN BIT_VECTOR;
+
+ FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic;
+ FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector;
+ FUNCTION To_StdLogicVector ( s : std_ulogic_vector ) RETURN std_logic_vector;
+ FUNCTION To_StdULogicVector ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
+ FUNCTION To_StdULogicVector ( s : std_logic_vector ) RETURN std_ulogic_vector;
+
+ -------------------------------------------------------------------
+ -- strength strippers and type convertors
+ -------------------------------------------------------------------
+
+ FUNCTION To_X01 ( s : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION To_X01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
+ FUNCTION To_X01 ( s : std_ulogic ) RETURN X01;
+ FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_logic_vector;
+ FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
+ FUNCTION To_X01 ( b : BIT ) RETURN X01;
+
+ FUNCTION To_X01Z ( s : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION To_X01Z ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
+ FUNCTION To_X01Z ( s : std_ulogic ) RETURN X01Z;
+ FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_logic_vector;
+ FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
+ FUNCTION To_X01Z ( b : BIT ) RETURN X01Z;
+
+ FUNCTION To_UX01 ( s : std_logic_vector ) RETURN std_logic_vector;
+ FUNCTION To_UX01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector;
+ FUNCTION To_UX01 ( s : std_ulogic ) RETURN UX01;
+ FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_logic_vector;
+ FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector;
+ FUNCTION To_UX01 ( b : BIT ) RETURN UX01;
+
+ -------------------------------------------------------------------
+ -- edge detection
+ -------------------------------------------------------------------
+ FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
+ FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
+
+ -------------------------------------------------------------------
+ -- object contains an unknown
+ -------------------------------------------------------------------
+ FUNCTION Is_X ( s : std_ulogic_vector ) RETURN BOOLEAN;
+ FUNCTION Is_X ( s : std_logic_vector ) RETURN BOOLEAN;
+ FUNCTION Is_X ( s : std_ulogic ) RETURN BOOLEAN;
+
+END std_logic_1164;
diff --git a/libraries/ieee/std_logic_1164_body.vhdl b/libraries/ieee/std_logic_1164_body.vhdl
new file mode 100644
index 000000000..65c5965e0
--- /dev/null
+++ b/libraries/ieee/std_logic_1164_body.vhdl
@@ -0,0 +1,830 @@
+-- --------------------------------------------------------------------
+--
+-- Title : std_logic_1164 multi-value logic system
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers: IEEE model standards group (par 1164)
+-- Purpose : This packages defines a standard for designers
+-- : to use in describing the interconnection data types
+-- : used in vhdl modeling.
+-- :
+-- Limitation: The logic system defined in this package may
+-- : be insufficient for modeling switched transistors,
+-- : since such a requirement is out of the scope of this
+-- : effort. Furthermore, mathematics, primitives,
+-- : timing standards, etc. are considered orthogonal
+-- : issues as it relates to this package and are therefore
+-- : beyond the scope of this effort.
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the types, subtypes and declarations of
+-- : std_logic_1164. The std_logic_1164 package body shall be
+-- : considered the formal definition of the semantics of
+-- : this package. Tool developers may choose to implement
+-- : the package body in the most efficient manner available
+-- : to them.
+-- :
+-- --------------------------------------------------------------------
+-- modification history :
+-- --------------------------------------------------------------------
+-- version | mod. date:|
+-- v4.200 | 01/02/91 |
+-- --------------------------------------------------------------------
+
+PACKAGE BODY std_logic_1164 IS
+ -------------------------------------------------------------------
+ -- local types
+ -------------------------------------------------------------------
+ TYPE stdlogic_1d IS ARRAY (std_ulogic) OF std_ulogic;
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+
+ -------------------------------------------------------------------
+ -- resolution function
+ -------------------------------------------------------------------
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H - | |
+ -- ---------------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
+ ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
+ ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
+ ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
+ ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
+ );
+
+ FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS
+ VARIABLE result : std_ulogic := 'Z'; -- weakest state default
+ BEGIN
+ -- the test for a single driver is essential otherwise the
+ -- loop would return 'X' for a single driver of '-' and that
+ -- would conflict with the value of a single driver unresolved
+ -- signal.
+ IF (s'LENGTH = 1) THEN RETURN s(s'LOW);
+ ELSE
+ FOR i IN s'RANGE LOOP
+ result := resolution_table(result, s(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END resolved;
+
+ -------------------------------------------------------------------
+ -- tables for logical operations
+ -------------------------------------------------------------------
+
+ -- truth table for "and" function
+ CONSTANT and_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H - | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), -- | U |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 1 |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | H |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ) -- | - |
+ );
+
+ -- truth table for "or" function
+ CONSTANT or_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H - | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U' ), -- | U |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | 1 |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | H |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ) -- | - |
+ );
+
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H - | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
+ );
+
+ -- truth table for "not" function
+ CONSTANT not_table: stdlogic_1d :=
+ -- -------------------------------------------------
+ -- | U X 0 1 Z W L H - |
+ -- -------------------------------------------------
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' );
+
+ -------------------------------------------------------------------
+ -- overloaded logical operators ( with optimizing hints )
+ -------------------------------------------------------------------
+
+ FUNCTION "and" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (and_table(l, r));
+ END "and";
+
+ FUNCTION "nand" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (not_table ( and_table(l, r)));
+ END "nand";
+
+ FUNCTION "or" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (or_table(l, r));
+ END "or";
+
+ FUNCTION "nor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (not_table ( or_table( l, r )));
+ END "nor";
+
+ FUNCTION "xor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (xor_table(l, r));
+ END "xor";
+
+--START-V93
+ FUNCTION "xnor" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN not_table(xor_table(l, r));
+ END "xnor";
+--END-V93
+
+ FUNCTION "not" ( l : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (not_table(l));
+ END "not";
+
+ -------------------------------------------------------------------
+ -- and
+ -------------------------------------------------------------------
+ FUNCTION "and" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'and' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := and_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "and";
+ ---------------------------------------------------------------------
+ FUNCTION "and" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'and' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := and_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "and";
+ -------------------------------------------------------------------
+ -- nand
+ -------------------------------------------------------------------
+ FUNCTION "nand" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'nand' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(and_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "nand";
+ ---------------------------------------------------------------------
+ FUNCTION "nand" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'nand' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(and_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "nand";
+ -------------------------------------------------------------------
+ -- or
+ -------------------------------------------------------------------
+ FUNCTION "or" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'or' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := or_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "or";
+ ---------------------------------------------------------------------
+ FUNCTION "or" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'or' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := or_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "or";
+ -------------------------------------------------------------------
+ -- nor
+ -------------------------------------------------------------------
+ FUNCTION "nor" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'nor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(or_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "nor";
+ ---------------------------------------------------------------------
+ FUNCTION "nor" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'nor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(or_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "nor";
+ ---------------------------------------------------------------------
+ -- xor
+ -------------------------------------------------------------------
+ FUNCTION "xor" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'xor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := xor_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "xor";
+ ---------------------------------------------------------------------
+ FUNCTION "xor" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'xor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := xor_table (lv(i), rv(i));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "xor";
+-- -------------------------------------------------------------------
+-- -- xnor
+-- -------------------------------------------------------------------
+-- -----------------------------------------------------------------------
+-- Note : The declaration and implementation of the "xnor" function is
+-- specifically commented until at which time the VHDL language has been
+-- officially adopted as containing such a function. At such a point,
+-- the following comments may be removed along with this notice without
+-- further "official" ballotting of this std_logic_1164 package. It is
+-- the intent of this effort to provide such a function once it becomes
+-- available in the VHDL standard.
+-- -----------------------------------------------------------------------
+--START-V93
+ FUNCTION "xnor" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'xnor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(xor_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "xnor";
+ ---------------------------------------------------------------------
+ FUNCTION "xnor" ( l,r : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH );
+ BEGIN
+ IF ( l'LENGTH /= r'LENGTH ) THEN
+ ASSERT FALSE
+ REPORT "arguments of overloaded 'xnor' operator are not of the same length"
+ SEVERITY FAILURE;
+ ELSE
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table(xor_table (lv(i), rv(i)));
+ END LOOP;
+ END IF;
+ RETURN result;
+ END "xnor";
+--END-V93
+ -------------------------------------------------------------------
+ -- not
+ -------------------------------------------------------------------
+ FUNCTION "not" ( l : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
+ VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ) := (OTHERS => 'X');
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table( lv(i) );
+ END LOOP;
+ RETURN result;
+ END;
+ ---------------------------------------------------------------------
+ FUNCTION "not" ( l : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l;
+ VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ) := (OTHERS => 'X');
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := not_table( lv(i) );
+ END LOOP;
+ RETURN result;
+ END;
+ -------------------------------------------------------------------
+ -- conversion tables
+ -------------------------------------------------------------------
+ TYPE logic_x01_table IS ARRAY (std_ulogic'LOW TO std_ulogic'HIGH) OF X01;
+ TYPE logic_x01z_table IS ARRAY (std_ulogic'LOW TO std_ulogic'HIGH) OF X01Z;
+ TYPE logic_ux01_table IS ARRAY (std_ulogic'LOW TO std_ulogic'HIGH) OF UX01;
+ ----------------------------------------------------------
+ -- table name : cvt_to_x01
+ --
+ -- parameters :
+ -- in : std_ulogic -- some logic value
+ -- returns : x01 -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ --
+ -- example : if (cvt_to_x01 (input_signal) = '1' ) then ...
+ --
+ ----------------------------------------------------------
+ CONSTANT cvt_to_x01 : logic_x01_table := (
+ 'X', -- 'U'
+ 'X', -- 'X'
+ '0', -- '0'
+ '1', -- '1'
+ 'X', -- 'Z'
+ 'X', -- 'W'
+ '0', -- 'L'
+ '1', -- 'H'
+ 'X' -- '-'
+ );
+
+ ----------------------------------------------------------
+ -- table name : cvt_to_x01z
+ --
+ -- parameters :
+ -- in : std_ulogic -- some logic value
+ -- returns : x01z -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ --
+ -- example : if (cvt_to_x01z (input_signal) = '1' ) then ...
+ --
+ ----------------------------------------------------------
+ CONSTANT cvt_to_x01z : logic_x01z_table := (
+ 'X', -- 'U'
+ 'X', -- 'X'
+ '0', -- '0'
+ '1', -- '1'
+ 'Z', -- 'Z'
+ 'X', -- 'W'
+ '0', -- 'L'
+ '1', -- 'H'
+ 'X' -- '-'
+ );
+
+ ----------------------------------------------------------
+ -- table name : cvt_to_ux01
+ --
+ -- parameters :
+ -- in : std_ulogic -- some logic value
+ -- returns : ux01 -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ --
+ -- example : if (cvt_to_ux01 (input_signal) = '1' ) then ...
+ --
+ ----------------------------------------------------------
+ CONSTANT cvt_to_ux01 : logic_ux01_table := (
+ 'U', -- 'U'
+ 'X', -- 'X'
+ '0', -- '0'
+ '1', -- '1'
+ 'X', -- 'Z'
+ 'X', -- 'W'
+ '0', -- 'L'
+ '1', -- 'H'
+ 'X' -- '-'
+ );
+
+ -------------------------------------------------------------------
+ -- conversion functions
+ -------------------------------------------------------------------
+ FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT IS
+ BEGIN
+ CASE s IS
+ WHEN '0' | 'L' => RETURN ('0');
+ WHEN '1' | 'H' => RETURN ('1');
+ WHEN OTHERS => RETURN xmap;
+ END CASE;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR IS
+ ALIAS sv : std_logic_vector ( s'LENGTH-1 DOWNTO 0 ) IS s;
+ VARIABLE result : BIT_VECTOR ( s'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE sv(i) IS
+ WHEN '0' | 'L' => result(i) := '0';
+ WHEN '1' | 'H' => result(i) := '1';
+ WHEN OTHERS => result(i) := xmap;
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_bitvector ( s : std_ulogic_vector; xmap : BIT := '0') RETURN BIT_VECTOR IS
+ ALIAS sv : std_ulogic_vector ( s'LENGTH-1 DOWNTO 0 ) IS s;
+ VARIABLE result : BIT_VECTOR ( s'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE sv(i) IS
+ WHEN '0' | 'L' => result(i) := '0';
+ WHEN '1' | 'H' => result(i) := '1';
+ WHEN OTHERS => result(i) := xmap;
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic IS
+ BEGIN
+ CASE b IS
+ WHEN '0' => RETURN '0';
+ WHEN '1' => RETURN '1';
+ END CASE;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector IS
+ ALIAS bv : BIT_VECTOR ( b'LENGTH-1 DOWNTO 0 ) IS b;
+ VARIABLE result : std_logic_vector ( b'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_StdLogicVector ( s : std_ulogic_vector ) RETURN std_logic_vector IS
+ ALIAS sv : std_ulogic_vector ( s'LENGTH-1 DOWNTO 0 ) IS s;
+ VARIABLE result : std_logic_vector ( s'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := sv(i);
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_StdULogicVector ( b : BIT_VECTOR ) RETURN std_ulogic_vector IS
+ ALIAS bv : BIT_VECTOR ( b'LENGTH-1 DOWNTO 0 ) IS b;
+ VARIABLE result : std_ulogic_vector ( b'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_StdULogicVector ( s : std_logic_vector ) RETURN std_ulogic_vector IS
+ ALIAS sv : std_logic_vector ( s'LENGTH-1 DOWNTO 0 ) IS s;
+ VARIABLE result : std_ulogic_vector ( s'LENGTH-1 DOWNTO 0 );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := sv(i);
+ END LOOP;
+ RETURN result;
+ END;
+
+ -------------------------------------------------------------------
+ -- strength strippers and type convertors
+ -------------------------------------------------------------------
+ -- to_x01
+ -------------------------------------------------------------------
+ FUNCTION To_X01 ( s : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS sv : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_logic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_x01 (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS sv : std_ulogic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_ulogic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_x01 (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01 ( s : std_ulogic ) RETURN X01 IS
+ BEGIN
+ RETURN (cvt_to_x01(s));
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_logic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_logic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_ulogic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01 ( b : BIT ) RETURN X01 IS
+ BEGIN
+ CASE b IS
+ WHEN '0' => RETURN('0');
+ WHEN '1' => RETURN('1');
+ END CASE;
+ END;
+ --------------------------------------------------------------------
+ -- to_x01z
+ -------------------------------------------------------------------
+ FUNCTION To_X01Z ( s : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS sv : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_logic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_x01z (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01Z ( s : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS sv : std_ulogic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_ulogic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_x01z (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01Z ( s : std_ulogic ) RETURN X01Z IS
+ BEGIN
+ RETURN (cvt_to_x01z(s));
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_logic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_logic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01Z ( b : BIT_VECTOR ) RETURN std_ulogic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_ulogic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_X01Z ( b : BIT ) RETURN X01Z IS
+ BEGIN
+ CASE b IS
+ WHEN '0' => RETURN('0');
+ WHEN '1' => RETURN('1');
+ END CASE;
+ END;
+ --------------------------------------------------------------------
+ -- to_ux01
+ -------------------------------------------------------------------
+ FUNCTION To_UX01 ( s : std_logic_vector ) RETURN std_logic_vector IS
+ ALIAS sv : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_logic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_ux01 (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_UX01 ( s : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ ALIAS sv : std_ulogic_vector ( 1 TO s'LENGTH ) IS s;
+ VARIABLE result : std_ulogic_vector ( 1 TO s'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ result(i) := cvt_to_ux01 (sv(i));
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_UX01 ( s : std_ulogic ) RETURN UX01 IS
+ BEGIN
+ RETURN (cvt_to_ux01(s));
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_logic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_logic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_UX01 ( b : BIT_VECTOR ) RETURN std_ulogic_vector IS
+ ALIAS bv : BIT_VECTOR ( 1 TO b'LENGTH ) IS b;
+ VARIABLE result : std_ulogic_vector ( 1 TO b'LENGTH );
+ BEGIN
+ FOR i IN result'RANGE LOOP
+ CASE bv(i) IS
+ WHEN '0' => result(i) := '0';
+ WHEN '1' => result(i) := '1';
+ END CASE;
+ END LOOP;
+ RETURN result;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION To_UX01 ( b : BIT ) RETURN UX01 IS
+ BEGIN
+ CASE b IS
+ WHEN '0' => RETURN('0');
+ WHEN '1' => RETURN('1');
+ END CASE;
+ END;
+
+ -------------------------------------------------------------------
+ -- edge detection
+ -------------------------------------------------------------------
+ FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
+ BEGIN
+ RETURN (s'EVENT AND (To_X01(s) = '1') AND
+ (To_X01(s'LAST_VALUE) = '0'));
+ END;
+
+ FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
+ BEGIN
+ RETURN (s'EVENT AND (To_X01(s) = '0') AND
+ (To_X01(s'LAST_VALUE) = '1'));
+ END;
+
+ -------------------------------------------------------------------
+ -- object contains an unknown
+ -------------------------------------------------------------------
+ FUNCTION Is_X ( s : std_ulogic_vector ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN s'RANGE LOOP
+ CASE s(i) IS
+ WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
+ WHEN OTHERS => NULL;
+ END CASE;
+ END LOOP;
+ RETURN FALSE;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION Is_X ( s : std_logic_vector ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN s'RANGE LOOP
+ CASE s(i) IS
+ WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
+ WHEN OTHERS => NULL;
+ END CASE;
+ END LOOP;
+ RETURN FALSE;
+ END;
+ --------------------------------------------------------------------
+ FUNCTION Is_X ( s : std_ulogic ) RETURN BOOLEAN IS
+ BEGIN
+ CASE s IS
+ WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
+ WHEN OTHERS => NULL;
+ END CASE;
+ RETURN FALSE;
+ END;
+
+END std_logic_1164;
diff --git a/libraries/mentor/std_logic_arith.vhdl b/libraries/mentor/std_logic_arith.vhdl
new file mode 100644
index 000000000..7bbd1d80b
--- /dev/null
+++ b/libraries/mentor/std_logic_arith.vhdl
@@ -0,0 +1,254 @@
+----------------------------------------------------------------------------
+-- --
+-- Copyright (c) 1993 by Mentor Graphics --
+-- --
+-- This source file is proprietary information of Mentor Graphics,Inc. --
+-- It may be distributed in whole without restriction provided that --
+-- this copyright statement is not removed from the file and that --
+-- any derivative work contains this copyright notice. --
+-- --
+-- Package Name : std_logic_arith --
+-- --
+-- Purpose : This package is to allow the synthesis of the 1164 package. --
+-- This package add the capability of SIGNED/UNSIGNED math. --
+-- --
+----------------------------------------------------------------------------
+
+LIBRARY ieee ;
+
+PACKAGE std_logic_arith IS
+
+
+ USE ieee.std_logic_1164.ALL;
+
+ TYPE SIGNED IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;
+ TYPE UNSIGNED IS ARRAY (Natural RANGE <>) OF STD_LOGIC ;
+
+ FUNCTION std_ulogic_wired_or ( input : std_ulogic_vector ) RETURN std_ulogic;
+ FUNCTION std_ulogic_wired_and ( input : std_ulogic_vector ) RETURN std_ulogic;
+
+ -------------------------------------------------------------------------------
+ -- Note that all functions that take two vector arguments will
+ -- handle unequal argument lengths
+ -------------------------------------------------------------------------------
+
+ -------------------------------------------------------------------
+ -- Conversion Functions
+ -------------------------------------------------------------------
+
+ -- Except for the to_integer and conv_integer functions for the
+ -- signed argument all others assume the input vector to be of
+ -- magnitude representation. The signed functions assume
+ -- a 2's complement representation.
+ FUNCTION to_integer ( arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
+ FUNCTION to_integer ( arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
+ FUNCTION to_integer ( arg1 : STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL;
+ FUNCTION to_integer ( arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL;
+ FUNCTION to_integer ( arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER;
+
+ FUNCTION conv_integer ( arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
+ FUNCTION conv_integer ( arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER;
+ FUNCTION conv_integer ( arg1 : STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL;
+ FUNCTION conv_integer ( arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL;
+ FUNCTION conv_integer ( arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER;
+
+ -- Following functions will return the natural argument in magnitude representation.
+ FUNCTION to_stdlogic ( arg1 : BOOLEAN ) RETURN STD_LOGIC;
+ FUNCTION to_stdlogicvector ( arg1 : INTEGER; size : NATURAL ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION to_stdulogicvector ( arg1 : INTEGER; size : NATURAL ) RETURN STD_ULOGIC_VECTOR;
+
+ FUNCTION to_unsigned ( arg1 : NATURAL; size : NATURAL ) RETURN UNSIGNED;
+ FUNCTION conv_unsigned ( arg1 : NATURAL; size : NATURAL ) RETURN UNSIGNED;
+
+ -- The integer argument is returned in 2's complement representation.
+ FUNCTION to_signed ( arg1 : INTEGER; size : NATURAL ) RETURN SIGNED;
+ FUNCTION conv_signed ( arg1 : INTEGER; size : NATURAL ) RETURN SIGNED;
+
+
+ -------------------------------------------------------------------------------
+ -- sign/zero extend FUNCTIONs
+ -------------------------------------------------------------------------------
+
+ -- The zero_extend functions will perform zero padding to the input vector,
+ -- returning a vector of length equal to size (the second argument). Note that
+ -- if size is less than the length of the input argument an assertion will occur.
+ FUNCTION zero_extend ( arg1 : STD_ULOGIC_VECTOR; size : NATURAL ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION zero_extend ( arg1 : STD_LOGIC_VECTOR; size : NATURAL ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION zero_extend ( arg1 : STD_LOGIC; size : NATURAL ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION zero_extend ( arg1 : UNSIGNED; size : NATURAL ) RETURN UNSIGNED;
+ FUNCTION sign_extend ( arg1 : SIGNED; size : NATURAL ) RETURN SIGNED;
+
+
+ -------------------------------------------------------------------------------
+ -- Arithmetic functions
+ -------------------------------------------------------------------------------
+
+ -- All arithmetic functions except multiplication will return a vector
+ -- of size equal to the size of its largest argument. For multiplication,
+ -- the resulting vector has a size equal to the sum of the size of its inputs.
+ -- Note that arguments of unequal lengths are allowed.
+ FUNCTION "+" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC;
+ FUNCTION "+" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "+" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "+" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED ;
+ FUNCTION "+" ( arg1, arg2 : SIGNED ) RETURN SIGNED ;
+
+ FUNCTION "-" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC;
+ FUNCTION "-" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "-" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "-" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED;
+ FUNCTION "-" ( arg1, arg2 : SIGNED ) RETURN SIGNED;
+
+ FUNCTION "+" ( arg1 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "+" ( arg1 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "+" ( arg1 : UNSIGNED ) RETURN UNSIGNED;
+ FUNCTION "+" ( arg1 : SIGNED ) RETURN SIGNED;
+ FUNCTION "-" ( arg1 : SIGNED ) RETURN SIGNED;
+
+ FUNCTION "*" ( arg1, arg2 : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "*" ( arg1, arg2 : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "*" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED ;
+ FUNCTION "*" ( arg1, arg2 : SIGNED ) RETURN SIGNED ;
+
+ FUNCTION "abs" ( arg1 : SIGNED) RETURN SIGNED;
+
+ -- Vectorized Overloaded Arithmetic Operators, not supported for synthesis.
+ -- The following operators are not supported for synthesis.
+ FUNCTION "/" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "/" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "/" ( l, r : UNSIGNED ) RETURN UNSIGNED;
+ FUNCTION "/" ( l, r : SIGNED ) RETURN SIGNED;
+ FUNCTION "MOD" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "MOD" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "MOD" ( l, r : UNSIGNED ) RETURN UNSIGNED;
+ FUNCTION "REM" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "REM" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "REM" ( l, r : UNSIGNED ) RETURN UNSIGNED;
+ FUNCTION "**" ( l, r : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "**" ( l, r : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "**" ( l, r : UNSIGNED ) RETURN UNSIGNED;
+
+
+ -------------------------------------------------------------------------------
+ -- Shift and rotate functions.
+ -------------------------------------------------------------------------------
+
+ -- Note that all the shift and rotate functions below will change to overloaded
+ -- operators in the train1 release.
+ FUNCTION "sla" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "sla" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "sla" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "sla" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+ FUNCTION "sra" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "sra" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "sra" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "sra" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+ FUNCTION "sll" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "sll" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "sll" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "sll" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+ FUNCTION "srl" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "srl" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "srl" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "srl" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+ FUNCTION "rol" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "rol" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "rol" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "rol" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+ FUNCTION "ror" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED ;
+ FUNCTION "ror" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED ;
+ FUNCTION "ror" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR ;
+ FUNCTION "ror" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR ;
+
+
+ -------------------------------------------------------------------------------
+ -- Comparision functions and operators.
+ -------------------------------------------------------------------------------
+
+ -- For all comparision operators, the default operator for signed and unsigned
+ -- types has been overloaded to perform logical comparisions. Note that for
+ -- other types the default operator is not overloaded and the use will result
+ -- in literal comparisions which is not supported for synthesis.
+ --
+ -- Unequal operator widths are supported for all the comparision functions.
+ FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION eq ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION eq ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION eq ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION eq ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION "=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION "=" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ FUNCTION ne ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION ne ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION ne ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION ne ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION ne ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION "/=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION "/=" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION lt ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION lt ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION lt ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION lt ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION "<" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION "<" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ FUNCTION gt ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION gt ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION gt ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION gt ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION gt ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION ">" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION ">" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ FUNCTION le ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION le ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION le ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION le ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION le ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION "<=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION "<=" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ FUNCTION ge ( l, r : STD_LOGIC ) RETURN BOOLEAN;
+ FUNCTION ge ( l, r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION ge ( l, r : STD_LOGIC_VECTOR ) RETURN BOOLEAN;
+ FUNCTION ge ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION ge ( l, r : SIGNED ) RETURN BOOLEAN ;
+ FUNCTION ">=" ( l, r : UNSIGNED ) RETURN BOOLEAN ;
+ FUNCTION ">=" ( l, r : SIGNED ) RETURN BOOLEAN ;
+
+ -------------------------------------------------------------------------------
+ -- Logical operators.
+ -------------------------------------------------------------------------------
+
+ -- allows operands of unequal lengths, return vector is
+ -- equal to the size of the largest argument.
+
+ FUNCTION "and" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "and" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+ FUNCTION "nand" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "nand" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+ FUNCTION "or" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "or" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+ FUNCTION "nor" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "nor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+ FUNCTION "xor" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "xor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+ FUNCTION "not" (arg1:SIGNED) RETURN SIGNED;
+ FUNCTION "not" (arg1:UNSIGNED) RETURN UNSIGNED;
+
+ FUNCTION "xnor" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR;
+ FUNCTION "xnor" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+ FUNCTION "xnor" (arg1, arg2:SIGNED) RETURN SIGNED;
+ FUNCTION "xnor" (arg1, arg2:UNSIGNED) RETURN UNSIGNED;
+
+END std_logic_arith ;
+
+
diff --git a/libraries/mentor/std_logic_arith_body.vhdl b/libraries/mentor/std_logic_arith_body.vhdl
new file mode 100644
index 000000000..36f76cb7d
--- /dev/null
+++ b/libraries/mentor/std_logic_arith_body.vhdl
@@ -0,0 +1,2915 @@
+LIBRARY ieee;
+-- LIBRARY arithmetic;
+
+PACKAGE BODY std_logic_arith IS
+
+ USE ieee.std_logic_1164.ALL;
+ -- USE arithmetic.utils.all;
+
+ -------------------------------------------------------------------
+ -- Local Types
+ -------------------------------------------------------------------
+ TYPE stdlogic_1d IS ARRAY (std_ulogic) OF std_ulogic;
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+ TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
+
+ --------------------------------------------------------------------
+ --------------------------------------------------------------------
+ -- FUNCTIONS DEFINED FOR SYNTHESIS
+ --------------------------------------------------------------------
+ --------------------------------------------------------------------
+
+ FUNCTION std_ulogic_wired_or ( input : std_ulogic_vector ) RETURN std_ulogic IS
+ VARIABLE result : std_ulogic := '-'; -- weakest state default
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ---------------------------------------------------------
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | U |
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | X |
+ ( 'X', 'X', '0', '1', '0', 'X', '0', '1', '0' ), -- | 0 |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | 1 |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ), -- | Z |
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | W |
+ ( 'X', 'X', '0', '1', '0', 'X', '0', '1', '0' ), -- | L |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | H |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ) -- | D |
+ );
+
+ BEGIN
+ -- Iterate through all inputs
+ FOR i IN input'range LOOP
+ result := resolution_table(result, input(i));
+ END LOOP;
+ -- Return the resultant value
+ RETURN result;
+ END std_ulogic_wired_or;
+
+ FUNCTION std_ulogic_wired_and ( input : std_ulogic_vector ) RETURN std_ulogic IS
+ VARIABLE result : std_ulogic := '-'; -- weakest state default
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ---------------------------------------------------------
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | U |
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 |
+ ( 'X', 'X', '0', '1', '1', 'X', '0', '1', '1' ), -- | 1 |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ), -- | Z |
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L |
+ ( 'X', 'X', '0', '1', '1', 'X', '0', '1', '1' ), -- | H |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ) -- | D |
+ );
+
+ BEGIN
+ -- Iterate through all inputs
+ FOR i IN input'range LOOP
+ result := resolution_table(result, input(i));
+ END LOOP;
+ -- Return the resultant value
+ RETURN result;
+ END std_ulogic_wired_and;
+
+--
+-- MGC base level functions
+--
+--
+-- Convert Base Type to Integer
+--
+ FUNCTION to_integer (arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION to_integer (arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION to_integer (arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL IS
+ VARIABLE tmp : SIGNED( arg1'length DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : NATURAL;
+ BEGIN
+ tmp := '0' & SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION TO_INTEGER (arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE return_int,x_tmp : INTEGER := 0;
+ BEGIN
+ ASSERT arg1'length > 0
+ REPORT "NULL vector, returning 0"
+ SEVERITY NOTE;
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT arg1'length <= 32 -- implementation dependent limit
+ REPORT "vector too large, conversion may cause overflow"
+ SEVERITY WARNING;
+ IF x /= 0 THEN
+ x_tmp := 1;
+ END IF;
+ IF arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L' OR -- positive value
+ ( x_tmp = 0 AND arg1(arg1'left) /= '1' AND arg1(arg1'left) /= 'H') THEN
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => NULL;
+ WHEN '1'|'H' => return_int := return_int + 1;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ ELSE -- negative value
+ IF (x_tmp = 0) THEN
+ x_tmp := 1;
+ ELSE
+ x_tmp := 0;
+ END IF;
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => return_int := return_int + 1;
+ WHEN '1'|'H' => NULL;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ return_int := (-return_int) - 1;
+ END IF;
+ RETURN return_int;
+ END TO_INTEGER;
+
+ FUNCTION to_integer (arg1:STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL IS
+ BEGIN
+ IF(arg1 = '0' OR arg1 = 'L' OR (x = 0 AND arg1 /= '1' AND arg1 /= 'H')) THEN
+ RETURN(0);
+ ELSE
+ RETURN(1) ;
+ END IF ;
+ END ;
+
+ FUNCTION conv_integer (arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_integer (arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length -1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_integer (arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL IS
+ VARIABLE tmp : SIGNED( arg1'length DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : NATURAL;
+ BEGIN
+ tmp := '0' & SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_INTEGER (arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE return_int,x_tmp : INTEGER := 0;
+ BEGIN
+ ASSERT arg1'length > 0
+ REPORT "NULL vector, returning 0"
+ SEVERITY NOTE;
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT arg1'length <= 32 -- implementation dependent limit
+ REPORT "vector too large, conversion may cause overflow"
+ SEVERITY WARNING;
+ IF x /= 0 THEN
+ x_tmp := 1;
+ END IF;
+ IF arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L' OR -- positive value
+ ( x_tmp = 0 AND arg1(arg1'left) /= '1' AND arg1(arg1'left) /= 'H') THEN
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => NULL;
+ WHEN '1'|'H' => return_int := return_int + 1;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ ELSE -- negative value
+ IF (x_tmp = 0) THEN
+ x_tmp := 1;
+ ELSE
+ x_tmp := 0;
+ END IF;
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => return_int := return_int + 1;
+ WHEN '1'|'H' => NULL;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ return_int := (-return_int) - 1;
+ END IF;
+ RETURN return_int;
+ END ;
+
+ FUNCTION conv_integer (arg1:STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL IS
+ BEGIN
+ IF(arg1 = '0' OR arg1 = 'L' OR (x = 0 AND arg1 /= '1' AND arg1 /= 'H')) THEN
+ RETURN(0);
+ ELSE
+ RETURN(1) ;
+ END IF ;
+ END ;
+
+--
+-- Convert Base Type to STD_LOGIC
+--
+
+ FUNCTION to_stdlogic (arg1:BOOLEAN) RETURN STD_LOGIC IS
+ BEGIN
+ IF(arg1) THEN
+ RETURN('1') ;
+ ELSE
+ RETURN('0') ;
+ END IF ;
+ END ;
+
+--
+-- Convert Base Type to STD_LOGIC_VECTOR
+--
+ FUNCTION To_StdlogicVector (arg1 : integer; size : NATURAL) RETURN std_logic_vector IS
+ VARIABLE vector : std_logic_vector(0 TO size-1);
+ VARIABLE tmp_int : integer := arg1;
+ VARIABLE carry : std_logic := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : std_logic;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END To_StdlogicVector;
+
+ FUNCTION To_StdUlogicVector (arg1 : integer; size : NATURAL) RETURN std_ulogic_vector IS
+ VARIABLE vector : std_ulogic_vector(0 TO size-1);
+ VARIABLE tmp_int : integer := arg1;
+ VARIABLE carry : std_ulogic := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : std_ulogic;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END To_StdUlogicVector;
+
+
+--
+-- Convert Base Type to UNSIGNED
+--
+
+ FUNCTION to_unsigned (arg1:NATURAL ; size:NATURAL) RETURN UNSIGNED IS
+ VARIABLE vector : UNSIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ RETURN vector;
+ END ;
+
+ FUNCTION conv_unsigned (arg1:NATURAL ; size:NATURAL) RETURN UNSIGNED IS
+ VARIABLE vector : UNSIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ RETURN vector;
+ END ;
+
+--
+-- Convert Base Type to SIGNED
+--
+
+ FUNCTION to_signed (arg1:INTEGER ; size : NATURAL) RETURN SIGNED IS
+ VARIABLE vector : SIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ VARIABLE carry : STD_LOGIC := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : STD_LOGIC := '0';
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END ;
+
+ FUNCTION conv_signed (arg1:INTEGER ; size : NATURAL) RETURN SIGNED IS
+ VARIABLE vector : SIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ VARIABLE carry : STD_LOGIC := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : STD_LOGIC := '0';
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END ;
+
+ -- sign/zero extend functions
+ --
+
+ FUNCTION zero_extend ( arg1 : STD_ULOGIC_VECTOR; size : NATURAL ) RETURN STD_ULOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_ULOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length-1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : STD_LOGIC_VECTOR; size : NATURAL ) RETURN STD_LOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length-1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : STD_LOGIC; size : NATURAL ) RETURN STD_LOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ answer := (OTHERS => '0') ;
+ answer(0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : UNSIGNED; size : NATURAL ) RETURN UNSIGNED IS
+ VARIABLE answer : UNSIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length - 1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION sign_extend ( arg1 : SIGNED; size : NATURAL ) RETURN SIGNED IS
+ VARIABLE answer : SIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => arg1(arg1'left)) ;
+ answer(arg1'length - 1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+
+
+ -- Some useful generic functions
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
+ VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : STD_LOGIC_VECTOR; i : INTEGER ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE qs : STD_LOGIC_VECTOR (1 TO i);
+ VARIABLE qt : STD_LOGIC_VECTOR (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : UNSIGNED; i : INTEGER ) RETURN UNSIGNED IS
+ VARIABLE qs : UNSIGNED (1 TO i);
+ VARIABLE qt : UNSIGNED (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+--------------------------------------
+-- Synthesizable addition Functions --
+--------------------------------------
+
+ FUNCTION "+" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC IS
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+ BEGIN
+ RETURN xor_table( arg1, arg2 );
+ END "+";
+
+ function maximum (arg1, arg2: integer) return integer is
+ begin
+ if arg1 > arg2 then
+ return arg1;
+ else
+ return arg2;
+ end if;
+ end;
+
+ FUNCTION "+" (arg1, arg2 :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE carry : STD_ULOGIC := '0';
+ VARIABLE a,b,s1 : STD_ULOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2 :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE carry : STD_LOGIC := '0';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE res : UNSIGNED(1 TO ml);
+ VARIABLE carry : STD_LOGIC := '0';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a + b);
+ RETURN (answer);
+ END ;
+
+-----------------------------------------
+-- Synthesizable subtraction Functions --
+-----------------------------------------
+
+ FUNCTION "-" ( arg1, arg2 : std_logic ) RETURN std_logic IS
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+ BEGIN
+ RETURN xor_table( arg1, arg2 );
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE borrow : STD_ULOGIC := '1';
+ VARIABLE a,b,s1 : STD_ULOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE borrow : STD_LOGIC := '1';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE res : UNSIGNED(1 TO ml);
+ VARIABLE borrow : STD_LOGIC := '1';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+
+ FUNCTION "-" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED( a - b );
+ RETURN (answer);
+ END ;
+
+-----------------------------------------
+-- Unary subtract and add Functions --
+-----------------------------------------
+ FUNCTION "+" (arg1:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:UNSIGNED) RETURN UNSIGNED IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:SIGNED) RETURN SIGNED IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION hasx( v : SIGNED ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION "-" (arg1:SIGNED) RETURN SIGNED IS
+ constant len : integer := arg1'length;
+ VARIABLE answer, tmp : SIGNED( len-1 downto 0 ) := (others=>'0');
+ VARIABLE index : integer := len;
+ BEGIN
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ IF hasx(arg1) THEN
+ answer := (OTHERS => 'X');
+ ELSE
+ tmp := arg1;
+ lp1 : FOR i IN answer'REVERSE_RANGE LOOP
+ IF (tmp(i) = '1' OR tmp(i) = 'H') THEN
+ index := i+1;
+ answer(i downto 0) := tmp(i downto 0);
+ exit;
+ END IF;
+ END LOOP lp1;
+ answer(len-1 downto index) := NOT tmp(len-1 downto index);
+ end if;
+ RETURN (answer);
+ END ;
+
+--------------------------------------------
+-- Synthesizable multiplication Functions --
+--------------------------------------------
+ FUNCTION shift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE v1 : STD_ULOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN STD_ULOGIC_VECTOR; b : OUT STD_ULOGIC_VECTOR) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE v1 : STD_LOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN STD_LOGIC_VECTOR; b : OUT STD_LOGIC_VECTOR) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : SIGNED ) RETURN SIGNED IS
+ VARIABLE v1 : SIGNED( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN SIGNED; b : OUT SIGNED) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE v1 : UNSIGNED( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN UNSIGNED; b : OUT UNSIGNED) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION "*" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE prod : STD_ULOGIC_VECTOR(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION "*" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE prod : STD_LOGIC_VECTOR(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION "*" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE prod : UNSIGNED(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ --//// Sign Extend ////
+ --
+ -- Function sxt
+ --
+ FUNCTION sxt( q : SIGNED; i : INTEGER ) RETURN SIGNED IS
+ VARIABLE qs : SIGNED (1 TO i);
+ VARIABLE qt : SIGNED (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>q(q'left));
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ FUNCTION "*" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : SIGNED(1 TO ml);
+ VARIABLE rt : SIGNED(1 TO ml);
+ VARIABLE prod : SIGNED(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := sxt( arg1, ml );
+ rt := sxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION rshift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE v1 : STD_ULOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE v1 : STD_LOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE v1 : UNSIGNED( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : UNSIGNED ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : SIGNED ) RETURN SIGNED IS
+ VARIABLE v1 : SIGNED( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION "/" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :SIGNED) RETURN SIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : SIGNED(0 TO ml+1);
+ VARIABLE rt : SIGNED(0 TO ml+1);
+ VARIABLE quote : SIGNED(1 TO ml);
+ VARIABLE tmp : SIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : SIGNED(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := sxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := sxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "MOD" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "MOD" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "MOD" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "REM" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "REM" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "REM" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "**" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ VARIABLE return_vector : STD_ULOGIC_VECTOR(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : STD_ULOGIC_VECTOR(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+ FUNCTION "**" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ VARIABLE return_vector : STD_LOGIC_VECTOR(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : STD_LOGIC_VECTOR(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+ FUNCTION "**" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ VARIABLE return_vector : UNSIGNED(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : UNSIGNED(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+--
+-- Absolute Value Functions
+--
+ FUNCTION "abs" (arg1:SIGNED) RETURN SIGNED IS
+ constant len : integer := arg1'length;
+ VARIABLE answer, tmp : SIGNED( len-1 downto 0 ) := (others=>'0');
+ VARIABLE index : integer := len;
+ BEGIN
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ IF hasx(arg1) THEN
+ answer := (OTHERS => 'X');
+ ELSIF (arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L') THEN
+ answer := arg1;
+ ELSE
+ tmp := arg1;
+ lp1 : FOR i IN answer'REVERSE_RANGE LOOP
+ IF (tmp(i) = '1' OR tmp(i) = 'H') THEN
+ index := i+1;
+ answer(i downto 0) := tmp(i downto 0);
+ exit;
+ END IF;
+ END LOOP lp1;
+ answer(len-1 downto index) := NOT tmp(len-1 downto index);
+ end if;
+ RETURN (answer);
+ END ;
+
+--
+-- Shift Left (arithmetic) Functions
+--
+
+ FUNCTION "sla" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Right (arithmetics) Functions
+--
+ FUNCTION "sra" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Left (logical) Functions
+--
+
+ FUNCTION "sll" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others =>'0');
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others =>'0');
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others =>'0');
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others =>'0');
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Right (logical) Functions
+--
+ FUNCTION "srl" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => '0');
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => '0');
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => '0');
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => '0');
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+--
+-- Rotate Left (Logical) Functions
+--
+ FUNCTION "rol" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+--
+-- Rotate Right (Logical) Functions
+--
+ FUNCTION "ror" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+--
+-- Equal functions.
+--
+ CONSTANT eq_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN eq_table( l, r );
+ END;
+
+ FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (eq( lt, rt ));
+ END;
+
+ FUNCTION "=" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION "=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (eq( lt, rt ));
+ END;
+
+--
+-- Not Equal function.
+--
+ CONSTANT neq_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+
+ FUNCTION ne ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN neq_table( l, r );
+ END;
+
+ FUNCTION ne ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (ne( lt, rt ));
+ END;
+
+ FUNCTION "/=" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION "/=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (ne( lt, rt ));
+ END;
+
+--
+-- Less Than functions.
+--
+ CONSTANT ltb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN ltb_table( l, r );
+ END;
+
+ FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rtt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : UNSIGNED ( 1 TO ml );
+ VARIABLE rtt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt, rtt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ltt := (OTHERS => l(l'left)) ;
+ ltt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rtt := (OTHERS => r(r'left)) ;
+ rtt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(ltt(ltt'left) = '1' AND rtt(rtt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(ltt(ltt'left) = '0' AND rtt(rtt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (lt( ltt, rtt ));
+ END IF ;
+ END;
+
+ FUNCTION "<" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : UNSIGNED ( 1 TO ml );
+ VARIABLE rtt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION "<" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt, rtt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ltt := (OTHERS => l(l'left)) ;
+ ltt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rtt := (OTHERS => r(r'left)) ;
+ rtt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(ltt(ltt'left) = '1' AND rtt(rtt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(ltt(ltt'left) = '0' AND rtt(rtt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (lt( ltt, rtt ));
+ END IF ;
+ END;
+
+--
+-- Greater Than functions.
+--
+ CONSTANT gtb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN gtb_table( l, r );
+ END ;
+
+ FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (gt( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION ">" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ">" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (gt( lt, rt ));
+ END IF ;
+ END;
+
+--
+-- Less Than or Equal to functions.
+--
+ CONSTANT leb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | X |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | W |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | L |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ) -- | D |
+ );
+
+ FUNCTION le ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN leb_table( l, r );
+ END ;
+
+ TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
+ TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
+
+ CONSTANT le_fuzzy_table : std_ulogic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | X |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | 0 |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | W |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | L |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ) -- | D |
+ );
+
+ FUNCTION le ( L,R : std_ulogic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_fuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ TYPE std_logic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
+ TYPE std_logic_fuzzy_state_table IS ARRAY ( std_logic, std_logic ) OF std_logic_fuzzy_state;
+
+ CONSTANT le_lfuzzy_table : std_logic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | X |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | 0 |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | W |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | L |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ) -- | D |
+ );
+
+ FUNCTION le ( L,R : std_logic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION le ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION le (l, r:SIGNED) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (le( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION "<=" ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION "<=" (l, r:SIGNED) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (le( lt, rt ));
+ END IF ;
+ END;
+
+--
+-- Greater Than or Equal to functions.
+--
+ CONSTANT geb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | 1 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | H |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION ge ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN geb_table( l, r );
+ END ;
+
+ CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
+ );
+
+ FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_fuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ CONSTANT ge_lfuzzy_table : std_logic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
+ );
+
+ FUNCTION ge ( L,R : std_logic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ge ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ge ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (ge( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION ">=" ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ">=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (ge( lt, rt ));
+ END IF ;
+ END;
+
+ -------------------------------------------------------------------------------
+ -- Logical Operations
+ -------------------------------------------------------------------------------
+
+ -- truth table for "and" function
+ CONSTANT and_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), -- | U |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 1 |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | H |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ) -- | D |
+ );
+
+ -- truth table for "or" function
+ CONSTANT or_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U' ), -- | U |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | 1 |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | H |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ) -- | D |
+ );
+
+
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+
+ -- truth table for "not" function
+ CONSTANT not_table: stdlogic_1D :=
+ -- -------------------------------------------------
+ -- | U X 0 1 Z W L H D |
+ -- -------------------------------------------------
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' );
+
+ FUNCTION "and" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := and_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "and";
+
+ FUNCTION "nand" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( and_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "nand";
+
+ FUNCTION "or" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := or_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "or";
+
+ FUNCTION "nor" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( or_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "nor";
+
+ FUNCTION "xor" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := xor_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "xor";
+
+ FUNCTION "not" ( arg1 : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE result : UNSIGNED ( arg1'RANGE ) := (Others => 'X');
+ begin
+ for i in result'range loop
+ result(i) := not_table( arg1(i) );
+ end loop;
+ return result;
+ end "not";
+
+ FUNCTION "and" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a and b);
+ RETURN (answer);
+ end "and";
+
+ FUNCTION "nand" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a nand b);
+ RETURN (answer);
+ end "nand";
+
+ FUNCTION "or" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a or b);
+ RETURN (answer);
+ end "or";
+
+ FUNCTION "nor" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a nor b);
+ RETURN (answer);
+ end "nor";
+
+ FUNCTION "xor" ( arg1, arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a xor b);
+ RETURN (answer);
+ end "xor";
+
+ FUNCTION "not" ( arg1 : SIGNED ) RETURN SIGNED IS
+ VARIABLE result : SIGNED ( arg1'RANGE ) := (Others => 'X');
+ begin
+ for i in result'range loop
+ result(i) := not_table( arg1(i) );
+ end loop;
+ return result;
+ end "not";
+
+ FUNCTION "xnor" ( arg1, arg2 : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_vector ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : std_logic_vector ) RETURN std_logic_vector IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_vector ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a xnor b);
+ RETURN (answer);
+ end "xnor";
+
+END ;
diff --git a/libraries/std/textio.vhdl b/libraries/std/textio.vhdl
new file mode 100644
index 000000000..71b3ca72e
--- /dev/null
+++ b/libraries/std/textio.vhdl
@@ -0,0 +1,130 @@
+-- Std.Textio package declaration. This file is part of GHDL.
+-- This file was written from the clause 14.3 of the VHDL LRM.
+-- Copyright (C) 2002, 2003, 2004, 2005 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.
+
+package textio is
+
+-- type definitions for text i/o
+
+ -- a LINE is a pointer to a string value.
+ type line is access string;
+
+ -- A file of variable-length ASCII records.
+ -- Note: in order to work correctly, the TEXT file type must be declared in
+ -- the textio package of library std. Otherwise, a file of string has a
+ -- non-ASCII format.
+ type text is file of string;
+
+ type side is (right, left); -- For justifying ouput data within fields.
+ subtype width is natural; -- For specifying widths of output fields.
+
+-- standard text files
+
+ file input: text is in "STD_INPUT"; --V87
+ file output: text is out "STD_OUTPUT"; --V87
+ file input : text open read_mode is "STD_INPUT"; --V93
+ file output : text open write_mode is "STD_OUTPUT"; --V93
+
+-- input routines for standard types
+
+ procedure readline (variable f: in text; l: inout line); --V87
+ procedure readline (file f: text; l: inout line); --V93
+
+ -- For READ procedures:
+ -- In this implementation, any L is accepted (ie, there is no constraints
+ -- on direction, or left bound). Therefore, even variable of type LINE
+ -- not initialized by READLINE are accepted. Strictly speaking, this is
+ -- not required by LRM, nor prevented. However, other implementations may
+ -- fail at parsing such strings.
+ --
+ -- Also, in case of error (GOOD is false), this implementation do not
+ -- modify L (as specified by the LRM) nor VALUE.
+ --
+ -- For READ procedures without a GOOD argument, an assertion fails in case
+ -- of error.
+ --
+ -- In case of overflow (ie, if the number is out of the bounds of the type),
+ -- the procedure will fail with an execution error.
+ -- FIXME: this should not occur for a bad string.
+
+ procedure read (l: inout line; value: out bit; good: out boolean);
+ procedure read (l: inout line; value: out bit);
+
+ procedure read (l: inout line; value: out bit_vector; good: out boolean);
+ procedure read (l: inout line; value: out bit_vector);
+
+ procedure read (l: inout line; value: out boolean; good: out boolean);
+ procedure read (l: inout line; value: out boolean);
+
+ procedure read (l: inout line; value: out character; good: out boolean);
+ procedure read (l: inout line; value: out character);
+
+ procedure read (l: inout line; value: out integer; good: out boolean);
+ procedure read (l: inout line; value: out integer);
+
+ procedure read (l: inout line; value: out real; good: out boolean);
+ procedure read (l: inout line; value: out real);
+
+ procedure read (l: inout line; value: out string; good: out boolean);
+ procedure read (l: inout line; value: out string);
+
+ -- This implementation requires no space after the unit identifier,
+ -- ie "7.5 nsv" is parsed as 7.5 ns.
+ -- The unit identifier can be in lower case, upper case or mixed case.
+ procedure read (l: inout line; value: out time; good: out boolean);
+ procedure read (l: inout line; value: out time);
+
+-- output routines for standard types
+
+ procedure writeline (variable f: out text; l: inout line); --V87
+ procedure writeline (file f: text; l: inout line); --V93
+
+ -- This implementation accept any value for all the types.
+ procedure write
+ (l: inout line; value: in bit;
+ justified: in side := right; field: in width := 0);
+ procedure write
+ (l: inout line; value: in bit_vector;
+ justified: in side := right; field: in width := 0);
+ procedure write
+ (l: inout line; value: in boolean;
+ justified: in side := right; field: in width := 0);
+ procedure write
+ (l: inout line; value: in character;
+ justified: in side := right; field: in width := 0);
+ procedure write
+ (l: inout line; value: in integer;
+ justified: in side := right; field: in width := 0);
+ procedure write
+ (L: inout line; value: in real;
+ justified: in side := right; field: in width := 0;
+ digits: in natural := 0);
+ procedure write
+ (l: inout line; value: in string;
+ justified: in side := right; field: in width := 0);
+
+ -- UNIT must be a unit name declared in std.standard. Of course, no rules
+ -- in the core VHDL language prevent you from using a value that is not a
+ -- unit (eg: 10 ns or even 5 fs).
+ -- An assertion error message is generated in this case, and question mark
+ -- (?) is written at the place of the unit name.
+ procedure write
+ (l: inout line; value : in time;
+ justified: in side := right; field: in width := 0; unit : in TIME := ns);
+
+end textio;
diff --git a/libraries/std/textio_body.vhdl b/libraries/std/textio_body.vhdl
new file mode 100644
index 000000000..0362ef61a
--- /dev/null
+++ b/libraries/std/textio_body.vhdl
@@ -0,0 +1,1320 @@
+-- Std.Textio package body. This file is part of GHDL.
+-- Copyright (C) 2002, 2003, 2004, 2005 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.
+
+package body textio is
+ -- output routines for standard types
+
+ -- TIME_NAMES associates time units with textual names.
+ -- Textual names are in lower cases, since according to LRM93 14.3:
+ -- when written, the identifier is expressed in lowercase characters.
+ -- The length of the names are 3 characters, the last one may be a space
+ -- for 2 characters long names.
+ type time_unit is
+ record
+ val : time;
+ name : string (1 to 3);
+ end record;
+ type time_names_type is array (1 to 8) of time_unit;
+ constant time_names : time_names_type :=
+ ((fs, "fs "), (ps, "ps "), (ns, "ns "), (us, "us "),
+ (ms, "ms "), (sec, "sec"), (min, "min"), (hr, "hr "));
+
+ -- Non breaking space character. --V93
+ constant nbsp : character := character'val (160); --V93
+
+ procedure writeline (f: out text; l: inout line) is --V87
+ procedure writeline (file f: text; l: inout line) is --V93
+ begin
+ if l = null then
+ -- LRM93 14.3
+ -- If parameter L contains a null access value at the start of the call,
+ -- the a null string is written to the file.
+ write (f, "");
+ else
+ -- LRM93 14.3
+ -- Procedure WRITELINE causes the current line designated by parameter L
+ -- to be written to the file and returns with the value of parameter L
+ -- designating a null string.
+ write (f, l.all);
+ deallocate (l);
+ l := new string'("");
+ end if;
+ end writeline;
+
+ procedure write
+ (l: inout line; value: in string;
+ justified: in side := right; field: in width := 0)
+ is
+ variable length: natural;
+ variable nl: line;
+ begin
+ -- l can be null.
+ if l = null then
+ length := 0;
+ else
+ length := l.all'length;
+ end if;
+ if value'length < field then
+ nl := new string (1 to length + field);
+ if length /= 0 then
+ nl (1 to length) := l.all;
+ end if;
+ if justified = right then
+ nl (length + 1 to length + field - value'length) := (others => ' ');
+ nl (nl.all'high - value'length + 1 to nl.all'high) := value;
+ else
+ nl (length + 1 to length + value'length) := value;
+ nl (length + value'length + 1 to nl.all'high) := (others => ' ');
+ end if;
+ else
+ nl := new string (1 to length + value'length);
+ if length /= 0 then
+ nl (1 to length) := l.all;
+ end if;
+ nl (length + 1 to nl.all'high) := value;
+ end if;
+ deallocate (l);
+ l := nl;
+ end write;
+
+ procedure write
+ (l: inout line; value: in integer;
+ justified: in side := right; field: in width := 0)
+ is
+ variable str: string (11 downto 1);
+ variable val: integer := value;
+ variable digit: natural;
+ variable index: natural := 0;
+ begin
+ -- Note: the absolute value of VAL cannot be directly taken, since
+ -- it may be greather that the maximum value of an INTEGER.
+ loop
+ -- LRM93 7.2.6
+ -- (A rem B) has the sign of A and an absolute value less then
+ -- the absoulte value of B.
+ digit := abs (val rem 10);
+ val := val / 10;
+ index := index + 1;
+ str (index) := character'val(48 + digit);
+ exit when val = 0;
+ end loop;
+ if value < 0 then
+ index := index + 1;
+ str(index) := '-';
+ end if;
+ write (l, str (index downto 1), justified, field);
+ end write;
+
+ procedure write
+ (l: inout line; value: in boolean;
+ justified: in side := right; field: in width := 0)
+ is
+ begin
+ if value then
+ write (l, string'("TRUE"), justified, field);
+ else
+ write (l, string'("FALSE"), justified, field);
+ end if;
+ end write;
+
+ procedure write
+ (l: inout line; value: in character;
+ justified: in side := right; field: in width := 0)
+ is
+ variable str: string (1 to 1);
+ begin
+ str (1) := value;
+ write (l, str, justified, field);
+ end write;
+
+ function bit_to_char (value : in bit) return character is
+ begin
+ case value is
+ when '0' =>
+ return '0';
+ when '1' =>
+ return '1';
+ end case;
+ end bit_to_char;
+
+ procedure write
+ (l: inout line; value: in bit;
+ justified: in side := right; field: in width := 0)
+ is
+ variable str : string (1 to 1);
+ begin
+ str (1) := bit_to_char (value);
+ write (l, str, justified, field);
+ end write;
+
+ procedure write
+ (l: inout line; value: in bit_vector;
+ justified: in side := right; field: in width := 0)
+ is
+ constant length : natural := value'length;
+ alias n_value : bit_vector (1 to value'length) is value;
+ variable str : string (1 to length);
+ begin
+ for i in str'range loop
+ str (i) := bit_to_char (n_value (i));
+ end loop;
+ write (l, str, justified, field);
+ end write;
+
+ procedure write
+ (l: inout line; value : in time;
+ justified: in side := right; field: in width := 0; unit : in TIME := ns)
+ is
+ -- Copy of VALUE on which we are working.
+ variable val : time := value;
+
+ -- Copy of UNIT on which we are working.
+ variable un : time := unit;
+
+ -- Digit extract from VAL/UN.
+ variable d : integer; -- natural range 0 to 9;
+
+ -- Index for unit name.
+ variable n : integer;
+
+ -- Result.
+ variable str : string (1 to 28);
+
+ -- Current character in RES.
+ variable pos : natural := 1;
+
+ -- Add a character to STR.
+ procedure add_char (c : character) is
+ begin
+ str (pos) := c;
+ pos := pos + 1;
+ end add_char;
+ begin
+ -- Note:
+ -- Care is taken to avoid overflow. Time may be 64 bits while integer
+ -- may be only 32 bits.
+
+ -- Handle sign.
+ -- Note: VAL cannot be negated since its range may be not symetric
+ -- around 0.
+ if val < 0 ns then
+ add_char ('-');
+ end if;
+
+ -- Search for the first digit.
+ -- Note: we must start from unit, since all units are not a power of 10.
+ -- Note: UN can be multiplied only after we know it is possible. This
+ -- is a to avoid overflow.
+ if un <= 0 fs then
+ assert false report "UNIT argument is not positive" severity error;
+ un := 1 ns;
+ end if;
+ while val / 10 >= un or val / 10 <= -un loop
+ un := un * 10;
+ end loop;
+
+ -- Extract digits one per one.
+ loop
+ d := val / un;
+ add_char (character'val (abs d + character'pos ('0')));
+ val := val - d * un;
+ exit when val = 0 ns and un <= unit;
+ if un = unit then
+ add_char ('.');
+ end if;
+ -- Stop as soon as precision will be lost.
+ -- This can happen only for hr and min.
+ -- FIXME: change the algorithm to display all the digits.
+ exit when (un / 10) * 10 /= un;
+ un := un / 10;
+ end loop;
+
+ add_char (' ');
+
+ -- Search the time unit name in the time table.
+ n := 0;
+ for i in time_names'range loop
+ if time_names (i).val = unit then
+ n := i;
+ exit;
+ end if;
+ end loop;
+ assert n /= 0 report "UNIT argument is not a unit name" severity error;
+ if n = 0 then
+ add_char ('?');
+ else
+ add_char (time_names (n).name (1));
+ add_char (time_names (n).name (2));
+ if time_names (n).name (3) /= ' ' then
+ add_char (time_names (n).name (3));
+ end if;
+ end if;
+
+ -- Write the result.
+ write (l, str (1 to pos - 1), justified, field);
+ end write;
+
+ -- Parameter DIGITS specifies how many digits to the right of the decimal
+ -- point are to be output when writing a real number; the default value 0
+ -- indicates that the number should be output in standard form, consisting
+ -- of a normalized mantissa plus exponent (e.g., 1.079236E23). If DIGITS is
+ -- nonzero, then the real number is output as an integer part followed by
+ -- '.' followed by the fractional part, using the specified number of digits
+ -- (e.g., 3.14159).
+ -- Note: Nan, +Inf, -Inf are not to be considered, since these numbers are
+ -- not in the bounds defined by any real range.
+ procedure write (L: inout line; value: in real;
+ justified: in side := right; field: in width := 0;
+ digits: in natural := 0)
+ is
+ -- STR contains the result of the conversion.
+ variable str : string (1 to 320);
+
+ -- POS is the index of the next character to be put in STR.
+ variable pos : positive := str'left;
+
+ -- VAL contains the value to be converted.
+ variable val : real;
+
+ -- The exponent or mantissa computed is stored in MANTISSA. This is
+ -- a signed number.
+ variable mantissa : integer;
+
+ variable b : boolean;
+ variable d : natural;
+
+ -- Append character C in STR.
+ procedure add_char (c : character) is
+ begin
+ str (pos) := c;
+ pos := pos + 1;
+ end add_char;
+
+ -- Add digit V in STR.
+ procedure add_digit (v : natural) is
+ begin
+ add_char (character'val (character'pos ('0') + v));
+ end add_digit;
+
+ -- Add leading digit and substract it.
+ procedure extract_leading_digit is
+ variable d : natural range 0 to 10;
+ begin
+ -- Note: We need truncation but type conversion does rounding.
+ -- FIXME: should consider precision.
+ d := natural (val);
+ if real (d) > val then
+ d := d - 1;
+ end if;
+
+ val := (val - real (d)) * 10.0;
+
+ add_digit (d);
+ end extract_leading_digit;
+ begin
+ -- Handle sign.
+ -- There is no overflow here, since with IEEE implementations, sign is
+ -- independant of the mantissa.
+ -- LRM93 14.3
+ -- The sign is never written if the value is non-negative.
+ if value < 0.0 then
+ add_char ('-');
+ val := -value;
+ else
+ val := value;
+ end if;
+
+ -- Compute the mantissa.
+ -- FIXME: should do a dichotomy.
+ if val = 0.0 then
+ mantissa := 0;
+ elsif val < 1.0 then
+ mantissa := -1;
+ while val * (10.0 ** (-mantissa)) < 1.0 loop
+ mantissa := mantissa - 1;
+ end loop;
+ else
+ mantissa := 0;
+ while val / (10.0 ** mantissa) >= 10.0 loop
+ mantissa := mantissa + 1;
+ end loop;
+ end if;
+
+ -- Normalize VAL: in [0; 10[
+ if mantissa >= 0 then
+ val := val / (10.0 ** mantissa);
+ else
+ val := val * 10.0 ** (-mantissa);
+ end if;
+
+ if digits = 0 then
+ for i in 0 to 15 loop
+ extract_leading_digit;
+
+ if i = 0 then
+ add_char ('.');
+ end if;
+ exit when i > 0 and val < 10.0 ** (i + 1 - 15);
+ end loop;
+
+ -- LRM93 14.3
+ -- if the exponent is present, the `e' is written as a lower case
+ -- character.
+ add_char ('e');
+
+ if mantissa < 0 then
+ add_char ('-');
+ mantissa := -mantissa;
+ end if;
+ b := false;
+ for i in 4 downto 0 loop
+ d := (mantissa / 10000) mod 10;
+ if d /= 0 or b or i = 0 then
+ add_digit (d);
+ b := true;
+ end if;
+ mantissa := (mantissa - d * 10000) * 10;
+ end loop;
+ else
+ if mantissa < 0 then
+ add_char ('0');
+ mantissa := mantissa + 1;
+ else
+ loop
+ extract_leading_digit;
+ exit when mantissa = 0;
+ mantissa := mantissa - 1;
+ end loop;
+ end if;
+ add_char ('.');
+ for i in 1 to digits loop
+ if mantissa = 0 then
+ extract_leading_digit;
+ else
+ add_char ('0');
+ mantissa := mantissa + 1;
+ end if;
+ end loop;
+ end if;
+ write (l, str (1 to pos - 1), justified, field);
+ end write;
+
+ procedure untruncated_text_read --V87
+ (variable f : text; str : out string; len : out natural); --V87
+ procedure untruncated_text_read --V93
+ (file f : text; str : out string; len : out natural); --V93
+
+ attribute foreign : string; --V87
+ attribute foreign of untruncated_text_read : procedure is "GHDL intrinsic";
+
+ procedure untruncated_text_read
+ (variable f : text; str : out string; len : out natural) is --V87
+ (file f : text; str : out string; len : out natural) is --V93
+ begin
+ assert false report "must not be called" severity failure;
+ end untruncated_text_read;
+
+ procedure readline (variable f: in text; l: inout line) --V87
+ procedure readline (file f: text; l: inout line) --V93
+ is
+ variable len, nlen, posn : natural;
+ variable nl, old_l : line;
+ variable str : string (1 to 128);
+ variable is_eol : boolean;
+ begin
+ -- LRM93 14.3
+ -- If parameter L contains a non-null access value at the start of the
+ -- call, the object designated by that value is deallocated before the
+ -- new object is created.
+ if l /= null then
+ deallocate (l);
+ end if;
+
+ -- We read the input in 128-byte chunks.
+ -- We keep reading until we reach a newline or there is no more input.
+ -- The loop invariant is that old_l is allocated and contains the
+ -- previous chunks read, and posn = old_l.all'length.
+ posn := 0;
+ loop
+ untruncated_text_read (f, str, len);
+ exit when len = 0;
+ if str (len) = LF then
+ -- LRM 14.3
+ -- The representation of the line does not contain the representation
+ -- of the end of the line.
+ is_eol := true;
+ len := len - 1;
+ else
+ is_eol := false;
+ end if;
+ l := new string (1 to posn + len);
+ if old_l /= null then
+ l (1 to posn) := old_l (1 to posn);
+ deallocate (old_l);
+ end if;
+ l (posn + 1 to posn + len) := str (1 to len);
+ exit when is_eol;
+ posn := posn + len;
+ old_l := l;
+ end loop;
+ end readline;
+
+ -- Replaces L with L (LEFT to/downto L'RIGHT)
+ procedure trim (l : inout line; left : natural)
+ is
+ variable nl : line;
+ begin
+ if l = null then
+ return;
+ end if;
+ if l'left < l'right then
+ -- Ascending.
+ if left > l'right then
+ nl := new string'("");
+ else
+ nl := new string (left to l'right);
+-- nl := new string (1 to l'right + 1 - left);
+ nl.all := l (left to l'right);
+ end if;
+ else
+ -- Descending
+ if left < l'right then
+ nl := new string'("");
+ else
+ nl := new string (left downto l'right);
+-- nl := new string (left - l'right + 1 downto 1);
+ nl.all := l (left downto l'right);
+ end if;
+ end if;
+ deallocate (l);
+ l := nl;
+ end trim;
+
+ -- Replaces L with L (LEFT + 1 to L'RIGHT or LEFT - 1 downto L'RIGHT)
+ procedure trim_next (l : inout line; left : natural)
+ is
+ variable nl : line;
+ begin
+ if l = null then
+ return;
+ end if;
+ if l'left < l'right then
+ -- Ascending.
+ trim (l, left + 1);
+ else
+ -- Descending
+ trim (l, left - 1);
+ end if;
+ end trim_next;
+
+ function to_lower (c : character) return character is
+ begin
+ if c >= 'A' and c <= 'Z' then
+ return character'val (character'pos (c) + 32);
+ else
+ return c;
+ end if;
+ end to_lower;
+
+ procedure read (l: inout line; value: out character; good: out boolean)
+ is
+ variable nl : line;
+ begin
+ if l'length = 0 then
+ good := false;
+ else
+ value := l (l'left);
+ trim_next (l, l'left);
+ good := true;
+ end if;
+ end read;
+
+ procedure read (l: inout line; value: out character)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "character read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out bit; good: out boolean)
+ is
+ begin
+ good := false;
+ for i in l'range loop
+ case l(i) is
+ when ' '
+ | NBSP --V93
+ | HT =>
+ null;
+ when '1' =>
+ value := '1';
+ good := true;
+ trim_next (l, i);
+ return;
+ when '0' =>
+ value := '0';
+ good := true;
+ trim_next (l, i);
+ return;
+ when others =>
+ return;
+ end case;
+ end loop;
+ return;
+ end read;
+
+ procedure read (l: inout line; value: out bit)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "bit read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out bit_vector; good: out boolean)
+ is
+ -- Number of bit to parse.
+ variable len : natural;
+
+ variable pos, last : natural;
+ variable res : bit_vector (1 to value'length);
+
+ -- State of the previous byte:
+ -- LEADING: blank before the bit vector.
+ -- FOUND: bit of the vector.
+ type state_type is (leading, found);
+ variable state : state_type;
+ begin
+ -- Initialization.
+ len := value'length;
+ if len = 0 then
+ -- If VALUE is a nul array, return now.
+ -- L stay unchanged.
+ -- FIXME: should blanks be removed ?
+ good := true;
+ return;
+ end if;
+ good := false;
+ state := leading;
+ pos := res'left;
+ for i in l'range loop
+ case l(i) is
+ when ' '
+ | NBSP --V93
+ | HT =>
+ case state is
+ when leading =>
+ null;
+ when found =>
+ return;
+ end case;
+ when '1' | '0' =>
+ case state is
+ when leading =>
+ state := found;
+ when found =>
+ null;
+ end case;
+ if l(i) = '0' then
+ res (pos) := '0';
+ else
+ res (pos) := '1';
+ end if;
+ pos := pos + 1;
+ len := len - 1;
+ last := i;
+ exit when len = 0;
+ when others =>
+ return;
+ end case;
+ end loop;
+
+ if len /= 0 then
+ -- Not enough bits.
+ return;
+ end if;
+
+ -- Note: if LEN = 0, then FIRST and LAST have been set.
+ good := true;
+ value := res;
+ trim_next (l, last);
+ return;
+ end read;
+
+ procedure read (l: inout line; value: out bit_vector)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "bit_vector read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out boolean; good: out boolean)
+ is
+ -- State:
+ -- BLANK: space are being scaned.
+ -- L_TF : T(rue) or F(alse) has been scanned.
+ -- L_RA : (t)R(ue) or (f)A(lse) has been scanned.
+ -- L_UL : (tr)U(e) or (fa)L(se) has been scanned.
+ -- L_ES : (tru)E or (fal)S(e) has been scanned.
+ type state_type is (blank, l_tf, l_ra, l_ul, l_es);
+ variable state : state_type;
+
+ -- Set to TRUE if T has been scanned, to FALSE if F has been scanned.
+ variable res : boolean;
+ begin
+ -- By default, it is a failure.
+ good := false;
+ state := blank;
+ for i in l'range loop
+ case state is
+ when blank =>
+ if l (i) = ' '
+ or l (i) = nbsp --V93
+ or l (i) = HT
+ then
+ null;
+ elsif to_lower (l (i)) = 't' then
+ res := true;
+ state := l_tf;
+ elsif to_lower (l (i)) = 'f' then
+ res := false;
+ state := l_tf;
+ else
+ return;
+ end if;
+ when l_tf =>
+ if res = true and to_lower (l (i)) = 'r' then
+ state := l_ra;
+ elsif res = false and to_lower (l (i)) = 'a' then
+ state := l_ra;
+ else
+ return;
+ end if;
+ when l_ra =>
+ if res = true and to_lower (l (i)) = 'u' then
+ state := l_ul;
+ elsif res = false and to_lower (l (i)) = 'l' then
+ state := l_ul;
+ else
+ return;
+ end if;
+ when l_ul =>
+ if res = true and to_lower (l (i)) = 'e' then
+ trim_next (l, i);
+ good := true;
+ value := true;
+ return;
+ elsif res = false and to_lower (l (i)) = 's' then
+ state := l_es;
+ else
+ return;
+ end if;
+ when l_es =>
+ if res = false and to_lower (l (i)) = 'e' then
+ trim_next (l, i);
+ good := true;
+ value := false;
+ return;
+ else
+ return;
+ end if;
+ end case;
+ end loop;
+ return;
+ end read;
+
+ procedure read (l: inout line; value: out boolean)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "boolean read failure"
+ severity failure;
+ end read;
+
+ function char_to_nat (c : character) return natural
+ is
+ begin
+ return character'pos (c) - character'pos ('0');
+ end char_to_nat;
+
+ procedure read (l: inout line; value: out integer; good: out boolean)
+ is
+ variable val : integer;
+ variable d : natural;
+
+ type state_t is (leading, sign, digits);
+ variable cur_state : state_t := leading;
+ begin
+ val := 1;
+ for i in l'range loop
+ case cur_state is
+ when leading =>
+ case l(i) is
+ when ' '
+ | NBSP --V93
+ | ht =>
+ null;
+ when '+' =>
+ cur_state := sign;
+ when '-' =>
+ val := -1;
+ cur_state := sign;
+ when '0' to '9' =>
+ val := char_to_nat (l(i));
+ cur_state := digits;
+ when others =>
+ good := false;
+ return;
+ end case;
+ when sign =>
+ case l(i) is
+ when '0' to '9' =>
+ val := val * char_to_nat (l(i));
+ cur_state := digits;
+ when others =>
+ good := false;
+ return;
+ end case;
+ when digits =>
+ case l(i) is
+ when '0' to '9' =>
+ d := char_to_nat (l(i));
+ val := val * 10;
+ if val < 0 then
+ val := val - d;
+ else
+ val := val + d;
+ end if;
+ when others =>
+ trim (l, i);
+ good := true;
+ value := val;
+ return;
+ end case;
+ end case;
+ end loop;
+ deallocate (l);
+ l := new string'("");
+ if cur_state /= leading then
+ good := true;
+ value := val;
+ else
+ good := false;
+ end if;
+ end read;
+
+ procedure read (l: inout line; value: out integer)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "integer read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out real; good: out boolean)
+ is
+ -- The result.
+ variable val : real;
+ -- True if the result is negative.
+ variable val_neg : boolean;
+
+ -- Number of digits after the dot.
+ variable nbr_dec : natural;
+
+ -- Value of the exponent.
+ variable exp : integer;
+ -- True if the exponent is negative.
+ variable exp_neg : boolean;
+
+ -- The parsing is done with a state machine.
+ -- LEADING: leading blank suppression.
+ -- SIGN: a sign has been found.
+ -- DIGITS: integer parts
+ -- DECIMALS: digits after the dot.
+ -- EXPONENT_SIGN: sign after "E"
+ -- EXPONENT_1: first digit of the exponent.
+ -- EXPONENT: digits of the exponent.
+ type state_t is (leading, sign, digits, decimals,
+ exponent_sign, exponent_1, exponent);
+ variable cur_state : state_t := leading;
+
+ -- Set VALUE to the result, and set GOOD to TRUE.
+ procedure set_value is
+ begin
+ good := true;
+
+ if exp_neg then
+ val := val * 10.0 ** (-exp);
+ else
+ val := val * 10.0 ** exp;
+ end if;
+ if val_neg then
+ value := -val;
+ else
+ value := val;
+ end if;
+ end set_value;
+
+ begin
+ -- Initialization.
+ val_neg := false;
+ nbr_dec := 1;
+ exp := 0;
+ exp_neg := false;
+
+ -- By default, parsing has failed.
+ good := false;
+
+ -- Iterate over all characters of the string.
+ -- Return immediatly in case of parse error.
+ -- Trim L and call SET_VALUE and return in case of success.
+ for i in l'range loop
+ case cur_state is
+ when leading =>
+ case l(i) is
+ when ' '
+ | NBSP --V93
+ | ht =>
+ null;
+ when '+' =>
+ cur_state := sign;
+ when '-' =>
+ val_neg := true;
+ cur_state := sign;
+ when '0' to '9' =>
+ val := real (char_to_nat (l(i)));
+ cur_state := digits;
+ when others =>
+ return;
+ end case;
+ when sign =>
+ case l(i) is
+ when '0' to '9' =>
+ val := real (char_to_nat (l(i)));
+ cur_state := digits;
+ when others =>
+ return;
+ end case;
+ when digits =>
+ case l(i) is
+ when '0' to '9' =>
+ val := val * 10.0 + real (char_to_nat (l(i)));
+ when '.' =>
+ cur_state := decimals;
+ when others =>
+ -- A "." (dot) is required in the string.
+ return;
+ end case;
+ when decimals =>
+ case l(i) is
+ when '0' to '9' =>
+ val := val + real (char_to_nat (l(i))) / (10.0 ** nbr_dec);
+ nbr_dec := nbr_dec + 1;
+ when 'e' | 'E' =>
+ -- "nnn.E" is erroneous.
+ if nbr_dec = 1 then
+ return;
+ end if;
+ cur_state := exponent_sign;
+ when others =>
+ -- "nnn.XX" is erroneous.
+ if nbr_dec = 1 then
+ return;
+ end if;
+ trim (l, i);
+ set_value;
+ return;
+ end case;
+ when exponent_sign =>
+ case l(i) is
+ when '+' =>
+ cur_state := exponent_1;
+ when '-' =>
+ exp_neg := true;
+ cur_state := exponent_1;
+ when '0' to '9' =>
+ exp := char_to_nat (l(i));
+ cur_state := exponent;
+ when others =>
+ -- Error.
+ return;
+ end case;
+ when exponent_1 | exponent =>
+ case l(i) is
+ when '0' to '9' =>
+ exp := exp * 10 + char_to_nat (l(i));
+ cur_state := exponent;
+ when others =>
+ trim (l, i);
+ set_value;
+ return;
+ end case;
+ end case;
+ end loop;
+
+ -- End of string.
+ case cur_state is
+ when leading | sign | digits =>
+ -- Erroneous.
+ return;
+ when decimals =>
+ -- "nnn.XX" is erroneous.
+ if nbr_dec = 1 then
+ return;
+ end if;
+ when exponent_sign =>
+ -- Erroneous ("NNN.NNNE")
+ return;
+ when exponent_1 =>
+ -- "NNN.NNNE-"
+ return;
+ when exponent =>
+ null;
+ end case;
+
+ deallocate (l);
+ l := new string'("");
+ set_value;
+ end read;
+
+ procedure read (l: inout line; value: out real)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "real read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out time; good: out boolean)
+ is
+ -- The result.
+ variable res : time;
+
+ -- UNIT is computed from the unit name, the exponent and the number of
+ -- digits before the dot. UNIT is the weight of the current digit.
+ variable unit : time;
+
+ -- Number of digits before the dot.
+ variable nbr_digits : integer;
+
+ -- True if a unit name has been found. Used temporaly to know the status
+ -- at the end of the search loop.
+ variable unit_found : boolean;
+
+ -- True if the number is negative.
+ variable is_neg : boolean;
+
+ -- Value of the exponent.
+ variable exp : integer;
+
+ -- True if the exponent is negative.
+ variable exp_neg : boolean;
+
+ -- Unit name extracted from the string.
+ variable unit_name : string (1 to 3);
+
+ -- state is the kind of the previous character parsed.
+ -- LEADING: leading blanks
+ -- SIGN: + or - as the first character of the number.
+ -- DIGITS: digit of the integer part of the number.
+ -- DOT: dot (.) after the integer part and before the decimal part.
+ -- DECIMALS: digit of the decimal part.
+ -- EXPONENT_MARK: e or E.
+ -- EXPONENT_SIGN: + or - just after the exponent mark (E).
+ -- EXPONENT: digit of the exponent.
+ -- UNIT_BLANK: blank after the exponent.
+ -- UNIT_1, UNIT_2, UNIT_3: first, second, third character of the unit.
+ type state_type is (leading, sign, digits, dot, decimals,
+ exponent_mark, exponent_sign, exponent,
+ unit_blank, unit_1, unit_2, unit_3);
+ variable state : state_type;
+
+ -- Used during the second scan of the string, TRUE is digits is being
+ -- scaned.
+ variable has_digits : boolean;
+
+ -- Position at the end of the string.
+ variable pos : integer;
+
+ -- Used to compute POS.
+ variable length : integer;
+ begin
+ -- Initialization.
+ -- Fail by default; therefore, in case of error, a return statement is
+ -- ok.
+ good := false;
+
+ nbr_digits := 0;
+ is_neg := false;
+ exp := 0;
+ exp_neg := false;
+ res := 0 fs;
+
+ -- Look for exponent and unit name.
+ -- Parse the string: this loop checks the correctness of the format, and
+ -- must return (GOOD has been set to FALSE) in case of error.
+ -- Set: NBR_DIGITS, IS_NEG, EXP, EXP_NEG.
+ state := leading;
+ for i in l'range loop
+ case l (i) is
+ when ' '
+ | NBSP --V93
+ | HT =>
+ case state is
+ when leading | unit_blank =>
+ null;
+ when sign | dot | exponent_mark | exponent_sign =>
+ return;
+ when digits | decimals | exponent =>
+ state := unit_blank;
+ when unit_1 | unit_2 =>
+ exit;
+ when unit_3 =>
+ -- Cannot happen, since an exit is performed at unit_3.
+ assert false report "internal error" severity failure;
+ end case;
+ when '+' | '-' =>
+ case state is
+ when leading =>
+ if l(i) = '-' then
+ is_neg := true;
+ end if;
+ state := sign;
+ when exponent_mark =>
+ if l(i) = '-' then
+ exp_neg := true;
+ end if;
+ state := exponent_sign;
+ when others =>
+ return;
+ end case;
+ when '0' to '9' =>
+ case state is
+ when exponent_mark | exponent_sign | exponent =>
+ exp := exp * 10 + char_to_nat (l (i));
+ state := exponent;
+ when leading | sign | digits =>
+ -- Leading "0" are not significant.
+ if nbr_digits > 0 or l (i) /= '0' then
+ nbr_digits := nbr_digits + 1;
+ end if;
+ state := digits;
+ when decimals =>
+ null;
+ when dot =>
+ state := decimals;
+ when others =>
+ return;
+ end case;
+ when 'a' to 'z' | 'A' to 'Z' =>
+ case state is
+ when digits | decimals =>
+ -- "E" has exponent mark.
+ if l (i) = 'e' or l(i) = 'E' then
+ state := exponent_mark;
+ else
+ return;
+ end if;
+ when unit_blank =>
+ unit_name (1) := to_lower (l(i));
+ state := unit_1;
+ when unit_1 =>
+ unit_name (2) := to_lower (l(i));
+ state := unit_2;
+ pos := i;
+ when unit_2 =>
+ unit_name (3) := to_lower (l(i));
+ state := unit_3;
+ exit;
+ when others =>
+ return;
+ end case;
+ when '.' =>
+ case state is
+ when digits =>
+ state := decimals;
+ when others =>
+ return;
+ end case;
+ when others =>
+ return;
+ end case;
+ end loop;
+
+ -- A unit name (2 or 3 letters) must have been found.
+ -- The string may end anywhere.
+ if state /= unit_2 and state /= unit_3 then
+ return;
+ end if;
+
+ -- Compute EXP with the sign.
+ if exp_neg then
+ exp := -exp;
+ end if;
+
+ -- Search the unit name in the list of time names.
+ unit_found := false;
+ for i in time_names'range loop
+ -- The first two characters must match (case insensitive).
+ -- The third character must match if:
+ -- * the unit name is a three characters identifier (ie, not a blank).
+ -- * there is a third character in STR.
+ if time_names (i).name (1) = unit_name (1)
+ and time_names (i).name (2) = unit_name (2)
+ and (time_names (i).name (3) = ' '
+ or time_names (i).name (3) = unit_name (3))
+ then
+ unit := time_names (i).val;
+ unit_found := true;
+ -- POS is set to the position of the first invalid character.
+ if time_names (i).name (3) = ' ' then
+ length := 1;
+ else
+ length := 2;
+ end if;
+ if l'left < l'right then
+ pos := pos + length;
+ else
+ pos := pos - length;
+ end if;
+ exit;
+ end if;
+ end loop;
+ if not unit_found then
+ return;
+ end if;
+
+ -- Compute UNIT, the weight of the first non-significant character.
+ nbr_digits := nbr_digits + exp - 1;
+ if nbr_digits < 0 then
+ unit := unit / 10 ** (-nbr_digits);
+ else
+ unit := unit * 10 ** nbr_digits;
+ end if;
+
+ -- HAS_DIGITS will be set as soon as a digit is found.
+ -- No error is expected here (this has been checked during the first
+ -- pass).
+ has_digits := false;
+ for i in l'range loop
+ case l (i) is
+ when ' '
+ | NBSP --V93
+ | HT =>
+ if has_digits then
+ exit;
+ end if;
+ when '+' | '-' =>
+ if not has_digits then
+ has_digits := true;
+ else
+ assert false report "internal error" severity failure;
+ return;
+ end if;
+ when '0' to '9' =>
+ -- Leading "0" are not significant.
+ if l (i) /= '0' or res /= 0 fs then
+ res := res + char_to_nat (l (i)) * unit;
+ unit := unit / 10;
+ end if;
+ has_digits := true;
+ when 'a' to 'z' | 'A' to 'Z' =>
+ if has_digits then
+ exit;
+ else
+ assert false report "internal error" severity failure;
+ return;
+ end if;
+ when '.' =>
+ if not has_digits then
+ assert false report "internal error" severity failure;
+ return;
+ end if;
+ when others =>
+ assert false report "internal error" severity failure;
+ return;
+ end case;
+ end loop;
+
+ -- Set VALUE.
+ if is_neg then
+ value := -res;
+ else
+ value := res;
+ end if;
+ good := true;
+ trim (l, pos);
+ return;
+ end read;
+
+ procedure read (l: inout line; value: out time)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "time read failure"
+ severity failure;
+ end read;
+
+ procedure read (l: inout line; value: out string; good: out boolean)
+ is
+ constant len : natural := value'length;
+ begin
+ if l'length < len then
+ good := false;
+ return;
+ end if;
+ good := true;
+ if len = 0 then
+ return;
+ end if;
+ if l'left < l'right then
+ value := l (l'left to l'left + len - 1);
+ trim (l, l'left + len);
+ else
+ value := l (l'left downto l'left - len + 1);
+ trim (l, l'left - len);
+ end if;
+ end read;
+
+ procedure read (l: inout line; value: out string)
+ is
+ variable res : boolean;
+ begin
+ read (l, value, res);
+ assert res = true
+ report "string read failure"
+ severity failure;
+ end read;
+
+end textio;
diff --git a/libraries/synopsys/std_logic_arith.vhdl b/libraries/synopsys/std_logic_arith.vhdl
new file mode 100644
index 000000000..685b64732
--- /dev/null
+++ b/libraries/synopsys/std_logic_arith.vhdl
@@ -0,0 +1,2391 @@
+--------------------------------------------------------------------------
+-- --
+-- Copyright (c) 1990,1991,1992 by Synopsys, Inc. All rights reserved. --
+-- --
+-- This source file may be used and distributed without restriction --
+-- provided that this copyright statement is not removed from the file --
+-- and that any derivative work contains this copyright notice. --
+-- --
+-- Package name: STD_LOGIC_ARITH --
+-- --
+-- Purpose: --
+-- A set of arithemtic, conversion, and comparison functions --
+-- for SIGNED, UNSIGNED, SMALL_INT, INTEGER, --
+-- STD_ULOGIC, STD_LOGIC, and STD_LOGIC_VECTOR. --
+-- --
+--------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package std_logic_arith is
+
+ type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
+ type SIGNED is array (NATURAL range <>) of STD_LOGIC;
+ subtype SMALL_INT is INTEGER range 0 to 1;
+
+ function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
+ function "+"(L: SIGNED; R: SIGNED) return SIGNED;
+ function "+"(L: UNSIGNED; R: SIGNED) return SIGNED;
+ function "+"(L: SIGNED; R: UNSIGNED) return SIGNED;
+ function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED;
+ function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED;
+ function "+"(L: SIGNED; R: INTEGER) return SIGNED;
+ function "+"(L: INTEGER; R: SIGNED) return SIGNED;
+ function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED;
+ function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED;
+ function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED;
+ function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED;
+
+ function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR;
+
+ function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
+ function "-"(L: SIGNED; R: SIGNED) return SIGNED;
+ function "-"(L: UNSIGNED; R: SIGNED) return SIGNED;
+ function "-"(L: SIGNED; R: UNSIGNED) return SIGNED;
+ function "-"(L: UNSIGNED; R: INTEGER) return UNSIGNED;
+ function "-"(L: INTEGER; R: UNSIGNED) return UNSIGNED;
+ function "-"(L: SIGNED; R: INTEGER) return SIGNED;
+ function "-"(L: INTEGER; R: SIGNED) return SIGNED;
+ function "-"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED;
+ function "-"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED;
+ function "-"(L: SIGNED; R: STD_ULOGIC) return SIGNED;
+ function "-"(L: STD_ULOGIC; R: SIGNED) return SIGNED;
+
+ function "-"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "-"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "-"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR;
+
+ function "+"(L: UNSIGNED) return UNSIGNED;
+ function "+"(L: SIGNED) return SIGNED;
+ function "-"(L: SIGNED) return SIGNED;
+ function "ABS"(L: SIGNED) return SIGNED;
+
+ function "+"(L: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "+"(L: SIGNED) return STD_LOGIC_VECTOR;
+ function "-"(L: SIGNED) return STD_LOGIC_VECTOR;
+ function "ABS"(L: SIGNED) return STD_LOGIC_VECTOR;
+
+ function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
+ function "*"(L: SIGNED; R: SIGNED) return SIGNED;
+ function "*"(L: SIGNED; R: UNSIGNED) return SIGNED;
+ function "*"(L: UNSIGNED; R: SIGNED) return SIGNED;
+
+ function "*"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "*"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+ function "*"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
+ function "*"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
+
+ function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function "<"(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function "<"(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function "<"(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function "<"(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function "<"(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function "<"(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function "<"(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function "<="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function "<="(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function "<="(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function "<="(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function "<="(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function "<="(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function "<="(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function "<="(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function ">"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function ">"(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function ">"(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function ">"(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function ">"(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function ">"(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function ">"(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function ">"(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function ">="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function ">="(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function ">="(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function ">="(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function ">="(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function ">="(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function ">="(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function ">="(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function "="(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function "="(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function "="(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function "="(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function "="(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function "="(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function "="(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function "/="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
+ function "/="(L: SIGNED; R: SIGNED) return BOOLEAN;
+ function "/="(L: UNSIGNED; R: SIGNED) return BOOLEAN;
+ function "/="(L: SIGNED; R: UNSIGNED) return BOOLEAN;
+ function "/="(L: UNSIGNED; R: INTEGER) return BOOLEAN;
+ function "/="(L: INTEGER; R: UNSIGNED) return BOOLEAN;
+ function "/="(L: SIGNED; R: INTEGER) return BOOLEAN;
+ function "/="(L: INTEGER; R: SIGNED) return BOOLEAN;
+
+ function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED;
+ function SHL(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED;
+ function SHR(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED;
+ function SHR(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED;
+
+ function CONV_INTEGER(ARG: INTEGER) return INTEGER;
+ function CONV_INTEGER(ARG: UNSIGNED) return INTEGER;
+ function CONV_INTEGER(ARG: SIGNED) return INTEGER;
+ function CONV_INTEGER(ARG: STD_ULOGIC) return SMALL_INT;
+
+ function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED;
+ function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED;
+ function CONV_UNSIGNED(ARG: SIGNED; SIZE: INTEGER) return UNSIGNED;
+ function CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED;
+
+ function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED;
+ function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) return SIGNED;
+ function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED;
+ function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return SIGNED;
+
+ function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER)
+ return STD_LOGIC_VECTOR;
+ function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; SIZE: INTEGER)
+ return STD_LOGIC_VECTOR;
+ function CONV_STD_LOGIC_VECTOR(ARG: SIGNED; SIZE: INTEGER)
+ return STD_LOGIC_VECTOR;
+ function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER)
+ return STD_LOGIC_VECTOR;
+ -- zero extend STD_LOGIC_VECTOR (ARG) to SIZE,
+ -- SIZE < 0 is same as SIZE = 0
+ -- returns STD_LOGIC_VECTOR(SIZE-1 downto 0)
+ function EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR;
+
+ -- sign extend STD_LOGIC_VECTOR (ARG) to SIZE,
+ -- SIZE < 0 is same as SIZE = 0
+ -- return STD_LOGIC_VECTOR(SIZE-1 downto 0)
+ function SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR;
+
+end Std_logic_arith;
+
+
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package body std_logic_arith is
+
+ function max(L, R: INTEGER) return INTEGER is
+ begin
+ if L > R then
+ return L;
+ else
+ return R;
+ end if;
+ end;
+
+
+ function min(L, R: INTEGER) return INTEGER is
+ begin
+ if L < R then
+ return L;
+ else
+ return R;
+ end if;
+ end;
+
+ -- synopsys synthesis_off
+ type tbl_type is array (STD_ULOGIC) of STD_ULOGIC;
+ constant tbl_BINARY : tbl_type :=
+ ('X', 'X', '0', '1', 'X', 'X', '0', '1', 'X');
+ -- synopsys synthesis_on
+
+ -- synopsys synthesis_off
+ type tbl_mvl9_boolean is array (STD_ULOGIC) of boolean;
+ constant IS_X : tbl_mvl9_boolean :=
+ (true, true, false, false, true, true, false, false, true);
+ -- synopsys synthesis_on
+
+
+
+ function MAKE_BINARY(A : STD_ULOGIC) return STD_ULOGIC is
+ -- synopsys built_in SYN_FEED_THRU
+ begin
+ -- synopsys synthesis_off
+ if (IS_X(A)) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ return ('X');
+ end if;
+ return tbl_BINARY(A);
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : UNSIGNED) return UNSIGNED is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : UNSIGNED (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : UNSIGNED) return SIGNED is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : SIGNED (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : SIGNED) return UNSIGNED is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : UNSIGNED (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : SIGNED) return SIGNED is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : SIGNED (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : STD_LOGIC_VECTOR (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : UNSIGNED) return STD_LOGIC_VECTOR is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : STD_LOGIC_VECTOR (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function MAKE_BINARY(A : SIGNED) return STD_LOGIC_VECTOR is
+ -- synopsys built_in SYN_FEED_THRU
+ variable one_bit : STD_ULOGIC;
+ variable result : STD_LOGIC_VECTOR (A'range);
+ begin
+ -- synopsys synthesis_off
+ for i in A'range loop
+ if (IS_X(A(i))) then
+ assert false
+ report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
+ severity warning;
+ result := (others => 'X');
+ return result;
+ end if;
+ result(i) := tbl_BINARY(A(i));
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+
+ -- Type propagation function which returns a signed type with the
+ -- size of the left arg.
+ function LEFT_SIGNED_ARG(A,B: SIGNED) return SIGNED is
+ variable Z: SIGNED (A'left downto 0);
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+ -- Type propagation function which returns an unsigned type with the
+ -- size of the left arg.
+ function LEFT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is
+ variable Z: UNSIGNED (A'left downto 0);
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+ -- Type propagation function which returns a signed type with the
+ -- size of the result of a signed multiplication
+ function MULT_SIGNED_ARG(A,B: SIGNED) return SIGNED is
+ variable Z: SIGNED ((A'length+B'length-1) downto 0);
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+ -- Type propagation function which returns an unsigned type with the
+ -- size of the result of a unsigned multiplication
+ function MULT_UNSIGNED_ARG(A,B: UNSIGNED) return UNSIGNED is
+ variable Z: UNSIGNED ((A'length+B'length-1) downto 0);
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+
+
+ function mult(A,B: SIGNED) return SIGNED is
+
+ variable BA: SIGNED((A'length+B'length-1) downto 0);
+ variable PA: SIGNED((A'length+B'length-1) downto 0);
+ variable AA: SIGNED(A'length downto 0);
+ variable neg: STD_ULOGIC;
+ constant one : UNSIGNED(1 downto 0) := "01";
+
+ -- pragma map_to_operator MULT_TC_OP
+ -- pragma type_function MULT_SIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ PA := (others => 'X');
+ return(PA);
+ end if;
+ PA := (others => '0');
+ neg := B(B'left) xor A(A'left);
+ BA := CONV_SIGNED(('0' & ABS(B)),(A'length+B'length));
+ AA := '0' & ABS(A);
+ for i in integer range 0 to A'length-1 loop
+ if AA(i) = '1' then
+ PA := PA+BA;
+ end if;
+ BA := SHL(BA,one);
+ end loop;
+ if (neg= '1') then
+ return(-PA);
+ else
+ return(PA);
+ end if;
+ end;
+
+ function mult(A,B: UNSIGNED) return UNSIGNED is
+
+ variable BA: UNSIGNED((A'length+B'length-1) downto 0);
+ variable PA: UNSIGNED((A'length+B'length-1) downto 0);
+ constant one : UNSIGNED(1 downto 0) := "01";
+
+ -- pragma map_to_operator MULT_UNS_OP
+ -- pragma type_function MULT_UNSIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ PA := (others => 'X');
+ return(PA);
+ end if;
+ PA := (others => '0');
+ BA := CONV_UNSIGNED(B,(A'length+B'length));
+ for i in integer range 0 to A'length-1 loop
+ if A(i) = '1' then
+ PA := PA+BA;
+ end if;
+ BA := SHL(BA,one);
+ end loop;
+ return(PA);
+ end;
+
+ -- subtract two signed numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function minus(A, B: SIGNED) return SIGNED is
+ variable carry: STD_ULOGIC;
+ variable BV: STD_ULOGIC_VECTOR (A'left downto 0);
+ variable sum: SIGNED (A'left downto 0);
+
+ -- pragma map_to_operator SUB_TC_OP
+
+ -- pragma type_function LEFT_SIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ sum := (others => 'X');
+ return(sum);
+ end if;
+ carry := '1';
+ BV := not STD_ULOGIC_VECTOR(B);
+
+ for i in 0 to A'left loop
+ sum(i) := A(i) xor BV(i) xor carry;
+ carry := (A(i) and BV(i)) or
+ (A(i) and carry) or
+ (carry and BV(i));
+ end loop;
+ return sum;
+ end;
+
+ -- add two signed numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function plus(A, B: SIGNED) return SIGNED is
+ variable carry: STD_ULOGIC;
+ variable BV, sum: SIGNED (A'left downto 0);
+
+ -- pragma map_to_operator ADD_TC_OP
+ -- pragma type_function LEFT_SIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ sum := (others => 'X');
+ return(sum);
+ end if;
+ carry := '0';
+ BV := B;
+
+ for i in 0 to A'left loop
+ sum(i) := A(i) xor BV(i) xor carry;
+ carry := (A(i) and BV(i)) or
+ (A(i) and carry) or
+ (carry and BV(i));
+ end loop;
+ return sum;
+ end;
+
+
+ -- subtract two unsigned numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function unsigned_minus(A, B: UNSIGNED) return UNSIGNED is
+ variable carry: STD_ULOGIC;
+ variable BV: STD_ULOGIC_VECTOR (A'left downto 0);
+ variable sum: UNSIGNED (A'left downto 0);
+
+ -- pragma map_to_operator SUB_UNS_OP
+ -- pragma type_function LEFT_UNSIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ sum := (others => 'X');
+ return(sum);
+ end if;
+ carry := '1';
+ BV := not STD_ULOGIC_VECTOR(B);
+
+ for i in 0 to A'left loop
+ sum(i) := A(i) xor BV(i) xor carry;
+ carry := (A(i) and BV(i)) or
+ (A(i) and carry) or
+ (carry and BV(i));
+ end loop;
+ return sum;
+ end;
+
+ -- add two unsigned numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function unsigned_plus(A, B: UNSIGNED) return UNSIGNED is
+ variable carry: STD_ULOGIC;
+ variable BV, sum: UNSIGNED (A'left downto 0);
+
+ -- pragma map_to_operator ADD_UNS_OP
+ -- pragma type_function LEFT_UNSIGNED_ARG
+ -- pragma return_port_name Z
+
+ begin
+ if (A(A'left) = 'X' or B(B'left) = 'X') then
+ sum := (others => 'X');
+ return(sum);
+ end if;
+ carry := '0';
+ BV := B;
+
+ for i in 0 to A'left loop
+ sum(i) := A(i) xor BV(i) xor carry;
+ carry := (A(i) and BV(i)) or
+ (A(i) and carry) or
+ (carry and BV(i));
+ end loop;
+ return sum;
+ end;
+
+
+
+ function "*"(L: SIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 296
+ begin
+ return mult(CONV_SIGNED(L, L'length),
+ CONV_SIGNED(R, R'length)); -- pragma label mult
+ end;
+
+ function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 295
+ begin
+ return mult(CONV_UNSIGNED(L, L'length),
+ CONV_UNSIGNED(R, R'length)); -- pragma label mult
+ end;
+
+ function "*"(L: UNSIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 297
+ begin
+ return mult(CONV_SIGNED(L, L'length+1),
+ CONV_SIGNED(R, R'length)); -- pragma label mult
+ end;
+
+ function "*"(L: SIGNED; R: UNSIGNED) return SIGNED is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 298
+ begin
+ return mult(CONV_SIGNED(L, L'length),
+ CONV_SIGNED(R, R'length+1)); -- pragma label mult
+ end;
+
+
+ function "*"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 301
+ begin
+ return STD_LOGIC_VECTOR (
+ mult(-- pragma label mult
+ CONV_SIGNED(L, L'length), CONV_SIGNED(R, R'length)));
+ end;
+
+ function "*"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 300
+ begin
+ return STD_LOGIC_VECTOR (
+ mult(-- pragma label mult
+ CONV_UNSIGNED(L, L'length), CONV_UNSIGNED(R, R'length)));
+ end;
+
+ function "*"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 302
+ begin
+ return STD_LOGIC_VECTOR (
+ mult(-- pragma label mult
+ CONV_SIGNED(L, L'length+1), CONV_SIGNED(R, R'length)));
+ end;
+
+ function "*"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ -- synopsys subpgm_id 303
+ begin
+ return STD_LOGIC_VECTOR (
+ mult(-- pragma label mult
+ CONV_SIGNED(L, L'length), CONV_SIGNED(R, R'length+1)));
+ end;
+
+
+ function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 236
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_plus(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: SIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 237
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: UNSIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 238
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: SIGNED; R: UNSIGNED) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 239
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 240
+ constant length: INTEGER := L'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ plus( -- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 241
+ constant length: INTEGER := R'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ plus( -- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "+"(L: SIGNED; R: INTEGER) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 242
+ constant length: INTEGER := L'length;
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: INTEGER; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 243
+ constant length: INTEGER := R'length;
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 244
+ constant length: INTEGER := L'length;
+ begin
+ return unsigned_plus(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)) ; -- pragma label plus
+ end;
+
+
+ function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 245
+ constant length: INTEGER := R'length;
+ begin
+ return unsigned_plus(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 246
+ constant length: INTEGER := L'length;
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+ function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 247
+ constant length: INTEGER := R'length;
+ begin
+ return plus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label plus
+ end;
+
+
+
+ function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 260
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ unsigned_plus(-- pragma label plus
+ CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)));
+ end;
+
+
+ function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 261
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 262
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 263
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 264
+ constant length: INTEGER := L'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ plus( -- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 265
+ constant length: INTEGER := R'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ plus( -- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 266
+ constant length: INTEGER := L'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 267
+ constant length: INTEGER := R'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 268
+ constant length: INTEGER := L'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ unsigned_plus(-- pragma label plus
+ CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length))) ;
+ end;
+
+
+ function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 269
+ constant length: INTEGER := R'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ unsigned_plus(-- pragma label plus
+ CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)));
+ end;
+
+
+ function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 270
+ constant length: INTEGER := L'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ -- synopsys subpgm_id 271
+ constant length: INTEGER := R'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ plus(-- pragma label plus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+
+ function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 248
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_minus(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: SIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 249
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: UNSIGNED; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 250
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: SIGNED; R: UNSIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 251
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: UNSIGNED; R: INTEGER) return UNSIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 252
+ constant length: INTEGER := L'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "-"(L: INTEGER; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 253
+ constant length: INTEGER := R'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "-"(L: SIGNED; R: INTEGER) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 254
+ constant length: INTEGER := L'length;
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: INTEGER; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 255
+ constant length: INTEGER := R'length;
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 256
+ constant length: INTEGER := L'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "-"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 257
+ constant length: INTEGER := R'length + 1;
+ begin
+ return CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1);
+ end;
+
+
+ function "-"(L: SIGNED; R: STD_ULOGIC) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 258
+ constant length: INTEGER := L'length;
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+ function "-"(L: STD_ULOGIC; R: SIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 259
+ constant length: INTEGER := R'length;
+ begin
+ return minus(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label minus
+ end;
+
+
+
+
+ function "-"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 272
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ unsigned_minus(-- pragma label minus
+ CONV_UNSIGNED(L, length), CONV_UNSIGNED(R, length)));
+ end;
+
+
+ function "-"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 273
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 274
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 275
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 276
+ constant length: INTEGER := L'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "-"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 277
+ constant length: INTEGER := R'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "-"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 278
+ constant length: INTEGER := L'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 279
+ constant length: INTEGER := R'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 280
+ constant length: INTEGER := L'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "-"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 281
+ constant length: INTEGER := R'length + 1;
+ begin
+ return STD_LOGIC_VECTOR (CONV_UNSIGNED(
+ minus( -- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)), length-1));
+ end;
+
+
+ function "-"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 282
+ constant length: INTEGER := L'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+ function "-"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 283
+ constant length: INTEGER := R'length;
+ begin
+ return STD_LOGIC_VECTOR (
+ minus(-- pragma label minus
+ CONV_SIGNED(L, length), CONV_SIGNED(R, length)));
+ end;
+
+
+
+
+ function "+"(L: UNSIGNED) return UNSIGNED is
+ -- synopsys subpgm_id 284
+ begin
+ return L;
+ end;
+
+
+ function "+"(L: SIGNED) return SIGNED is
+ -- synopsys subpgm_id 285
+ begin
+ return L;
+ end;
+
+
+ function "-"(L: SIGNED) return SIGNED is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 286
+ begin
+ return 0 - L; -- pragma label minus
+ end;
+
+
+ function "ABS"(L: SIGNED) return SIGNED is
+ -- synopsys subpgm_id 287
+ begin
+ if (L(L'left) = '0' or L(L'left) = 'L') then
+ return L;
+ else
+ return 0 - L;
+ end if;
+ end;
+
+
+ function "+"(L: UNSIGNED) return STD_LOGIC_VECTOR is
+ -- synopsys subpgm_id 289
+ begin
+ return STD_LOGIC_VECTOR (L);
+ end;
+
+
+ function "+"(L: SIGNED) return STD_LOGIC_VECTOR is
+ -- synopsys subpgm_id 290
+ begin
+ return STD_LOGIC_VECTOR (L);
+ end;
+
+
+ function "-"(L: SIGNED) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ -- synopsys subpgm_id 292
+ variable tmp: SIGNED(L'length-1 downto 0);
+ begin
+ tmp := 0 - L; -- pragma label minus
+ return STD_LOGIC_VECTOR (tmp);
+ end;
+
+
+ function "ABS"(L: SIGNED) return STD_LOGIC_VECTOR is
+ -- synopsys subpgm_id 294
+ variable tmp: SIGNED(L'length-1 downto 0);
+ begin
+ if (L(L'left) = '0' or L(L'left) = 'L') then
+ return STD_LOGIC_VECTOR (L);
+ else
+ tmp := 0 - L;
+ return STD_LOGIC_VECTOR (tmp);
+ end if;
+ end;
+
+
+ -- Type propagation function which returns the type BOOLEAN
+ function UNSIGNED_RETURN_BOOLEAN(A,B: UNSIGNED) return BOOLEAN is
+ variable Z: BOOLEAN;
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+ -- Type propagation function which returns the type BOOLEAN
+ function SIGNED_RETURN_BOOLEAN(A,B: SIGNED) return BOOLEAN is
+ variable Z: BOOLEAN;
+ -- pragma return_port_name Z
+ begin
+ return(Z);
+ end;
+
+
+ -- compare two signed numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function is_less(A, B: SIGNED) return BOOLEAN is
+ constant sign: INTEGER := A'left;
+ variable a_is_0, b_is_1, result : boolean;
+
+ -- pragma map_to_operator LT_TC_OP
+ -- pragma type_function SIGNED_RETURN_BOOLEAN
+ -- pragma return_port_name Z
+
+ begin
+ if A(sign) /= B(sign) then
+ result := A(sign) = '1';
+ else
+ result := FALSE;
+ for i in 0 to sign-1 loop
+ a_is_0 := A(i) = '0';
+ b_is_1 := B(i) = '1';
+ result := (a_is_0 and b_is_1) or
+ (a_is_0 and result) or
+ (b_is_1 and result);
+ end loop;
+ end if;
+ return result;
+ end;
+
+
+ -- compare two signed numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function is_less_or_equal(A, B: SIGNED) return BOOLEAN is
+ constant sign: INTEGER := A'left;
+ variable a_is_0, b_is_1, result : boolean;
+
+ -- pragma map_to_operator LEQ_TC_OP
+ -- pragma type_function SIGNED_RETURN_BOOLEAN
+ -- pragma return_port_name Z
+
+ begin
+ if A(sign) /= B(sign) then
+ result := A(sign) = '1';
+ else
+ result := TRUE;
+ for i in 0 to sign-1 loop
+ a_is_0 := A(i) = '0';
+ b_is_1 := B(i) = '1';
+ result := (a_is_0 and b_is_1) or
+ (a_is_0 and result) or
+ (b_is_1 and result);
+ end loop;
+ end if;
+ return result;
+ end;
+
+
+
+ -- compare two unsigned numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function unsigned_is_less(A, B: UNSIGNED) return BOOLEAN is
+ constant sign: INTEGER := A'left;
+ variable a_is_0, b_is_1, result : boolean;
+
+ -- pragma map_to_operator LT_UNS_OP
+ -- pragma type_function UNSIGNED_RETURN_BOOLEAN
+ -- pragma return_port_name Z
+
+ begin
+ result := FALSE;
+ for i in 0 to sign loop
+ a_is_0 := A(i) = '0';
+ b_is_1 := B(i) = '1';
+ result := (a_is_0 and b_is_1) or
+ (a_is_0 and result) or
+ (b_is_1 and result);
+ end loop;
+ return result;
+ end;
+
+
+ -- compare two unsigned numbers of the same length
+ -- both arrays must have range (msb downto 0)
+ function unsigned_is_less_or_equal(A, B: UNSIGNED) return BOOLEAN is
+ constant sign: INTEGER := A'left;
+ variable a_is_0, b_is_1, result : boolean;
+
+ -- pragma map_to_operator LEQ_UNS_OP
+ -- pragma type_function UNSIGNED_RETURN_BOOLEAN
+ -- pragma return_port_name Z
+
+ begin
+ result := TRUE;
+ for i in 0 to sign loop
+ a_is_0 := A(i) = '0';
+ b_is_1 := B(i) = '1';
+ result := (a_is_0 and b_is_1) or
+ (a_is_0 and result) or
+ (b_is_1 and result);
+ end loop;
+ return result;
+ end;
+
+
+
+
+ function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 305
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_is_less(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 306
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 307
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 308
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 309
+ constant length: INTEGER := L'length + 1;
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 310
+ constant length: INTEGER := R'length + 1;
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 311
+ constant length: INTEGER := L'length;
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+ function "<"(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to lt
+ -- synopsys subpgm_id 312
+ constant length: INTEGER := R'length;
+ begin
+ return is_less(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label lt
+ end;
+
+
+
+
+ function "<="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 314
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_is_less_or_equal(CONV_UNSIGNED(L, length),
+ CONV_UNSIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 315
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 316
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 317
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 318
+ constant length: INTEGER := L'length + 1;
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 319
+ constant length: INTEGER := R'length + 1;
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 320
+ constant length: INTEGER := L'length;
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+ function "<="(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to leq
+ -- synopsys subpgm_id 321
+ constant length: INTEGER := R'length;
+ begin
+ return is_less_or_equal(CONV_SIGNED(L, length),
+ CONV_SIGNED(R, length)); -- pragma label leq
+ end;
+
+
+
+
+ function ">"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 323
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_is_less(CONV_UNSIGNED(R, length),
+ CONV_UNSIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 324
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 325
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 326
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 327
+ constant length: INTEGER := L'length + 1;
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 328
+ constant length: INTEGER := R'length + 1;
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 329
+ constant length: INTEGER := L'length;
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+ function ">"(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to gt
+ -- synopsys subpgm_id 330
+ constant length: INTEGER := R'length;
+ begin
+ return is_less(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label gt
+ end;
+
+
+
+
+ function ">="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 332
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return unsigned_is_less_or_equal(CONV_UNSIGNED(R, length),
+ CONV_UNSIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 333
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 334
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 335
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 336
+ constant length: INTEGER := L'length + 1;
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 337
+ constant length: INTEGER := R'length + 1;
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 338
+ constant length: INTEGER := L'length;
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+ function ">="(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- pragma label_applies_to geq
+ -- synopsys subpgm_id 339
+ constant length: INTEGER := R'length;
+ begin
+ return is_less_or_equal(CONV_SIGNED(R, length),
+ CONV_SIGNED(L, length)); -- pragma label geq
+ end;
+
+
+
+
+ -- for internal use only. Assumes SIGNED arguments of equal length.
+ function bitwise_eql(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR)
+ return BOOLEAN is
+ -- pragma built_in SYN_EQL
+ begin
+ for i in L'range loop
+ if L(i) /= R(i) then
+ return FALSE;
+ end if;
+ end loop;
+ return TRUE;
+ end;
+
+ -- for internal use only. Assumes SIGNED arguments of equal length.
+ function bitwise_neq(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR)
+ return BOOLEAN is
+ -- pragma built_in SYN_NEQ
+ begin
+ for i in L'range loop
+ if L(i) /= R(i) then
+ return TRUE;
+ end if;
+ end loop;
+ return FALSE;
+ end;
+
+
+ function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 341
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 342
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 343
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 344
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- synopsys subpgm_id 345
+ constant length: INTEGER := L'length + 1;
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 346
+ constant length: INTEGER := R'length + 1;
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- synopsys subpgm_id 347
+ constant length: INTEGER := L'length;
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "="(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 348
+ constant length: INTEGER := R'length;
+ begin
+ return bitwise_eql( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+
+
+ function "/="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 350
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: SIGNED; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 351
+ constant length: INTEGER := max(L'length, R'length);
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: UNSIGNED; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 352
+ constant length: INTEGER := max(L'length + 1, R'length);
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: SIGNED; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 353
+ constant length: INTEGER := max(L'length, R'length + 1);
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: UNSIGNED; R: INTEGER) return BOOLEAN is
+ -- synopsys subpgm_id 354
+ constant length: INTEGER := L'length + 1;
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: INTEGER; R: UNSIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 355
+ constant length: INTEGER := R'length + 1;
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: SIGNED; R: INTEGER) return BOOLEAN is
+ -- synopsys subpgm_id 356
+ constant length: INTEGER := L'length;
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+ function "/="(L: INTEGER; R: SIGNED) return BOOLEAN is
+ -- synopsys subpgm_id 357
+ constant length: INTEGER := R'length;
+ begin
+ return bitwise_neq( STD_ULOGIC_VECTOR( CONV_SIGNED(L, length) ),
+ STD_ULOGIC_VECTOR( CONV_SIGNED(R, length) ) );
+ end;
+
+
+
+ function SHL(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is
+ -- synopsys subpgm_id 358
+ constant control_msb: INTEGER := COUNT'length - 1;
+ variable control: UNSIGNED (control_msb downto 0);
+ constant result_msb: INTEGER := ARG'length-1;
+ subtype rtype is UNSIGNED (result_msb downto 0);
+ variable result, temp: rtype;
+ begin
+ control := MAKE_BINARY(COUNT);
+ -- synopsys synthesis_off
+ if (control(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ -- synopsys synthesis_on
+ result := ARG;
+ for i in 0 to control_msb loop
+ if control(i) = '1' then
+ temp := rtype'(others => '0');
+ if 2**i <= result_msb then
+ temp(result_msb downto 2**i) :=
+ result(result_msb - 2**i downto 0);
+ end if;
+ result := temp;
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function SHL(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is
+ -- synopsys subpgm_id 359
+ constant control_msb: INTEGER := COUNT'length - 1;
+ variable control: UNSIGNED (control_msb downto 0);
+ constant result_msb: INTEGER := ARG'length-1;
+ subtype rtype is SIGNED (result_msb downto 0);
+ variable result, temp: rtype;
+ begin
+ control := MAKE_BINARY(COUNT);
+ -- synopsys synthesis_off
+ if (control(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ -- synopsys synthesis_on
+ result := ARG;
+ for i in 0 to control_msb loop
+ if control(i) = '1' then
+ temp := rtype'(others => '0');
+ if 2**i <= result_msb then
+ temp(result_msb downto 2**i) :=
+ result(result_msb - 2**i downto 0);
+ end if;
+ result := temp;
+ end if;
+ end loop;
+ return result;
+ end;
+
+
+ function SHR(ARG: UNSIGNED; COUNT: UNSIGNED) return UNSIGNED is
+ -- synopsys subpgm_id 360
+ constant control_msb: INTEGER := COUNT'length - 1;
+ variable control: UNSIGNED (control_msb downto 0);
+ constant result_msb: INTEGER := ARG'length-1;
+ subtype rtype is UNSIGNED (result_msb downto 0);
+ variable result, temp: rtype;
+ begin
+ control := MAKE_BINARY(COUNT);
+ -- synopsys synthesis_off
+ if (control(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ -- synopsys synthesis_on
+ result := ARG;
+ for i in 0 to control_msb loop
+ if control(i) = '1' then
+ temp := rtype'(others => '0');
+ if 2**i <= result_msb then
+ temp(result_msb - 2**i downto 0) :=
+ result(result_msb downto 2**i);
+ end if;
+ result := temp;
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function SHR(ARG: SIGNED; COUNT: UNSIGNED) return SIGNED is
+ -- synopsys subpgm_id 361
+ constant control_msb: INTEGER := COUNT'length - 1;
+ variable control: UNSIGNED (control_msb downto 0);
+ constant result_msb: INTEGER := ARG'length-1;
+ subtype rtype is SIGNED (result_msb downto 0);
+ variable result, temp: rtype;
+ variable sign_bit: STD_ULOGIC;
+ begin
+ control := MAKE_BINARY(COUNT);
+ -- synopsys synthesis_off
+ if (control(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ -- synopsys synthesis_on
+ result := ARG;
+ sign_bit := ARG(ARG'left);
+ for i in 0 to control_msb loop
+ if control(i) = '1' then
+ temp := rtype'(others => sign_bit);
+ if 2**i <= result_msb then
+ temp(result_msb - 2**i downto 0) :=
+ result(result_msb downto 2**i);
+ end if;
+ result := temp;
+ end if;
+ end loop;
+ return result;
+ end;
+
+
+
+
+ function CONV_INTEGER(ARG: INTEGER) return INTEGER is
+ -- synopsys subpgm_id 365
+ begin
+ return ARG;
+ end;
+
+ function CONV_INTEGER(ARG: UNSIGNED) return INTEGER is
+ variable result: INTEGER;
+ variable tmp: STD_ULOGIC;
+ -- synopsys built_in SYN_UNSIGNED_TO_INTEGER
+ -- synopsys subpgm_id 366
+ begin
+ -- synopsys synthesis_off
+ assert ARG'length <= 31
+ report "ARG is too large in CONV_INTEGER"
+ severity FAILURE;
+ result := 0;
+ for i in ARG'range loop
+ result := result * 2;
+ tmp := tbl_BINARY(ARG(i));
+ if tmp = '1' then
+ result := result + 1;
+ elsif tmp = 'X' then
+ assert false
+ report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0."
+ severity WARNING;
+ end if;
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_INTEGER(ARG: SIGNED) return INTEGER is
+ variable result: INTEGER;
+ variable tmp: STD_ULOGIC;
+ -- synopsys built_in SYN_SIGNED_TO_INTEGER
+ -- synopsys subpgm_id 367
+ begin
+ -- synopsys synthesis_off
+ assert ARG'length <= 32
+ report "ARG is too large in CONV_INTEGER"
+ severity FAILURE;
+ result := 0;
+ for i in ARG'range loop
+ if i /= ARG'left then
+ result := result * 2;
+ tmp := tbl_BINARY(ARG(i));
+ if tmp = '1' then
+ result := result + 1;
+ elsif tmp = 'X' then
+ assert false
+ report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0."
+ severity WARNING;
+ end if;
+ end if;
+ end loop;
+ tmp := MAKE_BINARY(ARG(ARG'left));
+ if tmp = '1' then
+ if ARG'length = 32 then
+ result := (result - 2**30) - 2**30;
+ else
+ result := result - (2 ** (ARG'length-1));
+ end if;
+ end if;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_INTEGER(ARG: STD_ULOGIC) return SMALL_INT is
+ variable tmp: STD_ULOGIC;
+ -- synopsys built_in SYN_FEED_THRU
+ -- synopsys subpgm_id 370
+ begin
+ -- synopsys synthesis_off
+ tmp := tbl_BINARY(ARG);
+ if tmp = '1' then
+ return 1;
+ elsif tmp = 'X' then
+ assert false
+ report "CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0."
+ severity WARNING;
+ return 0;
+ else
+ return 0;
+ end if;
+ -- synopsys synthesis_on
+ end;
+
+
+ -- convert an integer to a unsigned STD_ULOGIC_VECTOR
+ function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED is
+ variable result: UNSIGNED(SIZE-1 downto 0);
+ variable temp: integer;
+ -- synopsys built_in SYN_INTEGER_TO_UNSIGNED
+ -- synopsys subpgm_id 371
+ begin
+ -- synopsys synthesis_off
+ temp := ARG;
+ for i in 0 to SIZE-1 loop
+ if (temp mod 2) = 1 then
+ result(i) := '1';
+ else
+ result(i) := '0';
+ end if;
+ if temp > 0 then
+ temp := temp / 2;
+ else
+ temp := (temp - 1) / 2; -- simulate ASR
+ end if;
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is UNSIGNED (SIZE-1 downto 0);
+ variable new_bounds: UNSIGNED (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 372
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => '0');
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_UNSIGNED(ARG: SIGNED; SIZE: INTEGER) return UNSIGNED is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is UNSIGNED (SIZE-1 downto 0);
+ variable new_bounds: UNSIGNED (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_SIGN_EXTEND
+ -- synopsys subpgm_id 373
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => new_bounds(new_bounds'left));
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED is
+ subtype rtype is UNSIGNED (SIZE-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 375
+ begin
+ -- synopsys synthesis_off
+ result := rtype'(others => '0');
+ result(0) := MAKE_BINARY(ARG);
+ if (result(0) = 'X') then
+ result := rtype'(others => 'X');
+ end if;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ -- convert an integer to a 2's complement STD_ULOGIC_VECTOR
+ function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED is
+ variable result: SIGNED (SIZE-1 downto 0);
+ variable temp: integer;
+ -- synopsys built_in SYN_INTEGER_TO_SIGNED
+ -- synopsys subpgm_id 376
+ begin
+ -- synopsys synthesis_off
+ temp := ARG;
+ for i in 0 to SIZE-1 loop
+ if (temp mod 2) = 1 then
+ result(i) := '1';
+ else
+ result(i) := '0';
+ end if;
+ if temp > 0 then
+ temp := temp / 2;
+ elsif (temp > integer'low) then
+ temp := (temp - 1) / 2; -- simulate ASR
+ else
+ temp := temp / 2; -- simulate ASR
+ end if;
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) return SIGNED is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is SIGNED (SIZE-1 downto 0);
+ variable new_bounds : SIGNED (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 377
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => '0');
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is SIGNED (SIZE-1 downto 0);
+ variable new_bounds : SIGNED (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_SIGN_EXTEND
+ -- synopsys subpgm_id 378
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => new_bounds(new_bounds'left));
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return SIGNED is
+ subtype rtype is SIGNED (SIZE-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 380
+ begin
+ -- synopsys synthesis_off
+ result := rtype'(others => '0');
+ result(0) := MAKE_BINARY(ARG);
+ if (result(0) = 'X') then
+ result := rtype'(others => 'X');
+ end if;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ -- convert an integer to an STD_LOGIC_VECTOR
+ function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ variable result: STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable temp: integer;
+ -- synopsys built_in SYN_INTEGER_TO_SIGNED
+ -- synopsys subpgm_id 381
+ begin
+ -- synopsys synthesis_off
+ temp := ARG;
+ for i in 0 to SIZE-1 loop
+ if (temp mod 2) = 1 then
+ result(i) := '1';
+ else
+ result(i) := '0';
+ end if;
+ if temp > 0 then
+ temp := temp / 2;
+ elsif (temp > integer'low) then
+ temp := (temp - 1) / 2; -- simulate ASR
+ else
+ temp := temp / 2; -- simulate ASR
+ end if;
+ end loop;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 382
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => '0');
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function CONV_STD_LOGIC_VECTOR(ARG: SIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_SIGN_EXTEND
+ -- synopsys subpgm_id 383
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => new_bounds(new_bounds'left));
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 384
+ begin
+ -- synopsys synthesis_off
+ result := rtype'(others => '0');
+ result(0) := MAKE_BINARY(ARG);
+ if (result(0) = 'X') then
+ result := rtype'(others => 'X');
+ end if;
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+ function EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER)
+ return STD_LOGIC_VECTOR is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable new_bounds: STD_LOGIC_VECTOR (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_ZERO_EXTEND
+ -- synopsys subpgm_id 385
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => '0');
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+ function SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ constant msb: INTEGER := min(ARG'length, SIZE) - 1;
+ subtype rtype is STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ variable new_bounds : STD_LOGIC_VECTOR (ARG'length-1 downto 0);
+ variable result: rtype;
+ -- synopsys built_in SYN_SIGN_EXTEND
+ -- synopsys subpgm_id 386
+ begin
+ -- synopsys synthesis_off
+ new_bounds := MAKE_BINARY(ARG);
+ if (new_bounds(0) = 'X') then
+ result := rtype'(others => 'X');
+ return result;
+ end if;
+ result := rtype'(others => new_bounds(new_bounds'left));
+ result(msb downto 0) := new_bounds(msb downto 0);
+ return result;
+ -- synopsys synthesis_on
+ end;
+
+
+end std_logic_arith;
diff --git a/libraries/synopsys/std_logic_misc-body.vhdl b/libraries/synopsys/std_logic_misc-body.vhdl
new file mode 100644
index 000000000..531328c3f
--- /dev/null
+++ b/libraries/synopsys/std_logic_misc-body.vhdl
@@ -0,0 +1,811 @@
+--------------------------------------------------------------------------
+--
+-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. All rights reserved.
+--
+-- This source file may be used and distributed without restriction
+-- provided that this copyright statement is not removed from the file
+-- and that any derivative work contains this copyright notice.
+--
+-- Package name: std_logic_misc
+--
+-- Purpose: This package defines supplemental types, subtypes,
+-- constants, and functions for the Std_logic_1164 Package.
+--
+-- Author: GWH
+--
+--------------------------------------------------------------------------
+
+package body std_logic_misc is
+
+--synopsys synthesis_off
+
+ type STRN_STD_ULOGIC_TABLE is array (STD_ULOGIC,STRENGTH) of STD_ULOGIC;
+
+ --------------------------------------------------------------------
+ --
+ -- Truth tables for output strength --> STD_ULOGIC lookup
+ --
+ --------------------------------------------------------------------
+
+ -- truth table for output strength --> STD_ULOGIC lookup
+ constant tbl_STRN_STD_ULOGIC: STRN_STD_ULOGIC_TABLE :=
+ -- ------------------------------------------------------------------
+ -- | X01 X0H XL1 X0Z XZ1 WLH WLZ WZH W0H WL1 | strn/ output|
+ -- ------------------------------------------------------------------
+ (('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | X |
+ ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | 0 |
+ ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | 1 |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | Z |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | W |
+ ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | L |
+ ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | H |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W')); -- | - |
+
+
+
+ --------------------------------------------------------------------
+ --
+ -- Truth tables for strength --> STD_ULOGIC mapping ('Z' pass through)
+ --
+ --------------------------------------------------------------------
+
+ -- truth table for output strength --> STD_ULOGIC lookup
+ constant tbl_STRN_STD_ULOGIC_Z: STRN_STD_ULOGIC_TABLE :=
+ -- ------------------------------------------------------------------
+ -- | X01 X0H XL1 X0Z XZ1 WLH WLZ WZH W0H WL1 | strn/ output|
+ -- ------------------------------------------------------------------
+ (('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | X |
+ ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | 0 |
+ ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | 1 |
+ ('Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z'), -- | Z |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W'), -- | W |
+ ('0', '0', 'L', '0', 'Z', 'L', 'L', 'Z', '0', 'L'), -- | L |
+ ('1', 'H', '1', 'Z', '1', 'H', 'Z', 'H', 'H', '1'), -- | H |
+ ('X', 'X', 'X', 'X', 'X', 'W', 'W', 'W', 'W', 'W')); -- | - |
+
+
+
+ ---------------------------------------------------------------------
+ --
+ -- functions for mapping the STD_(U)LOGIC according to STRENGTH
+ --
+ ---------------------------------------------------------------------
+
+ function strength_map(input: STD_ULOGIC; strn: STRENGTH) return STD_LOGIC is
+ -- pragma subpgm_id 387
+ begin
+ return tbl_STRN_STD_ULOGIC(input, strn);
+ end strength_map;
+
+
+ function strength_map_z(input:STD_ULOGIC; strn:STRENGTH) return STD_LOGIC is
+ -- pragma subpgm_id 388
+ begin
+ return tbl_STRN_STD_ULOGIC_Z(input, strn);
+ end strength_map_z;
+
+
+ ---------------------------------------------------------------------
+ --
+ -- conversion functions for STD_LOGIC_VECTOR and STD_ULOGIC_VECTOR
+ --
+ ---------------------------------------------------------------------
+
+--synopsys synthesis_on
+ function Drive (V: STD_LOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ -- pragma built_in SYN_FEED_THRU
+ -- pragma subpgm_id 389
+--synopsys synthesis_off
+ alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V;
+--synopsys synthesis_on
+ begin
+--synopsys synthesis_off
+ return STD_ULOGIC_VECTOR(Value);
+--synopsys synthesis_on
+ end Drive;
+
+
+ function Drive (V: STD_ULOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma built_in SYN_FEED_THRU
+ -- pragma subpgm_id 390
+--synopsys synthesis_off
+ alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V;
+--synopsys synthesis_on
+ begin
+--synopsys synthesis_off
+ return STD_LOGIC_VECTOR(Value);
+--synopsys synthesis_on
+ end Drive;
+--synopsys synthesis_off
+
+
+ ---------------------------------------------------------------------
+ --
+ -- conversion functions for sensing various types
+ --
+ -- (the second argument allows the user to specify the value to
+ -- be returned when the network is undriven)
+ --
+ ---------------------------------------------------------------------
+
+ function Sense (V: STD_ULOGIC; vZ, vU, vDC: STD_ULOGIC)
+ return STD_LOGIC is
+ -- pragma subpgm_id 391
+ begin
+ if V = 'Z' then
+ return vZ;
+ elsif V = 'U' then
+ return vU;
+ elsif V = '-' then
+ return vDC;
+ else
+ return V;
+ end if;
+ end Sense;
+
+
+ function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_LOGIC_VECTOR is
+ -- pragma subpgm_id 392
+ alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: STD_LOGIC_VECTOR (V'length-1 downto 0);
+ begin
+ for i in Value'range loop
+ if ( Value(i) = 'Z' ) then
+ Result(i) := vZ;
+ elsif Value(i) = 'U' then
+ Result(i) := vU;
+ elsif Value(i) = '-' then
+ Result(i) := vDC;
+ else
+ Result(i) := Value(i);
+ end if;
+ end loop;
+ return Result;
+ end Sense;
+
+
+ function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_ULOGIC_VECTOR is
+ -- pragma subpgm_id 393
+ alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: STD_ULOGIC_VECTOR (V'length-1 downto 0);
+ begin
+ for i in Value'range loop
+ if ( Value(i) = 'Z' ) then
+ Result(i) := vZ;
+ elsif Value(i) = 'U' then
+ Result(i) := vU;
+ elsif Value(i) = '-' then
+ Result(i) := vDC;
+ else
+ Result(i) := Value(i);
+ end if;
+ end loop;
+ return Result;
+ end Sense;
+
+
+ function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_LOGIC_VECTOR is
+ -- pragma subpgm_id 394
+ alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: STD_LOGIC_VECTOR (V'length-1 downto 0);
+ begin
+ for i in Value'range loop
+ if ( Value(i) = 'Z' ) then
+ Result(i) := vZ;
+ elsif Value(i) = 'U' then
+ Result(i) := vU;
+ elsif Value(i) = '-' then
+ Result(i) := vDC;
+ else
+ Result(i) := Value(i);
+ end if;
+ end loop;
+ return Result;
+ end Sense;
+
+
+ function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_ULOGIC_VECTOR is
+ -- pragma subpgm_id 395
+ alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: STD_ULOGIC_VECTOR (V'length-1 downto 0);
+ begin
+ for i in Value'range loop
+ if ( Value(i) = 'Z' ) then
+ Result(i) := vZ;
+ elsif Value(i) = 'U' then
+ Result(i) := vU;
+ elsif Value(i) = '-' then
+ Result(i) := vDC;
+ else
+ Result(i) := Value(i);
+ end if;
+ end loop;
+ return Result;
+ end Sense;
+
+ ---------------------------------------------------------------------
+ --
+ -- Function: STD_LOGIC_VECTORtoBIT_VECTOR
+ --
+ -- Purpose: Conversion fun. from STD_LOGIC_VECTOR to BIT_VECTOR
+ --
+ -- Mapping: 0, L --> 0
+ -- 1, H --> 1
+ -- X, W --> vX if Xflag is TRUE
+ -- X, W --> 0 if Xflag is FALSE
+ -- Z --> vZ if Zflag is TRUE
+ -- Z --> 0 if Zflag is FALSE
+ -- U --> vU if Uflag is TRUE
+ -- U --> 0 if Uflag is FALSE
+ -- - --> vDC if DCflag is TRUE
+ -- - --> 0 if DCflag is FALSE
+ --
+ ---------------------------------------------------------------------
+
+--synopsys synthesis_on
+ function STD_LOGIC_VECTORtoBIT_VECTOR (V: STD_LOGIC_VECTOR
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT_VECTOR is
+ -- pragma built_in SYN_FEED_THRU
+ -- pragma subpgm_id 396
+--synopsys synthesis_off
+ alias Value: STD_LOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: BIT_VECTOR (V'length-1 downto 0);
+--synopsys synthesis_on
+ begin
+--synopsys synthesis_off
+ for i in Value'range loop
+ case Value(i) is
+ when '0' | 'L' =>
+ Result(i) := '0';
+ when '1' | 'H' =>
+ Result(i) := '1';
+ when 'X' =>
+ if ( Xflag ) then
+ Result(i) := vX;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_LOGIC_VECTORtoBIT_VECTOR: X --> 0"
+ severity WARNING;
+ end if;
+ when 'W' =>
+ if ( Xflag ) then
+ Result(i) := vX;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_LOGIC_VECTORtoBIT_VECTOR: W --> 0"
+ severity WARNING;
+ end if;
+ when 'Z' =>
+ if ( Zflag ) then
+ Result(i) := vZ;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_LOGIC_VECTORtoBIT_VECTOR: Z --> 0"
+ severity WARNING;
+ end if;
+ when 'U' =>
+ if ( Uflag ) then
+ Result(i) := vU;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_LOGIC_VECTORtoBIT_VECTOR: U --> 0"
+ severity WARNING;
+ end if;
+ when '-' =>
+ if ( DCflag ) then
+ Result(i) := vDC;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_LOGIC_VECTORtoBIT_VECTOR: - --> 0"
+ severity WARNING;
+ end if;
+ end case;
+ end loop;
+ return Result;
+--synopsys synthesis_on
+ end STD_LOGIC_VECTORtoBIT_VECTOR;
+
+
+
+
+ ---------------------------------------------------------------------
+ --
+ -- Function: STD_ULOGIC_VECTORtoBIT_VECTOR
+ --
+ -- Purpose: Conversion fun. from STD_ULOGIC_VECTOR to BIT_VECTOR
+ --
+ -- Mapping: 0, L --> 0
+ -- 1, H --> 1
+ -- X, W --> vX if Xflag is TRUE
+ -- X, W --> 0 if Xflag is FALSE
+ -- Z --> vZ if Zflag is TRUE
+ -- Z --> 0 if Zflag is FALSE
+ -- U --> vU if Uflag is TRUE
+ -- U --> 0 if Uflag is FALSE
+ -- - --> vDC if DCflag is TRUE
+ -- - --> 0 if DCflag is FALSE
+ --
+ ---------------------------------------------------------------------
+
+ function STD_ULOGIC_VECTORtoBIT_VECTOR (V: STD_ULOGIC_VECTOR
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT_VECTOR is
+ -- pragma built_in SYN_FEED_THRU
+ -- pragma subpgm_id 397
+--synopsys synthesis_off
+ alias Value: STD_ULOGIC_VECTOR (V'length-1 downto 0) is V;
+ variable Result: BIT_VECTOR (V'length-1 downto 0);
+--synopsys synthesis_on
+ begin
+--synopsys synthesis_off
+ for i in Value'range loop
+ case Value(i) is
+ when '0' | 'L' =>
+ Result(i) := '0';
+ when '1' | 'H' =>
+ Result(i) := '1';
+ when 'X' =>
+ if ( Xflag ) then
+ Result(i) := vX;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_ULOGIC_VECTORtoBIT_VECTOR: X --> 0"
+ severity WARNING;
+ end if;
+ when 'W' =>
+ if ( Xflag ) then
+ Result(i) := vX;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_ULOGIC_VECTORtoBIT_VECTOR: W --> 0"
+ severity WARNING;
+ end if;
+ when 'Z' =>
+ if ( Zflag ) then
+ Result(i) := vZ;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_ULOGIC_VECTORtoBIT_VECTOR: Z --> 0"
+ severity WARNING;
+ end if;
+ when 'U' =>
+ if ( Uflag ) then
+ Result(i) := vU;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_ULOGIC_VECTORtoBIT_VECTOR: U --> 0"
+ severity WARNING;
+ end if;
+ when '-' =>
+ if ( DCflag ) then
+ Result(i) := vDC;
+ else
+ Result(i) := '0';
+ assert FALSE
+ report "STD_ULOGIC_VECTORtoBIT_VECTOR: - --> 0"
+ severity WARNING;
+ end if;
+ end case;
+ end loop;
+ return Result;
+--synopsys synthesis_on
+ end STD_ULOGIC_VECTORtoBIT_VECTOR;
+
+
+
+
+ ---------------------------------------------------------------------
+ --
+ -- Function: STD_ULOGICtoBIT
+ --
+ -- Purpose: Conversion function from STD_ULOGIC to BIT
+ --
+ -- Mapping: 0, L --> 0
+ -- 1, H --> 1
+ -- X, W --> vX if Xflag is TRUE
+ -- X, W --> 0 if Xflag is FALSE
+ -- Z --> vZ if Zflag is TRUE
+ -- Z --> 0 if Zflag is FALSE
+ -- U --> vU if Uflag is TRUE
+ -- U --> 0 if Uflag is FALSE
+ -- - --> vDC if DCflag is TRUE
+ -- - --> 0 if DCflag is FALSE
+ --
+ ---------------------------------------------------------------------
+
+ function STD_ULOGICtoBIT (V: STD_ULOGIC
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT is
+ -- pragma built_in SYN_FEED_THRU
+ -- pragma subpgm_id 398
+ variable Result: BIT;
+ begin
+--synopsys synthesis_off
+ case V is
+ when '0' | 'L' =>
+ Result := '0';
+ when '1' | 'H' =>
+ Result := '1';
+ when 'X' =>
+ if ( Xflag ) then
+ Result := vX;
+ else
+ Result := '0';
+ assert FALSE
+ report "STD_ULOGICtoBIT: X --> 0"
+ severity WARNING;
+ end if;
+ when 'W' =>
+ if ( Xflag ) then
+ Result := vX;
+ else
+ Result := '0';
+ assert FALSE
+ report "STD_ULOGICtoBIT: W --> 0"
+ severity WARNING;
+ end if;
+ when 'Z' =>
+ if ( Zflag ) then
+ Result := vZ;
+ else
+ Result := '0';
+ assert FALSE
+ report "STD_ULOGICtoBIT: Z --> 0"
+ severity WARNING;
+ end if;
+ when 'U' =>
+ if ( Uflag ) then
+ Result := vU;
+ else
+ Result := '0';
+ assert FALSE
+ report "STD_ULOGICtoBIT: U --> 0"
+ severity WARNING;
+ end if;
+ when '-' =>
+ if ( DCflag ) then
+ Result := vDC;
+ else
+ Result := '0';
+ assert FALSE
+ report "STD_ULOGICtoBIT: - --> 0"
+ severity WARNING;
+ end if;
+ end case;
+ return Result;
+--synopsys synthesis_on
+ end STD_ULOGICtoBIT;
+
+
+ --------------------------------------------------------------------------
+
+ function AND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 399
+ variable result: STD_LOGIC;
+ begin
+ result := '1';
+ for i in ARG'range loop
+ result := result and ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function NAND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 400
+ begin
+ return not AND_REDUCE(ARG);
+ end;
+
+ function OR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 401
+ variable result: STD_LOGIC;
+ begin
+ result := '0';
+ for i in ARG'range loop
+ result := result or ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function NOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 402
+ begin
+ return not OR_REDUCE(ARG);
+ end;
+
+ function XOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 403
+ variable result: STD_LOGIC;
+ begin
+ result := '0';
+ for i in ARG'range loop
+ result := result xor ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function XNOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 404
+ begin
+ return not XOR_REDUCE(ARG);
+ end;
+
+ function AND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 405
+ variable result: STD_LOGIC;
+ begin
+ result := '1';
+ for i in ARG'range loop
+ result := result and ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function NAND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 406
+ begin
+ return not AND_REDUCE(ARG);
+ end;
+
+ function OR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 407
+ variable result: STD_LOGIC;
+ begin
+ result := '0';
+ for i in ARG'range loop
+ result := result or ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function NOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 408
+ begin
+ return not OR_REDUCE(ARG);
+ end;
+
+ function XOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 409
+ variable result: STD_LOGIC;
+ begin
+ result := '0';
+ for i in ARG'range loop
+ result := result xor ARG(i);
+ end loop;
+ return result;
+ end;
+
+ function XNOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01 is
+ -- pragma subpgm_id 410
+ begin
+ return not XOR_REDUCE(ARG);
+ end;
+
+--synopsys synthesis_off
+
+ function fun_BUF3S(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC is
+ -- pragma subpgm_id 411
+ type TRISTATE_TABLE is array(STRENGTH, UX01, UX01) of STD_LOGIC;
+
+ -- truth table for tristate "buf" function (Enable active Low)
+ constant tbl_BUF3S: TRISTATE_TABLE :=
+ -- ----------------------------------------------------
+ -- | Input U X 0 1 | Enable Strength |
+ -- ---------------------------------|-----------------|
+ ((('U', 'U', 'U', 'U'), --| U X01 |
+ ('U', 'X', 'X', 'X'), --| X X01 |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 X01 |
+ ('U', 'X', '0', '1')), --| 1 X01 |
+ (('U', 'U', 'U', 'U'), --| U X0H |
+ ('U', 'X', 'X', 'X'), --| X X0H |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 X0H |
+ ('U', 'X', '0', 'H')), --| 1 X0H |
+ (('U', 'U', 'U', 'U'), --| U XL1 |
+ ('U', 'X', 'X', 'X'), --| X XL1 |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 XL1 |
+ ('U', 'X', 'L', '1')), --| 1 XL1 |
+ (('U', 'U', 'U', 'Z'), --| U X0Z |
+ ('U', 'X', 'X', 'Z'), --| X X0Z |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 X0Z |
+ ('U', 'X', '0', 'Z')), --| 1 X0Z |
+ (('U', 'U', 'U', 'U'), --| U XZ1 |
+ ('U', 'X', 'X', 'X'), --| X XZ1 |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 XZ1 |
+ ('U', 'X', 'Z', '1')), --| 1 XZ1 |
+ (('U', 'U', 'U', 'U'), --| U WLH |
+ ('U', 'W', 'W', 'W'), --| X WLH |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 WLH |
+ ('U', 'W', 'L', 'H')), --| 1 WLH |
+ (('U', 'U', 'U', 'U'), --| U WLZ |
+ ('U', 'W', 'W', 'Z'), --| X WLZ |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 WLZ |
+ ('U', 'W', 'L', 'Z')), --| 1 WLZ |
+ (('U', 'U', 'U', 'U'), --| U WZH |
+ ('U', 'W', 'W', 'W'), --| X WZH |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 WZH |
+ ('U', 'W', 'Z', 'H')), --| 1 WZH |
+ (('U', 'U', 'U', 'U'), --| U W0H |
+ ('U', 'W', 'W', 'W'), --| X W0H |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 W0H |
+ ('U', 'W', '0', 'H')), --| 1 W0H |
+ (('U', 'U', 'U', 'U'), --| U WL1 |
+ ('U', 'W', 'W', 'W'), --| X WL1 |
+ ('Z', 'Z', 'Z', 'Z'), --| 0 WL1 |
+ ('U', 'W', 'L', '1')));--| 1 WL1 |
+ begin
+ return tbl_BUF3S(Strn, Enable, Input);
+ end fun_BUF3S;
+
+
+ function fun_BUF3SL(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC is
+ -- pragma subpgm_id 412
+ type TRISTATE_TABLE is array(STRENGTH, UX01, UX01) of STD_LOGIC;
+
+ -- truth table for tristate "buf" function (Enable active Low)
+ constant tbl_BUF3SL: TRISTATE_TABLE :=
+ -- ----------------------------------------------------
+ -- | Input U X 0 1 | Enable Strength |
+ -- ---------------------------------|-----------------|
+ ((('U', 'U', 'U', 'U'), --| U X01 |
+ ('U', 'X', 'X', 'X'), --| X X01 |
+ ('U', 'X', '0', '1'), --| 0 X01 |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 X01 |
+ (('U', 'U', 'U', 'U'), --| U X0H |
+ ('U', 'X', 'X', 'X'), --| X X0H |
+ ('U', 'X', '0', 'H'), --| 0 X0H |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 X0H |
+ (('U', 'U', 'U', 'U'), --| U XL1 |
+ ('U', 'X', 'X', 'X'), --| X XL1 |
+ ('U', 'X', 'L', '1'), --| 0 XL1 |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 XL1 |
+ (('U', 'U', 'U', 'Z'), --| U X0Z |
+ ('U', 'X', 'X', 'Z'), --| X X0Z |
+ ('U', 'X', '0', 'Z'), --| 0 X0Z |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 X0Z |
+ (('U', 'U', 'U', 'U'), --| U XZ1 |
+ ('U', 'X', 'X', 'X'), --| X XZ1 |
+ ('U', 'X', 'Z', '1'), --| 0 XZ1 |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 XZ1 |
+ (('U', 'U', 'U', 'U'), --| U WLH |
+ ('U', 'W', 'W', 'W'), --| X WLH |
+ ('U', 'W', 'L', 'H'), --| 0 WLH |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 WLH |
+ (('U', 'U', 'U', 'U'), --| U WLZ |
+ ('U', 'W', 'W', 'Z'), --| X WLZ |
+ ('U', 'W', 'L', 'Z'), --| 0 WLZ |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 WLZ |
+ (('U', 'U', 'U', 'U'), --| U WZH |
+ ('U', 'W', 'W', 'W'), --| X WZH |
+ ('U', 'W', 'Z', 'H'), --| 0 WZH |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 WZH |
+ (('U', 'U', 'U', 'U'), --| U W0H |
+ ('U', 'W', 'W', 'W'), --| X W0H |
+ ('U', 'W', '0', 'H'), --| 0 W0H |
+ ('Z', 'Z', 'Z', 'Z')), --| 1 W0H |
+ (('U', 'U', 'U', 'U'), --| U WL1 |
+ ('U', 'W', 'W', 'W'), --| X WL1 |
+ ('U', 'W', 'L', '1'), --| 0 WL1 |
+ ('Z', 'Z', 'Z', 'Z')));--| 1 WL1 |
+ begin
+ return tbl_BUF3SL(Strn, Enable, Input);
+ end fun_BUF3SL;
+
+
+ function fun_MUX2x1(Input0, Input1, Sel: UX01) return UX01 is
+ -- pragma subpgm_id 413
+ type MUX_TABLE is array (UX01, UX01, UX01) of UX01;
+
+ -- truth table for "MUX2x1" function
+ constant tbl_MUX2x1: MUX_TABLE :=
+ --------------------------------------------
+ --| In0 'U' 'X' '0' '1' | Sel In1 |
+ --------------------------------------------
+ ((('U', 'U', 'U', 'U'), --| 'U' 'U' |
+ ('U', 'U', 'U', 'U'), --| 'X' 'U' |
+ ('U', 'X', '0', '1'), --| '0' 'U' |
+ ('U', 'U', 'U', 'U')), --| '1' 'U' |
+ (('U', 'X', 'U', 'U'), --| 'U' 'X' |
+ ('U', 'X', 'X', 'X'), --| 'X' 'X' |
+ ('U', 'X', '0', '1'), --| '0' 'X' |
+ ('X', 'X', 'X', 'X')), --| '1' 'X' |
+ (('U', 'U', '0', 'U'), --| 'U' '0' |
+ ('U', 'X', '0', 'X'), --| 'X' '0' |
+ ('U', 'X', '0', '1'), --| '0' '0' |
+ ('0', '0', '0', '0')), --| '1' '0' |
+ (('U', 'U', 'U', '1'), --| 'U' '1' |
+ ('U', 'X', 'X', '1'), --| 'X' '1' |
+ ('U', 'X', '0', '1'), --| '0' '1' |
+ ('1', '1', '1', '1')));--| '1' '1' |
+ begin
+ return tbl_MUX2x1(Input1, Sel, Input0);
+ end fun_MUX2x1;
+
+
+ function fun_MAJ23(Input0, Input1, Input2: UX01) return UX01 is
+ -- pragma subpgm_id 414
+ type MAJ23_TABLE is array (UX01, UX01, UX01) of UX01;
+
+ ----------------------------------------------------------------------------
+ -- The "tbl_MAJ23" truth table return 1 if the majority of three
+ -- inputs is 1, a 0 if the majority is 0, a X if unknown, and a U if
+ -- uninitialized.
+ ----------------------------------------------------------------------------
+ constant tbl_MAJ23: MAJ23_TABLE :=
+ --------------------------------------------
+ --| In0 'U' 'X' '0' '1' | In1 In2 |
+ --------------------------------------------
+ ((('U', 'U', 'U', 'U'), --| 'U' 'U' |
+ ('U', 'U', 'U', 'U'), --| 'X' 'U' |
+ ('U', 'U', '0', 'U'), --| '0' 'U' |
+ ('U', 'U', 'U', '1')), --| '1' 'U' |
+ (('U', 'U', 'U', 'U'), --| 'U' 'X' |
+ ('U', 'X', 'X', 'X'), --| 'X' 'X' |
+ ('U', 'X', '0', 'X'), --| '0' 'X' |
+ ('U', 'X', 'X', '1')), --| '1' 'X' |
+ (('U', 'U', '0', 'U'), --| 'U' '0' |
+ ('U', 'X', '0', 'X'), --| 'X' '0' |
+ ('0', '0', '0', '0'), --| '0' '0' |
+ ('U', 'X', '0', '1')), --| '1' '0' |
+ (('U', 'U', 'U', '1'), --| 'U' '1' |
+ ('U', 'X', 'X', '1'), --| 'X' '1' |
+ ('U', 'X', '0', '1'), --| '0' '1' |
+ ('1', '1', '1', '1')));--| '1' '1' |
+
+ begin
+ return tbl_MAJ23(Input0, Input1, Input2);
+ end fun_MAJ23;
+
+
+ function fun_WiredX(Input0, Input1: STD_ULOGIC) return STD_LOGIC is
+ -- pragma subpgm_id 415
+ TYPE stdlogic_table IS ARRAY(STD_ULOGIC, STD_ULOGIC) OF STD_LOGIC;
+
+ -- truth table for "WiredX" function
+ -------------------------------------------------------------------
+ -- resolution function
+ -------------------------------------------------------------------
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H - | |
+ -- ---------------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
+ ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
+ ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
+ ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
+ ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ));-- | - |
+ begin
+ return resolution_table(Input0, Input1);
+ end fun_WiredX;
+
+--synopsys synthesis_on
+
+end;
diff --git a/libraries/synopsys/std_logic_misc.vhdl b/libraries/synopsys/std_logic_misc.vhdl
new file mode 100644
index 000000000..999aa8391
--- /dev/null
+++ b/libraries/synopsys/std_logic_misc.vhdl
@@ -0,0 +1,170 @@
+--------------------------------------------------------------------------
+--
+-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. All rights reserved.
+--
+-- This source file may be used and distributed without restriction
+-- provided that this copyright statement is not removed from the file
+-- and that any derivative work contains this copyright notice.
+--
+-- Package name: std_logic_misc
+--
+-- Purpose: This package defines supplemental types, subtypes,
+-- constants, and functions for the Std_logic_1164 Package.
+--
+-- Author: GWH
+--
+--------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+--library SYNOPSYS;
+--use SYNOPSYS.attributes.all;
+
+
+package std_logic_misc is
+
+ -- output-strength types
+
+ type STRENGTH is (strn_X01, strn_X0H, strn_XL1, strn_X0Z, strn_XZ1,
+ strn_WLH, strn_WLZ, strn_WZH, strn_W0H, strn_WL1);
+
+
+--synopsys synthesis_off
+
+ type MINOMAX is array (1 to 3) of TIME;
+
+
+ ---------------------------------------------------------------------
+ --
+ -- functions for mapping the STD_(U)LOGIC according to STRENGTH
+ --
+ ---------------------------------------------------------------------
+
+ function strength_map(input: STD_ULOGIC; strn: STRENGTH) return STD_LOGIC;
+
+ function strength_map_z(input:STD_ULOGIC; strn:STRENGTH) return STD_LOGIC;
+
+ ---------------------------------------------------------------------
+ --
+ -- conversion functions for STD_ULOGIC_VECTOR and STD_LOGIC_VECTOR
+ --
+ ---------------------------------------------------------------------
+
+--synopsys synthesis_on
+ function Drive (V: STD_ULOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function Drive (V: STD_LOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+--synopsys synthesis_off
+
+ --attribute CLOSELY_RELATED_TCF of Drive: function is TRUE;
+
+ ---------------------------------------------------------------------
+ --
+ -- conversion functions for sensing various types
+ -- (the second argument allows the user to specify the value to
+ -- be returned when the network is undriven)
+ --
+ ---------------------------------------------------------------------
+
+ function Sense (V: STD_ULOGIC; vZ, vU, vDC: STD_ULOGIC) return STD_LOGIC;
+
+ function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_LOGIC_VECTOR;
+ function Sense (V: STD_ULOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_ULOGIC_VECTOR;
+
+ function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_LOGIC_VECTOR;
+ function Sense (V: STD_LOGIC_VECTOR; vZ, vU, vDC: STD_ULOGIC)
+ return STD_ULOGIC_VECTOR;
+
+--synopsys synthesis_on
+
+
+ ---------------------------------------------------------------------
+ --
+ -- Function: STD_LOGIC_VECTORtoBIT_VECTOR STD_ULOGIC_VECTORtoBIT_VECTOR
+ --
+ -- Purpose: Conversion fun. from STD_(U)LOGIC_VECTOR to BIT_VECTOR
+ --
+ -- Mapping: 0, L --> 0
+ -- 1, H --> 1
+ -- X, W --> vX if Xflag is TRUE
+ -- X, W --> 0 if Xflag is FALSE
+ -- Z --> vZ if Zflag is TRUE
+ -- Z --> 0 if Zflag is FALSE
+ -- U --> vU if Uflag is TRUE
+ -- U --> 0 if Uflag is FALSE
+ -- - --> vDC if DCflag is TRUE
+ -- - --> 0 if DCflag is FALSE
+ --
+ ---------------------------------------------------------------------
+
+ function STD_LOGIC_VECTORtoBIT_VECTOR (V: STD_LOGIC_VECTOR
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT_VECTOR;
+
+ function STD_ULOGIC_VECTORtoBIT_VECTOR (V: STD_ULOGIC_VECTOR
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT_VECTOR;
+
+
+ ---------------------------------------------------------------------
+ --
+ -- Function: STD_ULOGICtoBIT
+ --
+ -- Purpose: Conversion function from STD_(U)LOGIC to BIT
+ --
+ -- Mapping: 0, L --> 0
+ -- 1, H --> 1
+ -- X, W --> vX if Xflag is TRUE
+ -- X, W --> 0 if Xflag is FALSE
+ -- Z --> vZ if Zflag is TRUE
+ -- Z --> 0 if Zflag is FALSE
+ -- U --> vU if Uflag is TRUE
+ -- U --> 0 if Uflag is FALSE
+ -- - --> vDC if DCflag is TRUE
+ -- - --> 0 if DCflag is FALSE
+ --
+ ---------------------------------------------------------------------
+
+ function STD_ULOGICtoBIT (V: STD_ULOGIC
+--synopsys synthesis_off
+ ; vX, vZ, vU, vDC: BIT := '0';
+ Xflag, Zflag, Uflag, DCflag: BOOLEAN := FALSE
+--synopsys synthesis_on
+ ) return BIT;
+
+ --------------------------------------------------------------------
+ function AND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+ function NAND_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+ function OR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+ function NOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+ function XOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+ function XNOR_REDUCE(ARG: STD_LOGIC_VECTOR) return UX01;
+
+ function AND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+ function NAND_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+ function OR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+ function NOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+ function XOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+ function XNOR_REDUCE(ARG: STD_ULOGIC_VECTOR) return UX01;
+
+--synopsys synthesis_off
+
+ function fun_BUF3S(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC;
+ function fun_BUF3SL(Input, Enable: UX01; Strn: STRENGTH) return STD_LOGIC;
+ function fun_MUX2x1(Input0, Input1, Sel: UX01) return UX01;
+
+ function fun_MAJ23(Input0, Input1, Input2: UX01) return UX01;
+ function fun_WiredX(Input0, Input1: std_ulogic) return STD_LOGIC;
+
+--synopsys synthesis_on
+
+end;
diff --git a/libraries/synopsys/std_logic_signed.vhdl b/libraries/synopsys/std_logic_signed.vhdl
new file mode 100644
index 000000000..27d211be5
--- /dev/null
+++ b/libraries/synopsys/std_logic_signed.vhdl
@@ -0,0 +1,343 @@
+--------------------------------------------------------------------------
+-- --
+-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. --
+-- All rights reserved. --
+-- --
+-- This source file may be used and distributed without restriction --
+-- provided that this copyright statement is not removed from the file --
+-- and that any derivative work contains this copyright notice. --
+-- --
+-- Package name: STD_LOGIC_SIGNED --
+-- --
+-- --
+-- Date: 09/11/91 KN --
+-- 10/08/92 AMT change std_ulogic to signed std_logic --
+-- 10/28/92 AMT added signed functions, -, ABS --
+-- --
+-- Purpose: --
+-- A set of signed arithemtic, conversion, --
+-- and comparision functions for STD_LOGIC_VECTOR. --
+-- --
+-- Note: Comparision of same length std_logic_vector is defined --
+-- in the LRM. The interpretation is for unsigned vectors --
+-- This package will "overload" that definition. --
+-- --
+--------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+package STD_LOGIC_SIGNED is
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "ABS"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+
+ function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER;
+
+-- remove this since it is already in std_logic_arith
+-- function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR;
+
+end STD_LOGIC_SIGNED;
+
+
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+package body STD_LOGIC_SIGNED is
+
+
+ function maximum(L, R: INTEGER) return INTEGER is
+ begin
+ if L > R then
+ return L;
+ else
+ return R;
+ end if;
+ end;
+
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR (length-1 downto 0);
+ begin
+ result := SIGNED(L) + SIGNED(R); -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := SIGNED(L) + R; -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L + SIGNED(R); -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := SIGNED(L) + R; -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L + SIGNED(R); -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR (length-1 downto 0);
+ begin
+ result := SIGNED(L) - SIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := SIGNED(L) - R; -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L - SIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := SIGNED(L) - R; -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L - SIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := + SIGNED(L); -- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := - SIGNED(L); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "ABS"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := ABS( SIGNED(L));
+ return std_logic_vector(result);
+ end;
+
+ function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0);
+ begin
+ result := SIGNED(L) * SIGNED(R); -- pragma label mult
+ return std_logic_vector(result);
+ end;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to lt
+ constant length: INTEGER := maximum(L'length, R'length);
+ begin
+ return SIGNED(L) < SIGNED(R); -- pragma label lt
+ end;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to lt
+ begin
+ return SIGNED(L) < R; -- pragma label lt
+ end;
+
+ function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to lt
+ begin
+ return L < SIGNED(R); -- pragma label lt
+ end;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return SIGNED(L) <= SIGNED(R); -- pragma label leq
+ end;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return SIGNED(L) <= R; -- pragma label leq
+ end;
+
+ function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return L <= SIGNED(R); -- pragma label leq
+ end;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return SIGNED(L) > SIGNED(R); -- pragma label gt
+ end;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return SIGNED(L) > R; -- pragma label gt
+ end;
+
+ function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return L > SIGNED(R); -- pragma label gt
+ end;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return SIGNED(L) >= SIGNED(R); -- pragma label geq
+ end;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return SIGNED(L) >= R; -- pragma label geq
+ end;
+
+ function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return L >= SIGNED(R); -- pragma label geq
+ end;
+
+ function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return SIGNED(L) = SIGNED(R);
+ end;
+
+ function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ begin
+ return SIGNED(L) = R;
+ end;
+
+ function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L = SIGNED(R);
+ end;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return SIGNED(L) /= SIGNED(R);
+ end;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ begin
+ return SIGNED(L) /= R;
+ end;
+
+ function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L /= SIGNED(R);
+ end;
+
+ function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR(SHL(SIGNED(ARG),UNSIGNED(COUNT)));
+ end;
+
+ function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR(SHR(SIGNED(ARG),UNSIGNED(COUNT)));
+ end;
+
+
+
+-- This function converts std_logic_vector to a signed integer value
+-- using a conversion function in std_logic_arith
+ function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER is
+ variable result : SIGNED(ARG'range);
+ begin
+ result := SIGNED(ARG);
+ return CONV_INTEGER(result);
+ end;
+end STD_LOGIC_SIGNED;
+
+
diff --git a/libraries/synopsys/std_logic_textio.vhdl b/libraries/synopsys/std_logic_textio.vhdl
new file mode 100644
index 000000000..d69a87e37
--- /dev/null
+++ b/libraries/synopsys/std_logic_textio.vhdl
@@ -0,0 +1,634 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. All rights reserved.
+--
+-- This source file may be used and distributed without restriction
+-- provided that this copyright statement is not removed from the file
+-- and that any derivative work contains this copyright notice.
+--
+-- Package name: STD_LOGIC_TEXTIO
+--
+-- Purpose: This package overloads the standard TEXTIO procedures
+-- READ and WRITE.
+--
+-- Author: CRC, TS
+--
+----------------------------------------------------------------------------
+
+use STD.textio.all;
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package STD_LOGIC_TEXTIO is
+--synopsys synthesis_off
+ -- Read and Write procedures for STD_ULOGIC and STD_ULOGIC_VECTOR
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC);
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC; GOOD: out BOOLEAN);
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR);
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+ procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+
+ -- Read and Write procedures for STD_LOGIC_VECTOR
+ procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR);
+ procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+
+ --
+ -- Read and Write procedures for Hex and Octal values.
+ -- The values appear in the file as a series of characters
+ -- between 0-F (Hex), or 0-7 (Octal) respectively.
+ --
+
+ -- Hex
+ procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR);
+ procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure HWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+ procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR);
+ procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure HWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+
+ -- Octal
+ procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR);
+ procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure OWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+ procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR);
+ procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN);
+ procedure OWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0);
+
+
+--synopsys synthesis_on
+end STD_LOGIC_TEXTIO;
+
+package body STD_LOGIC_TEXTIO is
+--synopsys synthesis_off
+
+ -- Type and constant definitions used to map STD_ULOGIC values
+ -- into/from character values.
+
+ type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', ERROR);
+ type char_indexed_by_MVL9 is array (STD_ULOGIC) of character;
+ type MVL9_indexed_by_char is array (character) of STD_ULOGIC;
+ type MVL9plus_indexed_by_char is array (character) of MVL9plus;
+
+ constant MVL9_to_char: char_indexed_by_MVL9 := "UX01ZWLH-";
+ constant char_to_MVL9: MVL9_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
+ constant char_to_MVL9plus: MVL9plus_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => ERROR);
+
+
+ -- Overloaded procedures.
+
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC; GOOD:out BOOLEAN) is
+ variable c: character;
+ begin
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ if (char_to_MVL9plus(c) = ERROR) then
+ value := 'U';
+ good := FALSE;
+ else
+ value := char_to_MVL9(c);
+ good := TRUE;
+ end if;
+ end READ;
+
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD:out BOOLEAN) is
+ variable m: STD_ULOGIC;
+ variable c: character;
+ variable s: string(1 to value'length-1);
+ variable mv: STD_ULOGIC_VECTOR(0 to value'length-1);
+ constant allU: STD_ULOGIC_VECTOR(0 to value'length-1)
+ := (others => 'U');
+ begin
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ if (char_to_MVL9plus(c) = ERROR) then
+ value := allU;
+ good := FALSE;
+ return;
+ end if;
+
+ read(l, s);
+ for i in integer range 1 to value'length-1 loop
+ if (char_to_MVL9plus(s(i)) = ERROR) then
+ value := allU;
+ good := FALSE;
+ return;
+ end if;
+ end loop;
+
+ mv(0) := char_to_MVL9(c);
+ for i in integer range 1 to value'length-1 loop
+ mv(i) := char_to_MVL9(s(i));
+ end loop;
+ value := mv;
+ good := TRUE;
+ end READ;
+
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC) is
+ variable c: character;
+ begin
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ if (char_to_MVL9plus(c) = ERROR) then
+ value := 'U';
+ assert FALSE report "READ(STD_ULOGIC) Error: Character '" &
+ c & "' read, expected STD_ULOGIC literal.";
+ else
+ value := char_to_MVL9(c);
+ end if;
+ end READ;
+
+ procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is
+ variable m: STD_ULOGIC;
+ variable c: character;
+ variable s: string(1 to value'length-1);
+ variable mv: STD_ULOGIC_VECTOR(0 to value'length-1);
+ constant allU: STD_ULOGIC_VECTOR(0 to value'length-1)
+ := (others => 'U');
+ begin
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ if (char_to_MVL9plus(c) = ERROR) then
+ value := allU;
+ assert FALSE report
+ "READ(STD_ULOGIC_VECTOR) Error: Character '" &
+ c & "' read, expected STD_ULOGIC literal.";
+ return;
+ end if;
+
+ read(l, s);
+ for i in integer range 1 to value'length-1 loop
+ if (char_to_MVL9plus(s(i)) = ERROR) then
+ value := allU;
+ assert FALSE report
+ "READ(STD_ULOGIC_VECTOR) Error: Character '" &
+ s(i) & "' read, expected STD_ULOGIC literal.";
+ return;
+ end if;
+ end loop;
+
+ mv(0) := char_to_MVL9(c);
+ for i in integer range 1 to value'length-1 loop
+ mv(i) := char_to_MVL9(s(i));
+ end loop;
+ value := mv;
+ end READ;
+
+ procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ write(l, MVL9_to_char(value), justified, field);
+ end WRITE;
+
+
+ procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ variable s: string(1 to value'length);
+ variable m: STD_ULOGIC_VECTOR(1 to value'length) := value;
+ begin
+ for i in 1 to value'length loop
+ s(i) := MVL9_to_char(m(i));
+ end loop;
+ write(l, s, justified, field);
+ end WRITE;
+
+ -- Read and Write procedures for STD_LOGIC_VECTOR
+ procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ READ(L, tmp);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end READ;
+
+ procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ READ(L, tmp, GOOD);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end READ;
+
+ procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ WRITE(L, STD_ULOGIC_VECTOR(VALUE), JUSTIFIED, FIELD);
+ end WRITE;
+
+
+ --
+ -- Hex Read and Write procedures.
+ --
+
+ --
+ -- Hex, and Octal Read and Write procedures for BIT_VECTOR
+ -- (these procedures are not exported, they are only used
+ -- by the STD_ULOGIC hex/octal reads and writes below.
+ --
+ --
+
+ procedure Char2QuadBits(C: Character;
+ RESULT: out Bit_Vector(3 downto 0);
+ GOOD: out Boolean;
+ ISSUE_ERROR: in Boolean) is
+ begin
+ case c is
+ when '0' => result := x"0"; good := TRUE;
+ when '1' => result := x"1"; good := TRUE;
+ when '2' => result := x"2"; good := TRUE;
+ when '3' => result := x"3"; good := TRUE;
+ when '4' => result := x"4"; good := TRUE;
+ when '5' => result := x"5"; good := TRUE;
+ when '6' => result := x"6"; good := TRUE;
+ when '7' => result := x"7"; good := TRUE;
+ when '8' => result := x"8"; good := TRUE;
+ when '9' => result := x"9"; good := TRUE;
+ when 'A' => result := x"A"; good := TRUE;
+ when 'B' => result := x"B"; good := TRUE;
+ when 'C' => result := x"C"; good := TRUE;
+ when 'D' => result := x"D"; good := TRUE;
+ when 'E' => result := x"E"; good := TRUE;
+ when 'F' => result := x"F"; good := TRUE;
+
+ when 'a' => result := x"A"; good := TRUE;
+ when 'b' => result := x"B"; good := TRUE;
+ when 'c' => result := x"C"; good := TRUE;
+ when 'd' => result := x"D"; good := TRUE;
+ when 'e' => result := x"E"; good := TRUE;
+ when 'f' => result := x"F"; good := TRUE;
+ when others =>
+ if ISSUE_ERROR then
+ assert FALSE report
+ "HREAD Error: Read a '" & c &
+ "', expected a Hex character (0-F).";
+ end if;
+ good := FALSE;
+ end case;
+ end;
+
+ procedure HREAD(L:inout LINE; VALUE:out BIT_VECTOR) is
+ variable ok: boolean;
+ variable c: character;
+ constant ne: integer := value'length/4;
+ variable bv: bit_vector(0 to value'length-1);
+ variable s: string(1 to ne-1);
+ begin
+ if value'length mod 4 /= 0 then
+ assert FALSE report
+ "HREAD Error: Trying to read vector " &
+ "with an odd (non multiple of 4) length";
+ return;
+ end if;
+
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ Char2QuadBits(c, bv(0 to 3), ok, TRUE);
+ if not ok then
+ return;
+ end if;
+
+ read(L, s, ok);
+ if not ok then
+ assert FALSE
+ report "HREAD Error: Failed to read the STRING";
+ return;
+ end if;
+
+ for i in 1 to ne-1 loop
+ Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, TRUE);
+ if not ok then
+ return;
+ end if;
+ end loop;
+ value := bv;
+ end HREAD;
+
+ procedure HREAD(L:inout LINE; VALUE:out BIT_VECTOR;GOOD: out BOOLEAN) is
+ variable ok: boolean;
+ variable c: character;
+ constant ne: integer := value'length/4;
+ variable bv: bit_vector(0 to value'length-1);
+ variable s: string(1 to ne-1);
+ begin
+ if value'length mod 4 /= 0 then
+ good := FALSE;
+ return;
+ end if;
+
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ Char2QuadBits(c, bv(0 to 3), ok, FALSE);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+
+ read(L, s, ok);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+
+ for i in 1 to ne-1 loop
+ Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, FALSE);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+ end loop;
+ good := TRUE;
+ value := bv;
+ end HREAD;
+
+
+ procedure HWRITE(L:inout LINE; VALUE:in BIT_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ variable quad: bit_vector(0 to 3);
+ constant ne: integer := value'length/4;
+ variable bv: bit_vector(0 to value'length-1) := value;
+ variable s: string(1 to ne);
+ begin
+ if value'length mod 4 /= 0 then
+ assert FALSE report
+ "HWRITE Error: Trying to read vector " &
+ "with an odd (non multiple of 4) length";
+ return;
+ end if;
+
+ for i in 0 to ne-1 loop
+ quad := bv(4*i to 4*i+3);
+ case quad is
+ when x"0" => s(i+1) := '0';
+ when x"1" => s(i+1) := '1';
+ when x"2" => s(i+1) := '2';
+ when x"3" => s(i+1) := '3';
+ when x"4" => s(i+1) := '4';
+ when x"5" => s(i+1) := '5';
+ when x"6" => s(i+1) := '6';
+ when x"7" => s(i+1) := '7';
+ when x"8" => s(i+1) := '8';
+ when x"9" => s(i+1) := '9';
+ when x"A" => s(i+1) := 'A';
+ when x"B" => s(i+1) := 'B';
+ when x"C" => s(i+1) := 'C';
+ when x"D" => s(i+1) := 'D';
+ when x"E" => s(i+1) := 'E';
+ when x"F" => s(i+1) := 'F';
+ end case;
+ end loop;
+ write(L, s, JUSTIFIED, FIELD);
+ end HWRITE;
+
+ procedure Char2TriBits(C: Character;
+ RESULT: out bit_vector(2 downto 0);
+ GOOD: out Boolean;
+ ISSUE_ERROR: in Boolean) is
+ begin
+ case c is
+ when '0' => result := o"0"; good := TRUE;
+ when '1' => result := o"1"; good := TRUE;
+ when '2' => result := o"2"; good := TRUE;
+ when '3' => result := o"3"; good := TRUE;
+ when '4' => result := o"4"; good := TRUE;
+ when '5' => result := o"5"; good := TRUE;
+ when '6' => result := o"6"; good := TRUE;
+ when '7' => result := o"7"; good := TRUE;
+ when others =>
+ if ISSUE_ERROR then
+ assert FALSE report
+ "OREAD Error: Read a '" & c &
+ "', expected an Octal character (0-7).";
+ end if;
+ good := FALSE;
+ end case;
+ end;
+
+ procedure OREAD(L:inout LINE; VALUE:out BIT_VECTOR) is
+ variable c: character;
+ variable ok: boolean;
+ constant ne: integer := value'length/3;
+ variable bv: bit_vector(0 to value'length-1);
+ variable s: string(1 to ne-1);
+ begin
+ if value'length mod 3 /= 0 then
+ assert FALSE report
+ "OREAD Error: Trying to read vector " &
+ "with an odd (non multiple of 3) length";
+ return;
+ end if;
+
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ Char2TriBits(c, bv(0 to 2), ok, TRUE);
+ if not ok then
+ return;
+ end if;
+
+ read(L, s, ok);
+ if not ok then
+ assert FALSE
+ report "OREAD Error: Failed to read the STRING";
+ return;
+ end if;
+
+ for i in 1 to ne-1 loop
+ Char2TriBits(s(i), bv(3*i to 3*i+2), ok, TRUE);
+ if not ok then
+ return;
+ end if;
+ end loop;
+ value := bv;
+ end OREAD;
+
+ procedure OREAD(L:inout LINE; VALUE:out BIT_VECTOR;GOOD: out BOOLEAN) is
+ variable ok: boolean;
+ variable c: character;
+ constant ne: integer := value'length/3;
+ variable bv: bit_vector(0 to value'length-1);
+ variable s: string(1 to ne-1);
+ begin
+ if value'length mod 3 /= 0 then
+ good := FALSE;
+ return;
+ end if;
+
+ loop -- skip white space
+ read(l,c);
+ exit when ((c /= ' ') and (c /= CR) and (c /= HT));
+ end loop;
+
+ Char2TriBits(c, bv(0 to 2), ok, FALSE);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+
+ read(L, s, ok);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+
+ for i in 1 to ne-1 loop
+ Char2TriBits(s(i), bv(3*i to 3*i+2), ok, FALSE);
+ if not ok then
+ good := FALSE;
+ return;
+ end if;
+ end loop;
+ good := TRUE;
+ value := bv;
+ end OREAD;
+
+
+ procedure OWRITE(L:inout LINE; VALUE:in BIT_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ variable tri: bit_vector(0 to 2);
+ constant ne: integer := value'length/3;
+ variable bv: bit_vector(0 to value'length-1) := value;
+ variable s: string(1 to ne);
+ begin
+ if value'length mod 3 /= 0 then
+ assert FALSE report
+ "OWRITE Error: Trying to read vector " &
+ "with an odd (non multiple of 3) length";
+ return;
+ end if;
+
+ for i in 0 to ne-1 loop
+ tri := bv(3*i to 3*i+2);
+ case tri is
+ when o"0" => s(i+1) := '0';
+ when o"1" => s(i+1) := '1';
+ when o"2" => s(i+1) := '2';
+ when o"3" => s(i+1) := '3';
+ when o"4" => s(i+1) := '4';
+ when o"5" => s(i+1) := '5';
+ when o"6" => s(i+1) := '6';
+ when o"7" => s(i+1) := '7';
+ end case;
+ end loop;
+ write(L, s, JUSTIFIED, FIELD);
+ end OWRITE;
+
+ -- Hex Read and Write procedures for STD_LOGIC_VECTOR
+ procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR;GOOD:out BOOLEAN) is
+ variable tmp: bit_vector(VALUE'length-1 downto 0);
+ begin
+ HREAD(L, tmp, GOOD);
+ VALUE := To_X01(tmp);
+ end HREAD;
+
+ procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is
+ variable tmp: bit_vector(VALUE'length-1 downto 0);
+ begin
+ HREAD(L, tmp);
+ VALUE := To_X01(tmp);
+ end HREAD;
+
+ procedure HWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ HWRITE(L, To_bitvector(VALUE),JUSTIFIED, FIELD);
+ end HWRITE;
+
+ -- Hex Read and Write procedures for STD_LOGIC_VECTOR
+
+ procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ HREAD(L, tmp);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end HREAD;
+
+ procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ HREAD(L, tmp, GOOD);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end HREAD;
+
+ procedure HWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ HWRITE(L, To_bitvector(VALUE), JUSTIFIED, FIELD);
+ end HWRITE;
+
+
+ -- Octal Read and Write procedures for STD_ULOGIC_VECTOR
+ procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR;GOOD:out BOOLEAN) is
+ variable tmp: bit_vector(VALUE'length-1 downto 0);
+ begin
+ OREAD(L, tmp, GOOD);
+ VALUE := To_X01(tmp);
+ end OREAD;
+
+ procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is
+ variable tmp: bit_vector(VALUE'length-1 downto 0);
+ begin
+ OREAD(L, tmp);
+ VALUE := To_X01(tmp);
+ end OREAD;
+
+ procedure OWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ OWRITE(L, To_bitvector(VALUE),JUSTIFIED, FIELD);
+ end OWRITE;
+
+ -- Octal Read and Write procedures for STD_LOGIC_VECTOR
+
+ procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ OREAD(L, tmp);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end OREAD;
+
+ procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is
+ variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
+ begin
+ OREAD(L, tmp, GOOD);
+ VALUE := STD_LOGIC_VECTOR(tmp);
+ end OREAD;
+
+ procedure OWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
+ JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is
+ begin
+ OWRITE(L, STD_ULOGIC_VECTOR(VALUE), JUSTIFIED, FIELD);
+ end OWRITE;
+
+
+--synopsys synthesis_on
+end STD_LOGIC_TEXTIO;
diff --git a/libraries/synopsys/std_logic_unsigned.vhdl b/libraries/synopsys/std_logic_unsigned.vhdl
new file mode 100644
index 000000000..3e29847a8
--- /dev/null
+++ b/libraries/synopsys/std_logic_unsigned.vhdl
@@ -0,0 +1,329 @@
+--------------------------------------------------------------------------
+-- --
+-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. --
+-- All rights reserved. --
+-- --
+-- This source file may be used and distributed without restriction --
+-- provided that this copyright statement is not removed from the file --
+-- and that any derivative work contains this copyright notice. --
+-- --
+-- Package name: STD_LOGIC_UNSIGNED --
+-- --
+-- --
+-- Date: 09/11/92 KN --
+-- 10/08/92 AMT --
+-- --
+-- Purpose: --
+-- A set of unsigned arithemtic, conversion, --
+-- and comparision functions for STD_LOGIC_VECTOR. --
+-- --
+-- Note: comparision of same length discrete arrays is defined --
+-- by the LRM. This package will "overload" those --
+-- definitions --
+-- --
+--------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+package STD_LOGIC_UNSIGNED is
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
+ function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
+ function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
+ function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
+ function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
+ function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+
+ function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER;
+
+-- remove this since it is already in std_logic_arith
+-- function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR;
+
+end STD_LOGIC_UNSIGNED;
+
+
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+package body STD_LOGIC_UNSIGNED is
+
+
+ function maximum(L, R: INTEGER) return INTEGER is
+ begin
+ if L > R then
+ return L;
+ else
+ return R;
+ end if;
+ end;
+
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR (length-1 downto 0);
+ begin
+ result := UNSIGNED(L) + UNSIGNED(R);-- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := UNSIGNED(L) + R;-- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L + UNSIGNED(R);-- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := UNSIGNED(L) + R;-- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to plus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L + UNSIGNED(R);-- pragma label plus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR (length-1 downto 0);
+ begin
+ result := UNSIGNED(L) - UNSIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := UNSIGNED(L) - R; -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L - UNSIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR is
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := UNSIGNED(L) - R;
+ return std_logic_vector(result);
+ end;
+
+ function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to minus
+ variable result : STD_LOGIC_VECTOR (R'range);
+ begin
+ result := L - UNSIGNED(R); -- pragma label minus
+ return std_logic_vector(result);
+ end;
+
+ function "+"(L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ variable result : STD_LOGIC_VECTOR (L'range);
+ begin
+ result := + UNSIGNED(L);
+ return std_logic_vector(result);
+ end;
+
+ function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ -- pragma label_applies_to mult
+ constant length: INTEGER := maximum(L'length, R'length);
+ variable result : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0);
+ begin
+ result := UNSIGNED(L) * UNSIGNED(R); -- pragma label mult
+ return std_logic_vector(result);
+ end;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to lt
+ constant length: INTEGER := maximum(L'length, R'length);
+ begin
+ return UNSIGNED(L) < UNSIGNED(R); -- pragma label lt
+ end;
+
+ function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to lt
+ begin
+ return UNSIGNED(L) < R; -- pragma label lt
+ end;
+
+ function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to lt
+ begin
+ return L < UNSIGNED(R); -- pragma label lt
+ end;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return UNSIGNED(L) <= UNSIGNED(R); -- pragma label leq
+ end;
+
+ function "<="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return UNSIGNED(L) <= R; -- pragma label leq
+ end;
+
+ function "<="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to leq
+ begin
+ return L <= UNSIGNED(R); -- pragma label leq
+ end;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return UNSIGNED(L) > UNSIGNED(R); -- pragma label gt
+ end;
+
+ function ">"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return UNSIGNED(L) > R; -- pragma label gt
+ end;
+
+ function ">"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to gt
+ begin
+ return L > UNSIGNED(R); -- pragma label gt
+ end;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return UNSIGNED(L) >= UNSIGNED(R); -- pragma label geq
+ end;
+
+ function ">="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return UNSIGNED(L) >= R; -- pragma label geq
+ end;
+
+ function ">="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ -- pragma label_applies_to geq
+ begin
+ return L >= UNSIGNED(R); -- pragma label geq
+ end;
+
+ function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = UNSIGNED(R);
+ end;
+
+ function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ begin
+ return UNSIGNED(L) = R;
+ end;
+
+ function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L = UNSIGNED(R);
+ end;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= UNSIGNED(R);
+ end;
+
+ function "/="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN is
+ begin
+ return UNSIGNED(L) /= R;
+ end;
+
+ function "/="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN is
+ begin
+ return L /= UNSIGNED(R);
+ end;
+
+ function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER is
+ variable result : UNSIGNED(ARG'range);
+ begin
+ result := UNSIGNED(ARG);
+ return CONV_INTEGER(result);
+ end;
+ function SHL(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR(SHL(UNSIGNED(ARG),UNSIGNED(COUNT)));
+ end;
+
+ function SHR(ARG:STD_LOGIC_VECTOR;COUNT: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin
+ return STD_LOGIC_VECTOR(SHR(UNSIGNED(ARG),UNSIGNED(COUNT)));
+ end;
+
+
+-- remove this since it is already in std_logic_arith
+ --function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
+ --variable result1 : UNSIGNED (SIZE-1 downto 0);
+ --variable result2 : STD_LOGIC_VECTOR (SIZE-1 downto 0);
+ --begin
+ --result1 := CONV_UNSIGNED(ARG,SIZE);
+ --return std_logic_vector(result1);
+ --end;
+
+
+end STD_LOGIC_UNSIGNED;
+
+
diff --git a/libraries/vital2000/memory_b.vhdl b/libraries/vital2000/memory_b.vhdl
new file mode 100644
index 000000000..0376ee4d3
--- /dev/null
+++ b/libraries/vital2000/memory_b.vhdl
@@ -0,0 +1,7151 @@
+-- ----------------------------------------------------------------------------
+-- Title : Standard VITAL Memory Package
+-- :
+-- Library : Vital_Memory
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- : Ekambaram Balaji, LSI Logic Corporation
+-- : Jose De Castro, Consultant
+-- : Prakash Bare, GDA Technologies
+-- : William Yam, LSI Logic Corporation
+-- : Dennis Brophy, Model Technology
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC memory models.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Ver:|Auth:| Date:| Changes Made:
+-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal
+-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme
+-- 0.3 | jdc |090297| Extensive updates for TAG review (functional)
+-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable
+-- | | | Added interface of VitalMemoryCrossPorts() &
+-- | | | VitalMemoryViolation().
+-- 0.5 | jdc |092997| Completed naming changes thoughout package body.
+-- | | | Testing with simgle port test model looks ok.
+-- 0.6 | jdc |121797| Major updates to the packages:
+-- | | | - Implement VitalMemoryCrossPorts()
+-- | | | - Use new VitalAddressValueType
+-- | | | - Use new VitalCrossPortModeType enum
+-- | | | - Overloading without SamePort args
+-- | | | - Honor erroneous address values
+-- | | | - Honor ports disabled with 'Z'
+-- | | | - Implement implicit read 'M' table symbol
+-- | | | - Cleanup buses to use (H DOWNTO L)
+-- | | | - Message control via MsgOn,HeaderMsg,PortName
+-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases
+-- 0.7 | jdc |052698| Bug fixes to the packages:
+-- | | | - Fix failure with negative Address values
+-- | | | - Added debug messages for VMT table search
+-- | | | - Remove 'S' for action column (only 's')
+-- | | | - Remove 's' for response column (only 'S')
+-- | | | - Remove 'X' for action and response columns
+-- 0.8 | jdc |061298| Implemented VitalMemoryViolation()
+-- | | | - Minimal functionality violation tables
+-- | | | - Missing:
+-- | | | - Cannot handle wide violation variables
+-- | | | - Cannot handle sub-word cases
+-- | | | Fixed IIC version of MemoryMatch
+-- | | | Fixed 'M' vs 'm' switched on debug output
+-- | | | TO BE DONE:
+-- | | | - Implement 'd' corrupting a single bit
+-- | | | - Implement 'D' corrupting a single bit
+-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType
+-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType
+-- 0.11|eb/sc|081798| Added overloaded function interface for
+-- | | | VitalDeclareMemory
+-- 0.14| jdc |113198| Merging of memory functionality and version
+-- | | | 1.4 9/17/98 of timing package from Prakash
+-- 0.15| jdc |120198| Major development of VMV functionality
+-- 0.16| jdc |120298| Complete VMV functionlality for initial testing
+-- | | | - New ViolationTableCorruptMask() procedure
+-- | | | - New MemoryTableCorruptMask() procedure
+-- | | | - HandleMemoryAction():
+-- | | | - Removed DataOutBus bogus output
+-- | | | - Replaced DataOutTmp with DataInTmp
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'c','l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit
+-- | | | - HandleDataAction():
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'L','D','E' to use HighBit, LowBit
+-- | | | - MemoryTableLookUp():
+-- | | | - Added MsgOn table debug output
+-- | | | - Uses new MemoryTableCorruptMask()
+-- | | | - ViolationTableLookUp():
+-- | | | - Uses new ViolationTableCorruptMask()
+-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType,
+-- | | | VitalMemoryViolationTableType data
+-- | | | types but not used yet (need to discuss)
+-- | | | - Added overload for VitalMemoryViolation()
+-- | | | which does not have array flags
+-- | | | - Bug fixes for VMV functionality:
+-- | | | - ViolationTableLookUp() not handling '-' in
+-- | | | scalar violation matching
+-- | | | - VitalMemoryViolation() now normalizes
+-- | | | VFlagArrayTmp'LEFT as LSB before calling
+-- | | | ViolationTableLookUp() for proper scanning
+-- | | | - ViolationTableCorruptMask() had to remove
+-- | | | normalization of CorruptMaskTmp and
+-- | | | ViolMaskTmp for proper MSB:LSB corruption
+-- | | | - HandleMemoryAction(), HandleDataAction()
+-- | | | - Removed 'D','E' since not being used
+-- | | | - Use XOR instead of OR for corrupt masks
+-- | | | - Now 'd' is sensitive to HighBit, LowBit
+-- | | | - Fixed LowBit overflow in bit writeable case
+-- | | | - MemoryTableCorruptMask()
+-- | | | - ViolationTableCorruptMask()
+-- | | | - VitalMemoryTable()
+-- | | | - VitalMemoryCrossPorts()
+-- | | | - Fixed VitalMemoryViolation() failing on
+-- | | | error AddressValue from earlier VMT()
+-- | | | - Minor cleanup of code formatting
+-- 0.18| jdc |032599| - In VitalDeclareMemory()
+-- | | | - Added BinaryLoadFile formal arg and
+-- | | | modified LoadMemory() to handle bin
+-- | | | - Added NOCHANGE to VitalPortFlagType
+-- | | | - For VitalCrossPortModeType
+-- | | | - Added CpContention enum
+-- | | | - In HandleDataAction()
+-- | | | - Set PortFlag := NOCHANGE for 'S'
+-- | | | - In HandleMemoryAction()
+-- | | | - Set PortFlag := NOCHANGE for 's'
+-- | | | - In VitalMemoryTable() and
+-- | | | VitalMemoryViolation()
+-- | | | - Honor PortFlag = NOCHANGE returned
+-- | | | from HandleMemoryAction()
+-- | | | - In VitalMemoryCrossPorts()
+-- | | | - Fixed Address = AddressJ for all
+-- | | | conditions of DoWrCont & DoCpRead
+-- | | | - Handle CpContention like WrContOnly
+-- | | | under CpReadOnly conditions, with
+-- | | | associated memory message changes
+-- | | | - Handle PortFlag = NOCHANGE like
+-- | | | PortFlag = READ for actions
+-- | | | - Modeling change:
+-- | | | - Need to init PortFlag every delta
+-- | | | PortFlag_A := (OTHES => UNDEF);
+-- | | | - Updated InternalTimingCheck code
+-- 0.19| jdc |042599| - Fixes for bit-writeable cases
+-- | | | - Check PortFlag after HandleDataAction
+-- | | | in VitalMemoryViolation()
+-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash
+-- | | | and Willian:
+-- | | | VitalMemorySchedulePathDelay()
+-- | | | VitalMemoryExpandPortFlag()
+-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums,
+-- | | | added new CpReadAndReadContention.
+-- | | | - Fixed VitalMemoryCrossPorts() parameter
+-- | | | SamePortFlag to INOUT so that it can
+-- | | | set CORRUPT or READ value.
+-- | | | - Fixed VitalMemoryTable() where PortFlag
+-- | | | setting by HandleDataAction() is being
+-- | | | ignored when HandleMemoryAction() sets
+-- | | | PortFlagTmp to NOCHANGE.
+-- | | | - Fixed VitalMemoryViolation() to set
+-- | | | all bits of PortFlag when violating.
+-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData
+-- | | | checks whether the previous state is HIGHZ.
+-- | | | If yes then portFlag should be NOCHANGE
+-- | | | for VMPD to ignore IORetain corruption.
+-- | | | The idea is that the first Z should be
+-- | | | propagated but later ones should be ignored.
+-- | | |
+-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99
+-- | | | - Changed VitalPortFlagType to record of
+-- | | | new VitalPortStateType to hold current,
+-- | | | previous values and separate disable.
+-- | | | Also created VitalDefaultPortFlag const.
+-- | | | Removed usage of PortFlag NOCHANGE
+-- | | | - VitalMemoryTable() changes:
+-- | | | Optimized return when all curr = prev
+-- | | | AddressValue is now INOUT to optimize
+-- | | | Transfer PF.MemoryCurrent to MemoryPrevious
+-- | | | Transfer PF.DataCurrent to DataPrevious
+-- | | | Reset PF.OutputDisable to FALSE
+-- | | | Expects PortFlag init in declaration
+-- | | | No need to init PortFlag every delta
+-- | | | - VitalMemorySchedulePathDelay() changes:
+-- | | | Initialize with VitalDefaultPortFlag
+-- | | | Check PortFlag.OutputDisable
+-- | | | - HandleMemoryAction() changes:
+-- | | | Set value of PortFlag.MemoryCurrent
+-- | | | Never set PortFlag.OutputDisable
+-- | | | - HandleDataAction() changes:
+-- | | | Set value of PortFlag.DataCurrent
+-- | | | Set PortFlag.DataCurrent for HIGHZ
+-- | | | - VitalMemoryCrossPorts() changes:
+-- | | | Check/set value of PF.MemoryCurrent
+-- | | | Check value of PF.OutputDisable
+-- | | | - VitalMemoryViolation() changes:
+-- | | | Fixed bug - not reading inout PF value
+-- | | | Clean up setting of PortFlag
+-- 0.24| jdc |100899| - Modified update of PF.OutputDisable
+-- | | | to correctly accomodate 2P1W1R case:
+-- | | | the read port should not exhibit
+-- | | | IO retain corrupt when reading
+-- | | | addr unrelated to addr being written.
+-- 0.25| jdc |100999| - VitalMemoryViolation() change:
+-- | | | Fixed bug with RDNWR mode incorrectly
+-- | | | updating the PF.OutputDisable
+-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change:
+-- | | | Fixed bugs with update of PF
+-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change:
+-- | | | Added DoRdWrCont message (ErrMcpRdWrCo,
+-- | | | Memory cross port read/write data only
+-- | | | contention)
+-- | | | - VitalMemoryTable() change:
+-- | | | Set PF.OutputDisable := TRUE for the
+-- | | | optimized cases.
+-- 0.28| pb |112399| - Added 8 VMPD procedures for vector
+-- | | | PathCondition support. Now the total
+-- | | | number of overloadings for VMPD is 24.
+-- | | | - Number of overloadings for SetupHold
+-- | | | procedures increased to 5. Scalar violations
+-- | | | are not supported anymore. Vector checkEnabled
+-- | | | support is provided through the new overloading
+-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction()
+-- | | | Reinstated 'D' and 'E' actions but
+-- | | | with new PortFlagType
+-- | | | - Updated file handling syntax, must compile
+-- | | | with -93 syntax now.
+-- 0.30| jdc |022300| - Formated for 80 column max width
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.Vital_Timing.all;
+USE IEEE.Vital_Primitives.all;
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+-- ----------------------------------------------------------------------------
+PACKAGE BODY Vital_Memory IS
+
+-- ----------------------------------------------------------------------------
+-- Timing Section
+-- ----------------------------------------------------------------------------
+
+FILE LogFile : TEXT OPEN write_mode IS "delayLog";
+FILE Output : TEXT OPEN write_mode IS "STD_OUTPUT";
+
+-- Added for turning off the debug msg..
+CONSTANT PrintDebugMsg : STD_ULOGIC := '0';
+ -- '0' - don't print in STD OUTPUT
+ -- '1' - print in STD OUTPUT
+
+-- Type and constant definitions for type conversion.
+TYPE MVL9_TO_CHAR_TBL IS ARRAY (STD_ULOGIC) OF character;
+
+--constant MVL9_to_char: MVL9_TO_CHAR_TBL := "UX01ZWLH-";
+CONSTANT MVL9_to_char: MVL9_TO_CHAR_TBL := "XX01ZX010";
+
+-- ----------------------------------------------------------------------------
+-- STD_LOGIC WRITE UTILITIES
+-- ----------------------------------------------------------------------------
+PROCEDURE WRITE(
+ l : INOUT line;
+ val : IN std_logic_vector;
+ justify : IN side := right;
+ field : IN width := 0
+) IS
+ VARIABLE invect : std_logic_vector(val'LENGTH DOWNTO 1);
+ VARIABLE ins : STRING(val'LENGTH DOWNTO 1);
+BEGIN
+ invect := val;
+ FOR I IN invect'length DOWNTO 1 LOOP
+ ins(I) := MVL9_to_char(invect(I));
+ END LOOP;
+ WRITE(L, ins, justify, field);
+END;
+
+PROCEDURE WRITE(
+ l : INOUT line;
+ val : IN std_ulogic;
+ justify : IN side := right;
+ field : in width := 0
+) IS
+ VARIABLE ins : CHARACTER;
+BEGIN
+ ins := MVL9_to_char(val);
+ WRITE(L, ins, justify, field);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE DelayValue(
+ InputTime : IN TIME ;
+ outline : INOUT LINE
+) IS
+ CONSTANT header : STRING := "TIME'HIGH";
+BEGIN
+ IF(InputTime = TIME'HIGH) THEN
+ WRITE(outline, header);
+ ELSE
+ WRITE(outline, InputTime);
+ END IF;
+END DelayValue;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintScheduleDataArray (
+ ScheduleDataArray : IN VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ VARIABLE value : TIME;
+ CONSTANT empty : STRING := " ";
+ CONSTANT header1 : STRING := "i Age PropDly RetainDly";
+ CONSTANT header2 : STRING := "i Sc.Value Output Lastvalue Sc.Time";
+BEGIN
+ WRITE (outline1, empty);
+ WRITE (outline1, NOW);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE (outline1, header1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ WRITE (outline1, i );
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).InputAge, outline1);
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).PropDelay, outline1);
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).OutputRetainDelay, outline1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ END LOOP;
+ WRITE (outline1, header2);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ WRITE (outline1, i );
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).ScheduleValue);
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).OutputData);
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).LastOutputValue );
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).ScheduleTime, outline1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ END LOOP;
+ WRITE (outline1, empty);
+ WRITE (outline2, empty);
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (Output, outline2);
+ END IF;
+END PrintScheduleDataArray;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintArcType (
+ ArcType : IN VitalMemoryArcType
+) IS
+ VARIABLE outline1, outline2 : LINE;
+ CONSTANT empty : STRING := " ";
+ CONSTANT cross : STRING := "CrossArc";
+ CONSTANT para : STRING := "ParallelArc";
+ CONSTANT sub : STRING := "SubWordArc";
+ CONSTANT Header1 : STRING := "Path considered @ ";
+ CONSTANT Header2 : STRING := " is ";
+BEGIN
+ WRITELINE (LogFile, outline1);
+ WRITE (outline1, header1);
+ WRITE (outline1, NOW);
+ WRITE (outline1, empty);
+ WRITE (outline1, header2);
+ WRITE (outline1, empty);
+ case ArcType is
+ WHEN CrossArc =>
+ WRITE (outline1, cross);
+ WHEN ParallelArc =>
+ WRITE (outline1, para);
+ WHEN SubwordArc =>
+ WRITE (outline1, sub);
+ END CASE;
+ outline2 := outline1 ;
+ -- Appears on STD OUT
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (Output, outline1);
+ END IF;
+ WRITELINE (LogFile, outline2);
+END PrintArcType;
+
+-- ----------------------------------------------------------------------------
+-- This returns the value picked from the delay array
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintDelay (
+ outbitpos : IN INTEGER;
+ InputArrayLow : IN INTEGER;
+ InputArrayHigh : IN INTEGER;
+ debugprop : IN VitalTimeArrayT;
+ debugretain : IN VitalTimeArrayT
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ VARIABLE outline3 : LINE;
+ VARIABLE outline4 : LINE;
+ VARIABLE outline5 : LINE;
+ VARIABLE outline6 : LINE;
+ CONSTANT empty : STRING := " ";
+ CONSTANT empty5 : STRING := " ";
+ CONSTANT header1 : STRING := "Prop. delays : ";
+ CONSTANT header2 : STRING := "Retain delays : ";
+ CONSTANT header3 : STRING := "output bit : ";
+BEGIN
+ WRITE(outline1, header3);
+ WRITE(outline1, outbitpos);
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+ WRITE(outline1, header1);
+ WRITE (outline1, empty5);
+ FOR i IN InputArrayHigh DOWNTO InputArrayLow LOOP
+ DelayValue(debugprop(i), outline1);
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+ WRITE(outline1, header2);
+ WRITE (outline1, empty5);
+ FOR i in InputArrayHigh DOWNTO InputArrayLow LOOP
+ DelayValue(debugretain(i), outline1);
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+END PrintDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE DebugMsg1 IS
+ CONSTANT header1:STRING:= "******************************************";
+ CONSTANT header2 :STRING:="Entering the process because of an i/p change";
+ variable outline1, outline2 : LINE;
+BEGIN
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE(outline1, header2);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+END DebugMsg1;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ScheduleDebugMsg IS
+ CONSTANT header1 : STRING := "******************************************";
+ CONSTANT header2 : STRING := "Finished executing all the procedures";
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+BEGIN
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header2);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+END ScheduleDebugMsg;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputName(
+ InputSignalName : IN STRING
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ CONSTANT header1 : STRING := "***Changing input is ";
+ CONSTANT header2 : STRING := "(";
+ CONSTANT header3 : STRING := ")";
+ CONSTANT header4 : STRING := "****";
+ CONSTANT header5 : STRING := "******************************************";
+ CONSTANT header6 : STRING:="Entering the process because of an i/p change";
+ CONSTANT empty : STRING := " ";
+BEGIN
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header6);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header1);
+ WRITE(outline1, InputSignalName);
+ WRITE(outline1, empty);
+ WRITE(outline1, now);
+ WRITE(outline1, empty);
+ WRITE(outline1, header4);
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+END PrintInputName;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputChangeTime(
+ ChangeTimeArray : IN VitalTimeArrayT
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ CONSTANT header5 : STRING := "*************************************";
+ CONSTANT header6 : STRING:="ChangeTime Array : ";
+ CONSTANT empty : STRING := " ";
+BEGIN
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header6);
+ FOR i in ChangeTimeArray'range LOOP
+ WRITE(outline1, ChangeTimeArray(i));
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+END PrintInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputChangeTime(
+ ChangeTime : IN Time
+) IS
+ VARIABLE ChangeTimeArray : VitalTimeArrayT(0 DOWNTO 0);
+BEGIN
+ ChangeTimeArray(0) := ChangeTime;
+ PrintInputChangeTime(ChangeTimeArray);
+END PrintInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+-- for debug purpose
+CONSTANT MaxNoInputBits : INTEGER := 1000;
+
+TYPE VitalMemoryDelayType IS RECORD
+ PropDelay : TIME;
+ OutputRetainDelay : TIME;
+END RECORD;
+
+-- ----------------------------------------------------------------------------
+-- PROCEDURE: IntToStr
+--
+-- PARAMETERS: InputInt - Integer to be converted to String.
+-- ResultStr - String buffer for converted Integer
+-- AppendPos - Position in buffer to place result
+--
+-- DESCRIPTION: This procedure is used to convert an input integer
+-- into a string representation. The converted string
+-- may be placed at a specific position in the result
+-- buffer.
+--
+-- ----------------------------------------------------------------------------
+
+PROCEDURE IntToStr (
+ InputInt : IN INTEGER ;
+ ResultStr : INOUT STRING ( 1 TO 256) ;
+ AppendPos : INOUT NATURAL
+) IS
+ -- Look-up table. Given an int, we can get the character.
+ TYPE integer_table_type IS ARRAY (0 TO 9) OF CHARACTER ;
+ CONSTANT integer_table : integer_table_type :=
+ ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ;
+ -- Local variables used in this function.
+ VARIABLE inpVal : INTEGER := inputInt ;
+ VARIABLE divisor : INTEGER := 10 ;
+ VARIABLE tmpStrIndex : INTEGER := 1 ;
+ VARIABLE tmpStr : STRING ( 1 TO 256 ) ;
+BEGIN
+ IF ( inpVal = 0 ) THEN
+ tmpStr(tmpStrIndex) := integer_table ( 0 ) ;
+ tmpStrIndex := tmpStrIndex + 1 ;
+ ELSE
+ WHILE ( inpVal > 0 ) LOOP
+ tmpStr(tmpStrIndex) := integer_table (inpVal mod divisor);
+ tmpStrIndex := tmpStrIndex + 1 ;
+ inpVal := inpVal / divisor ;
+ END LOOP ;
+ END IF ;
+ IF (appendPos /= 1 ) THEN
+ resultStr(appendPos) := ',' ;
+ appendPos := appendPos + 1 ;
+ END IF ;
+
+ FOR i IN tmpStrIndex-1 DOWNTO 1 LOOP
+ resultStr(appendPos) := tmpStr(i) ;
+ appendPos := appendPos + 1 ;
+ END LOOP ;
+END IntToStr ;
+
+-- ----------------------------------------------------------------------------
+TYPE CheckType IS (
+ SetupCheck,
+ HoldCheck,
+ RecoveryCheck,
+ RemovalCheck,
+ PulseWidCheck,
+ PeriodCheck
+);
+
+TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+END RECORD;
+
+TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+
+-- last value, present value, edge symbol
+CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType :=
+ (
+ 'X' =>
+ ( 'X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE )
+ ),
+ '0' =>
+ ( 'X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE )
+ ),
+ '1' =>
+ ( 'X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE )
+ )
+ );
+
+-- ----------------------------------------------------------------------------
+FUNCTION Minimum (
+ CONSTANT t1, t2 : IN TIME
+) RETURN TIME IS
+BEGIN
+ IF (t1 < t2) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+END Minimum;
+
+-- ----------------------------------------------------------------------------
+FUNCTION Maximum (
+ CONSTANT t1, t2 : IN TIME
+) RETURN TIME IS
+BEGIN
+ IF (t1 < t2) THEN RETURN (t2); ELSE RETURN (t1); END IF;
+END Maximum;
+
+-- ----------------------------------------------------------------------------
+-- FUNCTION: VitalMemoryCalcDelay
+-- Description: Select Transition dependent Delay.
+-- Used internally by VitalMemorySelectDelay.
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryCalcDelay (
+ CONSTANT NewVal : IN STD_ULOGIC := 'X';
+ CONSTANT OldVal : IN STD_ULOGIC := 'X';
+ CONSTANT Delay : IN VitalDelayType01ZX
+) RETURN VitalMemoryDelayType IS
+ VARIABLE Result : VitalMemoryDelayType;
+BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(tr01);
+ WHEN 'Z' =>
+ Result.PropDelay := Delay(tr0Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr01), Delay(tr0Z));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr0X);
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(tr01);
+ WHEN 'Z' =>
+ Result.PropDelay := Delay(tr1Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr10), Delay(tr1Z));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr1X);
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(trZ0);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(trZ1);
+ WHEN 'Z' =>
+ Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z));
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(trZ1), Delay(trZ0));
+ END CASE;
+ Result.OutputRetainDelay := Delay(trZX);
+ WHEN OTHERS =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Maximum(Delay(tr10), Delay(trZ0));
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Maximum(Delay(tr01), Delay(trZ1));
+ WHEN 'Z' =>
+ Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z));
+ WHEN OTHERS =>
+ Result.PropDelay := Maximum(Delay(tr10), Delay(tr01));
+ END CASE;
+ Result.OutputRetainDelay := Minimum(Delay(tr1X), Delay(tr0X));
+ END CASE;
+ RETURN Result;
+END VitalMemoryCalcDelay;
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryCalcDelay (
+ CONSTANT NewVal : IN STD_ULOGIC := 'X';
+ CONSTANT OldVal : IN STD_ULOGIC := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+) RETURN VitalMemoryDelayType IS
+ VARIABLE Result : VitalMemoryDelayType;
+BEGIN
+CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' => Result.PropDelay := Delay(tr01);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr01), Delay(tr10));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr0Z);
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' => Result.PropDelay := Delay(tr01);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr10), Delay(tr01));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr1Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Maximum(Delay(tr10),Delay(tr01));
+ Result.OutputRetainDelay := Minimum(Delay(tr1Z),Delay(tr0Z));
+ END CASE;
+ RETURN Result;
+END VitalMemoryCalcDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ VARIABLE NumBitsPerSubword : INTEGER
+) IS
+ VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0);
+ VARIABLE InSignalNorm : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0);
+ VARIABLE ChangeTimeNorm : VitalTimeArrayT(InputSignal'LENGTH-1 downto 0);
+ VARIABLE BitsPerWord : INTEGER;
+BEGIN
+ LastInputValue := InputSignal'LAST_VALUE;
+ IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN
+ BitsPerWord := InputSignal'LENGTH;
+ ELSE
+ BitsPerWord := NumBitsPerSubword;
+ END IF;
+
+ FOR i IN InSignalNorm'RANGE LOOP
+ IF (InSignalNorm(i) /= LastInputValue(i)) THEN
+ ChangeTimeNorm(i/BitsPerWord) := NOW - InputSignal'LAST_EVENT;
+ ELSE
+ ChangeTimeNorm(i/BitsPerWord) := InputChangeTimeArray(i);
+ END IF;
+ END LOOP;
+
+ FOR i IN ChangeTimeNorm'RANGE LOOP
+ ChangeTimeNorm(i) := ChangeTimeNorm(i/BitsPerword);
+ END LOOP;
+
+ InputChangeTimeArray := ChangeTimeNorm;
+
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTimeArray);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryUpdateInputChangeTime
+-- Description: Time since previous event for each bit of the input
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR
+) IS
+ VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'RANGE) ;
+BEGIN
+ LastInputValue := InputSignal'LAST_VALUE;
+ FOR i IN InputSignal'RANGE LOOP
+ IF (InputSignal(i) /= LastInputValue(i)) THEN
+ InputChangeTimeArray(i) := NOW - InputSignal'LAST_EVENT;
+ END IF;
+ END LOOP;
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTimeArray);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTime : INOUT TIME;
+ SIGNAL InputSignal : IN STD_ULOGIC
+) IS
+BEGIN
+ InputChangeTime := NOW - InputSignal'LAST_EVENT;
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTime);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryExpandPortFlag (
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT NumBitsPerSubword : IN INTEGER;
+ VARIABLE ExpandedPortFlag : OUT VitalPortFlagVectorType
+) IS
+ VARIABLE PortFlagNorm : VitalPortFlagVectorType(
+ PortFlag'LENGTH-1 downto 0) := PortFlag;
+ VARIABLE ExpandedPortFlagNorm : VitalPortFlagVectorType(
+ ExpandedPortFlag'LENGTH-1 downto 0);
+ VARIABLE SubwordIndex : INTEGER;
+BEGIN
+ FOR Index IN INTEGER RANGE 0 to ExpandedPortFlag'LENGTH-1 LOOP
+ IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN
+ SubwordIndex := 0;
+ ELSE
+ SubwordIndex := Index / NumBitsPerSubword;
+ END IF;
+ ExpandedPortFlagNorm(Index) := PortFlagNorm(SubWordIndex);
+ END LOOP;
+ ExpandedPortFlag := ExpandedPortFlagNorm;
+END VitalMemoryExpandPortFlag;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySelectDelay
+-- Description : Select Propagation Delay. Used internally by
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01ZX
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE CurRetainDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01ZX(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):= ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND
+ (OutputRetainFlag = FALSE ));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH - 1 ;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ (CurPropDelay,CurRetainDelay) :=
+ VitalMemoryCalcDelay (
+ NewValue, OldValue, DelayArrayNorm(DelayArrayIndex)
+ );
+ IF (OutputRetainFlag = FALSE) THEN
+ CurRetainDelay := TIME'HIGH;
+ END IF;
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := CurRetainDelay;
+
+ IF ArcType = CrossArc THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns)THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge)THEN
+ PropDelay := CurPropDelay;
+ RetainDelay := CurRetainDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge)THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ IF (OutputRetainFlag = TRUE) THEN
+ IF (CurRetainDelay < RetainDelay) THEN
+ RetainDelay := CurRetainDelay;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos,InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01Z
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE CurRetainDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01Z(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND
+ (OutputRetainFlag = FALSE));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ (CurPropDelay, CurRetainDelay) :=
+ VitalMemoryCalcDelay (
+ NewValue, OldValue, DelayArrayNorm(DelayArrayIndex)
+ );
+ IF (OutputRetainFlag = FALSE) THEN
+ CurRetainDelay := TIME'HIGH;
+ END IF;
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := CurRetainDelay;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ RetainDelay := CurRetainDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ IF (OutputRetainFlag = TRUE) THEN
+ IF (CurRetainDelay < RetainDelay) THEN
+ RetainDelay := CurRetainDelay;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE CurPathDelay : VitalMemoryDelayType;
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):= InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ CurPropDelay:= VitalCalcDelay (NewValue,
+ OldValue, DelayArrayNorm(DelayArrayIndex));
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := TIME'HIGH;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0) := InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType(
+ PathDelayArray'LENGTH-1 downto 0) := PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0) := ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ CurPropDelay := VitalCalcDelay (NewValue,
+ OldValue, DelayArrayNorm(DelayArrayIndex));
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := TIME'HIGH;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryInitPathDelay
+-- Description: To initialize Schedule Data structure for an
+-- output.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword
+) IS
+BEGIN
+ -- Initialize the ScheduleData Structure.
+ FOR i IN OutputDataArray'RANGE LOOP
+ ScheduleDataArray(i).OutputData := OutputDataArray(i);
+ ScheduleDataArray(i).PropDelay := TIME'HIGH;
+ ScheduleDataArray(i).OutputRetainDelay := TIME'HIGH;
+ ScheduleDataArray(i).InputAge := TIME'HIGH;
+ ScheduleDataArray(i).NumBitsPerSubWord := NumBitsPerSubWord;
+
+ -- Update LastOutputValue of Output if the Output has
+ -- already been scheduled.
+ IF ((ScheduleDataArray(i).ScheduleValue /= OutputDataArray(i)) AND
+ (ScheduleDataArray(i).ScheduleTime <= NOW)) THEN
+ ScheduleDataArray(i).LastOutputValue
+ := ScheduleDataArray(i).ScheduleValue;
+ END IF;
+ END LOOP;
+
+ -- for debug purpose
+ DebugMsg1;
+ PrintScheduleDataArray(ScheduleDataArray);
+
+END VitalMemoryInitPathDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ VARIABLE OutputData : IN STD_ULOGIC
+) IS
+ VARIABLE ScheduledataArray: VitalMemoryScheduleDataVectorType
+ (0 downto 0);
+ VARIABLE OutputDataArray : STD_LOGIC_VECTOR(0 downto 0);
+BEGIN
+ ScheduledataArray(0) := ScheduleData;
+ OutputDataArray(0) := OutputData;
+ VitalMemoryInitPathDelay (
+ ScheduleDataArray => ScheduleDataArray,
+ OutputDataArray => OutputDataArray,
+ NumBitsPerSubWord => DefaultNumBitsPerSubword
+ );
+
+ -- for debug purpose
+ DebugMsg1;
+ PrintScheduleDataArray( ScheduleDataArray);
+
+END VitalMemoryInitPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryAddPathDelay
+-- Description: Declare a path for one scalar/vector input to
+-- the output for which Schedule Data has been
+-- initialized previously.
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- #1
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #2
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray
+ );
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #3
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR Mem400
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #4
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+
+ ScheduleDataArray(0) := ScheduleData;
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #5
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #6
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #7
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #8
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #9
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #10
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray: INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+)IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #11
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #12
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #13
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01Z(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #14
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #15
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm : VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0);
+ VARIABLE PathConditionArrayExp : VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #16
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ NumBitsPerSubword := ScheduleDataArray(0).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray,
+ InputSignal,
+ NumBitsPerSubword
+ );
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #17
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray,
+ InputSignal,
+ NumBitsPerSubword
+ );
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #18
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+VARIABLE NumBitsPerSubword : INTEGER;
+VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0);
+VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #19
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01ZX(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #20
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #21
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #22
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #23
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #24
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySchedulePathDelay
+-- Description: Schedule Output after Propagation Delay selected
+-- by checking all the paths added thru'
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+BEGIN
+ IF (PortFlag.OutputDisable /= TRUE) THEN
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ PropDelay := ScheduleDataArray(i).PropDelay;
+ RetainDelay := ScheduleDataArray(i).OutputRetainDelay;
+
+ NEXT WHEN PropDelay = TIME'HIGH;
+
+ Age := ScheduleDataArray(i).InputAge;
+ Data := ScheduleDataArray(i).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay) THEN
+ OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age);
+ ScheduleDataArray(i).ScheduleValue := Data;
+ ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySchedulePathDelay
+-- Description: Schedule Output after Propagation Delay selected
+-- by checking all the paths added thru'
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+ VARIABLE ExpandedPortFlag :
+ VitalPortFlagVectorType(ScheduleDataArray'RANGE);
+ VARIABLE NumBitsPerSubword : INTEGER;
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ VitalMemoryExpandPortFlag( PortFlag, NumBitsPerSubword, ExpandedPortFlag );
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ NEXT WHEN ExpandedPortFlag(i).OutputDisable = TRUE;
+
+ PropDelay := ScheduleDataArray(i).PropDelay;
+ RetainDelay := ScheduleDataArray(i).OutputRetainDelay;
+
+ NEXT WHEN PropDelay = TIME'HIGH;
+
+ Age := ScheduleDataArray(i).InputAge;
+ Data := ScheduleDataArray(i).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay) THEN
+ OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age);
+ ScheduleDataArray(i).ScheduleValue := Data;
+ ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END LOOP;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_ULOGIC;
+ CONSTANT OutputSignalName: IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+ VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType (0 downto 0);
+BEGIN
+ IF (PortFlag.OutputDisable /= TRUE) THEN
+ ScheduledataArray(0) := ScheduleData;
+ PropDelay := ScheduleDataArray(0).PropDelay;
+ RetainDelay := ScheduleDataArray(0).OutputRetainDelay;
+ Age := ScheduleDataArray(0).InputAge;
+ Data := ScheduleDataArray(0).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay and PropDelay /= TIME'HIGH) THEN
+ OutSignal <= TRANSPORT OutputMap(Data) AFTER (PropDelay - Age);
+ ScheduleDataArray(0).ScheduleValue := Data;
+ ScheduleDataArray(0).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END IF;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure : InternalTimingCheck
+-- ----------------------------------------------------------------------------
+PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+) IS
+ VARIABLE bias : TIME;
+ VARIABLE actualObsTime : TIME;
+ VARIABLE BC : TIME;
+ VARIABLE Message :LINE;
+BEGIN
+ -- Check SETUP constraint
+ IF (RefEdge) THEN
+ IF (SetupEn) THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := SetupLow;
+ -- start of new code IR245-246
+ BC := HoldHigh;
+ -- end of new code IR245-246
+ WHEN '1' =>
+ CheckInfo.ExpTime := SetupHigh;
+ -- start of new code IR245-246
+ BC := HoldLow;
+ -- end of new code IR245-246
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ -- start of new code IR245-246
+ BC := Maximum(HoldHigh,HoldLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation :=
+ ((CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))));
+ -- start of new code IR245-246
+ IF (CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ ELSE
+ CheckInfo.CheckKind := SetupCheck;
+ END IF;
+ -- end of new code IR245-246
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF (TestEvent) THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := HoldHigh;
+ -- new code for unnamed IR
+ CheckInfo.State := '1';
+ -- start of new code IR245-246
+ BC := SetupLow;
+ -- end of new code IR245-246
+ WHEN '1' =>
+ CheckInfo.ExpTime := HoldLow;
+ -- new code for unnamed IR
+ CheckInfo.State := '0';
+ -- start of new code IR245-246
+ BC := SetupHigh;
+ -- end of new code IR245-246
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ -- start of new code IR245-246
+ BC := Maximum(SetupHigh,SetupLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation :=
+ ((CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))));
+ -- start of new code IR245-246
+ IF (CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ END IF;
+ -- end of new code IR245-246
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative
+ -- Note: bias may be negative or positive
+ IF MsgOn AND CheckInfo.Violation THEN
+ -- modified the code for correct reporting of violation in case of
+ -- order of signals being reversed because of internal delays
+ -- new variable
+ actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay);
+ bias := TestDelay - RefDelay;
+ IF (actualObsTime < 0 ns) THEN -- It should be a setup check
+ IF ( CheckInfo.CheckKind = HoldCheck) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ END IF;
+ CheckInfo.ObsTime := -actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE -- It should be a hold check
+ IF (CheckInfo.CheckKind = SetupCheck) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := HoldHigh;
+ CheckInfo.State := '1';
+ WHEN '1' =>
+ CheckInfo.ExpTime := HoldLow;
+ CheckInfo.State := '0';
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ END IF;
+ CheckInfo.ObsTime := actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+ END IF;
+END InternalTimingCheck;
+
+
+-- ----------------------------------------------------------------------------
+-- Setup and Hold Time Check Routine
+-- ----------------------------------------------------------------------------
+PROCEDURE TimingArrayIndex (
+ SIGNAL InputSignal : IN Std_logic_vector;
+ CONSTANT ArrayIndexNorm : IN INTEGER;
+ VARIABLE Index : OUT INTEGER
+) IS
+BEGIN
+ IF (InputSignal'LEFT > InputSignal'RIGHT) THEN
+ Index := ArrayIndexNorm + InputSignal'RIGHT;
+ ELSE
+ Index := InputSignal'RIGHT - ArrayIndexNorm;
+ END IF;
+END TimingArrayIndex;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT TestArrayIndex : IN INTEGER;
+ CONSTANT RefArrayIndex : IN INTEGER;
+ SIGNAL TestSignal : IN std_logic_vector;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+ VARIABLE i, j : INTEGER;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ TimingArrayIndex(TestSignal, TestArrayIndex, i);
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, i);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, i);
+ Write ( Message, ')');
+ END CASE;
+
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+
+ IF(RefSignal'LENGTH > 0) THEN
+ TimingArrayIndex(RefSignal, RefArrayIndex, j);
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, j);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, j);
+ Write ( Message, ')');
+ END CASE;
+ END IF;
+
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT TestArrayIndex : IN INTEGER;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") );
+ END CASE;
+
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, TestArrayIndex);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, TestArrayIndex);
+ Write ( Message, ')');
+ END CASE;
+
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryTimingDataInit
+RETURN VitalMemoryTimingDataType IS
+BEGIN
+ RETURN (FALSE, 'X', 0 ns, FALSE, 'X', 0 ns, FALSE,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalSetupHoldCheck
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayType;
+ CONSTANT SetupLow : IN VitalDelayType;
+ CONSTANT HoldHigh : IN VitalDelayType;
+ CONSTANT HoldLow : IN VitalDelayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE CheckEnScalar : BOOLEAN := FALSE;
+ VARIABLE ViolationInt : X01ArrayT(CheckEnabled'RANGE);
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef;
+ TimingData.HoldEn := EnableHoldOnRef;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.SetupEn := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTime := NOW;
+ END IF;
+
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ CheckEnScalar := TRUE;
+ END IF;
+ ViolationInt(i) := '0';
+ END LOOP;
+
+ IF (CheckEnScalar) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ ViolationInt(i) := 'X';
+ END IF;
+ END LOOP;
+ END IF;
+ END IF;
+ END IF;
+ Violation := ViolationInt;
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN TestSignal'RANGE LOOP
+ Violation(i) := '0';
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE ViolationInt : X01ArrayT(TestSignal'RANGE);
+ VARIABLE ViolationIntNorm: X01ArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE ViolationNorm : X01ArrayT(Violation'LENGTH-1 downto 0);
+ VARIABLE CheckEnInt : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE CheckEnIntNorm : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE CheckEnScalar : BOOLEAN := FALSE; --Mem IR 401
+ VARIABLE CheckEnabledNorm: VitalBoolArrayT(CheckEnabled'LENGTH-1 downto 0);
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ IF ArcType = CrossArc THEN
+ CheckEnScalar := FALSE;
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ CheckEnScalar := TRUE;
+ END IF;
+ END LOOP;
+ FOR i IN CheckEnInt'RANGE LOOP
+ CheckEnInt(i) := CheckEnScalar;
+ END LOOP;
+ ELSE
+ FOR i IN CheckEnIntNorm'RANGE LOOP
+ CheckEnIntNorm(i) := CheckEnabledNorm(i / NumBitsPerSubWord );
+ END LOOP;
+ CheckEnInt := CheckEnIntNorm;
+ END IF;
+
+ FOR i IN TestSignal'RANGE LOOP
+ ViolationInt(i) := '0';
+
+ IF (CheckEnInt(i)) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ ViolationInt(i) := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ IF (ViolationInt'LENGTH = Violation'LENGTH) THEN
+ Violation := ViolationInt;
+ ELSE
+ ViolationIntNorm := ViolationInt;
+ FOR i IN ViolationNorm'RANGE LOOP
+ ViolationNorm(i) := '0';
+ END LOOP;
+ FOR i IN ViolationIntNorm'RANGE LOOP
+ IF (ViolationIntNorm(i) = 'X') THEN
+ ViolationNorm(i / NumBitsPerSubWord) := 'X';
+ END IF;
+ END LOOP;
+ Violation := ViolationNorm;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0);
+ VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0);
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF (ArcType = CrossArc) THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF (RefEdge(i)) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF (TestEvent(i)) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN ViolationTest'RANGE LOOP
+ ViolationTest(i) := '0';
+ END LOOP;
+ FOR i IN ViolationRef'RANGE LOOP
+ ViolationRef(i) := '0';
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF ArcType = SubwordArc THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF TestEvent(i) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF RefEdge(RefBitLow) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ FOR j IN RefBitLow to RefBitHigh LOOP
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ ViolationTest(i) := 'X';
+ ViolationRef(j) := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+
+ END LOOP;
+ END LOOP;
+
+ IF (ArcType = CrossArc) THEN
+ Violation := ViolationRef;
+ ELSE
+ IF (Violation'LENGTH = ViolationRef'LENGTH) THEN
+ Violation := ViolationRef;
+ ELSE
+ Violation := ViolationTest;
+ END IF;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0);
+ VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0);
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE CheckEnNorm : VitalBoolArrayT(NumRefBits-1 downto 0)
+ := CheckEnabled;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF ArcType = CrossArc THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF RefEdge(i) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN ViolationTest'RANGE LOOP
+ ViolationTest(i) := '0';
+ END LOOP;
+ FOR i IN ViolationRef'RANGE LOOP
+ ViolationRef(i) := '0';
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF (ArcType = SubwordArc) THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(RefBitLow)) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ FOR j IN RefBitLow to RefBitHigh LOOP
+ IF (CheckEnNorm(j)) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+
+ IF (XOn) THEN
+ ViolationTest(i) := 'X';
+ ViolationRef(j) := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+ END LOOP;
+ END LOOP;
+
+ IF (ArcType = CrossArc) THEN
+ Violation := ViolationRef;
+ ELSE
+ IF (Violation'LENGTH = ViolationRef'LENGTH) THEN
+ Violation := ViolationRef;
+ ELSE
+ Violation := ViolationTest;
+ END IF;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+-- scalar violations not needed
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ Violation := '0';
+ FOR i IN TestSignal'RANGE LOOP
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF (ArcType = CrossArc) THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF (RefEdge(i)) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF (TestEvent(i)) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF (ArcType = SubwordArc) THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(RefBitLow)) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ Violation := '0';
+ FOR j IN RefBitLow to RefBitHigh LOOP
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+
+ END LOOP;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ CONSTANT Period : IN VitalDelayArraytype;
+ CONSTANT PulseWidthHigh : IN VitalDelayArraytype;
+ CONSTANT PulseWidthLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+) IS
+ VARIABLE TestDly : VitalDelayType;
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : VitalDelayType;
+ VARIABLE PulseTest : BOOLEAN;
+ VARIABLE PeriodTest: BOOLEAN;
+ VARIABLE TestValue : X01;
+BEGIN
+
+ -- Initialize for no violation
+ Violation := '0'; --MEM IR 402
+
+ FOR i IN TestSignal'RANGE LOOP
+ TestDly := Maximum(0 ns, TestDelay(i));
+ TestValue := To_X01(TestSignal(i));
+
+ IF (PeriodData(i).NotFirstFlag = FALSE) THEN
+ PeriodData(i).Rise := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Fall := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Last := TestValue;
+ PeriodData(i).NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- Violation := '0'; --Mem IR 402
+
+ -- No violation possible if no test signal change
+ NEXT WHEN (PeriodData(i).Last = TestValue);
+
+ -- record starting pulse times
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData(i).Rise;
+ PeriodData(i).Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData(i).Fall;
+ PeriodData(i).Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Fall;
+ CheckInfo.ExpTime := PulseWidthLow(i);
+ PulseTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Rise;
+ CheckInfo.ExpTime := PulseWidthHigh(i);
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF (PulseTest AND CheckEnabled) THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData(i).Last;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF (PeriodTest AND CheckEnabled) THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period(i);
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData(i).Last := TestValue;
+ END LOOP;
+
+END VitalMemoryPeriodPulseCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ CONSTANT Period : IN VitalDelayArraytype;
+ CONSTANT PulseWidthHigh : IN VitalDelayArraytype;
+ CONSTANT PulseWidthLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+)IS
+ VARIABLE TestDly : VitalDelayType;
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : VitalDelayType;
+ VARIABLE PulseTest : BOOLEAN;
+ VARIABLE PeriodTest: BOOLEAN;
+ VARIABLE TestValue : X01;
+BEGIN
+
+ FOR i IN TestSignal'RANGE LOOP
+ TestDly := Maximum(0 ns, TestDelay(i));
+ TestValue := To_X01(TestSignal(i));
+
+ IF (PeriodData(i).NotFirstFlag = FALSE) THEN
+ PeriodData(i).Rise := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Fall := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Last := TestValue;
+ PeriodData(i).NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ Violation(i) := '0';
+
+ -- No violation possible if no test signal change
+ NEXT WHEN (PeriodData(i).Last = TestValue);
+
+ -- record starting pulse times
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData(i).Rise;
+ PeriodData(i).Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData(i).Fall;
+ PeriodData(i).Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Fall;
+ CheckInfo.ExpTime := PulseWidthLow(i);
+ PulseTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Rise;
+ CheckInfo.ExpTime := PulseWidthHigh(i);
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF (PulseTest AND CheckEnabled) THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData(i).Last;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF (PeriodTest AND CheckEnabled) THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period(i);
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFOrmat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData(i).Last := TestValue;
+ END LOOP;
+
+END VitalMemoryPeriodPulseCheck;
+
+-- ----------------------------------------------------------------------------
+-- Functionality Section
+-- ----------------------------------------------------------------------------
+
+-- Look-up table. Given an int, we can get the 4-bit bit_vector.
+TYPE HexToBitvTableType IS ARRAY (NATURAL RANGE <>) OF
+ std_logic_vector(3 DOWNTO 0) ;
+
+CONSTANT HexToBitvTable : HexToBitvTableType (0 TO 15) :=
+ (
+ "0000", "0001", "0010", "0011",
+ "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011",
+ "1100", "1101", "1110", "1111"
+ ) ;
+
+-- ----------------------------------------------------------------------------
+-- Misc Utilities Local Utilities
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: IsSpace
+-- Parameters: ch -- input character
+-- Description: Returns TRUE or FALSE depending on the input character
+-- being white space or not.
+-- ----------------------------------------------------------------------------
+FUNCTION IsSpace (ch : character)
+RETURN boolean IS
+BEGIN
+ RETURN ((ch = ' ') OR (ch = CR) OR (ch = HT) OR (ch = NUL));
+END IsSpace;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: LenOfString
+-- Parameters: Str -- input string
+-- Description: Returns the NATURAL length of the input string.
+-- as terminated by the first NUL character.
+-- ----------------------------------------------------------------------------
+FUNCTION LenOfString (Str : STRING)
+RETURN NATURAL IS
+ VARIABLE StrRight : NATURAL;
+BEGIN
+ StrRight := Str'RIGHT;
+ FOR i IN Str'RANGE LOOP
+ IF (Str(i) = NUL) THEN
+ StrRight := i - 1;
+ EXIT;
+ END IF;
+ END LOOP;
+ RETURN (StrRight);
+END LenOfString;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HexToInt
+-- Parameters: Hex -- input character or string
+-- Description: Converts input character or string interpreted as a
+-- hexadecimal representation to integer value.
+-- ----------------------------------------------------------------------------
+FUNCTION HexToInt(Hex : CHARACTER) RETURN INTEGER IS
+ CONSTANT HexChars : STRING := "0123456789ABCDEFabcdef";
+ CONSTANT XHiChar : CHARACTER := 'X';
+ CONSTANT XLoChar : CHARACTER := 'x';
+BEGIN
+ IF (Hex = XLoChar OR Hex = XHiChar) THEN
+ RETURN (23);
+ END IF;
+ FOR i IN 1 TO 16 LOOP
+ IF(Hex = HexChars(i)) THEN
+ RETURN (i-1);
+ END IF;
+ END LOOP;
+ FOR i IN 17 TO 22 LOOP
+ IF (Hex = HexChars(i)) THEN
+ RETURN (i-7);
+ END IF;
+ END LOOP;
+ ASSERT FALSE REPORT
+ "Invalid character received by HexToInt function"
+ SEVERITY WARNING;
+ RETURN (0);
+END HexToInt;
+
+-- ----------------------------------------------------------------------------
+FUNCTION HexToInt (Hex : STRING) RETURN INTEGER IS
+ VARIABLE Value : INTEGER := 0;
+ VARIABLE Length : INTEGER;
+BEGIN
+ Length := LenOfString(hex);
+ IF (Length > 8) THEN
+ ASSERT FALSE REPORT
+ "Invalid string length received by HexToInt function"
+ SEVERITY WARNING;
+ ELSE
+ FOR i IN 1 TO Length LOOP
+ Value := Value + HexToInt(Hex(i)) * 16 ** (Length - i);
+ END LOOP;
+ END IF;
+ RETURN (Value);
+END HexToInt;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HexToBitv
+-- Parameters: Hex -- Input hex string
+-- Description: Converts input hex string to a std_logic_vector
+-- ----------------------------------------------------------------------------
+FUNCTION HexToBitv(
+ Hex : STRING
+) RETURN std_logic_vector is
+ VARIABLE Index : INTEGER := 0 ;
+ VARIABLE ValHexToInt : INTEGER ;
+ VARIABLE BitsPerHex : INTEGER := 4 ; -- Denotes no. of bits per hex char.
+ VARIABLE HexLen : NATURAL := (BitsPerHex * LenOfString(Hex)) ;
+ VARIABLE TableVal : std_logic_vector(3 DOWNTO 0) ;
+ VARIABLE Result : std_logic_vector(HexLen-1 DOWNTO 0) ;
+BEGIN
+ -- Assign 4-bit wide bit vector to result directly from a look-up table.
+ Index := 0 ;
+ WHILE ( Index < HexLen ) LOOP
+ ValHexToInt := HexToInt( Hex((HexLen - Index)/BitsPerHex ) );
+ IF ( ValHexToInt = 23 ) THEN
+ TableVal := "XXXX";
+ ELSE
+ -- Look up from the table.
+ TableVal := HexToBitvTable( ValHexToInt ) ;
+ END IF;
+ -- Assign now.
+ Result(Index+3 DOWNTO Index) := TableVal ;
+ -- Get ready for next block of 4-bits.
+ Index := Index + 4 ;
+ END LOOP ;
+ RETURN Result ;
+END HexToBitv ;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: BinToBitv
+-- Parameters: Bin -- Input bin string
+-- Description: Converts input bin string to a std_logic_vector
+-- ----------------------------------------------------------------------------
+FUNCTION BinToBitv(
+ Bin : STRING
+) RETURN std_logic_vector is
+ VARIABLE Index : INTEGER := 0 ;
+ VARIABLE Length : NATURAL := LenOfString(Bin);
+ VARIABLE BitVal : std_ulogic;
+ VARIABLE Result : std_logic_vector(Length-1 DOWNTO 0) ;
+BEGIN
+ Index := 0 ;
+ WHILE ( Index < Length ) LOOP
+ IF (Bin(Length-Index) = '0') THEN
+ BitVal := '0';
+ ELSIF (Bin(Length-Index) = '1') THEN
+ BitVal := '1';
+ ELSE
+ BitVal := 'X';
+ END IF ;
+ -- Assign now.
+ Result(Index) := BitVal ;
+ Index := Index + 1 ;
+ END LOOP ;
+ RETURN Result ;
+END BinToBitv ;
+
+-- ----------------------------------------------------------------------------
+-- For Memory Table Modeling
+-- ----------------------------------------------------------------------------
+
+TYPE To_MemoryCharType IS ARRAY (VitalMemorySymbolType) OF CHARACTER;
+CONSTANT To_MemoryChar : To_MemoryCharType :=
+ ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
+ 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S',
+ 'g', 'u', 'i', 'G', 'U', 'I',
+ 'w', 's',
+ 'c', 'l', 'd', 'e', 'C', 'L',
+ 'M', 'm', 't' );
+
+TYPE ValidMemoryTableInputType IS ARRAY (VitalMemorySymbolType) OF BOOLEAN;
+CONSTANT ValidMemoryTableInput : ValidMemoryTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'E', 'A', 'D', '*',
+ TRUE, TRUE, TRUE, TRUE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S',
+ TRUE,
+ -- 'g', 'u', 'i', 'G', 'U', 'I',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'w', 's',
+ FALSE, FALSE,
+ -- 'c', 'l', 'd', 'e', 'C', 'L',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'M', 'm', 't'
+ FALSE, FALSE, FALSE);
+
+TYPE MemoryTableMatchType IS ARRAY (X01,X01,VitalMemorySymbolType) OF BOOLEAN;
+-- last value, present value, table symbol
+CONSTANT MemoryTableMatch : MemoryTableMatchType := (
+ ( -- X (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,TRUE, TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
+ TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ ),
+
+ (-- 0 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ ),
+
+ (-- 1 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ )
+ );
+
+
+-- ----------------------------------------------------------------------------
+-- Error Message Types and Tables
+-- ----------------------------------------------------------------------------
+
+TYPE VitalMemoryErrorType IS (
+ ErrGoodAddr, -- 'g' Good address (no transition)
+ ErrUnknAddr, -- 'u' 'X' levels in address (no transition)
+ ErrInvaAddr, -- 'i' Invalid address (no transition)
+ ErrGoodTrAddr, -- 'G' Good address (with transition)
+ ErrUnknTrAddr, -- 'U' 'X' levels in address (with transition)
+ ErrInvaTrAddr, -- 'I' Invalid address (with transition)
+ ErrWrDatMem, -- 'w' Writing data to memory
+ ErrNoChgMem, -- 's' Retaining previous memory contents
+ ErrCrAllMem, -- 'c' Corrupting entire memory with 'X'
+ ErrCrWrdMem, -- 'l' Corrupting a word in memory with 'X'
+ ErrCrBitMem, -- 'd' Corrupting a single bit in memory with 'X'
+ ErrCrDatMem, -- 'e' Corrupting a word with 'X' based on data in
+ ErrCrAllSubMem,-- 'C' Corrupting a sub-word entire memory with 'X'
+ ErrCrWrdSubMem,-- 'L' Corrupting a sub-word in memory with 'X'
+ ErrCrBitSubMem,-- 'D' Corrupting a single bit of a memory sub-word with 'X'
+ ErrCrDatSubMem,-- 'E' Corrupting a sub-word with 'X' based on data in
+ ErrCrWrdOut, -- 'l' Corrupting data out with 'X'
+ ErrCrBitOut, -- 'd' Corrupting a single bit of data out with 'X'
+ ErrCrDatOut, -- 'e' Corrupting data out with 'X' based on data in
+ ErrCrWrdSubOut,-- 'L' Corrupting data out sub-word with 'X'
+ ErrCrBitSubOut,-- 'D' Corrupting a single bit of data out sub-word with 'X'
+ ErrCrDatSubOut,-- 'E' Corrupting data out sub-word with 'X' based on data in
+ ErrImplOut, -- 'M' Implicit read from memory to data out
+ ErrReadOut, -- 'm' Reading data from memory to data out
+ ErrAssgOut, -- 't' Transfering from data in to data out
+ ErrAsgXOut, -- 'X' Assigning unknown level to data out
+ ErrAsg0Out, -- '0' Assigning low level to data out
+ ErrAsg1Out, -- '1' Assigning high level to data out
+ ErrAsgZOut, -- 'Z' Assigning high impedence to data out
+ ErrAsgSOut, -- 'S' Keeping data out at steady value
+ ErrAsgXMem, -- 'X' Assigning unknown level to memory location
+ ErrAsg0Mem, -- '0' Assigning low level to memory location
+ ErrAsg1Mem, -- '1' Assigning high level to memory location
+ ErrAsgZMem, -- 'Z' Assigning high impedence to memory location
+ ErrDefMemAct, -- No memory table match, using default action
+ ErrInitMem, -- Initialize memory contents
+ ErrMcpWrCont, -- Memory cross port to same port write contention
+ ErrMcpCpCont, -- Memory cross port read/write data/memory contention
+ ErrMcpCpRead, -- Memory cross port read to same port
+ ErrMcpRdWrCo, -- Memory cross port read/write data only contention
+ ErrMcpCpWrCont,-- Memory cross port to cross port write contention
+ ErrUnknMemDo, -- Unknown memory action
+ ErrUnknDatDo, -- Unknown data action
+ ErrUnknSymbol, -- Illegal memory symbol
+ ErrLdIlgArg,
+ ErrLdAddrRng,
+ ErrLdMemInfo,
+ ErrLdFileEmpty,
+ ErrPrintString
+);
+
+TYPE VitalMemoryErrorSeverityType IS
+ARRAY (VitalMemoryErrorType) OF SEVERITY_LEVEL;
+CONSTANT VitalMemoryErrorSeverity :
+ VitalMemoryErrorSeverityType := (
+ ErrGoodAddr => NOTE,
+ ErrUnknAddr => WARNING,
+ ErrInvaAddr => WARNING,
+ ErrGoodTrAddr => NOTE,
+ ErrUnknTrAddr => WARNING,
+ ErrInvaTrAddr => WARNING,
+ ErrWrDatMem => NOTE,
+ ErrNoChgMem => NOTE,
+ ErrCrAllMem => WARNING,
+ ErrCrWrdMem => WARNING,
+ ErrCrBitMem => WARNING,
+ ErrCrDatMem => WARNING,
+ ErrCrAllSubMem => WARNING,
+ ErrCrWrdSubMem => WARNING,
+ ErrCrBitSubMem => WARNING,
+ ErrCrDatSubMem => WARNING,
+ ErrCrWrdOut => WARNING,
+ ErrCrBitOut => WARNING,
+ ErrCrDatOut => WARNING,
+ ErrCrWrdSubOut => WARNING,
+ ErrCrBitSubOut => WARNING,
+ ErrCrDatSubOut => WARNING,
+ ErrImplOut => NOTE,
+ ErrReadOut => NOTE,
+ ErrAssgOut => NOTE,
+ ErrAsgXOut => NOTE,
+ ErrAsg0Out => NOTE,
+ ErrAsg1Out => NOTE,
+ ErrAsgZOut => NOTE,
+ ErrAsgSOut => NOTE,
+ ErrAsgXMem => NOTE,
+ ErrAsg0Mem => NOTE,
+ ErrAsg1Mem => NOTE,
+ ErrAsgZMem => NOTE,
+ ErrDefMemAct => NOTE,
+ ErrInitMem => NOTE,
+ ErrMcpWrCont => WARNING,
+ ErrMcpCpCont => WARNING,
+ ErrMcpCpRead => WARNING,
+ ErrMcpRdWrCo => WARNING,
+ ErrMcpCpWrCont => WARNING,
+ ErrUnknMemDo => ERROR,
+ ErrUnknDatDo => ERROR,
+ ErrUnknSymbol => ERROR,
+ ErrLdIlgArg => ERROR,
+ ErrLdAddrRng => WARNING,
+ ErrLdMemInfo => NOTE,
+ ErrLdFileEmpty => ERROR,
+ ErrPrintString => WARNING
+ );
+
+-- ----------------------------------------------------------------------------
+CONSTANT MsgGoodAddr : STRING
+ := "Good address (no transition)";
+CONSTANT MsgUnknAddr : STRING
+ := "Unknown address (no transition)";
+CONSTANT MsgInvaAddr : STRING
+ := "Invalid address (no transition)";
+CONSTANT MsgGoodTrAddr : STRING
+ := "Good address (with transition)";
+CONSTANT MsgUnknTrAddr : STRING
+ := "Unknown address (with transition)";
+CONSTANT MsgInvaTrAddr : STRING
+ := "Invalid address (with transition)";
+CONSTANT MsgNoChgMem : STRING
+ := "Retaining previous memory contents";
+CONSTANT MsgWrDatMem : STRING
+ := "Writing data to memory";
+CONSTANT MsgCrAllMem : STRING
+ := "Corrupting entire memory with 'X'";
+CONSTANT MsgCrWrdMem : STRING
+ := "Corrupting a word in memory with 'X'";
+CONSTANT MsgCrBitMem : STRING
+ := "Corrupting a single bit in memory with 'X'";
+CONSTANT MsgCrDatMem : STRING
+ := "Corrupting a word with 'X' based on data in";
+CONSTANT MsgCrAllSubMem : STRING
+ := "Corrupting a sub-word entire memory with 'X'";
+CONSTANT MsgCrWrdSubMem : STRING
+ := "Corrupting a sub-word in memory with 'X'";
+CONSTANT MsgCrBitSubMem : STRING
+ := "Corrupting a single bit of a sub-word with 'X'";
+CONSTANT MsgCrDatSubMem : STRING
+ := "Corrupting a sub-word with 'X' based on data in";
+CONSTANT MsgCrWrdOut : STRING
+ := "Corrupting data out with 'X'";
+CONSTANT MsgCrBitOut : STRING
+ := "Corrupting a single bit of data out with 'X'";
+CONSTANT MsgCrDatOut : STRING
+ := "Corrupting data out with 'X' based on data in";
+CONSTANT MsgCrWrdSubOut : STRING
+ := "Corrupting data out sub-word with 'X'";
+CONSTANT MsgCrBitSubOut : STRING
+ := "Corrupting a single bit of data out sub-word with 'X'";
+CONSTANT MsgCrDatSubOut : STRING
+ := "Corrupting data out sub-word with 'X' based on data in";
+CONSTANT MsgImplOut : STRING
+ := "Implicit read from memory to data out";
+CONSTANT MsgReadOut : STRING
+ := "Reading data from memory to data out";
+CONSTANT MsgAssgOut : STRING
+ := "Transfering from data in to data out";
+CONSTANT MsgAsgXOut : STRING
+ := "Assigning unknown level to data out";
+CONSTANT MsgAsg0Out : STRING
+ := "Assigning low level to data out";
+CONSTANT MsgAsg1Out : STRING
+ := "Assigning high level to data out";
+CONSTANT MsgAsgZOut : STRING
+ := "Assigning high impedance to data out";
+CONSTANT MsgAsgSOut : STRING
+ := "Keeping data out at steady value";
+CONSTANT MsgAsgXMem : STRING
+ := "Assigning unknown level to memory location";
+CONSTANT MsgAsg0Mem : STRING
+ := "Assigning low level to memory location";
+CONSTANT MsgAsg1Mem : STRING
+ := "Assigning high level to memory location";
+CONSTANT MsgAsgZMem : STRING
+ := "Assigning high impedance to memory location";
+CONSTANT MsgDefMemAct : STRING
+ := "No memory table match, using default action";
+CONSTANT MsgInitMem : STRING
+ := "Initializing memory contents";
+CONSTANT MsgMcpWrCont : STRING
+ := "Same port write contention";
+CONSTANT MsgMcpCpCont : STRING
+ := "Cross port read/write data/memory contention";
+CONSTANT MsgMcpCpRead : STRING
+ := "Cross port read to same port";
+CONSTANT MsgMcpRdWrCo : STRING
+ := "Cross port read/write data only contention";
+CONSTANT MsgMcpCpWrCont : STRING
+ := "Cross port write contention";
+CONSTANT MsgUnknMemDo : STRING
+ := "Unknown memory action";
+CONSTANT MsgUnknDatDo : STRING
+ := "Unknown data action";
+CONSTANT MsgUnknSymbol : STRING
+ := "Illegal memory symbol";
+
+CONSTANT MsgLdIlgArg : STRING
+ := "Illegal bit arguments while loading memory.";
+CONSTANT MsgLdMemInfo : STRING
+ := "Loading data from the file into memory.";
+CONSTANT MsgLdAddrRng : STRING
+ := "Address out of range while loading memory.";
+CONSTANT MsgLdFileEmpty : STRING
+ := "Memory load file is empty.";
+CONSTANT MsgPrintString : STRING
+ := "";
+
+CONSTANT MsgUnknown : STRING
+ := "Unknown error message.";
+
+CONSTANT MsgVMT : STRING
+ := "VitalMemoryTable";
+CONSTANT MsgVMV : STRING
+ := "VitalMemoryViolation";
+CONSTANT MsgVDM : STRING
+ := "VitalDeclareMemory";
+CONSTANT MsgVMCP : STRING
+ := "VitalMemoryCrossPorts";
+
+-- ----------------------------------------------------------------------------
+-- LOCAL Utilities
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryMessage
+-- Parameters: ErrorId -- Input error code
+-- Description: This function looks up the input error code and returns
+-- the string value of the associated message.
+-- ----------------------------------------------------------------------------
+
+FUNCTION MemoryMessage (
+ CONSTANT ErrorId : IN VitalMemoryErrorType
+) RETURN STRING IS
+BEGIN
+ CASE ErrorId IS
+ WHEN ErrGoodAddr => RETURN MsgGoodAddr ;
+ WHEN ErrUnknAddr => RETURN MsgUnknAddr ;
+ WHEN ErrInvaAddr => RETURN MsgInvaAddr ;
+ WHEN ErrGoodTrAddr => RETURN MsgGoodTrAddr ;
+ WHEN ErrUnknTrAddr => RETURN MsgUnknTrAddr ;
+ WHEN ErrInvaTrAddr => RETURN MsgInvaTrAddr ;
+ WHEN ErrWrDatMem => RETURN MsgWrDatMem ;
+ WHEN ErrNoChgMem => RETURN MsgNoChgMem ;
+ WHEN ErrCrAllMem => RETURN MsgCrAllMem ;
+ WHEN ErrCrWrdMem => RETURN MsgCrWrdMem ;
+ WHEN ErrCrBitMem => RETURN MsgCrBitMem ;
+ WHEN ErrCrDatMem => RETURN MsgCrDatMem ;
+ WHEN ErrCrAllSubMem => RETURN MsgCrAllSubMem;
+ WHEN ErrCrWrdSubMem => RETURN MsgCrWrdSubMem;
+ WHEN ErrCrBitSubMem => RETURN MsgCrBitSubMem;
+ WHEN ErrCrDatSubMem => RETURN MsgCrDatSubMem;
+ WHEN ErrCrWrdOut => RETURN MsgCrWrdOut ;
+ WHEN ErrCrBitOut => RETURN MsgCrBitOut ;
+ WHEN ErrCrDatOut => RETURN MsgCrDatOut ;
+ WHEN ErrCrWrdSubOut => RETURN MsgCrWrdSubOut;
+ WHEN ErrCrBitSubOut => RETURN MsgCrBitSubOut;
+ WHEN ErrCrDatSubOut => RETURN MsgCrDatSubOut;
+ WHEN ErrImplOut => RETURN MsgImplOut ;
+ WHEN ErrReadOut => RETURN MsgReadOut ;
+ WHEN ErrAssgOut => RETURN MsgAssgOut ;
+ WHEN ErrAsgXOut => RETURN MsgAsgXOut ;
+ WHEN ErrAsg0Out => RETURN MsgAsg0Out ;
+ WHEN ErrAsg1Out => RETURN MsgAsg1Out ;
+ WHEN ErrAsgZOut => RETURN MsgAsgZOut ;
+ WHEN ErrAsgSOut => RETURN MsgAsgSOut ;
+ WHEN ErrAsgXMem => RETURN MsgAsgXMem ;
+ WHEN ErrAsg0Mem => RETURN MsgAsg0Mem ;
+ WHEN ErrAsg1Mem => RETURN MsgAsg1Mem ;
+ WHEN ErrAsgZMem => RETURN MsgAsgZMem ;
+ WHEN ErrDefMemAct => RETURN MsgDefMemAct ;
+ WHEN ErrInitMem => RETURN MsgInitMem ;
+ WHEN ErrMcpWrCont => RETURN MsgMcpWrCont ;
+ WHEN ErrMcpCpCont => RETURN MsgMcpCpCont ;
+ WHEN ErrMcpCpRead => RETURN MsgMcpCpRead ;
+ WHEN ErrMcpRdWrCo => RETURN MsgMcpRdWrCo ;
+ WHEN ErrMcpCpWrCont => RETURN MsgMcpCpWrCont;
+ WHEN ErrUnknMemDo => RETURN MsgUnknMemDo ;
+ WHEN ErrUnknDatDo => RETURN MsgUnknDatDo ;
+ WHEN ErrUnknSymbol => RETURN MsgUnknSymbol ;
+ WHEN ErrLdIlgArg => RETURN MsgLdIlgArg ;
+ WHEN ErrLdAddrRng => RETURN MsgLdAddrRng ;
+ WHEN ErrLdMemInfo => RETURN MsgLdMemInfo ;
+ WHEN ErrLdFileEmpty => RETURN MsgLdFileEmpty;
+ WHEN ErrPrintString => RETURN MsgPrintString;
+ WHEN OTHERS => RETURN MsgUnknown ;
+ END CASE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: PrintMemoryMessage
+-- Parameters: Routine -- String identifying the calling routine
+-- ErrorId -- Input error code for message lookup
+-- Info -- Output string or character
+-- InfoStr -- Additional output string
+-- Info1 -- Additional output integer
+-- Info2 -- Additional output integer
+-- Info3 -- Additional output integer
+-- Description: This procedure prints out a memory status message
+-- given the input error id and other status information.
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId)
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info : IN STRING
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info1 : IN STRING;
+ CONSTANT Info2 : IN STRING
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info1 & " " & Info2
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info : IN CHARACTER
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL;
+ CONSTANT Info2 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ IntToStr(Info2,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL;
+ CONSTANT Info2 : IN NATURAL;
+ CONSTANT Info3 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ IntToStr(Info2,TmpStr,TmpInt);
+ IntToStr(Info3,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT Table : IN VitalMemoryTableType;
+ CONSTANT Index : IN INTEGER;
+ CONSTANT InfoStr : IN STRING
+) IS
+ CONSTANT TableEntries : INTEGER := Table'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := Table'LENGTH(2);
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IF (Index < 0 AND Index > TableEntries-1) THEN
+ ASSERT FALSE
+ REPORT Routine & ": Memory table search failure"
+ SEVERITY ERROR;
+ END IF;
+ ColLoop:
+ FOR i IN 0 TO TableWidth-1 LOOP
+ IF (i >= 64) THEN
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ EXIT ColLoop;
+ END IF;
+ TmpStr(TmpInt) := ''';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := To_MemoryChar(Table(Index,i));
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := ''';
+ TmpInt := TmpInt + 1;
+ IF (i < TableWidth-1) THEN
+ TmpStr(TmpInt) := ',';
+ TmpInt := TmpInt + 1;
+ END IF;
+ END LOOP;
+ ASSERT FALSE
+ REPORT Routine & ": Port=" & InfoStr & " TableRow=" & TmpStr
+ SEVERITY NOTE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: DecodeAddress
+-- Parameters: Address - Converted address.
+-- AddrFlag - Flag to indicte address match
+-- MemoryData - Information about memory characteristics
+-- PrevAddressBus - Previous input address value
+-- AddressBus - Input address value.
+-- Description: This procedure is used for transforming a valid
+-- address value to an integer in order to access memory.
+-- It performs address bound checking as well.
+-- Sets Address to -1 for unknowns
+-- Sets Address to -2 for out of range
+-- ----------------------------------------------------------------------------
+
+PROCEDURE DecodeAddress (
+ VARIABLE Address : INOUT INTEGER;
+ VARIABLE AddrFlag : INOUT VitalMemorySymbolType;
+ VARIABLE MemoryData : IN VitalMemoryDataType;
+ CONSTANT PrevAddressBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector
+) IS
+ VARIABLE Power : NATURAL;
+ VARIABLE AddrUnkn : BOOLEAN;
+BEGIN
+ Power := 0;
+ AddrUnkn := FALSE;
+ -- It is assumed that always Address'LEFT represents the Most significant bit.
+ FOR i IN AddressBus'RANGE LOOP
+ Power := Power * 2;
+ IF (AddressBus(i) /= '1' AND AddressBus(i) /= '0') THEN
+ AddrUnkn := TRUE;
+ Power := 0;
+ EXIT;
+ ELSIF (AddressBus(i) = '1') THEN
+ Power := Power + 1;
+ END IF;
+ END LOOP;
+ Address := Power;
+ AddrFlag := 'g';
+ IF (AddrUnkn) THEN
+ AddrFlag := 'u'; -- unknown addr
+ Address := -1;
+ END IF;
+ IF ( Power > (MemoryData.NoOfWords - 1)) THEN
+ AddrFlag := 'i'; -- invalid addr
+ Address := -2;
+ END IF;
+ IF (PrevAddressBus /= AddressBus) THEN
+ CASE AddrFlag IS
+ WHEN 'g' => AddrFlag := 'G';
+ WHEN 'u' => AddrFlag := 'U';
+ WHEN 'i' => AddrFlag := 'I';
+ WHEN OTHERS =>
+ ASSERT FALSE REPORT
+ "DecodeAddress: Internal error. [AddrFlag]="
+ & To_MemoryChar(AddrFlag)
+ SEVERITY ERROR;
+ END CASE;
+ END IF;
+END DecodeAddress;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: DecodeData
+-- Parameters: DataFlag - Flag to indicte data match
+-- PrevDataInBus - Previous input data value
+-- DataInBus - Input data value.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used for interpreting the input data
+-- as a data flag for subsequent table matching.
+-- ----------------------------------------------------------------------------
+PROCEDURE DecodeData (
+ VARIABLE DataFlag : INOUT VitalMemorySymbolType;
+ CONSTANT PrevDataInBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE DataUnkn : BOOLEAN := FALSE;
+BEGIN
+ FOR i IN LowBit TO HighBit LOOP
+ IF DataInBus(i) /= '1' AND DataInBus(i) /= '0' THEN
+ DataUnkn := TRUE;
+ EXIT;
+ END IF;
+ END LOOP;
+ DataFlag := 'g';
+ IF (DataUnkn) THEN
+ DataFlag := 'u'; -- unknown addr
+ END IF;
+ IF (PrevDataInBus(HighBit DOWNTO LowBit) /=
+ DataInBus(HighBit DOWNTO LowBit)) THEN
+ CASE DataFlag IS
+ WHEN 'g' => DataFlag := 'G';
+ WHEN 'u' => DataFlag := 'U';
+ WHEN OTHERS =>
+ ASSERT FALSE REPORT
+ "DecodeData: Internal error. [DataFlag]="
+ & To_MemoryChar(DataFlag)
+ SEVERITY ERROR;
+ END CASE;
+ END IF;
+END DecodeData;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: WriteMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- DataInBus - Input Data to be written.
+-- Address - Address of the memory location.
+-- BitPosition - Position of bit in memory location.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to write to a memory location
+-- on a bit/byte/word basis.
+-- The high bit and low bit offset are used for byte write
+-- operations.These parameters specify the data byte for write.
+-- In the case of word write the complete memory word is used.
+-- This procedure is overloaded for bit,byte and word write
+-- memory operations.The number of parameters may vary.
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE TmpData : std_logic_vector(DataInBus'LENGTH - 1 DOWNTO 0);
+BEGIN
+ -- Address bound checking.
+ IF ( Address < 0 OR Address > (MemoryPtr.NoOfWords - 1)) THEN
+ PrintMemoryMessage ( "WriteMemory", ErrPrintString,
+ "Aborting write operation as address is out of range.") ;
+ RETURN;
+ END IF;
+ TmpData := To_UX01(DataInBus);
+ FOR i in LowBit to HighBit LOOP
+ MemoryPtr.MemoryArrayPtr(Address).all(i) := TmpData(i);
+ END LOOP;
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT BitPosition : IN NATURAL
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := BitPosition;
+ LowBit := BitPosition;
+ WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit);
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := MemoryPtr.NoOfBitsPerWord - 1;
+ LowBit := 0;
+ WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit);
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: ReadMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- DataOut - Output Data to be read in this.
+-- Address - Address of the memory location.
+-- BitPosition - Position of bit in memory location.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to read from a memory location
+-- on a bit/byte/word basis.
+-- The high bit and low bit offset are used for byte write
+-- operations.These parameters specify the data byte for
+-- read.In the case of word write the complete memory word
+-- is used.This procedure is overloaded for bit,byte and
+-- word write memory operations.The number of parameters
+-- may vary.
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE DataOutTmp : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0);
+ VARIABLE length : NATURAL := (HighBit - LowBit + 1);
+BEGIN
+ -- Address bound checking.
+ IF ( Address > (MemoryPtr.NoOfWords - 1)) THEN
+ PrintMemoryMessage (
+ "ReadMemory",ErrInvaAddr,
+ "[Address,NoOfWords]=",Address,MemoryPtr.NoOfWords
+ );
+ FOR i in LowBit to HighBit LOOP
+ DataOutTmp(i) := 'X';
+ END LOOP;
+ ELSE
+ FOR i in LowBit to HighBit LOOP
+ DataOutTmp(i) := MemoryPtr.MemoryArrayPtr (Address).all(i);
+ END LOOP;
+ END IF;
+ DataOut := DataOutTmp;
+END ReadMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT BitPosition : IN NATURAL
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := BitPosition;
+ LowBit := BitPosition;
+ ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit);
+END ReadMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := MemoryPtr.NoOfBitsPerWord - 1;
+ LowBit := 0;
+ ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit);
+END ReadMemory;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: LoadMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- FileName - Name of the output file.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to load the contents of the memory
+-- from a specified input file.
+-- The high bit and low bit offset are used so that same task
+-- can be used for all bit/byte/word write operations.
+-- In the case of a bit write RAM the HighBit and LowBit have
+-- the same value.
+-- This procedure is overloaded for word write operations.
+-- ----------------------------------------------------------------------------
+PROCEDURE LoadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT FileName : IN STRING;
+ CONSTANT BinaryFile : IN BOOLEAN := FALSE
+) IS
+ FILE Fptr : TEXT OPEN read_mode IS FileName;
+ VARIABLE OneLine : LINE;
+ VARIABLE Ignore : CHARACTER;
+ VARIABLE Index : NATURAL := 1;
+ VARIABLE LineNo : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE DataInBus : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0);
+ VARIABLE AddrStr : STRING(1 TO 80) ;
+ VARIABLE DataInStr : STRING(1 TO 255) ;
+BEGIN
+ IF (ENDFILE(fptr)) THEN
+ PrintMemoryMessage (MsgVDM, ErrLdFileEmpty,
+ "[FileName]="&FileName);
+ RETURN;
+ END IF ;
+ PrintMemoryMessage (
+ MsgVDM,ErrLdMemInfo, "[FileName]="&FileName
+ );
+ WHILE (NOT ENDFILE(fptr)) LOOP
+ ReadLine(Fptr, OneLine);
+ LineNo := LineNo + 1 ;
+ -- First ignoring leading spaces.
+ WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ -- Note that, by now oneline has been "stripped" of its leading spaces.
+ IF ( OneLine(1) = '@' ) THEN
+ READ (OneLine, Ignore); -- Ignore the '@' character and read the string.
+ -- Now strip off spaces, if any, between '@' and Address string.
+ WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ -- Now get the string which represents the address into string variable.
+ Index := 1;
+ WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP
+ READ(OneLine, AddrStr(Index));
+ Index := Index + 1;
+ END LOOP ;
+ AddrStr(Index) := NUL;
+ -- Now convert the hex string into a hex integer
+ Address := HexToInt(AddrStr) ;
+ ELSE
+ IF ( LineNo /= 1 ) THEN
+ Address := Address + 1;
+ END IF;
+ END IF ;
+ IF ( Address > (MemoryPtr.NoOfWords - 1) ) THEN
+ PrintMemoryMessage (MsgVDM, ErrLdAddrRng,
+ "[Address,lineno]=", Address, LineNo) ;
+ EXIT ;
+ END IF;
+ -- Now strip off spaces, between Address string and DataInBus string.
+ WHILE (OneLine'LENGTH /= 0 AND IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ Index := 1;
+ WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP
+ READ(OneLine, DataInStr(Index));
+ Index := Index + 1;
+ END LOOP ;
+ DataInStr(Index) := NUL;
+ IF (BinaryFile) THEN
+ DataInBus := BinToBitv (DataInStr);
+ ELSE
+ DataInBus := HexToBitv (DataInStr);
+ END IF ;
+ WriteMemory (MemoryPtr, DataInBus, Address);
+ END LOOP ;
+END LoadMemory;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryMatch
+-- Parameters: Symbol - Symbol from memory table
+-- TestFlag - Interpreted data or address symbol
+-- In2 - input from VitalMemoryTable procedure
+-- to memory table
+-- In2LastValue - Previous value of input
+-- Err - TRUE if symbol is not a valid input symbol
+-- ReturnValue - TRUE if match occurred
+-- Description: This procedure sets ReturnValue to true if in2 matches
+-- symbol (from the memory table). If symbol is an edge
+-- value edge is set to true and in2 and in2LastValue are
+-- checked against symbol. Err is set to true if symbol
+-- is an invalid value for the input portion of the memory
+-- table.
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryMatch (
+ CONSTANT Symbol : IN VitalMemorySymbolType;
+ CONSTANT In2 : IN std_ulogic;
+ CONSTANT In2LastValue : IN std_ulogic;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+) IS
+BEGIN
+ IF (NOT ValidMemoryTableInput(Symbol) ) THEN
+ PrintMemoryMessage(MsgVMT,ErrUnknSymbol,To_MemoryChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ ReturnValue := MemoryTableMatch(To_X01(In2LastValue), To_X01(In2), Symbol);
+ Err := FALSE;
+ END IF;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryMatch (
+ CONSTANT Symbol : IN VitalMemorySymbolType;
+ CONSTANT TestFlag : IN VitalMemorySymbolType;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+) IS
+BEGIN
+ Err := FALSE;
+ ReturnValue := FALSE;
+ CASE Symbol IS
+ WHEN 'g'|'u'|'i'|'G'|'U'|'I'|'-'|'*'|'S' =>
+ IF (Symbol = TestFlag) THEN
+ ReturnValue := TRUE;
+ ELSE
+ CASE Symbol IS
+ WHEN '-' =>
+ ReturnValue := TRUE;
+ Err := FALSE;
+ WHEN '*' =>
+ IF (TestFlag = 'G' OR
+ TestFlag = 'U' OR
+ TestFlag = 'I') THEN
+ ReturnValue := TRUE;
+ Err := FALSE;
+ END IF;
+ WHEN 'S' =>
+ IF (TestFlag = 'g' OR
+ TestFlag = 'u' OR
+ TestFlag = 'i') THEN
+ ReturnValue := TRUE;
+ Err := FALSE;
+ END IF;
+ WHEN OTHERS =>
+ ReturnValue := FALSE;
+ END CASE;
+ END IF;
+ WHEN OTHERS =>
+ Err := TRUE;
+ RETURN;
+ END CASE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableCorruptMask
+-- Description: Compute memory and data corruption masks for memory table
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType;
+ CONSTANT EnableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'e' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN 'd'|'C'|'L'|'D'|'E' =>
+ -- Process corruption below
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ IF (Action = 'd') THEN
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END IF;
+ -- Remaining are subword cases 'C', 'L', 'D', 'E'
+ CorruptMaskTmp := (OTHERS => '0');
+ LowBit := 0;
+ HighBit := BitsPerSubWord-1;
+ SubWordLoop:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (i = EnableIndex) THEN
+ FOR j IN HighBit TO LowBit LOOP
+ CorruptMaskTmp(j) := 'X';
+ END LOOP;
+ END IF;
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END LOOP;
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (0 TO CorruptMask'LENGTH-1)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'d'|'e'|'C'|'L'|'D'|'E' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableCorruptMask
+-- Description: Compute memory and data corruption masks for violation table
+-- ----------------------------------------------------------------------------
+PROCEDURE ViolationTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN std_logic_vector;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT TableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+ CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH;
+ CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH;
+ CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'e' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN 'd'|'C'|'L'|'D'|'E' =>
+ -- Process corruption below
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ RowLoop: -- Check each element of the ViolationFlags
+ FOR j IN 0 TO ViolFlagsSize LOOP
+ IF (j = ViolFlagsSize) THEN
+ ViolFlAryPosn := 0;
+ RowLoop2: -- Check relevant elements of the ViolationFlagsArray
+ FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP
+ IF (ViolationTable(TableIndex, k + ViolFlagsSize) = 'X') THEN
+ MaskLoop: -- Set the 'X' bits in the violation mask
+ FOR m IN INTEGER RANGE 0 TO CorruptMask'LENGTH-1 LOOP
+ IF (m <= ViolationSizesArray(k)-1) THEN
+ ViolMaskTmp(m) := ViolMaskTmp(m) XOR
+ ViolationFlagsArray(ViolFlAryPosn+m);
+ ELSE
+ EXIT MaskLoop;
+ END IF;
+ END LOOP;
+ END IF;
+ ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k);
+ END LOOP;
+ ELSE
+ IF (ViolationTable(TableIndex, j) = 'X') THEN
+ ViolMaskTmp(0) := ViolMaskTmp(0) XOR ViolationFlags(j);
+ END IF;
+ END IF;
+ END LOOP;
+ IF (Action = 'd') THEN
+ CorruptMask := ViolMaskTmp;
+ RETURN;
+ END IF;
+ -- Remaining are subword cases 'C', 'L', 'D', 'E'
+ CorruptMaskTmp := (OTHERS => '0');
+ LowBit := 0;
+ HighBit := BitsPerSubWord-1;
+ SubWordLoop:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (ViolMaskTmp(i) = 'X') THEN
+ FOR j IN HighBit TO LowBit LOOP
+ CorruptMaskTmp(j) := 'X';
+ END LOOP;
+ END IF;
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END LOOP;
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableLookUp
+-- Parameters: MemoryAction - Output memory action to be performed
+-- DataAction - Output data action to be performed
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- EnableIndex - Current slice of vector control lines
+-- AddrFlag - Matching symbol from address decoding
+-- DataFlag - Matching symbol from data decoding
+-- MemoryTable - Input memory action table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+--
+-- Description: This function is used to find the output of the
+-- MemoryTable corresponding to a given set of inputs.
+--
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT PrevControls : IN std_logic_vector;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT AddrFlag : IN VitalMemorySymbolType;
+ CONSTANT DataFlag : IN VitalMemorySymbolType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ControlsSize : INTEGER := Controls'LENGTH;
+ CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ CONSTANT DataInBusNdx : INTEGER := TableWidth - 3;
+ CONSTANT AddressBusNdx : INTEGER := TableWidth - 4;
+ VARIABLE AddrFlagTable : VitalMemorySymbolType;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := MemoryTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the Controls
+ FOR j IN 0 TO ControlsSize LOOP
+ IF (j = ControlsSize) THEN
+ -- a match occurred, now check AddrFlag, DataFlag
+ MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match);
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match);
+ IF (Match) THEN
+ MemoryTableCorruptMask (
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx)
+ );
+ MemoryTableCorruptMask (
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx)
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ END IF;
+ ELSE
+ -- Match memory table inputs
+ MemoryMatch ( TableAlias(i,j),
+ Controls(j), PrevControls(j),
+ Err, Match);
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT PrevControls : IN std_logic_vector;
+ CONSTANT PrevEnableBus : IN std_logic_vector;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT EnableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER;
+ CONSTANT AddrFlag : IN VitalMemorySymbolType;
+ CONSTANT DataFlag : IN VitalMemorySymbolType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ControlsSize : INTEGER := Controls'LENGTH;
+ CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ CONSTANT DataInBusNdx : INTEGER := TableWidth - 3;
+ CONSTANT AddressBusNdx : INTEGER := TableWidth - 4;
+ VARIABLE AddrFlagTable : VitalMemorySymbolType;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := MemoryTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the Controls
+ FOR j IN 0 TO ControlsSize LOOP
+ IF (j = ControlsSize) THEN
+ -- a match occurred, now check EnableBus, AddrFlag, DataFlag
+ IF (EnableIndex >= 0) THEN
+ RowLoop2: -- Check relevant elements of the EnableBus
+ FOR k IN 0 TO AddressBusNdx - ControlsSize - 1 LOOP
+ MemoryMatch ( TableAlias(i,k + ControlsSize),
+ EnableBus(k * BitsPerEnable + EnableIndex),
+ PrevEnableBus(k * BitsPerEnable + EnableIndex),
+ Err, Match);
+ EXIT RowLoop2 WHEN NOT(Match);
+ END LOOP;
+ END IF;
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match);
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match);
+ IF (Match) THEN
+ MemoryTableCorruptMask (
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx),
+ EnableIndex => EnableIndex ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ MemoryTableCorruptMask (
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx),
+ EnableIndex => EnableIndex ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ END IF;
+ END IF;
+ ELSE
+ -- Match memory table inputs
+ MemoryMatch ( TableAlias(i,j),
+ Controls(j), PrevControls(j),
+ Err, Match);
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: ViolationTableLookUp
+-- Parameters: MemoryAction - Output memory action to be performed
+-- DataAction - Output data action to be performed
+-- TimingDataArray - This is currently not used (comment out)
+-- ViolationArray - Aggregation of violation variables
+-- ViolationTable - Input memory violation table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This function is used to find the output of the
+-- ViolationTable corresponding to a given set of inputs.
+-- ----------------------------------------------------------------------------
+PROCEDURE ViolationTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN std_logic_vector;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH;
+ CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH;
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE ViolFlAryItem : std_ulogic;
+ CONSTANT ViolSzArySize : INTEGER := ViolationSizesArray'LENGTH;
+ CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ VARIABLE HighBit : NATURAL := 0;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := ViolationTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the ViolationFlags
+ FOR j IN 0 TO ViolFlagsSize LOOP
+ IF (j = ViolFlagsSize) THEN
+ ViolFlAryPosn := 0;
+ RowLoop2: -- Check relevant elements of the ViolationFlagsArray
+ FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP
+ ViolFlAryItem := '0';
+ SubwordLoop: -- Check for 'X' in ViolationFlagsArray chunk
+ FOR s IN ViolFlAryPosn TO ViolFlAryPosn+ViolationSizesArray(k)-1 LOOP
+ IF (ViolationFlagsArray(s) = 'X') THEN
+ ViolFlAryItem := 'X';
+ EXIT SubwordLoop;
+ END IF;
+ END LOOP;
+ MemoryMatch ( TableAlias(i,k + ViolFlagsSize),
+ ViolFlAryItem,ViolFlAryItem,
+ Err, Match);
+ ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k);
+ EXIT RowLoop2 WHEN NOT(Match);
+ END LOOP;
+ IF (Match) THEN
+ -- Compute memory and data corruption masks
+ ViolationTableCorruptMask(
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx),
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => ViolationFlagsArray ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ TableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ ViolationTableCorruptMask(
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx),
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => ViolationFlagsArray ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ TableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMV,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ ELSE
+ -- Match violation table inputs
+ Err := FALSE;
+ Match := FALSE;
+ IF (TableAlias(i,j) /= 'X' AND
+ TableAlias(i,j) /= '0' AND
+ TableAlias(i,j) /= '-') THEN
+ Err := TRUE;
+ ELSIF (TableAlias(i,j) = '-' OR
+ (TableAlias(i,j) = 'X' AND ViolationFlags(j) = 'X') OR
+ (TableAlias(i,j) = '0' AND ViolationFlags(j) = '0')) THEN
+ Match := TRUE;
+ END IF;
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMV,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HandleMemoryAction
+-- Parameters: MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates read/write mode of port
+-- CorruptMask - XOR'ed with DataInBus when corrupting
+-- DataInBus - Current data bus in
+-- Address - Current address integer
+-- HighBit - Current address high bit
+-- LowBit - Current address low bit
+-- MemoryTable - Input memory action table
+-- MemoryAction - Memory action to be performed
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This procedure performs the specified memory action on
+-- the input memory data structure.
+-- ----------------------------------------------------------------------------
+PROCEDURE HandleMemoryAction (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagType;
+ CONSTANT CorruptMask : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT MemoryAction : IN VitalMemorySymbolType;
+ CONSTANT CallerName : IN STRING;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ VARIABLE DataInTmp : std_logic_vector(DataInBus'RANGE)
+ := DataInBus;
+ BEGIN
+
+ -- Handle the memory action
+ CASE MemoryAction IS
+
+ WHEN 'w' =>
+ -- Writing data to memory
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrWrDatMem,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,DataInBus,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN 's' =>
+ -- Retaining previous memory contents
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrNoChgMem,HeaderMsg,PortName);
+ END IF;
+ -- Set memory current to quiet state
+ PortFlag.MemoryCurrent := READ;
+
+ WHEN 'c' =>
+ -- Corrupting entire memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrAllMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP
+ WriteMemory(MemoryData,DataInTmp,i);
+ END LOOP;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'l' =>
+ -- Corrupting a word in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ WriteMemory(MemoryData,DataInTmp,Address);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'd' =>
+ -- Corrupting a single bit in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'e' =>
+ -- Corrupting a word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ IF (DataInTmp /= DataInBus) THEN
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ WriteMemory(MemoryData,DataInTmp,Address);
+ END IF;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'C' =>
+ -- Corrupting a sub-word entire memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrAllSubMem,HeaderMsg,PortName);
+ END IF;
+ FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP
+ ReadMemory(MemoryData,DataInTmp,i);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,i,HighBit,LowBit);
+ END LOOP;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'L' =>
+ -- Corrupting a sub-word in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'D' =>
+ -- Corrupting a single bit of a memory sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'E' =>
+ -- Corrupting a sub-word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ IF (DataInBus(HighBit DOWNTO LowBit) /=
+ DataInTmp(HighBit DOWNTO LowBit)) THEN
+ DataInTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ END IF;
+ --PortFlag := WRITE;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN '0' =>
+ -- Assigning low level to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg0Mem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => '0');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN '1' =>
+ -- Assigning high level to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg1Mem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => '1');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN 'Z' =>
+ -- Assigning high impedence to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgZMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'Z');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN OTHERS =>
+ -- Unknown memory action
+ PortFlag.MemoryCurrent := UNDEF;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrUnknMemDo,HeaderMsg,PortName);
+ END IF;
+
+ END CASE;
+
+ -- Note: HandleMemoryAction does not change the PortFlag.OutputDisable
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HandleDataAction
+-- Parameters: DataOutBus - Output result of the data action
+-- MemoryData - Input pointer to memory data structure
+-- PortFlag - Indicates read/write mode of port
+-- CorruptMask - XOR'ed with DataInBus when corrupting
+-- DataInBus - Current data bus in
+-- Address - Current address integer
+-- HighBit - Current address high bit
+-- LowBit - Current address low bit
+-- MemoryTable - Input memory action table
+-- DataAction - Data action to be performed
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This procedure performs the specified data action based
+-- on the input memory data structure. Checks whether
+-- the previous state is HighZ. If yes then portFlag
+-- should be NOCHANGE for VMPD to ignore IORetain
+-- corruption. The idea is that the first Z should be
+-- propagated but later ones should be ignored.
+-- ----------------------------------------------------------------------------
+PROCEDURE HandleDataAction (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagType;
+ CONSTANT CorruptMask : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT DataAction : IN VitalMemorySymbolType;
+ CONSTANT CallerName : IN STRING;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+
+BEGIN
+
+ -- Handle the data action
+ CASE DataAction IS
+
+ WHEN 'l' =>
+ -- Corrupting data out with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'd' =>
+ -- Corrupting a single bit of data out with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'e' =>
+ -- Corrupting data out with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ IF (DataOutTmp /= DataInBus) THEN
+ DataOutTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ END IF;
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'L' =>
+ -- Corrupting data out sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdSubOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'D' =>
+ -- Corrupting a single bit of data out sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitSubOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'E' =>
+ -- Corrupting data out sub-word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatSubOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ IF (DataInBus(HighBit DOWNTO LowBit) /=
+ DataOutTmp(HighBit DOWNTO LowBit)) THEN
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ -- No need to CorruptMask
+ END IF;
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'M' =>
+ -- Implicit read from memory to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrImplOut,HeaderMsg,PortName);
+ END IF;
+ PortFlag.DataCurrent := READ;
+
+ WHEN 'm' =>
+ -- Reading data from memory to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrReadOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ PortFlag.DataCurrent := READ;
+
+ WHEN 't' =>
+ -- Transfering from data in to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAssgOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := DataInBus;
+ PortFlag.DataCurrent := READ;
+
+ WHEN '0' =>
+ -- Assigning low level to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg0Out,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => '0');
+ PortFlag.DataCurrent := READ;
+
+ WHEN '1' =>
+ -- Assigning high level to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg1Out,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => '1');
+ PortFlag.DataCurrent := READ;
+
+ WHEN 'Z' =>
+ -- Assigning high impedence to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgZOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => 'Z');
+ PortFlag.DataCurrent := HIGHZ;
+
+ WHEN 'S' =>
+ -- Keeping data out at steady value
+ PortFlag.OutputDisable := TRUE;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgSOut,HeaderMsg,PortName);
+ END IF;
+
+ WHEN OTHERS =>
+ -- Unknown data action
+ PortFlag.DataCurrent := UNDEF;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrUnknDatDo,HeaderMsg,PortName);
+ END IF;
+
+ END CASE;
+
+ DataOutBus(HighBit DOWNTO LowBit) := DataOutTmp(HighBit DOWNTO LowBit);
+
+END;
+
+
+-- ----------------------------------------------------------------------------
+-- Memory Table Modeling Primitives
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalDeclareMemory
+-- Parameters: NoOfWords - Number of words in the memory
+-- NoOfBitsPerWord - Number of bits per word in memory
+-- NoOfBitsPerSubWord - Number of bits per sub word
+-- MemoryLoadFile - Name of data file to load
+-- Description: This function is intended to be used to initialize
+-- memory data declarations, i.e. to be executed duing
+-- simulation elaboration time. Handles the allocation
+-- and initialization of memory for the memory data.
+-- Default NoOfBitsPerSubWord is NoOfBitsPerWord.
+-- ----------------------------------------------------------------------------
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType IS
+ VARIABLE MemoryPtr : VitalMemoryDataType;
+BEGIN
+ MemoryPtr := VitalDeclareMemory(
+ NoOfWords => NoOfWords,
+ NoOfBitsPerWord => NoOfBitsPerWord,
+ NoOfBitsPerSubWord => NoOfBitsPerWord,
+ MemoryLoadFile => MemoryLoadFile,
+ BinaryLoadFile => BinaryLoadFile
+ );
+ RETURN MemoryPtr;
+END;
+
+-- ----------------------------------------------------------------------------
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT NoOfBitsPerSubWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType IS
+ VARIABLE MemoryPtr : VitalMemoryDataType;
+ VARIABLE BitsPerEnable : NATURAL
+ := ((NoOfBitsPerWord-1)
+ /NoOfBitsPerSubWord)+1;
+BEGIN
+ PrintMemoryMessage(MsgVDM,ErrInitMem);
+ MemoryPtr := new VitalMemoryArrayRecType '(
+ NoOfWords => NoOfWords,
+ NoOfBitsPerWord => NoOfBitsPerWord,
+ NoOfBitsPerSubWord => NoOfBitsPerSubWord,
+ NoOfBitsPerEnable => BitsPerEnable,
+ MemoryArrayPtr => NULL
+ );
+ MemoryPtr.MemoryArrayPtr
+ := new MemoryArrayType (0 to MemoryPtr.NoOfWords - 1);
+ FOR i IN 0 TO MemoryPtr.NoOfWords - 1 LOOP
+ MemoryPtr.MemoryArrayPtr(i)
+ := new MemoryWordType (MemoryPtr.NoOfBitsPerWord - 1 DOWNTO 0);
+ END LOOP;
+ IF (MemoryLoadFile /= "") THEN
+ LoadMemory (MemoryPtr, MemoryLoadFile, BinaryLoadFile);
+ END IF;
+ RETURN MemoryPtr;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryTable
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- PrevDataInBus - Previous data bus for edge detection
+-- PrevAddressBus - Previous address bus for edge detection
+-- PortFlag - Indicates port operating mode
+-- PortFlagArray - Vector form of PortFlag for sub-word
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- MemoryTable - Input memory action table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure implements the majority of the memory
+-- modeling functionality via lookup of the memory action
+-- tables and performing the specified actions if matches
+-- are found, or the default actions otherwise. The
+-- overloadings are provided for the word and sub-word
+-- (using the EnableBus and PortFlagArray arguments) addressing
+-- cases.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ VARIABLE HighBit : NATURAL := MemoryData.NoOfBitsPerWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr
+ VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Optimize for case when all current inputs are same as previous
+ IF (PrevDataInBus = DataInBus
+ AND PrevAddressBus = AddressBus
+ AND PrevControls = Controls
+ AND PortFlag(0).MemoryCurrent = PortFlag(0).MemoryPrevious
+ AND PortFlag(0).DataCurrent = PortFlag(0).DataPrevious) THEN
+ PortFlag(0).OutputDisable := TRUE;
+ RETURN;
+ END IF;
+
+ PortFlag(0).DataPrevious := PortFlag(0).DataCurrent;
+ PortFlag(0).MemoryPrevious := PortFlag(0).MemoryCurrent;
+ PortFlag(0).OutputDisable := FALSE;
+ PortFlagTmp := PortFlag(0);
+
+ -- Convert address bus to integer value and table lookup flag
+ DecodeAddress(
+ Address => Address ,
+ AddrFlag => AddrFlag ,
+ MemoryData => MemoryData ,
+ PrevAddressBus => PrevAddressBus ,
+ AddressBus => AddressBus
+ );
+
+ -- Interpret data bus as a table lookup flag
+ DecodeData (
+ DataFlag => DataFlag ,
+ PrevDataInBus => PrevDataInBus ,
+ DataInBus => DataInBus ,
+ HighBit => HighBit ,
+ LowBit => LowBit
+ );
+
+ -- Lookup memory and data actions
+ MemoryTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ PrevControls => PrevControls ,
+ Controls => Controls ,
+ AddrFlag => AddrFlag ,
+ DataFlag => DataFlag ,
+ MemoryTable => MemoryTable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Set the output PortFlag(0) value
+ IF (DataAction = 'S') THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious
+ AND PortFlagTmp.DataCurrent = HIGHZ) THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ PortFlag(0) := PortFlagTmp;
+
+ -- Set previous values for subsequent edge detection
+ PrevControls := Controls;
+ PrevDataInBus := DataInBus;
+ PrevAddressBus := AddressBus;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+ -- Set the output AddressValue for VitalMemoryCrossPorts
+ AddressValue := Address;
+
+END VitalMemoryTable;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevEnableBus : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr
+ VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Optimize for case when all current inputs are same as previous
+ IF (PrevDataInBus = DataInBus
+ AND PrevAddressBus = AddressBus
+ AND PrevControls = Controls) THEN
+ CheckFlags:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (PortFlagArray(i).MemoryCurrent /= PortFlagArray(i).MemoryPrevious
+ OR PortFlagArray(i).DataCurrent /= PortFlagArray(i).DataPrevious) THEN
+ EXIT CheckFlags;
+ END IF;
+ IF (i = BitsPerEnable-1) THEN
+ FOR j IN 0 TO BitsPerEnable-1 LOOP
+ PortFlagArray(j).OutputDisable := TRUE;
+ END LOOP;
+ RETURN;
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- Convert address bus to integer value and table lookup flag
+ DecodeAddress(
+ Address => Address,
+ AddrFlag => AddrFlag,
+ MemoryData => MemoryData,
+ PrevAddressBus => PrevAddressBus,
+ AddressBus => AddressBus
+ );
+
+ -- Perform independent operations for each sub-word
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+
+ -- Set the output PortFlag(i) value
+ PortFlagArray(i).DataPrevious := PortFlagArray(i).DataCurrent;
+ PortFlagArray(i).MemoryPrevious := PortFlagArray(i).MemoryCurrent;
+ PortFlagArray(i).OutputDisable := FALSE;
+ PortFlagTmp := PortFlagArray(i);
+
+ -- Interpret data bus as a table lookup flag
+ DecodeData (
+ DataFlag => DataFlag ,
+ PrevDataInBus => PrevDataInBus ,
+ DataInBus => DataInBus ,
+ HighBit => HighBit ,
+ LowBit => LowBit
+ );
+
+ -- Lookup memory and data actions
+ MemoryTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ PrevControls => PrevControls ,
+ PrevEnableBus => PrevEnableBus ,
+ Controls => Controls ,
+ EnableBus => EnableBus ,
+ EnableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable ,
+ AddrFlag => AddrFlag ,
+ DataFlag => DataFlag ,
+ MemoryTable => MemoryTable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Set the output PortFlag(i) value
+ IF (DataAction = 'S') THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious
+ AND PortFlagTmp.DataCurrent = HIGHZ) THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ PortFlagArray(i) := PortFlagTmp;
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+
+ END LOOP;
+
+ -- Set previous values for subsequent edge detection
+ PrevControls := Controls;
+ PrevEnableBus := EnableBus;
+ PrevDataInBus := DataInBus;
+ PrevAddressBus := AddressBus;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+ -- Set the output AddressValue for VitalMemoryCrossPorts
+ AddressValue := Address;
+
+END VitalMemoryTable;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryCrossPorts
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- SamePortFlag - Operating mode for same port
+-- SamePortAddressValue - Operating modes for cross ports
+-- CrossPortAddressArray - Decoded AddressBus for cross ports
+-- CrossPortMode - Write contention and crossport read control
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- Description: These procedures control the effect of memory operations
+-- on a given port due to operations on other ports in a
+-- multi-port memory.
+-- This includes data write through when reading and writing
+-- to the same address, as well as write contention when
+-- there are multiple write to the same address.
+-- If addresses do not match then data bus is unchanged.
+-- The DataOutBus can be diabled with 'Z' value.
+-- If the WritePortFlag is 'CORRUPT', that would mean
+-- that the whole memory is corrupted. So, for corrupting
+-- the Read port, the Addresses need not be compared.
+--
+-- CrossPortMode Enum Description
+-- 1. CpRead Allows Cross Port Read Only
+-- No contention checking.
+-- 2. WriteContention Allows for write contention checks
+-- only between multiple write ports
+-- 3. ReadWriteContention Allows contention between read and
+-- write ports. The action is to corrupt
+-- the memory and the output bus.
+-- 4. CpReadAndWriteContention Is a combination of 1 & 2
+-- 5. CpReadAndReadContention Allows contention between read and
+-- write ports. The action is to corrupt
+-- the dataout bus only. The cp read is
+-- performed if not contending.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT SamePortAddressValue : IN VitalAddressValueType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT CrossPortMode : IN VitalCrossPortModeType
+ := CpReadAndWriteContention;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) := (OTHERS => 'Z');
+ VARIABLE MemoryTmp : std_logic_vector(DataOutBus'RANGE);
+ VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE Address : VitalAddressValueType := SamePortAddressValue;
+ VARIABLE AddressJ : VitalAddressValueType;
+ VARIABLE AddressK : VitalAddressValueType;
+ VARIABLE PortFlagI : VitalPortFlagType;
+ VARIABLE PortFlagIJ : VitalPortFlagType;
+ VARIABLE PortFlagIK : VitalPortFlagType;
+ VARIABLE DoCpRead : BOOLEAN := FALSE;
+ VARIABLE DoWrCont : BOOLEAN := FALSE;
+ VARIABLE DoCpCont : BOOLEAN := FALSE;
+ VARIABLE DoRdWrCont : BOOLEAN := FALSE;
+ VARIABLE CpWrCont : BOOLEAN := FALSE;
+ VARIABLE ModeWrCont : BOOLEAN :=
+ (CrossPortMode=WriteContention) OR
+ (CrossPortMode=CpReadAndWriteContention);
+ VARIABLE ModeCpRead : BOOLEAN :=
+ (CrossPortMode=CpRead) OR
+ (CrossPortMode=CpReadAndWriteContention);
+ VARIABLE ModeCpCont : BOOLEAN := (CrossPortMode=ReadWriteContention);
+ VARIABLE ModeRdWrCont : BOOLEAN := (CrossPortMode=CpReadAndReadContention);
+
+BEGIN
+
+ -- Check for disabled port (i.e. OTHERS => 'Z')
+ IF (DataOutBus = DataOutTmp) THEN
+ RETURN;
+ ELSE
+ DataOutTmp := DataOutBus;
+ END IF;
+
+ -- Check for error in address
+ IF (Address < 0) THEN
+ RETURN;
+ END IF;
+
+ ReadMemory(MemoryData,MemoryTmp,Address);
+
+ SubWordLoop: -- For each slice of the sub-word I
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ PortFlagI := SamePortFlag(i);
+
+ -- For each cross port J: check with same port address
+ FOR j IN 0 TO CrossPorts-1 LOOP
+ PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable);
+ AddressJ := CrossPortAddressArray(j);
+ IF (AddressJ < 0) THEN
+ NEXT;
+ END IF;
+ DoWrCont := (Address = AddressJ) AND
+ (ModeWrCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = WRITE) OR
+ (PortFlagI.MemoryCurrent = CORRUPT)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoCpRead := (Address = AddressJ) AND
+ (ModeCpRead = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoCpCont := (Address = AddressJ) AND
+ (ModeCpCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoRdWrCont:= (Address = AddressJ) AND
+ (ModeRdWrCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ IF (DoWrCont OR DoCpCont) THEN
+ -- Corrupt dataout and memory
+ MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ SamePortFlag(i).MemoryCurrent := CORRUPT;
+ SamePortFlag(i).DataCurrent := CORRUPT;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ IF (DoCpRead) THEN
+ -- Update dataout with memory
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ MemoryTmp(HighBit DOWNTO LowBit);
+ SamePortFlag(i).MemoryCurrent := READ;
+ SamePortFlag(i).DataCurrent := READ;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ IF (DoRdWrCont) THEN
+ -- Corrupt dataout only
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ SamePortFlag(i).DataCurrent := CORRUPT;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+
+ END LOOP; -- SubWordLoop
+
+ DataOutBus := DataOutTmp;
+
+ IF (DoWrCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpWrCont,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,Address);
+ END IF;
+
+ IF (DoCpCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpCont,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,Address);
+ END IF;
+
+ IF (DoCpRead) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpRead,HeaderMsg,PortName);
+ END IF;
+ END IF;
+
+ IF (DoRdWrCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpRdWrCo,HeaderMsg,PortName);
+ END IF;
+ END IF;
+
+END VitalMemoryCrossPorts;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE MemoryTmp : std_logic_vector(BitsPerWord-1 DOWNTO 0);
+ VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE AddressJ : VitalAddressValueType;
+ VARIABLE AddressK : VitalAddressValueType;
+ VARIABLE PortFlagIJ : VitalPortFlagType;
+ VARIABLE PortFlagIK : VitalPortFlagType;
+ VARIABLE CpWrCont : BOOLEAN := FALSE;
+
+BEGIN
+
+ SubWordLoop: -- For each slice of the sub-word I
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+
+ -- For each cross port J: check with each cross port K
+ FOR j IN 0 TO CrossPorts-1 LOOP
+ PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable);
+ AddressJ := CrossPortAddressArray(j);
+ -- Check for error in address
+ IF (AddressJ < 0) THEN
+ NEXT;
+ END IF;
+ ReadMemory(MemoryData,MemoryTmp,AddressJ);
+ -- For each cross port K
+ FOR k IN 0 TO CrossPorts-1 LOOP
+ IF (k <= j) THEN
+ NEXT;
+ END IF;
+ PortFlagIK := CrossPortFlagArray(i+k*BitsPerEnable);
+ AddressK := CrossPortAddressArray(k);
+ -- Check for error in address
+ IF (AddressK < 0) THEN
+ NEXT;
+ END IF;
+ CpWrCont := ( (AddressJ = AddressK) AND
+ (PortFlagIJ.MemoryCurrent = WRITE) AND
+ (PortFlagIK.MemoryCurrent = WRITE) ) OR
+ ( (PortFlagIJ.MemoryCurrent = WRITE) AND
+ (PortFlagIK.MemoryCurrent = CORRUPT) ) OR
+ ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND
+ (PortFlagIK.MemoryCurrent = WRITE) ) OR
+ ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND
+ (PortFlagIK.MemoryCurrent = CORRUPT) ) ;
+ IF (CpWrCont) THEN
+ -- Corrupt memory only
+ MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ EXIT;
+ END IF;
+ END LOOP; -- FOR k IN 0 TO CrossPorts-1 LOOP
+ IF (CpWrCont = TRUE) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpWrCont,HeaderMsg);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,AddressJ);
+ END IF;
+ END LOOP; -- FOR j IN 0 TO CrossPorts-1 LOOP
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+ END LOOP; -- SubWordLoop
+
+END VitalMemoryCrossPorts;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryViolation
+-- Parameters: DataOutBus - Output zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates port operating mode
+-- TimingDataArray - This is currently not used (comment out)
+-- ViolationArray - Aggregation of violation variables
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- ViolationTable - Input memory violation table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure is intended to implement all actions on the
+-- memory contents and data out bus as a result of timing viols.
+-- It uses the memory action table to perform various corruption
+-- policies specified by the user.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN X01ArrayT;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ -- VMT relies on the corrupt masks so HighBit/LowBit are full word
+ VARIABLE HighBit : NATURAL := BitsPerWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE VFlagArrayTmp : std_logic_vector
+ (0 TO ViolationFlagsArray'LENGTH-1);
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Don't do anything if given an error address
+ IF (AddressValue < 0) THEN
+ RETURN;
+ END IF;
+
+ FOR i IN ViolationFlagsArray'RANGE LOOP
+ VFlagArrayTmp(i) := ViolationFlagsArray(i);
+ END LOOP;
+
+ -- Lookup memory and data actions
+ ViolationTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => VFlagArrayTmp ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Need to read incoming PF value (was not before)
+ PortFlagTmp := PortFlag(0);
+
+ IF (PortType = READ OR PortType = RDNWR) THEN
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => AddressValue ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => ViolationTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMV ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+ END IF;
+
+ IF (PortType = WRITE OR PortType = RDNWR) THEN
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => AddressValue ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => ViolationTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMV ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+ END IF;
+
+ -- Check if we need to turn off PF.OutputDisable
+ IF (DataAction /= 'S') THEN
+ PortFlagTmp.OutputDisable := FALSE;
+ -- Set the output PortFlag(0) value
+ -- Note that all bits of PortFlag get PortFlagTmp
+ FOR i IN PortFlag'RANGE LOOP
+ PortFlag(i) := PortFlagTmp;
+ END LOOP;
+ END IF;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+END;
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE VFlagArrayTmp : X01ArrayT (0 TO 0);
+
+BEGIN
+
+ VitalMemoryViolation (
+ DataOutBus => DataOutBus ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlag ,
+ DataInBus => DataInBus ,
+ AddressValue => AddressValue ,
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => VFlagArrayTmp ,
+ ViolationSizesArray => ( 0 => 0 ) ,
+ ViolationTable => ViolationTable ,
+ PortType => PortType ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn ,
+ MsgSeverity => MsgSeverity
+ );
+
+END;
+
+END Vital_Memory ;
diff --git a/libraries/vital2000/memory_p.vhdl b/libraries/vital2000/memory_p.vhdl
new file mode 100644
index 000000000..83874f45e
--- /dev/null
+++ b/libraries/vital2000/memory_p.vhdl
@@ -0,0 +1,1729 @@
+-- ----------------------------------------------------------------------------
+-- Title : Standard VITAL Memory Package
+-- :
+-- Library : Vital_Memory
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- : Ekambaram Balaji, LSI Logic Corporation
+-- : Jose De Castro, Consultant
+-- : Prakash Bare, GDA Technologies
+-- : William Yam, LSI Logic Corporation
+-- : Dennis Brophy, Model Technology
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC memory models.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Ver:|Auth:| Date:| Changes Made:
+-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal
+-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme
+-- 0.3 | jdc |090297| Extensive updates for TAG review (functional)
+-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable
+-- | | | Added interface of VitalMemoryCrossPorts() &
+-- | | | VitalMemoryViolation().
+-- 0.5 | jdc |092997| Completed naming changes thoughout package body.
+-- | | | Testing with simgle port test model looks ok.
+-- 0.6 | jdc |121797| Major updates to the packages:
+-- | | | - Implement VitalMemoryCrossPorts()
+-- | | | - Use new VitalAddressValueType
+-- | | | - Use new VitalCrossPortModeType enum
+-- | | | - Overloading without SamePort args
+-- | | | - Honor erroneous address values
+-- | | | - Honor ports disabled with 'Z'
+-- | | | - Implement implicit read 'M' table symbol
+-- | | | - Cleanup buses to use (H DOWNTO L)
+-- | | | - Message control via MsgOn,HeaderMsg,PortName
+-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases
+-- 0.7 | jdc |052698| Bug fixes to the packages:
+-- | | | - Fix failure with negative Address values
+-- | | | - Added debug messages for VMT table search
+-- | | | - Remove 'S' for action column (only 's')
+-- | | | - Remove 's' for response column (only 'S')
+-- | | | - Remove 'X' for action and response columns
+-- 0.8 | jdc |061298| Implemented VitalMemoryViolation()
+-- | | | - Minimal functionality violation tables
+-- | | | - Missing:
+-- | | | - Cannot handle wide violation variables
+-- | | | - Cannot handle sub-word cases
+-- | | | Fixed IIC version of MemoryMatch
+-- | | | Fixed 'M' vs 'm' switched on debug output
+-- | | | TO BE DONE:
+-- | | | - Implement 'd' corrupting a single bit
+-- | | | - Implement 'D' corrupting a single bit
+-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType
+-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType
+-- 0.11|eb/sc|081798| Added overloaded function interface for
+-- | | | VitalDeclareMemory
+-- 0.14| jdc |113198| Merging of memory functionality and version
+-- | | | 1.4 9/17/98 of timing package from Prakash
+-- 0.15| jdc |120198| Major development of VMV functionality
+-- 0.16| jdc |120298| Complete VMV functionlality for initial testing
+-- | | | - New ViolationTableCorruptMask() procedure
+-- | | | - New MemoryTableCorruptMask() procedure
+-- | | | - HandleMemoryAction():
+-- | | | - Removed DataOutBus bogus output
+-- | | | - Replaced DataOutTmp with DataInTmp
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'c','l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit
+-- | | | - HandleDataAction():
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'L','D','E' to use HighBit, LowBit
+-- | | | - MemoryTableLookUp():
+-- | | | - Added MsgOn table debug output
+-- | | | - Uses new MemoryTableCorruptMask()
+-- | | | - ViolationTableLookUp():
+-- | | | - Uses new ViolationTableCorruptMask()
+-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType,
+-- | | | VitalMemoryViolationTableType data
+-- | | | types but not used yet (need to discuss)
+-- | | | - Added overload for VitalMemoryViolation()
+-- | | | which does not have array flags
+-- | | | - Bug fixes for VMV functionality:
+-- | | | - ViolationTableLookUp() not handling '-' in
+-- | | | scalar violation matching
+-- | | | - VitalMemoryViolation() now normalizes
+-- | | | VFlagArrayTmp'LEFT as LSB before calling
+-- | | | ViolationTableLookUp() for proper scanning
+-- | | | - ViolationTableCorruptMask() had to remove
+-- | | | normalization of CorruptMaskTmp and
+-- | | | ViolMaskTmp for proper MSB:LSB corruption
+-- | | | - HandleMemoryAction(), HandleDataAction()
+-- | | | - Removed 'D','E' since not being used
+-- | | | - Use XOR instead of OR for corrupt masks
+-- | | | - Now 'd' is sensitive to HighBit, LowBit
+-- | | | - Fixed LowBit overflow in bit writeable case
+-- | | | - MemoryTableCorruptMask()
+-- | | | - ViolationTableCorruptMask()
+-- | | | - VitalMemoryTable()
+-- | | | - VitalMemoryCrossPorts()
+-- | | | - Fixed VitalMemoryViolation() failing on
+-- | | | error AddressValue from earlier VMT()
+-- | | | - Minor cleanup of code formatting
+-- 0.18| jdc |032599| - In VitalDeclareMemory()
+-- | | | - Added BinaryLoadFile formal arg and
+-- | | | modified LoadMemory() to handle bin
+-- | | | - Added NOCHANGE to VitalPortFlagType
+-- | | | - For VitalCrossPortModeType
+-- | | | - Added CpContention enum
+-- | | | - In HandleDataAction()
+-- | | | - Set PortFlag := NOCHANGE for 'S'
+-- | | | - In HandleMemoryAction()
+-- | | | - Set PortFlag := NOCHANGE for 's'
+-- | | | - In VitalMemoryTable() and
+-- | | | VitalMemoryViolation()
+-- | | | - Honor PortFlag = NOCHANGE returned
+-- | | | from HandleMemoryAction()
+-- | | | - In VitalMemoryCrossPorts()
+-- | | | - Fixed Address = AddressJ for all
+-- | | | conditions of DoWrCont & DoCpRead
+-- | | | - Handle CpContention like WrContOnly
+-- | | | under CpReadOnly conditions, with
+-- | | | associated memory message changes
+-- | | | - Handle PortFlag = NOCHANGE like
+-- | | | PortFlag = READ for actions
+-- | | | - Modeling change:
+-- | | | - Need to init PortFlag every delta
+-- | | | PortFlag_A := (OTHES => UNDEF);
+-- | | | - Updated InternalTimingCheck code
+-- 0.19| jdc |042599| - Fixes for bit-writeable cases
+-- | | | - Check PortFlag after HandleDataAction
+-- | | | in VitalMemoryViolation()
+-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash
+-- | | | and Willian:
+-- | | | VitalMemorySchedulePathDelay()
+-- | | | VitalMemoryExpandPortFlag()
+-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums,
+-- | | | added new CpReadAndReadContention.
+-- | | | - Fixed VitalMemoryCrossPorts() parameter
+-- | | | SamePortFlag to INOUT so that it can
+-- | | | set CORRUPT or READ value.
+-- | | | - Fixed VitalMemoryTable() where PortFlag
+-- | | | setting by HandleDataAction() is being
+-- | | | ignored when HandleMemoryAction() sets
+-- | | | PortFlagTmp to NOCHANGE.
+-- | | | - Fixed VitalMemoryViolation() to set
+-- | | | all bits of PortFlag when violating.
+-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData
+-- | | | checks whether the previous state is HIGHZ.
+-- | | | If yes then portFlag should be NOCHANGE
+-- | | | for VMPD to ignore IORetain corruption.
+-- | | | The idea is that the first Z should be
+-- | | | propagated but later ones should be ignored.
+-- | | |
+-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99
+-- | | | - Changed VitalPortFlagType to record of
+-- | | | new VitalPortStateType to hold current,
+-- | | | previous values and separate disable.
+-- | | | Also created VitalDefaultPortFlag const.
+-- | | | Removed usage of PortFlag NOCHANGE
+-- | | | - VitalMemoryTable() changes:
+-- | | | Optimized return when all curr = prev
+-- | | | AddressValue is now INOUT to optimize
+-- | | | Transfer PF.MemoryCurrent to MemoryPrevious
+-- | | | Transfer PF.DataCurrent to DataPrevious
+-- | | | Reset PF.OutputDisable to FALSE
+-- | | | Expects PortFlag init in declaration
+-- | | | No need to init PortFlag every delta
+-- | | | - VitalMemorySchedulePathDelay() changes:
+-- | | | Initialize with VitalDefaultPortFlag
+-- | | | Check PortFlag.OutputDisable
+-- | | | - HandleMemoryAction() changes:
+-- | | | Set value of PortFlag.MemoryCurrent
+-- | | | Never set PortFlag.OutputDisable
+-- | | | - HandleDataAction() changes:
+-- | | | Set value of PortFlag.DataCurrent
+-- | | | Set PortFlag.DataCurrent for HIGHZ
+-- | | | - VitalMemoryCrossPorts() changes:
+-- | | | Check/set value of PF.MemoryCurrent
+-- | | | Check value of PF.OutputDisable
+-- | | | - VitalMemoryViolation() changes:
+-- | | | Fixed bug - not reading inout PF value
+-- | | | Clean up setting of PortFlag
+-- 0.24| jdc |100899| - Modified update of PF.OutputDisable
+-- | | | to correctly accomodate 2P1W1R case:
+-- | | | the read port should not exhibit
+-- | | | IO retain corrupt when reading
+-- | | | addr unrelated to addr being written.
+-- 0.25| jdc |100999| - VitalMemoryViolation() change:
+-- | | | Fixed bug with RDNWR mode incorrectly
+-- | | | updating the PF.OutputDisable
+-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change:
+-- | | | Fixed bugs with update of PF
+-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change:
+-- | | | Added DoRdWrCont message (ErrMcpRdWrCo,
+-- | | | Memory cross port read/write data only
+-- | | | contention)
+-- | | | - VitalMemoryTable() change:
+-- | | | Set PF.OutputDisable := TRUE for the
+-- | | | optimized cases.
+-- 0.28| pb |112399| - Added 8 VMPD procedures for vector
+-- | | | PathCondition support. Now the total
+-- | | | number of overloadings for VMPD is 24.
+-- | | | - Number of overloadings for SetupHold
+-- | | | procedures increased to 5. Scalar violations
+-- | | | are not supported anymore. Vector checkEnabled
+-- | | | support is provided through the new overloading
+-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction()
+-- | | | Reinstated 'D' and 'E' actions but
+-- | | | with new PortFlagType
+-- | | | - Updated file handling syntax, must compile
+-- | | | with -93 syntax now.
+-- 0.30| jdc |022300| - Formated for 80 column max width
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.Vital_Timing.ALL;
+USE IEEE.Vital_Primitives.ALL;
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE Vital_Memory IS
+
+-- ----------------------------------------------------------------------------
+-- Timing Section
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Types and constants for Memory timing procedures
+-- ----------------------------------------------------------------------------
+TYPE VitalMemoryArcType IS (ParallelArc, CrossArc, SubwordArc);
+TYPE OutputRetainBehaviorType IS (BitCorrupt, WordCorrupt);
+TYPE VitalMemoryMsgFormatType IS (Vector, Scalar, VectorEnum);
+TYPE X01ArrayT IS ARRAY (NATURAL RANGE <> ) OF X01;
+TYPE X01ArrayPT IS ACCESS X01ArrayT;
+TYPE VitalMemoryViolationType IS ACCESS X01ArrayT;
+CONSTANT DefaultNumBitsPerSubword : INTEGER := -1;
+
+
+-- Data type storing path delay and schedule information for output bits
+TYPE VitalMemoryScheduleDataType IS RECORD
+ OutputData : std_ulogic;
+ NumBitsPerSubWord : INTEGER;
+ ScheduleTime : TIME;
+ ScheduleValue : std_ulogic;
+ LastOutputValue : std_ulogic;
+ PropDelay : TIME;
+ OutputRetainDelay : TIME;
+ InputAge : TIME;
+END RECORD;
+
+TYPE VitalMemoryTimingDataType IS RECORD
+ NotFirstFlag : BOOLEAN;
+ RefLast : X01;
+ RefTime : TIME;
+ HoldEn : BOOLEAN;
+ TestLast : std_ulogic;
+ TestTime : TIME;
+ SetupEn : BOOLEAN;
+ TestLastA : VitalLogicArrayPT;
+ TestTimeA : VitalTimeArrayPT;
+ RefLastA : X01ArrayPT;
+ RefTimeA : VitalTimeArrayPT;
+ HoldEnA : VitalBoolArrayPT;
+ SetupEnA : VitalBoolArrayPT;
+END RECORD;
+
+TYPE VitalPeriodDataArrayType IS ARRAY (NATURAL RANGE <>) OF
+ VitalPeriodDataType;
+
+-- Data type storing path delay and schedule information for output
+-- vectors
+TYPE VitalMemoryScheduleDataVectorType IS ARRAY (NATURAL RANGE <> ) OF
+ VitalMemoryScheduleDataType;
+
+-- VitalPortFlagType records runtime mode of port sub-word slices
+-- TYPE VitalPortFlagType IS (
+-- UNDEF,
+-- READ,
+-- WRITE,
+-- CORRUPT,
+-- HIGHZ,
+-- NOCHANGE
+-- );
+
+-- VitalPortFlagType records runtime mode of port sub-word slices
+TYPE VitalPortStateType IS (
+ UNDEF,
+ READ,
+ WRITE,
+ CORRUPT,
+ HIGHZ
+);
+
+TYPE VitalPortFlagType IS RECORD
+ MemoryCurrent : VitalPortStateType;
+ MemoryPrevious : VitalPortStateType;
+ DataCurrent : VitalPortStateType;
+ DataPrevious : VitalPortStateType;
+ OutputDisable : BOOLEAN;
+END RECORD;
+
+CONSTANT VitalDefaultPortFlag : VitalPortFlagType := (
+ MemoryCurrent => READ,
+ MemoryPrevious => UNDEF,
+ DataCurrent => READ,
+ DataPrevious => UNDEF,
+ OutputDisable => FALSE
+);
+
+-- VitalPortFlagVectorType to be same width i as enables of a port
+-- or j multiples thereof, where j is the number of cross ports
+TYPE VitalPortFlagVectorType IS
+ ARRAY (NATURAL RANGE <>) OF VitalPortFlagType;
+
+-- ----------------------------------------------------------------------------
+-- Functions : VitalMemory path delay procedures
+-- - VitalMemoryInitPathDelay
+-- - VitalMemoryAddPathDelay
+-- - VitalMemorySchedulePathDelay
+--
+-- Description: VitalMemoryInitPathDelay, VitalMemoryAddPathDelay and
+-- VitalMemorySchedulePathDelay are Level 1 routines used
+-- for selecting the propagation delay paths based on
+-- path condition, transition type and delay values and
+-- schedule a new output value.
+--
+-- Following features are implemented in these procedures:
+-- o condition dependent path selection
+-- o Transition dependent delay selection
+-- o shortest delay path selection from multiple
+-- candidate paths
+-- o Scheduling of the computed values on the specified
+-- signal.
+-- o output retain behavior if outputRetain flag is set
+-- o output mapping to alternate strengths to model
+-- pull-up, pull-down etc.
+--
+-- <More details to be added here>
+--
+-- Following is information on overloading of the procedures.
+--
+-- VitalMemoryInitPathDelay is overloaded for ScheduleDataArray and
+-- OutputDataArray
+--
+-- ----------------------------------------------------------------------------
+-- ScheduleDataArray OutputDataArray
+-- ----------------------------------------------------------------------------
+-- Scalar Scalar
+-- Vector Vector
+-- ----------------------------------------------------------------------------
+--
+--
+-- VitalMemoryAddPathDelay is overloaded for ScheduleDataArray,
+-- PathDelayArray, InputSignal and delaytype.
+--
+-- ----------------------------------------------------------------------------
+-- DelayType InputSignal ScheduleData PathDelay
+-- Array Array
+-- ----------------------------------------------------------------------------
+-- VitalDelayType Scalar Scalar Scalar
+-- VitalDelayType Scalar Vector Vector
+-- VitalDelayType Vector Scalar Vector
+-- VitalDelayType Vector Vector Vector
+-- VitalDelayType01 Scalar Scalar Scalar
+-- VitalDelayType01 Scalar Vector Vector
+-- VitalDelayType01 Vector Scalar Vector
+-- VitalDelayType01 Vector Vector Vector
+-- VitalDelayType01Z Scalar Scalar Scalar
+-- VitalDelayType01Z Scalar Vector Vector
+-- VitalDelayType01Z Vector Scalar Vector
+-- VitalDelayType01Z Vector Vector Vector
+-- VitalDelayType01XZ Scalar Scalar Scalar
+-- VitalDelayType01XZ Scalar Vector Vector
+-- VitalDelayType01XZ Vector Scalar Vector
+-- VitalDelayType01XZ Vector Vector Vector
+-- ----------------------------------------------------------------------------
+--
+--
+-- VitalMemorySchedulePathDelay is overloaded for ScheduleDataArray,
+-- and OutSignal
+--
+-- ----------------------------------------------------------------------------
+-- OutSignal ScheduleDataArray
+-- ----------------------------------------------------------------------------
+-- Scalar Scalar
+-- Vector Vector
+-- ----------------------------------------------------------------------------
+--
+-- Procedure Declarations:
+--
+--
+-- Function : VitalMemoryInitPathDelay
+--
+-- Arguments:
+--
+-- INOUT Type Description
+--
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each output bit
+--
+--
+-- IN
+--
+-- OutputDataArray/ STD_LOGIC_VECTOR/Array containing current output
+-- OutputData STD_ULOGIC value
+--
+--
+-- NumBitsPerSubWord INTEGER Number of bits per subword.
+-- Default value of this argument
+-- is DefaultNumBitsPerSubword
+-- which is interpreted as no
+-- subwords
+--
+-- ----------------------------------------------------------------------------
+--
+--
+-- ScheduleDataArray - Vector
+-- OutputDataArray - Vector
+--
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword
+);
+--
+-- ScheduleDataArray - Scalar
+-- OutputDataArray - Scalar
+--
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ VARIABLE OutputData : IN STD_ULOGIC
+);
+
+-- ----------------------------------------------------------------------------
+--
+-- Function : VitalMemoryAddPathDelay
+--
+-- Arguments
+--
+-- INOUT Type Description
+--
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each output bit
+--
+-- InputChangeTimeArray/ VitaltimeArrayT/Time
+-- InputChangeTime Holds the time since the last
+-- input change
+--
+-- IN
+--
+-- InputSignal STD_LOGIC_VECTOR
+-- STD_ULOGIC/ Array holding the input value
+--
+-- OutputSignalName STRING The output signal name
+--
+-- PathDelayArray/ VitalDelayArrayType01ZX,
+-- PathDelay VitalDelayArrayType01Z,
+-- VitalDelayArrayType01,
+-- VitalDelayArrayType/
+-- VitalDelayType01ZX,
+-- VitalDelayType01Z,
+-- VitalDelayType01,
+-- VitalDelayType Array of delay values
+--
+-- ArcType VitalMemoryArcType
+-- Indicates the Path type. This
+-- can be SubwordArc, CrossArc or
+-- ParallelArc
+--
+-- PathCondition BOOLEAN If True, the transition in
+-- the corresponding input signal
+-- is considered while
+-- caluculating the prop. delay
+-- else the transition is ignored.
+--
+-- OutputRetainFlag BOOLEAN If specified TRUE,output retain
+-- (hold) behavior is implemented.
+--
+-- ----------------------------------------------------------------------------
+--
+-- #1
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #2
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #3
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+);
+
+-- #4
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #5
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #6
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+);
+
+-- #7
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #8
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #9
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+);
+
+-- #10
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #11
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #12
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+);
+
+-- #13
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #14
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #15
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #16
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #17
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #18
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #19
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #20
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #21
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #22
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #23
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #24
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- ----------------------------------------------------------------------------
+--
+-- Function : VitalMemorySchedulePathDelay
+--
+-- Arguments:
+--
+-- OUT Type Description
+-- OutSignal STD_LOGIC_VECTOR/ The output signal for
+-- STD_ULOGIC scheduling
+--
+-- IN
+-- OutputSignalName STRING The name of the output signal
+--
+-- IN
+-- PortFlag VitalPortFlagType Port flag variable from
+-- functional procedures
+--
+-- IN
+-- OutputMap VitalOutputMapType For VitalPathDelay01Z, the
+-- output can be mapped to
+-- alternate strengths to model
+-- tri-state devices, pull-ups
+-- and pull-downs.
+--
+-- INOUT
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each
+-- output bit
+--
+-- ----------------------------------------------------------------------------
+--
+-- ScheduleDataArray - Vector
+-- OutputSignal - Vector
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+);
+--
+-- ScheduleDataArray - Vector
+-- OutputSignal - Vector
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+);
+--
+-- ScheduleDataArray - Scalar
+-- OutputSignal - Scalar
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_ulogic;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType
+);
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryTimingDataInit RETURN VitalMemoryTimingDataType;
+
+-- ----------------------------------------------------------------------------
+--
+-- Function Name: VitalMemorySetupHoldCheck
+--
+-- Description: The VitalMemorySetupHoldCheck procedure detects a setup or a
+-- hold violation on the input test signal with respect
+-- to the corresponding input reference signal. The timing
+-- constraints are specified through parameters
+-- representing the high and low values for the setup and
+-- hold values for the setup and hold times. This
+-- procedure assumes non-negative values for setup and hold
+-- timing constraints.
+--
+-- It is assumed that negative timing constraints
+-- are handled by internally delaying the test or
+-- reference signals. Negative setup times result in
+-- a delayed reference signal. Negative hold times
+-- result in a delayed test signal. Furthermore, the
+-- delays and constraints associated with these and
+-- other signals may need to be appropriately
+-- adjusted so that all constraint intervals overlap
+-- the delayed reference signals and all constraint
+-- values (with respect to the delayed signals) are
+-- non-negative.
+--
+-- This function is overloaded based on the input
+-- TestSignal and reference signals. Parallel, Subword and
+-- Cross Arc relationships between test and reference
+-- signals are supported.
+--
+-- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX
+-- :
+-- : -->| error region |<--
+-- :
+-- _______________________________
+-- RefSignal \______________________________
+-- : | | |
+-- : | -->| |<-- thold
+-- : -->| tsetup |<--
+--
+-- Arguments:
+--
+-- IN Type Description
+-- TestSignal std_logic_vector Value of test signal
+-- TestSignalName STRING Name of test signal
+-- TestDelay VitalDelayArrayType Model's internal delay associated
+-- with TestSignal
+-- RefSignal std_ulogic Value of reference signal
+-- std_logic_vector
+-- RefSignalName STRING Name of reference signal
+-- RefDelay TIME Model's internal delay associated
+-- VitalDelayArrayType with RefSignal
+-- SetupHigh VitalDelayArrayType Absolute minimum time duration
+-- before the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to proceed
+-- to the "1" state without causing
+-- a setup violation.
+-- SetupLow VitalDelayArrayType Absolute minimum time duration
+-- before the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to proceed
+-- to the "0" state without causing
+-- a setup violation.
+-- HoldHigh VitalDelayArrayType Absolute minimum time duration
+-- after the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to
+-- proceed to the "1" state without
+-- causing a hold violation.
+-- HoldLow VitalDelayArrayType Absolute minimum time duration
+-- after the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to
+-- proceed to the "0" state without
+-- causing a hold violation.
+-- CheckEnabled BOOLEAN Check performed if TRUE.
+-- RefTransition VitalEdgeSymbolType
+-- Reference edge specified. Events
+-- on the RefSignal which match the
+-- edge spec. are used as reference
+-- edges.
+-- ArcType VitalMemoryArcType
+-- NumBitsPerSubWord INTEGER
+-- HeaderMsg STRING String that will accompany any
+-- assertion messages produced.
+-- XOn BOOLEAN If TRUE, Violation output
+-- parameter is set to "X".
+-- Otherwise, Violation is always
+-- set to "0."
+-- MsgOn BOOLEAN If TRUE, set and hold violation
+-- message will be generated.
+-- Otherwise, no messages are
+-- generated, even upon violations.
+-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+-- MsgFormat VitalMemoryMsgFormatType
+-- Format of the Test/Reference
+-- signals in violation messages.
+--
+-- INOUT
+-- TimingData VitalMemoryTimingDataType
+-- VitalMemorySetupHoldCheck information
+-- storage area. This is used
+-- internally to detect reference
+-- edges and record the time of the
+-- last edge.
+--
+-- OUT
+-- Violation X01 This is the violation flag returned.
+-- X01ArrayT Overloaded for array type.
+--
+--
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayType;
+ CONSTANT SetupLow : IN VitalDelayType;
+ CONSTANT HoldHigh : IN VitalDelayType;
+ CONSTANT HoldLow : IN VitalDelayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+--------------- following are not needed --------------------------
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+
+-- ----------------------------------------------------------------------------
+--
+-- Function Name: VitalPeriodPulseCheck
+--
+-- Description: VitalPeriodPulseCheck checks for minimum and maximum
+-- periodicity and pulse width for "1" and "0" values of
+-- the input test signal. The timing constraint is
+-- specified through parameters representing the minimal
+-- period between successive rising and falling edges of
+-- the input test signal and the minimum pulse widths
+-- associated with high and low values.
+--
+-- VitalPeriodCheck's accepts rising and falling edges
+-- from 1 and 0 as well as transitions to and from 'X.'
+--
+-- _______________ __________
+-- ____________| |_______|
+--
+-- |<--- pw_hi --->|
+-- |<-------- period ----->|
+-- -->| pw_lo |<--
+--
+-- Arguments:
+-- IN Type Description
+-- TestSignal std_logic_vector Value of test signal
+-- TestSignalName STRING Name of the test signal
+-- TestDelay VitalDelayArrayType
+-- Model's internal delay associated
+-- with TestSignal
+-- Period VitalDelayArrayType
+-- Minimum period allowed between
+-- consecutive rising ('P') or
+-- falling ('F') transitions.
+-- PulseWidthHigh VitalDelayArrayType
+-- Minimum time allowed for a high
+-- pulse ('1' or 'H')
+-- PulseWidthLow VitalDelayArrayType
+-- Minimum time allowed for a low
+-- pulse ('0' or 'L')
+-- CheckEnabled BOOLEAN Check performed if TRUE.
+-- HeaderMsg STRING String that will accompany any
+-- assertion messages produced.
+-- XOn BOOLEAN If TRUE, Violation output parameter
+-- is set to "X". Otherwise, Violation
+-- is always set to "0."
+-- MsgOn BOOLEAN If TRUE, period/pulse violation
+-- message will be generated.
+-- Otherwise, no messages are generated,
+-- even though a violation is detected.
+-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+-- MsgFormat VitalMemoryMsgFormatType
+-- Format of the Test/Reference signals
+-- in violation messages.
+--
+-- INOUT
+-- PeriodData VitalPeriodDataArrayType
+-- VitalPeriodPulseCheck information
+-- storage area. This is used
+-- internally to detect reference edges
+-- and record the pulse and period
+-- times.
+-- OUT
+-- Violation X01 This is the violation flag returned.
+-- X01ArrayT Overloaded for array type.
+--
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ CONSTANT Period : IN VitalDelayArrayType;
+ CONSTANT PulseWidthHigh : IN VitalDelayArrayType;
+ CONSTANT PulseWidthLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+);
+
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ CONSTANT Period : IN VitalDelayArrayType;
+ CONSTANT PulseWidthHigh : IN VitalDelayArrayType;
+ CONSTANT PulseWidthLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+);
+
+-- ----------------------------------------------------------------------------
+-- Functionality Section
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- All Memory Types and Record definitions.
+-- ----------------------------------------------------------------------------
+TYPE MemoryWordType IS ARRAY (NATURAL RANGE <>) OF UX01;
+TYPE MemoryWordPtr IS ACCESS MemoryWordType;
+
+TYPE MemoryArrayType IS ARRAY (NATURAL RANGE <>) OF MemoryWordPtr;
+TYPE MemoryArrayPtrType IS ACCESS MemoryArrayType;
+
+TYPE VitalMemoryArrayRecType IS
+RECORD
+NoOfWords : POSITIVE;
+NoOfBitsPerWord : POSITIVE;
+NoOfBitsPerSubWord : POSITIVE;
+NoOfBitsPerEnable : POSITIVE;
+MemoryArrayPtr : MemoryArrayPtrType;
+END RECORD;
+
+TYPE VitalMemoryDataType IS ACCESS VitalMemoryArrayRecType;
+
+TYPE VitalTimingDataVectorType IS
+ARRAY (NATURAL RANGE <>) OF VitalTimingDataType;
+
+TYPE VitalMemoryViolFlagSizeType IS ARRAY (NATURAL RANGE <>) OF INTEGER;
+
+-- ----------------------------------------------------------------------------
+-- Symbol Literals used for Memory Table Modeling
+-- ----------------------------------------------------------------------------
+
+-- Symbol literals from '/' to 'S' are closely related to MemoryTableMatch
+-- lookup matching and the order cannot be arbitrarily changed.
+-- The remaining symbol literals are interpreted directly and matchting is
+-- handled in the MemoryMatch procedure itself.
+
+TYPE VitalMemorySymbolType IS (
+ '/', -- 0 -> 1
+ '\', -- 1 -> 0
+ 'P', -- Union of '/' and '^' (any edge to 1)
+ 'N', -- Union of '\' and 'v' (any edge to 0)
+ 'r', -- 0 -> X
+ 'f', -- 1 -> X
+ 'p', -- Union of '/' and 'r' (any edge from 0)
+ 'n', -- Union of '\' and 'f' (any edge from 1)
+ 'R', -- Union of '^' and 'p' (any possible rising edge)
+ 'F', -- Union of 'v' and 'n' (any possible falling edge)
+ '^', -- X -> 1
+ 'v', -- X -> 0
+ 'E', -- Union of 'v' and '^' (any edge from X)
+ 'A', -- Union of 'r' and '^' (rising edge to or from 'X')
+
+ 'D', -- Union of 'f' and 'v' (falling edge to or from 'X')
+
+ '*', -- Union of 'R' and 'F' (any edge)
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '-', -- don't care
+ 'B', -- 0 or 1
+ 'Z', -- High Impedance
+ 'S', -- steady value
+
+ 'g', -- Good address (no transition)
+ 'u', -- Unknown address (no transition)
+ 'i', -- Invalid address (no transition)
+ 'G', -- Good address (with transition)
+ 'U', -- Unknown address (with transition)
+ 'I', -- Invalid address (with transition)
+
+ 'w', -- Write data to memory
+ 's', -- Retain previous memory contents
+
+ 'c', -- Corrupt entire memory with 'X'
+ 'l', -- Corrupt a word in memory with 'X'
+ 'd', -- Corrupt a single bit in memory with 'X'
+ 'e', -- Corrupt a word with 'X' based on data in
+ 'C', -- Corrupt a sub-word entire memory with 'X'
+ 'L', -- Corrupt a sub-word in memory with 'X'
+
+ -- The following entries are commented since their
+ -- interpretation overlap with existing definitions.
+
+ -- 'D', -- Corrupt a single bit of a sub-word with 'X'
+ -- 'E', -- Corrupt a sub-word with 'X' based on datain
+
+ 'M', -- Implicit read data from memory
+ 'm', -- Read data from memory
+ 't' -- Immediate assign/transfer data in
+
+);
+
+TYPE VitalMemoryTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalMemorySymbolType;
+
+TYPE VitalMemoryViolationSymbolType IS (
+ 'X', -- Unknown level
+ '0', -- low level
+ '-' -- don't care
+);
+
+TYPE VitalMemoryViolationTableType IS
+ ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalMemoryViolationSymbolType;
+
+TYPE VitalPortType IS (
+ UNDEF,
+ READ,
+ WRITE,
+ RDNWR
+);
+
+TYPE VitalCrossPortModeType IS (
+ CpRead, -- CpReadOnly,
+ WriteContention, -- WrContOnly,
+ ReadWriteContention, -- CpContention
+ CpReadAndWriteContention, -- WrContAndCpRead,
+ CpReadAndReadContention
+);
+
+SUBTYPE VitalAddressValueType IS INTEGER;
+TYPE VitalAddressValueVectorType IS
+ ARRAY (NATURAL RANGE <>) OF VitalAddressValueType;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalDeclareMemory
+-- Parameters: NoOfWords - Number of words in the memory
+-- NoOfBitsPerWord - Number of bits per word in memory
+-- NoOfBitsPerSubWord - Number of bits per sub word
+-- MemoryLoadFile - Name of data file to load
+-- Description: This function is intended to be used to initialize
+-- memory data declarations, i.e. to be executed duing
+-- simulation elaboration time. Handles the allocation
+-- and initialization of memory for the memory data.
+-- Default NoOfBitsPerSubWord is NoOfBits.
+-- ----------------------------------------------------------------------------
+
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT NoOfBitsPerSubWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType;
+
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryTable
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- PrevDataInBus - Previous data bus for edge detection
+-- PrevAddressBus - Previous address bus for edge detection
+-- PortFlag - Indicates port operating mode
+-- PortFlagArray - Vector form of PortFlag for sub-word
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- MemoryTable - Input memory action table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure implements the majority of the memory
+-- modeling functionality via lookup of the memory action
+-- tables and performing the specified actions if matches
+-- are found, or the default actions otherwise. The
+-- overloadings are provided for the word and sub-word
+-- (using the EnableBus and PortFlagArray arguments) addressing
+-- cases.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+);
+
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevEnableBus : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+);
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryCrossPorts
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- SamePortFlag - Operating mode for same port
+-- SamePortAddressValue - Decoded AddressBus for same port
+-- CrossPortFlagArray - Operating modes for cross ports
+-- CrossPortAddressArray - Decoded AddressBus for cross ports
+-- CrossPortMode - Write contention and crossport read control
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+--
+-- Description: These procedures control the effect of memory operations
+-- on a given port due to operations on other ports in a
+-- multi-port memory.
+-- This includes data write through when reading and writing
+-- to the same address, as well as write contention when
+-- there are multiple write to the same address.
+-- If addresses do not match then data bus is unchanged.
+-- The DataOutBus can be diabled with 'Z' value.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT SamePortAddressValue : IN VitalAddressValueType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT CrossPortMode : IN VitalCrossPortModeType
+ := CpReadAndWriteContention;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) ;
+
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) ;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryViolation
+-- Parameters: DataOutBus - Output zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates port operating mode
+-- DataInBus - Input value of data bus in
+-- AddressValue - Decoded value of the AddressBus
+-- ViolationFlags - Aggregate of scalar violation vars
+-- ViolationFlagsArray - Concatenation of vector violation vars
+-- ViolationTable - Input memory violation table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure is intended to implement all actions on the
+-- memory contents and data out bus as a result of timing viols.
+-- It uses the memory action table to perform various corruption
+-- policies specified by the user.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN X01ArrayT;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) ;
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) ;
+
+END Vital_Memory;
diff --git a/libraries/vital2000/prmtvs_b.vhdl b/libraries/vital2000/prmtvs_b.vhdl
new file mode 100644
index 000000000..c015e62d5
--- /dev/null
+++ b/libraries/vital2000/prmtvs_b.vhdl
@@ -0,0 +1,5622 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 600 $
+-- :
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #204 - glitch detection prior to OutputMap
+-- ----------------------------------------------------------------------------
+-- v95.2 | ddl | 09/14/96 | #223 - single input prmtvs use on-detect
+-- | | | instead of glitch-on-event behavior
+-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of
+-- | | | of class SIGNAL
+-- v95.4 | ddl | 01/16/97 | #243 - index constraint error in nbit xor/xnor
+-- v99.1 | dbb | 03/31/99 | Updated for VHDL 93
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Default values for Primitives
+ -- ------------------------------------------------------------------------
+ -- default values for delay parameters
+ CONSTANT VitalDefDelay01 : VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z;
+
+ TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME;
+
+ -- default primitive model operation parameters
+ -- Glitch detection/reporting
+ TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch);
+ CONSTANT PrimGlitchMode : VitalGlitchModeType := XOnly;
+
+ -- ------------------------------------------------------------------------
+ -- Local Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- enumeration value representing the transition or level of the signal.
+ -- See function 'GetEdge'
+ ---------------------------------------------------------------------------
+ TYPE EdgeType IS ( 'U', -- Uninitialized level
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '\', -- 1 to 0 falling edge
+ '/', -- 0 to 1 rising edge
+ 'F', -- * to 0 falling edge
+ 'R', -- * to 1 rising edge
+ 'f', -- rising to X edge
+ 'r', -- falling to X edge
+ 'x', -- Unknown edge (ie U->X)
+ 'V' -- Timing violation edge
+ );
+ TYPE EdgeArray IS ARRAY ( NATURAL RANGE <> ) OF EdgeType;
+
+ TYPE EdgeX1Table IS ARRAY ( EdgeType ) OF EdgeType;
+ TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType;
+
+ TYPE LogicToEdgeT IS ARRAY(std_ulogic, std_ulogic) OF EdgeType;
+ TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType;
+
+ TYPE GlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ CurrentValue : std_ulogic;
+ END RECORD;
+ TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF GlitchDataType;
+
+ -- Enumerated type used in selection of output path delays
+ TYPE SchedType IS
+ RECORD
+ inp0 : TIME; -- time (abs) of output change due to input change to 0
+ inp1 : TIME; -- time (abs) of output change due to input change to 1
+ InpX : TIME; -- time (abs) of output change due to input change to X
+ Glch0 : TIME; -- time (abs) of output glitch due to input change to 0
+ Glch1 : TIME; -- time (abs) of output glitch due to input change to 0
+ END RECORD;
+
+ TYPE SchedArray IS ARRAY ( NATURAL RANGE <> ) OF SchedType;
+ CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns);
+ CONSTANT DefSchedAnd : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns);
+
+ -- Constrained array declarations (common sizes used by primitives)
+ SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0);
+ SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0);
+ SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0);
+ SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0);
+
+ SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0);
+ SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0);
+ SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0);
+ SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0);
+
+ SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0);
+ SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0);
+ SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0);
+ SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0);
+
+ SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0);
+ SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0);
+ SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0);
+ SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0);
+
+ CONSTANT DefSchedArray2 : SchedArray2 :=
+ (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns));
+
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+
+ CONSTANT InitialEdge : LogicToLevelT := (
+ '1'|'H' => 'R',
+ '0'|'L' => 'F',
+ OTHERS => 'x'
+ );
+
+ CONSTANT LogicToEdge : LogicToEdgeT := ( -- previous, current
+ -- old \ new: U X 0 1 Z W L H -
+ 'U' => ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ),
+ 'X' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ '0' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ '1' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ 'Z' => ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ),
+ 'W' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ 'L' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ 'H' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ '-' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' )
+ );
+ CONSTANT LogicToLevel : LogicToLevelT := (
+ '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X'
+ );
+
+ -- -----------------------------------
+ -- 3-state logic tables
+ -- -----------------------------------
+ CONSTANT BufIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT BufIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+
+
+ TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER;
+ CONSTANT To_StateChar : To_StateCharType :=
+ ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
+ 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' );
+ TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER;
+ CONSTANT To_TruthChar : To_TruthCharType :=
+ ( 'X', '0', '1', '-', 'B', 'Z' );
+
+ TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic;
+ CONSTANT TruthTableOutMap : TruthTableOutMapType :=
+ -- 'X', '0', '1', '-', 'B', 'Z'
+ ( 'X', '0', '1', 'X', '-', 'Z' );
+
+ TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic;
+ -- does conversion to X01Z or '-' if invalid
+ CONSTANT StateTableOutMap : StateTableOutMapType :=
+ -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v'
+ -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S'
+ ( '-','-','-','-','-','-','-','-','-','-','-','-',
+ '-','-','-','-','X','0','1','X','-','Z','W');
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if a symbol IS valid for the stimulus portion of a truth table
+ CONSTANT ValidTruthTableInput : ValidTruthTableInputType :=
+ -- 'X' '0' '1' '-' 'B' 'Z'
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, FALSE );
+
+ TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if an input matches th corresponding truth table symbol
+ -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol)
+ CONSTANT TruthTableMatch : TruthTableMatchType := (
+ -- X, 0, 1, - B Z
+ ( TRUE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- X
+ ( FALSE, TRUE, FALSE, TRUE, TRUE, FALSE ), -- 0
+ ( FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) -- 1
+ );
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN;
+ CONSTANT ValidStateTableInput : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'E', 'A', 'D', '*',
+ TRUE, TRUE, TRUE, TRUE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ TRUE );
+
+ CONSTANT ValidStateTableState : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'E', 'A', 'D', '*',
+ FALSE, FALSE, FALSE, FALSE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ FALSE );
+
+ TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN;
+ -- last value, present value, table symbol
+ CONSTANT StateTableMatch : StateTableMatchType := (
+ ( -- X (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,TRUE, TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
+ TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 0 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ),
+ (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 1 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE )
+ )
+ );
+
+ TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z;
+ ----------------------------------------------------------
+ -- table name : cvt_to_x01z
+ -- parameters : std_ulogic -- some logic value
+ -- returns : UX01Z -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ ----------------------------------------------------------
+ CONSTANT cvt_to_ux01z : Logic_UX01Z_Table :=
+ ('U','X','0','1','Z','X','0','1','X' );
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MINIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return smaller of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 < in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MAXIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return larger of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 > in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ -----------------------------------------------------------------------
+ FUNCTION GlitchMinTime (
+ CONSTANT Time1, Time2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( Time1 >= NOW ) THEN
+ IF ( Time2 >= NOW ) THEN
+ RETURN Minimum ( Time1, Time2);
+ ELSE
+ RETURN Time1;
+ END IF;
+ ELSE
+ IF ( Time2 >= NOW ) THEN
+ RETURN Time2;
+ ELSE
+ RETURN 0 ns;
+ END IF;
+ END IF;
+ END;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrNegDel,
+ ErrInpSym,
+ ErrOutSym,
+ ErrStaSym,
+ ErrVctLng,
+ ErrTabWidSml,
+ ErrTabWidLrg,
+ ErrTabResSml,
+ ErrTabResLrg
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrNegDel => WARNING,
+ ErrInpSym => ERROR,
+ ErrOutSym => ERROR,
+ ErrStaSym => ERROR,
+ ErrVctLng => ERROR,
+ ErrTabWidSml => ERROR,
+ ErrTabWidLrg => WARNING,
+ ErrTabResSml => WARNING,
+ ErrTabResLrg => WARNING
+ );
+
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgInpSym : STRING :=
+ "Illegal symbol in the input portion of a Truth/State table.";
+ CONSTANT MsgOutSym : STRING :=
+ "Illegal symbol in the output portion of a Truth/State table.";
+ CONSTANT MsgStaSym : STRING :=
+ "Illegal symbol in the state portion of a State table.";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+ CONSTANT MsgTabWidSml : STRING :=
+ "Width of the Truth/State table is too small.";
+ CONSTANT MsgTabWidLrg : STRING :=
+ "Width of Truth/State table is too large. Extra elements are ignored.";
+ CONSTANT MsgTabResSml : STRING :=
+ "Result of Truth/State table has too many elements.";
+ CONSTANT MsgTabResLrg : STRING :=
+ "Result of Truth/State table has too few elements.";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN ErrInpSym => RETURN MsgInpSym;
+ WHEN ErrOutSym => RETURN MsgOutSym;
+ WHEN ErrStaSym => RETURN MsgStaSym;
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrTabWidSml => RETURN MsgTabWidSml;
+ WHEN ErrTabWidLrg => RETURN MsgTabWidLrg;
+ WHEN ErrTabResSml => RETURN MsgTabResSml;
+ WHEN ErrTabResLrg => RETURN MsgTabResLrg;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preemted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalGlitchOnEvent
+ -- :
+ -- Parameters : OutSignal ........ signal being driven
+ -- : OutSignalName..... name of the driven signal
+ -- : GlitchData........ internal data required by the procedure
+ -- : NewValue.......... new value being assigned
+ -- : NewDelay.......... Delay accompanying the assignment
+ -- : (Note: for vectors, this is an array)
+ -- : GlitchMode........ Glitch generation mode
+ -- : MessagePlusX, MessageOnly,
+ -- : XOnly, NoGlitch )
+ -- : GlitchDelay....... if <= 0 ns , then there will be no Glitch
+ -- : if > NewDelay, then there is no Glitch,
+ -- : otherwise, this is the time when a FORCED
+ -- : generation of a glitch will occur.
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataType;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN TIME := -1 ns; -- IR#223
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ -- ------------------------------------------------------------------------
+ VARIABLE NoGlitchDet : BOOLEAN := FALSE;
+ VARIABLE OldGlitch : BOOLEAN := FALSE;
+ VARIABLE Dly : TIME := NewDelay;
+
+ BEGIN
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+
+ ELSE
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN
+ GlitchData.CurrentValue := GlitchData.SchedValue;
+ IF (GlitchDelay <= 0 ns) THEN
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ GlitchData.CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue) AND
+ (GlitchData.SchedTime = GlitchData.GlitchTime) AND
+ (GlitchDelay <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+
+ END IF;
+
+ GlitchData.SchedTime := NOW+Dly;
+ IF OldGlitch THEN
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSIF NoGlitchDet THEN
+ GlitchData.GlitchTime := NOW+Dly;
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSE -- new glitch
+ GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime,
+ NOW+GlitchDelay );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (Dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ OutSignal <= TRANSPORT NewValue AFTER Dly;
+ ELSE
+ OutSignal <= NewValue AFTER Dly;
+ END IF;
+ END IF;
+
+ GlitchData.SchedValue := NewValue;
+ END IF;
+
+ RETURN;
+ END;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataArrayType;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT NewDelay : IN VitalTimeArray;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN VitalTimeArray;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ ALIAS GlDataAlias : GlitchDataArrayType(1 TO GlitchData'LENGTH)
+ IS GlitchData;
+ ALIAS NewValAlias : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue;
+ ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH)
+ IS GlitchDelay;
+ ALIAS NewDelAlias : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay;
+
+ VARIABLE Index : INTEGER := OutSignal'LEFT;
+ VARIABLE Direction : INTEGER;
+ VARIABLE NoGlitchDet : BOOLEAN;
+ VARIABLE OldGlitch : BOOLEAN;
+ VARIABLE Dly, GlDly : TIME;
+
+ BEGIN
+ IF (OutSignal'LEFT > OutSignal'RIGHT) THEN
+ Direction := -1;
+ ELSE
+ Direction := 1;
+ END IF;
+
+ IF ( (OutSignal'LENGTH /= GlitchData'LENGTH) OR
+ (OutSignal'LENGTH /= NewValue'LENGTH) OR
+ (OutSignal'LENGTH /= NewDelay'LENGTH) OR
+ (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName );
+ RETURN;
+ END IF;
+
+ -- a call to the scalar function cannot be made since the actual
+ -- name associated with a signal parameter must be locally static
+ FOR n IN 1 TO OutSignal'LENGTH LOOP
+
+ NoGlitchDet := FALSE;
+ OldGlitch := FALSE;
+ Dly := NewDelAlias(n);
+
+ -- If nothing to schedule, just skip to next loop iteration
+ IF NewDelAlias(n) < 0 ns THEN
+ IF (NewValAlias(n) /= GlDataAlias(n).SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+ ELSE
+ -- If nothing currently scheduled (i.e. last scheduled
+ -- transaction already occurred)
+ IF GlDataAlias(n).SchedTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue;
+ IF (GlDelayAlias(n) <= 0 ns) THEN
+ -- Next iteration if no change in value
+ IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN
+ Index := Index + Direction;
+ NEXT;
+ END IF;
+ -- since last transaction already occurred there is no glitch
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlDataAlias(n).GlitchTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN
+ dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- Transaction currently scheduled
+ ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND
+ (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND
+ (GlDelayAlias(n) <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- update last scheduled transaction
+ GlDataAlias(n).SchedTime := NOW+Dly;
+
+ IF OldGlitch THEN
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSIF NoGlitchDet THEN
+ -- if no glitch then update last glitch time
+ -- and OutSignal(actual_index)
+ GlDataAlias(n).GlitchTime := NOW+Dly;
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSE -- new glitch
+ GlDataAlias(n).GlitchTime := GlitchMinTime (
+ GlDataAlias(n).GlitchTime,
+ NOW+GlDelayAlias(n) );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlDataAlias(n).GlitchTime,
+ GlDataAlias(n).SchedValue,
+ (Dly + NOW), NewValAlias(n),
+ Index, TRUE, MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ GlDly := GlDataAlias(n).GlitchTime - NOW;
+ OutSignal(Index) <= 'X' AFTER GlDly;
+ OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly;
+ ELSE
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ END IF;
+
+ END IF; -- glitch / no-glitch
+ GlDataAlias(n).SchedValue := NewValAlias(n);
+
+ END IF; -- NewDelAlias(n) < 0 ns
+ Index := Index + Direction;
+ END LOOP;
+
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : TruthOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- X01Zout - output converted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ --
+ -- DESCRIPTION : converts the output of a truth table to a valid
+ -- std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE TruthOutputX01Z (
+ CONSTANT TableOut : IN VitalTruthSymbolType;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := TruthTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut));
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : StateOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- prev_out - previous output value
+ -- X01Zout - output cojnverted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ -- DESCRIPTION : converts the output of a state table to a
+ -- valid std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateOutputX01Z (
+ CONSTANT TableOut : IN VitalStateSymbolType;
+ CONSTANT PrevOut : IN std_ulogic;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := StateTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut));
+ ELSIF (TempOut = 'W') THEN
+ TempOut := To_X01Z(PrevOut);
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME: StateMatch
+ --
+ -- PARAMETERS : symbol - symbol from state table
+ -- in2 - input from VitalStateTble procedure
+ -- to state table
+ -- in2LastValue - previous value of input
+ -- state - false if the symbol is from the input
+ -- portion of the table,
+ -- true if the symbol is from the state
+ -- portion of the table
+ -- Err - true if symbol is not a valid input symbol
+ -- ReturnValue - true if match occurred
+ --
+ -- DESCRIPTION : This procedure sets ReturnValue to true if in2 matches
+ -- symbol (from the state table). If symbol is an edge
+ -- value edge is set to true and in2 and in2LastValue are
+ -- checked against symbol. Err is set to true if symbol
+ -- is an invalid value for the input portion of the state
+ -- table.
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateMatch (
+ CONSTANT Symbol : IN VitalStateSymbolType;
+ CONSTANT in2 : IN std_ulogic;
+ CONSTANT in2LastValue : IN std_ulogic;
+ CONSTANT State : IN BOOLEAN;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+ ) IS
+ BEGIN
+ IF (State) THEN
+ IF (NOT ValidStateTableState(Symbol)) THEN
+ VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ Err := FALSE;
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ END IF;
+ ELSE
+ IF (NOT ValidStateTableInput(Symbol) ) THEN
+ VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ Err := FALSE;
+ END IF;
+ END IF;
+ END;
+
+ -- -----------------------------------------------------------------------
+ -- FUNCTION NAME: StateTableLookUp
+ --
+ -- PARAMETERS : StateTable - state table
+ -- PresentDataIn - current inputs
+ -- PreviousDataIn - previous inputs and states
+ -- NumStates - number of state variables
+ -- PresentOutputs - current state and current outputs
+ --
+ -- DESCRIPTION : This function is used to find the output of the
+ -- StateTable corresponding to a given set of inputs.
+ --
+ -- ------------------------------------------------------------------------
+ FUNCTION StateTableLookUp (
+ CONSTANT StateTable : VitalStateTableType;
+ CONSTANT PresentDataIn : std_logic_vector;
+ CONSTANT PreviousDataIn : std_logic_vector;
+ CONSTANT NumStates : NATURAL;
+ CONSTANT PresentOutputs : std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := PresentDataIn'LENGTH;
+ CONSTANT NumInputs : INTEGER := InputSize + NumStates - 1;
+ CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := StateTable'LENGTH(2);
+ CONSTANT OutSize : INTEGER := TableWidth - InputSize - NumStates;
+ VARIABLE Inputs : std_logic_vector(0 TO NumInputs);
+ VARIABLE PrevInputs : std_logic_vector(0 TO NumInputs)
+ := (OTHERS => 'X');
+ VARIABLE ReturnValue : std_logic_vector(0 TO (OutSize-1))
+ := (OTHERS => 'X');
+ VARIABLE Temp : std_ulogic;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalStateTableType(0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := StateTable;
+
+ BEGIN
+ Inputs(0 TO InputSize-1) := PresentDataIn;
+ Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1);
+ PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1);
+
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each element of the entry
+ FOR j IN 0 TO InputSize + NumStates LOOP
+
+ IF (j = InputSize + NumStates) THEN -- a match occurred
+ FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1 LOOP
+ StateOutputX01Z (
+ TableAlias(i, TableWidth - k - 1),
+ PresentOutputs(PresentOutputs'LENGTH - k - 1),
+ Temp, Err);
+ ReturnValue(OutSize - k - 1) := Temp;
+ IF (Err) THEN
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END IF;
+ END LOOP;
+ RETURN ReturnValue;
+ END IF;
+
+ StateMatch ( TableAlias(i,j),
+ Inputs(j), PrevInputs(j),
+ j >= InputSize, Err, Match);
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END;
+
+ --------------------------------------------------------------------
+ -- to_ux01z
+ -------------------------------------------------------------------
+ FUNCTION To_UX01Z ( s : std_ulogic
+ ) RETURN UX01Z IS
+ BEGIN
+ RETURN cvt_to_ux01z (s);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Function : GetEdge
+ -- Purpose : Converts transitions on a given input signal into a
+ -- enumeration value representing the transition or level
+ -- of the signal.
+ --
+ -- previous "value" current "value" := "edge"
+ -- ---------------------------------------------------------
+ -- '1' | 'H' '1' | 'H' '1' level, no edge
+ -- '0' | 'L' '1' | 'H' '/' rising edge
+ -- others '1' | 'H' 'R' rising from X
+ --
+ -- '1' | 'H' '0' | 'L' '\' falling egde
+ -- '0' | 'L' '0' | 'L' '0' level, no edge
+ -- others '0' | 'L' 'F' falling from X
+ --
+ -- 'X' | 'W' | '-' 'X' | 'W' | '-' 'X' unknown (X) level
+ -- 'Z' 'Z' 'X' unknown (X) level
+ -- 'U' 'U' 'U' 'U' level
+ --
+ -- '1' | 'H' others 'f' falling to X
+ -- '0' | 'L' others 'r' rising to X
+ -- 'X' | 'W' | '-' 'U' | 'Z' 'x' unknown (X) edge
+ -- 'Z' 'X' | 'W' | '-' | 'U' 'x' unknown (X) edge
+ -- 'U' 'X' | 'W' | '-' | 'Z' 'x' unknown (X) edge
+ --
+ ---------------------------------------------------------------------------
+ FUNCTION GetEdge (
+ SIGNAL s : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ IF (s'EVENT)
+ THEN RETURN LogicToEdge ( s'LAST_VALUE, s );
+ ELSE RETURN LogicToLevel ( s );
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE GetEdge (
+ SIGNAL s : IN std_logic_vector;
+ VARIABLE LastS : INOUT std_logic_vector;
+ VARIABLE Edge : OUT EdgeArray ) IS
+
+ ALIAS sAlias : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS;
+ ALIAS EdgeAlias : EdgeArray ( 1 TO Edge'LENGTH ) IS Edge;
+ BEGIN
+ IF s'LENGTH /= LastS'LENGTH OR
+ s'LENGTH /= Edge'LENGTH THEN
+ VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" );
+ END IF;
+
+ FOR n IN 1 TO s'LENGTH LOOP
+ EdgeAlias(n) := LogicToEdge( LastSAlias(n), sAlias(n) );
+ LastSAlias(n) := sAlias(n);
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ FUNCTION ToEdge ( Value : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ RETURN LogicToLevel( Value );
+ END;
+
+ -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92
+ ----------------------------------------------------------------------------
+ IMPURE FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataType
+ ) RETURN std_logic IS
+ BEGIN
+ IF NOW >= GlitchData.SchedTime THEN
+ RETURN GlitchData.SchedValue;
+ ELSIF NOW >= GlitchData.GlitchTime THEN
+ RETURN 'X';
+ ELSE
+ RETURN GlitchData.CurrentValue;
+ END IF;
+ END;
+ ---------------------------------------------------------------------------
+ IMPURE FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataArrayType
+ ) RETURN std_logic_vector IS
+ VARIABLE Result : std_logic_vector(GlitchData'RANGE);
+ BEGIN
+ FOR n IN GlitchData'RANGE LOOP
+ IF NOW >= GlitchData(n).SchedTime THEN
+ Result(n) := GlitchData(n).SchedValue;
+ ELSIF NOW >= GlitchData(n).GlitchTime THEN
+ Result(n) := 'X';
+ ELSE
+ Result(n) := GlitchData(n).CurrentValue;
+ END IF;
+ END LOOP;
+ RETURN Result;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- function calculation utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalSame
+ -- Returns : VitalSame compares the state (UX01) of two logic value. A
+ -- value of 'X' is returned if the values are different. The
+ -- common value is returned if the values are equal.
+ -- Purpose : When the result of a logic model may be either of two
+ -- separate input values (eg. when the select on a MUX is 'X'),
+ -- VitalSame may be used to determine if the result needs to
+ -- be 'X'.
+ -- Arguments : See the declarations below...
+ ---------------------------------------------------------------------------
+ FUNCTION VitalSame (
+ CONSTANT a, b : IN std_ulogic
+ ) RETURN std_ulogic IS
+ BEGIN
+ IF To_UX01(a) = To_UX01(b)
+ THEN RETURN To_UX01(a);
+ ELSE RETURN 'X';
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- delay selection utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufPath, InvPath
+ --
+ -- Purpose : BufPath and InvPath compute output change times, based on
+ -- a change on an input port. The computed output change times
+ -- returned in the composite parameter 'schd'.
+ --
+ -- BufPath and InpPath are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the input ports of a model are
+ -- combined by the delay selection functions (VitalAND,
+ -- VitalOR, ...). The GetSchedDelay procedure converts the
+ -- combined output changes times to the single delay (delta
+ -- time) value for scheduling the output change (passed to
+ -- VitalGlitchOnEvent).
+ --
+ -- The values in 'schd' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- The output times are computed from the model INPUT value
+ -- and not the final value. For this reason, 'BufPath' should
+ -- be used to compute the output times for a non-inverting
+ -- delay paths and 'InvPath' should be used to compute the
+ -- ouput times for inverting delay paths. Delay paths which
+ -- include both non-inverting and paths require usage of both
+ -- 'BufPath' and 'InvPath'. (IE this is needed for the
+ -- select->output path of a MUX -- See the VitalMUX model).
+ --
+ --
+ -- Parameters : schd....... Computed output result times. (INOUT parameter
+ -- modified only on input edges)
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays from this input
+ --
+ ---------------------------------------------------------------------------
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr01); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr10); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr01);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr10);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr10); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr01); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr10);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr01);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufEnab, InvEnab
+ --
+ -- Purpose : BufEnab and InvEnab compute output change times, from a
+ -- change on an input enable port for a 3-state driver. The
+ -- computed output change times are returned in the composite
+ -- parameters 'schd1', 'schd0'.
+ --
+ -- BufEnab and InpEnab are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the non-enable input ports of
+ -- a model (See BufPath, InvPath) are combined using the delay
+ -- selection functions (VitalAND, VitalOR, ...). The
+ -- GetSchedDelay procedure combines the output times on the
+ -- enable path with the output times from the data path(s) and
+ -- computes the single delay (delta time) value for scheduling
+ -- the output change (passed to VitalGlitchOnEvent)
+ --
+ -- The values in 'schd*' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- 'schd1' contains output times for 1->Z, Z->1 transitions.
+ -- 'schd0' contains output times for 0->Z, Z->0 transitions.
+ --
+ -- 'BufEnab' is used for computing the output times for an
+ -- high asserted enable (output 'Z' for enable='0').
+ -- 'InvEnab' is used for computing the output times for an
+ -- low asserted enable (output 'Z' for enable='1').
+ --
+ -- Note: separate 'schd1', 'schd0' parameters are generated
+ -- so that the combination of the delay paths from
+ -- multiple enable signals may be combined using the
+ -- same functions/operators used in combining separate
+ -- data paths. (See exampe 2 below)
+ --
+ --
+ -- Parameters : schd1...... Computed output result times for 1->Z, Z->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- schd0...... Computed output result times for 0->Z, 0->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays for the enable -> output path.
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE BufEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(trz1);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(trz0);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(tr1z);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(tr0z);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(tr1z);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(tr0z);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(trz1);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(trz0);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : GetSchedDelay
+ --
+ -- Purpose : GetSchedDelay computes the final delay (incremental) for
+ -- for scheduling an output signal. The delay is computed
+ -- from the absolute output times in the 'NewSched' parameter.
+ -- (See BufPath, InvPath).
+ --
+ -- Computation of the output delay for non-3_state outputs
+ -- consists of selection the appropriate output time based
+ -- on the new output value 'NewValue' and subtracting 'NOW'
+ -- to convert to an incremental delay value.
+ --
+ -- The Computation of the output delay for 3_state output
+ -- also includes combination of the enable path delay with
+ -- the date path delay.
+ --
+ -- Parameters : NewDelay... Returned output delay value.
+ -- GlchDelay.. Returned output delay for the start of a glitch.
+ -- NewValue... New output value.
+ -- CurValue... Current value of the output.
+ -- NewSched... Composite containing the combined absolute
+ -- output times from the data inputs.
+ -- EnSched1... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 1->Z, Z->1)
+ -- EnSched0... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 0->Z, Z->0)
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE To_UX01(NewValue) IS
+ WHEN '0' => Tim := NewSched.inp0;
+ Glch := NewSched.Glch1;
+ WHEN '1' => Tim := NewSched.inp1;
+ Glch := NewSched.Glch0;
+ WHEN OTHERS => Tim := NewSched.InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValue /= NewValue)
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT VitalTimeArray;
+ VARIABLE GlchDelay : OUT VitalTimeArray;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT CurValue : IN std_logic_vector;
+ CONSTANT NewSched : IN SchedArray
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ ALIAS NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1)
+ IS NewDelay;
+ ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1)
+ IS GlchDelay;
+ ALIAS NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1)
+ IS NewSched;
+ ALIAS NewValueAlias : std_logic_vector ( NewValue'LENGTH DOWNTO 1 )
+ IS NewValue;
+ ALIAS CurValueAlias : std_logic_vector ( CurValue'LENGTH DOWNTO 1 )
+ IS CurValue;
+ BEGIN
+ FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP
+ CASE To_UX01(NewValueAlias(n)) IS
+ WHEN '0' => Tim := NewSchedAlias(n).inp0;
+ Glch := NewSchedAlias(n).Glch1;
+ WHEN '1' => Tim := NewSchedAlias(n).inp1;
+ Glch := NewSchedAlias(n).Glch0;
+ WHEN OTHERS => Tim := NewSchedAlias(n).InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValueAlias(n) /= NewValueAlias(n))
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelayAlias(n) := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelayAlias(n) := Glch;
+ ELSE GlchDelayAlias(n) := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END LOOP;
+ RETURN;
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType;
+ CONSTANT EnSched1 : IN SchedType;
+ CONSTANT EnSched0 : IN SchedType
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS
+ WHEN "00" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0);
+ WHEN "01" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := EnSched1.Glch0;
+ WHEN "0Z" => Tim := EnSched0.inp0;
+ Glch := NewSched.Glch1;
+ WHEN "0X" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "10" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := EnSched0.Glch0;
+ WHEN "11" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0);
+ WHEN "1Z" => Tim := EnSched1.inp0;
+ Glch := NewSched.Glch0;
+ WHEN "1X" => Tim := Maximum (NewSched.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "Z0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ IF NewSched.Glch0 > NOW
+ THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "Z1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ IF NewSched.Glch1 > NOW
+ THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "ZX" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "ZZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "X0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := 0 ns;
+ WHEN "X1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := 0 ns;
+ WHEN "XZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN OTHERS => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+
+ END CASE;
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Operators and Functions for combination (selection) of path delays
+ -- > These functions support selection of the "appripriate" path delay
+ -- dependent on the logic function.
+ -- > These functions only "select" from the possable output times. No
+ -- calculation (addition) of delays is performed.
+ -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay'
+ -- > See primitive PROCEDURE models for examples.
+ ---------------------------------------------------------------------------
+
+ FUNCTION "not" (
+ CONSTANT a : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := a.inp0 ;
+ z.inp0 := a.inp1 ;
+ z.InpX := a.InpX ;
+ z.Glch1 := a.Glch0;
+ z.Glch0 := a.Glch1;
+ RETURN (z);
+ END;
+
+ FUNCTION "and" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp1 , b.inp1 );
+ z.inp0 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ FUNCTION "or" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp0 , b.inp0 );
+ z.inp1 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION "nand" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp1 , b.inp1 );
+ z.inp1 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION "nor" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp0 , b.inp0 );
+ z.inp0 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) NOR (a NOR b)
+ z.inp1 := Maximum ( Minimum (ai.inp0 , bi.inp0 ),
+ Minimum (ab.inp1 , bb.inp1 ) );
+ z.inp0 := Minimum ( Maximum (ai.inp1 , bi.inp1 ),
+ Maximum (ab.inp0 , bb.inp0 ) );
+ z.InpX := Maximum ( Maximum (ai.InpX , bi.InpX ),
+ Maximum (ab.InpX , bb.InpX ) );
+ z.Glch1 := Maximum (GlitchMinTime (ai.Glch0, bi.Glch0),
+ GlitchMinTime (ab.Glch1, bb.Glch1) );
+ z.Glch0 := GlitchMinTime ( Maximum (ai.Glch1, bi.Glch1),
+ Maximum (ab.Glch0, bb.Glch0) );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION VitalXNOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) OR (a NOR b)
+ z.inp0 := Maximum ( Minimum (ab.inp0 , bb.inp0 ),
+ Minimum (ai.inp1 , bi.inp1 ) );
+ z.inp1 := Minimum ( Maximum (ab.inp1 , bb.inp1 ),
+ Maximum (ai.inp0 , bi.inp0 ) );
+ z.InpX := Maximum ( Maximum (ab.InpX , bb.InpX ),
+ Maximum (ai.InpX , bi.InpX ) );
+ z.Glch0 := Maximum (GlitchMinTime (ab.Glch0, bb.Glch0),
+ GlitchMinTime (ai.Glch1, bi.Glch1) );
+ z.Glch1 := GlitchMinTime ( Maximum (ab.Glch1, bb.Glch1),
+ Maximum (ai.Glch0, bi.Glch0) );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi),
+ VitalXOR2 (ai,ab, bi,bb),
+ cb, ci );
+ END;
+
+ IMPURE FUNCTION VitalXNOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ cb, ci );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ IMPURE FUNCTION VitalXNOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for N-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ IMPURE FUNCTION VitalXOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ IMPURE FUNCTION VitalXNOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT d1, d0 : IN SchedType;
+ CONSTANT sb, SI : IN SchedType
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN (d1 AND sb) OR (d0 AND (NOT SI) );
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN SchedArray4;
+ CONSTANT sb : IN SchedArray2;
+ CONSTANT SI : IN SchedArray2
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( sb(1) AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) )
+ OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) );
+ END;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN SchedArray8;
+ CONSTANT sb : IN SchedArray3;
+ CONSTANT SI : IN SchedArray3
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( ( sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) )
+ OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) );
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT sMsb : INTEGER := sb'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ BEGIN
+ IF sb'LENGTH = 1 THEN
+ RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) );
+ ELSIF sb'LENGTH = 2 THEN
+ RETURN VitalMUX4( Data, sb, SI );
+ ELSIF sb'LENGTH = 3 THEN
+ RETURN VitalMUX8( Data, sb, SI );
+ ELSIF sb'LENGTH > 3 THEN
+ RETURN (( sb(sMsb)) AND VInterMux( Data(dMsbLow DOWNTO 1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ))
+ OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ));
+ ELSE
+ RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1
+ END IF;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT msb : INTEGER := 2**sb'LENGTH;
+ VARIABLE lDat : SchedArray(msb DOWNTO 1);
+ ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data;
+ ALIAS sbAlias : SchedArray ( sb'LENGTH DOWNTO 1 ) IS sb;
+ ALIAS siAlias : SchedArray ( SI'LENGTH DOWNTO 1 ) IS SI;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ FOR i IN msb DOWNTO Data'LENGTH+1 LOOP
+ lDat(i) := DefSchedAnd;
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ RETURN VInterMux( lDat, sbAlias, siAlias );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT DataB : IN SchedType;
+ CONSTANT DataI : IN SchedType;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray2;
+ BEGIN
+ Result(1) := Enable AND ( DataB);
+ Result(0) := Enable AND (NOT DataI);
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT DataB : IN SchedArray2;
+ CONSTANT DataI : IN SchedArray2;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray4;
+ BEGIN
+ Result(3) := Enable AND ( DataB(1)) AND ( DataB(0));
+ Result(2) := Enable AND ( DataB(1)) AND (NOT DataI(0));
+ Result(1) := Enable AND (NOT DataI(1)) AND ( DataB(0));
+ Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0));
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT DataB : IN SchedArray3;
+ CONSTANT DataI : IN SchedArray3;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray8;
+ BEGIN
+ Result(7):= Enable AND ( DataB(2))AND( DataB(1))AND( DataB(0));
+ Result(6):= Enable AND ( DataB(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(5):= Enable AND ( DataB(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(4):= Enable AND ( DataB(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ Result(3):= Enable AND (NOT DataI(2))AND( DataB(1))AND( DataB(0));
+ Result(2):= Enable AND (NOT DataI(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ RETURN Result;
+ END;
+
+
+ FUNCTION VitalDECODER (
+ CONSTANT DataB : IN SchedArray;
+ CONSTANT DataI : IN SchedArray;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ CONSTANT DMsb : INTEGER := DataB'LENGTH - 1;
+ ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB;
+ ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI;
+ BEGIN
+ IF DataB'LENGTH = 1 THEN
+ RETURN VitalDECODER2 ( DataBAlias( 0 ),
+ DataIAlias( 0 ), Enable );
+ ELSIF DataB'LENGTH = 2 THEN
+ RETURN VitalDECODER4 ( DataBAlias(1 DOWNTO 0),
+ DataIAlias(1 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH = 3 THEN
+ RETURN VitalDECODER8 ( DataBAlias(2 DOWNTO 0),
+ DataIAlias(2 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH > 3 THEN
+ RETURN VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataBAlias(DMsb)) )
+ & VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataIAlias(DMsb)) );
+ ELSE
+ RETURN DefSchedArray2;
+ END IF;
+ END;
+
+
+-------------------------------------------------------------------------------
+-- PRIMITIVES
+-------------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b);
+ END;
+--
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b);
+ END;
+--
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b);
+ END;
+--
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NAND b);
+ END;
+--
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NOR b);
+ END;
+--
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b));
+ END;
+--
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c);
+ END;
+--
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c);
+ END;
+--
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c);
+ END;
+--
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c));
+ END;
+--
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c));
+ END;
+--
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c));
+ END;
+
+ -- ---------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ---------------------------------------------------------------------------
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c AND d);
+ END;
+--
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c OR d);
+ END;
+--
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c XOR d);
+ END;
+--
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c AND d));
+ END;
+--
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c OR d));
+ END;
+--
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c XOR d));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01(Data));
+ END;
+--
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf1_Table(Enable,Data));
+ END;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01Z(Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT Data);
+ END;
+--
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf1_Table(Enable,Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect) IS
+ WHEN '0' => Result := To_UX01(Data0);
+ WHEN '1' => Result := To_UX01(Data1);
+ WHEN OTHERS => Result := VitalSame( Data1, Data0 );
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Slct : std_logic_vector2;
+ VARIABLE Result : UX01;
+ BEGIN
+ Slct := To_X01(dSelect);
+ CASE Slct IS
+ WHEN "00" => Result := To_UX01(Data(0));
+ WHEN "01" => Result := To_UX01(Data(1));
+ WHEN "10" => Result := To_UX01(Data(2));
+ WHEN "11" => Result := To_UX01(Data(3));
+ WHEN "0X" => Result := VitalSame( Data(1), Data(0) );
+ WHEN "1X" => Result := VitalSame( Data(2), Data(3) );
+ WHEN "X0" => Result := VitalSame( Data(2), Data(0) );
+ WHEN "X1" => Result := VitalSame( Data(3), Data(1) );
+ WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)),
+ VitalSame(Data(1),Data(0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect(2)) IS
+ WHEN '0' => Result := VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0));
+ WHEN '1' => Result := VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0));
+ WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0)),
+ VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector
+ ) RETURN std_ulogic IS
+
+ CONSTANT sMsb : INTEGER := dSelect'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+
+ VARIABLE Result : UX01;
+ BEGIN
+ IF dSelect'LENGTH = 1 THEN
+ Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) );
+ ELSIF dSelect'LENGTH = 2 THEN
+ Result := VitalMUX4( DataAlias, dSelAlias );
+ ELSIF dSelect'LENGTH > 2 THEN
+ CASE To_X01(dSelect(sMsb)) IS
+ WHEN '0' =>
+ Result := VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN '1' =>
+ Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN OTHERS =>
+ Result := VitalSame(
+ VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) ),
+ VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) )
+ );
+ END CASE;
+ ELSE
+ Result := 'X'; -- dselect'LENGTH < 1
+ END IF;
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ CONSTANT msb : INTEGER := 2**dSelect'LENGTH;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+ VARIABLE lDat : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X');
+ VARIABLE Result : UX01;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ Result := VInterMux( lDat, dSelAlias );
+ RETURN ResultMap(Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2 IS
+ VARIABLE Result : std_logic_vector2;
+ BEGIN
+ Result(1) := ResultMap(Enable AND ( Data));
+ Result(0) := ResultMap(Enable AND (NOT Data));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4 IS
+ VARIABLE Result : std_logic_vector4;
+ BEGIN
+ Result(3) := ResultMap(Enable AND ( Data(1)) AND ( Data(0)));
+ Result(2) := ResultMap(Enable AND ( Data(1)) AND (NOT Data(0)));
+ Result(1) := ResultMap(Enable AND (NOT Data(1)) AND ( Data(0)));
+ Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0)));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8 IS
+ VARIABLE Result : std_logic_vector8;
+ BEGIN
+ Result(7) := ( Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(6) := ( Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(5) := ( Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(4) := ( Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+ Result(3) := (NOT Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(2) := (NOT Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+
+ Result(0) := ResultMap ( Enable AND Result(0) );
+ Result(1) := ResultMap ( Enable AND Result(1) );
+ Result(2) := ResultMap ( Enable AND Result(2) );
+ Result(3) := ResultMap ( Enable AND Result(3) );
+ Result(4) := ResultMap ( Enable AND Result(4) );
+ Result(5) := ResultMap ( Enable AND Result(5) );
+ Result(6) := ResultMap ( Enable AND Result(6) );
+ Result(7) := ResultMap ( Enable AND Result(7) );
+
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector IS
+
+ CONSTANT DMsb : INTEGER := Data'LENGTH - 1;
+ ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data;
+ BEGIN
+ IF Data'LENGTH = 1 THEN
+ RETURN VitalDECODER2 (DataAlias( 0 ), Enable, ResultMap );
+ ELSIF Data'LENGTH = 2 THEN
+ RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH = 3 THEN
+ RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH > 3 THEN
+ RETURN VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataAlias(DMsb)), ResultMap )
+ & VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataAlias(DMsb)), ResultMap );
+ ELSE RETURN "X";
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXOR ( Data );
+ new_schd := VitalXOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXNOR ( Data );
+ new_schd := VitalXNOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b;
+ new_schd := a_schd AND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b;
+ new_schd := a_schd OR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NAND b;
+ new_schd := a_schd NAND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NOR b;
+ new_schd := a_schd NOR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b;
+ new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b);
+ new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+--
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c;
+ new_schd := a_schd AND b_schd AND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c;
+ new_schd := a_schd OR b_schd OR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND c;
+ new_schd := (a_schd AND b_schd) NAND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR c;
+ new_schd := (a_schd OR b_schd) NOR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c;
+ new_schd := VitalXOR3 ( ab_schd,ai_schd,
+ bb_schd,bi_schd,
+ cb_schd,ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c);
+ new_schd := VitalXNOR3 ( ab_schd, ai_schd,
+ bb_schd, bi_schd,
+ cb_schd, ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c AND d;
+ new_schd := a_schd AND b_schd AND c_schd AND d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c OR d;
+ new_schd := a_schd OR b_schd OR c_schd OR d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND (c AND d);
+ new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR (c OR d);
+ new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c XOR d;
+ new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c XOR d);
+ new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(To_UX01(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := To_UX01(a); -- convert to forcing strengths
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF1( Data, Enable );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01Z) THEN
+ LOOP
+ q <= ResultMap(To_UX01Z(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS
+ WHEN "00" => Dly := tpd_a_q(tr10);
+ WHEN "01" => Dly := tpd_a_q(tr01);
+ WHEN "0Z" => Dly := tpd_a_q(tr0z);
+ WHEN "0X" => Dly := tpd_a_q(tr01);
+ WHEN "10" => Dly := tpd_a_q(tr10);
+ WHEN "11" => Dly := tpd_a_q(tr01);
+ WHEN "1Z" => Dly := tpd_a_q(tr1z);
+ WHEN "1X" => Dly := tpd_a_q(tr10);
+ WHEN "Z0" => Dly := tpd_a_q(trz0);
+ WHEN "Z1" => Dly := tpd_a_q(trz1);
+ WHEN "ZZ" => Dly := 0 ns;
+ WHEN "ZX" => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0));
+ WHEN "X0" => Dly := tpd_a_q(tr10);
+ WHEN "X1" => Dly := tpd_a_q(tr01);
+ WHEN "XZ" => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z));
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+ NewValue := To_UX01Z(a);
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(NOT a);
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT a;
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF1( Data, Enable );
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE d1_Schd, d0_Schd : SchedType;
+ VARIABLE dSel_bSchd, dSel_iSchd : SchedType;
+ VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_d1_q = VitalZeroDelay01)
+ AND (tpd_d0_q = VitalZeroDelay01)
+ AND (tpd_dsel_q = VitalZeroDelay01) ) THEN
+ LOOP
+ q <= VitalMUX2 ( d1, d0, dSel, ResultMap );
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX2 ( d1, d0, dSel );
+ new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray4;
+ VARIABLE Data_Edge : EdgeArray4;
+ VARIABLE dSel_Edge : EdgeArray2;
+ VARIABLE dSel_bSchd : SchedArray2;
+ VARIABLE dSel_iSchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX4 ( Data, dSel );
+ new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray8;
+ VARIABLE Data_Edge : EdgeArray8;
+ VARIABLE dSel_Edge : EdgeArray3;
+ VARIABLE dSel_bSchd : SchedArray3;
+ VARIABLE dSel_iSchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX8 ( Data, dSel );
+ new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE dSel_Edge : EdgeArray(dSel'RANGE);
+ VARIABLE dSel_bSchd : SchedArray(dSel'RANGE);
+ VARIABLE dSel_iSchd : SchedArray(dSel'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX ( Data, dSel );
+ new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- Caution: If 'ResultMap' defines other than strength mapping, the
+ -- delay selection is not defined.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : std_logic_vector2;
+ VARIABLE Glitch_Data : GlitchArray2;
+ VARIABLE new_schd : SchedArray2;
+ VARIABLE Dly, Glch : TimeArray2;
+ VARIABLE Enable_Schd : SchedType := DefSchedType;
+ VARIABLE Data_BSchd, Data_ISchd : SchedType;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= VitalDECODER2(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q );
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER2 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; -- SN
+ END;
+--
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector4;
+ VARIABLE Glitch_Data : GlitchArray4;
+ VARIABLE new_schd : SchedArray4;
+ VARIABLE Dly, Glch : TimeArray4;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray2;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER4(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER4 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector8;
+ VARIABLE Glitch_Data : GlitchArray8;
+ VARIABLE new_schd : SchedArray8;
+ VARIABLE Dly, Glch : TimeArray8;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray3;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER8 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector(q'RANGE);
+ VARIABLE Glitch_Data : GlitchDataArrayType(q'RANGE);
+ VARIABLE new_schd : SchedArray(q'RANGE);
+ VARIABLE Dly, Glch : VitalTimeArray(q'RANGE);
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1)
+ := To_X01(DataIn);
+ VARIABLE Index : INTEGER;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1),
+ 0 TO (TruthTable'LENGTH(2)-1))
+ := TruthTable;
+
+ BEGIN
+ -- search through each row of the truth table
+ IF OutSize > 0 THEN
+ ColLoop:
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each input element of the entry
+ FOR j IN 0 TO InputSize LOOP
+
+ IF (j = InputSize) THEN -- This entry matches
+ -- Return the Result
+ Index := 0;
+ FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP
+ TruthOutputX01Z ( TableAlias(i,k),
+ ReturnValue(Index), Err);
+ EXIT WHEN Err;
+ Index := Index + 1;
+ END LOOP;
+
+ IF Err THEN
+ ReturnValue := (OTHERS => 'X');
+ END IF;
+ RETURN ReturnValue;
+ END IF;
+ IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN
+ VitalError ( "VitalTruthTable", ErrInpSym,
+ To_TruthChar(TableAlias(i,j)) );
+ EXIT ColLoop;
+ END IF;
+ EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j),
+ TableAlias(i, j)));
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ END IF;
+ RETURN ReturnValue;
+ END VitalTruthTable;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ BEGIN
+ IF (OutSize > 0) THEN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ RETURN (TempResult(0));
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ RETURN 'X';
+ END IF;
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ ) IS
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng);
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF (ResLeng > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF (ResLeng < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0);
+ Result <= TempResult;
+
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ ) IS
+
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF ( 1 > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ IF (ActResLen > 0) THEN
+ Result <= TempResult(0);
+ END IF;
+
+ END VitalTruthTable;
+
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := To_X01(DataIn);
+ VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1)
+ := To_X01(PreviousDataIn);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1)
+ := To_X01(Result);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN
+ VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn<DataIn");
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSIF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevDataAlias, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result := ResultAlias;
+ PrevDataAlias(0 TO InputSize - 1) := DataInAlias;
+ PreviousDataIn := PrevDataAlias;
+
+ END IF;
+ END VitalStateTable;
+
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic; -- states
+ VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states
+ CONSTANT StateTable : IN VitalStateTableType; -- User's StateTable data
+ CONSTANT DataIn : IN std_logic_vector -- Inputs
+ ) IS
+
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ BEGIN
+ ResultAlias(0) := Result;
+ VitalStateTable ( StateTable => StateTable,
+ DataIn => DataIn,
+ NumStates => 1,
+ Result => ResultAlias,
+ PreviousDataIn => PreviousDataIn
+ );
+ Result := ResultAlias(0);
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result <= ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ DataInAlias := To_X01(DataIn);
+ ResultAlias := To_X01(Result);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result <= ResultAlias;
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+
+ END IF;
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize-1;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ Result <= 'X';
+
+ ELSE
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ ResultAlias(0) := To_X01(Result);
+ DataInAlias := To_X01(DataIn);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, 1, ResultAlias);
+
+ Result <= ExpResult(OutSize-1);
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+ END IF;
+
+ END VitalStateTable;
+
+ -- ------------------------------------------------------------------------
+ -- std_logic resolution primitive
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector --IR236 4/2/98
+ ) IS
+ VARIABLE uData : std_ulogic_vector(Data'RANGE);
+ BEGIN
+ FOR i IN Data'RANGE LOOP
+ uData(i) := Data(i);
+ END LOOP;
+ q <= resolved(uData);
+ END;
+
+END VITAL_Primitives;
+
diff --git a/libraries/vital2000/prmtvs_p.vhdl b/libraries/vital2000/prmtvs_p.vhdl
new file mode 100644
index 000000000..764ac449a
--- /dev/null
+++ b/libraries/vital2000/prmtvs_p.vhdl
@@ -0,0 +1,1413 @@
+-- -----------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 598 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- ----------------------------------------------------------------------------
+-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of
+-- | | | of class SIGNAL (PROPOSED)
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+USE IEEE.VITAL_Timing.ALL;
+
+PACKAGE VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+
+ -- For Truth and State Tables
+ SUBTYPE VitalTruthSymbolType IS VitalTableSymbolType RANGE 'X' TO 'Z';
+ SUBTYPE VitalStateSymbolType IS VitalTableSymbolType RANGE '/' TO 'S';
+
+ TYPE VitalTruthTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalTruthSymbolType;
+ TYPE VitalStateTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalStateSymbolType;
+
+ -- ---------------------------------
+ -- Default values used by primitives
+ -- ---------------------------------
+ CONSTANT VitalDefDelay01 : VitalDelayType01; -- Propagation delays
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ -- VITAL Primitives
+ --
+ -- The primitives packages contains a collections of common gates,
+ -- including AND, OR, XOR, NAND, NOR, XNOR, BUF, INV, MUX and DECODER
+ -- functions. In addition, for sequential devices, a STATE TABLE construct
+ -- is provided. For complex functions a modeler may wish to use either
+ -- a collection of connected VITAL primitives, or a TRUTH TABLE construct.
+ --
+ -- For each primitive a Function and Procedure is provided. The primitive
+ -- functions are provided to support behavioral modeling styles. The
+ -- primitive procedures are provided to support structural modeling styles.
+ --
+ -- The procedures wait internally for an event on an input signal, compute
+ -- the new result, perform glitch handling, schedule transaction on the
+ -- output signals, and wait for future input events. All of the functional
+ -- (logic) input or output parameters of the primitive procedures are
+ -- signals. All the other parameters are constants.
+ --
+ -- The procedure primitives are parameterized for separate path delays
+ -- from each input signal. All path delays default to 0 ns.
+ --
+ -- The sequential primitive functions compute the defined function and
+ -- return a value of type std_ulogic or std_logic_vector. All parameters
+ -- of the primitive functions are constants of mode IN.
+ --
+ -- The primitives are based on 1164 operators. The user may also elect to
+ -- express functions using the 1164 operators as well. These styles are
+ -- all equally acceptable methods for device modeling.
+ --
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: N-input logic device function calls:
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The function calls return the evaluated logic function
+ -- corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-bit
+ -- wide logic functions.
+ -- ResultMap VitalResultMapType The output signal strength
+ -- result map to modify default
+ -- result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The evaluated logic function of
+ -- the n-bit wide primitives.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: N-input logic device concurrent procedure calls.
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delay form data to q is a
+ -- a parameter to the procedure. A vector of delay values
+ -- for inputs to output are provided. It is noted that
+ -- limitations in SDF make the back annotation of the delay
+ -- array difficult.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-
+ -- bit wide logic functions.
+ -- tpd_data_q VitalDelayArrayType01 The propagation delay from
+ -- the data inputs to the output
+ -- q.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the
+ -- evaluated logic function.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: 2,3 and 4 input logic device function calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The function calls return the evaluated 2, 3 or 4 input
+ -- logic function corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The result of the evaluated logic
+ -- function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: 2, 3 and 4 input logic device concurrent procedure
+ -- calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delays from a and b to q are
+ -- a parameter to the procedure. The default propagation
+ -- delay is 0 ns.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- tpd_a_q VitalDelayType01 The propagation delay from the a
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_b_q VitalDelayType01 The propagation delay from the b
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_c_q VitalDelayType01 The propagation delay from the c
+ -- input to output q for 3 and 4 input
+ -- devices.
+ -- tpd_d_q VitalDelayType01 The propagation delay from the d
+ -- input to output q for 4 input
+ -- devices.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the evaluated
+ -- logic function.
+ --
+ -- Returns
+ -- none
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: Buffer logic device concurrent procedure calls.
+ --
+ -- Description: Four buffer sequential primitive function calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the four permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the buffers
+ -- Enable std_ulogic Enable for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The output signal of the evaluated
+ -- buffer function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: Buffer device procedure calls.
+ --
+ -- Description: Four buffer concurrent primitive procedure calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the fourth permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal to the buffers
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low buffers.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input to
+ -- output for the simple buffer.
+ -- VitalDelayType01Z Propagation delay from input to
+ -- to output for the enable high and low
+ -- and identity buffers.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from enable to
+ -- output for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output of the buffers.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: Inverter functions which return the inverted signal
+ -- value. Inverters with enable low and high are provided
+ -- which can drive high impedance when inactive.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the inverter
+ -- Enable std_ulogic Enable to the enable high and low
+ -- inverters.
+ -- ResultMap VitalResultMap The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic Output of the inverter
+ --
+ -- -------------------------------------------------------------------------
+
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: The concurrent primitive procedure calls implement a
+ -- signal inversion function. The output is a parameter to
+ -- the procedure. The path delay information is passed as
+ -- a parameter to the call.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal for the simple inverter
+ -- Data std_ulogic Input signal for the enable high and
+ -- low inverters.
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low inverters.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input a to
+ -- output q for the simple inverter.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data to
+ -- output q for the enable high and low
+ -- inverters.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from input enable
+ -- to output q for the enable high and
+ -- low inverters.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal of the inverter.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX functions return the selected data bit
+ -- based on the value of dSelect. For MUX2, the function
+ -- returns data0 when dselect is 0 and returns data1 when
+ -- dselect is 1. When dselect is X, result is X for MUX2
+ -- when data0 /= data1. X propagation is reduced when the
+ -- dselect signal is X and both data signals are identical.
+ -- When this is the case, the result returned is the value
+ -- of the data signals.
+ --
+ -- For the N input device:
+ --
+ -- N must equal 2**(bits of dSelect)
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Input signal for the N-bit, 4-bit and
+ -- 8-bit mux.
+ -- Data1,Data0 std_ulogic Input signals for the 2-bit mux.
+ -- dSelect std_ulogic Select signal for 2-bit mux
+ -- std_logic_vector2 Select signal for 4-bit mux
+ -- std_logic_vector3 Select signal for 8-bit mux
+ -- std_logic_vector Select signal for N-Bit mux
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The value of the selected bit is
+ -- returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX concurrent primitive procedures calls
+ -- return in the output q the value of the selected data
+ -- bit based on the value of dsel. For the two bit mux,
+ -- the data returned is either d0 or d1, the data input.
+ -- For 4, 8 and N-bit functions, data is the input and is
+ -- of type std_logic_vector. For the 2-bit mux, if d0 or
+ -- d1 are X, the output is X only when d0 do not equal d1.
+ -- When d0 and d1 are equal, the return value is this value
+ -- to reduce X propagation.
+ --
+ -- Propagation delay information is passed as a parameter
+ -- to the procedure call for delays from data to output and
+ -- select to output. For 2-bit muxes, the propagation
+ -- delays from data are provided for d0 and d1 to output.
+ --
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- d1,d0 std_ulogic Input signals for the 2-bit mux.
+ -- Data std_logic_vector4 Input signals for the 4-bit mux.
+ -- std_logic_vector8 Input signals for the 8-bit mux.
+ -- std_logic_vector Input signals for the N-bit mux.
+ -- dsel std_ulogic Select signal for the 2-bit mux.
+ -- std_logic_vector2 Select signals for the 4-bit mux.
+ -- std_logic_vector3 Select signals for the 8-bit mux.
+ -- std_logic_vector Select signals for the N-bit mux.
+ -- tpd_d1_q VitalDelayType01 Propagation delay from input d1 to
+ -- output q for 2-bit mux.
+ -- tpd_d0_q VitalDelayType01 Propagation delay from input d0 to
+ -- output q for 2-bit mux.
+ -- tpd_data_q VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- tpd_dsel_q VitalDelayType01 Propagation delay from input dsel
+ -- to output q for 2-bit mux.
+ -- VitalDelayArrayType01 Propagation delay from input dsel
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- ResultMap VitalResultMapType The output signal strength result
+ -- map to modify default result
+ -- mapping for all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The value of the selected signal.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER functions are the sequential primitive
+ -- calls for decoder logic. The functions are provided
+ -- for N, 2, 4 and 8-bit outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The VitalDECODER returns 0 if enable is 0.
+ -- The VitalDECODER returns the result bit set to 1 if
+ -- enable is 1. All other bits of returned result are
+ -- set to 0.
+ --
+ -- The returned array is in descending order:
+ -- (n-1 downto 0).
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- Enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all output signals of the decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_logic_vector2 The output of the 2-bit decoder.
+ -- std_logic_vector4 The output of the 4-bit decoder.
+ -- std_logic_vector8 The output of the 8-bit decoder.
+ -- std_logic_vector The output of the n-bit decoder.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER procedures are the concurrent primitive
+ -- procedure calls for decoder functions. The procedures
+ -- are provided for N, 2, 4 and 8 outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The procedural form of the decoder is used for
+ -- distributed delay modeling. The delay information for
+ -- each path is passed as an argument to the procedure.
+ --
+ -- Result is set to 0 if enable is 0.
+ -- The result bit represented by data is set to 1 if
+ -- enable is 1. All other bits of result are set to 0.
+ --
+ -- The result array is in descending order: (n-1 downto 0).
+ --
+ -- For the N-bit decoder, the delay path is a vector of
+ -- delays from inputs to outputs.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data
+ -- to output q for 2-bit decoder.
+ -- VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4, 8 and n-bit
+ -- decoders.
+ -- tpd_enable_q VitalDelayType01 Propagation delay from input enable
+ -- to output q for 2, 4, 8 and n-bit
+ -- decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_logic_vector2 Output signals for 2-bit decoder.
+ -- std_logic_vector4 Output signals for 4-bit decoder.
+ -- std_logic_vector8 Output signals for 8-bit decoder.
+ -- std_logic_vector Output signals for n-bit decoder.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ -- Function Name: VitalTruthTable
+ --
+ -- Description: VitalTruthTable implements a truth table. Given
+ -- a set of inputs, a sequential search is performed
+ -- to match the input. If a match is found, the output
+ -- is set based on the contents of the CONSTANT TruthTable.
+ -- If there is no match, all X's are returned. There is
+ -- no limit to the size of the table.
+ --
+ -- There is a procedure and function for VitalTruthTable.
+ -- For each of these, a single value output (std_logic) and
+ -- a multi-value output (std_logic_vector) are provided.
+ --
+ -- The first dimension of the table is for number of
+ -- entries in the truth table and second dimension is for
+ -- the number of elements in a row. The number of inputs
+ -- in the row should be Data'LENGTH plus result'LENGTH.
+ --
+ -- Elements is a row will be interpreted as
+ -- Input(NumInputs - 1),.., Input(0),
+ -- Result(NumOutputs - 1),.., Result(0)
+ --
+ -- All inputs will be mapped to the X01 subtype
+ --
+ -- If the value of Result is not in the range 'X' to 'Z'
+ -- then an error will be reported. Also, the Result is
+ -- always given either as a 0, 1, X or Z value.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TruthTable The input constant which defines the
+ -- behavior in truth table form.
+ -- DataIn The inputs to the truth table used to
+ -- perform input match to select
+ -- output(s) to value(s) to drive.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- Result std_logic Concurrent procedure version scalar
+ -- output.
+ -- std_logic_vector Concurrent procedure version vector
+ -- output.
+ --
+ -- Returns
+ -- Result std_logic Function version scalar output.
+ -- std_logic_vector Function version vector output.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ );
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ );
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalStateTable
+ --
+ -- Description: VitalStateTable is a non-concurrent implementation of a
+ -- state machine (Moore Machine). It is used to model
+ -- sequential devices and devices with internal states.
+ --
+ -- The procedure takes the value of the state table
+ -- data set and performs a sequential search of the
+ -- CONSTANT StateTable until a match is found. Once a
+ -- match is found, the result of that match is applied
+ -- to Result. If there is no match, all X's are returned.
+ -- The resultant output becomes the input for the next
+ -- state.
+ --
+ -- The first dimension of the table is the number of
+ -- entries in the state table and second dimension is the
+ -- number of elements in a row of the table. The number of
+ -- inputs in the row should be DataIn'LENGTH. Result should
+ -- contain the current state (which will become the next
+ -- state) as well as the outputs
+ --
+ -- Elements is a row of the table will be interpreted as
+ -- Input(NumInputs-1),.., Input(0), State(NumStates-1),
+ -- ..., State(0),Output(NumOutputs-1),.., Output(0)
+ --
+ -- where State(numStates-1) DOWNTO State(0) represent the
+ -- present state and Output(NumOutputs - 1) DOWNTO
+ -- Outputs(NumOutputs - NumStates) represent the new
+ -- values of the state variables (i.e. the next state).
+ -- Also, Output(NumOutputs - NumStates - 1)
+ --
+ -- This procedure returns the next state and the new
+ -- outputs when a match is made between the present state
+ -- and present inputs and the state table. A search is
+ -- made starting at the top of the state table and
+ -- terminates with the first match. If no match is found
+ -- then the next state and new outputs are set to all 'X's.
+ --
+ -- (Asynchronous inputs (i.e. resets and clears) must be
+ -- handled by placing the corresponding entries at the top
+ -- of the table. )
+ --
+ -- All inputs will be mapped to the X01 subtype.
+ --
+ -- NOTE: Edge transitions should not be used as values
+ -- for the state variables in the present state
+ -- portion of the state table. The only valid
+ -- values that can be used for the present state
+ -- portion of the state table are:
+ -- 'X', '0', '1', 'B', '-'
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- StateTable VitalStateTableType The input constant which defines
+ -- the behavior in state table form.
+ -- DataIn std_logic_vector The current state inputs to the
+ -- state table used to perform input
+ -- matches and transition
+ -- calculations.
+ -- NumStates NATURAL Number of state variables
+ --
+ -- INOUT
+ -- Result std_logic Output signal for scalar version of
+ -- the concurrent procedure call.
+ -- std_logic_vector Output signals for vector version
+ -- of the concurrent procedure call.
+ -- PreviousDataIn std_logic_vector The previous inputs and states used
+ -- in transition calculations and to
+ -- set outputs for steady state cases.
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalResolve
+ --
+ -- Description: VitalResolve takes a vector of signals and resolves
+ -- them to a std_ulogic value. This procedure can be used
+ -- to resolve multiple drivers in a single model.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Set of input signals which drive a
+ -- common signal.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal which is the resolved
+ -- value being driven by the collection of
+ -- input signals.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector); --IR236 4/2/98
+
+END VITAL_Primitives;
diff --git a/libraries/vital2000/timing_b.vhdl b/libraries/vital2000/timing_b.vhdl
new file mode 100644
index 000000000..28bf52095
--- /dev/null
+++ b/libraries/vital2000/timing_b.vhdl
@@ -0,0 +1,2187 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 598 $
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- : This file contains the Package Body.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/08/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #IR203 - Timing violations at time 0
+-- #IR204 - Output mapping prior to glitch detection
+-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998
+-- | #IR225 - Negative Premptive Glitch
+-- **Code_effected=ReportGlitch,VitalGlitch,
+-- VitalPathDelay,VitalPathDelay01,
+-- VitalPathDelay01z.
+-- #IR105 - Skew timing check needed
+-- **Code_effected=NONE, New code added!!
+-- #IR245,IR246,IR251 ITC code to fix false boundry cases
+-- **Code_effected=InternalTimingCheck.
+-- #IR248 - Allows VPD to use a default timing delay
+-- **Code_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z,
+-- VitalSelectPathDelay,VitalSelectPathDelay01,
+-- VitalSelectPathDelay01z.
+-- #IR250 - Corrects fastpath condition in VPD
+-- **Code_effected=VitalPathDelay01,
+-- VitalPathDelay01z,
+-- #IR252 - Corrects cancelled timing check call if
+-- condition expires.
+-- **Code_effected=VitalSetupHoldCheck,
+-- VitalRecoveryRemovalCheck.
+-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay
+-- and set default to FALSE in VitalPathDelay()
+--
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Timing IS
+
+ -- --------------------------------------------------------------------
+ -- Package Local Declarations
+ -- --------------------------------------------------------------------
+
+ TYPE CheckType IS ( SetupCheck, HoldCheck, RecoveryCheck, RemovalCheck,
+ PulseWidCheck, PeriodCheck );
+
+ TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+ END RECORD;
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+ CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+ TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+ -- last value, present value, edge symbol
+ CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := (
+ 'X'=>('X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) ),
+ '0'=>('X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) ),
+ '1'=>('X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE ) ) );
+
+
+
+
+ ---------------------------------------------------------------------------
+ -- Tables used to implement 'posedge' and 'negedge' in path delays
+ -- These are new tables for Skewcheck routines. IR105
+ ---------------------------------------------------------------------------
+
+ TYPE EdgeRable IS ARRAY(std_ulogic, std_ulogic) OF boolean;
+
+ CONSTANT Posedge : EdgeRable := (
+ -- ------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- ------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- U
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- X
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- 0
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 1
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- Z
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- W
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- L
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- H
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ) -- -
+
+ ); --IR105
+
+
+ CONSTANT Negedge : EdgeRable := (
+ -- -----------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- -----------------------------------------------------------------------
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- U
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- X
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 0
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- 1
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- Z
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- W
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- L
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- H
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ) -- -
+
+ ); --IR105
+
+ TYPE SkewType IS (Inphase, Outphase); --IR105
+
+ CONSTANT noTrigger : TIME := -1 ns; --IR105
+ ---------------------------------------------------------------------------
+ -- End of Skew (IR105 additions)
+ ---------------------------------------------------------------------------
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Misc Utilities Local Utilities
+ ---------------------------------------------------------------------------
+ -----------------------------------------------------------------------
+ FUNCTION Minimum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrVctLng ,
+ ErrNoPath ,
+ ErrNegPath ,
+ ErrNegDel
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrVctLng => ERROR,
+ ErrNoPath => WARNING,
+ ErrNegPath => WARNING,
+ ErrNegDel => WARNING
+ );
+
+ CONSTANT MsgNoPath : STRING :=
+ "No Delay Path Condition TRUE. 0-delay used. Output signal is: ";
+ CONSTANT MsgNegPath : STRING :=
+ "Path Delay less than time since input. 0 delay used. Output signal is: ";
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrNoPath => RETURN MsgNoPath;
+ WHEN ErrNegPath => RETURN MsgNegPath;
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Time Delay Assignment Subprograms
+ ---------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN (OTHERS => Delay);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z IS
+ VARIABLE Delay01Z : VitalDelayType01Z;
+ BEGIN
+ Delay01Z(tr01) := Delay(tr01);
+ Delay01Z(tr0z) := Delay(tr01);
+ Delay01Z(trz1) := Delay(tr01);
+ Delay01Z(tr10) := Delay(tr10);
+ Delay01Z(tr1z) := Delay(tr10);
+ Delay01Z(trz0) := Delay(tr10);
+ RETURN (Delay01Z);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN Delay;
+ END VitalExtendToFillDelay;
+
+ ---------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME IS
+ BEGIN
+ RETURN delay;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ WHEN OTHERS =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN 'Z' => Result := MINIMUM(Delay(tr10), Delay(tr01));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr0z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr01), Delay(tr0z));
+ END CASE;
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr1z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr10), Delay(tr1z));
+ END CASE;
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(trz0);
+ WHEN '1' | 'H' => Result := Delay(trz1);
+ WHEN 'Z' => Result := MAXIMUM (Delay(tr0z), Delay(tr1z));
+ WHEN OTHERS => Result := MINIMUM (Delay(trz1), Delay(trz0));
+ END CASE;
+ WHEN 'U' | 'X' | 'W' | '-' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := MAXIMUM(Delay(tr10), Delay(trz0));
+ WHEN '1' | 'H' => Result := MAXIMUM(Delay(tr01), Delay(trz1));
+ WHEN 'Z' => Result := MAXIMUM(Delay(tr1z), Delay(tr0z));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ ---------------------------------------------------------------------------
+ --
+ -- VitalSelectPathDelay returns the path delay selected by the Paths array.
+ -- If no paths are selected, it returns either the appropriate default
+ -- delay or TIME'HIGH, depending upon the value of IgnoreDefaultDelay.
+ --
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Glitch Handlers
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preempted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ ASSERT PreemptedTime <= NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Negative Preempted Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalGlitch (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225
+ CONSTANT MsgOn : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ ---------------------------------------------------------------------------
+ VARIABLE NewGlitch : BOOLEAN := TRUE;
+ VARIABLE dly : TIME := NewDelay;
+ VARIABLE NOW_TIME : TIME := NOW;
+ VARIABLE NegPreemptGlitch : BOOLEAN := FALSE;
+
+ BEGIN
+ NegPreemptGlitch:=FALSE;--reset Preempt-Glitch
+
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitch", ErrNegDel, OutSignalName );
+ END IF;
+ RETURN;
+ END IF;
+
+ -- If simple signal assignment
+ -- perform the signal assignment
+ IF ( Mode = VitalInertial) THEN
+ OutSignal <= NewValue AFTER dly;
+ ELSIF ( Mode = VitalTransport ) THEN
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ ELSE
+ -- Glitch Processing ---
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN -- NOW >= last event
+ -- Note: NewValue is always /= OldValue when called from VPPD
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- New value earlier than the earliest previous value scheduled
+ -- (negative preemptive)
+ ELSIF (NOW+dly <= GlitchData.GlitchTime)
+ AND (NOW+dly <= GlitchData.SchedTime) THEN
+
+ -- Glitch is negative preemptive - check if same value and
+ -- NegPreempt is on IR225
+ IF (GlitchData.SchedValue /= NewValue) AND (NegPreemptOn) AND
+ (NOW > 0 NS) THEN
+ NewGlitch := TRUE;
+ NegPreemptGlitch :=TRUE; -- Set preempt Glitch condition
+ ELSE
+ NewGlitch := FALSE; -- No new glitch, save time for
+ -- possible future glitch
+ END IF;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+ NewGlitch := FALSE;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue)
+ AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN
+ -- revise scheduled output time if new delay is sooner
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ -- No new glitch, save time for possable future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled represents a glitch
+ ELSE
+ NewGlitch := TRUE; -- A new glitch has been detected
+ END IF;
+
+ IF NewGlitch THEN
+ -- If messages requested, report the glitch
+ IF MsgOn THEN
+ IF NegPreemptGlitch THEN --IR225
+ ReportGlitch ("VitalGlitch-Neg", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ ELSE
+ ReportGlitch ("VitalGlitch", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+ END IF;
+
+ -- If 'X' generation is requested, schedule the new value
+ -- preceeded by a glitch pulse.
+ -- Otherwise just schedule the new value (inertial mode).
+ IF XOn THEN
+ IF (Mode = OnDetect) THEN
+ OutSignal <= 'X';
+ ELSE
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ END IF;
+
+ IF NegPreemptGlitch THEN -- IR225
+ OutSignal <= TRANSPORT NewValue AFTER GlitchData.SchedTime-NOW;
+ ELSE
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ END IF;
+ ELSE
+ OutSignal <= NewValue AFTER dly; -- no glitch regular prop delay
+ END IF;
+
+ -- If there no new glitch was detected, just schedule the new value.
+ ELSE
+ OutSignal <= NewValue AFTER dly;
+ END IF;
+ END IF;
+
+ -- Record the new value and time depending on glitch type just scheduled.
+ IF NOT NegPreemptGlitch THEN -- 5/2/96 for "x-pulse" IR225
+ GlitchData.SchedValue := NewValue;
+ GlitchData.SchedTime := NOW+dly; -- pulse timing.
+ ELSE
+ GlitchData.SchedValue := 'X';
+ -- leave GlitchData.SchedTime to old value since glitch is negative
+ END IF;
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay;
+
+ ---------------------------------------------------------------------------
+
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+
+
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01Z;
+
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER twire;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER dly;
+ END;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Setup and Hold Time Check Routine
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ IF NOT CheckInfo.Violation THEN RETURN; END IF;
+
+ Write ( Message, HeaderMsg );
+ Case CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportViolation;
+
+
+ ---------------------------------------------------------------------------
+ -- Procedure : InternalTimingCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+ ) IS
+ VARIABLE bias : TIME;
+ VARIABLE actualObsTime : TIME;
+ VARIABLE BC : TIME;
+ VARIABLE Message:LINE;
+ BEGIN
+ -- Check SETUP constraint
+ IF RefEdge THEN
+ IF SetupEn THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ -- start of new code IR245-246
+ BC := HoldHigh;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ -- start of new code IR245-246
+ BC := HoldLow;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ -- start of new code IR245-246
+ BC := Maximum(HoldHigh,HoldLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ ELSE
+ CheckInfo.CheckKind := SetupCheck;
+ END IF;
+ -- end of new code IR245-246
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF TestEvent THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '1';
+
+ -- start of new code IR245-246
+ BC := SetupLow;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '0';
+
+ -- start of new code IR245-246
+ BC := SetupHigh;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ -- start of new code IR245-246
+ BC := Maximum(SetupHigh,SetupLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ END IF;
+ -- end of new code IR245-246
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative
+ -- Note: bias may be negative or positive
+ IF MsgOn AND CheckInfo.Violation THEN
+ -- modified the code for correct reporting of violation in case of
+ -- order of signals being reversed because of internal delays
+ -- new variable
+ actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay);
+ bias := TestDelay - RefDelay;
+ IF (actualObsTime < 0 ns) THEN -- It should be a setup check
+ IF ( CheckInfo.CheckKind = HoldCheck) then
+ CheckInfo.CheckKind := SetupCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := -actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE -- It should be a hold check
+ IF ( CheckInfo.CheckKind = SetupCheck) then
+ CheckInfo.CheckKind := HoldCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+ CheckInfo.State := '1';
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+ CheckInfo.State := '0';
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+
+ END IF;
+ END InternalTimingCheck;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ FUNCTION VitalTimingDataInit
+ RETURN VitalTimingDataType IS
+ BEGIN
+ RETURN (FALSE,'X', 0 ns, FALSE, 'X', 0 ns, FALSE, NULL, NULL, NULL, NULL);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalSetupHoldCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableHoldOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ VARIABLE ChangedAllAtOnce : BOOLEAN := TRUE;
+ VARIABLE StrPtr1 : LINE;
+
+ BEGIN
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEnA.all := (TestSignal'RANGE => EnableHoldOnRef); --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ TimingData.SetupEnA(i) := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ TimingData.TestTime := NOW; --IR252 3/23/98
+ END IF;
+ END LOOP;
+
+ -- Check to see if the Bus subelements changed all at the same time.
+ -- If so, then we can reduce the volume of error messages since we no
+ -- longer have to report every subelement individually
+ FOR i IN TestSignal'RANGE LOOP
+ IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN
+ ChangedAllAtOnce := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ FOR i IN TestSignal'RANGE LOOP
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN
+ ReportViolation (TestSignalName&"(...)", RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ ELSIF (NOT ChangedAllAtOnce) THEN
+ Write (StrPtr1, i);
+ ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")",
+ RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ DEALLOCATE (StrPtr1);
+ END IF;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+
+ DEALLOCATE (StrPtr1);
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalRecoveryRemovalCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableRecOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableRemOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableRecOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableRemOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+
+ IF ActiveLow THEN
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ Recovery, 0 ns, 0 ns, Removal,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ ELSE
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ 0 ns, Recovery, Removal, 0 ns,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ END IF;
+
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF CheckInfo.CheckKind = SetupCheck THEN
+ CheckInfo.CheckKind := RecoveryCheck;
+ ELSE
+ CheckInfo.CheckKind := RemovalCheck;
+ END IF;
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalRecoveryRemovalCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : TIME;
+ VARIABLE PulseTest, PeriodTest : BOOLEAN;
+ VARIABLE TestValue : X01 := To_X01(TestSignal);
+ BEGIN
+
+ IF (PeriodData.NotFirstFlag = FALSE) THEN
+ PeriodData.Rise :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Fall :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Last := To_X01(TestSignal);
+ PeriodData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- No violation possible if no test signal change
+ Violation := '0';
+ IF (PeriodData.Last = TestValue) THEN
+ RETURN;
+ END IF;
+
+ -- record starting pulse times
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData.Rise;
+ PeriodData.Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData.Fall;
+ PeriodData.Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Fall;
+ CheckInfo.ExpTime := PulseWidthLow;
+ PulseTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Rise;
+ CheckInfo.ExpTime := PulseWidthHigh;
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF PulseTest AND CheckEnabled THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData.Last;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF PeriodTest AND CheckEnabled THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period;
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData.Last := TestValue;
+
+ END VitalPeriodPulseCheck;
+
+
+
+ PROCEDURE ReportSkewViolation (
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT ExpectedTime : IN TIME;
+ CONSTANT OccuranceTime : IN TIME;
+ CONSTANT HeaderMsg : IN STRING;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT SkewPhase : IN SkewType;
+ CONSTANT ViolationFlag : IN BOOLEAN := TRUE
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ Write ( Message, HeaderMsg );
+ IF (ViolationFlag /= TRUE) THEN
+ Write ( Message, STRING'(" POSSIBLE") );
+ END IF;
+ IF (SkewPhase = Inphase) THEN
+ Write ( Message, STRING'(" IN PHASE ") );
+ ELSE
+ Write ( Message, STRING'(" OUT OF PHASE ") );
+ END IF;
+ Write ( Message, STRING'("SKEW VIOLATION ON ") );
+ Write ( Message, Signal2Name );
+ IF (Signal1Name'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, Signal1Name );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" At : ") );
+ Write ( Message, OccuranceTime);
+ Write ( Message, STRING'("; Skew Limit : ") );
+ Write ( Message, ExpectedTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportSkewViolation;
+
+
+ PROCEDURE VitalInPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ ReportType := none;
+ TriggerDelay := noTrigger;
+
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF ( Signal1'Event OR Signal2'Event ) THEN
+ IF ( Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF ((Signal2Delay -Signal1Delay) >=
+ SkewS2S1RiseRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2RiseRise < SkewS2S1RiseRise) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise;
+ ELSE
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2FallFall < SkewS2S1FallFall) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall;
+ ELSE
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF ( Signal1 /= Signal2) THEN
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2RiseRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2FallFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2RiseRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF ((SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseRise)) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1RiseRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1FallFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ SkewData.ExpectedType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalInPhaseSkewCheck;
+
+ PROCEDURE VitalOutPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ TriggerDelay := noTrigger;
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF (Signal1'Event OR Signal2'Event ) THEN
+ IF (Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ SkewData.ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1RiseFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1RiseFall < SkewS1S2RiseFall) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall;
+ ELSE
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1FallRise < SkewS1S2FallRise) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise;
+ ELSE
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE,Signal1)) THEN
+ IF (SkewS1S2RiseFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ END IF;
+ ELSIF ( Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ( SkewS1S2FallRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge( Signal1'LAST_VALUE, Signal1 )) THEN
+ IF ((Signal1Delay - SkewS1S2RiseFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2RiseFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2FallRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1RiseFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall + Signal1Delay -
+ Signal2Delay ;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1FallRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise + Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ ReportType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalOutPhaseSkewCheck;
+
+END VITAL_Timing;
diff --git a/libraries/vital2000/timing_p.vhdl b/libraries/vital2000/timing_p.vhdl
new file mode 100644
index 000000000..e18c8c24a
--- /dev/null
+++ b/libraries/vital2000/timing_p.vhdl
@@ -0,0 +1,1202 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 598 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #203 - Timing violations at time 0
+-- #204 - Output mapping prior to glitch detection
+-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998
+-- | #IR225 - Negative Premptive Glitch
+-- **Pkg_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z.
+-- #IR105 - Skew timing check needed
+-- **Pkg_effected=NONE, New code added!!
+-- #IR248 - Allows VPD to use a default timing
+-- delay
+-- **Pkg_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z,
+-- #IR250 - Corrects fastpath condition in VPD
+-- **Pkg_effected=VitalPathDelay01,
+-- VitalPathDelay01z,
+-- #IR252 - Corrects cancelled timing check call if
+-- condition expires.
+-- **Pkg_effected=VitalSetupHoldCheck,
+-- VitalRecoveryRemovalCheck.
+-- #IR105 - Skew timing check
+-- **Pkg_effected=NONE, New code added
+-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay
+-- and set default to FALSE in VitalPathDelay()
+-- v00.7 | dbb | 07/18/00 | Removed "maximum" from VitalPeriodPulse()
+-- comments
+
+
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+
+PACKAGE VITAL_Timing IS
+ TYPE VitalTransitionType IS ( tr01, tr10, tr0z, trz1, tr1z, trz0,
+ tr0X, trx1, tr1x, trx0, trxz, trzx);
+
+ SUBTYPE VitalDelayType IS TIME;
+ TYPE VitalDelayType01 IS ARRAY (VitalTransitionType RANGE tr01 to tr10)
+ OF TIME;
+ TYPE VitalDelayType01Z IS ARRAY (VitalTransitionType RANGE tr01 to trz0)
+ OF TIME;
+ TYPE VitalDelayType01ZX IS ARRAY (VitalTransitionType RANGE tr01 to trzx)
+ OF TIME;
+
+ TYPE VitalDelayArrayType IS ARRAY (NATURAL RANGE <>) OF VitalDelayType;
+ TYPE VitalDelayArrayType01 IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01;
+ TYPE VitalDelayArrayType01Z IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01Z;
+ TYPE VitalDelayArrayType01ZX IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01ZX;
+ -- ----------------------------------------------------------------------
+ -- **********************************************************************
+ -- ----------------------------------------------------------------------
+
+ CONSTANT VitalZeroDelay : VitalDelayType := 0 ns;
+ CONSTANT VitalZeroDelay01 : VitalDelayType01 := ( 0 ns, 0 ns );
+ CONSTANT VitalZeroDelay01Z : VitalDelayType01Z := ( OTHERS => 0 ns );
+ CONSTANT VitalZeroDelay01ZX : VitalDelayType01ZX := ( OTHERS => 0 ns );
+
+ ---------------------------------------------------------------------------
+ -- examples of usage:
+ ---------------------------------------------------------------------------
+ -- tpd_CLK_Q : VitalDelayType := 5 ns;
+ -- tpd_CLK_Q : VitalDelayType01 := (tr01 => 2 ns, tr10 => 3 ns);
+ -- tpd_CLK_Q : VitalDelayType01Z := ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns );
+ -- tpd_CLK_Q : VitalDelayArrayType(0 to 1)
+ -- := (0 => 5 ns, 1 => 6 ns);
+ -- tpd_CLK_Q : VitalDelayArrayType01(0 to 1)
+ -- := (0 => (tr01 => 2 ns, tr10 => 3 ns),
+ -- 1 => (tr01 => 2 ns, tr10 => 3 ns));
+ -- tpd_CLK_Q : VitalDelayArrayType01Z(0 to 1)
+ -- := (0 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ),
+ -- 1 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ));
+ ---------------------------------------------------------------------------
+
+ -- TRUE if the model is LEVEL0 | LEVEL1 compliant
+ ATTRIBUTE VITAL_Level0 : BOOLEAN;
+ ATTRIBUTE VITAL_Level1 : BOOLEAN;
+
+ SUBTYPE std_logic_vector2 IS std_logic_vector(1 DOWNTO 0);
+ SUBTYPE std_logic_vector3 IS std_logic_vector(2 DOWNTO 0);
+ SUBTYPE std_logic_vector4 IS std_logic_vector(3 DOWNTO 0);
+ SUBTYPE std_logic_vector8 IS std_logic_vector(7 DOWNTO 0);
+
+ -- Types for strength mapping of outputs
+ TYPE VitalOutputMapType IS ARRAY ( std_ulogic ) OF std_ulogic;
+ TYPE VitalResultMapType IS ARRAY ( UX01 ) OF std_ulogic;
+ TYPE VitalResultZMapType IS ARRAY ( UX01Z ) OF std_ulogic;
+ CONSTANT VitalDefaultOutputMap : VitalOutputMapType
+ := "UX01ZWLH-";
+ CONSTANT VitalDefaultResultMap : VitalResultMapType
+ := ( 'U', 'X', '0', '1' );
+ CONSTANT VitalDefaultResultZMap : VitalResultZMapType
+ := ( 'U', 'X', '0', '1', 'Z' );
+
+ -- Types for fields of VitalTimingDataType
+ TYPE VitalTimeArrayT IS ARRAY (INTEGER RANGE <>) OF TIME;
+ TYPE VitalTimeArrayPT IS ACCESS VitalTimeArrayT;
+ TYPE VitalBoolArrayT IS ARRAY (INTEGER RANGE <>) OF BOOLEAN;
+ TYPE VitalBoolArrayPT IS ACCESS VitalBoolArrayT;
+ TYPE VitalLogicArrayPT IS ACCESS std_logic_vector;
+
+ TYPE VitalTimingDataType IS RECORD
+ NotFirstFlag : BOOLEAN;
+ RefLast : X01;
+ RefTime : TIME;
+ HoldEn : BOOLEAN;
+ TestLast : std_ulogic;
+ TestTime : TIME;
+ SetupEn : BOOLEAN;
+ TestLastA : VitalLogicArrayPT;
+ TestTimeA : VitalTimeArrayPT;
+ HoldEnA : VitalBoolArrayPT;
+ SetupEnA : VitalBoolArrayPT;
+ END RECORD;
+
+ FUNCTION VitalTimingDataInit RETURN VitalTimingDataType;
+
+ -- type for internal data of VitalPeriodPulseCheck
+ TYPE VitalPeriodDataType IS RECORD
+ Last : X01;
+ Rise : TIME;
+ Fall : TIME;
+ NotFirstFlag : BOOLEAN;
+ END RECORD;
+ CONSTANT VitalPeriodDataInit : VitalPeriodDataType
+ := ('X', 0 ns, 0 ns, FALSE );
+
+ -- Type for specifying the kind of Glitch handling to use
+ TYPE VitalGlitchKindType IS (OnEvent,
+ OnDetect,
+ VitalInertial,
+ VitalTransport);
+
+ TYPE VitalGlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ LastValue : std_ulogic;
+ END RECORD;
+ TYPE VitalGlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF VitalGlitchDataType;
+
+ -- PathTypes: for handling simple PathDelay info
+ TYPE VitalPathType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01Type IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01ZType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01Z;-- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+
+ -- For representing multiple paths to an output
+ TYPE VitalPathArrayType IS ARRAY (NATURAL RANGE <> ) OF VitalPathType;
+ TYPE VitalPathArray01Type IS ARRAY (NATURAL RANGE <> ) OF VitalPath01Type;
+ TYPE VitalPathArray01ZType IS ARRAY (NATURAL RANGE <> ) OF VitalPath01ZType;
+
+ TYPE VitalTableSymbolType IS (
+ '/', -- 0 -> 1
+ '\', -- 1 -> 0
+ 'P', -- Union of '/' and '^' (any edge to 1)
+ 'N', -- Union of '\' and 'v' (any edge to 0)
+ 'r', -- 0 -> X
+ 'f', -- 1 -> X
+ 'p', -- Union of '/' and 'r' (any edge from 0)
+ 'n', -- Union of '\' and 'f' (any edge from 1)
+ 'R', -- Union of '^' and 'p' (any possible rising edge)
+ 'F', -- Union of 'v' and 'n' (any possible falling edge)
+ '^', -- X -> 1
+ 'v', -- X -> 0
+ 'E', -- Union of 'v' and '^' (any edge from X)
+ 'A', -- Union of 'r' and '^' (rising edge to or from 'X')
+ 'D', -- Union of 'f' and 'v' (falling edge to or from 'X')
+ '*', -- Union of 'R' and 'F' (any edge)
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '-', -- don't care
+ 'B', -- 0 or 1
+ 'Z', -- High Impedance
+ 'S' -- steady value
+ );
+
+ SUBTYPE VitalEdgeSymbolType IS VitalTableSymbolType RANGE '/' TO '*';
+
+
+
+
+ -- Addition of Vital Skew Type Information
+ -- March 14, 1998
+
+ ---------------------------------------------------------------------------
+ -- Procedures and Type Definitions for Defining Skews
+ ---------------------------------------------------------------------------
+
+ TYPE VitalSkewExpectedType IS (none, s1r, s1f, s2r, s2f);
+
+ TYPE VitalSkewDataType IS RECORD
+ ExpectedType : VitalSkewExpectedType;
+ Signal1Old1 : TIME;
+ Signal2Old1 : TIME;
+ Signal1Old2 : TIME;
+ Signal2Old2 : TIME;
+ END RECORD;
+
+ CONSTANT VitalSkewDataInit : VitalSkewDataType := ( none, 0 ns, 0 ns, 0 ns, 0 ns );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalExtendToFillDelay
+ --
+ -- Description: A six element array of delay values of type
+ -- VitalDelayType01Z is returned when a 1, 2 or 6
+ -- element array is given. This function will convert
+ -- VitalDelayType and VitalDelayType01 delay values into
+ -- a VitalDelayType01Z type following these rules:
+ --
+ -- When a VitalDelayType is passed, all six transition
+ -- values are assigned the input value. When a
+ -- VitalDelayType01 is passed, the 01 transitions are
+ -- assigned to the 01, 0Z and Z1 transitions and the 10
+ -- transitions are assigned to 10, 1Z and Z0 transition
+ -- values. When a VitalDelayType01Z is passed, the values
+ -- are kept as is.
+ --
+ -- The function is overloaded based on input type.
+ --
+ -- There is no function to fill a 12 value delay
+ -- type.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Delay A one, two or six delay value Vital-
+ -- DelayType is passed and a six delay,
+ -- VitalDelayType01Z, item is returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- VitalDelayType01Z
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalCalcDelay
+ --
+ -- Description: This function accepts a 1, 2 or 6 value delay and
+ -- chooses the correct delay time to delay the NewVal
+ -- signal. This function is overloaded based on the
+ -- delay type passed. The function returns a single value
+ -- of time.
+ --
+ -- This function is provided for Level 0 models in order
+ -- to calculate the delay which should be applied
+ -- for the passed signal. The delay selection is performed
+ -- using the OldVal and the NewVal to determine the
+ -- transition to select. The default value of OldVal is X.
+ --
+ -- This function cannot be used in a Level 1 model since
+ -- the VitalPathDelay routines perform the delay path
+ -- selection and output driving function.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- NewVal New value of the signal to be
+ -- assigned
+ -- OldVal Previous value of the signal.
+ -- Default value is 'X'
+ -- Delay The delay structure from which to
+ -- select the appropriate delay. The
+ -- function overload is based on the
+ -- type of delay passed. In the case of
+ -- the single delay, VitalDelayType, no
+ -- selection is performed, since there
+ -- is only one value to choose from.
+ -- For the other cases, the transition
+ -- from the old value to the new value
+ -- decide the value returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- Time The time value selected from the
+ -- Delay INPUT is returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPathDelay
+ --
+ -- Description: VitalPathDelay is the Level 1 routine used to select
+ -- the propagation delay path and schedule a new output
+ -- value.
+ --
+ -- For single and dual delay values, VitalDelayType and
+ -- VitalDelayType01 are used. The output value is
+ -- scheduled with a calculated delay without strength
+ -- modification.
+ --
+ -- For the six delay value, VitalDelayType01Z, the output
+ -- value is scheduled with a calculated delay. The drive
+ -- strength can be modified to handle weak signal strengths
+ -- to model tri-state devices, pull-ups and pull-downs as
+ -- an example.
+ --
+ -- The correspondence between the delay type and the
+ -- path delay function is as follows:
+ --
+ -- Delay Type Path Type
+ --
+ -- VitalDelayType VitalPathDelay
+ -- VitalDelayType01 VitalPathDelay01
+ -- VitalDelayType01Z VitalPathDelay01Z
+ --
+ -- For each of these routines, the following capabilities
+ -- is provided:
+ --
+ -- o Transition dependent path delay selection
+ -- o User controlled glitch detection with the ability
+ -- to generate "X" on output and report the violation
+ -- o Control of the severity level for message generation
+ -- o Scheduling of the computed values on the specified
+ -- signal.
+ --
+ -- Selection of the appropriate path delay begins with the
+ -- candidate paths. The candidate paths are selected by
+ -- identifying the paths for which the PathCondition is
+ -- true. If there is a single candidate path, then that
+ -- delay is selected. If there is more than one candidate
+ -- path, then the shortest delay is selected using
+ -- transition dependent delay selection. If there is no
+ -- candidate paths, then the delay specified by the
+ -- DefaultDelay parameter to the path delay is used.
+ --
+ -- Once the delay is known, the output signal is then
+ -- scheduled with that delay. In the case of
+ -- VitalPathDelay01Z, an additional result mapping of
+ -- the output value is performed before scheduling. The
+ -- result mapping is performed after transition dependent
+ -- delay selection but before scheduling the final output.
+ --
+ -- In order to perform glitch detection, the user is
+ -- obligated to provide a variable of VitalGlitchDataType
+ -- for the propagation delay functions to use. The user
+ -- cannot modify or use this information.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- OutSignalName string The name of the output signal
+ -- OutTemp std_logic The new output value to be driven
+ -- Paths VitalPathArrayType A list of paths of VitalPathArray
+ -- VitalPathArrayType01 type. The VitalPathDelay routine
+ -- VitalPathArrayType01Z is overloaded based on the type
+ -- of constant passed in. With
+ -- VitalPathArrayType01Z, the
+ -- resulting output strengths can be
+ -- mapped.
+ -- DefaultDelay VitalDelayType The default delay can be changed
+ -- VitalDelayType01 from zero-delay to another set
+ -- VitalDelayType01Z of values.
+ --
+ -- IgnoreDefaultDelay BOOLEAN If TRUE, the default delay will
+ -- be used when no paths are
+ -- selected. If false, no event
+ -- will be scheduled if no paths are
+ -- selected.
+ --
+ -- Mode VitalGlitchKindType The value of this constant
+ -- selects the type of glitch
+ -- detection.
+ -- OnEvent Glitch on transition event
+ -- | OnDetect Glitch immediate on detection
+ -- | VitalInertial No glitch, use INERTIAL
+ -- assignment
+ -- | VitalTransport No glitch, use TRANSPORT
+ -- assignment
+ -- XOn BOOLEAN Control for generation of 'X' on
+ -- glitch. When TRUE, 'X's are
+ -- scheduled for glitches, otherwise
+ -- no are generated.
+ -- MsgOn BOOLEAN Control for message generation on
+ -- glitch detect. When TRUE,
+ -- glitches are reported, otherwise
+ -- they are not reported.
+ -- MsgSeverity SEVERITY_LEVEL The level at which the message,
+ -- or assertion, will be reported.
+ -- IgnoreDefaultDelay BOOLEAN Tells the VPD whether to use the
+ -- default delay value in the absense
+ -- of a valid delay for input conditions 3/14/98 MG
+ --
+ -- OutputMap VitalOutputMapType For VitalPathDelay01Z, the output
+ -- can be mapped to alternate
+ -- strengths to model tri-state
+ -- devices, pull-ups and pull-downs.
+ --
+ -- INOUT
+ -- GlitchData VitalGlitchDataType The internal data storage
+ -- variable required to detect
+ -- glitches.
+ --
+ -- OUT
+ -- OutSignal std_logic The output signal to be driven
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98
+ );
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ );
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalWireDelay
+ --
+ -- Description: VitalWireDelay is used to delay an input signal.
+ -- The delay is selected from the input parameter passed.
+ -- The function is useful for back annotation of actual
+ -- net delays.
+ --
+ -- The function is overloaded to permit passing a delay
+ -- value for twire for VitalDelayType, VitalDelayType01
+ -- and VitalDelayType01Z. twire is a generic which can
+ -- be back annotated and must be constructed to follow
+ -- the SDF to generic mapping rules.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The input signal (port) to be
+ -- delayed.
+ -- twire VitalDelayType The delay value for which the input
+ -- VitalDelayType01 signal should be delayed. For Vital-
+ -- VitalDelayType01Z DelayType, the value is single value
+ -- passed. For VitalDelayType01 and
+ -- VitalDelayType01Z, the appropriate
+ -- delay value is selected by VitalCalc-
+ -- Delay.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The internal delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSignalDelay
+ --
+ -- Description: The VitalSignalDelay procedure is called in a signal
+ -- delay block in the architecture to delay the
+ -- appropriate test or reference signal in order to
+ -- accommodate negative constraint checks.
+ --
+ -- The amount of delay is of type TIME and is a constant.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The signal to be delayed.
+ -- dly TIME The amount of time the signal is
+ -- delayed.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSetupHoldCheck
+ --
+ -- Description: The VitalSetupHoldCheck procedure detects a setup or a
+ -- hold violation on the input test signal with respect
+ -- to the corresponding input reference signal. The timing
+ -- constraints are specified through parameters
+ -- representing the high and low values for the setup and
+ -- hold values for the setup and hold times. This
+ -- procedure assumes non-negative values for setup and hold
+ -- timing constraints.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative setup times result in
+ -- a delayed reference signal. Negative hold times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- This function is overloaded based on the input
+ -- TestSignal. A vector and scalar form are provided.
+ --
+ -- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| error region |<--
+ -- :
+ -- _______________________________
+ -- RefSignal \______________________________
+ -- : | | |
+ -- : | -->| |<-- thold
+ -- : -->| tsetup |<--
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- std_logic_vector
+ -- TestSignalName STRING Name of test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- RefSignal std_ulogic Value of reference signal
+ -- RefSignalName STRING Name of reference signal
+ -- RefDelay TIME Model's internal delay associated
+ -- with RefSignal
+ -- SetupHigh TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a setup violation.
+ -- SetupLow TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a setup violation.
+ -- HoldHigh TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a hold violation.
+ -- HoldLow TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a hold violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specified. Events on
+ -- the RefSignal which match the edge
+ -- spec. are used as reference edges.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0".
+ -- MsgOn BOOLEAN If TRUE, set and hold violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ -- EnableSetupOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no setup check will be performed.
+ -- EnableSetupOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no setup check will be performed.
+ -- EnableHoldOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no hold check will be performed.
+ -- EnableHoldOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no hold check will be performed.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalSetupHoldCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalRecoveryRemovalCheck
+ --
+ -- Description: The VitalRecoveryRemovalCheck detects the presence of
+ -- a recovery or removal violation on the input test
+ -- signal with respect to the corresponding input reference
+ -- signal. It assumes non-negative values of setup and
+ -- hold timing constraints. The timing constraint is
+ -- specified through parameters representing the recovery
+ -- and removal times associated with a reference edge of
+ -- the reference signal. A flag indicates whether a test
+ -- signal is asserted when it is high or when it is low.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative recovery times result in
+ -- a delayed reference signal. Negative removal times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of TestSignal. The routine is
+ -- TestSignalName STRING Name of TestSignal
+ -- TestDelay TIME Model internal delay associated with
+ -- the TestSignal
+ -- RefSignal std_ulogic Value of RefSignal
+ -- RefSignalName STRING Name of RefSignal
+ -- RefDelay TIME Model internal delay associated with
+ -- the RefSignal
+ -- Recovery TIME A change to an unasserted value on
+ -- the asynchronous TestSignal must
+ -- precede reference edge (on RefSignal)
+ -- by at least this time.
+ -- Removal TIME An asserted condition must be present
+ -- on the asynchronous TestSignal for at
+ -- least the removal time following a
+ -- reference edge on RefSignal.
+ -- ActiveLow BOOLEAN A flag which indicates if TestSignal
+ -- is asserted when it is low - "0."
+ -- FALSE indicate that TestSignal is
+ -- asserted when it has a value "1."
+ -- CheckEnabled BOOLEAN The check in enabled when the value
+ -- is TRUE, otherwise the constraints
+ -- are not checked.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specifier. Events on
+ -- RefSignal will match the edge
+ -- specified.
+ -- HeaderMsg STRING A header message that will accompany
+ -- any assertion message.
+ -- XOn BOOLEAN When TRUE, the output Violation is
+ -- set to "X." When FALSE, it is always
+ -- "0."
+ -- MsgOn BOOLEAN When TRUE, violation messages are
+ -- output. When FALSE, no messages are
+ -- generated.
+ -- MsgSeverity SEVERITY_LEVEL Severity level of the asserted
+ -- message.
+ -- EnableRecOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no recovery check will be performed.
+ -- EnableRecOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no recovery check will be performed.
+ -- EnableRemOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no removal check will be performed.
+ -- EnableRemOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no removal check will be performed.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalRecoveryRemovalCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPeriodPulseCheck
+ --
+ -- Description: VitalPeriodPulseCheck checks for minimum
+ -- periodicity and pulse width for "1" and "0" values of
+ -- the input test signal. The timing constraint is
+ -- specified through parameters representing the minimal
+ -- period between successive rising and falling edges of
+ -- the input test signal and the minimum pulse widths
+ -- associated with high and low values.
+ --
+ -- VitalPeriodCheck's accepts rising and falling edges
+ -- from 1 and 0 as well as transitions to and from 'X.'
+ --
+ -- _______________ __________
+ -- ____________| |_______|
+ --
+ -- |<--- pw_hi --->|
+ -- |<-------- period ----->|
+ -- -->| pw_lo |<--
+ --
+ -- Arguments:
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- TestSignalName STRING Name of the test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- Period TIME Minimum period allowed between
+ -- consecutive rising ('P') or
+ -- falling ('F') transitions.
+ -- PulseWidthHigh TIME Minimum time allowed for a high
+ -- pulse ('1' or 'H')
+ -- PulseWidthLow TIME Minimum time allowed for a low
+ -- pulse ('0' or 'L')
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0".
+ -- XOnChecks is a global that allows for
+ -- only timing checks to be turned on.
+ -- MsgOn BOOLEAN If TRUE, period/pulse violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even though a violation is detected.
+ -- MsgOnChecks allows for only timing
+ -- check messages to be turned on.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- PeriodData VitalPeriodDataType
+ -- VitalPeriodPulseCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the pulse and period
+ -- times.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalInPhaseSkewCheck
+ --
+ -- Description: The VitalInPhaseSkewCheck procedure detects an in-phase
+ -- skew violation between input signals Signal1 and Signal2.
+ -- This is a timer based skew check in which a
+ -- violation is detected if Signal1 and Signal2 are in
+ -- different logic states longer than the specified skew
+ -- interval.
+ --
+ -- The timing constraints are specified through parameters
+ -- representing the skew values for the different states
+ -- of Signal1 and Signal2.
+ --
+ --
+ -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| |<--
+ -- : Signal2 should go low in this region
+ -- :
+ --
+ -- ____________
+ -- Signal1 \_________________________________________________
+ -- : | |
+ -- : |<-------- tskew -------->|
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Signal1 std_ulogic Value of first signal
+ -- Signal1Name STRING Name of first signal
+ -- Signal1Delay TIME Model's internal delay associated
+ -- with Signal1
+ -- Signal2 std_ulogic Value of second signal
+ -- Signal2Name STRING Name of second signal
+ -- Signal2Delay TIME Model's internal delay associated
+ -- with Signal2
+ -- SkewS1S2RiseRise TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "0"
+ -- after Signal1 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS2S1RiseRise TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "0"
+ -- after Signal2 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS1S2FallFall TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "1"
+ -- after Signal1 goes to the "0" state,
+ -- without causing a skew violation.
+ -- SkewS2S1FallFall TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "1"
+ -- after Signal2 goes to the "0" state,
+ -- without causing a skew violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, skew timing violation
+ -- messages will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- SkewData VitalSkewDataType
+ -- VitalInPhaseSkewCheck information
+ -- storage area. This is used
+ -- internally to detect signal edges
+ -- and record the time of the last edge.
+ --
+ --
+ -- Trigger std_ulogic This signal is used to trigger the
+ -- process in which the timing check
+ -- occurs upon expiry of the skew
+ -- interval.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+
+ PROCEDURE VitalInPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalOutPhaseSkewCheck
+ --
+ -- Description: The VitalOutPhaseSkewCheck procedure detects an
+ -- out-of-phase skew violation between input signals Signal1
+ -- and Signal2. This is a timer based skew check in
+ -- which a violation is detected if Signal1 and Signal2 are
+ -- in the same logic state longer than the specified skew
+ -- interval.
+ --
+ -- The timing constraints are specified through parameters
+ -- representing the skew values for the different states
+ -- of Signal1 and Signal2.
+ --
+ --
+ -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| |<--
+ -- : Signal2 should go high in this region
+ -- :
+ --
+ -- ____________
+ -- Signal1 \_________________________________________________
+ -- : | |
+ -- : |<-------- tskew -------->|
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Signal1 std_ulogic Value of first signal
+ -- Signal1Name STRING Name of first signal
+ -- Signal1Delay TIME Model's internal delay associated
+ -- with Signal1
+ -- Signal2 std_ulogic Value of second signal
+ -- Signal2Name STRING Name of second signal
+ -- Signal2Delay TIME Model's internal delay associated
+ -- with Signal2
+ -- SkewS1S2RiseFall TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "1"
+ -- after Signal1 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS2S1RiseFall TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "1"
+ -- after Signal2 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS1S2FallRise TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "0"
+ -- after Signal1 goes to the "0" state,
+ -- without causing a skew violation.
+ -- SkewS2S1FallRise TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "0"
+ -- after Signal2 goes to the "0" state,
+ -- without causing a skew violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, skew timing violation
+ -- messages will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- SkewData VitalSkewDataType
+ -- VitalInPhaseSkewCheck information
+ -- storage area. This is used
+ -- internally to detect signal edges
+ -- and record the time of the last edge.
+ --
+ -- Trigger std_ulogic This signal is used to trigger the
+ -- process in which the timing check
+ -- occurs upon expiry of the skew
+ -- interval.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalOutPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ );
+
+
+END VITAL_Timing;
diff --git a/libraries/vital95/vital_primitives.vhdl b/libraries/vital95/vital_primitives.vhdl
new file mode 100644
index 000000000..d0da36ba0
--- /dev/null
+++ b/libraries/vital95/vital_primitives.vhdl
@@ -0,0 +1,1410 @@
+-- -----------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 597 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- ----------------------------------------------------------------------------
+--
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+USE IEEE.VITAL_Timing.ALL;
+
+PACKAGE VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+
+ -- For Truth and State Tables
+ SUBTYPE VitalTruthSymbolType IS VitalTableSymbolType RANGE 'X' TO 'Z';
+ SUBTYPE VitalStateSymbolType IS VitalTableSymbolType RANGE '/' TO 'S';
+
+ TYPE VitalTruthTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalTruthSymbolType;
+ TYPE VitalStateTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalStateSymbolType;
+
+ -- ---------------------------------
+ -- Default values used by primitives
+ -- ---------------------------------
+ CONSTANT VitalDefDelay01 : VitalDelayType01; -- Propagation delays
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ -- VITAL Primitives
+ --
+ -- The primitives packages contains a collections of common gates,
+ -- including AND, OR, XOR, NAND, NOR, XNOR, BUF, INV, MUX and DECODER
+ -- functions. In addition, for sequential devices, a STATE TABLE construct
+ -- is provided. For complex functions a modeler may wish to use either
+ -- a collection of connected VITAL primitives, or a TRUTH TABLE construct.
+ --
+ -- For each primitive a Function and Procedure is provided. The primitive
+ -- functions are provided to support behavioral modeling styles. The
+ -- primitive procedures are provided to support structural modeling styles.
+ --
+ -- The procedures wait internally for an event on an input signal, compute
+ -- the new result, perform glitch handling, schedule transaction on the
+ -- output signals, and wait for future input events. All of the functional
+ -- (logic) input or output parameters of the primitive procedures are
+ -- signals. All the other parameters are constants.
+ --
+ -- The procedure primitives are parameterized for separate path delays
+ -- from each input signal. All path delays default to 0 ns.
+ --
+ -- The sequential primitive functions compute the defined function and
+ -- return a value of type std_ulogic or std_logic_vector. All parameters
+ -- of the primitive functions are constants of mode IN.
+ --
+ -- The primitives are based on 1164 operators. The user may also elect to
+ -- express functions using the 1164 operators as well. These styles are
+ -- all equally acceptable methods for device modeling.
+ --
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: N-input logic device function calls:
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The function calls return the evaluated logic function
+ -- corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-bit
+ -- wide logic functions.
+ -- ResultMap VitalResultMapType The output signal strength
+ -- result map to modify default
+ -- result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The evaluated logic function of
+ -- the n-bit wide primitives.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: N-input logic device concurrent procedure calls.
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delay form data to q is a
+ -- a parameter to the procedure. A vector of delay values
+ -- for inputs to output are provided. It is noted that
+ -- limitations in SDF make the back annotation of the delay
+ -- array difficult.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-
+ -- bit wide logic functions.
+ -- tpd_data_q VitalDelayArrayType01 The propagation delay from
+ -- the data inputs to the output
+ -- q.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the
+ -- evaluated logic function.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: 2,3 and 4 input logic device function calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The function calls return the evaluated 2, 3 or 4 input
+ -- logic function corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The result of the evaluated logic
+ -- function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: 2, 3 and 4 input logic device concurrent procedure
+ -- calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delays from a and b to q are
+ -- a parameter to the procedure. The default propagation
+ -- delay is 0 ns.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- tpd_a_q VitalDelayType01 The propagation delay from the a
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_b_q VitalDelayType01 The propagation delay from the b
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_c_q VitalDelayType01 The propagation delay from the c
+ -- input to output q for 3 and 4 input
+ -- devices.
+ -- tpd_d_q VitalDelayType01 The propagation delay from the d
+ -- input to output q for 4 input
+ -- devices.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the evaluated
+ -- logic function.
+ --
+ -- Returns
+ -- none
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: Buffer logic device concurrent procedure calls.
+ --
+ -- Description: Four buffer sequential primitive function calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the four permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the buffers
+ -- Enable std_ulogic Enable for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The output signal of the evaluated
+ -- buffer function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: Buffer device procedure calls.
+ --
+ -- Description: Four buffer concurrent primitive procedure calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the fourth permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal to the buffers
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low buffers.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input to
+ -- output for the simple buffer.
+ -- VitalDelayType01Z Propagation delay from input to
+ -- to output for the enable high and low
+ -- and identity buffers.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from enable to
+ -- output for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output of the buffers.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: Inverter functions which return the inverted signal
+ -- value. Inverters with enable low and high are provided
+ -- which can drive high impedance when inactive.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the inverter
+ -- Enable std_ulogic Enable to the enable high and low
+ -- inverters.
+ -- ResultMap VitalResultMap The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic Output of the inverter
+ --
+ -- -------------------------------------------------------------------------
+
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: The concurrent primitive procedure calls implement a
+ -- signal inversion function. The output is a parameter to
+ -- the procedure. The path delay information is passed as
+ -- a parameter to the call.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal for the simple inverter
+ -- Data std_ulogic Input signal for the enable high and
+ -- low inverters.
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low inverters.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input a to
+ -- output q for the simple inverter.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data to
+ -- output q for the enable high and low
+ -- inverters.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from input enable
+ -- to output q for the enable high and
+ -- low inverters.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal of the inverter.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX functions return the selected data bit
+ -- based on the value of dSelect. For MUX2, the function
+ -- returns data0 when dselect is 0 and returns data1 when
+ -- dselect is 1. When dselect is X, result is X for MUX2
+ -- when data0 /= data1. X propagation is reduced when the
+ -- dselect signal is X and both data signals are identical.
+ -- When this is the case, the result returned is the value
+ -- of the data signals.
+ --
+ -- For the N input device:
+ --
+ -- N must equal 2**(bits of dSelect)
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Input signal for the N-bit, 4-bit and
+ -- 8-bit mux.
+ -- Data1,Data0 std_ulogic Input signals for the 2-bit mux.
+ -- dSelect std_ulogic Select signal for 2-bit mux
+ -- std_logic_vector2 Select signal for 4-bit mux
+ -- std_logic_vector3 Select signal for 8-bit mux
+ -- std_logic_vector Select signal for N-Bit mux
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The value of the selected bit is
+ -- returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX concurrent primitive procedures calls
+ -- return in the output q the value of the selected data
+ -- bit based on the value of dsel. For the two bit mux,
+ -- the data returned is either d0 or d1, the data input.
+ -- For 4, 8 and N-bit functions, data is the input and is
+ -- of type std_logic_vector. For the 2-bit mux, if d0 or
+ -- d1 are X, the output is X only when d0 do not equal d1.
+ -- When d0 and d1 are equal, the return value is this value
+ -- to reduce X propagation.
+ --
+ -- Propagation delay information is passed as a parameter
+ -- to the procedure call for delays from data to output and
+ -- select to output. For 2-bit muxes, the propagation
+ -- delays from data are provided for d0 and d1 to output.
+ --
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- d1,d0 std_ulogic Input signals for the 2-bit mux.
+ -- Data std_logic_vector4 Input signals for the 4-bit mux.
+ -- std_logic_vector8 Input signals for the 8-bit mux.
+ -- std_logic_vector Input signals for the N-bit mux.
+ -- dsel std_ulogic Select signal for the 2-bit mux.
+ -- std_logic_vector2 Select signals for the 4-bit mux.
+ -- std_logic_vector3 Select signals for the 8-bit mux.
+ -- std_logic_vector Select signals for the N-bit mux.
+ -- tpd_d1_q VitalDelayType01 Propagation delay from input d1 to
+ -- output q for 2-bit mux.
+ -- tpd_d0_q VitalDelayType01 Propagation delay from input d0 to
+ -- output q for 2-bit mux.
+ -- tpd_data_q VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- tpd_dsel_q VitalDelayType01 Propagation delay from input dsel
+ -- to output q for 2-bit mux.
+ -- VitalDelayArrayType01 Propagation delay from input dsel
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- ResultMap VitalResultMapType The output signal strength result
+ -- map to modify default result
+ -- mapping for all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The value of the selected signal.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER functions are the sequential primitive
+ -- calls for decoder logic. The functions are provided
+ -- for N, 2, 4 and 8-bit outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The VitalDECODER returns 0 if enable is 0.
+ -- The VitalDECODER returns the result bit set to 1 if
+ -- enable is 1. All other bits of returned result are
+ -- set to 0.
+ --
+ -- The returned array is in descending order:
+ -- (n-1 downto 0).
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- Enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all output signals of the decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_logic_vector2 The output of the 2-bit decoder.
+ -- std_logic_vector4 The output of the 4-bit decoder.
+ -- std_logic_vector8 The output of the 8-bit decoder.
+ -- std_logic_vector The output of the n-bit decoder.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER procedures are the concurrent primitive
+ -- procedure calls for decoder functions. The procedures
+ -- are provided for N, 2, 4 and 8 outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The procedural form of the decoder is used for
+ -- distributed delay modeling. The delay information for
+ -- each path is passed as an argument to the procedure.
+ --
+ -- Result is set to 0 if enable is 0.
+ -- The result bit represented by data is set to 1 if
+ -- enable is 1. All other bits of result are set to 0.
+ --
+ -- The result array is in descending order: (n-1 downto 0).
+ --
+ -- For the N-bit decoder, the delay path is a vector of
+ -- delays from inputs to outputs.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data
+ -- to output q for 2-bit decoder.
+ -- VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4, 8 and n-bit
+ -- decoders.
+ -- tpd_enable_q VitalDelayType01 Propagation delay from input enable
+ -- to output q for 2, 4, 8 and n-bit
+ -- decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_logic_vector2 Output signals for 2-bit decoder.
+ -- std_logic_vector4 Output signals for 4-bit decoder.
+ -- std_logic_vector8 Output signals for 8-bit decoder.
+ -- std_logic_vector Output signals for n-bit decoder.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ -- Function Name: VitalTruthTable
+ --
+ -- Description: VitalTruthTable implements a truth table. Given
+ -- a set of inputs, a sequential search is performed
+ -- to match the input. If a match is found, the output
+ -- is set based on the contents of the CONSTANT TruthTable.
+ -- If there is no match, all X's are returned. There is
+ -- no limit to the size of the table.
+ --
+ -- There is a procedure and function for VitalTruthTable.
+ -- For each of these, a single value output (std_logic) and
+ -- a multi-value output (std_logic_vector) are provided.
+ --
+ -- The first dimension of the table is for number of
+ -- entries in the truth table and second dimension is for
+ -- the number of elements in a row. The number of inputs
+ -- in the row should be Data'LENGTH plus result'LENGTH.
+ --
+ -- Elements is a row will be interpreted as
+ -- Input(NumInputs - 1),.., Input(0),
+ -- Result(NumOutputs - 1),.., Result(0)
+ --
+ -- All inputs will be mapped to the X01 subtype
+ --
+ -- If the value of Result is not in the range 'X' to 'Z'
+ -- then an error will be reported. Also, the Result is
+ -- always given either as a 0, 1, X or Z value.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TruthTable The input constant which defines the
+ -- behavior in truth table form.
+ -- DataIn The inputs to the truth table used to
+ -- perform input match to select
+ -- output(s) to value(s) to drive.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- Result std_logic Concurrent procedure version scalar
+ -- output.
+ -- std_logic_vector Concurrent procedure version vector
+ -- output.
+ --
+ -- Returns
+ -- Result std_logic Function version scalar output.
+ -- std_logic_vector Function version vector output.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ );
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ );
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalStateTable
+ --
+ -- Description: VitalStateTable is a non-concurrent implementation of a
+ -- state machine (Moore Machine). It is used to model
+ -- sequential devices and devices with internal states.
+ --
+ -- The procedure takes the value of the state table
+ -- data set and performs a sequential search of the
+ -- CONSTANT StateTable until a match is found. Once a
+ -- match is found, the result of that match is applied
+ -- to Result. If there is no match, all X's are returned.
+ -- The resultant output becomes the input for the next
+ -- state.
+ --
+ -- The first dimension of the table is the number of
+ -- entries in the state table and second dimension is the
+ -- number of elements in a row of the table. The number of
+ -- inputs in the row should be DataIn'LENGTH. Result should
+ -- contain the current state (which will become the next
+ -- state) as well as the outputs
+ --
+ -- Elements is a row of the table will be interpreted as
+ -- Input(NumInputs-1),.., Input(0), State(NumStates-1),
+ -- ..., State(0),Output(NumOutputs-1),.., Output(0)
+ --
+ -- where State(numStates-1) DOWNTO State(0) represent the
+ -- present state and Output(NumOutputs - 1) DOWNTO
+ -- Outputs(NumOutputs - NumStates) represent the new
+ -- values of the state variables (i.e. the next state).
+ -- Also, Output(NumOutputs - NumStates - 1)
+ --
+ -- This procedure returns the next state and the new
+ -- outputs when a match is made between the present state
+ -- and present inputs and the state table. A search is
+ -- made starting at the top of the state table and
+ -- terminates with the first match. If no match is found
+ -- then the next state and new outputs are set to all 'X's.
+ --
+ -- (Asynchronous inputs (i.e. resets and clears) must be
+ -- handled by placing the corresponding entries at the top
+ -- of the table. )
+ --
+ -- All inputs will be mapped to the X01 subtype.
+ --
+ -- NOTE: Edge transitions should not be used as values
+ -- for the state variables in the present state
+ -- portion of the state table. The only valid
+ -- values that can be used for the present state
+ -- portion of the state table are:
+ -- 'X', '0', '1', 'B', '-'
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- StateTable VitalStateTableType The input constant which defines
+ -- the behavior in state table form.
+ -- DataIn std_logic_vector The current state inputs to the
+ -- state table used to perform input
+ -- matches and transition
+ -- calculations.
+ -- NumStates NATURAL Number of state variables
+ --
+ -- INOUT
+ -- Result std_logic Output signal for scalar version of
+ -- the concurrent procedure call.
+ -- std_logic_vector Output signals for vector version
+ -- of the concurrent procedure call.
+ -- PreviousDataIn std_logic_vector The previous inputs and states used
+ -- in transition calculations and to
+ -- set outputs for steady state cases.
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalResolve
+ --
+ -- Description: VitalResolve takes a vector of signals and resolves
+ -- them to a std_ulogic value. This procedure can be used
+ -- to resolve multiple drivers in a single model.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Set of input signals which drive a
+ -- common signal.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal which is the resolved
+ -- value being driven by the collection of
+ -- input signals.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ CONSTANT Data : IN std_logic_vector);
+
+END VITAL_Primitives;
diff --git a/libraries/vital95/vital_primitives_body.vhdl b/libraries/vital95/vital_primitives_body.vhdl
new file mode 100644
index 000000000..25e834189
--- /dev/null
+++ b/libraries/vital95/vital_primitives_body.vhdl
@@ -0,0 +1,5614 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 597 $
+-- :
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #204 - glitch detection prior to OutputMap
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Default values for Primitives
+ -- ------------------------------------------------------------------------
+ -- default values for delay parameters
+ CONSTANT VitalDefDelay01 : VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z;
+
+ TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME;
+
+ -- default primitive model operation parameters
+ -- Glitch detection/reporting
+ TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch);
+ CONSTANT PrimGlitchMode : VitalGlitchModeType := XOnly;
+
+ -- ------------------------------------------------------------------------
+ -- Local Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- enumeration value representing the transition or level of the signal.
+ -- See function 'GetEdge'
+ ---------------------------------------------------------------------------
+ TYPE EdgeType IS ( 'U', -- Uninitialized level
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '\', -- 1 to 0 falling edge
+ '/', -- 0 to 1 rising edge
+ 'F', -- * to 0 falling edge
+ 'R', -- * to 1 rising edge
+ 'f', -- rising to X edge
+ 'r', -- falling to X edge
+ 'x', -- Unknown edge (ie U->X)
+ 'V' -- Timing violation edge
+ );
+ TYPE EdgeArray IS ARRAY ( NATURAL RANGE <> ) OF EdgeType;
+
+ TYPE EdgeX1Table IS ARRAY ( EdgeType ) OF EdgeType;
+ TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType;
+
+ TYPE LogicToEdgeT IS ARRAY(std_ulogic, std_ulogic) OF EdgeType;
+ TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType;
+
+ TYPE GlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ CurrentValue : std_ulogic;
+ END RECORD;
+ TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF GlitchDataType;
+
+ -- Enumerated type used in selection of output path delays
+ TYPE SchedType IS
+ RECORD
+ inp0 : TIME; -- time (abs) of output change due to input change to 0
+ inp1 : TIME; -- time (abs) of output change due to input change to 1
+ InpX : TIME; -- time (abs) of output change due to input change to X
+ Glch0 : TIME; -- time (abs) of output glitch due to input change to 0
+ Glch1 : TIME; -- time (abs) of output glitch due to input change to 0
+ END RECORD;
+
+ TYPE SchedArray IS ARRAY ( NATURAL RANGE <> ) OF SchedType;
+ CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns);
+ CONSTANT DefSchedAnd : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns);
+
+ -- Constrained array declarations (common sizes used by primitives)
+ SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0);
+ SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0);
+ SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0);
+ SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0);
+
+ SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0);
+ SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0);
+ SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0);
+ SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0);
+
+ SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0);
+ SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0);
+ SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0);
+ SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0);
+
+ SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0);
+ SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0);
+ SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0);
+ SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0);
+
+ CONSTANT DefSchedArray2 : SchedArray2 :=
+ (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns));
+
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+
+ CONSTANT InitialEdge : LogicToLevelT := (
+ '1'|'H' => 'R',
+ '0'|'L' => 'F',
+ OTHERS => 'x'
+ );
+
+ CONSTANT LogicToEdge : LogicToEdgeT := ( -- previous, current
+ -- old \ new: U X 0 1 Z W L H -
+ 'U' => ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ),
+ 'X' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ '0' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ '1' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ 'Z' => ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ),
+ 'W' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ 'L' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ 'H' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ '-' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' )
+ );
+ CONSTANT LogicToLevel : LogicToLevelT := (
+ '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X'
+ );
+
+ -- -----------------------------------
+ -- 3-state logic tables
+ -- -----------------------------------
+ CONSTANT BufIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT BufIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+
+
+ TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER;
+ CONSTANT To_StateChar : To_StateCharType :=
+ ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
+ 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' );
+ TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER;
+ CONSTANT To_TruthChar : To_TruthCharType :=
+ ( 'X', '0', '1', '-', 'B', 'Z' );
+
+ TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic;
+ CONSTANT TruthTableOutMap : TruthTableOutMapType :=
+ -- 'X', '0', '1', '-', 'B', 'Z'
+ ( 'X', '0', '1', 'X', '-', 'Z' );
+
+ TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic;
+ -- does conversion to X01Z or '-' if invalid
+ CONSTANT StateTableOutMap : StateTableOutMapType :=
+ -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v'
+ -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S'
+ ( '-','-','-','-','-','-','-','-','-','-','-','-',
+ '-','-','-','-','X','0','1','X','-','Z','W');
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if a symbol IS valid for the stimulus portion of a truth table
+ CONSTANT ValidTruthTableInput : ValidTruthTableInputType :=
+ -- 'X' '0' '1' '-' 'B' 'Z'
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, FALSE );
+
+ TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if an input matches th corresponding truth table symbol
+ -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol)
+ CONSTANT TruthTableMatch : TruthTableMatchType := (
+ -- X, 0, 1, - B Z
+ ( TRUE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- X
+ ( FALSE, TRUE, FALSE, TRUE, TRUE, FALSE ), -- 0
+ ( FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) -- 1
+ );
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN;
+ CONSTANT ValidStateTableInput : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'E', 'A', 'D', '*',
+ TRUE, TRUE, TRUE, TRUE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ TRUE );
+
+ CONSTANT ValidStateTableState : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'E', 'A', 'D', '*',
+ FALSE, FALSE, FALSE, FALSE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ FALSE );
+
+ TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN;
+ -- last value, present value, table symbol
+ CONSTANT StateTableMatch : StateTableMatchType := (
+ ( -- X (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,TRUE, TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
+ TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 0 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ),
+ (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 1 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE )
+ )
+ );
+
+ TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z;
+ ----------------------------------------------------------
+ -- table name : cvt_to_x01z
+ -- parameters : std_ulogic -- some logic value
+ -- returns : UX01Z -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ ----------------------------------------------------------
+ CONSTANT cvt_to_ux01z : Logic_UX01Z_Table :=
+ ('U','X','0','1','Z','X','0','1','X' );
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MINIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return smaller of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 < in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MAXIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return larger of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 > in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ -----------------------------------------------------------------------
+ FUNCTION GlitchMinTime (
+ CONSTANT Time1, Time2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( Time1 >= NOW ) THEN
+ IF ( Time2 >= NOW ) THEN
+ RETURN Minimum ( Time1, Time2);
+ ELSE
+ RETURN Time1;
+ END IF;
+ ELSE
+ IF ( Time2 >= NOW ) THEN
+ RETURN Time2;
+ ELSE
+ RETURN 0 ns;
+ END IF;
+ END IF;
+ END;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrNegDel,
+ ErrInpSym,
+ ErrOutSym,
+ ErrStaSym,
+ ErrVctLng,
+ ErrTabWidSml,
+ ErrTabWidLrg,
+ ErrTabResSml,
+ ErrTabResLrg
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrNegDel => WARNING,
+ ErrInpSym => ERROR,
+ ErrOutSym => ERROR,
+ ErrStaSym => ERROR,
+ ErrVctLng => ERROR,
+ ErrTabWidSml => ERROR,
+ ErrTabWidLrg => WARNING,
+ ErrTabResSml => WARNING,
+ ErrTabResLrg => WARNING
+ );
+
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgInpSym : STRING :=
+ "Illegal symbol in the input portion of a Truth/State table.";
+ CONSTANT MsgOutSym : STRING :=
+ "Illegal symbol in the output portion of a Truth/State table.";
+ CONSTANT MsgStaSym : STRING :=
+ "Illegal symbol in the state portion of a State table.";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+ CONSTANT MsgTabWidSml : STRING :=
+ "Width of the Truth/State table is too small.";
+ CONSTANT MsgTabWidLrg : STRING :=
+ "Width of Truth/State table is too large. Extra elements are ignored.";
+ CONSTANT MsgTabResSml : STRING :=
+ "Result of Truth/State table has too many elements.";
+ CONSTANT MsgTabResLrg : STRING :=
+ "Result of Truth/State table has too few elements.";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN ErrInpSym => RETURN MsgInpSym;
+ WHEN ErrOutSym => RETURN MsgOutSym;
+ WHEN ErrStaSym => RETURN MsgStaSym;
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrTabWidSml => RETURN MsgTabWidSml;
+ WHEN ErrTabWidLrg => RETURN MsgTabWidLrg;
+ WHEN ErrTabResSml => RETURN MsgTabResSml;
+ WHEN ErrTabResLrg => RETURN MsgTabResLrg;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preemted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalGlitchOnEvent
+ -- :
+ -- Parameters : OutSignal ........ signal being driven
+ -- : OutSignalName..... name of the driven signal
+ -- : GlitchData........ internal data required by the procedure
+ -- : NewValue.......... new value being assigned
+ -- : NewDelay.......... Delay accompanying the assignment
+ -- : (Note: for vectors, this is an array)
+ -- : GlitchMode........ Glitch generation mode
+ -- : MessagePlusX, MessageOnly,
+ -- : XOnly, NoGlitch )
+ -- : GlitchDelay....... if <= 0 ns , then there will be no Glitch
+ -- : if > NewDelay, then there is no Glitch,
+ -- : otherwise, this is the time when a FORCED
+ -- : generation of a glitch will occur.
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataType;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN TIME := 0 ns;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ -- ------------------------------------------------------------------------
+ VARIABLE NoGlitchDet : BOOLEAN := FALSE;
+ VARIABLE OldGlitch : BOOLEAN := FALSE;
+ VARIABLE Dly : TIME := NewDelay;
+
+ BEGIN
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+
+ ELSE
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN
+ GlitchData.CurrentValue := GlitchData.SchedValue;
+ IF (GlitchDelay <= 0 ns) THEN
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ GlitchData.CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue) AND
+ (GlitchData.SchedTime = GlitchData.GlitchTime) AND
+ (GlitchDelay <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+
+ END IF;
+
+ GlitchData.SchedTime := NOW+Dly;
+ IF OldGlitch THEN
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSIF NoGlitchDet THEN
+ GlitchData.GlitchTime := NOW+Dly;
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSE -- new glitch
+ GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime,
+ NOW+GlitchDelay );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (Dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ OutSignal <= TRANSPORT NewValue AFTER Dly;
+ ELSE
+ OutSignal <= NewValue AFTER Dly;
+ END IF;
+ END IF;
+
+ GlitchData.SchedValue := NewValue;
+ END IF;
+
+ RETURN;
+ END;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataArrayType;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT NewDelay : IN VitalTimeArray;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN VitalTimeArray;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ ALIAS GlDataAlias : GlitchDataArrayType(1 TO GlitchData'LENGTH)
+ IS GlitchData;
+ ALIAS NewValAlias : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue;
+ ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH)
+ IS GlitchDelay;
+ ALIAS NewDelAlias : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay;
+
+ VARIABLE Index : INTEGER := OutSignal'LEFT;
+ VARIABLE Direction : INTEGER;
+ VARIABLE NoGlitchDet : BOOLEAN;
+ VARIABLE OldGlitch : BOOLEAN;
+ VARIABLE Dly, GlDly : TIME;
+
+ BEGIN
+ IF (OutSignal'LEFT > OutSignal'RIGHT) THEN
+ Direction := -1;
+ ELSE
+ Direction := 1;
+ END IF;
+
+ IF ( (OutSignal'LENGTH /= GlitchData'LENGTH) OR
+ (OutSignal'LENGTH /= NewValue'LENGTH) OR
+ (OutSignal'LENGTH /= NewDelay'LENGTH) OR
+ (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName );
+ RETURN;
+ END IF;
+
+ -- a call to the scalar function cannot be made since the actual
+ -- name associated with a signal parameter must be locally static
+ FOR n IN 1 TO OutSignal'LENGTH LOOP
+
+ NoGlitchDet := FALSE;
+ OldGlitch := FALSE;
+ Dly := NewDelAlias(n);
+
+ -- If nothing to schedule, just skip to next loop iteration
+ IF NewDelAlias(n) < 0 ns THEN
+ IF (NewValAlias(n) /= GlDataAlias(n).SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+ ELSE
+ -- If nothing currently scheduled (i.e. last scheduled
+ -- transaction already occurred)
+ IF GlDataAlias(n).SchedTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue;
+ IF (GlDelayAlias(n) <= 0 ns) THEN
+ -- Next iteration if no change in value
+ IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN
+ Index := Index + Direction;
+ NEXT;
+ END IF;
+ -- since last transaction already occurred there is no glitch
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlDataAlias(n).GlitchTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN
+ dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- Transaction currently scheduled
+ ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND
+ (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND
+ (GlDelayAlias(n) <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- update last scheduled transaction
+ GlDataAlias(n).SchedTime := NOW+Dly;
+
+ IF OldGlitch THEN
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSIF NoGlitchDet THEN
+ -- if no glitch then update last glitch time
+ -- and OutSignal(actual_index)
+ GlDataAlias(n).GlitchTime := NOW+Dly;
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSE -- new glitch
+ GlDataAlias(n).GlitchTime := GlitchMinTime (
+ GlDataAlias(n).GlitchTime,
+ NOW+GlDelayAlias(n) );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlDataAlias(n).GlitchTime,
+ GlDataAlias(n).SchedValue,
+ (Dly + NOW), NewValAlias(n),
+ Index, TRUE, MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ GlDly := GlDataAlias(n).GlitchTime - NOW;
+ OutSignal(Index) <= 'X' AFTER GlDly;
+ OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly;
+ ELSE
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ END IF;
+
+ END IF; -- glitch / no-glitch
+ GlDataAlias(n).SchedValue := NewValAlias(n);
+
+ END IF; -- NewDelAlias(n) < 0 ns
+ Index := Index + Direction;
+ END LOOP;
+
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : TruthOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- X01Zout - output converted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ --
+ -- DESCRIPTION : converts the output of a truth table to a valid
+ -- std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE TruthOutputX01Z (
+ CONSTANT TableOut : IN VitalTruthSymbolType;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := TruthTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut));
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : StateOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- prev_out - previous output value
+ -- X01Zout - output cojnverted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ -- DESCRIPTION : converts the output of a state table to a
+ -- valid std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateOutputX01Z (
+ CONSTANT TableOut : IN VitalStateSymbolType;
+ CONSTANT PrevOut : IN std_ulogic;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := StateTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut));
+ ELSIF (TempOut = 'W') THEN
+ TempOut := To_X01Z(PrevOut);
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME: StateMatch
+ --
+ -- PARAMETERS : symbol - symbol from state table
+ -- in2 - input from VitalStateTble procedure
+ -- to state table
+ -- in2LastValue - previous value of input
+ -- state - false if the symbol is from the input
+ -- portion of the table,
+ -- true if the symbol is from the state
+ -- portion of the table
+ -- Err - true if symbol is not a valid input symbol
+ -- ReturnValue - true if match occurred
+ --
+ -- DESCRIPTION : This procedure sets ReturnValue to true if in2 matches
+ -- symbol (from the state table). If symbol is an edge
+ -- value edge is set to true and in2 and in2LastValue are
+ -- checked against symbol. Err is set to true if symbol
+ -- is an invalid value for the input portion of the state
+ -- table.
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateMatch (
+ CONSTANT Symbol : IN VitalStateSymbolType;
+ CONSTANT in2 : IN std_ulogic;
+ CONSTANT in2LastValue : IN std_ulogic;
+ CONSTANT State : IN BOOLEAN;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+ ) IS
+ BEGIN
+ IF (State) THEN
+ IF (NOT ValidStateTableState(Symbol)) THEN
+ VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ Err := FALSE;
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ END IF;
+ ELSE
+ IF (NOT ValidStateTableInput(Symbol) ) THEN
+ VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ Err := FALSE;
+ END IF;
+ END IF;
+ END;
+
+ -- -----------------------------------------------------------------------
+ -- FUNCTION NAME: StateTableLookUp
+ --
+ -- PARAMETERS : StateTable - state table
+ -- PresentDataIn - current inputs
+ -- PreviousDataIn - previous inputs and states
+ -- NumStates - number of state variables
+ -- PresentOutputs - current state and current outputs
+ --
+ -- DESCRIPTION : This function is used to find the output of the
+ -- StateTable corresponding to a given set of inputs.
+ --
+ -- ------------------------------------------------------------------------
+ FUNCTION StateTableLookUp (
+ CONSTANT StateTable : VitalStateTableType;
+ CONSTANT PresentDataIn : std_logic_vector;
+ CONSTANT PreviousDataIn : std_logic_vector;
+ CONSTANT NumStates : NATURAL;
+ CONSTANT PresentOutputs : std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := PresentDataIn'LENGTH;
+ CONSTANT NumInputs : INTEGER := InputSize + NumStates - 1;
+ CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := StateTable'LENGTH(2);
+ CONSTANT OutSize : INTEGER := TableWidth - InputSize - NumStates;
+ VARIABLE Inputs : std_logic_vector(0 TO NumInputs);
+ VARIABLE PrevInputs : std_logic_vector(0 TO NumInputs)
+ := (OTHERS => 'X');
+ VARIABLE ReturnValue : std_logic_vector(0 TO (OutSize-1))
+ := (OTHERS => 'X');
+ VARIABLE Temp : std_ulogic;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalStateTableType(0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := StateTable;
+
+ BEGIN
+ Inputs(0 TO InputSize-1) := PresentDataIn;
+ Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1);
+ PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1);
+
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each element of the entry
+ FOR j IN 0 TO InputSize + NumStates LOOP
+
+ IF (j = InputSize + NumStates) THEN -- a match occurred
+ FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1 LOOP
+ StateOutputX01Z (
+ TableAlias(i, TableWidth - k - 1),
+ PresentOutputs(PresentOutputs'LENGTH - k - 1),
+ Temp, Err);
+ ReturnValue(OutSize - k - 1) := Temp;
+ IF (Err) THEN
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END IF;
+ END LOOP;
+ RETURN ReturnValue;
+ END IF;
+
+ StateMatch ( TableAlias(i,j),
+ Inputs(j), PrevInputs(j),
+ j >= InputSize, Err, Match);
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END;
+
+ --------------------------------------------------------------------
+ -- to_ux01z
+ -------------------------------------------------------------------
+ FUNCTION To_UX01Z ( s : std_ulogic
+ ) RETURN UX01Z IS
+ BEGIN
+ RETURN cvt_to_ux01z (s);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Function : GetEdge
+ -- Purpose : Converts transitions on a given input signal into a
+ -- enumeration value representing the transition or level
+ -- of the signal.
+ --
+ -- previous "value" current "value" := "edge"
+ -- ---------------------------------------------------------
+ -- '1' | 'H' '1' | 'H' '1' level, no edge
+ -- '0' | 'L' '1' | 'H' '/' rising edge
+ -- others '1' | 'H' 'R' rising from X
+ --
+ -- '1' | 'H' '0' | 'L' '\' falling egde
+ -- '0' | 'L' '0' | 'L' '0' level, no edge
+ -- others '0' | 'L' 'F' falling from X
+ --
+ -- 'X' | 'W' | '-' 'X' | 'W' | '-' 'X' unknown (X) level
+ -- 'Z' 'Z' 'X' unknown (X) level
+ -- 'U' 'U' 'U' 'U' level
+ --
+ -- '1' | 'H' others 'f' falling to X
+ -- '0' | 'L' others 'r' rising to X
+ -- 'X' | 'W' | '-' 'U' | 'Z' 'x' unknown (X) edge
+ -- 'Z' 'X' | 'W' | '-' | 'U' 'x' unknown (X) edge
+ -- 'U' 'X' | 'W' | '-' | 'Z' 'x' unknown (X) edge
+ --
+ ---------------------------------------------------------------------------
+ FUNCTION GetEdge (
+ SIGNAL s : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ IF (s'EVENT)
+ THEN RETURN LogicToEdge ( s'LAST_VALUE, s );
+ ELSE RETURN LogicToLevel ( s );
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE GetEdge (
+ SIGNAL s : IN std_logic_vector;
+ VARIABLE LastS : INOUT std_logic_vector;
+ VARIABLE Edge : OUT EdgeArray ) IS
+
+ ALIAS sAlias : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS;
+ ALIAS EdgeAlias : EdgeArray ( 1 TO Edge'LENGTH ) IS Edge;
+ BEGIN
+ IF s'LENGTH /= LastS'LENGTH OR
+ s'LENGTH /= Edge'LENGTH THEN
+ VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" );
+ END IF;
+
+ FOR n IN 1 TO s'LENGTH LOOP
+ EdgeAlias(n) := LogicToEdge( LastSAlias(n), sAlias(n) );
+ LastSAlias(n) := sAlias(n);
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ FUNCTION ToEdge ( Value : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ RETURN LogicToLevel( Value );
+ END;
+
+ -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92
+ ----------------------------------------------------------------------------
+ FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataType
+ ) RETURN std_logic IS
+ BEGIN
+ IF NOW >= GlitchData.SchedTime THEN
+ RETURN GlitchData.SchedValue;
+ ELSIF NOW >= GlitchData.GlitchTime THEN
+ RETURN 'X';
+ ELSE
+ RETURN GlitchData.CurrentValue;
+ END IF;
+ END;
+ ---------------------------------------------------------------------------
+ FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataArrayType
+ ) RETURN std_logic_vector IS
+ VARIABLE Result : std_logic_vector(GlitchData'RANGE);
+ BEGIN
+ FOR n IN GlitchData'RANGE LOOP
+ IF NOW >= GlitchData(n).SchedTime THEN
+ Result(n) := GlitchData(n).SchedValue;
+ ELSIF NOW >= GlitchData(n).GlitchTime THEN
+ Result(n) := 'X';
+ ELSE
+ Result(n) := GlitchData(n).CurrentValue;
+ END IF;
+ END LOOP;
+ RETURN Result;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- function calculation utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalSame
+ -- Returns : VitalSame compares the state (UX01) of two logic value. A
+ -- value of 'X' is returned if the values are different. The
+ -- common value is returned if the values are equal.
+ -- Purpose : When the result of a logic model may be either of two
+ -- separate input values (eg. when the select on a MUX is 'X'),
+ -- VitalSame may be used to determine if the result needs to
+ -- be 'X'.
+ -- Arguments : See the declarations below...
+ ---------------------------------------------------------------------------
+ FUNCTION VitalSame (
+ CONSTANT a, b : IN std_ulogic
+ ) RETURN std_ulogic IS
+ BEGIN
+ IF To_UX01(a) = To_UX01(b)
+ THEN RETURN To_UX01(a);
+ ELSE RETURN 'X';
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- delay selection utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufPath, InvPath
+ --
+ -- Purpose : BufPath and InvPath compute output change times, based on
+ -- a change on an input port. The computed output change times
+ -- returned in the composite parameter 'schd'.
+ --
+ -- BufPath and InpPath are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the input ports of a model are
+ -- combined by the delay selection functions (VitalAND,
+ -- VitalOR, ...). The GetSchedDelay procedure converts the
+ -- combined output changes times to the single delay (delta
+ -- time) value for scheduling the output change (passed to
+ -- VitalGlitchOnEvent).
+ --
+ -- The values in 'schd' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- The output times are computed from the model INPUT value
+ -- and not the final value. For this reason, 'BufPath' should
+ -- be used to compute the output times for a non-inverting
+ -- delay paths and 'InvPath' should be used to compute the
+ -- ouput times for inverting delay paths. Delay paths which
+ -- include both non-inverting and paths require usage of both
+ -- 'BufPath' and 'InvPath'. (IE this is needed for the
+ -- select->output path of a MUX -- See the VitalMUX model).
+ --
+ --
+ -- Parameters : schd....... Computed output result times. (INOUT parameter
+ -- modified only on input edges)
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays from this input
+ --
+ ---------------------------------------------------------------------------
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr01); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr10); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr01);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr10);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr10); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr01); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr10);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr01);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufEnab, InvEnab
+ --
+ -- Purpose : BufEnab and InvEnab compute output change times, from a
+ -- change on an input enable port for a 3-state driver. The
+ -- computed output change times are returned in the composite
+ -- parameters 'schd1', 'schd0'.
+ --
+ -- BufEnab and InpEnab are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the non-enable input ports of
+ -- a model (See BufPath, InvPath) are combined using the delay
+ -- selection functions (VitalAND, VitalOR, ...). The
+ -- GetSchedDelay procedure combines the output times on the
+ -- enable path with the output times from the data path(s) and
+ -- computes the single delay (delta time) value for scheduling
+ -- the output change (passed to VitalGlitchOnEvent)
+ --
+ -- The values in 'schd*' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- 'schd1' contains output times for 1->Z, Z->1 transitions.
+ -- 'schd0' contains output times for 0->Z, Z->0 transitions.
+ --
+ -- 'BufEnab' is used for computing the output times for an
+ -- high asserted enable (output 'Z' for enable='0').
+ -- 'InvEnab' is used for computing the output times for an
+ -- low asserted enable (output 'Z' for enable='1').
+ --
+ -- Note: separate 'schd1', 'schd0' parameters are generated
+ -- so that the combination of the delay paths from
+ -- multiple enable signals may be combined using the
+ -- same functions/operators used in combining separate
+ -- data paths. (See exampe 2 below)
+ --
+ --
+ -- Parameters : schd1...... Computed output result times for 1->Z, Z->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- schd0...... Computed output result times for 0->Z, 0->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays for the enable -> output path.
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE BufEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(trz1);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(trz0);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(tr1z);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(tr0z);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(tr1z);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(tr0z);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(trz1);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(trz0);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : GetSchedDelay
+ --
+ -- Purpose : GetSchedDelay computes the final delay (incremental) for
+ -- for scheduling an output signal. The delay is computed
+ -- from the absolute output times in the 'NewSched' parameter.
+ -- (See BufPath, InvPath).
+ --
+ -- Computation of the output delay for non-3_state outputs
+ -- consists of selection the appropriate output time based
+ -- on the new output value 'NewValue' and subtracting 'NOW'
+ -- to convert to an incremental delay value.
+ --
+ -- The Computation of the output delay for 3_state output
+ -- also includes combination of the enable path delay with
+ -- the date path delay.
+ --
+ -- Parameters : NewDelay... Returned output delay value.
+ -- GlchDelay.. Returned output delay for the start of a glitch.
+ -- NewValue... New output value.
+ -- CurValue... Current value of the output.
+ -- NewSched... Composite containing the combined absolute
+ -- output times from the data inputs.
+ -- EnSched1... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 1->Z, Z->1)
+ -- EnSched0... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 0->Z, Z->0)
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE To_UX01(NewValue) IS
+ WHEN '0' => Tim := NewSched.inp0;
+ Glch := NewSched.Glch1;
+ WHEN '1' => Tim := NewSched.inp1;
+ Glch := NewSched.Glch0;
+ WHEN OTHERS => Tim := NewSched.InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValue /= NewValue)
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT VitalTimeArray;
+ VARIABLE GlchDelay : OUT VitalTimeArray;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT CurValue : IN std_logic_vector;
+ CONSTANT NewSched : IN SchedArray
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ ALIAS NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1)
+ IS NewDelay;
+ ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1)
+ IS GlchDelay;
+ ALIAS NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1)
+ IS NewSched;
+ ALIAS NewValueAlias : std_logic_vector ( NewValue'LENGTH DOWNTO 1 )
+ IS NewValue;
+ ALIAS CurValueAlias : std_logic_vector ( CurValue'LENGTH DOWNTO 1 )
+ IS CurValue;
+ BEGIN
+ FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP
+ CASE To_UX01(NewValueAlias(n)) IS
+ WHEN '0' => Tim := NewSchedAlias(n).inp0;
+ Glch := NewSchedAlias(n).Glch1;
+ WHEN '1' => Tim := NewSchedAlias(n).inp1;
+ Glch := NewSchedAlias(n).Glch0;
+ WHEN OTHERS => Tim := NewSchedAlias(n).InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValueAlias(n) /= NewValueAlias(n))
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelayAlias(n) := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelayAlias(n) := Glch;
+ ELSE GlchDelayAlias(n) := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END LOOP;
+ RETURN;
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType;
+ CONSTANT EnSched1 : IN SchedType;
+ CONSTANT EnSched0 : IN SchedType
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS
+ WHEN "00" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0);
+ WHEN "01" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := EnSched1.Glch0;
+ WHEN "0Z" => Tim := EnSched0.inp0;
+ Glch := NewSched.Glch1;
+ WHEN "0X" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "10" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := EnSched0.Glch0;
+ WHEN "11" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0);
+ WHEN "1Z" => Tim := EnSched1.inp0;
+ Glch := NewSched.Glch0;
+ WHEN "1X" => Tim := Maximum (NewSched.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "Z0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ IF NewSched.Glch0 > NOW
+ THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "Z1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ IF NewSched.Glch1 > NOW
+ THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "ZX" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "ZZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "X0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := 0 ns;
+ WHEN "X1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := 0 ns;
+ WHEN "XZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN OTHERS => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+
+ END CASE;
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Operators and Functions for combination (selection) of path delays
+ -- > These functions support selection of the "appripriate" path delay
+ -- dependent on the logic function.
+ -- > These functions only "select" from the possable output times. No
+ -- calculation (addition) of delays is performed.
+ -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay'
+ -- > See primitive PROCEDURE models for examples.
+ ---------------------------------------------------------------------------
+
+ FUNCTION "not" (
+ CONSTANT a : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := a.inp0 ;
+ z.inp0 := a.inp1 ;
+ z.InpX := a.InpX ;
+ z.Glch1 := a.Glch0;
+ z.Glch0 := a.Glch1;
+ RETURN (z);
+ END;
+
+ FUNCTION "and" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp1 , b.inp1 );
+ z.inp0 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ FUNCTION "or" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp0 , b.inp0 );
+ z.inp1 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ FUNCTION "nand" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp1 , b.inp1 );
+ z.inp1 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ FUNCTION "nor" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp0 , b.inp0 );
+ z.inp0 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalXOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) NOR (a NOR b)
+ z.inp1 := Maximum ( Minimum (ai.inp0 , bi.inp0 ),
+ Minimum (ab.inp1 , bb.inp1 ) );
+ z.inp0 := Minimum ( Maximum (ai.inp1 , bi.inp1 ),
+ Maximum (ab.inp0 , bb.inp0 ) );
+ z.InpX := Maximum ( Maximum (ai.InpX , bi.InpX ),
+ Maximum (ab.InpX , bb.InpX ) );
+ z.Glch1 := Maximum (GlitchMinTime (ai.Glch0, bi.Glch0),
+ GlitchMinTime (ab.Glch1, bb.Glch1) );
+ z.Glch0 := GlitchMinTime ( Maximum (ai.Glch1, bi.Glch1),
+ Maximum (ab.Glch0, bb.Glch0) );
+ RETURN (z);
+ END;
+
+ FUNCTION VitalXNOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) OR (a NOR b)
+ z.inp0 := Maximum ( Minimum (ab.inp0 , bb.inp0 ),
+ Minimum (ai.inp1 , bi.inp1 ) );
+ z.inp1 := Minimum ( Maximum (ab.inp1 , bb.inp1 ),
+ Maximum (ai.inp0 , bi.inp0 ) );
+ z.InpX := Maximum ( Maximum (ab.InpX , bb.InpX ),
+ Maximum (ai.InpX , bi.InpX ) );
+ z.Glch0 := Maximum (GlitchMinTime (ab.Glch0, bb.Glch0),
+ GlitchMinTime (ai.Glch1, bi.Glch1) );
+ z.Glch1 := GlitchMinTime ( Maximum (ab.Glch1, bb.Glch1),
+ Maximum (ai.Glch0, bi.Glch0) );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalXOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi),
+ VitalXOR2 (ai,ab, bi,bb),
+ cb, ci );
+ END;
+
+ FUNCTION VitalXNOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ cb, ci );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalXOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ FUNCTION VitalXNOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for N-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ FUNCTION VitalXOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ FUNCTION VitalXNOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT d1, d0 : IN SchedType;
+ CONSTANT sb, SI : IN SchedType
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN (d1 AND sb) OR (d0 AND (NOT SI) );
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN SchedArray4;
+ CONSTANT sb : IN SchedArray2;
+ CONSTANT SI : IN SchedArray2
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( sb(1) AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) )
+ OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) );
+ END;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN SchedArray8;
+ CONSTANT sb : IN SchedArray3;
+ CONSTANT SI : IN SchedArray3
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( ( sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) )
+ OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) );
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT sMsb : INTEGER := sb'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ BEGIN
+ IF sb'LENGTH = 1 THEN
+ RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) );
+ ELSIF sb'LENGTH = 2 THEN
+ RETURN VitalMUX4( Data, sb, SI );
+ ELSIF sb'LENGTH = 3 THEN
+ RETURN VitalMUX8( Data, sb, SI );
+ ELSIF sb'LENGTH > 3 THEN
+ RETURN (( sb(sMsb)) AND VInterMux( Data(dMsbLow DOWNTO 1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ))
+ OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ));
+ ELSE
+ RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1
+ END IF;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT msb : INTEGER := 2**sb'LENGTH;
+ VARIABLE lDat : SchedArray(msb DOWNTO 1);
+ ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data;
+ ALIAS sbAlias : SchedArray ( sb'LENGTH DOWNTO 1 ) IS sb;
+ ALIAS siAlias : SchedArray ( SI'LENGTH DOWNTO 1 ) IS SI;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ FOR i IN msb DOWNTO Data'LENGTH+1 LOOP
+ lDat(i) := DefSchedAnd;
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ RETURN VInterMux( lDat, sbAlias, siAlias );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT DataB : IN SchedType;
+ CONSTANT DataI : IN SchedType;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray2;
+ BEGIN
+ Result(1) := Enable AND ( DataB);
+ Result(0) := Enable AND (NOT DataI);
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT DataB : IN SchedArray2;
+ CONSTANT DataI : IN SchedArray2;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray4;
+ BEGIN
+ Result(3) := Enable AND ( DataB(1)) AND ( DataB(0));
+ Result(2) := Enable AND ( DataB(1)) AND (NOT DataI(0));
+ Result(1) := Enable AND (NOT DataI(1)) AND ( DataB(0));
+ Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0));
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT DataB : IN SchedArray3;
+ CONSTANT DataI : IN SchedArray3;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray8;
+ BEGIN
+ Result(7):= Enable AND ( DataB(2))AND( DataB(1))AND( DataB(0));
+ Result(6):= Enable AND ( DataB(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(5):= Enable AND ( DataB(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(4):= Enable AND ( DataB(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ Result(3):= Enable AND (NOT DataI(2))AND( DataB(1))AND( DataB(0));
+ Result(2):= Enable AND (NOT DataI(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ RETURN Result;
+ END;
+
+
+ FUNCTION VitalDECODER (
+ CONSTANT DataB : IN SchedArray;
+ CONSTANT DataI : IN SchedArray;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ CONSTANT DMsb : INTEGER := DataB'LENGTH - 1;
+ ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB;
+ ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI;
+ BEGIN
+ IF DataB'LENGTH = 1 THEN
+ RETURN VitalDECODER2 ( DataBAlias( 0 ),
+ DataIAlias( 0 ), Enable );
+ ELSIF DataB'LENGTH = 2 THEN
+ RETURN VitalDECODER4 ( DataBAlias(1 DOWNTO 0),
+ DataIAlias(1 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH = 3 THEN
+ RETURN VitalDECODER8 ( DataBAlias(2 DOWNTO 0),
+ DataIAlias(2 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH > 3 THEN
+ RETURN VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataBAlias(DMsb)) )
+ & VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataIAlias(DMsb)) );
+ ELSE
+ RETURN DefSchedArray2;
+ END IF;
+ END;
+
+
+-------------------------------------------------------------------------------
+-- PRIMITIVES
+-------------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b);
+ END;
+--
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b);
+ END;
+--
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b);
+ END;
+--
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NAND b);
+ END;
+--
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NOR b);
+ END;
+--
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b));
+ END;
+--
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c);
+ END;
+--
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c);
+ END;
+--
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c);
+ END;
+--
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c));
+ END;
+--
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c));
+ END;
+--
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c));
+ END;
+
+ -- ---------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ---------------------------------------------------------------------------
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c AND d);
+ END;
+--
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c OR d);
+ END;
+--
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c XOR d);
+ END;
+--
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c AND d));
+ END;
+--
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c OR d));
+ END;
+--
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c XOR d));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01(Data));
+ END;
+--
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf1_Table(Enable,Data));
+ END;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01Z(Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT Data);
+ END;
+--
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf1_Table(Enable,Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect) IS
+ WHEN '0' => Result := To_UX01(Data0);
+ WHEN '1' => Result := To_UX01(Data1);
+ WHEN OTHERS => Result := VitalSame( Data1, Data0 );
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Slct : std_logic_vector2;
+ VARIABLE Result : UX01;
+ BEGIN
+ Slct := To_X01(dSelect);
+ CASE Slct IS
+ WHEN "00" => Result := To_UX01(Data(0));
+ WHEN "01" => Result := To_UX01(Data(1));
+ WHEN "10" => Result := To_UX01(Data(2));
+ WHEN "11" => Result := To_UX01(Data(3));
+ WHEN "0X" => Result := VitalSame( Data(1), Data(0) );
+ WHEN "1X" => Result := VitalSame( Data(2), Data(3) );
+ WHEN "X0" => Result := VitalSame( Data(2), Data(0) );
+ WHEN "X1" => Result := VitalSame( Data(3), Data(1) );
+ WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)),
+ VitalSame(Data(1),Data(0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect(2)) IS
+ WHEN '0' => Result := VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0));
+ WHEN '1' => Result := VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0));
+ WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0)),
+ VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector
+ ) RETURN std_ulogic IS
+
+ CONSTANT sMsb : INTEGER := dSelect'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+
+ VARIABLE Result : UX01;
+ BEGIN
+ IF dSelect'LENGTH = 1 THEN
+ Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) );
+ ELSIF dSelect'LENGTH = 2 THEN
+ Result := VitalMUX4( DataAlias, dSelAlias );
+ ELSIF dSelect'LENGTH > 2 THEN
+ CASE To_X01(dSelect(sMsb)) IS
+ WHEN '0' =>
+ Result := VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN '1' =>
+ Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN OTHERS =>
+ Result := VitalSame(
+ VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) ),
+ VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) )
+ );
+ END CASE;
+ ELSE
+ Result := 'X'; -- dselect'LENGTH < 1
+ END IF;
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ CONSTANT msb : INTEGER := 2**dSelect'LENGTH;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+ VARIABLE lDat : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X');
+ VARIABLE Result : UX01;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ Result := VInterMux( lDat, dSelAlias );
+ RETURN ResultMap(Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2 IS
+ VARIABLE Result : std_logic_vector2;
+ BEGIN
+ Result(1) := ResultMap(Enable AND ( Data));
+ Result(0) := ResultMap(Enable AND (NOT Data));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4 IS
+ VARIABLE Result : std_logic_vector4;
+ BEGIN
+ Result(3) := ResultMap(Enable AND ( Data(1)) AND ( Data(0)));
+ Result(2) := ResultMap(Enable AND ( Data(1)) AND (NOT Data(0)));
+ Result(1) := ResultMap(Enable AND (NOT Data(1)) AND ( Data(0)));
+ Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0)));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8 IS
+ VARIABLE Result : std_logic_vector8;
+ BEGIN
+ Result(7) := ( Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(6) := ( Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(5) := ( Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(4) := ( Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+ Result(3) := (NOT Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(2) := (NOT Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+
+ Result(0) := ResultMap ( Enable AND Result(0) );
+ Result(1) := ResultMap ( Enable AND Result(1) );
+ Result(2) := ResultMap ( Enable AND Result(2) );
+ Result(3) := ResultMap ( Enable AND Result(3) );
+ Result(4) := ResultMap ( Enable AND Result(4) );
+ Result(5) := ResultMap ( Enable AND Result(5) );
+ Result(6) := ResultMap ( Enable AND Result(6) );
+ Result(7) := ResultMap ( Enable AND Result(7) );
+
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector IS
+
+ CONSTANT DMsb : INTEGER := Data'LENGTH - 1;
+ ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data;
+ BEGIN
+ IF Data'LENGTH = 1 THEN
+ RETURN VitalDECODER2 (DataAlias( 0 ), Enable, ResultMap );
+ ELSIF Data'LENGTH = 2 THEN
+ RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH = 3 THEN
+ RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH > 3 THEN
+ RETURN VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataAlias(DMsb)), ResultMap )
+ & VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataAlias(DMsb)), ResultMap );
+ ELSE RETURN "X";
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( DataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( DataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXOR ( Data );
+ new_schd := VitalXOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( DataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( DataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXNOR ( Data );
+ new_schd := VitalXNOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b;
+ new_schd := a_schd AND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b;
+ new_schd := a_schd OR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NAND b;
+ new_schd := a_schd NAND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NOR b;
+ new_schd := a_schd NOR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b;
+ new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b);
+ new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+--
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c;
+ new_schd := a_schd AND b_schd AND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c;
+ new_schd := a_schd OR b_schd OR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND c;
+ new_schd := (a_schd AND b_schd) NAND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR c;
+ new_schd := (a_schd OR b_schd) NOR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c;
+ new_schd := VitalXOR3 ( ab_schd,ai_schd,
+ bb_schd,bi_schd,
+ cb_schd,ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c);
+ new_schd := VitalXNOR3 ( ab_schd, ai_schd,
+ bb_schd, bi_schd,
+ cb_schd, ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c AND d;
+ new_schd := a_schd AND b_schd AND c_schd AND d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c OR d;
+ new_schd := a_schd OR b_schd OR c_schd OR d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND (c AND d);
+ new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR (c OR d);
+ new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c XOR d;
+ new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c XOR d);
+ new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(To_UX01(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := To_UX01(a); -- convert to forcing strengths
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF1( Data, Enable );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01Z) THEN
+ LOOP
+ q <= ResultMap(To_UX01Z(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS
+ WHEN "00" => Dly := tpd_a_q(tr10);
+ WHEN "01" => Dly := tpd_a_q(tr01);
+ WHEN "0Z" => Dly := tpd_a_q(tr0z);
+ WHEN "0X" => Dly := tpd_a_q(tr01);
+ WHEN "10" => Dly := tpd_a_q(tr10);
+ WHEN "11" => Dly := tpd_a_q(tr01);
+ WHEN "1Z" => Dly := tpd_a_q(tr1z);
+ WHEN "1X" => Dly := tpd_a_q(tr10);
+ WHEN "Z0" => Dly := tpd_a_q(trz0);
+ WHEN "Z1" => Dly := tpd_a_q(trz1);
+ WHEN "ZZ" => Dly := 0 ns;
+ WHEN "ZX" => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0));
+ WHEN "X0" => Dly := tpd_a_q(tr10);
+ WHEN "X1" => Dly := tpd_a_q(tr01);
+ WHEN "XZ" => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z));
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+ NewValue := To_UX01Z(a);
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(NOT a);
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT a;
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF1( Data, Enable );
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE d1_Schd, d0_Schd : SchedType;
+ VARIABLE dSel_bSchd, dSel_iSchd : SchedType;
+ VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_d1_q = VitalZeroDelay01)
+ AND (tpd_d0_q = VitalZeroDelay01)
+ AND (tpd_dsel_q = VitalZeroDelay01) ) THEN
+ LOOP
+ q <= VitalMUX2 ( d1, d0, dSel, ResultMap );
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX2 ( d1, d0, dSel );
+ new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray4;
+ VARIABLE Data_Edge : EdgeArray4;
+ VARIABLE dSel_Edge : EdgeArray2;
+ VARIABLE dSel_bSchd : SchedArray2;
+ VARIABLE dSel_iSchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX4 ( Data, dSel );
+ new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray8;
+ VARIABLE Data_Edge : EdgeArray8;
+ VARIABLE dSel_Edge : EdgeArray3;
+ VARIABLE dSel_bSchd : SchedArray3;
+ VARIABLE dSel_iSchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX8 ( Data, dSel );
+ new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE dSel_Edge : EdgeArray(dSel'RANGE);
+ VARIABLE dSel_bSchd : SchedArray(dSel'RANGE);
+ VARIABLE dSel_iSchd : SchedArray(dSel'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX ( Data, dSel );
+ new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- Caution: If 'ResultMap' defines other than strength mapping, the
+ -- delay selection is not defined.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : std_logic_vector2;
+ VARIABLE Glitch_Data : GlitchArray2;
+ VARIABLE new_schd : SchedArray2;
+ VARIABLE Dly, Glch : TimeArray2;
+ VARIABLE Enable_Schd : SchedType := DefSchedType;
+ VARIABLE Data_BSchd, Data_ISchd : SchedType;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= VitalDECODER2(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q );
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER2 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; -- SN
+ END;
+--
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector4;
+ VARIABLE Glitch_Data : GlitchArray4;
+ VARIABLE new_schd : SchedArray4;
+ VARIABLE Dly, Glch : TimeArray4;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray2;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER4(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER4 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector8;
+ VARIABLE Glitch_Data : GlitchArray8;
+ VARIABLE new_schd : SchedArray8;
+ VARIABLE Dly, Glch : TimeArray8;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray3;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER8 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector(q'RANGE);
+ VARIABLE Glitch_Data : GlitchDataArrayType(q'RANGE);
+ VARIABLE new_schd : SchedArray(q'RANGE);
+ VARIABLE Dly, Glch : VitalTimeArray(q'RANGE);
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1)
+ := To_X01(DataIn);
+ VARIABLE Index : INTEGER;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1),
+ 0 TO (TruthTable'LENGTH(2)-1))
+ := TruthTable;
+
+ BEGIN
+ -- search through each row of the truth table
+ IF OutSize > 0 THEN
+ ColLoop:
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each input element of the entry
+ FOR j IN 0 TO InputSize LOOP
+
+ IF (j = InputSize) THEN -- This entry matches
+ -- Return the Result
+ Index := 0;
+ FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP
+ TruthOutputX01Z ( TableAlias(i,k),
+ ReturnValue(Index), Err);
+ EXIT WHEN Err;
+ Index := Index + 1;
+ END LOOP;
+
+ IF Err THEN
+ ReturnValue := (OTHERS => 'X');
+ END IF;
+ RETURN ReturnValue;
+ END IF;
+ IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN
+ VitalError ( "VitalTruthTable", ErrInpSym,
+ To_TruthChar(TableAlias(i,j)) );
+ EXIT ColLoop;
+ END IF;
+ EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j),
+ TableAlias(i, j)));
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ END IF;
+ RETURN ReturnValue;
+ END VitalTruthTable;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ BEGIN
+ IF (OutSize > 0) THEN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ RETURN (TempResult(0));
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ RETURN 'X';
+ END IF;
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) IS
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng);
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF (ResLeng > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF (ResLeng < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0);
+ Result <= TempResult;
+
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) IS
+
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF ( 1 > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ IF (ActResLen > 0) THEN
+ Result <= TempResult(0);
+ END IF;
+
+ END VitalTruthTable;
+
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := To_X01(DataIn);
+ VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1)
+ := To_X01(PreviousDataIn);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1)
+ := To_X01(Result);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN
+ VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn<DataIn");
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSIF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevDataAlias, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result := ResultAlias;
+ PrevDataAlias(0 TO InputSize - 1) := DataInAlias;
+ PreviousDataIn := PrevDataAlias;
+
+ END IF;
+ END VitalStateTable;
+
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic; -- states
+ VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states
+ CONSTANT StateTable : IN VitalStateTableType; -- User's StateTable data
+ CONSTANT DataIn : IN std_logic_vector -- Inputs
+ ) IS
+
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ BEGIN
+ ResultAlias(0) := Result;
+ VitalStateTable ( StateTable => StateTable,
+ DataIn => DataIn,
+ NumStates => 1,
+ Result => ResultAlias,
+ PreviousDataIn => PreviousDataIn
+ );
+ Result := ResultAlias(0);
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result <= ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ DataInAlias := To_X01(DataIn);
+ ResultAlias := To_X01(Result);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result <= ResultAlias;
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+
+ END IF;
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize-1;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ Result <= 'X';
+
+ ELSE
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ ResultAlias(0) := To_X01(Result);
+ DataInAlias := To_X01(DataIn);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, 1, ResultAlias);
+
+ Result <= ExpResult(OutSize-1);
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+ END IF;
+
+ END VitalStateTable;
+
+ -- ------------------------------------------------------------------------
+ -- std_logic resolution primitive
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ CONSTANT Data : IN std_logic_vector
+ ) IS
+ VARIABLE uData : std_ulogic_vector(Data'RANGE);
+ BEGIN
+ FOR i IN Data'RANGE LOOP
+ uData(i) := Data(i);
+ END LOOP;
+ q <= resolved(uData);
+ END;
+
+END VITAL_Primitives;
diff --git a/libraries/vital95/vital_timing.vhdl b/libraries/vital95/vital_timing.vhdl
new file mode 100644
index 000000000..1fe5a9e24
--- /dev/null
+++ b/libraries/vital95/vital_timing.vhdl
@@ -0,0 +1,880 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 597 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #203 - Timing violations at time 0
+-- #204 - Output mapping prior to glitch detection
+-- ----------------------------------------------------------------------------
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+
+PACKAGE VITAL_Timing IS
+ TYPE VitalTransitionType IS ( tr01, tr10, tr0z, trz1, tr1z, trz0,
+ tr0X, trx1, tr1x, trx0, trxz, trzx);
+
+ SUBTYPE VitalDelayType IS TIME;
+ TYPE VitalDelayType01 IS ARRAY (VitalTransitionType RANGE tr01 to tr10)
+ OF TIME;
+ TYPE VitalDelayType01Z IS ARRAY (VitalTransitionType RANGE tr01 to trz0)
+ OF TIME;
+ TYPE VitalDelayType01ZX IS ARRAY (VitalTransitionType RANGE tr01 to trzx)
+ OF TIME;
+
+ TYPE VitalDelayArrayType IS ARRAY (NATURAL RANGE <>) OF VitalDelayType;
+ TYPE VitalDelayArrayType01 IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01;
+ TYPE VitalDelayArrayType01Z IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01Z;
+ TYPE VitalDelayArrayType01ZX IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01ZX;
+ -- ----------------------------------------------------------------------
+ -- **********************************************************************
+ -- ----------------------------------------------------------------------
+
+ CONSTANT VitalZeroDelay : VitalDelayType := 0 ns;
+ CONSTANT VitalZeroDelay01 : VitalDelayType01 := ( 0 ns, 0 ns );
+ CONSTANT VitalZeroDelay01Z : VitalDelayType01Z := ( OTHERS => 0 ns );
+ CONSTANT VitalZeroDelay01ZX : VitalDelayType01ZX := ( OTHERS => 0 ns );
+
+ ---------------------------------------------------------------------------
+ -- examples of usage:
+ ---------------------------------------------------------------------------
+ -- tpd_CLK_Q : VitalDelayType := 5 ns;
+ -- tpd_CLK_Q : VitalDelayType01 := (tr01 => 2 ns, tr10 => 3 ns);
+ -- tpd_CLK_Q : VitalDelayType01Z := ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns );
+ -- tpd_CLK_Q : VitalDelayArrayType(0 to 1)
+ -- := (0 => 5 ns, 1 => 6 ns);
+ -- tpd_CLK_Q : VitalDelayArrayType01(0 to 1)
+ -- := (0 => (tr01 => 2 ns, tr10 => 3 ns),
+ -- 1 => (tr01 => 2 ns, tr10 => 3 ns));
+ -- tpd_CLK_Q : VitalDelayArrayType01Z(0 to 1)
+ -- := (0 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ),
+ -- 1 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ));
+ ---------------------------------------------------------------------------
+
+ -- TRUE if the model is LEVEL0 | LEVEL1 compliant
+ ATTRIBUTE VITAL_Level0 : BOOLEAN;
+ ATTRIBUTE VITAL_Level1 : BOOLEAN;
+
+ SUBTYPE std_logic_vector2 IS std_logic_vector(1 DOWNTO 0);
+ SUBTYPE std_logic_vector3 IS std_logic_vector(2 DOWNTO 0);
+ SUBTYPE std_logic_vector4 IS std_logic_vector(3 DOWNTO 0);
+ SUBTYPE std_logic_vector8 IS std_logic_vector(7 DOWNTO 0);
+
+ -- Types for strength mapping of outputs
+ TYPE VitalOutputMapType IS ARRAY ( std_ulogic ) OF std_ulogic;
+ TYPE VitalResultMapType IS ARRAY ( UX01 ) OF std_ulogic;
+ TYPE VitalResultZMapType IS ARRAY ( UX01Z ) OF std_ulogic;
+ CONSTANT VitalDefaultOutputMap : VitalOutputMapType
+ := "UX01ZWLH-";
+ CONSTANT VitalDefaultResultMap : VitalResultMapType
+ := ( 'U', 'X', '0', '1' );
+ CONSTANT VitalDefaultResultZMap : VitalResultZMapType
+ := ( 'U', 'X', '0', '1', 'Z' );
+
+ -- Types for fields of VitalTimingDataType
+ TYPE VitalTimeArrayT IS ARRAY (INTEGER RANGE <>) OF TIME;
+ TYPE VitalTimeArrayPT IS ACCESS VitalTimeArrayT;
+ TYPE VitalBoolArrayT IS ARRAY (INTEGER RANGE <>) OF BOOLEAN;
+ TYPE VitalBoolArrayPT IS ACCESS VitalBoolArrayT;
+ TYPE VitalLogicArrayPT IS ACCESS std_logic_vector;
+
+ TYPE VitalTimingDataType IS RECORD
+ NotFirstFlag : BOOLEAN;
+ RefLast : X01;
+ RefTime : TIME;
+ HoldEn : BOOLEAN;
+ TestLast : std_ulogic;
+ TestTime : TIME;
+ SetupEn : BOOLEAN;
+ TestLastA : VitalLogicArrayPT;
+ TestTimeA : VitalTimeArrayPT;
+ HoldEnA : VitalBoolArrayPT;
+ SetupEnA : VitalBoolArrayPT;
+ END RECORD;
+
+ FUNCTION VitalTimingDataInit RETURN VitalTimingDataType;
+
+ -- type for internal data of VitalPeriodPulseCheck
+ TYPE VitalPeriodDataType IS RECORD
+ Last : X01;
+ Rise : TIME;
+ Fall : TIME;
+ NotFirstFlag : BOOLEAN;
+ END RECORD;
+ CONSTANT VitalPeriodDataInit : VitalPeriodDataType
+ := ('X', 0 ns, 0 ns, FALSE );
+
+ -- Type for specifying the kind of Glitch handling to use
+ TYPE VitalGlitchKindType IS (OnEvent,
+ OnDetect,
+ VitalInertial,
+ VitalTransport);
+
+ TYPE VitalGlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ LastValue : std_ulogic;
+ END RECORD;
+ TYPE VitalGlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF VitalGlitchDataType;
+
+ -- PathTypes: for handling simple PathDelay info
+ TYPE VitalPathType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01Type IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01ZType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01Z;-- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+
+ -- For representing multiple paths to an output
+ TYPE VitalPathArrayType IS ARRAY (NATURAL RANGE <> ) OF VitalPathType;
+ TYPE VitalPathArray01Type IS ARRAY (NATURAL RANGE <> ) OF VitalPath01Type;
+ TYPE VitalPathArray01ZType IS ARRAY (NATURAL RANGE <> ) OF VitalPath01ZType;
+
+ TYPE VitalTableSymbolType IS (
+ '/', -- 0 -> 1
+ '\', -- 1 -> 0
+ 'P', -- Union of '/' and '^' (any edge to 1)
+ 'N', -- Union of '\' and 'v' (any edge to 0)
+ 'r', -- 0 -> X
+ 'f', -- 1 -> X
+ 'p', -- Union of '/' and 'r' (any edge from 0)
+ 'n', -- Union of '\' and 'f' (any edge from 1)
+ 'R', -- Union of '^' and 'p' (any possible rising edge)
+ 'F', -- Union of 'v' and 'n' (any possible falling edge)
+ '^', -- X -> 1
+ 'v', -- X -> 0
+ 'E', -- Union of 'v' and '^' (any edge from X)
+ 'A', -- Union of 'r' and '^' (rising edge to or from 'X')
+ 'D', -- Union of 'f' and 'v' (falling edge to or from 'X')
+ '*', -- Union of 'R' and 'F' (any edge)
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '-', -- don't care
+ 'B', -- 0 or 1
+ 'Z', -- High Impedance
+ 'S' -- steady value
+ );
+
+ SUBTYPE VitalEdgeSymbolType IS VitalTableSymbolType RANGE '/' TO '*';
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalExtendToFillDelay
+ --
+ -- Description: A six element array of delay values of type
+ -- VitalDelayType01Z is returned when a 1, 2 or 6
+ -- element array is given. This function will convert
+ -- VitalDelayType and VitalDelayType01 delay values into
+ -- a VitalDelayType01Z type following these rules:
+ --
+ -- When a VitalDelayType is passed, all six transition
+ -- values are assigned the input value. When a
+ -- VitalDelayType01 is passed, the 01 transitions are
+ -- assigned to the 01, 0Z and Z1 transitions and the 10
+ -- transitions are assigned to 10, 1Z and Z0 transition
+ -- values. When a VitalDelayType01Z is passed, the values
+ -- are kept as is.
+ --
+ -- The function is overloaded based on input type.
+ --
+ -- There is no function to fill a 12 value delay
+ -- type.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Delay A one, two or six delay value Vital-
+ -- DelayType is passed and a six delay,
+ -- VitalDelayType01Z, item is returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- VitalDelayType01Z
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalCalcDelay
+ --
+ -- Description: This function accepts a 1, 2 or 6 value delay and
+ -- chooses the correct delay time to delay the NewVal
+ -- signal. This function is overloaded based on the
+ -- delay type passed. The function returns a single value
+ -- of time.
+ --
+ -- This function is provided for Level 0 models in order
+ -- to calculate the delay which should be applied
+ -- for the passed signal. The delay selection is performed
+ -- using the OldVal and the NewVal to determine the
+ -- transition to select. The default value of OldVal is X.
+ --
+ -- This function cannot be used in a Level 1 model since
+ -- the VitalPathDelay routines perform the delay path
+ -- selection and output driving function.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- NewVal New value of the signal to be
+ -- assigned
+ -- OldVal Previous value of the signal.
+ -- Default value is 'X'
+ -- Delay The delay structure from which to
+ -- select the appropriate delay. The
+ -- function overload is based on the
+ -- type of delay passed. In the case of
+ -- the single delay, VitalDelayType, no
+ -- selection is performed, since there
+ -- is only one value to choose from.
+ -- For the other cases, the transition
+ -- from the old value to the new value
+ -- decide the value returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- Time The time value selected from the
+ -- Delay INPUT is returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPathDelay
+ --
+ -- Description: VitalPathDelay is the Level 1 routine used to select
+ -- the propagation delay path and schedule a new output
+ -- value.
+ --
+ -- For single and dual delay values, VitalDelayType and
+ -- VitalDelayType01 are used. The output value is
+ -- scheduled with a calculated delay without strength
+ -- modification.
+ --
+ -- For the six delay value, VitalDelayType01Z, the output
+ -- value is scheduled with a calculated delay. The drive
+ -- strength can be modified to handle weak signal strengths
+ -- to model tri-state devices, pull-ups and pull-downs as
+ -- an example.
+ --
+ -- The correspondence between the delay type and the
+ -- path delay function is as follows:
+ --
+ -- Delay Type Path Type
+ --
+ -- VitalDelayType VitalPathDelay
+ -- VitalDelayType01 VitalPathDelay01
+ -- VitalDelayType01Z VitalPathDelay01Z
+ --
+ -- For each of these routines, the following capabilities
+ -- is provided:
+ --
+ -- o Transition dependent path delay selection
+ -- o User controlled glitch detection with the ability
+ -- to generate "X" on output and report the violation
+ -- o Control of the severity level for message generation
+ -- o Scheduling of the computed values on the specified
+ -- signal.
+ --
+ -- Selection of the appropriate path delay begins with the
+ -- candidate paths. The candidate paths are selected by
+ -- identifying the paths for which the PathCondition is
+ -- true. If there is a single candidate path, then that
+ -- delay is selected. If there is more than one candidate
+ -- path, then the shortest delay is selected using
+ -- transition dependent delay selection. If there is no
+ -- candidate paths, then the delay specified by the
+ -- DefaultDelay parameter to the path delay is used.
+ --
+ -- Once the delay is known, the output signal is then
+ -- scheduled with that delay. In the case of
+ -- VitalPathDelay01Z, an additional result mapping of
+ -- the output value is performed before scheduling. The
+ -- result mapping is performed after transition dependent
+ -- delay selection but before scheduling the final output.
+ --
+ -- In order to perform glitch detection, the user is
+ -- obligated to provide a variable of VitalGlitchDataType
+ -- for the propagation delay functions to use. The user
+ -- cannot modify or use this information.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- OutSignalName string The name of the output signal
+ -- OutTemp std_logic The new output value to be driven
+ -- Paths VitalPathArrayType A list of paths of VitalPathArray
+ -- VitalPathArrayType01 type. The VitalPathDelay routine
+ -- VitalPathArrayType01Z is overloaded based on the type
+ -- of constant passed in. With
+ -- VitalPathArrayType01Z, the
+ -- resulting output strengths can be
+ -- mapped.
+ -- DefaultDelay VitalDelayType The default delay can be changed
+ -- VitalDelayType01 from zero-delay to another set of
+ -- VitalDelayType01Z values.
+ -- Mode VitalGlitchKindType The value of this constant
+ -- selects the type of glitch
+ -- detection.
+ -- OnEvent Glitch on transition event
+ -- | OnDetect Glitch immediate on detection
+ -- | VitalInertial No glitch, use INERTIAL
+ -- assignment
+ -- | VitalTransport No glitch, use TRANSPORT
+ -- assignment
+ -- XOn BOOLEAN Control for generation of 'X' on
+ -- glitch. When TRUE, 'X's are
+ -- scheduled for glitches, otherwise
+ -- no are generated.
+ -- MsgOn BOOLEAN Control for message generation on
+ -- glitch detect. When TRUE,
+ -- glitches are reported, otherwise
+ -- they are not reported.
+ -- MsgSeverity SEVERITY_LEVEL The level at which the message,
+ -- or assertion, will be reported.
+ -- OutputMap VitalOutputMapType For VitalPathDelay01Z, the output
+ -- can be mapped to alternate
+ -- strengths to model tri-state
+ -- devices, pull-ups and pull-downs.
+ --
+ -- INOUT
+ -- GlitchData VitalGlitchDataType The internal data storage
+ -- variable required to detect
+ -- glitches.
+ --
+ -- OUT
+ -- OutSignal std_logic The output signal to be driven
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType
+ := VitalDefaultOutputMap
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalWireDelay
+ --
+ -- Description: VitalWireDelay is used to delay an input signal.
+ -- The delay is selected from the input parameter passed.
+ -- The function is useful for back annotation of actual
+ -- net delays.
+ --
+ -- The function is overloaded to permit passing a delay
+ -- value for twire for VitalDelayType, VitalDelayType01
+ -- and VitalDelayType01Z. twire is a generic which can
+ -- be back annotated and must be constructed to follow
+ -- the SDF to generic mapping rules.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The input signal (port) to be
+ -- delayed.
+ -- twire VitalDelayType The delay value for which the input
+ -- VitalDelayType01 signal should be delayed. For Vital-
+ -- VitalDelayType01Z DelayType, the value is single value
+ -- passed. For VitalDelayType01 and
+ -- VitalDelayType01Z, the appropriate
+ -- delay value is selected by VitalCalc-
+ -- Delay.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The internal delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSignalDelay
+ --
+ -- Description: The VitalSignalDelay procedure is called in a signal
+ -- delay block in the architecture to delay the
+ -- appropriate test or reference signal in order to
+ -- accommodate negative constraint checks.
+ --
+ -- The amount of delay is of type TIME and is a constant.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The signal to be delayed.
+ -- dly TIME The amount of time the signal is
+ -- delayed.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSetupHoldCheck
+ --
+ -- Description: The VitalSetupHoldCheck procedure detects a setup or a
+ -- hold violation on the input test signal with respect
+ -- to the corresponding input reference signal. The timing
+ -- constraints are specified through parameters
+ -- representing the high and low values for the setup and
+ -- hold values for the setup and hold times. This
+ -- procedure assumes non-negative values for setup and hold
+ -- timing constraints.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative setup times result in
+ -- a delayed reference signal. Negative hold times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- This function is overloaded based on the input
+ -- TestSignal. A vector and scalar form are provided.
+ --
+ -- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| error region |<--
+ -- :
+ -- _______________________________
+ -- RefSignal \______________________________
+ -- : | | |
+ -- : | -->| |<-- thold
+ -- : -->| tsetup |<--
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- std_logic_vector
+ -- TestSignalName STRING Name of test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- RefSignal std_ulogic Value of reference signal
+ -- RefSignalName STRING Name of reference signal
+ -- RefDelay TIME Model's internal delay associated
+ -- with RefSignal
+ -- SetupHigh TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a setup violation.
+ -- SetupLow TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a setup violation.
+ -- HoldHigh TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a hold violation.
+ -- HoldLow TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a hold violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specified. Events on
+ -- the RefSignal which match the edge
+ -- spec. are used as reference edges.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, set and hold violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalSetupHoldCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalRecoveryRemovalCheck
+ --
+ -- Description: The VitalRecoveryRemovalCheck detects the presence of
+ -- a recovery or removal violation on the input test
+ -- signal with respect to the corresponding input reference
+ -- signal. It assumes non-negative values of setup and
+ -- hold timing constraints. The timing constraint is
+ -- specified through parameters representing the recovery
+ -- and removal times associated with a reference edge of
+ -- the reference signal. A flag indicates whether a test
+ -- signal is asserted when it is high or when it is low.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative recovery times result in
+ -- a delayed reference signal. Negative removal times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of TestSignal. The routine is
+ -- TestSignalName STRING Name of TestSignal
+ -- TestDelay TIME Model internal delay associated with
+ -- the TestSignal
+ -- RefSignal std_ulogic Value of RefSignal
+ -- RefSignalName STRING Name of RefSignal
+ -- RefDelay TIME Model internal delay associated with
+ -- the RefSignal
+ -- Recovery TIME A change to an unasserted value on
+ -- the asynchronous TestSignal must
+ -- precede reference edge (on RefSignal)
+ -- by at least this time.
+ -- Removal TIME An asserted condition must be present
+ -- on the asynchronous TestSignal for at
+ -- least the removal time following a
+ -- reference edge on RefSignal.
+ -- ActiveLow BOOLEAN A flag which indicates if TestSignal
+ -- is asserted when it is low - "0."
+ -- FALSE indicate that TestSignal is
+ -- asserted when it has a value "1."
+ -- CheckEnabled BOOLEAN The check in enabled when the value
+ -- is TRUE, otherwise the constraints
+ -- are not checked.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specifier. Events on
+ -- RefSignal will match the edge
+ -- specified.
+ -- HeaderMsg STRING A header message that will accompany
+ -- any assertion message.
+ -- XOn BOOLEAN When TRUE, the output Violation is
+ -- set to "X." When FALSE, it is always
+ -- "0."
+ -- MsgOn BOOLEAN When TRUE, violation messages are
+ -- output. When FALSE, no messages are
+ -- generated.
+ -- MsgSeverity SEVERITY_LEVEL Severity level of the asserted
+ -- message.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalRecoveryRemovalCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPeriodPulseCheck
+ --
+ -- Description: VitalPeriodPulseCheck checks for minimum and maximum
+ -- periodicity and pulse width for "1" and "0" values of
+ -- the input test signal. The timing constraint is
+ -- specified through parameters representing the minimal
+ -- period between successive rising and falling edges of
+ -- the input test signal and the minimum pulse widths
+ -- associated with high and low values.
+ --
+ -- VitalPeriodCheck's accepts rising and falling edges
+ -- from 1 and 0 as well as transitions to and from 'X.'
+ --
+ -- _______________ __________
+ -- ____________| |_______|
+ --
+ -- |<--- pw_hi --->|
+ -- |<-------- period ----->|
+ -- -->| pw_lo |<--
+ --
+ -- Arguments:
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- TestSignalName STRING Name of the test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- Period TIME Minimum period allowed between
+ -- consecutive rising ('P') or
+ -- falling ('F') transitions.
+ -- PulseWidthHigh TIME Minimum time allowed for a high
+ -- pulse ('1' or 'H')
+ -- PulseWidthLow TIME Minimum time allowed for a low
+ -- pulse ('0' or 'L')
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, period/pulse violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even though a violation is detected.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- PeriodData VitalPeriodDataType
+ -- VitalPeriodPulseCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the pulse and period
+ -- times.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+END VITAL_Timing;
diff --git a/libraries/vital95/vital_timing_body.vhdl b/libraries/vital95/vital_timing_body.vhdl
new file mode 100644
index 000000000..09eb75565
--- /dev/null
+++ b/libraries/vital95/vital_timing_body.vhdl
@@ -0,0 +1,1275 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 597 $
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- : This file contains the Package Body.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/08/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #203 - Timing violations at time 0
+-- #204 - Output mapping prior to glitch detection
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Timing IS
+
+ -- --------------------------------------------------------------------
+ -- Package Local Declarations
+ -- --------------------------------------------------------------------
+ TYPE CheckType IS ( SetupCheck, HoldCheck, RecoveryCheck, RemovalCheck,
+ PulseWidCheck, PeriodCheck );
+
+ TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+ END RECORD;
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+ CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+ TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+ -- last value, present value, edge symbol
+ CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := (
+ 'X'=>('X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) ),
+ '0'=>('X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) ),
+ '1'=>('X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE ) ) );
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Misc Utilities Local Utilities
+ ---------------------------------------------------------------------------
+ -----------------------------------------------------------------------
+ FUNCTION Minimum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrVctLng ,
+ ErrNoPath ,
+ ErrNegPath ,
+ ErrNegDel
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrVctLng => ERROR,
+ ErrNoPath => WARNING,
+ ErrNegPath => WARNING,
+ ErrNegDel => WARNING
+ );
+
+ CONSTANT MsgNoPath : STRING :=
+ "No Delay Path Condition TRUE. 0-delay used. Output signal is: ";
+ CONSTANT MsgNegPath : STRING :=
+ "Path Delay less than time since input. 0 delay used. Output signal is: ";
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrNoPath => RETURN MsgNoPath;
+ WHEN ErrNegPath => RETURN MsgNegPath;
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Time Delay Assignment Subprograms
+ ---------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN (OTHERS => Delay);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z IS
+ VARIABLE Delay01Z : VitalDelayType01Z;
+ BEGIN
+ Delay01Z(tr01) := Delay(tr01);
+ Delay01Z(tr0z) := Delay(tr01);
+ Delay01Z(trz1) := Delay(tr01);
+ Delay01Z(tr10) := Delay(tr10);
+ Delay01Z(tr1z) := Delay(tr10);
+ Delay01Z(trz0) := Delay(tr10);
+ RETURN (Delay01Z);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN Delay;
+ END VitalExtendToFillDelay;
+
+ ---------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME IS
+ BEGIN
+ RETURN delay;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ WHEN OTHERS =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN 'Z' => Result := MINIMUM(Delay(tr10), Delay(tr01));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr0z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr01), Delay(tr0z));
+ END CASE;
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr1z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr10), Delay(tr1z));
+ END CASE;
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(trz0);
+ WHEN '1' | 'H' => Result := Delay(trz1);
+ WHEN 'Z' => Result := MAXIMUM (Delay(tr0z), Delay(tr1z));
+ WHEN OTHERS => Result := MINIMUM (Delay(trz1), Delay(trz0));
+ END CASE;
+ WHEN 'U' | 'X' | 'W' | '-' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := MAXIMUM(Delay(tr10), Delay(trz0));
+ WHEN '1' | 'H' => Result := MAXIMUM(Delay(tr01), Delay(trz1));
+ WHEN 'Z' => Result := MAXIMUM(Delay(tr1z), Delay(tr0z));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ ---------------------------------------------------------------------------
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default the delay
+ IF (PropDelay = TIME'HIGH ) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- If the time since the most recent input event is greater than the
+ -- propagation delay from that input then
+ -- use the default the delay
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default the delay
+ IF (PropDelay = TIME'HIGH ) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- If the time since the most recent input event is greater than the
+ -- propagation delay from that input then
+ -- use the default the delay
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default the delay
+ IF (PropDelay = TIME'HIGH ) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- If the time since the most recent input event is greater than the
+ -- propagation delay from that input then
+ -- use the default the delay
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Glitch Handlers
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preempted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalGlitch (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ ---------------------------------------------------------------------------
+ VARIABLE NewGlitch : BOOLEAN := TRUE;
+ VARIABLE dly : TIME := NewDelay;
+
+ BEGIN
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitch", ErrNegDel, OutSignalName );
+ END IF;
+ RETURN;
+ END IF;
+
+ -- If simple signal assignment
+ -- perform the signal assignment
+ IF ( Mode = VitalInertial) THEN
+ OutSignal <= NewValue AFTER dly;
+ ELSIF ( Mode = VitalTransport ) THEN
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ ELSE
+ -- Glitch Processing ---
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN
+ -- Note: NewValue is always /= OldValue when called from VPPD
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ -- No new glitch, save time for possable future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- New value earlier than the earliest previous value scheduled
+ ELSIF (NOW+dly <= GlitchData.GlitchTime)
+ AND (NOW+dly <= GlitchData.SchedTime) THEN
+ -- No new glitch, save time for possible future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+ NewGlitch := FALSE;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue)
+ AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN
+ -- revise scheduled output time if new delay is sooner
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ -- No new glitch, save time for possable future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled represents a glitch
+ ELSE
+ -- A new glitch has been detected
+ NewGlitch := TRUE;
+ END IF;
+
+ IF NewGlitch THEN
+ -- If messages requested, report the glitch
+ IF MsgOn THEN
+ ReportGlitch ("VitalGlitch", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+
+ -- Force immediate glitch for "OnDetect" mode.
+ IF (Mode = OnDetect) THEN
+ GlitchData.GlitchTime := NOW;
+ END IF;
+
+ -- If 'X' generation is requested, schedule the new value
+ -- preceeded by a glitch pulse.
+ -- Otherwise just schedule the new value (inertial mode).
+ IF XOn THEN
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ ELSE
+ OutSignal <= NewValue AFTER dly;
+ END IF;
+
+ -- If there no new glitch was detected, just schedule the new value.
+ ELSE
+ OutSignal <= NewValue AFTER dly;
+ END IF;
+
+ END IF;
+
+ -- Record the new value and time just scheduled.
+ GlitchData.SchedValue := NewValue;
+ GlitchData.SchedTime := NOW+dly;
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay);
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay;
+
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay);
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay01;
+
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType
+ := VitalDefaultOutputMap
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutputMap(OutTemp) )
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay);
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutputMap(OutTemp),
+ PropDelay, Mode, XOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay01Z;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER twire;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER dly;
+ END;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Setup and Hold Time Check Routine
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ IF NOT CheckInfo.Violation THEN RETURN; END IF;
+
+ Write ( Message, HeaderMsg );
+ Case CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportViolation;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : InternalTimingCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+ ) IS
+ VARIABLE bias, b2 : TIME;
+ BEGIN
+ -- Check SETUP constraint
+ IF RefEdge THEN
+ IF SetupEn THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ CheckInfo.Violation := CheckInfo.ObsTime < CheckInfo.ExpTime;
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF TestEvent THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ CheckInfo.Violation := CheckInfo.ObsTime < CheckInfo.ExpTime;
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime and bias are non-negative
+ IF MsgOn AND CheckInfo.Violation THEN
+ bias := TestDelay - RefDelay;
+ IF TestTime - RefTime <= bias THEN
+ CheckInfo.CheckKind := SetupCheck;
+ b2 := TIME'HIGH - bias;
+ IF (CheckInfo.ObsTime <= b2)
+ THEN CheckInfo.ObsTime := CheckInfo.ObsTime + bias;
+ ELSE CheckInfo.ObsTime := Time'HIGH;
+ END IF;
+ IF (CheckInfo.ExpTime <= b2)
+ THEN CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ ELSE CheckInfo.ExpTime := Time'HIGH;
+ END IF;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ CheckInfo.ObsTime := CheckInfo.ObsTime - bias;
+ IF (CheckInfo.ExpTime >= 0 ns) THEN
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ END IF;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+ END IF;
+ END InternalTimingCheck;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ FUNCTION VitalTimingDataInit
+ RETURN VitalTimingDataType IS
+ BEGIN
+ RETURN (FALSE,'X', 0 ns, FALSE, 'X', 0 ns, FALSE, NULL, NULL, NULL, NULL);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalSetupHoldCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.HoldEn := TRUE;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := TRUE;
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ VARIABLE ChangedAllAtOnce : BOOLEAN := TRUE;
+ VARIABLE StrPtr1 : LINE;
+
+ BEGIN
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ -- Check to see if the Bus subelements changed all at the same time.
+ -- If so, then we can reduce the volume of error messages since we no
+ -- longer have to report every subelement individually
+ FOR i IN TestSignal'RANGE LOOP
+ IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN
+ ChangedAllAtOnce := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ FOR i IN TestSignal'RANGE LOOP
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN
+ ReportViolation (TestSignalName&"(...)", RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ ELSIF (NOT ChangedAllAtOnce) THEN
+ Write (StrPtr1, i);
+ ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")",
+ RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ DEALLOCATE (StrPtr1);
+ END IF;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+
+ DEALLOCATE (StrPtr1);
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalRecoveryRemovalCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.HoldEn := TRUE;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := TRUE;
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+
+ IF ActiveLow THEN
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ Recovery, 0 ns, 0 ns, Removal,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ ELSE
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ 0 ns, Recovery, Removal, 0 ns,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ END IF;
+
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF CheckInfo.CheckKind = SetupCheck THEN
+ CheckInfo.CheckKind := RecoveryCheck;
+ ELSE
+ CheckInfo.CheckKind := RemovalCheck;
+ END IF;
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalRecoveryRemovalCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : TIME;
+ VARIABLE PulseTest, PeriodTest : BOOLEAN;
+ VARIABLE TestValue : X01 := To_X01(TestSignal);
+ BEGIN
+
+ IF (PeriodData.NotFirstFlag = FALSE) THEN
+ PeriodData.Rise :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Fall :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Last := To_X01(TestSignal);
+ PeriodData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- No violation possible if no test signal change
+ Violation := '0';
+ IF (PeriodData.Last = TestValue) THEN
+ RETURN;
+ END IF;
+
+ -- record starting pulse times
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData.Rise;
+ PeriodData.Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData.Fall;
+ PeriodData.Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Fall;
+ CheckInfo.ExpTime := PulseWidthLow;
+ PulseTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Rise;
+ CheckInfo.ExpTime := PulseWidthHigh;
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF PulseTest AND CheckEnabled THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData.Last;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF PeriodTest AND CheckEnabled THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period;
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData.Last := TestValue;
+
+ END VitalPeriodPulseCheck;
+
+END VITAL_Timing;
+