I'm writing vhdl code for a jk-flip-flop on modelsim and i get an error when i try to simulate it: Error: Iteration limit reached at time 0 ns.
I'm not sure what it means, but I've looked through much of my source code for errors to no success. Can anyone guess what the problem might be?
library ieee;
use ieee.std_logic_1164.all;
entity SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end SRlatch;
architecture structural of SRlatch is
begin
Q <= S nand QN;
QN <= R nand Q;
end;
entity JKFlipFlopStruct is
port(J,K,clk : in bit ; Q : inout bit ; QN : inout bit);
end JKFlipFlopStruct;
architecture structural of JKFlipFlopStruct is
component SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end component;
signal J0,K0,J1,K1,J2,K2 : bit;
begin
J0 <= not ( J and QN and clk) );
K0 <= not ( K and Q and clk) );
f1 : SRlatch port map ( J0,K0,J1,K1 );
J2 <= not ( J1 and (not clk) );
K2 <= not ( K1 and (not clk) );
f2 : SRlatch port map ( J2,K2,Q,QN );
end structural;
[JK Flop Flop negative edge triggered]
see image :http://i.stack.imgur.com/J3m1J.gif
As Russell say, this error usually indicates that ModelSim is stuck in an infinite loop. In VHDL, this can happen when a signal is placed in the sensitivity list and this signal is changed in the process.
A simple example:
process (sig)
begin
sig <= not sig;
end;
Your problem is also in this case. But there are some differences.
1. For any concurrent signal assignment statement, there is an equivalent process statement with the same meaning. (See VHDL LRM 93 $9.5 for more details)
So, in your code,
J0 <= not ( J and QN and clk) );
is short hand notation for
process
begin
J0 <= not ( J and QN and clk) );
wait on J, QN, clk;
end process;
or
process (J, QN, clk)
begin
J0 <= not ( J and QN and clk) );
end process;
Others concurrent statements are the same.
2. About simulation cycle (See VHDL LRM 93 $12.6.4 and Delta Delays)
In eacy cycle, the values of all signals in the description are computed. If as a result of this computation an event occurs on a given signal, process statements that are sentitive to that signal will resume and will be executed as part of the simulation cycle.
In your code:
f2 : SRlatch port map ( J2,K2,Q,QN );
it's equivalent process:
process (J2, K2)
begin
Q <= J2 nand QN;
QN <= K2 nand Q;
end process;
along with other processes make an infinite loop.
For example,
the J-K Flip-Flop is stable # 100 ns + 0 delta time
J or K or clk changes # 100 ns + 0 delta time
J0 or K0 \ ---
J1 or K1 |__ cost several delta times
J2 or K2 | Suppose that Q changes # 100 ns + 3 delta time
Q or QN changes / ---
Then the value of K0 will change again!!
This result in a infinite loop becase 100 ns + n delta time = 100 ns. Time never advanceds.
Solutions:
1.Make your design a sequential one (ie. use a synchronic clock).
process (clk)
begin
if (rising_edge(clk)) then
-- signal assignment
end if;
end process;
2.Use delay assignment. So, in the SRlatch.vhd, you should write
Q <= S nand QN after 1 ns;
QN <= R nand Q after 2 ns;
Unsymmetrical delay is used to ensure that either Q or QN sets up first and then feedbacks to set the other one.
Also refer to a similar question: Debugging Iteration Limit error in VHDL Modelsim.
Iteration limit means that you have created a feedback loop in your design and you made the simulator very angry! It cannot resolve the loop.
Use a clocked process to set J0 and K0.
jk_flippy_floppy : process (clk)
begin
if rising_edge(clk) then
J0 <= not ( J and QN );
K0 <= not ( K and Q );
end if;
end process jk_flippy_floppy;
library ieee;
use ieee.std_logic_1164.all;
entity SRlatch is
port(S,R:in bit; Q : inout bit := '0' ; QN : inout bit := '1');
end SRlatch;
architecture structural of SRlatch is
begin
Q <= S nand QN;
QN <= R nand Q;
end structural;
entity JKFlipFlopStruct is
port(J,K,clk : in bit ; Q : inout bit ; QN : inout bit:= '1');
end JKFlipFlopStruct;
architecture structural of JKFlipFlopStruct is
component SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end component;
signal J1 : bit;
signal J0,K0,K1,J2,K2 : bit:= '1';
begin
J0 <= not ( J and QN and (not clk) );
K0 <= not ( K and Q and (not clk) );
f1 : SRlatch port map ( J0,K0,J1,K1 );
J2 <= not ( J1 and clk );
K2 <= not ( K1 and clk );
f2 : SRlatch port map ( J2,K2,Q,QN );
end structural;
this is the correct code
Related
I have written a simple vhdl code to enable/disable an output port by some control signals under some conditions. Problem is that the output signal is either U or X while the code looks fine.
The main entity is shown below. the first process is sensitive to rst and will disable oe when it is 1. The second process is sensitive to clk and will enable the oe on clock transition. The output value is also set to 5.
entity test2 is
port( clk: in std_logic;
rst: in std_logic;
num: out integer range 0 to 7;
oe: out std_logic );
end;
architecture behav of test2 is
begin
process( rst )
begin
if rst = '1' then
oe <= '0';
end if;
end process;
process( clk )
begin
if (clk'event and clk = '1') then
num <= 5;
oe <= '1';
end if;
end process;
end;
Now consider the testbench file. As can be seen, in the main process, I set r which is connected to rst to 1 and then 0.
entity test2_tb is
end;
architecture behav of test2_tb is
component test2 port( clk: in std_logic;
rst: in std_logic;
num: out integer range 0 to 7;
oe: out std_logic );
end component;
signal c: std_logic := '0';
signal r: std_logic;
signal n: integer range 0 to 7 := 2;
signal o: std_logic;
begin
u1: test2 port map( c, r, n, o );
process( c )
begin
c <= not c after 2ns;
end process;
process
begin
r <= '1';
wait for 4 ns;
r <= '0';
wait for 8 ns;
end process;
end;
While r is 1, the o which is connected to oe is set to U. Why? Moreover, on the raising edge of the clock, the value of o becomes X. Why? please see the waves below
To make it short: your oe port should probably not be of type std_logic but std_ulogic (same for clk and rst) and it should probably be driven by one single process instead of two:
process(clk)
begin
if clk'event and clk = '1' then
if rst = '1' then
oe <= '0';
else
num <= 5;
oe <= '1';
end if;
end if;
end process;
Or, if you prefer an asynchronous reset:
process(clk, rst)
begin
if rst = '1' then
oe <= '0';
elsif clk'event and clk = '1' then
num <= 5;
oe <= '1';
end if;
end process;
In case your tools do not support std_ulogic properly (unfortunately there are logic synthesizers that do not support std_ulogic, at least in the top level), use std_logic but be very careful to always drive your output ports (and internal signals) in one single process, except in very specific situations where you really want several pieces of hardware to concurrently drive the same hardware wire, which is quite rare (tri-state logic, high impedance...)
The processes will continue to drive their values even after you made the assignment to oe (because you never told them to do anything else). One driving 0 an one driving 1 gives an X. Merge the two processes into one with an if-elsif statement. With only one driver there's no conflict. Initially the are both driving U.
It should output value of Qpl when all inputs are x and clk = 1 but it does not. What is the problem with the following code;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--This is a D Flip-Flop with Synchronous Reset,Set and Clock Enable(posedge clk).
--Note that the reset input has the highest priority,Set being the next highest
--priority and clock enable having the lowest priority.
ENTITY syn IS
PORT (
Q : OUT std_logic; -- Data output
CLK : IN std_logic; -- Clock input
Qpl : IN std_logic;
RESET : IN std_logic; -- Synchronous reset input
D : IN std_logic; -- Data input
SET : IN std_logic -- Synchronous set input
);
END syn;
ARCHITECTURE Behavioral OF syn IS --architecture of the circuit.
BEGIN
--"begin" statement for architecture.
PROCESS (CLK) --process with sensitivity list.
BEGIN
--"begin" statment for the process.
IF (CLK'EVENT AND CLK = '1') THEN --This makes the process synchronous(with clock)
IF (RESET = '1') THEN
Q <= '0';
ELSE
IF (SET = '1') THEN
Q <= D;
ELSE
Q <= Qpl;
END IF;
END IF;
END IF;
END PROCESS; --end of process statement.
END Behavioral;
Following diagram is showing the waveform of the above design, and desired operation requirements;
From the waveform diagram, it seems that everything works alright, when the input signal SET becomes U, the if condition cannot be evaluated, thus the output Q also becomes as such, namely U. You can see while SET was 0, the output Q was getting the value of Qpl correctly.
Sorry for the crude drawing, but you can see at the circled clock rising while SET is 0, Q gets the value of Qpl as expected. Only after SET signal becomes U, the output Q also loses its value in the next clock rising event, and also becomes U
You code and comments differ. As does the table/diagram. A D-flipflop/register is a very simple component. Example:
entity dff is
port (
clk : in std_logic;
rst : in std_logic;
set : in std_logic;
load : in std_logic;
d : in std_logic;
q : out std_logic
);
architecture rtl of dff is
begin
dff_proc : process(clk)
begin
if rising_edge(clk) then
if rst='1' then
q <= '0';
elsif set='1' then
q <= '1';
elsif load='1' then
q <= d;
end if;
end if;
end process;
end architecture;
I am trying to detect changes in the input signals of my Selector. When I find the first input that changed (either rising or falling edge), I give an index as output. When I try to synthesize my source code, I get an error "unsupported Clock statement". A also tried to use "rising_edge" and "falling_edge", but I got the same error.
Here is my code
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
begin
process(X1,X2,X3,X4,X5,X6)
begin
if (X1'event) then
O <= "000";
elsif (X2'event) then
O <= "001";
elsif (X3'event) then
O <= "010";
elsif (X4'event) then
O <= "011";
elsif (X5'event) then
O <= "100";
elsif (X6'event) then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
Is there an alternative solution for that?
You would need an additional clock input to make a comparison between the value of X1, X2, ... in the current clock cycle and the value in the last clock cycle. If the Xes are asynchronous to the clock you have to synchronize them first.
Input synchronisation
To synchronize the inputs to the clock, you have to sample each input with two D flip-flops in serial. The output of the first flip-flop may be harmed by metastability problems which is described in more detail in these papers:
Ran Ginosar: Metastability and Synchronizers: A Tutorial
Sunburst Design: Synthesis and Scripting Techniques for Designing Multi-
Asynchronous Clock Designs
The connection between both flip-flops (for each input) must be constrained so that the rounting path between them is as short as possible. The implementation below will just show the two flip-flops. A more advanced implementation can be found in the sync_Bits component of the PoC Library where I am one of the authors.
Comparison
Once the input is synchronous to the clock, just delay it another clock cylce. This will make up the last value, so that, you can compare the current values to the last values to detect a signal change. The frequency of the input clock must be much faster than the frequency of change on one of the X inputs:
to get a fast repsonse of the edge-detection, and
to catch all signal changes.
Here is a possible implementation:
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
clk : in std_logic;
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
signal X : std_logic_vector(6 downto 1); -- all inputs in one vector
signal X_meta : std_logic_vector(6 downto 1); -- first sampling stage
signal X_curr : std_logic_vector(6 downto 1); -- second sampling stage =
-- current value
signal X_last : std_logic_vector(6 downto 1); -- last value of X_curr
begin
-- Concatenate all inputs to one vector for shorter code below.
X <= X6 & X5 & X4 & X3 & X2 & X1;
-- Synchronize external inputs to clock. If the X* inputs are already
-- synchronous to 'clk' then replace this process with:
-- X_curr <= X;
sync: process(clk)
begin
if rising_edge(clk) then
-- The path betweeen these two flip-flops must be constrained for a
-- short delay, so that, the wire in between is as ahort as
-- possible.
X_meta <= X;
X_curr <= X_meta;
end if;
end process;
-- This statement delays the current value X_curr by one clock cycle.
X_last <= X_curr when rising_edge(clk);
-- Comparison and selector output.
process(X_curr, X_last)
begin
if (X_curr(1) xor X_last(1)) = '1' then
O <= "000";
elsif (X_curr(2) xor X_last(2)) = '1' then
O <= "001";
elsif (X_curr(3) xor X_last(3)) = '1' then
O <= "010";
elsif (X_curr(4) xor X_last(4)) = '1' then
O <= "011";
elsif (X_curr(5) xor X_last(5)) = '1' then
O <= "100";
elsif (X_curr(6) xor X_last(6)) = '1' then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
I am posting a Code for JK Flip flop in VHDL language. the code is correct according to the JK flip flop circuit. but i got output as red line. can any one tell me the what is the problem with only JK flip flop only.
Programme: JK Flip Flop
----------=======NAnd Gate with three inputs=====---------------
library ieee;
use ieee.std_logic_1164.all;
entity nand_gate3 is port(
A, B, C : in std_logic;
F : out std_logic);
end nand_gate3 ;
architecture nandfunc3 of nand_gate3 is
signal x : std_logic ;
begin
x <= A nand B ;
F <= x nand C ;
end nandfunc3;
------====== END NANd GATE with three inout ======--------
----=========NANd Gate with Two inputs==========------------
library ieee;
use ieee.std_logic_1164.all;
entity nand_gate2 is port(
A, B : in std_logic;
F : out std_logic );
end nand_gate2;
architecture nandFunc2 of nand_gate2 is
begin
F <= A nand B ;
end nandFunc2;
------====== END NANd GATE with three inout ======-
library ieee;
use ieee.std_logic_1164.all;
ENTITY JK_flipflop IS PORT (
clk , J, K : IN std_logic;
Q , Q_bar : OUT std_logic );
END JK_flipflop ;
architecture JK_structure OF JK_flipflop IS
----===Compnents
COMPONENT nand_gate3 IS PORT (
A, B ,C : IN std_logic ;
F : OUt std_logic );
End Component ;
COMPONENT nand_gate2 IS PORT (
A, B : IN std_logic ;
F : OUt std_logic );
End Component ;
Signal X, Y , Qback ,Qbar_back: std_logic ;
----== Structure
Begin
U1: nand_gate3 PORT MAP ( J, clk, Qbar_back, X );
U2: nand_gate3 PORT MAP ( K, clk, Qback ,Y );
U3: nand_gate2 PORT MAP ( X, Qbar_back ,Qback);
U4: nand_gate2 PORT MAP ( Y, Qback ,Qbar_back);
Q <= Qback;
Q_bar <= Qbar_back;
END JK_structure ;
--------------------Test Bench for JK flip flop----===
library ieee;
use ieee.std_logic_1164.all;
entity jk_flipflop_tb is
end jk_flipflop_tb ;
architecture tb of jk_flipflop_tb is
---====Jk_flipflop
component JK_flipflop is port(
clk,J , K : in std_logic;
Q, Q_bar : out std_logic);
end component;
---===signals
signal clk,J ,K , Q, Q_bar : std_logic;
begin
mapping: JK_flipflop port map(clk, J, K, Q, Q_bar);
-------=========Process for Clcok ===========---------------
process
begin
clk <= '1';
wait for 5 ns;
clk <= '0';
wait for 5 ns;
end process;
--------===========Process for j,k inputs values=======--------------
process
begin
-------===TEST 1
J <= '0';
K <= '1';
wait for 20 ns;
-------====TEST 2
J <= '1';
K <= '1';
wait for 20 ns;
-------====TEST 3
J <= '1';
K <= '0';
wait for 20 ns;
-------====TEST 4
J <= '0';
K <= '0';
wait for 20 ns;
end process;
end tb;
--------------------------------------------
configuration cfg_tb of jk_flipflop_tb is
for tb
end for;
end cfg_tb;
---------======------
JK flip flops must have a reset port to initialize outputs, Otherwise because outputs (Q , Qbar) are set by themselves (feedback), if they don't have any initial value, they are always undefined. Then you should add a reset port to your design.
You can use the following code to get the correct result :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity JK_FF is
port(
Reset : in std_logic;
Clock : in std_logic;
J,K : in std_logic;
Q,Qbar : out std_logic
);
end JK_FF;
architecture Behavioral of JK_FF is
signal temp : std_logic;
begin
process (Clock)
begin
if rising_edge(Clock) then
if Reset='1' then
temp <= '0';
else
if (J='0' and K='0') then
temp <= temp;
elsif (J='0' and K='1') then
temp <= '0';
elsif (J='1' and K='0') then
temp <= '1';
elsif (J='1' and K='1') then
temp <= not (temp);
end if;
end if;
end if;
end process;
Q <= temp;
Qbar <= not temp;
end Behavioral;
Your logic seems to be faulty. The right logic is:
Q = (J and Qbar_back) nand clk nand Qbar_back
Qbar = (K and Q_back) nand clk nand Q_back
The and operation is a nand operation in your logic.
Description:
I am trying to generate a test bench for a 5 state sequential state machine that detects 110 or any combination of (2) 1's and (1) 0. I already have written the code. see below. I am having trouble with the test bench which is wrong. I want to test for all possible sequences as well as input combinations that are off sequence.
Please give me examples of a good test bench to achieve what I need for a mealy machine.
vhdl code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity state is
port( clk, x : in std_logic;
z : out std_logic
);
end entity;
architecture behavioral of state is
type state_type is (s0,s1,s2,s3,s4);
signal state,next_s: state_type;
------------------------------------------------------------------------------
begin
process (state,x)
begin
if clk='1' and clk'event then
case state is
when s0 =>
if(x ='0') then
z <= '0';
next_s <= s4;
else
z <= '0';
next_s <= s1;
end if;
when s1 => --when current state is "s1"
if(x ='0') then
z <= '0';
next_s <= s3;
else
z <= '0';
next_s <= s2;
end if;
when s2 => --when current state is "s2"
if(x ='0') then
z <= '1';
next_s <= s0;
else
z <= '0';
next_s <= s0;
end if;
when s3 => --when current state is "s3"
if(x ='0') then
z <= '0';
next_s <= s0;
else
z <= '1';
next_s <= s0;
end if;
when s4 => --when current state is s4
if (x = '0') then
z <= '0';
next_s <= s0;
else
z <= '0';
next_s <= s3;
end if;
end case;
end if;
end process;
end behavioral;
Test Bench code:
library ieee;
use ieee.std_logic_1164.all;
-- Add your library and packages declaration here ...
entity state_tb is
end state_tb;
architecture TB_ARCHITECTURE of state_tb is
-- Component declaration of the tested unit
component state
port(
clk : in STD_LOGIC;
x : in STD_LOGIC;
z : out STD_LOGIC );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal clk : STD_LOGIC;
signal x : STD_LOGIC;
-- Observed signals - signals mapped to the output ports of tested entity
signal z : STD_LOGIC;
-- Add your code here ...
begin
-- Unit Under Test port map
UUT : state
port map (
clk => clk,
x => x,
z => z
);
-- CLOCK STIMULI
CLOCK: process
begin
CLK <= not clk after 20 ns;
wait for 40 ns;
end process;
-- X input STIMULI
X_Stimuli: process
begin
X <= not x after 40 ns;
wait for 80 ns;
end process;
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_state of state_tb is
for TB_ARCHITECTURE
for UUT : state
use entity work.state(behavioral);
end for;
end for;
end TESTBENCH_FOR_state;
These are some problems with both the FSM code and the testbench code in your example, but the main issue is that to test an FSM you need t apply a sequence of input values and check the outputs. You can't just toggle your input signal between 1 and 0. So, here's some advice:
First, you have to decide whether you want a generic FSM that detects any input sequence, or a
FSM that detects only a single sequence (your code shows the second option)
You need to consider the time dimension in your test. Yours is a clocked circuit, meaning that each test will take several clock cycles.
To test every possible input sequence, I suggest that you create a procedure that takes as arguments:
A sequence of 4 input values to the FSM (could be a std_logic_vector)
A sequence of 4 output values that you expect to see
(optionally) a sequence of the 4 states you expect the FSM will go through
Your procedure could look like:
procedure test_sequence(
input_sequence: std_logic_vector;
expected_output_sequence: std_logic_vector
) is begin
for i in input_sequence'range loop
x <= input_sequence(i);
wait until rising_edge(clk);
assert z = expected_output_sequence(i);
end loop;
end;
Then, in your main tests process, you can test one sequence with:
test_sequence(
input_sequence => "110",
expected_output_sequence => "001"
);
Some other suggestions:
You should add a reset signal to make testing easier and to prevent mismatchs between simulation and synthesis
There is no need for a configuration in your case, you can remove it from your code
Your FSM code is incomplete because you never update your current state
In a testbench like the one you are using, you need to initialize the signals used as input to the DUT (x and clk)
Note that the procedure above needs to be inside a process' declarative region. Something like:
main_test_process: process is
procedure test_sequence(
input_sequence: std_logic_vector;
expected_output_sequence: std_logic_vector
) is begin
for i in input_sequence'range loop
x <= input_sequence(i);
wait until rising_edge(clk);
assert z = expected_output_sequence(i);
end loop;
end;
begin
test_sequence( input_sequence => "000", expected_output_sequence => "000");
test_sequence( input_sequence => "001", expected_output_sequence => "000");
-- (add any other input sequences here...)
test_sequence( input_sequence => "110", expected_output_sequence => "001");
std.env.finish;
end process;
should work.
Your statemachine has the following possible cycles with 2 or 3 steps before going back to s0 and correctly detects sequencies of two 1s.
Case (x1,x2,x3) States (z1,z2,z3)
0 0,0,0 4,0,... 0,0,... (starts again at s0)
1 0,0,1 4,0,... 0,0,... (starts again at s0)
2 0,1,0 4,3,0 0,0,0 (covered by your TB)
3 0,1,1 4,3,0 0,0,1
4 1,0,0 1,3,0 0,0,0
5 1,0,1 1,3,0 0,0,1 (covered by your TB)
6 1,1,0 1,2,0 0,0,1
7 1,1,1 1,2,0 0,0,0
As I see it your creating you're stimuli as follows
__ __ __ __ __
clk __| |__| |__| |__| |__| |__...
_____ _____ _____
x _____| |_____| |_____| |...
I.e. because in each section with x=1 you have exactly one rising clock and therefore you're only testing sequencies with a 0101010... pattern, where your statemachine would go on one of the two paths marked in the table above. This means that the other 6 possible pathes are never executed in your testbench.
Since this statemachine has a small and finite number of paths I would recommend an exhaustive test where you would essentially cycle through the 8 possible cases listed above; this could be easily implemented with a 3bit counter. So you would create a sequence in the form
reset
test-case 0 (sequence 0,0,0)
reset
test-case 1 (and so on)
That would require you to add a reset to the entity state. Alternatively you could modify your statemachine to remain in s0 with a zero-input; then you could reset with a sequence of 0,0,0 at any time.