参考思路

初始化:复位,所有信号复位为0
发送方:
复位解除后,计数器计数到4,data_req 置1;发送 data_req 和 data 给接收方;
等待接收方返回 data_ack 后,利用两级同步器同步 data_ack;
当满足 data_ack_r1 && !data_ack_r2时,data增加1‘b1,data_req 置0,同时计数器cnt置0;
至此,一次完整的握手结束
等待计数器cnt == 4,发送下一次 data_req。
接收方:
接受到 data_req 和 data 后,利用两级同步器同步 data_req
当 data_req_r1 && !data_req_r2 时,输出data_ack置1,并且 data 存入到 data_reg;
过了一个周期,data_ack 必须置0,(否则下一次握手无法完成,因为data_ack 一直为1,使得 data_ack_r1 和 data_ack_r2 都一直为 1);
至此,接收方任务完成。

疑问

按题目给出data 位宽为4位 ,仿真结果data是0-15, 那么应该是循环发送0-15,而不是循环发送0-7.

代码实现

`timescale 1ns/1ns
module data_driver(
	input clk_a,
	input rst_n,
	input data_ack,
	output reg [3:0]data,
	output reg data_req
	);
   
    reg data_ack_r1, data_ack_r2;
    reg [2:0] cnt;
    //--------------两级同步------------------//
    always @(posedge clk_a, negedge rst_n) begin
        if(!rst_n) begin
            data_ack_r1 <= 0;
            data_ack_r2 <= 0;
        end else begin
            data_ack_r1 <= data_ack;
            data_ack_r2 <= data_ack_r1;
        end
    end
    //-----------------数据产生----------------------//
    always @(posedge clk_a, negedge rst_n) begin
        if(!rst_n) begin
            data <= 0;
        end else if(data_ack_r1 && !data_ack_r2) begin
            data <= data + 1;
        end else begin
            data <= data;
        end
    end
    //-----------------data_req----------------------//
    always @(posedge clk_a, negedge rst_n) begin
        if(!rst_n) begin
            data_req <= 0;
        end else if(data_ack_r1 && !data_ack_r2) begin
            data_req <= 0;
        end else if(cnt == 3'd4) begin
            data_req <= 1'b1;
        end else begin
            data_req <= data_req;
        end
    end
    //-----------------计数器----------------------//
    always @(posedge clk_a, negedge rst_n) begin
        if(!rst_n) begin
            cnt <= 0;
        end else if(data_ack_r1 && !data_ack_r2) begin
            cnt <= 0;
        end else if(data_req) begin
            cnt <= cnt;
        end else begin
            cnt <= cnt + 1;
        end
    end
endmodule

module data_receiver(
	input clk_b,
	input rst_n,
    input [3:0]data,
	output reg data_ack,
	input data_req
	);
   
    reg data_req_r1, data_req_r2;
    reg [3:0] data_reg;
    //--------------两级同步------------------//
    always @(posedge clk_b, negedge rst_n) begin
        if(!rst_n) begin
            data_req_r1 <= 0;
            data_req_r2 <= 0;
        end else begin
            data_req_r1 <= data_req;
            data_req_r2 <= data_req_r1;
        end
    end
    //-----------------数据存储----------------------//
    always @(posedge clk_b, negedge rst_n) begin
        if(!rst_n) begin
            data_reg <= 0;
        end else if(data_req_r1 && !data_req_r2) begin
            data_reg <= data;
        end else begin
            data_reg <= data_reg;
        end
    end
    //-----------------data_ack----------------------//
    always @(posedge clk_b, negedge rst_n) begin
        if(!rst_n) begin
            data_ack <= 0;
        end else if(data_req_r1 && !data_req_r2) begin
            data_ack <= 1'b1;
        end else begin
            data_ack <= 0;
        end
    end
   
endmodule

仿真结果