How can I implement a simple, Q only, D-latch using VHDL?
It is possible to generate a structural gate model of a D latch in VHDL.  Take a page out of PLD design where we find it requires a consensus term:

library ieee;
use ieee.std_logic_1164.all;

entity not1 is
    port ( 
        in1:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of not1 is

begin
    outp &lt;= not in1;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity and2 is 
    port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of and2 is

begin
    outp &lt;= in1 and in2;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity or3 is 
    port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        in3:    in  std_logic;
        outp:   out std_logic
    );
end entity;

architecture foo of or3 is

begin
    outp &lt;= in1 or in2 or in3;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
    port (
        d:  in  std_logic;
        en: in  std_logic;
        q:  out std_logic
    );
end entity;

architecture fum of dlatch is

    signal not_en:      std_logic;
    signal w1, w2, w3:  std_logic;
    signal q_int:       std_logic;

    component not1 is
        port (
        in1:    in  std_logic;
        outp:   out std_logic
        );
    end component;

    component and2 is
        port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        outp:   out std_logic
        );
    end component;    

    component or3 is
        port (
        in1:    in  std_logic;
        in2:    in  std_logic;
        in3:    in  std_logic;
        outp:   out std_logic
        );
    end component;

begin
U0:
    not1 
        port map (
        in1 =&gt; en,
        outp =&gt; not_en
        );
U1:
    and2
        port map (
        in1 =&gt; q_int,
        in2 =&gt; not_en,
        outp =&gt; w1
        );

U2:
    and2
        port map (
        in1 =&gt; d,
        in2 =&gt;  en,
        outp =&gt; w2 
        );

U3: -- consensus term
    and2
        port map (
        in1 =&gt;  d,
        in2 =&gt; q_int,
        outp =&gt; w3
        );

U4:
    or3
        port map (
            in1 =&gt; w1,
            in2 =&gt; w2,
            in3 =&gt; w3,
            outp =&gt; q_int
        );

    q &lt;= q_int;

end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch_tb is
end entity;

architecture test of dlatch_tb is
    signal d:   std_logic := '0';
    signal en:  std_logic := '0';
    signal q:   std_logic;

    component dlatch is
        port (
            d:  in  std_logic;
            en: in  std_logic;
            q:  out std_logic
        );
    end component;

begin
DUT:
    dlatch
        port map (
            d =&gt; d,
            en =&gt; en,
            q =&gt; q
        );
STIM:
    process
    begin
        wait for 10 ns;
        en &lt;= '1';
        wait for 10 ns;
        en &lt;= '0';
        wait for 10 ns;
        d &lt;= '1';
        wait for 10 ns;
        en &lt;= '1';
        wait for 10 ns;
        en &lt;= '0';
        wait for 10 ns;
        wait;
    end process;
end architecture;


The structural architecture using instantiated gates produces:


(clickable)


  Latches and flip-flop can't be modeled with logic gates in VHDL, this is for analog simulators only! 


The moral of the story is that you can't always separate opinion from knowledge or experience in answers here.  This little tidbit can be found in Digital Design Principles and Practices, 3rd edition by John F. Wakerly, 8.2.6 Registers and Latches in ABEL and PLDs, least digital design become a lost art.  It used to be common knowledge when digital design was dominated by PLDs (PALs).

Without the consensus term the output will oscillate.  There are other ways of stopping the oscillation which is caused by the delta cycle delay through the not1. This is one of at least two ways that a structural design can both be simulated and implemented.

And of course the big question is just how many real digital designers are needed in the world today?  Knowledge and experience comes from solving real world problems and as the accepted answer points out however indirectly it isn't necessary to know there is an answer in VHDL.  

For those with an actual need to digital design with structural elements it might be useful to google for hazard logic and/or consensus term along with digital design.

This particular one comes to mind because it was once an interview question for a job doing digital design in VHDL in an era of more primitive synthesis tools and slower simulations, meaning digital design experience counted for more.

If you look and the meat and potatoes part of the latch accomplished with three AND gates and one OR gate.  We see that this is also called an Earle latch:



This image taken from Page 40 of The Microarchitecture of Pipelined and Superscalar Computers, 1999 by Amos R. Omandi. The book and the Earle latch link tell us we can embed an Earle latch in other AND OR structures (like Carry Look Ahead Adders) and the history, used on an IBM 360/91 in the early 1960's.

The consensus term, the middle AND gate in the figure above overcomes the equal number of gates delay (or delta simulation cycle delays in a zero timed model) in the feedback path, preserving a '1' on the output when the input is also a '1'.  

In the VHDL design shown above the not1 inverter also provides that feedback unsettling, at least in one direction, if the not1 output had been used by the dlatch d input AND gate (U2) - in other words if the latch had been supplied externally with not_en and produced en via the inverter not1.

Use in hiding latches in existing AND OR structures is predicated on a wide number of terms that is somewhat atypical for early CPLDs (PALs) an advantage we don't have in FPGAs today, which implement other carry chain implementations in any event. It doubles the number of terms.

You can eliminate the need for consensus terms in RS based latches and flip flops by unbalancing the feedback delays between the R and S sides, typically by adding delay (as in a gate delay). This affects set up and hold times.