赞
踩
PART1:基本原理
在不同时钟域之间进行数据传输时,可以考虑使用握手同步机制。
握手同步机制分为半握手和全握手。当从低频时钟域向高频时钟域传输数据时,半握手机制比较适用,这是由于接收端可以更快地完成操作。但是当从高频时钟向低频时钟传输数据时,则需要全握手机制。
握手同步机制的工作步骤:
(1)发送端在t_clk时钟域下将需要发送的数据准备好后,将t_rdy信号置为有效,该信号必须在tclk下降沿输出。接收端在rclk时钟域下同步r_rdy信号,同步后的信号命名为t_rdy_rclk。
(2)接收端在t_rdy_rclk有效期间,对t_data进行采样,得到t_data_rclk。
(3)接收端将r_ack信号置为1,信号必须在rclk下降沿输出。发送端将r_ack同步为r_ack_tclk。
至此,已经完成“半握手”,发送端在输出下一数据前,不会等到r_ack_tclk被置为0。半握手机制工作速度快,但是使用不当有可能会导致操作错误。然而,如果要从高频时钟向低频时钟传输数据,则需要采用全握手机制。
(4)当r_ack_tclk为高电平时,发送端将t_rdy置为0。
(5)当t_rdy_rclk为低电平时,接收端将r_ack置为0。
(6)当r_ack_tclk为低电平时,发送端将t_rdy重新置为1发送端可以发送新的数据。
至此,全握手完成。显然,全握手过程耗时较长,数据传输较慢。但是全握手机制稳定可靠,可以在两个任意频率的时钟域中安全地进行数据传输。
上面过程比较绕口,因此我制作了一张流程图,如下所示:
PART2:verilog代码实现
发送端:使用三个状态的状态机,其跳转关系如下:
代码如下
module transmit(tclk,reset_tclk,t_rdy,data_avail,transmit_data,t_data,r_ack); input tclk; input reset_tclk; input data_avail; input [31:0]transmit_data; input r_ack; output t_rdy; output t_data; localparam IDLE_T = 2'd0, ASSERT_T_RDY = 2'd1, DEASSERT_T_RDY = 2'd2; reg [1:0] t_hndshk_state,t_hndshk_state_nxt; reg t_rdy,t_rdy_nxt; reg [31:0] t_data,t_data_nxt; reg r_ack_tclk; always@(*)begin t_hndshk_state_nxt = t_hndshk_state; t_rdy_nxt = 1'b0; t_data_nxt = t_data; case(t_hndshk_state) IDLE_T:begin if(data_avail) begin t_rdy_nxt = 1'b1; t_hndshk_state_nxt = ASSERT_T_RDY; t_data_nxt = transmit_data; end end ASSERT_T_RDY:begin if(r_ack_tclk)begin t_rdy_nxt = 1'b0; t_hndshk_state_nxt = DEASSERT_T_RDY; t_data_nxt = 'd0; end else begin t_rdy_nxt = 1'b1; t_data_nxt = transmit_data; end end DEASSERT_T_RDY:begin if(!r_ack_tclk)begin if(data_avail)begin t_rdy_nxt = 1'b1; t_hndshk_state_nxt = ASSERT_T_RDY; t_data_nxt = transmit_data; end else begin t_hndshk_state_nxt = IDLE_T; end end end endcase end always@(posedge tclk or negedge reset_tclk)begin if(!reset_tclk)begin t_rdy <= 1'b0; t_hndshk_state <= IDLE_T; t_data <= 32'h00000000; r_ack_tclk <= 1'b0; end else begin t_rdy <= t_rdy_nxt; t_hndshk_state <= t_hndshk_state_nxt; t_data <= t_data_nxt; r_ack_tclk <= r_ack; end end endmodule
接收端:使用两个状态的状态机,跳转关系如下:
代码如下:
module receiver(rclk,reset_rclk,t_rdy,t_data,r_ack); input rclk,reset_rclk; input t_rdy; input[31:0] t_data; output r_ack; reg r_hndshk_state,r_hndshk_state_nxt; reg t_rdy_rclk; reg[31:0] t_data_rclk,t_data_rclk_nxt; reg r_ack,r_ack_nxt; localparam IDLE_R = 1'b0, ASSERT_ACK = 1'b1; always@(*)begin r_hndshk_state_nxt = r_hndshk_state; r_ack_nxt = 1'b0; t_data_rclk_nxt = t_data_rclk; case(r_hndshk_state) IDLE_R:begin if(t_rdy_rclk)begin r_hndshk_state_nxt = ASSERT_ACK; t_data_rclk_nxt = t_data; r_ack_nxt = 1'b1; end end ASSERT_ACK:begin if(!t_rdy_rclk)begin r_hndshk_state_nxt = IDLE_R; r_ack_nxt = 1'b0; end else begin r_ack_nxt = 1'b1; end end endcase end always@(posedge rclk or negedge reset_rclk)begin if(!reset_rclk)begin r_hndshk_state <= IDLE_R; t_data_rclk <= 1'b0; t_rdy_rclk <= 1'b0; r_ack <= 1'b0; end else begin r_hndshk_state <= r_hndshk_state_nxt; t_data_rclk <= t_data_rclk_nxt; t_rdy_rclk <= t_rdy; r_ack <= r_ack_nxt; end end endmodule
测试代码
`timescale 1ns/1ns module testbench; reg tclk_tb,rclk_tb; reg [31:0] transmit_data_tb; reg reset_tclk_tb,reset_rclk_tb; reg data_avail_tb; wire t_rdy_tb; wire [31:0] t_data_tb; wire r_ack_tb; parameter CLK_HALF_PERIOD1 = 5; parameter CLK_HALF_PERIOD2 = 8; parameter RESET_DELAY = 100; initial begin tclk_tb = 0; rclk_tb = 0; end always #CLK_HALF_PERIOD1 tclk_tb = ~tclk_tb; always #CLK_HALF_PERIOD2 rclk_tb = ~rclk_tb; initial begin reset_rclk_tb = 0; reset_tclk_tb = 0; #RESET_DELAY reset_rclk_tb = 1; reset_tclk_tb = 1; end initial begin #500; data_avail_tb = 1; transmit_data_tb = 32'h96431346; end transmit transmit_test (.tclk(tclk_tb), .reset_tclk(reset_tclk_tb), .t_rdy(t_rdy_tb), .data_avail(data_avail_tb), .transmit_data(transmit_data_tb), .t_data(t_data_tb), .r_ack(r_ack_tb)); receiver receiver_test (.rclk(rclk_tb), .reset_rclk(reset_rclk_tb), .t_rdy(t_rdy_tb), .t_data(t_data_tb), .r_ack(r_ack_tb)); endmodule
PART3:v仿真结果及其分析
由波形图我们可以发现,在t_rdy有效期间,t_data=t_transmit,将数据发送出去(为了简便,这里把要发送的数据都设为一个数值),在t_rdy无效期间,t_data输出32’h00000000。并且t_rdy会带动后面的t_rdy_rclk、r_ack、r_ack_tclk的一连串变化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。