3
\$\begingroup\$

I just started VHDL today and I'm the type of person that can only learn by doing stuff, so after I made some basic gates in VHDL, I tried making a simple D-latch(so no clock signal), however without success. I get all kinds of errors such as in1 not defined, std_logic not defined, etc.

Here is my code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dflip is
end dflip;
architecture structural of dflip is
 component AND2
 port (in1, in2:in std_logic; out1: out std_logic);
 end component;
 component OR2
 port (in1, in2:in std_logic; out1: out std_logic);
 end component;
 component NOT1
 port (in1: in std_logic; out1: out std_logic);
 end component;
 signal D, E, E_NOT, Q, OUT_AND1, OUT_AND2: std_logic;
begin 
 U0: NOT1 port map (E, E_NOT);
 U1: AND2 port map (E, D, OUT_AND1);
 U2: AND2 port map (E_NOT, Q, OUT_AND2);
 U3: OR2 port map (OUT_AND1, OUT_AND2, Q);
end structural;
entity NOT1 is
 port (in1: in std_logic; out1: out std_logic);
end NOT1;
architecture behavioral_not of NOT1 is
begin
 out1 <= not in1;
end behavioral_not;
entity AND2 is
 port(in1, in2: in std_logic; out1: out std_logic);
end AND2;
architecture behavioral_and2 of AND2 is
begin
 out1 <= in1 and in2;
end behavioral_and2;
entity OR2 is
 port (in1, in2: in std_logic; out1: out std_logic);
end OR2;
architecture behavioral_or of OR2 is
begin
 out1 <= in1 or in2;
end behavioral_or;

I made it structural, because I could not make it to work behavioral, because it seems I cannot use if statements if I write behavioral(makes sense). The problem is with that Q output which needs to be connected back to the input of an AND gate.

So how do I do this?

asked Mar 15, 2015 at 17:37
\$\endgroup\$
1
  • \$\begingroup\$ The code between 'ARCHITECTURE ... BEGIN' and 'END ...' is concurrent. Each line like 'U0 : NOT port map' is re-evaluated by the simulator each time an event (for example a transition) occurs on one of the inputs. Code order is irrelevant. Sequential parts (like 'traditional' imperative code) must be inside PROCESS declarations. Unlike C code, there is no problem with 'using a variable before assigning it', as long as the signal is assigned somewhere. \$\endgroup\$ Commented Mar 15, 2015 at 17:47

4 Answers 4

3
\$\begingroup\$

Latches and flip-flop can't be modeled with logic gates in VHDL, this is for analog simulators only! The feedback logic doesn't bode well with the VHDL simulator. Furthermore, no synthesiser would recognize it as a latch/flip-flop.

To instantiate a latch/flip-flop, you can either instantiate your vendor's primitives or use this generic code:

LATCH: process(en, d)
begin
 if en = '1' then
 q <= d;
 end if;
end process LATCH;
DFF_ASYNC: process(rst, clk)
begin
 if rst = '1' then
 q <= '0';
 elsif rising_edge(clk) then
 q <= d;
 end if;
end process DFF_ASYNC;
DFF_SYNC: process(clk)
begin
 if rising_edge(clk) then
 if rst = '1' then
 q <= '0';
 else
 q <= d;
 end if;
 end if;
end process DFF_SYNC;

Use logic gates for combinational circuits only. If you want a challenge, you may be better with simulating ALU logic then synchronous elements. As a final note, keep in mind that using logic gates to design circuits is reserved for masochists, most VHDL designer use higher level construct that are easier to read and to debug.

Update

Apparently, latches can be simulated in VHDL using logic gates (thanks @David Koontz). Look at his answer to see how!

answered Mar 15, 2015 at 17:55
\$\endgroup\$
2
  • \$\begingroup\$ Thanks a lot! By higher level constructs you mean using behavioral models? \$\endgroup\$ Commented Mar 15, 2015 at 18:09
  • 1
    \$\begingroup\$ I mean RTL (register transfer level). It's a model where you describe registers (using my sample code) and how they are connected. As an example, an adder would have registers x, y and s and the statement s <= x + y enclosed in a rising_edge statement. I consider behavioral VHDL code that is not synthesisable. \$\endgroup\$ Commented Mar 15, 2015 at 18:17
6
\$\begingroup\$

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 <= 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 <= 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 <= 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 => en,
 outp => not_en
 );
U1:
 and2
 port map (
 in1 => q_int,
 in2 => not_en,
 outp => w1
 );
U2:
 and2
 port map (
 in1 => d,
 in2 => en,
 outp => w2 
 );
U3: -- consensus term
 and2
 port map (
 in1 => d,
 in2 => q_int,
 outp => w3
 );
U4:
 or3
 port map (
 in1 => w1,
 in2 => w2,
 in3 => w3,
 outp => q_int
 );
 q <= 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 => d,
 en => en,
 q => q
 );
STIM:
 process
 begin
 wait for 10 ns;
 en <= '1';
 wait for 10 ns;
 en <= '0';
 wait for 10 ns;
 d <= '1';
 wait for 10 ns;
 en <= '1';
 wait for 10 ns;
 en <= '0';
 wait for 10 ns;
 wait;
 end process;
end architecture;

The structural architecture using instantiated gates produces:

dlatch_tb structural.png (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:

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.

answered Mar 16, 2015 at 0:03
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the correction, as you can probably tell, I only touched a PAL in logic classes, before I learned about VHDL and FPGAs. Do you know if this would mapped to a latch primitive on any synthesizer? \$\endgroup\$ Commented Mar 16, 2015 at 20:23
  • \$\begingroup\$ I wouldn't bet it would map to a latch primitive anywhere. It should generate a working latch based on an three term AND OR structure. The driving reason it was well known in PLDs/PALs has to do with scarcity of resources, there's generally no reason in an FPGA today. You can also use consensus terms to get gate level models of flip flops to work. For the behavioral latch q_int <= (q_int and not en) or (d and en); works just fine, because there is no delta cycle delay needing consensus term coverage. \$\endgroup\$ Commented Mar 16, 2015 at 23:47
0
\$\begingroup\$

If you want structural design then component instantiation is the way to go but one really does not model latch using structural modeling. Behavioral is easier and you can use if statement for this method. Take a look at this video-

http://appliedelectronicsengineering.blogspot.com/2015/10/how-to-implement-d-latch-in-vhdl.html

answered Oct 22, 2015 at 1:47
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Please summarize some of the information in the video. \$\endgroup\$ Commented Oct 22, 2015 at 2:38
0
\$\begingroup\$

Latches can be modeled in many ways in VHDL, including with logic gates; and the VHDL code thus produced can be synthesised (at least with Synplify Pro).

The reported error messages,

in1 not defined, std_logic not defined, etc.

indicate that the error is missing library and use clauses. Indeed, basically the only thing I did to correct your code was to add those before every entity declaration. Here is the corrected code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity NOT1 is
port (in1: in std_logic; out1: out std_logic);
end;
architecture behavioral_not of NOT1 is
begin
 out1 <= not in1;
end;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity AND2 is
port (in1, in2: in std_logic; out1: out std_logic);
end;
architecture behavioral_and2 of AND2 is
begin
 out1 <= in1 and in2;
end;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity OR2 is
port (in1, in2: in std_logic; out1: out std_logic);
end;
architecture behavioral_or of OR2 is
begin
 out1 <= in1 or in2;
end;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dflip is
port (D, E: in std_logic; Q: out std_logic);
end;
architecture structural of dflip is
 signal E_NOT, Q_int, OUT_AND1, OUT_AND2: std_logic;
begin 
 U0: entity work.NOT1
 port map (E, E_NOT);
 U1: entity work.AND2
 port map (E, D, OUT_AND1);
 U2: entity work.AND2
 port map (E_NOT, Q_int, OUT_AND2);
 U3: entity work.OR2
 port map (OUT_AND1, OUT_AND2, Q_int);
 Q <= Q_int;
end;

As a bonus, let us see a shorter implementation of the unclocked D latch, with the same gates, but without separate entities for each gate:

architecture short of dflip is
 signal Q_int: std_logic;
begin
 Q_int <= (D and E) or (not E and Q_int);
 Q <= Q_int;
end;

Note that in practice you would almost surely use clocked, edge triggered flipflops instead of latches. Those can be nicely expressed with conditional signal assignment:

Q <= D when rising_edge(clock) and E = '1';
Blair Fonville
4,1294 gold badges22 silver badges48 bronze badges
answered Dec 28, 2018 at 22:55
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.