RS latch with VHDL - 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.

Related

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.

Digital frequency doubler with a dual edge triggered flip flop in VHDL

I am trying to implement a digital input frequency doubler. The circuit consists of an XOR2 gate, dual edge triggered flip flop and a couple of buffers.
The frequency-in goes to one of the Xor inputs. The output of the Xor gate goes through a buffer and into the clock signal of the DFF. The output(ussually Q) used in parallel to feed the remaining Xor input and to feedback to the D input of the flip flop through a buffer. finally the output of the doubler is taken from the Xor gate.
I have tested the circuit and it works.I am a novice in VHDL and have very basic knowledge in verilog. I figured i'd analyse it for practice so that i get a feel of VHDL before third year.
Regards
Stranger
if anyone in the future is suffering the same fate I am here is the ALMOST FINISHED. all you gotta do is find a way of using clk'event in place of if (clk ='1' and clk'EVENT).
Schematic is here
entity freq_doubler is
PORT (
vin : in BIT ;
vout : out BIT );
end entity freq_doubler;
architecture rtl of freq_doubler is
signal q : bit;
signal d,clk,buff : bit ;
begin
buff <= (vin XOR q);
clk <= buff;
vout <=buff;
p0: process (d,clk) is
begin
if (clk ='1' and clk'EVENT) then
q <=d;
end if;
end process p0;
end architecture rtl;
configuration freq_doubler_conf of freq_doubler is
for rtl
end for;
end configuration freq_doubler_conf;

Latch duplication in technology schema (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.

Why use concurrent statements in VHDL?

I am just starting with learning vhdl.
Consider the code here : - http://esd.cs.ucr.edu/labs/tutorial/jkff.vhd
I can't understand what are concurrent statements and why are they needed here?
Will it be correct if we modify Q and Qbar directly in process p without using internal signal 'state'? Also why are J,K not in sensitivity list of process p in the snippet?
Concurrent statements, as you may know, in a pure functional sense (i.e. not considering hardware implementation) do not incur any delay. So when you write
Q <= state;
Functionally, Q exactly follows state without any delay.
I am going to guess that the reason an intermediate signal state was used, instead of directly assigning Q inside the process, is that if you directly assign one of your outputs Q in the process, then you cannot "read" the output to derive your Qbar signal.
That is, you couldn't do this:
Qbar <= not Q;
This is because it is not strictly allowable to read an output signal in VHDL. By using "state" you have an internal signal from which you can derive both Q and Qbar.
An alternative, equivalent implementation to this would be to assign both outputs Q and Qbar in each of the cases in the state machine, and eliminate the intermediate state signal completely. However, this seems a bit more complicated since you will have nearly twice as many lines of code for an equivalent functionality.
To answer your second question: J,K are not in the sensitivity list because the process p is a synchronous process. You are describing a memory element (JK FlipFlop), which by definition only updates its outputs when clock or reset change. Input signals J and K can change and the process will not update its outputs. Every time there is a clock edge, or reset is asserted, the process "wakes up" and evaluates inputs, and determines what the output should be. Even in J,K were included in the sensitivity list, provided your ouputs were only updated on rising_edge(clock), then the overall function would be the same (although your code would be confusing).
There is no reason not to have the Q and Qbar assignments inside the process. You need to be slightly careful though.
Whenever a signal is assigned to, the value does not update until the simulator moves on to the next "delta-cycle". This means that within processes, when you assign to a signal, you are axtually only cheduling and update and if you read the signal you will get the "old" value. In order to have the sort of sequential updates you might expect, you use a variable. So you could model the JKFF like this:
architecture behv of JK_FF is
begin
p : process(clock, reset) is
variable state : std_logic;
variable input : std_logic_vector(1 downto 0);
begin
if (reset = '1') then
state := '0';
elsif (rising_edge(clock)) then
input := J & K;
case (input) is
when "11" =>
state := not state;
when "10" =>
state := '1';
when "01" =>
state := '0';
when others =>
null;
end case;
end if;
Q <= state;
Qbar <= not state;
end process;
end behv;
A synthesis note: the assignments to Q and Qbar occur outside of the if rising_edge(clk) so will be interpreted as just like concurrent drivers.

Resources