状态机表述
/*=============================================================================
#
# Author : yangl - yl.ee@qq.com
# What's Up : Keep on going never give up
# Create Date : 2020-06-07 22:48
# Last Modified : 2020-06-07 23:55
# Filename : async_shake_hand.v
# Description :
#
=============================================================================*/
module async_shake_hand (
input clkrx, // rx clock, fast clock
input rst_n,
input req,
input [7:0] din,
input clktx, // tx clock, slow clock
output ack,
output reg [7:0] dout
);
reg [1:0] ack_reg;
assign ack = ack_reg[1];
//---------------------------------------------------
// rx ack
//---------------------------------------------------
reg req_reg;
always @(posedge clkrx or negedge rst_n) begin
if (!rst_n)
req_reg <= 1'b0;
else if(req)
req_reg <= 1'b1;
else if(ack)
req_reg <= 1'b0;
end
//---------------------------------------------------
// req sync
//---------------------------------------------------
reg [2:0] req_reg_sync;
always @(posedge clktx or negedge rst_n) begin
if (!rst_n)
req_reg_sync <= 3'b000;
else
req_reg_sync <= {req_reg_sync[1:0], req_reg};
end
//---------------------------------------------------
// dout
//---------------------------------------------------
wire pos_req = req_reg_sync[1] & ~ req_reg_sync[2];
always @(posedge clktx or negedge rst_n) begin
if (!rst_n)
dout <= 8'd0;
else if(pos_req)
dout <= din;
end
//---------------------------------------------------
// release
//---------------------------------------------------
always @(posedge clkrx or negedge rst_n) begin
if (!rst_n)
ack_reg <= 2'b00;
else
ack_reg <= {ack_reg[0], req_reg_sync[1]};
end
endmodule