一、握手协议
当由快时钟跨到慢时钟时,为了避免采不到信号这种情况,通常运用电平展宽、脉冲同步器、或者是握手处理。
图中所示,发送端时钟是clk1,接收端时钟是clk2,当发送端接收到外部传过的数据时,准备就绪时拉高t_req,向接收端发送该信号表示我准备好传输了你准备好接收了吗,该信号到达接收端后进行两级同步器,为什么两级同步,主要是如果是快转慢,你需要用这种方式来展宽信号电平,这里由于是慢转快,仅仅两级同步就是 为了减小亚稳态发生的概率,两级同步时在接收端的时钟clk2下发生的,两级同步后得到t_req_rr,在下一个clk2时钟沿来时发现t_req_rr为高,进行拉高ack,表示我接受到你的请求了,同时开始采集数据,此时的数据最稳定,当发送端接收到这个ack信号后,进行同步处理,同样是两级同步得到re_ack_rr信号,在clk1上升沿识别到该信号为1后,在下一个时钟沿,时拉低req,表示发送端不在向接收端请求发送;半握手结束;
接下来进行全握手的部分:
当拉低的req信号,再次经过clk2两级同步后得到req_rr为0时,下一个时钟沿拉低ack信号,表示以及完成接收任务,该信号经过clk1发送时钟的两级同步后的ack_rr为0,下一个时钟沿来的时候进行下一次数据的传输,如果检测到总线有数据要传输,下一个时钟拉高req,重复以上传输;
快时钟,转慢时钟时,如图所示:
当监测到总线上要传输数据时,传输器拉高req,req经过接收器的时钟des_clk的两级同步后得到des_req_syn2,在下一时钟上升沿拉高des_ack,且同时接收器开始采集数据,此时发送端通过将ack信号在发送端时钟下打两拍得到src_ack_sync2,后下一次时钟上升沿拉低req,同样马上接收端在就知道他拉低了req,经过两拍后再下一时钟沿拉低ack,ack信号在发送端时钟下经过两拍后再下一拍开始下一个数据的传输,同理如果有下一个数据则经过一拍拉高req请求传输。
二、代码
1.>top层:
module asynchronous_data(
input tclk,
input rclk,
input rstn,
input rrstn,
input [4:0] data_in,
output[4:0]data_out
);
wire req;
wire ack;
reg [4:0]tx_data;
tx tx_module(
.tclk(tclk