1573 lines
56 KiB
VHDL
1573 lines
56 KiB
VHDL
-- -----------------------------------------------------------------
|
|
--
|
|
-- Copyright 2019 IEEE P1076 WG Authors
|
|
--
|
|
-- See the LICENSE file distributed with this work for copyright and
|
|
-- licensing information and the AUTHORS file.
|
|
--
|
|
-- This file to you under the Apache License, Version 2.0 (the "License").
|
|
-- You may obtain a copy of the License at
|
|
--
|
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
|
--
|
|
-- Unless required by applicable law or agreed to in writing, software
|
|
-- distributed under the License is distributed on an "AS IS" BASIS,
|
|
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
-- implied. See the License for the specific language governing
|
|
-- permissions and limitations under the License.
|
|
--
|
|
-- Title : Standard multivalue logic package
|
|
-- : (STD_LOGIC_1164 package body)
|
|
-- :
|
|
-- Library : This package shall be compiled into a library
|
|
-- : symbolically named IEEE.
|
|
-- :
|
|
-- Developers: IEEE model standards group (PAR 1164),
|
|
-- : Accellera VHDL-TC, and IEEE P1076 Working Group
|
|
-- :
|
|
-- 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 : This package may be modified to include additional data
|
|
-- : required by tools, but it must in no way change the
|
|
-- : external interfaces or simulation behavior 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 package declaration.
|
|
-- : The package body may be changed only in accordance with
|
|
-- : the terms of Clause 16 of this standard.
|
|
-- :
|
|
-- --------------------------------------------------------------------
|
|
-- $Revision: 1220 $
|
|
-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
|
|
-- --------------------------------------------------------------------
|
|
|
|
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 function 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 function "and";
|
|
|
|
function "nand" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (not_table (and_table(l, r)));
|
|
end function "nand";
|
|
|
|
function "or" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (or_table(l, r));
|
|
end function "or";
|
|
|
|
function "nor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (not_table (or_table(l, r)));
|
|
end function "nor";
|
|
|
|
function "xor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (xor_table(l, r));
|
|
end function "xor";
|
|
|
|
function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return not_table(xor_table(l, r));
|
|
end function "xnor";
|
|
|
|
function "not" (l : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (not_table(l));
|
|
end function "not";
|
|
|
|
-------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""and"": "
|
|
& "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 function "and";
|
|
-------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""nand"": "
|
|
& "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 function "nand";
|
|
-------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""or"": "
|
|
& "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 function "or";
|
|
-------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""nor"": "
|
|
& "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 function "nor";
|
|
---------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""xor"": "
|
|
& "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 function "xor";
|
|
-------------------------------------------------------------------
|
|
-- 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 "STD_LOGIC_1164.""xnor"": "
|
|
& "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 function "xnor";
|
|
-------------------------------------------------------------------
|
|
-- not
|
|
-------------------------------------------------------------------
|
|
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 function "not";
|
|
|
|
-------------------------------------------------------------------
|
|
-- and
|
|
-------------------------------------------------------------------
|
|
function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := and_table (lv(i), r);
|
|
end loop;
|
|
return result;
|
|
end function "and";
|
|
-------------------------------------------------------------------
|
|
function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := and_table (l, rv(i));
|
|
end loop;
|
|
return result;
|
|
end function "and";
|
|
|
|
-------------------------------------------------------------------
|
|
-- nand
|
|
-------------------------------------------------------------------
|
|
function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(and_table (lv(i), r));
|
|
end loop;
|
|
return result;
|
|
end function "nand";
|
|
-------------------------------------------------------------------
|
|
function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(and_table (l, rv(i)));
|
|
end loop;
|
|
return result;
|
|
end function "nand";
|
|
|
|
-------------------------------------------------------------------
|
|
-- or
|
|
-------------------------------------------------------------------
|
|
function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := or_table (lv(i), r);
|
|
end loop;
|
|
return result;
|
|
end function "or";
|
|
-------------------------------------------------------------------
|
|
function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := or_table (l, rv(i));
|
|
end loop;
|
|
return result;
|
|
end function "or";
|
|
|
|
-------------------------------------------------------------------
|
|
-- nor
|
|
-------------------------------------------------------------------
|
|
function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(or_table (lv(i), r));
|
|
end loop;
|
|
return result;
|
|
end function "nor";
|
|
-------------------------------------------------------------------
|
|
function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(or_table (l, rv(i)));
|
|
end loop;
|
|
return result;
|
|
end function "nor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- xor
|
|
-------------------------------------------------------------------
|
|
function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := xor_table (lv(i), r);
|
|
end loop;
|
|
return result;
|
|
end function "xor";
|
|
-------------------------------------------------------------------
|
|
function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := xor_table (l, rv(i));
|
|
end loop;
|
|
return result;
|
|
end function "xor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- xnor
|
|
-------------------------------------------------------------------
|
|
function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC)
|
|
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);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(xor_table (lv(i), r));
|
|
end loop;
|
|
return result;
|
|
end function "xnor";
|
|
-------------------------------------------------------------------
|
|
function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR)
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
|
|
variable result : STD_ULOGIC_VECTOR (1 to r'length);
|
|
begin
|
|
for i in result'range loop
|
|
result(i) := not_table(xor_table (l, rv(i)));
|
|
end loop;
|
|
return result;
|
|
end function "xnor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- and
|
|
-------------------------------------------------------------------
|
|
function "and" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '1';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := and_table (l(i), result);
|
|
end loop;
|
|
return result;
|
|
end function "and";
|
|
|
|
-------------------------------------------------------------------
|
|
-- nand
|
|
-------------------------------------------------------------------
|
|
function "nand" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '1';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := and_table (l(i), result);
|
|
end loop;
|
|
return not_table(result);
|
|
end function "nand";
|
|
|
|
-------------------------------------------------------------------
|
|
-- or
|
|
-------------------------------------------------------------------
|
|
function "or" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '0';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := or_table (l(i), result);
|
|
end loop;
|
|
return result;
|
|
end function "or";
|
|
|
|
-------------------------------------------------------------------
|
|
-- nor
|
|
-------------------------------------------------------------------
|
|
function "nor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '0';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := or_table (l(i), result);
|
|
end loop;
|
|
return not_table(result);
|
|
end function "nor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- xor
|
|
-------------------------------------------------------------------
|
|
function "xor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '0';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := xor_table (l(i), result);
|
|
end loop;
|
|
return result;
|
|
end function "xor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- xnor
|
|
-------------------------------------------------------------------
|
|
function "xnor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
|
|
variable result : STD_ULOGIC := '0';
|
|
begin
|
|
for i in l'reverse_range loop
|
|
result := xor_table (l(i), result);
|
|
end loop;
|
|
return not_table(result);
|
|
end function "xnor";
|
|
|
|
-------------------------------------------------------------------
|
|
-- shift operators
|
|
-------------------------------------------------------------------
|
|
|
|
-------------------------------------------------------------------
|
|
-- sll
|
|
-------------------------------------------------------------------
|
|
function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER)
|
|
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 => '0');
|
|
begin
|
|
if r >= 0 then
|
|
result(1 to l'length - r) := lv(r + 1 to l'length);
|
|
else
|
|
result := l srl -r;
|
|
end if;
|
|
return result;
|
|
end function "sll";
|
|
|
|
-------------------------------------------------------------------
|
|
-- srl
|
|
-------------------------------------------------------------------
|
|
function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER)
|
|
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 => '0');
|
|
begin
|
|
if r >= 0 then
|
|
result(r + 1 to l'length) := lv(1 to l'length - r);
|
|
else
|
|
result := l sll -r;
|
|
end if;
|
|
return result;
|
|
end function "srl";
|
|
|
|
-------------------------------------------------------------------
|
|
-- rol
|
|
-------------------------------------------------------------------
|
|
function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER)
|
|
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);
|
|
constant rm : INTEGER := r mod l'length;
|
|
begin
|
|
if r >= 0 then
|
|
result(1 to l'length - rm) := lv(rm + 1 to l'length);
|
|
result(l'length - rm + 1 to l'length) := lv(1 to rm);
|
|
else
|
|
result := l ror -r;
|
|
end if;
|
|
return result;
|
|
end function "rol";
|
|
|
|
-------------------------------------------------------------------
|
|
-- ror
|
|
-------------------------------------------------------------------
|
|
function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER)
|
|
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 => '0');
|
|
constant rm : INTEGER := r mod l'length;
|
|
begin
|
|
if r >= 0 then
|
|
result(rm + 1 to l'length) := lv(1 to l'length - rm);
|
|
result(1 to rm) := lv(l'length - rm + 1 to l'length);
|
|
else
|
|
result := l rol -r;
|
|
end if;
|
|
return result;
|
|
end function "ror";
|
|
|
|
-------------------------------------------------------------------
|
|
-- 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_bit;
|
|
--------------------------------------------------------------------
|
|
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_bitvector;
|
|
--------------------------------------------------------------------
|
|
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_StdULogic;
|
|
--------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
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_StdLogicVector;
|
|
--------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
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 function To_StdULogicVector;
|
|
|
|
-------------------------------------------------------------------
|
|
-- strength strippers and type convertors
|
|
-------------------------------------------------------------------
|
|
-- to_01
|
|
-------------------------------------------------------------------
|
|
function TO_01 (s : STD_ULOGIC_VECTOR; xmap : STD_ULOGIC := '0')
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
variable RESULT : STD_ULOGIC_VECTOR(s'length-1 downto 0);
|
|
variable BAD_ELEMENT : BOOLEAN := false;
|
|
alias XS : STD_ULOGIC_VECTOR(s'length-1 downto 0) is s;
|
|
begin
|
|
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 function TO_01;
|
|
-------------------------------------------------------------------
|
|
function TO_01 (s : STD_ULOGIC; xmap : STD_ULOGIC := '0') return STD_ULOGIC is
|
|
begin
|
|
case s is
|
|
when '0' | 'L' => RETURN '0';
|
|
when '1' | 'H' => RETURN '1';
|
|
when others => return xmap;
|
|
end case;
|
|
end function TO_01;
|
|
-------------------------------------------------------------------
|
|
function TO_01 (s : BIT_VECTOR; xmap : STD_ULOGIC := '0')
|
|
return STD_ULOGIC_VECTOR
|
|
is
|
|
variable RESULT : STD_ULOGIC_VECTOR(s'length-1 downto 0);
|
|
alias XS : BIT_VECTOR(s'length-1 downto 0) is s;
|
|
begin
|
|
for I in RESULT'range loop
|
|
case XS(I) is
|
|
when '0' => RESULT(I) := '0';
|
|
when '1' => RESULT(I) := '1';
|
|
end case;
|
|
end loop;
|
|
return RESULT;
|
|
end function TO_01;
|
|
-------------------------------------------------------------------
|
|
function TO_01 (s : BIT; xmap : STD_ULOGIC := '0') return STD_ULOGIC is
|
|
begin
|
|
case s is
|
|
when '0' => RETURN '0';
|
|
when '1' => RETURN '1';
|
|
end case;
|
|
end function TO_01;
|
|
-------------------------------------------------------------------
|
|
-- to_x01
|
|
-------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_X01 (s : STD_ULOGIC) return X01 is
|
|
begin
|
|
return (cvt_to_x01(s));
|
|
end function To_X01;
|
|
--------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_X01 (b : BIT) return X01 is
|
|
begin
|
|
case b is
|
|
when '0' => return('0');
|
|
when '1' => return('1');
|
|
end case;
|
|
end function To_X01;
|
|
--------------------------------------------------------------------
|
|
-- to_x01z
|
|
-------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_X01Z (s : STD_ULOGIC) return X01Z is
|
|
begin
|
|
return (cvt_to_x01z(s));
|
|
end function To_X01Z;
|
|
--------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_X01Z (b : BIT) return X01Z is
|
|
begin
|
|
case b is
|
|
when '0' => return('0');
|
|
when '1' => return('1');
|
|
end case;
|
|
end function To_X01Z;
|
|
--------------------------------------------------------------------
|
|
-- to_ux01
|
|
-------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_UX01 (s : STD_ULOGIC) return UX01 is
|
|
begin
|
|
return (cvt_to_ux01(s));
|
|
end function To_UX01;
|
|
--------------------------------------------------------------------
|
|
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;
|
|
--------------------------------------------------------------------
|
|
function To_UX01 (b : BIT) return UX01 is
|
|
begin
|
|
case b is
|
|
when '0' => return('0');
|
|
when '1' => return('1');
|
|
end case;
|
|
end function To_UX01;
|
|
|
|
function "??" (l : STD_ULOGIC) return BOOLEAN is
|
|
begin
|
|
return l = '1' or l = 'H';
|
|
end function "??";
|
|
|
|
-------------------------------------------------------------------
|
|
-- 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 rising_edge;
|
|
|
|
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 function falling_edge;
|
|
|
|
-------------------------------------------------------------------
|
|
-- 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;
|
|
--------------------------------------------------------------------
|
|
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 function Is_X;
|
|
|
|
-------------------------------------------------------------------
|
|
-- string conversion and write operations
|
|
-------------------------------------------------------------------
|
|
|
|
function TO_OSTRING (value : STD_ULOGIC_VECTOR) return STRING is
|
|
constant result_length : NATURAL := (value'length+2)/3;
|
|
variable pad : STD_ULOGIC_VECTOR(1 to result_length*3 - value'length);
|
|
variable padded_value : STD_ULOGIC_VECTOR(1 to result_length*3);
|
|
variable result : STRING(1 to result_length);
|
|
variable tri : STD_ULOGIC_VECTOR(1 to 3);
|
|
begin
|
|
if value (value'left) = 'Z' then
|
|
pad := (others => 'Z');
|
|
else
|
|
pad := (others => '0');
|
|
end if;
|
|
padded_value := pad & value;
|
|
for i in 1 to result_length loop
|
|
tri := To_X01Z(padded_value(3*i-2 to 3*i));
|
|
case tri is
|
|
when o"0" => result(i) := '0';
|
|
when o"1" => result(i) := '1';
|
|
when o"2" => result(i) := '2';
|
|
when o"3" => result(i) := '3';
|
|
when o"4" => result(i) := '4';
|
|
when o"5" => result(i) := '5';
|
|
when o"6" => result(i) := '6';
|
|
when o"7" => result(i) := '7';
|
|
when "ZZZ" => result(i) := 'Z';
|
|
when others => result(i) := 'X';
|
|
end case;
|
|
end loop;
|
|
return result;
|
|
end function TO_OSTRING;
|
|
|
|
function TO_HSTRING (value : STD_ULOGIC_VECTOR) return STRING is
|
|
constant result_length : NATURAL := (value'length+3)/4;
|
|
variable pad : STD_ULOGIC_VECTOR(1 to result_length*4 - value'length);
|
|
variable padded_value : STD_ULOGIC_VECTOR(1 to result_length*4);
|
|
variable result : STRING(1 to result_length);
|
|
variable quad : STD_ULOGIC_VECTOR(1 to 4);
|
|
begin
|
|
if value (value'left) = 'Z' then
|
|
pad := (others => 'Z');
|
|
else
|
|
pad := (others => '0');
|
|
end if;
|
|
padded_value := pad & value;
|
|
for i in 1 to result_length loop
|
|
quad := To_X01Z(padded_value(4*i-3 to 4*i));
|
|
case quad is
|
|
when x"0" => result(i) := '0';
|
|
when x"1" => result(i) := '1';
|
|
when x"2" => result(i) := '2';
|
|
when x"3" => result(i) := '3';
|
|
when x"4" => result(i) := '4';
|
|
when x"5" => result(i) := '5';
|
|
when x"6" => result(i) := '6';
|
|
when x"7" => result(i) := '7';
|
|
when x"8" => result(i) := '8';
|
|
when x"9" => result(i) := '9';
|
|
when x"A" => result(i) := 'A';
|
|
when x"B" => result(i) := 'B';
|
|
when x"C" => result(i) := 'C';
|
|
when x"D" => result(i) := 'D';
|
|
when x"E" => result(i) := 'E';
|
|
when x"F" => result(i) := 'F';
|
|
when "ZZZZ" => result(i) := 'Z';
|
|
when others => result(i) := 'X';
|
|
end case;
|
|
end loop;
|
|
return result;
|
|
end function TO_HSTRING;
|
|
|
|
-- 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);
|
|
|
|
constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
|
|
|
|
-- purpose: Skips white space
|
|
procedure skip_whitespace (
|
|
L : inout LINE) is
|
|
variable c : CHARACTER;
|
|
variable left : positive;
|
|
begin
|
|
while L /= null and L.all'length /= 0 loop
|
|
left := L.all'left;
|
|
c := L.all(left);
|
|
if (c = ' ' or c = NBSP or c = HT) then
|
|
read (L, c);
|
|
else
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
end procedure skip_whitespace;
|
|
|
|
procedure READ (L : inout LINE; VALUE : out STD_ULOGIC;
|
|
GOOD : out BOOLEAN) is
|
|
variable c : CHARACTER;
|
|
variable readOk : BOOLEAN;
|
|
begin
|
|
VALUE := 'U'; -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
read (L, c, readOk);
|
|
if not readOk then
|
|
GOOD := false;
|
|
else
|
|
if char_to_MVL9plus(c) = error then
|
|
GOOD := false;
|
|
else
|
|
VALUE := char_to_MVL9(c);
|
|
GOOD := true;
|
|
end if;
|
|
end if;
|
|
end procedure READ;
|
|
|
|
procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
|
|
GOOD : out BOOLEAN) is
|
|
variable c : CHARACTER;
|
|
variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
|
|
variable readOk : BOOLEAN;
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then
|
|
read (L, c, readOk);
|
|
i := 0;
|
|
GOOD := true;
|
|
while i < VALUE'length loop
|
|
if not readOk then -- Bail out if there was a bad read
|
|
GOOD := false;
|
|
return;
|
|
elsif c = '_' then
|
|
if i = 0 then
|
|
GOOD := false; -- Begins with an "_"
|
|
return;
|
|
elsif lastu then
|
|
GOOD := false; -- "__" detected
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
elsif (char_to_MVL9plus(c) = error) then
|
|
GOOD := false; -- Illegal character
|
|
return;
|
|
else
|
|
mv(i) := char_to_MVL9(c);
|
|
i := i + 1;
|
|
if i > mv'high then -- reading done
|
|
VALUE := mv;
|
|
return;
|
|
end if;
|
|
lastu := false;
|
|
end if;
|
|
read(L, c, readOk);
|
|
end loop;
|
|
else
|
|
GOOD := true; -- read into a null array
|
|
end if;
|
|
end procedure READ;
|
|
|
|
procedure READ (L : inout LINE; VALUE : out STD_ULOGIC) is
|
|
variable c : CHARACTER;
|
|
variable readOk : BOOLEAN;
|
|
begin
|
|
VALUE := 'U'; -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
read (L, c, readOk);
|
|
if not readOk then
|
|
report "STD_LOGIC_1164.READ(STD_ULOGIC) "
|
|
& "End of string encountered"
|
|
severity error;
|
|
return;
|
|
elsif char_to_MVL9plus(c) = error then
|
|
report
|
|
"STD_LOGIC_1164.READ(STD_ULOGIC) Error: Character '" &
|
|
c & "' read, expected STD_ULOGIC literal."
|
|
severity error;
|
|
else
|
|
VALUE := char_to_MVL9(c);
|
|
end if;
|
|
end procedure READ;
|
|
|
|
procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
|
|
variable c : CHARACTER;
|
|
variable readOk : BOOLEAN;
|
|
variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then -- non Null input string
|
|
read (L, c, readOk);
|
|
i := 0;
|
|
while i < VALUE'length loop
|
|
if readOk = false then -- Bail out if there was a bad read
|
|
report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
|
|
& "End of string encountered"
|
|
severity error;
|
|
return;
|
|
elsif c = '_' then
|
|
if i = 0 then
|
|
report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
|
|
& "String begins with an ""_""" severity error;
|
|
return;
|
|
elsif lastu then
|
|
report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
|
|
& "Two underscores detected in input string ""__"""
|
|
severity error;
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
elsif char_to_MVL9plus(c) = error then
|
|
report
|
|
"STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) Error: Character '" &
|
|
c & "' read, expected STD_ULOGIC literal."
|
|
severity error;
|
|
return;
|
|
else
|
|
mv(i) := char_to_MVL9(c);
|
|
i := i + 1;
|
|
if i > mv'high then
|
|
VALUE := mv;
|
|
return;
|
|
end if;
|
|
lastu := false;
|
|
end if;
|
|
read(L, c, readOk);
|
|
end loop;
|
|
end if;
|
|
end procedure 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 procedure 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);
|
|
alias m : STD_ULOGIC_VECTOR(1 to VALUE'length) is 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 procedure WRITE;
|
|
|
|
procedure Char2TriBits (C : in CHARACTER;
|
|
RESULT : out STD_ULOGIC_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 'Z' => RESULT := "ZZZ"; GOOD := true;
|
|
when 'X' => RESULT := "XXX"; GOOD := true;
|
|
when others =>
|
|
assert not ISSUE_ERROR
|
|
report
|
|
"STD_LOGIC_1164.OREAD Error: Read a '" & C &
|
|
"', expected an Octal character (0-7)."
|
|
severity error;
|
|
GOOD := false;
|
|
end case;
|
|
end procedure Char2TriBits;
|
|
|
|
procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
|
|
GOOD : out BOOLEAN) is
|
|
variable ok : BOOLEAN;
|
|
variable c : CHARACTER;
|
|
constant ne : INTEGER := (VALUE'length+2)/3;
|
|
constant pad : INTEGER := ne*3 - VALUE'length;
|
|
variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then
|
|
read (L, c, ok);
|
|
i := 0;
|
|
while i < ne loop
|
|
-- Bail out if there was a bad read
|
|
if not ok then
|
|
GOOD := false;
|
|
return;
|
|
elsif c = '_' then
|
|
if i = 0 then
|
|
GOOD := false; -- Begins with an "_"
|
|
return;
|
|
elsif lastu then
|
|
GOOD := false; -- "__" detected
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
else
|
|
Char2TriBits(c, sv(3*i to 3*i+2), ok, false);
|
|
if not ok then
|
|
GOOD := false;
|
|
return;
|
|
end if;
|
|
i := i + 1;
|
|
lastu := false;
|
|
end if;
|
|
if i < ne then
|
|
read(L, c, ok);
|
|
end if;
|
|
end loop;
|
|
if or (sv (0 to pad-1)) = '1' then
|
|
GOOD := false; -- vector was truncated.
|
|
else
|
|
GOOD := true;
|
|
VALUE := sv (pad to sv'high);
|
|
end if;
|
|
else
|
|
GOOD := true; -- read into a null array
|
|
end if;
|
|
end procedure OREAD;
|
|
|
|
procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
|
|
variable c : CHARACTER;
|
|
variable ok : BOOLEAN;
|
|
constant ne : INTEGER := (VALUE'length+2)/3;
|
|
constant pad : INTEGER := ne*3 - VALUE'length;
|
|
variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then
|
|
read (L, c, ok);
|
|
i := 0;
|
|
while i < ne loop
|
|
-- Bail out if there was a bad read
|
|
if not ok then
|
|
report "STD_LOGIC_1164.OREAD "
|
|
& "End of string encountered"
|
|
severity error;
|
|
return;
|
|
elsif c = '_' then
|
|
if i = 0 then
|
|
report "STD_LOGIC_1164.OREAD "
|
|
& "String begins with an ""_""" severity error;
|
|
return;
|
|
elsif lastu then
|
|
report "STD_LOGIC_1164.OREAD "
|
|
& "Two underscores detected in input string ""__"""
|
|
severity error;
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
else
|
|
Char2TriBits(c, sv(3*i to 3*i+2), ok, true);
|
|
if not ok then
|
|
return;
|
|
end if;
|
|
i := i + 1;
|
|
lastu := false;
|
|
end if;
|
|
if i < ne then
|
|
read(L, c, ok);
|
|
end if;
|
|
end loop;
|
|
if or (sv (0 to pad-1)) = '1' then
|
|
report "STD_LOGIC_1164.OREAD Vector truncated"
|
|
severity error;
|
|
else
|
|
VALUE := sv (pad to sv'high);
|
|
end if;
|
|
end if;
|
|
end procedure OREAD;
|
|
|
|
procedure Char2QuadBits (C : CHARACTER;
|
|
RESULT : out STD_ULOGIC_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' | 'a' => RESULT := x"A"; GOOD := true;
|
|
when 'B' | 'b' => RESULT := x"B"; GOOD := true;
|
|
when 'C' | 'c' => RESULT := x"C"; GOOD := true;
|
|
when 'D' | 'd' => RESULT := x"D"; GOOD := true;
|
|
when 'E' | 'e' => RESULT := x"E"; GOOD := true;
|
|
when 'F' | 'f' => RESULT := x"F"; GOOD := true;
|
|
when 'Z' => RESULT := "ZZZZ"; GOOD := true;
|
|
when 'X' => RESULT := "XXXX"; GOOD := true;
|
|
when others =>
|
|
assert not ISSUE_ERROR
|
|
report
|
|
"STD_LOGIC_1164.HREAD Error: Read a '" & C &
|
|
"', expected a Hex character (0-F)."
|
|
severity error;
|
|
GOOD := false;
|
|
end case;
|
|
end procedure Char2QuadBits;
|
|
|
|
procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
|
|
GOOD : out BOOLEAN) is
|
|
variable ok : BOOLEAN;
|
|
variable c : CHARACTER;
|
|
constant ne : INTEGER := (VALUE'length+3)/4;
|
|
constant pad : INTEGER := ne*4 - VALUE'length;
|
|
variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then
|
|
read (L, c, ok);
|
|
i := 0;
|
|
while i < ne loop
|
|
-- Bail out if there was a bad read
|
|
if not ok then
|
|
GOOD := false;
|
|
return;
|
|
elsif c = '_' then
|
|
if i = 0 then
|
|
GOOD := false; -- Begins with an "_"
|
|
return;
|
|
elsif lastu then
|
|
GOOD := false; -- "__" detected
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
else
|
|
Char2QuadBits(c, sv(4*i to 4*i+3), ok, false);
|
|
if not ok then
|
|
GOOD := false;
|
|
return;
|
|
end if;
|
|
i := i + 1;
|
|
lastu := false;
|
|
end if;
|
|
if i < ne then
|
|
read(L, c, ok);
|
|
end if;
|
|
end loop;
|
|
if or (sv (0 to pad-1)) = '1' then
|
|
GOOD := false; -- vector was truncated.
|
|
else
|
|
GOOD := true;
|
|
VALUE := sv (pad to sv'high);
|
|
end if;
|
|
else
|
|
GOOD := true; -- Null input string, skips whitespace
|
|
end if;
|
|
end procedure HREAD;
|
|
|
|
procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
|
|
variable ok : BOOLEAN;
|
|
variable c : CHARACTER;
|
|
constant ne : INTEGER := (VALUE'length+3)/4;
|
|
constant pad : INTEGER := ne*4 - VALUE'length;
|
|
variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
|
|
variable i : INTEGER;
|
|
variable lastu : BOOLEAN := false; -- last character was an "_"
|
|
begin
|
|
VALUE := (VALUE'range => 'U'); -- initialize to a "U"
|
|
skip_whitespace (L);
|
|
if VALUE'length > 0 then -- non Null input string
|
|
read (L, c, ok);
|
|
i := 0;
|
|
while i < ne loop
|
|
-- Bail out if there was a bad read
|
|
if not ok then
|
|
report "STD_LOGIC_1164.HREAD "
|
|
& "End of string encountered"
|
|
severity error;
|
|
return;
|
|
end if;
|
|
if c = '_' then
|
|
if i = 0 then
|
|
report "STD_LOGIC_1164.HREAD "
|
|
& "String begins with an ""_""" severity error;
|
|
return;
|
|
elsif lastu then
|
|
report "STD_LOGIC_1164.HREAD "
|
|
& "Two underscores detected in input string ""__"""
|
|
severity error;
|
|
return;
|
|
else
|
|
lastu := true;
|
|
end if;
|
|
else
|
|
Char2QuadBits(c, sv(4*i to 4*i+3), ok, true);
|
|
if not ok then
|
|
return;
|
|
end if;
|
|
i := i + 1;
|
|
lastu := false;
|
|
end if;
|
|
if i < ne then
|
|
read(L, c, ok);
|
|
end if;
|
|
end loop;
|
|
if or (sv (0 to pad-1)) = '1' then
|
|
report "STD_LOGIC_1164.HREAD Vector truncated"
|
|
severity error;
|
|
else
|
|
VALUE := sv (pad to sv'high);
|
|
end if;
|
|
end if;
|
|
end procedure HREAD;
|
|
|
|
procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
|
|
JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
|
|
begin
|
|
write (L, TO_OSTRING(VALUE), JUSTIFIED, FIELD);
|
|
end procedure OWRITE;
|
|
|
|
procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
|
|
JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
|
|
begin
|
|
write (L, TO_HSTRING (VALUE), JUSTIFIED, FIELD);
|
|
end procedure HWRITE;
|
|
|
|
end package body std_logic_1164;
|