Digital IC hand tear code - handshake signal (READY-VALID)

 Foreword:

        This column aims to record high-frequency pen interview hand-torn code questions for digital front-end autumn recruits. All articles in this column provide principle analysis, codes and waveforms, and all codes have been verified by myself.

The directory is as follows:

1. Digital IC hand-tear code-frequency divider (any even number frequency division)

2. Digital IC hand-tear code-frequency divider (any odd frequency division)

3. Digital IC hand-tear code-frequency divider (any decimal frequency division)

4. Digital IC hand tearing code - asynchronous reset and synchronous release

5. Digital IC hand tear code - edge detection (rising edge, falling edge, double edge)

6. Digital IC hand tearing code-sequence detection (state machine writing method)

7. Digital IC hand tearing code-sequence detection (shift register writing method)

8. Digital IC tearing code - half adder, full adder

9. Digital IC hand tearing code - serial to parallel, parallel to serial

10. Digital IC hand tearing code-data bit width converter (width-narrow, narrow-width conversion)

11. Digital IC hand tearing code - finite state machine FSM - beverage machine

12. Digital IC hand tear code - handshake signal (READY-VALID)

13. Digital IC hand tearing code - water handshake (use handshake to solve the problem of pipeline interruption and back pressure)

14. Digital IC hand tearing code - Telink micro written test questions

15. Digital IC hand tearing code - Pingtouge technology final face hand tearing real question

16. Digital IC manual tearing code-Zhaoyi innovation written test real questions

17. Digital IC hand tearing code - Espressif Technology written test real questions (4 times frequency)

18. Digital IC tearing code - dual-port RAM (dual-port-RAM)

        ...Continually updated

For convenience, you can bookmark the guide blog:  digital IC hand tear code - guide catalog


Table of contents

handshake signal

Interface explanation

the code

testbench 

waveform


handshake signal

The handshake signal is a signal derived for the correct data interaction between modules. It is nothing more than three possibilities

        1. The valid signal provided by the upstream master is pulled high together with the data, but the valid signal that the downstream slave is ready after a while is the first to be high. 

        2. The downstream slave is always ready, but the upstream data will take a while to be effective. The ready is respected first.

        3. The valid signal of the upstream master and the ready signal of the downstream slave are high at the same time. 

        When I first came into contact with the handshake signal, I was actually very clear about the above three handshake principles, but specifically, I was confused about how to write the code for the handshake signal between the master and slave. Just use this article to briefly talk about how the master and slave solve the data interaction problem through handshake signals. At the same time, it also lays the foundation for the next article " Multi-stage Pipeline Handshake ". The next article will explain how to use the handshake signal to solve the problem of pipeline stagnation caused by upstream cut-off and downstream backpressure.
        OK, back to this article.

        For the master, the master sends out a piece of data. If the data is valid , the master will pull up the valid signal sent to the slave , that is, tell the slave that the data is valid and can be received! If the slave is ready , the slave pulls up the ready signal sent to the master , telling the master that I am ready, and if your data is valid, I can receive it! Therefore, when the data transmitted by the master is valid and the slave is ready, the data will be taken away by the slave in the next cycle, and the master can continue to transmit the next data.

Interface explanation

        For the module you wrote, if you want to shake hands with the upstream and downstream, you are a slave for the upstream and a master for the downstream, so the interface should be as follows:

module handshake(
  input         clk       ,
  input         rstn      ,

  input [7:0]   data_i    ,
  input         valid_i   ,
  input         ready_o   ,

  output [7:0]  data_o    ,
  input         ready_i   ,
  output        valid_o
);

        data_i is the input data, if valid_i is 1, the data is valid, ready_o is the preparation signal sent by the slave to the upstream master, if ready_o is ready, it is 1.

        data_o is the data output by the module to the downstream, if the output data is valid, valid_o is 1. The downstream will also be ready and not ready, so a ready_i signal provided by the downstream to this module is needed to tell us whether the downstream is ready. 

the code

module handshake(
  input         clk       ,
  input         rstn      ,

  input [7:0]   data_i    ,
  input         valid_i   ,
  output        ready_o   ,

  output [7:0]  data_o    ,
  input         ready_i   ,
  output        valid_o
);

reg [7:0] data_o_r;
reg valid_o_r;

assign ready_o = ready_i;     //如果下游准备好了,那我就准备好了

always @(posedge clk)begin
  if(ready_i && valid_i)begin //如果下游准备好了,并且上游数据有效,那就把输入的数据乘以二输出
    data_o_r <= data_i * 2;   
  end
end

always @(posedge clk)begin
  if(!rstn)begin
    valid_o_r <= 1'b0;
  end
  else if(ready_o)begin
    valid_o_r <= valid_i;     //如果我准备好了,我就把上游的valid传递给下游。
  end
end

assign data_o  = data_o_r;
assign valid_o = valid_o_r;

endmodule

The code is written as above, the key lies in the comments:

        1. If the downstream is ready and the upstream input data is valid, multiply the input data by two and assign it to the output data.

        2. If the downstream is ready to receive data, then this module can process the data.

        3. If the module is ready, pass the upstream valid_i to the downstream valid_o.

The testbench here is also very important.

testbench 

module handshake_tb();

reg clk,rstn;

always #5 clk = ~clk;

reg valid_i,ready_i;
wire ready_o,valid_o;

reg  [7:0] data_i;
wire [7:0] data_o;

initial begin
  clk   <= 1'b0;
  rstn  <= 1'b0;
  #25
  rstn    <= 1'b1;
  ready_i <= 1'b1;    //下游准备好了
  valid_i <= 1'b0;    //上游数据无效
  data_i  <= 8'b0000_1000;
  #10
  data_i  <= 8'b0111_1000;
  valid_i <= 1'b1;    //上游数据有效
  #10
  data_i  <= 8'b0100_0100;
  #10
  valid_i <= 1'b0;
  #10
  data_i  <= 8'b0010_0100;
  valid_i <= 1'b1;    //虽然上游数据有效,但下游没准备好
  ready_i <= 1'b0;
  #20
  ready_i <= 1'b1;    //上游数据有效,下游准备好了
  #10
  valid_i <= 1'b0;
  #500
  $stop();
end

handshake u_handshake(
  .clk      (clk)     ,
  .rstn     (rstn)    ,
  .data_i   (data_i)  ,
  .data_o   (data_o)  ,

  .ready_i  (ready_i) ,
  .ready_o  (ready_o) ,
  .valid_i  (valid_i) ,
  .valid_o  (valid_o)

);

endmodule

        We use tb to simulate the upstream master and downstream slave of this module, and use tb to provide upstream data data_i and valid_i signals to this module. The upstream cut-off, that is, the valid_i is pulled down halfway, and the downstream backpressure, that is, the situation where ready_i is low halfway is simulated respectively. Both pass. 

waveform

        When the output data is valid, the valid_o output by this module is high, which meets the requirements. Friends who are not familiar with it, take a look at the waveform to understand. The whole module is also posted in two parts. If you are interested, you can type it yourself. The above is the complete code. tb omits port instantiation and variable definition. 

Guess you like

Origin blog.csdn.net/qq_57502075/article/details/127137378#comments_27675150