State machine with D Flip Flop

W

Wouter

Hi list,

For education purposes I am building a state machine. I made the state
tables, simplification with karnaugh maps, state table for the output
y and created the following VHDL code:
--
library IEEE;
use IEEE.std_logic_1164.all;

entity d_ff is
port (d, clk, reset : in std_logic; q : out std_logic);
end d_ff;

architecture gedrag_dff of d_ff is
begin
ff_behavior : process is
begin
wait until (clk'event and clk='1');
if (reset = '1') then
q <= '0';
else
q <= d;
end if;
end process;
end gedrag_dff;
--


-----------------------------------------------------
ENTITY systeem IS
port ( x, clk, reset : in std_logic;
y: out std_logic_vector(2 downto 0)
);
END systeem;
-----------------------------------------------------

ARCHITECTURE fsm OF systeem IS

-- Transition functions
--
-- d2 = Q1'.Q0'.X'Q2 + Q1.Q0'.X'.Q2'
-- d1 = Q1.Q0.X'.Q2' + Q1'.X.Q2'
-- d0 = Q1'.Q0'.X'.Q2 + Q0.X.Q2' + Q1.X.Q2' + Q1.Q0.Q2'
--
-- Output functions
--
-- y2 = Q2'.Q0
-- y1 = Q2.Q1'.Q0' + Q2'.Q1'.Q0 + Q2'.Q1.Q0'
-- y0 = Q2'.Q1.Q0 + Q2.Q1'.Q0'

SIGNAL d2, d1, d0 : std_logic;
SIGNAL q2, q1, q0 : std_logic;

BEGIN
-- next state selection
d2 <= (NOT q1 AND NOT q0 AND x AND NOT q2) OR (q1 AND NOT q0 AND NOT
x AND NOT q2);
d1 <= (q1 AND q0 AND NOT x AND NOT q2) OR (NOT q1 AND x AND NOT q2);
d0 <= (NOT q1 AND NOT q0 AND NOT x AND q2) OR (q0 AND x AND NOT q2)
OR (q1 AND x AND NOT q2) OR (q1 AND q0 AND NOT q2);

DFF2: ENTITY WORK.d_ff PORT MAP (d2, clk, reset, q2);
DFF1: ENTITY WORK.d_ff PORT MAP (d1, clk, reset, q1);
DFF0: ENTITY WORK.d_ff PORT MAP (d0, clk, reset, q0);

-- result of the output functions
y(2) <= NOT q2 AND q0;
y(1) <= (q2 AND (NOT q1) AND (NOT q0)) OR ((NOT q2) AND (NOT q1) AND
q0) OR ( (NOT q2) AND q1 AND (NOT q0) );
y(0) <= (NOT q2 AND q1 AND q0) OR (q2 AND NOT q1 AND NOT q0);

END fsm;

I have tested the functions manually in the simulator of Modelsim.
This is cumbersome as you can imagine, so i tried creating the
following test bench:

--
entity systeem_tb is
end systeem_tb;

architecture TB of systeem_tb is


component systeem
port ( x, clk, reset : in std_logic;
y: out std_logic_vector(2 downto 0)
);
end component;

signal x: std_logic := '0';
signal clk: std_logic := '0';
signal reset: std_logic := '1';
signal y: std_logic_vector(2 downto 0);

begin
uut: systeem port map(x => x, clk => clk, reset => reset, y => y);

clk_proc : process
begin
clk <= '0';
wait for 5 ns;
clk <= '1';
wait for 5 ns;
end process;

stim_proc : process
begin

-- simulation step 1:
reset <= '0' AFTER 11 ns;
x <= '1' AFTER 16 ns;
x <= '0' AFTER 26 ns;

wait;

end process;

end;
--

The problem is: signal x never goes to one. It always stays zero. I
have tried all kind of things, such as changing the waiting times, not
assigning default values, et cetera. I am pretty certain my logic in
the state machine is correct
(checked manually). I am obviously doing something wrong, but I am in
the dark. I don't know where to go from here. Could you give me some
pointers? Thank you,

Wouter
 
R

Rob Gaddi

[snip]

stim_proc : process
begin

-- simulation step 1:
reset <= '0' AFTER 11 ns;
x <= '1' AFTER 16 ns;
x <= '0' AFTER 26 ns;

wait;

end process;

end;
--

The problem is: signal x never goes to one. It always stays zero. I
have tried all kind of things, such as changing the waiting times, not
assigning default values, et cetera. I am pretty certain my logic in
the state machine is correct
(checked manually). I am obviously doing something wrong, but I am in
the dark. I don't know where to go from here. Could you give me some
pointers? Thank you,

Wouter

I think your problem is with inertial delay versus transport delay. By
assigning the same signal sequentially with all those different delays,
your last assignment of 0 is squelching your earlier one.

Without taking the time to test it, I believe that:

x <= '1' AFTER 16 ns, '0' AFTER 26 ns;

would work.
 
W

Wouter

Without taking the time to test it, I believe that:

  x <= '1' AFTER 16 ns, '0' AFTER 26 ns;

would work.

Thank you so much, your code solved that particular problem.

However, my output, y, stays 000. If reset is '0' and x = '1' the
output of y should change to 010. The flip flop is designed in such a
manner that on rising edge and on reset is zero the output is
configured; as seen in the code.

I'm wondering where to look. Is there something wrong with my
assignments to y(2), y(1) or y(0)? Or is this test bench related? I'm
quite new to VHDL; please excuse me for asking questions with
probably(?) obvious answers.

Wouter
 
M

Martin Thompson

Try this:
stim_proc : process
begin
-- simulation step 1:
wait for 11 ns;
reset <= '0';
wait for 16 ns; -- or maybe you want 5 ns?
x <= '1';
wait for 26 ns; -- or maybe 10 ns?
x <= '0';

wait;

end process;

Cheers,
Martin
 
P

Paul Uiterlinden

Wouter said:
Thank you so much, your code solved that particular problem.

However, my output, y, stays 000. If reset is '0' and x = '1' the
output of y should change to 010. The flip flop is designed in such a
manner that on rising edge and on reset is zero the output is
configured; as seen in the code.

I'm wondering where to look. Is there something wrong with my
assignments to y(2), y(1) or y(0)? Or is this test bench related? I'm
quite new to VHDL; please excuse me for asking questions with
probably(?) obvious answers.

Stop wondering and start analyzing.

If you say that you expect y(1) to go to '1', then first d(1) has to go
to '1'. Does it do that?

Trace the signals (you do know how to do that in the simulator, don't you?)
and check the observed behaviour against your expected behaviour.

I also would suggest to start simple (one flip-flop for example), test that,
and if that works add more functionality.
 
W

Wouter

Paul said:
Stop wondering and start analyzing.

You are right. It is working now. The problem was that my boolean
algebra was bogus. The transition functions were not correct. The code
itself, assignments, et cetera, are fully functional. Thanks.

Wouter
 
R

Rob Gaddi

You are right. It is working now. The problem was that my boolean
algebra was bogus. The transition functions were not correct. The code
itself, assignments, et cetera, are fully functional. Thanks.

Wouter

Glad you've got it working. That said, there's an issue at the
fundamental premise level of what you're working on. I don't know
anyone who designs state machines at the level of Karnaugh maps and
Boolean algebra in VHDL. The entire point of a high-level language
like VHDL is to move your design to a more manageable level. So
instead of all that, you'd have something like the following.

type t_state is (IDLE, THIS, THAT, THEOTHER);
signal state : t_state := IDLE;

....

case state is
when IDLE =>
if (go = '1') then
state <= THIS;
end if;

when THIS =>
...
end case;

Educational purposes are good, but hopefully one of the things you've
just educated yourself about is that trying to design state machines
that way is complicated, time-consuming, and generally error prone.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top