`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; always @(posedge clk_a or negedge rst_n) begin if (!rst_n) begin data_ack_r1 <= 'b0; data_ack_r2 <= 'b0; end else begin data_ack_r1 <= data_ack; data_ack_r2 <= data_ack_r1; end end always @(posedge clk_a or negedge rst_n) begin if (!rst_n) begin data <= 'b0; end else if (data_ack_r1 && !data_ack_r2)begin data <= data + 'd1; end end //同时在data_ack有效之后,开始计数五个时钟,之后发送新的数据,也就是再一次拉高data_req. reg [2:0] cnt; always @(posedge clk_a or negedge rst_n) begin if (!rst_n) begin cnt <= 'd0; end else if (data_ack_r1 && !data_ack_r2) begin cnt <= 'd0; end else if (data_req)begin cnt <= cnt; end else begin cnt <= cnt +'d1; end end always @(posedge clk_a or negedge rst_n) begin if (!rst_n) begin data_req <= 'b0; end else if (cnt == 'd4) begin data_req <= 'b1; end else if (data_ack_r1 && !data_ack_r2)begin data_req <= 'b0; end end endmodule module data_receiver( input clk_b, input rst_n, input data_req, input [3:0] data, output reg data_ack ); reg data_req_r1,data_req_r2; always @(posedge clk_b or negedge rst_n) begin if (!rst_n) begin data_req_r1 <= 'b0; data_req_r2 <= 'b0; end else begin data_req_r1 <= data_req; data_req_r2 <= data_req_r1; end end reg [2:0] data_o; always @(posedge clk_b or negedge rst_n) begin if (!rst_n) begin data_o <= 'b0; data_ack <= 'b0; end else if (data_req_r1 && !data_req_r2 )begin data_o <= data; data_ack <= 'b1; end else begin data_ack <= 'd0; data_o <= data_o; end end endmodule
关键点在于data信号和控制信号是分开变化考虑的,而不是同时变化。
可以这样想,如果控制信号和data信号的变化趋势相同,那么就不需要使用控制信号来指示了。