Channels ▼

Al Williams

Dr. Dobb's Bloggers

Inside an Automated State Machine

April 15, 2014

Last time I looked at Fizzim, an open source tool for generating state machines for synthesis into an FPGA. If you recall, I laid out a simple state machine that put out a specific output on a trigger:

The machine has five states: Idle (the default, indicated by the double circle), S1, S1delay, S2, and S2delay. There is an output Q. Here's the reason each state appears:

  • Idle — Wait for trigger input T
  • S1 — Trigger the output and load the counter with 5
  • S1delay — Hold the output asserted and decrement the counter to zero
  • S2 — Turn the output off and load the counter with 8
  • S2delay — Keep the output off and decrement the counter to zero

The result is that a T input causes a 6 time tick assert and then won't retrigger again for another 9 clock ticks. You can experiment with the code in any Verilog simulator, including the online EDA Playground.

There are many options that can control the output of Fizzim, but I wanted to example some bits of the generated code to see how readable it was. Here's the first part, which is hardly surprising:

module test (
  output reg Q,
  input wire T,
  input wire clk,
  input wire reset 
);

That certainly defines the module. I selected one hot encoding (that is, each state is represented by one bit). The state bits and some variables appear next:

// state bits
  parameter 
  idle    = 3'b000, 
  S1      = 3'b001, 
  S1delay = 3'b010, 
  S2      = 3'b011, 
  S2delay = 3'b100; 

  reg [2:0] state;
  reg [2:0] nextstate;
  reg [4:0] ctr1;
  reg [4:0] ctr2;

You can probably guess that state is the current state vector and nextstate is what will be the next state. If you aren't too familiar with Verilog, the 3'b notation means the following are 3 binary digits. The ctr1 and crt2 variables I defined to hold the counters for S1Delay and S2Delay (the numbers in brackets define how many bits are in each; 5 bits in the case of the two counters). There is a bit of code somewhat further down that handles the state change and reset logic:

// sequential always block
  always @(posedge clk or negedge reset) begin
    if (!reset)
      state <= idle;
    else
      state <= nextstate;
  end

Before that, though, there's code to work out the next state. Because of some options I set, the code will assume the next state is the same as the current state:

always @* begin
    nextstate = state; // default to hold value because implied_loopback is set
    Q = 0; // default
    case (state)
      idle   : begin
        if (T) begin
          nextstate = S1;
        end
      end
      S1     : begin
        Q = 1;
        begin
          nextstate = S1delay;
        end
      end
. . .

That makes sense. The idle state waits for a T to go to S1. However, it isn't clear how S1Delay handles decrementing the counter if you are looking at just this block of code:

   S1delay: begin
        Q = 1;
        if (ctr1==0) begin
          nextstate = S2;
        end
      end

The counter decrement happens in a separate "datapath" block:

// datapath sequential always block
  always @(posedge clk or negedge reset) begin
    if (!reset) begin
      ctr1[4:0] <= 4'b0;
      ctr2[4:0] <= 4'b0;
    end
    else begin
      ctr1[4:0] <= 0; // default
      ctr2[4:0] <= 0; // default
      case (nextstate)
        S1     : begin
          ctr1[4:0] <= 5;
        end
     S1delay: begin
          ctr1[4:0] <= ctr1-1;
        end
. . .

The rest of the code just handles the other states. There is also an optional piece that converts state names to text for simulation (which doesn't work for the wave viewer on EDA Playground, but works great for Modelsim or GTKWave).

Granted, for a small state machine like this, there isn't much motivation to use a tool like this other than the diagrams make for nice documentation. However, I was pleased to see that the generated code was reasonably easy to understand. Of course, if you really wanted a change, you ought to go change the Fizzim diagram and regenerate the output.

Fizzim will also generate VHDL, if you ask it to do so. I have a track record of looking at code generation tools, thinking they are cool, putting them away, and then hand-coding things anyway. However, as code-generation tools go, Fizzim seems pretty sane and with a little practice could even be more efficient since you can focus on the logic flow instead of the details.

I've been on a bit of an FPGA kick for the last few weeks talking about Zynq, test bed generation, and state machines. But I've been tinkering with some very cool embedded CPU toys, so I think I'll put the FPGA toys to the back of the workbench for a little while and turn back to programming next time.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Dr. Dobb's TV