【基本知识】握手
其实握手在平时设计的时候已经用到了,只是因为这知识实在是太基础,以至于都没有在意这种方法叫什么名字。废话不多说,开整。
握手其实就是通信的双方需要传输数据时,要发送数据的一方产生请求信号,接收方的此时如果可以接受,就会产生响应信号,发送方检测到响应信号后就开始发送。
实际就是我们常用的req、ack。
我想了下,单方面的表模块空闲与否的busy/valid信号应该不算握手吧。此外,应该还有一种在通信上的握手吧?就是上位机先发送数据包请求发送数据,然后下位机回应繁忙或者空闲的数据包。
简单(入门)的握手就是下面这个,注意,这真的是入门的握手:
module shake_in(
input clk, //内部输入时钟
input rst_n,//内部的复位信号,这里是异步复位,同步释放。
input req_in,//外部请求信号。
input ack_in,//外部响应信号。
input data_in,//外部数据输入。
output reg ack_out,//内部响应输出
output reg req_out,//内部接收输出(告诉外部数据已接收)
output reg data_in_r//数据输出给内部。
);
//外部输入信号应该过两级缓存来避免亚稳态,此处略去,直接用原信号了。
//产生响应信号
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
ack_out <= 1'b0; //默认为低电平
else if( req_in)
ack_out <= 1'b1; //接收到信号抬高
else if(!req_in)
ack_out <= 1'b0; //请求信号结束,响应结束。
end
//数据接收信号,接受数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
data_in_r <= 1'b0;
req_out <= 1'b1; //默认为高电平
end
else if(ack_in)begin
data_in_r <= data_in; //数据存入
req_out <= 1'b0; //数据存入同时拉低,告诉对方数据已接收。
end
else if(!ack_in)begin //数据方拉低响应说明此次通信完成。
data_in_r <= data_in_r;
req_out <= 1'b1;
end
end
endmodule