Introduction
Most existing digital devices use sequential circuits that create or track sequences of events. Many of these must take certain actions for particular inputs, and different actions for other inputs. This implies the circuit maintains an internal state, so that it can respond to inputs contextually. Digital circuits that maintain state, and create or track sequences of inputs, are known as state machines. This project introduces state machines, and present a design project (a stopwatch) that requires a state machine.
State machine circuits use an internal register to store a binary number, and the stored binary number defines the “state” of the circuit (the register is called the “state register”). In operation, the binary number stored in the state register is updated at every clock edge, and so a sequence of constantly updated numbers (or states) cycles through the state register. The stored numbers can be used to create a meaningful sequence of output signals. For example, a traffic light controller might turn off a pedestrian crossing audio annunciator, then turn off the visual indicator, then turn off the green traffic light and turn on the yellow light, wait for a few seconds and then turn yellow off and red on, and then turn on the perpendicular pedestrian crossing indicator, and so on. Each of these actions might be associated with one state in the controlling state machine.
To create an ordered sequence of state-to-state transitions, the state machine must base its next state on its present state. That is, the state machine can’t know what state to enter next without factoring in what state it’s currently in. To accomplish this, state register contents are fed back to a “next state logic” circuit that combines the present state signals with circuit inputs to create the next state signals. At every clock edge, the next state signals are memorized, and so become the present state. Because every future next state is based on the present state, an ordered sequence of state can be implemented. Exactly which next state follows the present state can be controlled by the overall circuit inputs.
The clock signal driving a state machine is generally a regular, repeating square wave at some fixed frequency. At each active clock edge, a new present state is memorized into the state register, and that memorized value is fed back to the next state logic circuit so a new next state can be determined. State register contents are also forwarded to an “output decoder” circuit that produces overall circuit outputs based on the state codes.
This project illustrates the state machine design process with two different state machines.
Before you begin, you should:
- Be comfortable and competent in creating behavioral and structural Verilog designs;
- Know how to design and use testbenches for combinational and sequential Verilog designs;
- Have a basic familiarity with state machine design.
After you’re done, you should:
- Understand how to design state machines;
- Be able to write behavioral Verilog for state machines;
- Be more comfortable implementing larger designs;
- Be familiar with the need for good design partioning.
Background
The general architecture of a state machine circuit is shown below. The figure shows the state register, and two combinational logic circuits – the next state logic and the output decoder blocks.
The next state logic circuit is responsible for driving the D inputs of the flip-flops in the state register. Next state logic inputs include the present state (which is the output of the state register), and the overall circuit inputs. This information is combined in the next state logic circuit so that next-states can be based on the present state, and on overall circuit inputs. The next state logic circuit can be designed using the techniques presented earlier – namely, a truth table to show the input-output relationships, and K-maps or computer algorithms to find optimal circuits. But, when truth tables are used like this (to define logic circuits that are in the feedback path of registers), it is difficult to see the “bigger picture”, or the sequence of states that are implemented by the next state logic circuit. A better design method uses a state diagram to capture the requirements – state diagrams are discussed in the background topics.
The output decoder circuit receives the present state signals as inputs, and creates useful output signals based on the present state. In the example presented in the opening paragraph above, the present state signals might indicate the traffic light controller state machine is in the “turn on the yellow light” state. That state would be associated with a unique binary number in the state register, and the output decoder would receive that state code, and from it, create a signal that could turn on the yellow light. The output decoder circuit requirements could also be captured in a truth table, and then a circuit could be designed based on that table. But, as with the next state logic circuit, the use of a state diagram makes it easier to visualize how output signals are generated from various states.
State machines, like other circuits we’ve encountered, can be designed using structural methods, or behavioral Verilog. Both structural and behavioral design methods are presented in the background topics, but behavioral Verilog is by far the preferred method. We will use behavioral Verilog in this project.
Behavioral Verilog for state machines can be created following many different models. Which model you use will depend on your personal experience and stylistic preferences. In the tutorial below, we present a model that uses two Verilog always blocks: one to describe the state register, a second to describe the next-state combinational logic. The state-register block is no different than code used earlier to describe Verilog registers. The next state block uses a case statement to make the code more readable. Note this is a stylistic choice – for all but the simplest state machines, clearly showing the next-state logic functions to the code reviewer/reader is a meaningful goal, and a case statement helps in that regard. If you use an always block (and you should strongly consider it!), be sure to cover all possible combinations of the inputs in the sensitivity list to avoid creating unwanted latches. The tutorial below will walk you through creating a state machine using our preferred style.
Requirements
1. Simulate a serial adder and prove its correctness
Follow the tutorial to create and simulate a serial adder. Make sure to cover all combinations of inputs when creating your testbench.
2. Stopwatch with Start, Stop, Increment, and Clear Functionality
Create a four-digit stopwatch on your Boolean board, using the seven-segment display as an output device. The stopwatch should count from 0.000 to 9.999 seconds and then roll over, with the count value updating exactly once per millisecond.
The stopwatch uses three pushbutton inputs: start, stop, increment, and clear (reset). The start input causes the stopwatch to begin incrementing at a 1KHz clock rate (i.e., one count per millisecond); the stop input stops the counter from incrementing but leaves the display showing the current counter value; the increment input causes the displayed value to increment once each time the button is pressed regardless of how long the increment button is held down; and the reset/clear input forces the counter value to zero.
Hint #1 - System block Diagram
A block diagram for the stopwatch is shown in Fig. 1 below. Except for the state machine, you have built and used all of these blocks in prior projects. You should consider using structrual Verilog, and reusing your previously built components (you may need to modify some of the components for this project).
Note that not all behaviors are fully specified in the design requirements section above. For example, if the timer is currently running and the increment button is pressed, no requirement is given to specify how the timer should behave. As an engineer, you must understand the design intent, and create behaviors for underspecified behaviors that are consistent with your understanding of the intent. In practice, it is difficult (or even impossible) to completely specify every behavior in a written document, so engineers frequently invent behaviors where specifications are lacking. Figures providing greater detail for the blocks shown above are shown below.
Hint #2 - Decimal Counter
The timer requires a four-digit decimal counter. Such a counter can be built from four individual counters that each count between 0 and 9 (
0000
to1001
), and then roll over from 9 back to 0, creating a continuous count pattern with 10 binary numbers.Individual counters are based on 4-bit binary counters that each detect when the pattern
1001
is present on their outputs. When1001
is detected, the counters reset themselves back to0000
and issue a terminal count (TC
) signal to indicate the count range is complete and counter is resetting back to zero.Each counter also uses an enable signal (
CEN
). WhenCEN
is asserted, the counter will increment with each clock edge, but when it is deasserted, the counter will ignore the clock and hold at its present state. TheCEN
signal can be used to enable more significant counters each time a less significant counter completes its count range.The
TC
signal is typically driven by logic gate combining the count bits according to some function (in our case,TC_1001
is generated by a 4-input AND gate detecting1001
).TC_1001
will be asserted for as long the1001
pattern is present on the counter outputs. In the least significant counter, this is a single clock period. But in the next most significant counter (representing the 10ms position in a four digit decimal number), the1001
pattern will be present for 10 clock periods, and so itsTC_1001
signal will be asserted for 10 system clock periods.To keep the next most significant counter from counting 10 times (during the period
TC_1001
is asserted), theTC_1001
signal from the first counter must be combined with theTC_1001
signal from the next most significant counter. In fact, a little thinking about the problem will reveal that eachTC_1001
from more significant counters must be combined with all such signals from all less significant counters.The outputs of the four individual counters can be assembled into a single 16 bit bus for transport to the seven-segment display controller.
Hint #3 - Seven Segment Display Controller
The block diagram below shows a structural design of the seven segment display controller.
Note that not all behaviors are fully specified in the design requirements section above. For example, if the timer is currently running and the increment button is pressed, no requirement is given to specify how the timer should behave. As an engineer, you must understand the design intent, and create behaviors for underspecified behaviors that are consistent with your understanding of the intent. In practice, it is difficult (or even impossible) to completely specify every behavior in a written document, so engineers frequently invent behaviors where specifications are lacking. Figures providing greater detail for the blocks shown above are shown below.
Final Result of your Stopwatch
Notice from the video that pushbuttons are used to “start", “stop", “increment", and “clear" your stopwatch.
3. State Diagram of the Stopwatch Controller
Draw a state diagram of your stopwatch controller on a paper and explain to the Assessor how it works.
Challenges
1. Add Timer Feature to Your Stopwatch
Add a feature so that you can change from a stop watch to a timer (count up or down depending on a slide switch input).