VHDL behavioural D Flip-Flop with R & S - vhdl

Hi can any of you with more experience with VHDL Quartus II please set me right on this please.
I have the following Entity and behavioural Architecture for a D Flip-Flop with Set and Reset.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY Q1 IS
PORT (D,R,S,CLK : IN std_logic;
Q : OUT std_logic
);
END ENTITY Q1;
ARCHITECTURE behavioural OF Q1 IS
BEGIN
D_FF : PROCESS (CLK,R,S)
BEGIN
IF R = '0' THEN Q <= '0';
ELSIF S = '0' THEN Q <= '1';
ELSIF (rising_edge(CLK)) THEN Q <= D;
END IF;
END PROCESS D_FF;
END ARCHITECTURE behavioural;
When I compile the code using Quartus II I get the following error message :
Warning (335093): TimeQuest Timing Analyzer is analyzing 1 combinational loops as latches.
I think it is a warning for the incomplete output assignments of the R & S inputs, but when I make a D Flip-Flop latch with only the SET input this error message does not appear when compiled. This leaves me thinking maybe I made an error when writing the architecture? If anyone has any answers or useful info that would be much appreciated.

You have described a clock-edge triggered flip-flop (FF) with both an asynchronous reset and an asynchronous set. Only one of them is supported at the same time because AFAIK, all FFs on Altera FPGAs have only an asynchronous reset.
An asynchronous set is emulated on Altera FPGAs by inverting the FF data input and output and then resetting it to low instead of setting it to high. It looks like this:
Don't overlook the inverter on the D input of the FF. If S is low, then the FF itself is asynchronously reset, but due the negation of the Q output afterwars, it behaves as an asynchronous set of output Q of your entity Q1. If S is high, the FF stores the negated input at the rising clock-edge, which is again negated at the output. As you see, the asynchronous reset port of the FF is already used, and thus, cannot be used for an additional asynchronous reset of your entity Q1.
I recommend to use flip-flops with synchronous set and reset instead:
ARCHITECTURE sync_rs OF Q1 IS
BEGIN
D_FF : PROCESS (CLK)
BEGIN
IF (rising_edge(CLK)) THEN
IF R = '0' THEN Q <= '0';
ELSIF S = '0' THEN Q <= '1';
ELSE Q <= D;
END IF;
END IF;
END PROCESS D_FF;
END ARCHITECTURE sync_rs;

Flip flops in FPGA devices usually have either asynchronous set or reset, but not both, so Altera Quartus tries to make the requested circuit with latches instead of dedicated hardware.
However, for most cases that is not what you want, so instead use flip flops with either asynchronous reset or set, or use synchronous set and and reset as Martin Zabel suggested in his answer.
Note that asynchronous reset have an advantage over synchronous reset in high speed designs, since the asynchronous reset does not add any login in the main synchronous data path, which is usually the critical path for high-speed designs.
Finally, for asynchronous reset, it is a good habit to use two if separate statements, with reset last, so clocking is not dependent on assertion of reset. It is not an issue for a single bit flip flop, but if more signals are controlled in the same process, and reset does not apply to all signals, then clocking should not be dependent on reset for those signal without reset, since that will infer latches. Code like:
D_FF : PROCESS (CLK, R)
BEGIN
IF rising_edge(CLK) THEN
Q <= D;
END IF;
IF R = '0' THEN
Q <= '0';
END IF;
END PROCESS D_FF;

Thanks for the reply, I made the R & S inputs asynchronous on purpose. I have been working through a VHDL text book "Free Range VHDL" and have come across the following question in the Exercises:
The question asks for both inputs to be asynchronous. You say this can be emulated with Altera by inverting the input and output and resetting it to low instead of high. Can you expand on this a little? Thanks

Related

Why do incomplete if statements create latches during synthesis in VHDL?

Why is it when we try to synthesize incomplete if statements in VHDL the synthesizer uses latches instead of flip-flops?
An explanation from a digital/circuit standpoint would be greatly appreciated.
The premise of the question is wrong. The latch is not inferred instead of a flip-flop.
Flip-flops are inferred every time a signal goes through a clocked process even with an incomplete IF statement. For example, the following code infers a flip-flop:
process(clock) is
begin
if rising_edge(clock) then
if (A) then
B <= C;
end if;
end if;
end process;
Latches are inferred only in combinatorial logic processes when there is an incomplete IF statement. This is due to the fact that an incomplete if statement requires the storage of information which is not possible with the simpler elements of combinatorial logic (wires and gates).
Short answer: because the behaviour of a latch matches that of an incomplete IF. A register does not.
if (A)
B = C;
If the condition A is true and C changes, the output B follows the input immediately. If A is false B keeps it value. This behavior of the IF statement corresponds with the behavior of a latch. Thus a latch is what is generated.
You can not generate this behaviour with a register.
Unfortunately, I can't answer to oldfart (not enough reputation), so technically the short answer is kinda correct.
But, the long answer has different variables: what kind of design do you implement, what tool do you use and what platform is your target.
E.g. Quartus II 16.1, Cyclone V CSXFC6D6F31C6 such code:
library ieee;
use ieee.std_logic_1164.all;
entity d_latch_test is
port
(
signal clk : in std_logic;
enable : in std_logic;
sr_in : in std_logic;
sr_out : out std_logic
);
end entity;
architecture rtl of d_latch_test is
begin
process (clk)
begin
if (rising_edge(clk)) then
if (enable = '1') then
sr_out <= sr_in;
end if;
end if;
end process;
end rtl;
Quartus Synthesis would not tell you that your code is a latch, but it is a D-flip-flop
But! It has asynchronous input.
So basically you can do a flip-flop from if-statement.

VHDL - FSM Control

I'm a beginner and I need a little help . My "current_s" is changing whenever rising edge of the clock detected. But, I want it to change only once when "Dot" or "Dash" is '1'.
I tried to create a signal like: Go_s<=Dot or Dash;
And then tried to use its rising_edge to enable the process, but I've been told that it's not a good idea. But I can't think anything else.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Let5 is
Port(
Clk: in std_logic;
Reset: in std_logic;
Dot: in std_logic;
Dash: in std_logic;
one_spc: in std_logic;
three_spc: in std_logic);
END Let5;
-------------------------------------------------------------------------------
Architecture Let5_a of Let5 is
-------------------------------------------------------------------------------
Type state is (Start, A, B, A_1, A_2, B_1, B_2);
Signal current_s: state;
-------------------------------------------------------------------------------
BEGIN
---------------------------------------------------------------------------------
PROCESS(Clk, Reset)
BEGIN
IF(Reset='1')Then
current_s<=Start;
ELSIF(Clk='1' and Clk'event)Then
Case current_s is
When Start =>
IF(Dot='1')Then
current_s<=A;
ELSIF(Dash='1')Then
current_s<=B;
END IF;
When A =>
IF(Dot='1')Then
current_s<=A_1;
ELSIF(Dash='1')Then
current_s<=A_2;
END IF;
When B =>
IF(Dot='1')Then
current_s<=B_1;
ELSIF(Dash='1')Then
current_s<=B_2;
END IF;
When OTHERS => current_s <= Start;
END Case;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
END Let5_a;
Simulation:
Add an conditional update of current_s inside the clocked process, using:
...
elsif (Clk='1' and Clk'event) then
if (Dot = '1') or (Dash = '1') then
case current_s is
...
Then current_s is updated only when the condition (Dot = '1') or (Dash = '1') is TRUE.
It is correct what you have been told, that you should not make an additional signal Go_s checking for rising edge of this, since this is not the way to implement standard synchronous designs. Instead use a signal clock and make updates on rising edge, for example using rising_edge(Clk) instead of Clk='1' and Clk'event, and then make the updated conditional to whatever signal required. FPGAs and tools are made to implement this kind of design.
Actually it ought to work reading Dot or Dash in the way you do now; I suspect something else is the problem.
If Dot is high for three consecutive clock cycles...
in the first, you get to State A.
in the second, you get to State A1.
in the third, ... there is no handler for State A1 so the "when others" clause takes you back to Start.
I suspect you actually want to remain in State A1 (or even State A) until either :
Dot is no longer 1, or:
Dash is 1
and to accomplish this (remain in State A1 instead of retriggering) you need:
When A1 =>
if Dot = '0' then
current_s <= Start;
elsif Dash = '1' then
current_s <= A_2;
end if;
Treat states Bn similarly for Dash.
If I'm misinterpreting and you actually want to remain in State A longer, it should now be clear how to make that happen instead.
Your code has a number of problems, and they are NOT related to Dot and Dash, because it is OK to have one with higher priority than the other. The present state changes at every clock cycle because that is exactly what you told the circuit to do when Dot and/or Dash is '1'. Note that in the states start, A, and B the machine changes to a state that is not in this list (start, A, B), so the WHEN OTHERS statement causes it to return to the start state at the next clock edge, with this repeated indefinitely.
My suggestion is that you draw the intended state transition diagram very carefuly, after which re-writing the code should be straightforward, especially because this is a relatively simple problem.

What is the correct implementation of handling asynchronous signals in an FSM?

We are implementing an Ethernet MAC controller in VHDL..
To start of, here is a code snippet of my code..
-- next state
PROCESS(p_state, phy_start, phy_ctr, phy_clk)
BEGIN
CASE p_state IS
WHEN sIDLE =>
IF(phy_start = '1' or rising_edge(phy_start)) THEN
n_state <= sPRE;
ELSIF(phy_start'event AND phy_start='0') THEN
n_state <= n_state;
ELSE
n_state <= sIDLE;
END IF;
............
The problem is that my professor told me I associated phy_start as the clock signal where in the rising_edge() must be only associated to only one clock which is phy_clk. What I want to happen is when phy_start asserts, it would go to sPRE state at the next clock cycle. The assertion is done in the rising edge of the clock. I have tried
PROCESS(p_state, phy_start, phy_ctr, phy_clk)
BEGIN
CASE p_state IS
WHEN sIDLE =>
IF(phy_start = '1') THEN
n_state <= sPRE;
ELSIF(phy_start'event AND phy_start='0') THEN
n_state <= n_state;
ELSE
n_state <= sIDLE;
.............
but it does not enter the phy_start = '1' because it happened in the transition.. (there is what we call the setup time in which the data must be stable in that duration in order to be read correctly). What is the correct implementation then? Or I have no choice but to assert the phy_start for 2 clock cycles if the assertion happens in the rising edge, or phy_start must be asserted in the falling edge of the clock. ALso, what is the correct set of sensitivity list for the next state logic?
If everything is clocked under phy_clk, you should never use rising_edge() or 'event on other signals. These are associated to the clocks, not the signals.
If you want to detect when a signal clocked on phy_clk rises, you should proceed like this:
process(phy_clk,nreset)
begin
if nreset = '0' then
phy_start_d <= '0';
elsif phy_clk = '1' and phy_clk'event then
phy_start_d <= phy_start;
end if;
end process;
phy_start_p <= phy_start and not phy_start_d;
the phy_start_p signal is set to 1 only when phy_start rises, and it's totally synchronous with phy_clk;
If phy_start is created synchronously by another process, then you have no problem.
Just read it in your other synchronous process, and compare against a value you stored from the last clock cycle, to detect when the signal has changed from 0 to 1:
process (phy_clk)
variable last_start : std_logic := '0';
begin
if rising_edge(phy_clk) then
if phy_start = '1' and last_start = '0' then
-- do something in here
end if;
last_start := phy_start;
end if;
end process;
There has been a related question with answers recently, which you can find at:
how many processes i need to monitor two signals?
It is useful to keep in mind that VHDL is for describing hardware (design), so
the synthesis tool can convert the description to fit the available hardware,
which is typically flip flops (sequential design) and gates (combinatorial
design). The synthesis tools does typically have some recommendations for
writing VHDL, so the translation to hardware will work smoothly.
For flip flops with asynchronous reset (rst) and rising edge clock (clk), with
next value generated by optional gates, the VHDL is typically:
-- Template for flip flops
process (clk, rst) is
begin
if rising_edge(clk) then
-- Flip flops outputs updated on rising edge of clk
end if;
if rst = '1' then
-- Flip flops outputs assigned with constant value when rst is '1'
end if;
end process;
Only rst and clk should be in the sensitivity list, so other signals used
in expressions in the process should not be included. Any expressions used to
generate the value for the flip flop will be converted to gates by the tool.
Only rising edge clock should be used for flip flop, unless there is a good
reason to use falling edge clock, or even both edges, since using only a single
edge will make it easier to do the timing constraining.
If asynchronous reset is not used, then leave out the rst from the
sensitivity list and remove the related if statement.
For pure gates the VHDL is typically, assuming use of VHDL-2008:
-- Template for gates
process (all) is
begin
-- Gates outputs updated based
end process;
or for simple expression just drop the process and write:
my_signal <= my_expression;
So back to the specific code, then it is possible to write this as a single
process with phy_clk as clock:
PROCESS (phy_clk)
BEGIN
IF RISING_EDGE(phy_clk) THEN
CASE p_state IS
WHEN sIDLE =>
p_state <= ... -- New value for state based on signals
When it is required to react on changes in signals, like phy_start going from
'0' to '1', then a signal with a single cycle delayed version of phy_start
can be made, for example phy_start_ff, and the an expression can be written
in the code like:
if (phy_start_ff = '0') and (phy_start = '1') then -- phy_start from 0 to 1
..

In a state machine process is there a difference if I state specifically that the state stays the same?

In a process that controls a state machine, when the state stays the same, is there a difference if specifically stated that the state signal gets the same value as it has? In the example below, are the two lines inside the process with the notes needed?
--CLK and RST are input signals
type state_machine_states is
(
st_idle, st_1
);
signal sm : state_machine_states ;
signal next_state : std_logic;
begin
--assume that there is some logic which deals with the next_state signal
states_proc: process (RST, CLK)
begin
if (RST = '1')
sm <= 'st_idle'
elsif rising_edge(CLK) then
case sm is
when st_idle =>
if (next_state = '1') then
sm <= st_1;
else --Are these two lines needed, and is there
sm <= st_idle --any difference if they are written or not?
end if;
when st_1 =>
sm <= st_idle;
end case;
end if;
end process;
This is fine with most modern tools. If you omit an else in a combinatorial process then you'll infer a latch. But in a clocked process you will not.
It treats this it as an enable to drive the register. The input is not clocked to the output when the enable is not driven.
when using an else statement, or generally when each code path is covered, then you avoid using latches
Update: when the else is omitted, you use the latch as memory
The code shown along with the original question is not appropriate for FSM implementation. You are looking at sm and next state to decide what sm should be, which does not make sense. The following must occur in ANY state machine:
1) Look at the present state and to the input to decide what the next state should be. This must be REGISTERED.
2) Look at the present state to decide what the output should be (Moore case). This should NOT BE REGISTERED, unless a special condition is required (for example, glitch-free output or pipelined construction - See, for example, "Finite State Machines in Hardware: Theory and Design (with VHDL and SystemVerilog)").

VHDL FSM set unit input and use output in same state

I am implementing a Mealy-type FSM in vhdl. I currently am using double process, although i've just read a single-process might be neater. Consider that a parameter of your answer.
The short version of the question is: May I have a state, inside of which the input of another component is changed, and, aftwerwards, in the same state, use an output of said component? Will that be safe or will it be a rat race, and I should make another state using the component's output?
Long version: I have a memory module. This is a fifo memory, and activating its reset signal takes a variable named queue_pointer to its first element. After writing to the memory, the pointer increases and, should it get out of range, it is (then also) reset to the first element, and an output signal done is activated. By the way, i call this component FIMEM.
My FSM first writes the whole FIMEM, then moves on to other matters. The last write will be done from the state:
when SRAM_read =>
READ_ACK <= '1';
FIMEM_enable <= '1';
FIMEM_write_readNEG <= '0';
if(FIMEM_done = '1') then --is that too fast? if so, we're gonna have to add another state
FIMEM_reset <= '1'; --this is even faster, will need check
data_pipe_to_FOMEM := DELAYS_FIMEM_TO_FOMEM;
next_state <= processing_phase1;
else
SRAM_address := SRAM_address + 1;
next_state <= SRAM_wait_read;
end if;
At this state, having enable and write active means data will be written on the FIMEM. If that was the last data space on the memory, FIMEM_done will activate, and the nice chunk of code within the if will take care of the future. But, will there be time enough? If not, and next state goes to SRAM_wait_read, and FIMEM_done gets activated then, there will be problems. The fact that FIMEM is totally synchronous (while this part of my code is in the asynchronous process) messes even more?
here's my memory code, just in case:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity memory is
generic (size: positive := 20);
Port ( clk,
reset,
enable,
write_readNEG: in std_logic;
done: out std_logic;
data_in: in STD_LOGIC_VECTOR(7 downto 0);
data_out: out STD_LOGIC_VECTOR(7 downto 0) );
end memory;
architecture Behavioral of memory is
subtype word is STD_LOGIC_VECTOR(7 downto 0);
type fifo_memory_t is array (0 to size-1) of word;
signal fifo_memory : fifo_memory_t :=((others=> (others=>'0')));
--Functionality instructions:
--Resetting sets the queue pointer to the first element, and done to 0
--Each cycle with enable active, a datum from the pointer position is
--written/read according to write_readNEG, and the pointer is incremented.
--If the operation was at the last element, the pointer returns to the first place
--and done is set to 1. When done is 1, enable is ignored.
Begin
process(clk,reset)
variable done_buf : std_logic;
variable queue_pointer: natural range 0 to size-1;
begin
if(reset = '1') then
queue_pointer := 0;
done_buf := '0';
elsif(rising_edge(clk)) then
if(done_buf = '0' and enable = '1') then
case write_readNEG is
when '0' =>
data_out <= fifo_memory(queue_pointer);
when '1' =>
fifo_memory(queue_pointer) <= data_in;
when others => null;
end case;
if(queue_pointer = size-1) then
done_buf := '1';
queue_pointer := 0;--check
else
queue_pointer := queue_pointer + 1;
end if;
end if; --enable x not done if
end if; --reset/rising edge end if
done <= done_buf;
end process;
End Behavioral;
More details inspired by the first comment:
The memory can read the data at the same cycle enable is activated, as seen here:
Notice how the "1", the value when enable is turned active, is actually written into the memory.
Unfortunately, the piece of code is in the asynchronous process! Although I'm VERY strongly thinking of moving to a single-process description.
In contrast to all the circuits I've designed until now, it is very hard for me to test it via simulation. This is a project in my university, where we download our vhdl programs to a xilinx spartan 3 FPGA. This time, we have been given a unit which transfers data between Matlab and the FPGA's SRAM (the functionality of which, I have no idea). Thus, I have to use this unit to transfer the data between the SRAM and my memory module. This means, in order to simulate, my testbench file will have to simulate the given unit! And this is hard..suppose I must try it, though...
first of all, whether to use a single process or a dual process type of FSM notation is a matter of preference (or company coding style rules). I find single process notation easier to write/read/manage.
your enable signal will have an effect on your memory code only after the next rising clock edge. the done signal related to the actual memory state will therefore be available one clock cycle after updating enable. I guess (and hope! but it's not visible in your posted code), your current_state<=next_state part of the FSM is synchronous! therefore your state machine will be in the SRAM_wait_read state by the time when done is updated!
btw: use a simulator! it will help to check the functionality!
thanks for adding the simulation view! strangely your done signal updates on neg. clock edge... in my simulation it updates on pos. edge; as it should, by the way!
to make the situation more clear I suggest, you move the done <= done_buf; line inside the "rising_edge-if" (this should be done anyhow when using synchronous processes!).

Resources