集成电路流片随笔19:full_handshake
全双工握手接收模块 (full_handshake_rx
),它的功能是接收来自发送端 (tx
) 的数据,并对发送端进行应答(ACK)。模块实现了基于握手的通信机制,以确保数据的可靠传输。模块的输入输出分别连接于发送端和接收端,并通过状态机来控制数据的接收和确认。
代码解析
1. 模块参数与输入输出信号
module full_handshake_rx #(parameter DW = 32)( // RX要接收数据的位宽input wire clk, // RX端时钟信号input wire rst_n, // RX端复位信号// from txinput wire req_i, // TX端请求信号input wire[DW-1:0] req_data_i, // TX端输入数据// to txoutput wire ack_o, // RX端应答TX端信号// to rxoutput wire[DW-1:0] recv_data_o,// RX端接收到的数据output wire recv_rdy_o // RX端是否接收到数据信号
);
DW
:接收数据的位宽,默认为 32 位。clk
:时钟信号,用于同步操作。rst_n
:复位信号,低电平有效,复位模块。req_i
:发送端的请求信号,表示发送端准备好发送数据。req_data_i
:发送端要发送的数据。ack_o
:接收端的应答信号,向发送端确认数据已经收到。recv_data_o
:接收的数据输出。recv_rdy_o
:接收数据准备好信号,表示接收端已经准备好接收数据。
2. 状态机的定义
localparam STATE_IDLE = 2'b01;
localparam STATE_DEASSERT = 2'b10;
STATE_IDLE
:表示接收端空闲状态,等待接收数据。STATE_DEASSERT
:表示接收端准备好状态,等待请求信号撤销。
3. 状态机转换
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginstate <= STATE_IDLE;end else beginstate <= state_next;end
endalways @ (*) begincase (state)STATE_IDLE: beginif (req == 1'b1) beginstate_next = STATE_DEASSERT;end else beginstate_next = STATE_IDLE;endendSTATE_DEASSERT: beginif (req) beginstate_next = STATE_DEASSERT;end else beginstate_next = STATE_IDLE;endenddefault: beginstate_next = STATE_IDLE;endendcase
end
- 状态机逻辑:
- 在
STATE_IDLE
状态,接收端等待req
信号的到来。当req == 1
时,表示发送端已经准备好数据,接收端将转到STATE_DEASSERT
状态,准备接收数据。 - 在
STATE_DEASSERT
状态,接收端等待req
信号撤销。当req == 0
时,表示接收结束,回到STATE_IDLE
状态。
- 在
4. 同步请求信号
reg req_d;
reg req;always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginreq_d <= 1'b0;req <= 1'b0;end else beginreq_d <= req_i;req <= req_d;end
end
req
信号是对req_i
信号的同步处理,确保req
信号稳定,消除时钟不同时的亚稳态问题。
5. 接收数据处理
reg[DW-1:0] recv_data;
reg recv_rdy;
reg ack;always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginack <= 1'b0;recv_rdy <= 1'b0;recv_data <= {(DW){1'b0}};end else begincase (state)STATE_IDLE: beginif (req == 1'b1) beginack <= 1'b1;recv_rdy <= 1'b1; // 这个信号只会持续一个时钟recv_data <= req_data_i; // 这个信号只会持续一个时钟endendSTATE_DEASSERT: beginrecv_rdy <= 1'b0;recv_data <= {(DW){1'b0}};if (req == 1'b0) beginack <= 1'b0;endendendcaseend
end
-
在
STATE_IDLE
状态,接收端在收到req == 1
时:- 将
ack
信号设为1
,表示接收端已准备好接收数据。 - 将
recv_rdy
设为1
,表示接收端准备好接收数据,且仅在该时钟周期有效。 - 将
recv_data
设置为req_data_i
,即接收的数据。
- 将
-
在
STATE_DEASSERT
状态,接收端等待req == 0
,表示接收完成,此时recv_rdy
被清零,recv_data
被重置。
6. 输出信号赋值
assign ack_o = ack;
assign recv_rdy_o = recv_rdy;
assign recv_data_o = recv_data;
ack_o
:表示接收端的应答信号,确认数据接收。recv_rdy_o
:表示接收端是否准备好接收数据。recv_data_o
:接收到的数据。
总结:
- 该模块实现了通过 JTAG 协议进行数据的接收,并通过握手信号确保接收端和发送端的数据交互可靠。
- 它基于 状态机,根据接收到的请求信号来控制接收过程:
- 在
STATE_IDLE
状态时,接收端等待接收请求; - 在
STATE_DEASSERT
状态时,接收端确认接收到数据并准备接收下一批数据。
- 在
- 同时通过应答信号(
ack
)向发送端确认数据接收状态,并通过recv_rdy
和recv_data
输出接收到的数据。