Latch duplication in technology schema (vhdl) - vhdl

Please note, this is a study question.
I have to describe a simple d-latch in vhdl, and then synthesize it. The problem is that it is a "unary" d-latch, and its single input is mapped directly to its outputs (Q and nQ). You can imagine it as a classical async d-latch, where clk signal is always high. This is useless element in logic, and xilinx synthesizer in most cases gives an empty technology schema. But the reason to keep this element is, for example, creating hardware "watermarks", which present on the schema, but don't affect its logic.
I came up with the following code:
entity dLatch is
port(
d: in std_logic;
q: out std_logic);
end dLatch;
architecture dLatch_beh of dLatch is
signal o: std_logic;
begin
latch: process(d)
begin
if d = '1' then
o <= '1';
elsif d = '0' then
o <= '0';
end if;
end process;
q <= o;
end;
This code produce the following technology schema
link
But when I try to add nQ out port, I gain duplication of latch
entity dLatch is
port(
d: in std_logic;
q, nq: out std_logic);
end dLatch;
architecture dLatch_beh of dLatch is
signal o: std_logic;
begin
latch: process(d)
begin
if d = '1' then
o <= '1';
elsif d = '0' then
o <= '0';
end if;
end process;
q <= o;
nq <= not o;
end;
Technology schema: link
I don't understand, why I am getting two completely equal latches here. I expected only one additional 'not' gate.
So my question is how to avoid the duplication of latches, or maybe some other way to solve this problem.
I use Xilinx ISE Web Pack 14.6 for synthesis.
UPD The solution is to set synthesizer's flag -register_duplication to false.

You're not getting any latches at all. You are looking at the Technology view, so it is showing you what Xilinx components it mapped into. You should be looking at RTL view instead first of all.
Secondly, latches are BAD as your professor probably made you aware. He even says in the description that the view will be blank because the tools will not generate a latch for you. They don't exist in the fabric.

The solution is to set synthesizer's flag -register_duplication to false.

Related

Initializing signals in vhdl componets

I was hoping you could help me with a problem I encountered while trying to design synchronous circuits.
I have a simple D flip-flop in my design, such as the one shown in the figure below. But when I initialize my inputs and set the reset to 1 in the test bench, the output of the D flip-flop is always undefined (as can be seen in the "Objects" view), even though I explicitly define it to be 0 when reset is high (the code for the D flip-flop is shown below).
This causes errors in larger circuits when I use the flip-flops and the outputs as signals to other components that require a defined input. How can I achieve an output of zero when my reset is high during initialization?
library ieee;
use ieee.std_logic_1164.all;
entity Dff_en is
port (
d : in std_logic;
en : in std_logic;
clk : in std_logic;
reset : in std_logic;
q : out std_logic
) ;
end entity;
architecture rtl of Dff_en is
signal q_next, q_reg : std_logic;
begin
--dff logic
process(clk, reset) is
begin
if(reset = '1') then
q_reg <= '0';
elsif(rising_edge(clk)) then
q_reg <= q_next;
end if;
end process;
-- next-state logic
q_next <= d when (en = '1') else q_reg;
--output
q <= q_reg;
end architecture; -- arch
Your code will only update the q_reg output when there are events on the signals in the sensitivity list (clk, reset). VHDL (and Verilog) require events to trigger changes. With signal initialization, then at time 0 the values are set, but there are no further events to simulate.
Even if you did a run 100 ns, there would be no change in outputs since you have not had any events. Change either clk or reset some time after time 0 and try again.

How are sequential statements inside a vhdl process synthesized?

I have some difficulties understanding how sequential statements inside a vhdl process are synthesized.
The IEEE standard reference manual Std 1076-2008 states:
Sequential statements are used to define algorithms for the execution of a subprogram or process; they execute in the order in which they appear.
It's easy to understand how it works in simulation since simulation is done by a CPU, that is build for sequential execution. In this case the hardest thing is to simulate concurrent executions, and this is done with the trick of delta delays.
But what about the synthesis? I don't understand how it is possible for two statements to be sequential in a fully logical architecture...
Any help ?
An example process:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity example is
Port (clk, rst, A : in STD_LOGIC; B : out STD_LOGIC);
end example;
architecture example_arch of example is
begin
process(clk, rst)
variable C : STD_LOGIC;
begin
if rst = '1' then
C := '0';
B <= '0';
elsif rising_edge(clk) then
if A = '1' then
E := '1';
else
E := '0';
end if;
-- then sequentially ?
if E = '1' then
B <= '1';
else
B <= '0';
end if;
end if;
end process;
end example_arch;
The synthesis tool will analyze the process and turn it into gates and flip-flops in a way that is faithful to the sequential (but also "instantaneous") execution of the process.
For example, your process (where I assume you meant to assign-to, and check the value of, variable C, not E) should be turned (synthesized) into a simple DFF with an asynchronous reset.

Simple SR Latch Simulation in VHDL(with Xilinx) doesn't oscillate

I've learned that SR-Latch does oscillate when S and R are both '0' after they were just '1' in following circuit VHDL Code.
here is VHDL of SRLATCH
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SRLATCH_VHDL is
port(
S : in STD_LOGIC;
R : in STD_LOGIC;
Q : inout STD_LOGIC;
NOTQ: inout STD_LOGIC);
end SRLATCH_VHDL;
architecture Behavioral of SRLATCH_VHDL is
begin
process(S,R,Q,NOTQ)
begin
Q <= R NOR NOTQ;
NOTQ<= S NOR Q;
end process;
end Behavioral;
and followings are process in Testbench code and its simulation results
-- Stimulus process
stim_proc: process
begin
S <= '1'; R <= '0'; WAIT FOR 100NS;
S <= '0'; R <= '0'; WAIT FOR 100NS;
S <= '0'; R <= '1'; WAIT FOR 100NS;
S <= '0'; R <= '0'; WAIT FOR 100NS;
S <= '1'; R <= '1'; WAIT FOR 500NS;
end process;
and totally I don't have any idea why simulation doesn't reflect...
(click to enlarge)
Someone is teaching you wrong knowledge!
SR and RS basic flip-flops (also called latches) don't oscillate. The problem on S = R = 1 (forbidden) is that you don't know the state after you leave S = R = 1 because you can never go to S = R = 0 (save) simultaneously. You will transition for S = R = 1 to S = R = 0 through S = 1; R = 0 (set) or S = 0; R = 1 (reset). This will trigger either a set or reset operation before you arrive in state save.
Be aware that VHDL simulates with discrete time and is reproducing the same simulation results on every run. You can not (easily) simulate physical effects that cause different signal delays per simulation run.
Btw. you VHDL description is also wrong. Q and NOTQ are of mode out, not inout. Use either a proper simulator supporting VHDL-2008 (that allows read back of out-ports) or use an intermediate signal.
Nice question, and your instructor is right - this circuit will oscillate if both S and R are released at the "same" time. Your issue is that your TB isn't doing this, but this one does:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TOP is
end entity TOP;
architecture A of TOP is
signal S,R,Q,NOTQ: std_logic;
component SRLATCH_VHDL is
port(
S : in std_logic;
R : in std_logic;
Q : inout std_logic;
NOTQ : inout std_logic);
end component SRLATCH_VHDL;
begin
U1 : SRLATCH_VHDL port map(S, R, Q, NOTQ);
process is
begin
S <= '1';
R <= '1';
wait for 10 ns;
S <= '0';
R <= '0';
wait;
end process;
end architecture A;
This will produce infinite delta-delay oscillation:
This isn't a great way to demonstrate asynchronous behaviour, because you are effectively simplifying the physical nature of the circuit, and using the VHDL scheduler to show that there's a problem (with the use of 'delta delays'). A better way to do this is to model real circuit behaviour by adding signal delays (this is exactly what your tools are doing when they back-annotate for timing simulations). Look up signal assignments with after, and the difference between transport and inertial delays. If you draw a circuit diagram, you'll see that the issue arises if both S and R are released in a 'small' time window that doesn't allow the signal propagation around your circuit to complete before the second control signal changes. You now need to write a testbench that changes S and R inside this time window.
Pretty much everything you ever design will be asynchronous, in exactly the same way as your SR circuit. We make circuits 'synchronous' only by ensuring that input signals don't change at the same time. The job of the timing tools is to tell us what 'same' actually means: when you get a report or a datasheet value giving you a setup or a hold time, then that number is simply the numerical version of 'not the same'.

This design contains one or more registers/latches that are directly incompatible with the Spartan6 architecture

I'm new in this world.
Actually, I'm learning VHDL. I've written the below code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Problems is
port(
S : in std_logic;
D : in std_logic;
CLK : in std_logic;
R : in std_logic;
Q : out std_logic;
Q_n : out std_logic
);
end Problems;
architecture Behavioral of Problems is
signal t_tmp1 : std_logic;
begin
DFF: process (S,R,D,CLK)
begin
if (S = '0' and R = '0') then
t_tmp1 <= not t_tmp1;
elsif (S = '0' and R = '1') then
t_tmp1 <= '1';
elsif (S = '1' and R = '0') then
t_tmp1 <= '0';
elsif (rising_edge(CLK)) then
t_tmp1 <= D;
end if;
end process DFF;
Q <= t_tmp1;
Q_n <= not t_tmp1;
end Behavioral;
When I synthesized appear me the below warnings:
WARNING:HDLCompiler:92 - "/home/joseph/ISEProjects/Exercise_BasicMemoryElements/Problems.vhd" Line 41: t_tmp1 should be on the sensitivity list of the process
WARNING:Xst:3002 - This design contains one or more registers/latches that are directly
incompatible with the Spartan6 architecture. The two primary causes of this is
either a register or latch described with both an asynchronous set and
asynchronous reset or a register or latch described with an asynchronous
set or reset which however has an initialization value of the opposite
polarity (i.e. asynchronous reset with an initialization value of 1).
The simulation works well.
I want to know why the warnings and what do I have to learn to solve problems like this.
Regards,
Joseph Peña.
If you were to read through Spartan-6 Libraries Guide for Schematic Designs you'd find a D flip flop with both an asynchronous Preset and asynchronous Clear isn't provided by Spartan 6 (or later device families for that matter).
Your if statement's first condition statement's behavior doesn't appear to represent what would happen if both a reset and a set were TRUE at the same time either. A distinction between what you can simulate and what you can technology map through synthesize.
In Spartan-3e for instance the reset would override the set:
Constraints on the synthesis eligible subset of the VHDL language for mapping into Register Transfer Logic elements in a target technology are found in IEEE Std 1076.6-2004, now rescinded, and can be found for Xilinx either in the ISE XST User Guide or Vivado Design Suite User Guide Synthesis (ug901).
The ability to map a VHDL description is predicated on having a supported target for the device family.

RS latch with VHDL

I have wrote a simple RS latch with VHDL and tried to synthesis it with ISE. The synthesizer added a D flip flop where the D input is grounded and my (S)et and (R)eset inputs are treated as preset and clear inputs. I expected to see NAND gates only. Why it added a flip flop while there is no need for that? Also why the D input is connected to ground?
entity rs is
Port ( r : in STD_LOGIC;
s : in STD_LOGIC;
q : inout STD_LOGIC);
end rs;
architecture Behavioral of rs is
begin
process( r, s )
begin
if r = '1' then
q <= '0';
elsif s = '1' then
q <= '1';
else
q <= q;
end if;
end process;
end Behavioral;
Your observation that a flip flop has been used is not correct. The element is labelled ldcp, and this is a transparent latch. Looking at your code, a latch is what you have described. The D input is connected to ground, because all your process ever does is set or clear the latch; you have not described a 'load' operation, so the latch does not use its D input.
An FPGA does not contain NAND gates. Even though the gates are shown in the schematic from ISE, their combined function is in fact implemented in LookUp Tables (LUTs). The behavior of a latch function only using LUTs is different from what you would have if you would implement a latch with NAND gates.
To realize latch functions, a Xilinx FPGA has to utilize "storage elements" (an actual available physical structure in the FPGA) to emulate their behavior. These elements have predictable behavior. The storage elements offer set and reset inputs. Together with some logic you can create latch-like behavior.
You could look at the PAR output instead of the synthesis output to see how it is realized.

Resources