-- Copyright © 1993 by McGraw-Hill, Inc. and Zainalabedin Navabi
-- FIGURE 6.40
-- BASIC UTILITIES PACKAGE DECLERATION :
PACKAGE basic_utilities IS
TYPE qit IS ('0', '1', 'Z', 'X');
TYPE qit_2d IS ARRAY (qit, qit) OF qit;
TYPE qit_1d IS ARRAY (qit) OF qit;
TYPE integer_vector IS ARRAY (NATURAL RANGE <>) OF INTEGER;
TYPE logic_data IS FILE OF CHARACTER;
TYPE capacitance IS RANGE 0 TO 1E16
UNITS
ffr; -- Femto Farads (base unit)
pfr = 1000 ffr;
nfr = 1000 pfr;
ufr = 1000 nfr;
mfr = 1000 ufr;
far = 1000 mfr;
kfr = 1000 far;
END UNITS;
TYPE resistance IS RANGE 0 TO 1E16
UNITS
l_o; -- Milli-Ohms (base unit)
ohms = 1000 l_o;
k_o = 1000 ohms;
m_o = 1000 k_o;
g_o = 1000 m_o;
END UNITS;
FUNCTION fgl (w, x, gl : BIT) RETURN BIT;
FUNCTION feq (w, x, eq : BIT) RETURN BIT;
PROCEDURE bin2int (bin : IN BIT_VECTOR; int : OUT INTEGER);
PROCEDURE int2bin (int : IN INTEGER; bin : OUT BIT_VECTOR);
PROCEDURE apply_data (
SIGNAL target : OUT BIT_VECTOR;
CONSTANT values : IN integer_vector; CONSTANT period : IN TIME);
PROCEDURE assign_bits (
SIGNAL s : OUT BIT; file_name : IN STRING; period : IN TIME);
PROCEDURE assign_bits (
SIGNAL s : OUT qit; file_name : IN STRING; period : IN TIME);
FUNCTION "AND" (a, b : qit) RETURN qit;
FUNCTION "OR" (a, b : qit) RETURN qit;
FUNCTION "NOT" (a : qit) RETURN qit;
FUNCTION "*" (a : resistance; b : capacitance) RETURN TIME;
END basic_utilities;
--
-- BASIC UTILITIES PACKAGE BODY :
PACKAGE BODY basic_utilities IS
FUNCTION "AND" (a, b : qit) RETURN qit IS
CONSTANT qit_and_table : qit_2d := (
('0','0','0','0'),
('0','1','1','X'),
('0','1','1','X'),
('0','X','X','X'));
BEGIN
RETURN qit_and_table (a, b);
END "AND";
FUNCTION "OR" (a, b : qit) RETURN qit IS
CONSTANT qit_or_table : qit_2d := (
('0','1','1','X'),
('1','1','1','1'),
('1','1','1','1'),
('X','1','1','X'));
BEGIN
RETURN qit_or_table (a, b);
END "OR";
FUNCTION "NOT" (a : qit) RETURN qit IS
CONSTANT qit_not_table : qit_1d := ('1','0','0','X');
BEGIN
RETURN qit_not_table (a);
END "NOT";
FUNCTION "*" (a : resistance; b : capacitance) RETURN TIME IS
BEGIN
RETURN ( ( a / 1 l_o) * ( b / 1 ffr ) * 1 FS ) / 1000;
END "*";
FUNCTION fgl (w, x, gl : BIT) RETURN BIT IS
BEGIN
RETURN (w AND gl) OR (NOT x AND gl) OR (w AND NOT x);
END fgl;
FUNCTION feq (w, x, eq : BIT) RETURN BIT IS
BEGIN
RETURN (w AND x AND eq) OR (NOT w AND NOT x AND eq);
END feq;
PROCEDURE bin2int (bin : IN BIT_VECTOR; int : OUT INTEGER) IS
VARIABLE result: INTEGER;
BEGIN
result := 0;
FOR i IN 0 TO (bin'LENGTH - 1) LOOP
IF bin(i) = '1' THEN
result := result + 2**i;
END IF;
END LOOP;
int := result;
END bin2int;
PROCEDURE int2bin (int : IN INTEGER; bin : OUT BIT_VECTOR) IS
VARIABLE tmp : INTEGER;
BEGIN
tmp := int;
FOR i IN 0 TO (bin'LENGTH - 1) LOOP
IF (tmp MOD 2 = 1) THEN
bin (i) := '1';
ELSE bin (i) := '0';
END IF;
tmp := tmp / 2;
END LOOP;
END int2bin;
PROCEDURE apply_data (
SIGNAL target : OUT BIT_VECTOR;
CONSTANT values : IN integer_vector; CONSTANT period : IN TIME)
IS
VARIABLE buf : BIT_VECTOR (target'RANGE);
BEGIN
FOR i IN values'RANGE LOOP
int2bin (values(i), buf);
target <= TRANSPORT buf AFTER i * period;
END LOOP;
END apply_data;
PROCEDURE assign_bits (
SIGNAL s : OUT BIT; file_name : IN STRING; period : IN TIME)
IS
VARIABLE char : CHARACTER;
VARIABLE current : TIME := 0 NS;
FILE input_value_file : logic_data IS IN file_name;
BEGIN
WHILE NOT ENDFILE (input_value_file) LOOP
READ (input_value_file, char);
IF char = '0' OR char = '1' THEN
current := current + period;
IF char = '0' THEN
s <= TRANSPORT '0' AFTER current;
ELSIF char = '1' THEN
s <= TRANSPORT '1' AFTER current;
END IF;
END IF;
END LOOP;
END assign_bits;
PROCEDURE assign_bits (
SIGNAL s : OUT qit; file_name : IN STRING; period : IN TIME)
IS
VARIABLE char : CHARACTER;
VARIABLE current : TIME := 0 NS;
FILE input_value_file : logic_data IS IN file_name;
BEGIN
WHILE NOT ENDFILE (input_value_file) LOOP
READ (input_value_file, char);
current := current + period;
CASE char IS
WHEN '0' => s <= TRANSPORT '0' AFTER current;
WHEN '1' => s <= TRANSPORT '1' AFTER current;
WHEN 'Z' | 'z' => s <= TRANSPORT 'Z' AFTER current;
WHEN 'X' | 'x' => s <= TRANSPORT 'X' AFTER current;
WHEN OTHERS => current := current - period;
END CASE;
END LOOP;
END assign_bits;
END basic_utilities;
--