-- Synthesis support functions
--
-- Version 1.0 Revised by: Jay Southard & Andy Tsay 18 Oct 91.
--    Added pla_table procedure for VdesII.
-- Version 1.0 Revised by: Rick Sullivan on 23 Apr 90.
--    Modified storage elements with asynchronous presets and clears.
--    Preset no longer takes priority over clear; if both are asserted
--    simultaneously, the q output goes to the unknown state. This
--    change was made because various target technologies handle this
--    situation differently.
--
-- Version 1.0 Revised by: Rick Sullivan on 18 Mar 90.
--    Added:
--        Trstmem
--        Pullup
--        Pulldn
--
-- Version 0.5 Revised by: Don Gay on 10/17/89
--    Changed the name to stdsynth (new name agreed on).
--
-- Version 0.4   Revised by: Don Gay  On: 10/6/89
--    Changed the Data input of the single bit flipflops and latches of
--    Dtype to Constant from Single so that they can be passed slices.
--
-- Version 0.3   Revised by: Don Gay  On: 9/13/89
--
--    This file was revised to:
--
--       Add additional agreed on Storage elements
--          DLATCH*
--          SRLATCH
--
--
-- Version 0.2   Revised by: Don Gay  On: 8/23/89
--
--    This file was revised to:
--
--          handle X and Z input values correctly
--          Add all the agreed on Storage elements
--          Produce warning messages when reset and set change at the
--             same time as clock.
--    
-- 
-- Note:
--
--       These definitions are used for simulation ONLY.
--       Modifying these functions will NOT affect the synthesis.
--
--
-- **********************************************************
-- Define the interface to these routines
-- **********************************************************
--
PACKAGE stdsynth IS

-- Pullup resistor
--
   PROCEDURE pullup (
      SIGNAL   d        : INOUT VLBIT);

-- Pulldown resistor
--
   PROCEDURE pulldn (
      SIGNAL   d        : INOUT VLBIT);

-- Tristate Latch
--    Remembers last driven bus state. When the bus is undriven, and
--    'wants' to float to the high impedance state, this device drives
--    the bus to the last driven state.
--
   PROCEDURE trstmem (
      SIGNAL   d        : INOUT VLBIT);
 
-- D type flip flop 
--    positive edge triggered
--    no preset or clear 
--
   PROCEDURE dff (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type flip flop
--    positive edge triggered
--    async. clear (active high) 
--
   PROCEDURE dffc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type flip flop
--    positive edge triggered
--    async. preset (active high)
--
   PROCEDURE dffp (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type flip flop
--    positive edge triggered
--    async. clear and preset (active high)
--
   PROCEDURE dffpc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    no clear or preset
--
   PROCEDURE dff_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. clear (active high) 
--
   PROCEDURE dffc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. preset (active high) 
--
   PROCEDURE dffp_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. clear and preset (active high) 
--
   PROCEDURE dffpc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type latch 
--    positive transparent
--
   PROCEDURE dlatch (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type latch 
--    positive transparent
--    async. clear (active high)
--
   PROCEDURE dlatchc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type latch 
--    positive transparent
--    async. preset (active high)
--
   PROCEDURE dlatchp (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type latch 
--    positive transparent
--    async. clear and preset (active high)
--
   PROCEDURE dlatchpc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- D type latch vectored register
--    positive transparent
--
   PROCEDURE dlatch_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type latch vectored register
--    positive transparent
--    async. clear (active high)
--
   PROCEDURE dlatchc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;   
      SIGNAL   clear    :  IN    VLBIT;
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type latch vectored register
--    positive transparent
--    async. preset (active high)
--
   PROCEDURE dlatchp_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;   
      SIGNAL   preset   :  IN    VLBIT;
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- D type latch vectored register
--    positive transparent
--    async. clear and preset (active high)
--
   PROCEDURE dlatchpc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;   
      SIGNAL   preset   :  IN    VLBIT;
      SIGNAL   clear    :  IN    VLBIT;
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR);


-- SR latch
--
   PROCEDURE srlatch (
      SIGNAL   set      :  IN    VLBIT;
      SIGNAL   reset    :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- JK flip flop
--    positive edge triggered
--    no clear or preset
--
   PROCEDURE jkff (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- JK flip flop
--    positive edge triggered
--    async. clear (active high)
--
   PROCEDURE jkffc (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- JK flip flop
--    positive edge triggered
--    async. preset (active high)
--
   PROCEDURE jkffp (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);


-- JK flip flop
--    positive edge triggered
--    async. clear and preset (active high)
--
   PROCEDURE jkffpc (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT);

--     pla_table  - Oct 18, 1991 Andy Tsay
    procedure pla_table(         I: in  vlbit_1d;
                          signal O: out vlbit_1d;
                               tbl: in  vlbit_2d);


END stdsynth;


-- **********************************************************
-- Define the functions
-- **********************************************************
--
PACKAGE BODY stdsynth IS
--

-- Pullup resistor
--
  PROCEDURE pullup (
      SIGNAL d          : INOUT VLBIT)
  IS
  BEGIN
       -- NOTE: Don't assign 'z' to 'd' if 'd' is '1', otherwise
       -- a zero delay loop will occur if the bus is undriven
       -- by anything else.
       IF BITZ(d) THEN d <= '1';
       ELSIF BITX(d) THEN d <= 'Z';
       END IF;
  END pullup;

-- Pulldown resistor
--
  PROCEDURE pulldn (
      SIGNAL d          : INOUT VLBIT)
  IS
  BEGIN
       -- NOTE: Don't assign 'z' to 'd' if 'd' is '0', otherwise
       -- a zero delay loop will occur if the bus is undriven
       -- by anything else.
       IF BITZ(d) THEN d <= '0';
       ELSIF BITX(d) THEN d <= 'Z';
       END IF;
  END pulldn;

-- Tristate latch
--    Remembers last driven bus state. When the bus is undriven, and
--    'wants' to float to the high impedance state, this device drives
--    the bus to the last driven state.
--    NOTE: 
--        (1) This procedure is implemented as a 'concurrent procedure'
--            so that it can have internal memory.
--        (2) There are two serious deficiencies of this implementation of
--            trstmem. First, when trstmem is driving the bus, it looks
--            for an 'X' on the bus before it relinquishes control. When
--            'trstmem' is not driving the bus, it looks for a 'Z' before
--            it drives the previous bus state onto the bus. Thus, 'X' and
--            'Z' glitches occur. THIS SITUATION COULD BE FIXED IF WE HAD
--            STRENGTH INFORMATION IN SIGNAL VALUE ENCODINGS.
--            Second, 'trstmem' cannot remember unknown bus states. This
--            because 'trstmem' can never output an unknown onto the bus,
--            since it uses unknown to sense when it should relinquish
--            control. Thus if the bus is driven to X, and then all the
--            drivers turn off, 'trstmem' should in theory output an X.
--            Instead, it outputs the last non-unknown driven value.
  PROCEDURE trstmem (
      SIGNAL d          : INOUT VLBIT)
  IS
  -- The 'last_known_value' of the bus cannot be X.
  -- If it were X, and the bus happened to come
  -- up with no drivers (i.e. 'Z'), trstmem would
  -- oscillate.
  VARIABLE last_known_value: VLBIT := '0';
  BEGIN
    WHILE TRUE LOOP
       -- If the Bus is being driven by a known value, 'remember' it.
       IF d = '0' THEN last_known_value := '0';
       ELSIF d = '1' THEN last_known_value := '1';
       -- If the Bus is undriven by anybody else, drive it to
       -- the last driven value.
       ELSIF BITZ(d) THEN 
          d <= last_known_value;
       -- Otherwise, the bus must be X. This means either (1) two other
       -- drivers are in conflict (probably circuit error), or (2) 'trstmem'
       -- and another driver are in conflict (i.e. the bus transitioned from
       -- a state in which 'trstmem' was the only driver to a state in which
       -- 'trstmem' and another driver are in conflict). Let the other 
       -- driver(s) have control.
       ELSE 
          d <= 'Z';
       END IF;
       WAIT ON d;   
       END LOOP;

  END trstmem;

-- D type flip flop 
--    positive edge triggered
--    no preset or clear 
--
   PROCEDURE dff (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF bitz(clk) THEN
         q <= (data and data);
      ELSIF (bitunknown(clk) and not(q = data)) THEN
         q <= 'X';
      ELSIF prising(clk) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dff;


-- D type flip flop
--    positive edge triggered
--    async. clear (active high) 
--
   PROCEDURE dffc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On DFFC: Clk and Clear both changing - Clk action suppressed";

      IF clear = '1' THEN
         q <= '0';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (bitunknown(clk) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(clear))) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dffc;


-- D type flip flop
--    positive edge triggered
--    async. preset (active high)
--
   PROCEDURE dffp (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN
      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On DFFP: Clk and Preset both changing - Clk action suppressed";

      IF preset = '1' THEN
         q <= '1';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(clk) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(preset))) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dffp;


-- D type flip flop
--    positive edge triggered
--    async. clear and preset (active high)
--
   PROCEDURE dffpc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN
      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On DFFPC: Clk and Preset both changing - Clk action suppressed";

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On DFFPC: Clk and Clear both changing - Clk action suppressed";

--      ASSERT not( pfalling(clear) and pfalling(preset))
--         REPORT "On DFFPC: Preset and clear both released at same time";

      IF clear /= '0' AND preset /= '0' THEN 
         q <= 'X';
      ELSIF preset = '1' AND clear = '0' THEN
         q <= '1';
      ELSIF clear = '1' AND preset = '0' THEN
         q <= '0';
--    ELSIF (pfalling(clear) and pfalling(preset)) THEN
--       q <= 'X';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (bitunknown(clk) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(clear) or pchanging(preset))) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dffpc;



-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    no clear or preset
--
   PROCEDURE dff_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN
      IF bitz(clk) THEN
         q <= (data and data);
      ELSIF (bitx(clk) and not(q = data)) THEN
         q <= extend2c(B"X",data'length);
      ELSIF (prising(clk)) THEN
         q <= (data and data);
      END IF;
   END dff_v;


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. clear (active high) 
--
   PROCEDURE dffc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On DFFC_V: Clk and Clear both changing - Clk action suppressed";


      IF clear = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))) );
      ELSIF ((bitunknown(clear) and 
              not(q =(vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))))))  ) or 
             (bitx(clk) and not(q = data))) THEN
               q <= extend2c(B"X",data'length);
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(clear))) THEN
         q <= (data and data);
      END IF;
   END dffc_v;


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. preset (active high) 
--
   PROCEDURE dffp_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On DFFP_V: Clk and Preset both changing - Clk action suppressed";

      IF preset = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))) );
      ELSIF ((bitunknown(preset) and 
               not(q = (vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))))))  ) or
             (bitx(clk) and not(q = data)))  THEN
               q <= extend2c(B"X",data'length);
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(preset))) THEN
         q <= (data and data);
      END IF;
   END dffp_v;


-- D type flip flop vectored register
--    register is width of passed data vector 
--    positive edge triggered
--    async. clear and preset (active high) 
--
   PROCEDURE dffpc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On DFFPC_V: Clk and Preset both changing - Clk action suppressed";

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On DFFPC_V: Clk and Clear both changing - Clk action suppressed";

--      ASSERT not( pfalling(clear) and pfalling(preset))
--         REPORT "On DFFPC: Preset and clear both released at same time";

      IF preset /= '0' AND clear /= '0' THEN
         q <= extend2c(B"X", data'length);
      ELSIF preset = '1' AND clear = '0' THEN
         q <= vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))) );
      ELSIF clear = '1' AND preset = '0' THEN
         q <= vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))) );
      ELSIF ((bitunknown(preset) and not(q = (vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))))) )) or
             (bitunknown(clear) and not(q = (vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))))) )) or
             (bitx(clk) and not(q = data)) or
             (pfalling(clear) and pfalling(preset))) THEN
               q <= extend2c(B"X",data'length);
      ELSIF bitz(clk) THEN
         q <= (data and data);
      ELSIF (prising(clk) and not(pchanging(clear) or pchanging(preset))) THEN
         q <= (data and data);
      END IF;
   END dffpc_v;



-- DLATCH
--    positive transparent
--    async. clear (active high)
--
   PROCEDURE dlatch (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF (bitunknown(gate) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (gate = '1' ) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dlatch;



-- DLATCH
--    positive transparent
--    async. clear (active high)
--
   PROCEDURE dlatchc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF clear = '1' THEN
         q <= '0';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (bitunknown(gate) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (bitunknown(data) and (gate = '1')) THEN
         q <= 'X';
      ELSIF (gate = '1' ) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dlatchc;



-- DLATCH
--    positive transparent
--    async. preset (active high)
--
   PROCEDURE dlatchp (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF preset = '1' THEN
         q <= '1';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(gate) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (bitunknown(data) and (gate = '1')) THEN
         q <= 'X';
      ELSIF (gate = '1' ) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dlatchp;



-- DLATCH
--    positive transparent
--    async. clear and preset (active high)
--
   PROCEDURE dlatchpc (
      CONSTANT data     :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF preset /= '0' and clear /= '0' THEN
         q <= 'X';
      ELSIF preset = '1' THEN
         q <= '1';
      ELSIF clear = '1' THEN
         q <= '0';
--      ELSIF (pfalling(clear) and pfalling(preset) and (gate /= '0')) THEN
--         q <= 'X';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (bitunknown(gate) and not(q = data)) THEN
         q <= 'X';
      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (bitunknown(data) and (gate = '1')) THEN
         q <= 'X';
      ELSIF (gate = '1' ) THEN
         q <= (data and data);
            -- NOTE: The AND in the above lines handles the case where 
            --       data is a Z.  We want Q to be assigned to X.
      END IF;
   END dlatchpc;



-- D type latch vectored register
--    register is width of passed data vector 
--    positive transparent
--
   PROCEDURE dlatch_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      IF (bitx(gate) and not(q = data)) THEN
               q <= extend2c(B"X",data'length);

      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (gate = '1') THEN
         q <= (data and data);
      END IF;
   END dlatch_v;



-- D type latch vectored register
--    register is width of passed data vector 
--    positive transparent
--    async. clear (active high) 
--
   PROCEDURE dlatchc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      IF clear = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))) );
      ELSIF ((bitunknown(clear) and not(q = (vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))))) )) or
             (vecunknown(data) and (gate = '1')) or
             (bitx(gate) and not(q = data)) ) THEN
               q <= extend2c(B"X",data'length);
      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (gate = '1') THEN
         q <= (data and data);
      END IF;
   END dlatchc_v;



-- D type latch vectored register
--    register is width of passed data vector 
--    positive transparent
--    async. preset (active high) 
--
   PROCEDURE dlatchp_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      IF preset = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))) );
      ELSIF ((bitunknown(preset) and not(q = (vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))))) )) or
             (vecunknown(data) and (gate = '1')) or
             (bitx(gate) and not(q = data)) ) THEN
                q <= extend2c(B"X",data'length);

      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (gate = '1') THEN
         q <= (data and data);
      END IF;
   END dlatchp_v;



-- D type latch vectored register
--    register is width of passed data vector 
--    positive transparent
--    async. clear and preset (active high) 
--
   PROCEDURE dlatchpc_v (
      CONSTANT data     :  IN    VLBIT_VECTOR;  
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   gate     :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT_VECTOR)
   IS 

   BEGIN

      IF clear /= '0' and preset /= '0' THEN
         q <= extend2c(B"X", data'length);
      ELSIF preset = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))) );
      ELSIF clear = '1' THEN
         q <= vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))) );
      ELSIF ((bitunknown(preset) and not(q = (vlbit_VECTOR( boolean_1D (data) or (not (boolean_1D (data))))) )) or
             (bitunknown(clear) and not(q = (vlbit_VECTOR( boolean_1D (data) and (not (boolean_1D (data))))) )) or
             (vecunknown(data) and (gate = '1')) or
             (bitx(gate) and not(q = data)) or
             (pfalling(clear) and pfalling(preset))) THEN
                q <= extend2c(B"X",data'length);

      ELSIF bitz(gate) THEN
         q <= (data and data);
      ELSIF (gate = '1') THEN
         q <= (data and data);
      END IF;
   END dlatchpc_v;



-- SR LATCH
--    positive transparent
--    async. clear and preset (active high)
--
   PROCEDURE srlatch (
      SIGNAL   set      :  IN    VLBIT;   
      SIGNAL   reset    :  IN    VLBIT;   
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      ASSERT not( pfalling(reset) and pfalling(set))
         REPORT "On SRLATCH: Set and reset both released at same time";

      IF set = '1' THEN
         q <= '1';
      ELSIF reset = '1' THEN
         q <= '0';
      ELSIF (pfalling(reset) and pfalling(set)) THEN
         q <= 'X';
      ELSIF (bitunknown(reset) and bitunknown(set)) THEN
         q <= 'X';
      ELSIF (bitunknown(set) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(reset) and not(q = '0')) THEN
         q <= 'X';
      END IF;
   END srlatch;



-- JK flip flop
--    positive edge triggered
--    no clear or preset
--
   PROCEDURE jkff (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      IF (bitunknown(clk)) THEN
         q <= 'X';
      ELSIF prising (clk) THEN

         IF (j = '1' AND k = '1') THEN
            q <= NOT q;
         ELSIF (j = '1' AND k = '0') THEN
            q <= '1';
         ELSIF (j = '0' AND k = '1') THEN
            q <= '0';
         ELSIF (bitunknown(j) OR bitunknown(k)) THEN
            q <= 'X';
         END IF;
      END IF;
   END jkff;


-- JK flip flop
--    positive edge triggered
--    async. clear (active high)
--
   PROCEDURE jkffc (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On JKFFC: Clk and Clear both changing - Clk action suppressed";


      IF clear = '1' THEN
         q <= '0';
      ELSIF bitunknown(clk) THEN
         q <= 'X';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (prising(clk) and not(pchanging(clear))) THEN
         IF (j = '1' AND k = '1') THEN
            q <= NOT q;
         ELSIF (j = '1' AND k = '0') THEN
            q <= '1';
         ELSIF (j = '0' AND k = '1') THEN
            q <= '0';
         ELSIF (bitunknown(j)  OR bitunknown(k)) THEN
            q <= 'X';
         END IF;
      END IF;
   END jkffc;


-- JK flip flop
--    positive edge triggered
--    async. preset (active high)
--
   PROCEDURE jkffp (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On JKFFP_V: Clk and Preset both changing - Clk action suppressed";

      IF preset = '1' THEN
         q <= '1';
      ELSIF bitunknown(clk) THEN
         q <= 'X';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (prising(clk) and not(pchanging(preset))) THEN
         IF (j = '1' AND k = '1') THEN
            q <= NOT q;
         ELSIF (j = '1' AND k = '0') THEN
            q <= '1';
         ELSIF (j = '0' AND k = '1') THEN
            q <= '0';
         ELSIF (bitunknown(j)  OR bitunknown(k)) THEN
            q <= 'X';
         END IF;
      END IF;
   END jkffp;


-- JK flip flop
--    positive edge triggered
--    async. clear and preset (active high)
--
   PROCEDURE jkffpc (
      SIGNAL   j        :  IN    VLBIT;   
      SIGNAL   k        :  IN    VLBIT;   
      SIGNAL   preset   :  IN    VLBIT;   
      SIGNAL   clear    :  IN    VLBIT;   
      SIGNAL   clk      :  IN    VLBIT;
      SIGNAL   q        :  INOUT VLBIT)
   IS 

   BEGIN

      ASSERT not( prising(clk) and pchanging(preset))
         REPORT "On JKFFPC: Clk and Preset both changing - Clk action suppressed";

      ASSERT not( prising(clk) and pchanging(clear))
         REPORT "On JKFFPC: Clk and Clear both changing - Clk action suppressed";

--    ASSERT not( pfalling(preset) and pfalling(clear))
--       REPORT "On JKFFPC: Preset and Clear both released at same time";

      IF preset /= '0' AND clear /= '0' THEN
         q <= 'X';
      ELSIF preset = '1' THEN
         q <= '1';
      ELSIF clear = '1' THEN
         q <= '0';
      ELSIF bitunknown(clk) THEN
         q <= 'X';
      ELSIF (bitunknown(preset) and not(q = '1')) THEN
         q <= 'X';
      ELSIF (bitunknown(clear) and not(q = '0')) THEN
         q <= 'X';
      ELSIF (prising(clk) and not(pchanging(clear) or pchanging(preset))) THEN
         IF (j = '1' AND k = '1') THEN
            q <= NOT q;
         ELSIF (j = '1' AND k = '0') THEN
            q <= '1';
         ELSIF (j = '0' AND k = '1') THEN
            q <= '0';
         ELSIF (bitunknown(j)  OR bitunknown(k)) THEN
            q <= 'X';
         END IF;
      END IF;
   END jkffpc;

-- pla_table   Andy Tsay 18 Oct 1991
--    for VdesII pla synthesis.  Remember to run filter on vhdl file
--    to transform constants:  "1ZX0"&"001X"
--                      into:  "1ZX0001X"
--
    procedure pla_table(         I: in  vlbit_1d;
                          signal O: out vlbit_1d;
                               tbl: in  vlbit_2d) is
        variable term     : vlbit;
        variable idx, inc : integer;
    begin
--
-- check bad tbl
--
        if ( (I'length+O'length) /= tbl'length(2) ) then
                assert false report "bad pla_table" severity failure;
                return;
        end if;
--
-- get direction for 2nd index
--
        if ( tbl'left(2) < tbl'right(2) ) then
            inc := 1;
        else
            inc := -1;
        end if;
--
-- init O to 0's
--
        l0: for j  in O'range loop
            O(j) <= '0';
        end loop;
        l1: for k in tbl'range(1) loop  -- For the number of rows
--
-- get and plane
--
            term := '1';
            idx := tbl'left(2);
            l2: for j in I'range loop
                if (tbl(k,idx) = '1') then
                    term := term and I(j);
                elsif (tbl(k,idx) = '0') then
                    term := term and not(I(j));
--              else
--                  >>>*** input don't care ***<<<
--                  HANDLED CORRECTLY BY SKIPPING HERE!!!
                end if;
                idx := idx + inc;
            end loop;
--
-- get or plane
--
            if (term = '1') then -- If the AND is true: output.
                if ( inc = 1 ) then
                    idx := tbl'left(2) + I'length;
                else
                    idx := tbl'left(2) - I'length;
                end if;
                l3: for j  in O'range loop
                    if ('1'= tbl(k, idx)) then
                        O(j) <= '1';
--                  elsif ( DONT_CARE(tbl(k, idx)) ) then
--                      >>>*** output don't care ***<<<
--                      NOT HANDLED AND TREATED AS ZEROS
                    end if;
                    idx := idx + inc;
                end loop;
            end if;
        end loop;
    end pla_table;




END stdsynth;
