。
什么是握手協(xié)議
說起握手,首先查了一下百度百科。握手是一種禮儀,起源于中世紀(jì)的歐洲,順序為長幼有序,女士優(yōu)先。(PS:所以握手的時候,男士記得要紳士一點哦)。
在芯片中,握手是最古老的跨時鐘域之間傳輸數(shù)據(jù)的方式。握手機(jī)制通過將脈沖信號展寬,待輸出一側(cè)檢測到信號并將其解析為脈沖信號后,再向輸入一側(cè)發(fā)送應(yīng)答信號,表明接收到信號并且傳輸完成。
為什么要握手
在人類的進(jìn)化史中,握手作為一種善意的表達(dá)方式,可以增進(jìn)人與人之間的和諧。言歸正傳,那么數(shù)字電路中為什么也需要握手機(jī)制呢?這是因為在數(shù)字電路中,跨時鐘域處理是個較為常見的問題。關(guān)于跨時鐘域,我們公眾號之前有介紹過,想復(fù)習(xí)一下的同學(xué)可以查看一下之前寫的文章。
在從快時鐘向慢時鐘傳遞時,由于輸入信號變化較快,輸出一側(cè)可能跟不上輸入的變化,從而導(dǎo)致“漏采“現(xiàn)象。由于兩個時鐘之間的頻率不同,來自快時鐘域的脈沖信號,還沒來得及被慢時鐘的采到,便轉(zhuǎn)瞬即逝,從而導(dǎo)致信號被漏采。此時,握手機(jī)制便可以大顯神通。
握手機(jī)制的原理
(1)發(fā)送端在t_clk時鐘域下將需要發(fā)送的數(shù)據(jù)準(zhǔn)備好后,將t_rdy信號置為有效,該信號必須在tclk下降沿輸出。接收端在rclk時鐘域下同步r_rdy信號,同步后的信號命名為t_rdy_rclk。
(2)接收端在t_rdy_rclk有效期間,對t_data進(jìn)行采樣,得到t_data_rclk。
(3)接收端將r_ack信號置為1,信號必須在rclk下降沿輸出。發(fā)送端將r_ack同步為r_ack_tclk。
至此,已經(jīng)完成“半握手”,發(fā)送端在輸出下一數(shù)據(jù)前,不會等到r_ack_tclk被置為0。半握手機(jī)制工作速度快,但是使用不當(dāng)有可能會導(dǎo)致操作錯誤。然而,如果要從高頻時鐘向低頻時鐘傳輸數(shù)據(jù),則需要采用全握手機(jī)制。
(4)當(dāng)r_ack_tclk為高電平時,發(fā)送端將t_rdy置為0。
(5)當(dāng)t_rdy_rclk為低電平時,接收端將r_ack置為0。
(6)當(dāng)r_ack_tclk為低電平時,發(fā)送端將t_rdy重新置為1發(fā)送端可以發(fā)送新的數(shù)據(jù)。
至此,全握手完成。顯然,全握手過程耗時較長,數(shù)據(jù)傳輸較慢。但是全握手機(jī)制穩(wěn)定可靠,可以在兩個任意頻率的時鐘域中安全地進(jìn)行數(shù)據(jù)傳輸。需要注意一點的是,數(shù)據(jù)應(yīng)該在發(fā)送時鐘域內(nèi)穩(wěn)定至少兩個時鐘上升沿,請求信號req的寬度應(yīng)該超過兩個時鐘周期,否則從高速時鐘向低速時鐘傳遞可能無法捕捉到該信號,也就是信號“失聯(lián)”了。
握手機(jī)制的代碼實現(xiàn)
發(fā)送端狀態(tài)機(jī):
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
接收端狀態(tài)機(jī):
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
握手機(jī)制的缺點
一個字:慢。
好了,希望本文對大家有所幫助。
審核編輯 :李倩
-
數(shù)字電路
+關(guān)注
關(guān)注
193文章
1608瀏覽量
80680 -
代碼
+關(guān)注
關(guān)注
30文章
4798瀏覽量
68726 -
脈沖信號
+關(guān)注
關(guān)注
6文章
399瀏覽量
37009
原文標(biāo)題:談?wù)剶?shù)字芯片中的握手協(xié)議
文章出處:【微信號:IP與SoC設(shè)計,微信公眾號:IP與SoC設(shè)計】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論