The valid-ready protocol is probably the most frequently used handshake mechanism in digital design and verification, and it is a hot topic in hardware interview questions. In a nutshell, it has the following properties:

  1. Valid is asserted by the master when it has data to transfer, while ready is asserted by the slave when it has space to accept the data. Data transfer happens when both valid and ready are asserted.
  2. When valid is asserted, master should keep data stable until the data transfer completes.
  3. Master can wait until ready is asserted before asserting valid, or slave can wait until valid is asserted before asserting ready. However master and slave cannot wait for each other at the same time, otherwise it will introduce a deadlock.

Fairly simple, isn’t it? What if, physical designers see a timing violation between master and slave and timing fixes cannot help? Consider inserting register slice between master and slave.

Forward Register Slice

If “valid” path has a timing violation but “ready” path is fine, we can insert “forward register slice”, shown below, to cut “valid” path, but leave “ready” path as it is.

Both “data_out” and “valid_out” are driven by registers directly, and “ready_out” is asserted whenever either “data_reg” does not have valid data, or “ready_in” is asserted.

“Data Reg” samples “data_in” and “Valid Reg” is asserted every time a data transfer happens between master and register slice; “Valid Reg” is de-asserted when a data transfer happens between register slice and slave, but no data transfer between master and register slice.

Backward Register Slice

If “ready” path has a timing violation but “ready” path is fine, we can insert “backward register slice”, shown below, to cut “ready” path, but leave “valid” path as it is.

Compared to its “forward” counterpart, “backward register slice” is trickier. Consider the case where “ready_out” is 1 but “ready_in” is 0, slave is not ready for the data transfer but master thinks a data transfer can complete, therefore we need a temporary data storage “Data Reg” inside the register slice to handle this case. In addition, we need a flag “Data Reg Valid“ to indicate whether “Data Reg” has valid data. “Data Reg Valid” is used to statically mux between “Data Reg” and “data_in” for “data_out”. Whenever temporary data storage is valid or “valid_in” is asserted, “valid_out” is also asserted.

Full Register Slice

We will need to insert “full register slice” if both “valid” path and “ready” path have timing violations. “Full register slice” is essentially equivalent to a ping-pong FIFO, not “empty” serves as valid signal to slave, and not “full” serves as ready signal to master.


Although register slice insertion helps with timing, “forward register slice” and “full register slice” add one extra cycle latency to the datapath. Use these techniques with caution if your design is latency sensitive.

Related Interview Questions

  • Timing Questions



  1. in backward register slice topic,in first line , there should be ” valid ” in stead of ” ready “.

  2. Great explanation!
    Could you confirm if this backward register slice is what is referred to as “skid buffer” in the industry?

    1. Backward register doesn’t meet valid&ready protocol, it takes additional clock unit valid is de-asserted while ready on the source side is low. So basically valid goes low without associated ready.

  3. For the backward register slice consider the case where initially valid_in=1, ready_out=0, ready_in=1. The slave considers this a transaction and accepts the data (let’s call it data0), the master doesn’t have ready set hence it holds on to same valid and data (data0). Now next cycle, valid_in=1, ready_out=1 and suppose ready_in=1. In this case both master and slave consider the transaction completed, but slave stores the data0 again. Isn’t this a problem, am I missing something?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.