Skip to content

5.6 Testing FSMs

Why this matters

A state machine that works for the inputs you tried can still be wrong on the ones you did not. Because the behavior of a machine is its arrows, a practical baseline for testing it is to make sure that every arrow gets taken, with both its destination and its output checked. That is transition coverage, and it is a minimum, not a proof: the end of the section says what it leaves out. This section turns the idea into a plan you can carry out: a short list of inputs, one testbench line for each, and a waveform you know how to read.

  • Plan a test that takes every arrow of a state diagram from reset, and write it as a table of cycles.
  • Turn a plan into a testbench with one line per clock cycle and a comment that names the state.
  • Count the clock cycles of a test, saying which cycles are included.
  • Read a simulation for the three things a test must show: reset works, every arrow is taken, every output is right.
  • Find the arrow that fails in a waveform from a machine with a bug.

Think of checking a new road map by driving it. You do not need to drive every possible route, because there are far too many, but you do need to drive every road at least once, or a missing bridge on a road you skipped will stay hidden until a customer finds it. The state diagram is the road map, the arrows are the roads, and a test is a route that starts at the depot, the reset state. A good route drives every road, and it re-drives some of them only when that is the only way to get back to a junction you still need.

Two things come with driving a road. You check that you ended up where the map says (the state), and you check what the map says happens along the way (the output). A drive that does not look at either has tested nothing.

Definition 5.6.1(transition tour).

A transition tour is a sequence of inputs, applied one per clock cycle starting from the reset state, whose walk through the state diagram takes every arrow at least once. Arrows for input combinations that can never occur are not part of the tour.

An arrow that is not taken is an arrow that is not tested. The self-loops and the "no coin" arrows are easy to skip because they look boring, but they are arrows like any other, and a bug can sit in them. The tour has to take them all.

The arrows counted in this section are the arrows of the machine's specification, which lists each one separately even when the diagram draws two of them as a single arrow with a plus sign in its label. The arrows for combinations marked as don't cares are left out, because the machine is never asked to handle them.

The book counts the cycles of a test the way the tour table of Section 5.2 did, and tour numbers are what every "cycle" of this section means. The first cycle is the one in which reset is asserted, which the tour table calls cycle 0, and the machine is in its initial state after the edge that ends it. (The scenario tables of Sections 5.4 and 5.5 call the first cycle after reset cycle 0, so cycle kk of a scenario is cycle k+1k+1 of a tour table.) After that, every arrow taken is one cycle. The testbench then adds one more cycle at the end, so that the effect of the last input can be seen, and that extra cycle is not counted. So a test that takes kk arrows takes k+1k + 1 cycles with the reset cycle, and k+2k+2 lines of testbench if the extra cycle is written out.

Example 5.6.1(a tour of the gumball machine).

The gumball machine of Section 5.4 has six arrows to take. We start at reset, in 0¢, and plan a walk. A program searched every possible walk, and the table below is a shortest one: no shorter walk takes every arrow. The input columns follow the order N, D.

Exact. No walk from the start state that takes every arrow without a reset is shorter than this one.

8 cycles: 1 reset cycle, then 7 arrows taken. The machine has 6 arrows.

Test plan for ch05/vending: one row per clock cycle after the first reset cycle; 8 cycles: 1 reset cycle, then 7 arrows taken. The machine has 6 arrows.
CycleStateInputs N DNext stateOutput OpenArrow
0reset asserted: the machine starts in 0¢
10¢000¢01
20¢105¢02
35¢005¢04
45¢100¢15
50¢105¢02
65¢010¢16
70¢010¢13

The tour in words:

  • Cycle 0: reset asserted, the machine starts in 0¢.
  • Cycle 1: in 0¢ with N=0, D=0, arrow 1 goes to 0¢, output 0.
  • Cycle 2: in 0¢ with N=1, D=0, arrow 2 goes to 5¢, output 0.
  • Cycle 3: in 5¢ with N=0, D=0, arrow 4 goes to 5¢, output 0.
  • Cycle 4: in 5¢ with N=1, D=0, arrow 5 goes to 0¢, output 1.
  • Cycle 5: in 0¢ with N=1, D=0, arrow 2 goes to 5¢, output 0.
  • Cycle 6: in 5¢ with N=0, D=1, arrow 6 goes to 0¢, output 1.
  • Cycle 7: in 0¢ with N=0, D=1, arrow 3 goes to 0¢, output 1.

The numbers in the last column are the arrows of the diagram, numbered as in Figure 5.4.3 of Section 5.4, which is repeated here.

State diagram of vendingState diagram of vending: a Mealy machine with 2 states (0¢, 5¢). The initial state is 0¢, marked by an arrow that comes from no state. Arrow 1: from 0¢ when N=0, D=0, output 0, go to 0¢. Arrow 2: from 0¢ when N=1, D=0, output 0, go to 5¢. Arrow 3: from 0¢ when N=0, D=1, output 1, go to 0¢. Arrow 4: from 5¢ when N=0, D=0, output 0, go to 5¢. Arrow 5: from 5¢ when N=1, D=0, output 1, go to 0¢. Arrow 6: from 5¢ when N=0, D=1, output 1, go to 0¢. Inputs, in label order: N, D. Outputs: Open. Each arrow carries its number, the one the test plan table uses.ND/01ND/02ND/13ND/04ND/15ND/160¢5¢start

Description: State diagram with two circles, 0 cents and 5 cents, a starting arrow into 0 cents, and a number from 1 to 6 beside each of the six arrows.

Figure 5.6.1. The gumball machine with its arrows numbered, as the tour table uses them.

Six arrows take seven cycles after the reset cycle, because one arrow is taken twice. The reason is that 5¢ has two arrows that lead out of it, arrow 5 (5¢ to 0¢ when N=1, D=0, output 1) and arrow 6 (5¢ to 0¢ when N=0, D=1, output 1), and the only way into 5¢ is arrow 2 (0¢ to 5¢ when N=1, D=0, output 0). To take both of the two leaving arrows, the walk has to be in 5¢ twice, and so it enters through arrow 2 twice, once at cycle 2 (in 0¢ with N=1, D=0, arrow 2 to 5¢, output 0) and again at cycle 5 (in 0¢ with N=1, D=0, arrow 2 to 5¢, output 0). With the reset cycle that makes 8 cycles.

In SystemVerilog: from the table to a testbench

Section titled “In SystemVerilog: from the table to a testbench”

Each row of the table becomes one line of the testbench, in the shape that Section 5.2 introduced. The line sets the inputs of the cycle and waits for the clock edge that ends it, and its // expect: comment names the state the machine is in during that cycle, which is the table's State column, and the output of the arrow. The comment reports the state that the previous edge produced, as always. The first line of the testbench holds reset, and the line after the last row is the extra cycle.

vending_tour_tb.sv
// A second testbench for vending_machine: reset, then one walk that takes every arrow of the diagram, then one extra cycle.
module vending_tour_tb();
logic clk, reset, N, D, Open;
vending_machine dut(.*);
parameter CLOCK_PERIOD = 100;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD / 2) clk <= ~clk;
end
initial begin
reset <= 1; N <= 0; D <= 0; @(posedge clk);
reset <= 0; @(posedge clk); // expect: ps=C0, Open=0
N <= 1; @(posedge clk); // expect: ps=C0, Open=0
N <= 0; @(posedge clk); // expect: ps=C5, Open=0
N <= 1; @(posedge clk); // expect: ps=C5, Open=1
@(posedge clk); // expect: ps=C0, Open=0
N <= 0; D <= 1; @(posedge clk); // expect: ps=C5, Open=1
@(posedge clk); // expect: ps=C0, Open=1
D <= 0; @(posedge clk); // expect: ps=C0, Open=0
$stop;
end
endmodule

The book's tools run this testbench and check every comment against the simulation of the module and against the machine of Section 5.4, so a comment that disagrees with either fails the check.

Run it, and the waveforms are the evidence. Two figures cover the nine cycles.

Waveform ch05/vending-tour-a: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC0C5C0C5C0Open050100150200250300350400450500550600650time (ps)Waveform ch05/vending-tour-a: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC0C5C0C5C0Open050100150200250300350400450500550600650time (ps)Waveform ch05/vending-tour-a: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC0C5C0C5C0Open0100200300400500600time (ps)Waveform ch05/vending-tour-a: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC0C5C0C5C0Open0100200300400500600time (ps)Waveform ch05/vending-tour-a: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC0C5C0C5C0Open0100200300400500600time (ps)

Time in ps; one column is 50 ps.

Timing diagram from simulation, ch05/vending-tour-a: time in ps from 0 to 700, 14 columns of 50 ps.

clk: clock, period 100 ps, starts 0, 7 rising edges in the window (50, 150, 250, ...).

reset: 1 at 0, then 0 at 50.

N: 0 at 0, then 1 at 150, 0 at 250, 1 at 350, 0 at 550.

D: 0 at 0, then 1 at 550.

dut.ps (state names: C0, C5): unknown at 0, then C0 at 50, C5 at 250, C0 at 450, C5 at 550, C0 at 650.

Open: 0 at 0, then 1 at 350, 0 at 450, 1 at 550.

Dashed vertical guides mark the rising clock edges.

Description: A timing diagram of clk, reset, N, D, the state dut.ps and Open for the first seven clock cycles of the tour testbench.

Figure 5.6.2. The first seven cycles of the tour. Reset is high only in the first cycle.
Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)

Time in ps; one column is 50 ps.

Timing diagram from simulation, ch05/vending-tour-b: time in ps from 250 to 950, 14 columns of 50 ps.

clk: clock, period 100 ps, starts 1, 5 rising edges in the window (350, 450, 550, ...).

reset: 0 at 250, no changes.

N: 0 at 250, then 1 at 350, 0 at 550.

D: 0 at 250, then 1 at 550, 0 at 750.

dut.ps (state names: C0, C5): C5 at 250, then C0 at 450, C5 at 550, C0 at 650.

Open: 0 at 250, then 1 at 350, 0 at 450, 1 at 550, 0 at 750.

Dashed vertical guides mark the rising clock edges.

Description: A timing diagram of clk, reset, N, D, the state dut.ps and Open for the last cycles of the tour testbench.

Figure 5.6.3. The later part of the tour, from cycle 3 of the tour table to the extra cycle at the end.

A waveform of a tour is read for three things, in this order.

  1. Reset works. The state is unknown until the first clock edge with reset high, and the state after it is the initial state. In the first figure the state is drawn hatched before the first edge, and it is C0 after it. (The waveform writes the states by their names in the code, C0 and C5; the diagram and the table write them as 0¢ and 5¢.)
  2. Every arrow is taken. The sequence of states follows the table: compare each cycle's state and input with its row. The State column of the table is the state during the cycle, so the Next state of a row shows up on the waveform at the edge that ends that row's cycle.
  3. The outputs match. In every cycle, the output is the one on the arrow taken. The output of a Mealy machine depends on the input, so the question is what it is while that cycle's input is applied, which is just before the edge that ends the cycle.

Where the table says an arrow has output 1, look for Open high in that cycle: here, the cycles of cycle 4 (in 5¢ with N=1, D=0, arrow 5 to 0¢, output 1), cycle 6 (in 5¢ with N=0, D=1, arrow 6 to 0¢, output 1) and cycle 7 (in 0¢ with N=0, D=1, arrow 3 to 0¢, output 1).

The long-press detector of Section 5.2 has six arrows and needs a tour of 10 cycles, as Exercise 5.2.2 works out. That is more cycles than arrows for a similar reason: the last state has two arrows out, so the walk has to be there twice. The plan, the table and the testbench lines have the same shape for every machine, and only the table changes.

A tour is the minimum for a test, not everything a test could check, and passing it does not show that a machine is correct: a machine with extra hidden state can behave on the first visit to an arrow and differently on a later one. The checks that this book runs on its own modules go further than one walk. They also run each scenario of the machine's specification, they assert reset from every state that can be reached, and they sample every Mealy output at several points in each cycle, with the inputs changing a quarter of the way into the cycle, to see that the output follows the input and is stable until the next change. A reset that fails when the machine is in one particular state would pass a tour that resets only at the start, and an output that is wrong for part of a cycle and right again by the end would pass a test that looks at it only just before the edge. Those are the reasons for the extra checks, and they are what to add when a design matters.

How CSE 369 writes this

In CSE 369 we test by taking every arrow that can occur; arrows for input combinations marked as don't cares are left out. The testbench starts with a reset, defines every input at time zero, adds an extra cycle at the end to see the effect of the last input, and ends each line with a comment naming the current state. The count of cycles above follows the same pieces: the reset cycle is counted and the extra cycle is not.

Common pitfall

  • Skipping the arrows that look boring. Self-loops and "nothing happened" arrows are arrows too, and a bug in one of them is found only by taking it.
  • Checking the states and forgetting the outputs, or the other way round. An arrow is tested only when both its destination and its output are checked.
  • Counting cycles in different ways. State whether the reset cycle and the extra cycle at the end are included; the book counts the first and not the second.
  • Reading a line's comment as the state after its edge. The comment names the state during the cycle, which the previous edge produced.
  • Trusting a test written from the same table as the design. If the table is wrong, the design and the test are wrong in the same way; write the expected behavior from the description first.
Take the quiz (4 questions)

How many clock cycles does a shortest tour of the gumball machine take, counting the reset cycle but not the extra cycle at the end of the testbench?

A test starts with reset and then takes every arrow of the diagram, with outputs checked, but asserts reset only once. What could it miss?

A test has the machine in the 5-cent state with a nickel on the input. What should Open be?

Which of these is not something a waveform of a tour must show?

Exercise 5.6.1

Plan a test for the 15-cent machine of Section 5.4 that takes every arrow from reset in as few clock cycles as you can, and then write its testbench. How many cycles does it take, counting the reset cycle and not the extra cycle?

Hint
List the ways out of each state. How many times must you be in the 10-cent state to take each of the arrows that leave it? The same question for the 5-cent state tells you which arrows have to be taken more than once.
Solution

The 15-cent machine has twelve arrows, but a tour of twelve cycles after the reset cycle is impossible, because some states have to be entered more than once. A program searched every possible walk and found a shortest one, shown below.

Exact. No walk from the start state that takes every arrow without a reset is shorter than this one.

16 cycles: 1 reset cycle, then 15 arrows taken. The machine has 12 arrows.

Test plan for ch05/vend15: one row per clock cycle after the first reset cycle; 16 cycles: 1 reset cycle, then 15 arrows taken. The machine has 12 arrows.
CycleStateInputs N D QNext stateOutput OpenArrow
0reset asserted: the machine starts in 0¢
10¢0000¢01
20¢0010¢12
30¢1005¢03
45¢0005¢05
55¢10010¢06
610¢00010¢09
710¢1000¢110
80¢1005¢03
95¢0100¢17
100¢1005¢03
115¢0010¢18
120¢01010¢04
1310¢0100¢111
140¢01010¢04
1510¢0010¢112

The tour in words:

  • Cycle 0: reset asserted, the machine starts in 0¢.
  • Cycle 1: in 0¢ with N=0, D=0, Q=0, arrow 1 goes to 0¢, output 0.
  • Cycle 2: in 0¢ with N=0, D=0, Q=1, arrow 2 goes to 0¢, output 1.
  • Cycle 3: in 0¢ with N=1, D=0, Q=0, arrow 3 goes to 5¢, output 0.
  • Cycle 4: in 5¢ with N=0, D=0, Q=0, arrow 5 goes to 5¢, output 0.
  • Cycle 5: in 5¢ with N=1, D=0, Q=0, arrow 6 goes to 10¢, output 0.
  • Cycle 6: in 10¢ with N=0, D=0, Q=0, arrow 9 goes to 10¢, output 0.
  • Cycle 7: in 10¢ with N=1, D=0, Q=0, arrow 10 goes to 0¢, output 1.
  • Cycle 8: in 0¢ with N=1, D=0, Q=0, arrow 3 goes to 5¢, output 0.
  • Cycle 9: in 5¢ with N=0, D=1, Q=0, arrow 7 goes to 0¢, output 1.
  • Cycle 10: in 0¢ with N=1, D=0, Q=0, arrow 3 goes to 5¢, output 0.
  • Cycle 11: in 5¢ with N=0, D=0, Q=1, arrow 8 goes to 0¢, output 1.
  • Cycle 12: in 0¢ with N=0, D=1, Q=0, arrow 4 goes to 10¢, output 0.
  • Cycle 13: in 10¢ with N=0, D=1, Q=0, arrow 11 goes to 0¢, output 1.
  • Cycle 14: in 0¢ with N=0, D=1, Q=0, arrow 4 goes to 10¢, output 0.
  • Cycle 15: in 10¢ with N=0, D=0, Q=1, arrow 12 goes to 0¢, output 1.

The reason for the repeats is in the arrows that leave the 10-cent state: three of them, one for each coin, each going back to 0¢, so the walk has to be in 10¢ three times and must enter it three times. In the table above it enters once from 5¢ and twice directly from 0¢, which is why the arrow from 0¢ to 10¢ appears twice. The same argument for 5¢, which has three ways out (a nickel to 10¢, and a dime or a quarter back to 0¢), makes the walk visit it three times, each time through the nickel arrow from 0¢. That is how twelve arrows become fifteen cycles after the reset cycle, and sixteen with it.

Turning each row into a testbench line, with the state before the edge in the comment:

vend15_tb.sv
// Testbench for vend15: reset, one walk that takes every arrow, and an extra cycle. Each line is one clock cycle.
module vend15_tb();
logic clk, reset, N, D, Q, Open;
vend15 dut(.*);
parameter CLOCK_PERIOD = 100;
initial begin
clk <= 0;
forever #(CLOCK_PERIOD / 2) clk <= ~clk;
end
initial begin
{reset, N, D, Q} <= 4'b1000; @(posedge clk);
reset <= 0; {N, D, Q} <= 3'b000; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b001; @(posedge clk); // expect: ps=C0, Open=1
{N, D, Q} <= 3'b100; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b000; @(posedge clk); // expect: ps=C5, Open=0
{N, D, Q} <= 3'b100; @(posedge clk); // expect: ps=C5, Open=0
{N, D, Q} <= 3'b000; @(posedge clk); // expect: ps=C10, Open=0
{N, D, Q} <= 3'b100; @(posedge clk); // expect: ps=C10, Open=1
{N, D, Q} <= 3'b100; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b010; @(posedge clk); // expect: ps=C5, Open=1
{N, D, Q} <= 3'b100; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b001; @(posedge clk); // expect: ps=C5, Open=1
{N, D, Q} <= 3'b010; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b010; @(posedge clk); // expect: ps=C10, Open=1
{N, D, Q} <= 3'b010; @(posedge clk); // expect: ps=C0, Open=0
{N, D, Q} <= 3'b001; @(posedge clk); // expect: ps=C10, Open=1
{N, D, Q} <= 3'b000; @(posedge clk); // expect: ps=C0, Open=0
$stop;
end
endmodule

Tags: StandardFinite state machinesTest benches and simulation

Exercise 5.6.2

The equal-inputs counter of Section 5.4 has two inputs, A and B, and pulses its output on the third cycle in a row in which they are equal. How many cycles does the shortest test from reset take, counting the reset cycle but not the extra cycle?

Hint
The diagram draws each arrow once, but each such arrow stands for two input combinations. The table lists twelve arrows, one for every state and every input combination.
Solution

The machine has twelve arrows in its table, three states with four input combinations each, and the tour takes each one. The search below reports the minimum.

Exact. No walk from the start state that takes every arrow without a reset is shorter than this one.

19 cycles: 1 reset cycle, then 18 arrows taken. The machine has 12 arrows.

Test plan for ch05/s04-agree-run: one row per clock cycle after the first reset cycle; 19 cycles: 1 reset cycle, then 18 arrows taken. The machine has 12 arrows.
CycleStateInputs A BNext stateOutput OutArrow
0reset asserted: the machine starts in R0
1R000R101
2R100R205
3R200R019
4R000R101
5R100R205
6R211R0110
7R000R101
8R100R205
9R201R0011
10R000R101
11R111R206
12R210R0012
13R000R101
14R101R007
15R011R102
16R110R008
17R001R003
18R010R004

The tour in words:

  • Cycle 0: reset asserted, the machine starts in R0.
  • Cycle 1: in R0 with A=0, B=0, arrow 1 goes to R1, output 0.
  • Cycle 2: in R1 with A=0, B=0, arrow 5 goes to R2, output 0.
  • Cycle 3: in R2 with A=0, B=0, arrow 9 goes to R0, output 1.
  • Cycle 4: in R0 with A=0, B=0, arrow 1 goes to R1, output 0.
  • Cycle 5: in R1 with A=0, B=0, arrow 5 goes to R2, output 0.
  • Cycle 6: in R2 with A=1, B=1, arrow 10 goes to R0, output 1.
  • Cycle 7: in R0 with A=0, B=0, arrow 1 goes to R1, output 0.
  • Cycle 8: in R1 with A=0, B=0, arrow 5 goes to R2, output 0.
  • Cycle 9: in R2 with A=0, B=1, arrow 11 goes to R0, output 0.
  • Cycle 10: in R0 with A=0, B=0, arrow 1 goes to R1, output 0.
  • Cycle 11: in R1 with A=1, B=1, arrow 6 goes to R2, output 0.
  • Cycle 12: in R2 with A=1, B=0, arrow 12 goes to R0, output 0.
  • Cycle 13: in R0 with A=0, B=0, arrow 1 goes to R1, output 0.
  • Cycle 14: in R1 with A=0, B=1, arrow 7 goes to R0, output 0.
  • Cycle 15: in R0 with A=1, B=1, arrow 2 goes to R1, output 0.
  • Cycle 16: in R1 with A=1, B=0, arrow 8 goes to R0, output 0.
  • Cycle 17: in R0 with A=0, B=1, arrow 3 goes to R0, output 0.
  • Cycle 18: in R0 with A=1, B=0, arrow 4 goes to R0, output 0.

It takes 18 cycles after the reset cycle, and 19 with it. Here is why it is more than twelve. R2 has four arrows out, so the walk has to be in R2 four times, and R2 can only be entered from R1, so the two arrows from R1 to R2 are taken four times between them. R1 also has two arrows back to R0, which need two more visits, so R1 is visited six times, and it can only be entered from R0, so the two arrows from R0 to R1 are taken six times between them. Add the four arrows out of R2, the two arrows from R1 to R0 and the two loops at R0, and the total is 6+4+4+2+2=186 + 4 + 4 + 2 + 2 = 18.

Tags: StandardFinite state machinesTest benches and simulation

Exercise 5.6.3

The sequence generator of Section 5.4 has no inputs and outputs 1, 1, 0, 1, 0 repeatedly after reset. How many cycles does a test that takes every arrow take, counting the reset cycle but not the extra cycle? What does each line of its testbench contain?

Hint
With no inputs there is nothing to choose: the machine takes one arrow per cycle. How many arrows does it have?
Solution

There are five arrows, one leaving each state, and they form a ring. One walk takes all five, so the test is the reset cycle and five more: 6 cycles.

Exact. No walk from the start state that takes every arrow without a reset is shorter than this one.

6 cycles: 1 reset cycle, then 5 arrows taken. The machine has 5 arrows.

Test plan for ch05/s04-sequence: one row per clock cycle after the first reset cycle; 6 cycles: 1 reset cycle, then 5 arrows taken. The machine has 5 arrows.
CycleStateInput Next stateOutput OutArrow
0reset asserted: the machine starts in B0
1B0(none)B111
2B1(none)B212
3B2(none)B303
4B3(none)B414
5B4(none)B005

The tour in words:

  • Cycle 0: reset asserted, the machine starts in B0.
  • Cycle 1: in B0, arrow 1 goes to B1.
  • Cycle 2: in B1, arrow 2 goes to B2.
  • Cycle 3: in B2, arrow 3 goes to B3.
  • Cycle 4: in B3, arrow 4 goes to B4.
  • Cycle 5: in B4, arrow 5 goes to B0.

Each line of the testbench has no inputs to set; it waits for a clock edge and checks the output of the state the machine is in. Since the output is inside the state, the five lines check 1, 1, 0, 1 and 0 in turn.

Tags: Warm-upFinite state machinesTest benches and simulation

Exercise 5.6.4

A different gumball machine has a bug, and the tour of the previous example was run on it. The waveform shows its inputs, its state and its output. Using the tour table above, find the first cycle at which it goes wrong, and say which arrow is at fault.

Waveform ch05/vending-bug-trace: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-bug-trace: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-bug-trace: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5Open250350450550650750850time (ps)Waveform ch05/vending-bug-trace: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5Open250350450550650750850time (ps)Waveform ch05/vending-bug-trace: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5Open250350450550650750850time (ps)

Time in ps; one column is 50 ps.

Timing diagram from simulation, ch05/vending-bug-trace: time in ps from 250 to 950, 14 columns of 50 ps.

clk: clock, period 100 ps, starts 1, 5 rising edges in the window (350, 450, 550, ...).

reset: 0 at 250, no changes.

N: 0 at 250, then 1 at 350, 0 at 550.

D: 0 at 250, then 1 at 550, 0 at 750.

dut.ps (state names: C0, C5): C5 at 250, then C0 at 450, C5 at 550.

Open: 0 at 250, then 1 at 350, 0 at 450, 1 at 550, 0 at 750.

Dashed vertical guides mark the rising clock edges.

Description: A timing diagram of clk, reset, N, D, the state dut.ps and Open from the middle of a tour testbench.

Figure 5.6.4. The tour run on a machine with a bug. The window starts a few cycles into the run.
Hint
Compare the state in each cycle with the State column of the table, starting from the first cycle in the window. The input changes at an edge, so the state that results shows one edge later.
Solution

Go through the window with the tour table beside it. At the left edge the machine is in 5¢, and a nickel arrives in cycle 4 (in 5¢ with N=1, D=0, arrow 5 to 0¢, output 1): Open rises, and after the edge the state is 0¢, as the table says. In cycle 5 (in 0¢ with N=1, D=0, arrow 2 to 5¢, output 0) the nickel is still there, now in 0¢, and the state is 5¢ after the edge that ends it. Then comes cycle 6 (in 5¢ with N=0, D=1, arrow 6 to 0¢, output 1): the machine is in 5¢ and a dime arrives. Open is high, as it should be, and the table says the next state is 0¢.

The waveform does not do that. The state stays at C5 through the whole cycle after the dime was taken, and the table row for cycle 7 (in 0¢ with N=0, D=1, arrow 3 to 0¢, output 1) expects the machine to be in 0¢ there. So the first cycle that goes wrong is cycle 7 of the tour table, the one that starts at the edge on which the dime was taken, and the fault is in arrow 6 (5¢ to 0¢ when N=0, D=1, output 1), the arrow that the machine is taking in cycle 6: it leaves the machine in 5¢ instead of sending it back to 0¢.

Notice that Open matches the table in every cycle of the window, even in the wrong cycle, because a dime opens the machine from either state. A test that checked only the outputs would have passed this machine, and only the state comparison finds the fault. That is why every arrow has to be checked for its destination as well as its output.

Here is the same stretch of the tour on the correct machine:

Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250300350400450500550600650700750800850900time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)Waveform ch05/vending-tour-b: clk, reset, N, D, dut.ps, OpenclkresetNDdut.psC5C0C5C0Open250350450550650750850time (ps)

Time in ps; one column is 50 ps.

Timing diagram from simulation, ch05/vending-tour-b: time in ps from 250 to 950, 14 columns of 50 ps.

clk: clock, period 100 ps, starts 1, 5 rising edges in the window (350, 450, 550, ...).

reset: 0 at 250, no changes.

N: 0 at 250, then 1 at 350, 0 at 550.

D: 0 at 250, then 1 at 550, 0 at 750.

dut.ps (state names: C0, C5): C5 at 250, then C0 at 450, C5 at 550, C0 at 650.

Open: 0 at 250, then 1 at 350, 0 at 450, 1 at 550, 0 at 750.

Dashed vertical guides mark the rising clock edges.

Tags: ChallengeFinite state machinesWaveforms