LDCPE: transparent data latch with gate Enable, and asynchronous Clear/Preset

LDCPE is a transparent data latch with active-high gate (G), gate enable (GE), clear (CLR), and preset (PRE) inputs. G and GE are treated identically; the equivalent gate can be considered to be (G & GE).

If CLR is asserted, Q is set to 0. Otherwise, if PRE is asserted, Q is set to 1. Otherwise, if the equivalent gate is 1, LDCPE is transparent and Q follows the D input. Otherwise, Q retains its previous value.

Verilog

This code uses only level-sensitive timing controls, and so does not have the same problems as the FDCP and FDCPE models. The CLR and PRE inputs can therefore be applied and removed in an arbitrary order without causing a testbench failure.

module LDCPE(
  input CLR, PRE, GE, G, D,
  output reg Q);

  always @(CLR or PRE or GE or G or D)
    if(CLR)
      Q <= 0;
    else if(PRE)
      Q <= 1;
    else if(GE & G)
      Q <= D;
endmodule
VHDL
library IEEE;
use IEEE.std_logic_1164.all;

entity LDCPE is
  port (
    CLR, PRE, GE, G, D : in  std_logic;
    Q                  : out std_logic);
end entity LDCPE;

architecture A of LDCPE is
begin
  process (CLR, PRE, GE, G, D) is
  begin
    if CLR = '1' then
      Q <= '0';
    elsif PRE = '1' then
      Q <= '1';
    elsif (GE and G) = '1' then
      Q <= D;
    end if;
  end process;
end architecture A;
Testbench
DUT {
   module LDCPE(input CLR, PRE, GE, G, D; output Q)
   [CLR, PRE, GE, G, D] -> [Q]
}

[1, 0, 1, 1, 1] -> [0]        // clear
[0, 1, 1, 1, 0] -> [1]        // preset
[1, 1, 1, 1, 1] -> [0]        // both clear and preset; clear has priority
[0, 1, 1, 1, 0] -> [1]        // release clear; preset still asserted
[1, 1, 1, 1, 1] -> [0]        // both clear and preset; clear has priority
[1, 0, 1, 1, 1] -> [0]        // releasing preset has no effect

[0, 0, 1, 1, 0] -> [0]        // transmit 0
[0, 0, 1, 1, 1] -> [1]        // transmit 1
[0, 0, 1, 1, 0] -> [0]        // transmit 0

[0, 0, 1, 1, 0] -> [0]        // set Q to 0 for next test:
[0, 0, 0, 1, 0] -> [0]        // latch when GE falls
[0, 0, 0, 1, 1] -> [0]        // Q holds

[0, 0, 1, 1, 1] -> [1]        // set Q to 1 for next test:
[0, 0, 0, 1, 1] -> [1]        // latch when GE falls
[0, 0, 0, 1, 0] -> [1]        // Q holds

[0, 0, 1, 1, 0] -> [0]        // set Q to 0 for next test:
[0, 0, 1, 0, 0] -> [0]        // latch when G falls
[0, 0, 1, 0, 1] -> [0]        // Q holds

[0, 0, 1, 1, 1] -> [1]        // set Q to 1 for next test:
[0, 0, 1, 0, 1] -> [1]        // latch when G falls
[0, 0, 1, 0, 0] -> [1]        // Q holds
Synthesis

When synthesised with XST L.57, both the Verilog and VHDL models produced a technology schematic which contained an LDCPE primitive, as expected. XST also produced this warning:

WARNING:Xst:737 - Found 1-bit latch for signal Q. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.