参考思路
初始化:复位,所有信号复位为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