握手機制的verilog實現

2021-09-20 04:05:47 字數 3682 閱讀 1246

「一種解決匯流排同步問題的方法是使用乙個保持暫存器和握手訊號」,這也就是「先非同步暫存,後同步寫入」的方法

分別編寫了傳送時鐘域和接收時鐘域的**進行測試,用到兩組mem,以便於觀察實驗結果:

//傳送端**

//接收域應答訊號ack採用兩級暫存器同步,便於時序收斂

module woshou_tx

( input rst_n,

input t_clk,

input ack,

output [7:

0] dout,

output reg req);

reg ack_reg1,ack_reg2;

reg [7:

0] data_buf;

reg [2:

0]tr_state;

reg [7:

0] tr_mem_addr;

reg [7:

0] tr_mem [

255:0]

;parameter tr_idle=

3'b000, snd_data_req=3'b001, chk_ack_active=

3'b010, chk_comm_end=3'b100;

always@(negedge rst_n or posedge t_clk)

begin

if(!rst_n)begin

ack_reg1 <=

1'b0;

ack_reg2 <=

1'b0;

endelse begin

ack_reg1 <= ack;

ack_reg2 <= ack_reg1;

endend//

always@(posedge t_clk or negedge rst_n)

begin

if(!rst_n)

begin

data_buf <=

1'b0;

tr_state <= tr_idle;

tr_mem_addr <=

1'b0;

endelse

case

(tr_state)

tr_idle:

//初始化狀態

begin

req <=

1'b0;

tr_mem_addr <=

1'b0;

tr_state <= snd_data_req;

endsnd_data_req:

//送資料到匯流排上和傳送請求訊號

begin

data_buf <= tr_mem[tr_mem_addr]

; req <=

1'b1;

//傳送請求訊號,請求訊號為高,表示請求接收

tr_mem_addr <= tr_mem_addr +1;

tr_state <= chk_ack_active;

endchk_ack_active:

//檢測應答訊號為高,釋放請求訊號

begin

if(ack_reg2 ==

1'b1)

//便於時序收斂

begin

req <=

1'b0;

//釋放請求訊號

tr_state <= chk_comm_end;

endelse tr_state <= chk_ack_active;

endchk_comm_end:

//檢測握手通訊結束,如果應答訊號被釋放,一次握手結束

begin

if(ack_reg2 ==

1'b0)

tr_state <= snd_data_req;

else

tr_state <= chk_comm_end;

enddefault

:tr_state <= tr_idle;

endcase

endassign dout = data_buf;

endmodule

module woshou_rx

( input rst_n,

input r_clk,

input req,

input [7:

0] din,

output reg ack )

;reg req_reg1,req_reg2;

reg [2:

0] re_state;

reg [7:

0] re_mem_addr;

reg [7:

0] re_mem[

255:0]

;parameter re_idle=

3'b000, chk_req_active=3'b001, chk_req_release=

3'b010;

always@(posedge r_clk or negedge rst_n)

begin

if(!rst_n)

begin

req_reg1 <=

1'b0;

req_reg2 <=

1'b0;

endelse

begin

req_reg1 <= req;

req_reg2 <= req_reg1;

end

end//

always@(posedge r_clk or negedge rst_n)

begin

if(!rst_n)

begin

re_state <= re_idle;

ack <=

1'b0;

re_mem_addr <=

1'b0;

endelse

case

(re_state)

re_idle:

//初始化狀態

begin

re_mem_addr <=0;

re_state <= chk_req_active;

endchk_req_active:

//檢測傳送端的資料傳送請求訊號

begin

if(req_reg2 ==1)

//如果有請求訊號,接收資料

begin

re_state <= chk_req_release;

re_mem_addr <= re_mem_addr +1;

re_mem[re_mem_addr]

<= din;

//接收資料存放到mem

ack <=

1'b1;

//檢測到請求訊號,傳送接收端應答訊號

endelse re_state <= chk_req_active;

endchk_req_release:

//檢測請求訊號釋放,釋放應答訊號

begin

if(req_reg2 ==0)

begin

ack <=

1'b0;

//釋放應答訊號,一次握手通訊結束

re_state <= chk_req_active;

endelse re_state <= re_idle;

enddefault

: re_state <= re_idle;

endcase

endendmodule

pcie握手機制 PCIe匯流排的通訊機制

pcie 匯流排的通訊機制 在介紹事務層之前,首先簡單地了解一下 pcie 匯流排的通訊機制。假設某 個裝置要對另乙個裝置進行讀取資料的操作,首先這個裝置 稱之為 requester 需要向另乙個裝置傳送乙個 request 然後另乙個裝置 稱之為 completer 通過completion pa...

pcie握手機制 PCIe匯流排的熱插拔機制

pcie 匯流排的熱插拔機制 某些特殊的應用場合可能要求 pcie 裝置能夠以高可靠性持續不間斷運 行,為此,pcie 匯流排採用熱插拔 hotplug 和熱切換 hotswap 技術,來實現不關閉系統電源的情況下更換 pcie 卡裝置。注 本文將簡單地介紹一下 pcie 匯流排的熱插拔機制,關於熱...

TCP三次握手機制

seq是序列號,這是為了連線以後傳送資料用的,ack是對收到的資料報的確認,值是等待接收的資料報的序列號。在第一次訊息傳送中,a隨機選取乙個序列號作為自己的初始序號傳送給b 第二次訊息b使用ack對a的資料報進行確認,因為已經收到了序列號為x的資料報,準備接收序列號為x 1的包,所以ack x 1,...