Handshaking in Digital Design

Asynchronous Systems

The term “asynchronous” can refer to several different scenarios. Here is a brief description of some more common scenarios that we will study:

Asynchronous Handshaking: Race Metaphor

Asynchronous handshaking is an important technique for coordinating processes that have variable timing. To illustrate this concept, consider a competitive foot race with three states:

To coordinate this race, the officials use three flags for signaling: ready, start, and done. Before the competitors can line up, all three flags must be LOW. Once the runners are in position, the ready flag can go HIGH.

When the race official sees the ready flag, the start flag may go HIGH to start the race. Meanwhile, down at the finish line, once the start flag goes HIGH a race observer watches the runners to verify when they have all completed the race. At the end, the done flag goes HIGH.

At any time after raising the start flag, the ready flag can by lowered since the runners are no longer in the ready position. Once the done flag goes HIGH, the start flag may be lowered since the race is over. After the start flag is lowered, the done flag can go LOW again. Once all three flags are LOW, another set of runners can queue up at the starting line to begin another race.

The timing of this handshaking dance is shown in the figure below. Two race events are shown. The run time is indicated for each race, as well as the delay between races. Both the run time and delay can vary from one race to the next. Since the schedule is not absolute and repeatable, we need to use handshaking with the flags.

Timing diagram showing two complete races.

State Transition Diagram

A state transition diagram for the handshaking protocol is shown below. This state diagram responds to two inputs: ready and done. It controls one output: start. Elsewhere in the design, there must be other state machines that control the ready and done signals.

FSM State Transition Diagram for the race process.

Verilog Representation of the FSM

In digital systems, the “runners” represent data. The “race” represents some process that uses the data, where the process may take an unknown number of clock cycles to complete. We model this system using two modules: the race_official and the race_observer. The race_official is implemented as follows:

module race_official
(
   input      clk,
   input      rst_l,    
   input      ready,
   input      done,
   output reg start
);

   reg [1:0] state;

   always @(posedge clk, negedge rst) begin
      // ACTIVE-LOW RESET:
      if (!rst_l) begin
         state <= 0;
         start <= 0;
      end
      // NORMAL (NON-RESET) BEHAVIOR:
      else begin
         case (state)
           0: begin
                if (ready) begin
                   start <= 1;
                   state <= 1;
                end
                else 
                   start <= 0;
             end
           1: begin
                if (done) begin
                   start <= 0;
                   state <= 2;
                end
              end
           2: begin
                if (!done && !ready) 
                   state <= 0;
                end
           default: 
             begin
                start <= 0;
                state <= 0;
             end
         endcase
      end
   end   

endmodule

Some important features of this model:

  1. The state signal is two bits wide, since there are three states. In Verilog, it’s crucial to declare an adequate number of bits for state variables. One of the most common design errors is to declare too few bits; if our state variable had only one bit, it would never reach state 2.
  2. The case statement has a default condition. This is necessary since a hardware state machine could find itself in an erroneous state (e.g. state 3) due to some electrical error. If that happens, it needs a way to recover from the fault.

Assigned Tasks

Create a race_observer module

Design a state machine and Verilog module for the race_observer, according to these specifications:

Make a random_timer submodule

To simulate a random delay, use this non-synthesizeable random_timer submodule:

module random_timer
(
   input clk,
   output reg t
);

reg [1:0] r; // random number

always @(posedge clk) begin
   r <= $random();
   if (r == 0)
       t <= 1;
   else
       t <= 0;
end
endmodule

In your race_observer module, place an instance of random_timer and connect it to a wire named t:

   wire t;
   
   random_timer rt1 (.clk(clk), .t(t));

Draw a state transition diagram and implement it in Verilog

Create a state transition diagram for race_observer. The diagram’s conditions should involve start, rst_l and t. The diagram’s assignments should act on done. Use the t signal as a condition for all transitions, e.g. done can only go high when t==1. Scan or save the diagram in a graphical format in this assignment directory, with filename diagram.png or diagram.jpg or whatever graphics type you prefer to use. Implement the diagram’s state-transition logic in a file named src/race_observer.v.

Simulate the design

Once your race_observer is complete, type make simulate to simulate the official/observer handshaking. One handshaking event should look something like the example shown below, progressing from all-zeros to ready, then start, then done, then back to zeros.

clk:    5   ready: 0    start: 0    done:  0    start_state: 0  done_state: 0
clk:    6   ready: 0    start: 0    done:  0    start_state: 0  done_state: 0
clk:    7   ready: 0    start: 0    done:  0    start_state: 0  done_state: 0
clk:    8   ready: 0    start: 0    done:  0    start_state: 0  done_state: 0
clk:    9   ready: 1    start: 0    done:  0    start_state: 0  done_state: 0
clk:   10   ready: 1    start: 1    done:  0    start_state: 1  done_state: 0
clk:   11   ready: 0    start: 1    done:  0    start_state: 1  done_state: 1
clk:   12   ready: 0    start: 1    done:  0    start_state: 1  done_state: 1
clk:   13   ready: 0    start: 1    done:  0    start_state: 1  done_state: 1
clk:   14   ready: 0    start: 1    done:  0    start_state: 1  done_state: 1
clk:   15   ready: 0    start: 1    done:  1    start_state: 1  done_state: 2
clk:   16   ready: 0    start: 0    done:  1    start_state: 2  done_state: 2
clk:   17   ready: 0    start: 0    done:  0    start_state: 2  done_state: 0
clk:   18   ready: 0    start: 0    done:  0    start_state: 0  done_state: 0
clk:   19   ready: 1    start: 0    done:  0    start_state: 0  done_state: 0

Study the output to verify that the handshaking process is correct, you should note several races are completed, with each race taking different times to complete. Examine the ready signal and note the minimum and maximum delays between races. Similarly, examine the done signal and measure the minimum and maximum running time.

Turn in your work using git:

git add diagram* src/*.v *.txt
git commit . -m "Complete"
git push origin master

Indicate on Canvas that your assignment is done.