---
title: '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:

* **Communication between Systems with Different Clocks:** Two different
  devices usually possess their own individual clocks, with no mechanism
  to synchronize between them. Their respective clocks likely use distinct
  frequencies. In order to exchange data, the two machines require an
  agreed-upon **communication protocol** that is insensitive to the
  clocks' phase and frequency differences.
* **Processes that Require Multiple Clock Cycles:** digital module often
  implement *algorithms* that play out across multiple clock cycles. The
  required number of cycles may be unknown and/or variable. In this
  situation, a module needs a **handshaking protocol** to know when it
  should start, and to signal when it is finished.

## 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:

* 0: Runners get **ready** at the starting line.
* 1: An official signals to **start** the race.
* 2: All runners crosses the finish line, the race is **done**.

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.](figures/race_timing_diagram.svg){width=90%}


## 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.](figures/race_machine.svg){width=90%}


## 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: 

* Inputs: `clk`, `rst_l`, `start`
* Output: `done`
* Behavior: 
    - When `!rst_l`, `done` goes LOW
    - When `!start`, `done` goes LOW
    - When `start`, `done` goes HIGH **after a random delay**.


### 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.

```text
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`:

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

Indicate on Canvas that your assignment is done.