------------------------------------------------------------------------- -- -- (c) COPYRIGHT 1989 ZYCAD CORPORATION. -- This source file may be used and distributed without restriction -- provided that the copyright is not removed and that the code is -- not used or distributed for profit. -- -- File name: entities.vhd -- -- Purpose: A set of models (entity/architecture pairs) for the -- primitives of Zycad's Standard Logic library. -- -- Author: JT, PH, GWH -- -- NOTE: The TYPES and truth tables used by these entities are defined -- in the package ZYCAD.TYPES. -- The component declarations for the entities in this -- package appear in the package ZYCAD.COMPONENTS -- ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -- -- Primitive name: ANDGATE -- -- Purpose: An AND gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity ANDGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end ANDGATE; architecture A of ANDGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '1'; for j in Input'RANGE loop nextstate := table_AND(Input(j), nextstate); exit when nextstate = '0'; end loop; if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NANDGATE -- -- Purpose: A NAND gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NANDGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end NANDGATE; architecture A of NANDGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '1'; for j in Input'RANGE loop nextstate := table_AND(Input(j), nextstate); exit when nextstate = '0'; end loop; nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: ORGATE -- -- Purpose: An OR gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity ORGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end ORGATE; architecture A of ORGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '0'; for j in Input'RANGE loop nextstate := table_OR(Input(j), nextstate); exit when nextstate = '1'; end loop; if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NORGATE -- -- Purpose: A NOR gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NORGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end NORGATE; architecture A of NORGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '0'; for j in Input'RANGE loop nextstate := table_OR(Input(j), nextstate); exit when nextstate = '1'; end loop; nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: XORGATE -- -- Purpose: A XOR gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity XORGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end XORGATE; architecture A of XORGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '0'; for j in Input'RANGE loop nextstate := table_XOR(Input(j), nextstate); exit when nextstate = 'X'; end loop; if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NXORGATE -- -- Purpose: A NXOR gate for multiple value logic MVL4, -- N inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NXORGATE is generic (N: Positive := 2; -- number of inputs tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4_VECTOR (1 to N); -- inputs Output: out MVL4); -- output end NXORGATE; architecture A of NXORGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := '0'; for j in Input'RANGE loop nextstate := table_XOR(Input(j), nextstate); exit when nextstate = 'X'; end loop; nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: BUFGATE -- -- Purpose: A BUFFER gate for multiple value logic MVL4, -- 1 input, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity BUFGATE is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4; -- input Output: out MVL4); -- output end BUFGATE; architecture A of BUFGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_BUF(Input); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: INVGATE -- -- Purpose: An INVERTER (not) gate for multiple value logic MVL4, -- 1 input, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity INVGATE is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4; -- input Output: out MVL4); -- output end INVGATE; architecture A of INVGATE is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_NOT(Input); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: BUF3S -- -- Purpose: A TRISTATE BUFFER gate for multiple value logic MVL4, -- 1 input, 1 enable, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity BUF3S is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4; -- input Enable: in MVL4; -- enable Output: out MVL4); -- output end BUF3S; architecture A of BUF3S is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_BUF3S(Enable, Input); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "X1" => delta := tLH; when "10" | "1X" | "X0" => delta := tHL; when "0Z" => delta := tLH; when "Z0" => delta := tHL; when "1Z" => delta := tHL; when "Z1" => delta := tLH; when others => delta := 0 ns; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Enable, Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: INV3S -- -- Purpose: A TRISTATE INVERTER (not) gate for multiple value logic MVL4, -- 1 input, 1 enable, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity INV3S is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4; -- input Enable: in MVL4; -- enable Output: out MVL4); -- output end INV3S; architecture A of INV3S is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_NOT3S(Enable, Input); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "X1" => delta := tLH; when "10" | "1X" | "X0" => delta := tHL; when "0Z" => delta := tLH; when "Z0" => delta := tHL; when "1Z" => delta := tHL; when "Z1" => delta := tLH; when others => delta := 0 ns; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Enable, Input; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: KEEPER -- -- Purpose: A bus keeper -- -- Truth table: ----------------------------------------- -- | Input | 'X' '0' '1' 'Z' | -- ----------------------------------------- -- | Output| 'X' '0' '1' previous value | -- ----------------------------------------- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity KEEPER is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Input: in MVL4; -- input Output: out MVL4); -- output end KEEPER; architecture A of KEEPER is signal currentstate: MVL4 := 'X'; begin P: process variable delta: Time; begin -- compute delay case MVL4_VECTOR'(currentstate & Input) is when "XZ" | "ZX" | "00" | "11" | "XX" | "ZZ" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= Input after delta; Output <= Input after delta; -- wait for signal changes wait on Input until Input /= 'Z' and Input /= currentstate; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: MAJORITY -- -- Purpose: A MAJORITY gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for the truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity MAJORITY is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end MAJORITY; architecture A of MAJORITY is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_MJR(In1, In2, In3); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: MUX2x1 -- -- Purpose: A two inputs MULTIPLEXER for multiple value logic MVL4, -- 2 data inputs, 1 select input, 1 output. -- (see package ZYCAD.TYPES for the truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity MUX2x1 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In0, -- data input 0 In1, -- data input 1 Sel: in MVL4; -- select input Output: out MVL4); -- output end MUX2x1; architecture A of MUX2x1 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_MUX2x1(In1, Sel, In0); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In0, In1, Sel; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: DFF -- -- Purpose: A rising edge triggered D-flip-flop. -- -- Truth table: ------------------------------------- -- | Data Clock Reset | Output | -- ------------------------------------- -- | Data x U | 'X' | -- | Data U '0',U | 'X' | -- | Data x '1' | '0' | -- | Data '0'->'1' '0' | Data | -- | Data U ->'1' '0' | Data | -- ------------------------------------- -- x = don't care; U = 'X' or 'Z' -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity DFF is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Data, -- data input Clock, -- clock input Reset: in MVL4; -- reset input Output: out MVL4); -- output end DFF; architecture A of DFF is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function if (Reset = '1') then nextstate := '0'; elsif (Reset = '0' and Clock = '1' and Clock'EVENT) then nextstate := table_BUF (Data); elsif (Reset ='X' or Reset ='Z' or Clock ='X' or Clock='Z') then nextstate := 'X'; end if; if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Clock, Reset; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: DLATCH -- -- Purpose: A level sensitive D_latch. -- -- Truth table: ------------------------------------- -- | Data Enable Reset | Output | -- ------------------------------------- -- | Data x U | 'X' | -- | Data U '0',U | 'X' | -- | Data x '1' | '0' | -- | Data '1' '0' | Data | -- ------------------------------------- -- x = don't care; U = 'X' or 'Z' -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity DLATCH is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Data, -- data input Enable, -- enable input Reset: in MVL4; -- reset input Output: out MVL4); -- output end DLATCH; architecture A of DLATCH is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function if (Reset = '1') then nextstate := '0'; elsif (Reset = '0' and Enable = '1') then nextstate := table_BUF (Data); elsif (Reset='X' or Reset='Z' or Enable='X' or Enable='Z') then nextstate := 'X'; end if; if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on Data, Enable, Reset; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: REG_EDGE -- -- Purpose: An N-bit edge triggered register. -- -- Truth table: ------------------------------------- -- | Data Clock Reset | Output | -- ------------------------------------- -- | Data x U | 'X' | -- | Data U '0',U | 'X' | -- | Data x '1' | '0' | -- | Data '0'->'1' '0' | Data | -- | Data U ->'1' '0' | Data | -- ------------------------------------- -- x = don't care; U = 'X' or 'Z' -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity REG_EDGE is generic (N: Positive :=1; -- N bit register tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Data: in MVL4_VECTOR (N-1 downto 0); -- data input Clock, -- clock input Reset: in MVL4; -- reset input Output: out MVL4_VECTOR (N-1 downto 0)); -- output end REG_EDGE; architecture A of REG_EDGE is signal currentstate: MVL4_VECTOR (Data'RANGE); begin P: process variable nextstate: MVL4_VECTOR (Data'RANGE); variable delta: Time := 0 ns; begin -- evaluate logical function if (Reset = '1') then nextstate := (others => '0'); elsif (Reset = '0' and Clock = '1' and Clock'EVENT) then for i in Data'RANGE loop nextstate(i) := table_BUF(Data(i)); end loop; elsif (Reset ='X' or Reset ='Z' or Clock ='X' or Clock='Z') then nextstate := (others => 'X'); end if; if (nextstate /= currentstate) then -- compute delay for i in Data'RANGE loop case MVL4_VECTOR'(currentstate(i) & nextstate(i) ) is when "00" | "11" | "XX" | "ZZ" => next; when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate(i) <= nextstate(i) after delta; Output(i) <= nextstate(i) after delta; end loop; end if; -- wait for signal changes wait on Clock, Reset; end process P; end A; -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NXOR4 -- -- Purpose: A NXOR gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NXOR4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end NXOR4; architecture A of NXOR4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); nextstate := table_XOR(In3, nextstate); nextstate := table_XOR(In4, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: REG_LEVEL -- -- Purpose: A N-bit level sensitive register. -- -- Truth table: ------------------------------------- -- | Data Enable Reset | Output | -- ------------------------------------- -- | Data x U | 'X' | -- | Data U '0',U | 'X' | -- | Data x '1' | '0' | -- | Data '1' '0' | Data | -- ------------------------------------- -- x = don't care; U = 'X' or 'Z' -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity REG_LEVEL is generic (N: Positive :=1; -- N bit register tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (Data: in MVL4_VECTOR (N-1 downto 0); -- data input Enable, -- enable input Reset: in MVL4; -- reset input Output: out MVL4_VECTOR (N-1 downto 0)); -- output end REG_LEVEL; architecture A of REG_LEVEL is signal currentstate: MVL4_VECTOR (Data'RANGE); begin P: process variable nextstate: MVL4_VECTOR (Data'RANGE); variable delta: Time := 0 ns; begin -- evaluate logical function if (Reset = '1') then nextstate := (others => '0'); elsif (Reset = '0' and Enable = '1') then for i in Data'RANGE loop nextstate(i) := table_BUF(Data(i)); end loop; elsif (Reset='X' or Reset='Z' or Enable='X' or Enable='Z') then nextstate := (others => 'X'); end if; if (nextstate /= currentstate) then -- compute delay for i in Data'RANGE loop case MVL4_VECTOR'(currentstate(i) & nextstate(i) ) is when "00" | "11" | "XX" | "ZZ" => next; when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate(i) <= nextstate(i) after delta; Output(i) <= nextstate(i) after delta; end loop; end if; -- wait for signal changes wait on Data, Enable, Reset; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: RAM_EDGE -- -- Purpose: An edge sensitive random access memory model. -- -- Function: -- Illegal conditions which cause the ERR port to be set to '1': -- 1) Any undefined levels within an address during -- a read or write operation. No data are placed on -- in memory during a write operation. Undefined -- levels ('X') appear at the outputs on the trailing -- edge of a read operation. -- -- 2) Attempting to write data containing undefined -- levels to a memory specified as not allowing them -- will produce unpredictable levels for the -- undefined levels. -- -- 3) Asserting more than one of R, W, and INIT. -- The effect on the memory and output is -- unpredictable. -- -- The ERR port is reset to '0' after any legal operation. -- -- Truth table for transitions on W: -- ------------------------------------------------------------ -- | W | Action -- |----------------------------------------------------------- -- | '0',U->'1' | Write the data present on the data lines -- | | to the location specified by the address -- | | lines. -- | | -- | '0'-> U | Write undefined ('X') levels (for those -- | | memories that allow them, otherwise '0') -- | | to the location specified by the address -- | | lines. ERR is set to '1'. -- ------------------------------------------------------------ -- | else | None. -- ------------------------------------------------------------ -- U = 'X' or 'Z' -- -- Truth table for transitions on R: -- ------------------------------------------------------------ -- | R | Action -- |----------------------------------------------------------- -- | '0',U->'1' | Read the location specified by the address -- | | lines and move the addressed data to the -- | | output hold register. -- | | -- | '1'->'0' | Data in the output hold register are -- | | available on the output data lines. -- | | -- | '0'-> U | Set ERR to '1'. -- | | -- | '1'-> U | Undefined levels ('X') are available on -- | | the output data lines. ERR is set to '1'. -- ------------------------------------------------------------ -- | else | None. -- ------------------------------------------------------------ -- U = 'X' or 'Z' -- -- Truth table for transitions on INIT: -- ------------------------------------------------------------ -- | INIT | Action -- |----------------------------------------------------------- -- | '0',U->'1' | Write data from the data input lines to -- | | every location in the memory model. -- | | -- | '0'-> U | Write 'X', or '0' if 'X' is not permitted -- | | to every location in the memory. -- | | ERR is set to '1'. -- | | the output data lines. ERR is set to '1'. -- ------------------------------------------------------------ -- | else | None. -- ------------------------------------------------------------ -- U = 'X' or 'Z' -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; use ZYCAD.BV_ARITHMETIC.all; entity RAM_EDGE is generic (Ndata: Positive; -- # of data lines Naddr: Positive; -- # of address lines UndefFlag: Boolean := FALSE); -- TRUE => undef.val.ok port (DATAin: in MVL4_VECTOR (Ndata-1 downto 0); -- data in lines DATAout: out MVL4_VECTOR (Ndata-1 downto 0); -- data out lines ADDR: in MVL4_VECTOR (Naddr-1 downto 0); -- address lines INIT, -- initial control line W, -- write control line R: in MVL4; -- read control line ERR: out MVL4 := '0'); -- error flag end RAM_EDGE; architecture A of RAM_EDGE is begin P: process type MEMTYPE is array (0 to 2**ADDR'LENGTH-1) of MVL4_VECTOR(DATAin'RANGE); variable memory: MEMTYPE := (others => (others => '0')); variable bValid: BOOLEAN; variable iADDR: integer; variable temp, outhold: MVL4_VECTOR(DATAin'RANGE); variable eflag: MVL4; begin -- The variable memory and the port DATAout are correctly -- initialized at elaboration time. This makes it best to -- wait at the top of the process. wait on R, W, INIT; -- Read cycle if R'EVENT then if R = '1' then bValid := TRUE; for i in ADDR'RANGE loop if ADDR(i) /= '0' and ADDR(i) /= '1' then bValid := FALSE; exit; end if; end loop; if bValid then outhold := memory(BVtoI(MVL4VtoBV(ADDR))); ERR <= '0'; else outhold := (others => 'X'); ERR <= '1'; end if; elsif R = '0' and R'LAST_VALUE = '1' then DATAout <= outhold; elsif R = 'X' or R = 'Z' then ERR <= '1'; if R'LAST_VALUE = '1' then DATAout <= (others => 'X'); end if; end if; end if; -- write cycle if W'EVENT then if W = '1' then bValid := TRUE; for i in ADDR'RANGE loop if ADDR(i) /= '1' and ADDR(i) /= '0' then bValid := FALSE; exit; end if; end loop; if bValid then iADDR := BVtoI(MVL4VtoBV(ADDR)); if UndefFlag then ERR <= '0'; memory(iADDR) := Drive(DATAin); else eflag := '0'; for i in DATAin'RANGE loop if DATAin(i) = '0' or DATAin(i) = '1' then memory(iADDR)(i) := DATAin(i); else eflag := '1'; -- keep current value =>undef end if; end loop; ERR <= eflag; end if; else ERR <= '1'; end if; elsif (W = 'X' or W = 'Z') and W'LAST_VALUE = '0' then ERR <= '1'; bValid := TRUE; for i in ADDR'RANGE loop if ADDR(i) /= '1' and ADDR(i) /= '0' then bValid := FALSE; exit; end if; end loop; if bValid then if UndefFlag then memory(BVtoI(MVL4VtoBV(ADDR))) := (others => 'X'); else memory(BVtoI(MVL4VtoBV(ADDR))) := (others => '0'); end if; end if; end if; end if; -- initialization cycle if INIT'EVENT then if INIT = '1' then eflag := '0'; if UndefFlag then temp := Drive(DATAin); else for j in DATAin'RANGE loop if DATAin(j) = '0' or DATAin(j) = '1' then temp(j) := DATAin(j); else temp(j) := '0'; eflag := '1'; end if; end loop; end if; ERR <= eflag; for i in memory'RANGE loop memory(i) := temp; end loop; elsif (INIT = 'X' or INIT = 'Z') and INIT'LAST_VALUE = '0' then ERR <= '1'; if UndefFlag then temp := (others => 'X'); else temp := (others => '0'); end if; for i in memory'RANGE loop memory(i) := temp; end loop; end if; end if; -- Check to make sure read/write/init cycles are mutually exclusive if (R = '1' and (W ='1' or INIT ='1')) or (W = '1' and (R ='1' or INIT ='1')) or (INIT = '1' and (R ='1' or W ='1')) then ERR <= '1'; end if; end process; end A; ---------------------------------------------------------------------------- -- -- Primitive name: RAM_LEVEL -- -- Purpose: A level sensitive random access memory model. -- -- Function: -- VHDL Assertions are raised under the following conditions: -- 1) ADDR changes while RW = '1'. -- -- 2) One of the elements of ADDR is 'X' or 'Z' -- while RW is '1'. In this case the memory -- contents remain unchanged, and DATAout becomes -- 'X'. -- -- If RW = 'X' then the location specified by ADDR is updated -- with 'X'. DATAout has 'X' placed on it. -- -- If RW = '0' then the contents of the location specified -- by ADDR are available on DATAout. -- -- If RW = '1' then the memory location specified by ADDR is -- updated with DATAin. DATAin is available on DATAout. -- -- If CE /= '1' then ADDR, DATAin, and RW are ignored(chip enable). -- DATAout has 'X' placed on it. -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; use ZYCAD.BV_ARITHMETIC.all; entity RAM_LEVEL is generic (Ndata: Positive; -- # of data lines Naddr: Positive); -- # of address lines port (DATAin: in MVL4_VECTOR(Ndata-1 downto 0); -- data in lines DATAout: out MVL4_VECTOR(Ndata-1 downto 0); -- data out lines ADDR: in MVL4_VECTOR(Naddr-1 downto 0); -- address lines CE: in MVL4; -- chip enable(act.high) RW: in MVL4); -- read (active low) and -- write (active high) end RAM_LEVEL; architecture A of RAM_LEVEL is begin -- -- assertion for changes in address lines -- Assertion: process begin assert not(RW = '1' and CE = '1' and ADDR'EVENT) report "Address lines changed while RAM is Write Enabled" severity WARNING; wait on CE, RW, ADDR; end process; -- -- the memory model -- P: process subtype ETYPE is MVL4_VECTOR(DATAin'RANGE); type MEMTYPE is array (Natural range <>) of ETYPE; variable m: MEMTYPE(0 to 2**ADDR'length-1); procedure do_read is begin for i in ADDR'RANGE loop if ADDR(i) = 'X' or ADDR(i) = 'Z' then DATAout <= (others => 'X'); return; end if; end loop; DATAout <= m(BVtoI(MVL4VtoBV(ADDR))); end do_read; procedure do_write(data: ETYPE) is begin for i in ADDR'RANGE loop if ADDR(i) = 'X' or ADDR(i) = 'Z' then assert false report "Attempted write to bad RAM address" severity WARNING; DATAout <= (others => 'X'); return; end if; end loop; m(BVtoI(MVL4VtoBV(ADDR))) := data; DATAout <= data; end do_write; begin -- The variable m and the port DATAout are initialized correctly -- at elaboration time. This makes it best to wait at the top -- of the process. wait on CE, RW, DATAin, ADDR; if ( CE = '1' ) then if DATAin'EVENT and RW = '1' then do_write(Drive(DATAin)); elsif ADDR'EVENT and RW /= 'X' and RW /= 'Z' then if RW = '1' then do_write(Drive(DATAin)); else do_read; end if; elsif RW'EVENT then if RW = '1' then do_write(Drive(DATAin)); elsif RW = '0' then do_read; else do_write((DATAin'RANGE => 'X')); end if; end if; else DATAout <= (others => 'X'); end if; end process; end A; ---------------------------------------------------------------------------- -- -- Primitive name: AND2 -- -- Purpose: An AND gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity AND2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end AND2; architecture A of AND2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_AND(In1, In2); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: AND3 -- -- Purpose: An AND gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity AND3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end AND3; architecture A of AND3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_AND(In1, In2); nextstate := table_AND(In3, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: AND4 -- -- Purpose: An AND gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity AND4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end AND4; architecture A of AND4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_AND(In1, In2); nextstate := table_AND(In3, nextstate); nextstate := table_AND(In4, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NAND2 -- -- Purpose: A NAND gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NAND2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end NAND2; architecture A of NAND2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_NOT(table_AND(In1, In2)); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NAND3 -- -- Purpose: A NAND gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NAND3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end NAND3; architecture A of NAND3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_AND(In1, In2); nextstate := table_AND(In3, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NAND4 -- -- Purpose: A NAND gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NAND4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end NAND4; architecture A of NAND4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_AND(In1, In2); nextstate := table_AND(In3, nextstate); nextstate := table_AND(In4, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: OR2 -- -- Purpose: An OR gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity OR2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end OR2; architecture A of OR2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_OR(In1, In2); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: OR3 -- -- Purpose: An OR gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity OR3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end OR3; architecture A of OR3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_OR(In1, In2); nextstate := table_OR(In3, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: OR4 -- -- Purpose: An OR gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity OR4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end OR4; architecture A of OR4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_OR(In1, In2); nextstate := table_OR(In3, nextstate); nextstate := table_OR(In4, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NOR2 -- -- Purpose: A NOR gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NOR2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end NOR2; architecture A of NOR2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_NOT(table_OR(In1, In2)); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NOR3 -- -- Purpose: A NOR gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NOR3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end NOR3; architecture A of NOR3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_OR(In1, In2); nextstate := table_OR(In3, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NOR4 -- -- Purpose: A NOR gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NOR4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end NOR4; architecture A of NOR4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_OR(In1, In2); nextstate := table_OR(In3, nextstate); nextstate := table_OR(In4, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: XOR2 -- -- Purpose: A XOR gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity XOR2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end XOR2; architecture A of XOR2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: XOR3 -- -- Purpose: A XOR gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity XOR3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end XOR3; architecture A of XOR3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); nextstate := table_XOR(In3, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: XOR4 -- -- Purpose: A XOR gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity XOR4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end XOR4; architecture A of XOR4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); nextstate := table_XOR(In3, nextstate); nextstate := table_XOR(In4, nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NXOR2 -- -- Purpose: A NXOR gate for multiple value logic MVL4, -- 2 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NXOR2 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2: in MVL4; -- inputs Output: out MVL4); -- output end NXOR2; architecture A of NXOR2 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_NOT(table_XOR(In1, In2)); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NXOR3 -- -- Purpose: A NXOR gate for multiple value logic MVL4, -- 3 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NXOR3 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3: in MVL4; -- inputs Output: out MVL4); -- output end NXOR3; architecture A of NXOR3 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); nextstate := table_XOR(In3, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3; end process P; end A; ---------------------------------------------------------------------------- -- -- Primitive name: NXOR4 -- -- Purpose: A NXOR gate for multiple value logic MVL4, -- 4 inputs, 1 output. -- (see package ZYCAD.TYPES for truth table) -- ---------------------------------------------------------------------------- library ZYCAD; use ZYCAD.TYPES.all; entity NXOR4 is generic (tLH: Time := 0 ns; -- rise inertial delay tHL: Time := 0 ns); -- fall inertial delay port (In1, In2, In3, In4: in MVL4; -- inputs Output: out MVL4); -- output end NXOR4; architecture A of NXOR4 is signal currentstate: MVL4 := 'X'; begin P: process variable nextstate: MVL4; variable delta: Time; begin -- evaluate logical function nextstate := table_XOR(In1, In2); nextstate := table_XOR(In3, nextstate); nextstate := table_XOR(In4, nextstate); nextstate := table_NOT(nextstate); if (nextstate /= currentstate) then -- compute delay case MVL4_VECTOR'(currentstate & nextstate) is when "XZ" | "ZX" => delta := 0 ns; when "01" | "0X" | "0Z" | "X1" | "Z1" => delta := tLH; when others => delta := tHL; end case; -- assign new value after internal delay currentstate <= nextstate after delta; Output <= nextstate after delta; end if; -- wait for signal changes wait on In1, In2, In3, In4; end process P; end A;