1.序言
本文详细说明了valid/ready握手机制,并以牛客网verilog在线刷题的时序逻辑部分,VL31题为例进行说明。
2.握手机制
通信双方进行数据传输:
Data:传输的数据,发送方提供给接收方;
Valid:数据准备好标志信号,发送方提供给接收方,表示已经准备好了需要发送的数据;
Ready:准备好接收数据标志信号,接收方提供给发送方。表示已经准备好了接收数据;
注意:当且仅当,在时钟触发沿到来时,发送方Valid信号和接收方Ready信号均为高时,数据才能有效传输。
3.例子
(1)例子来源:
牛客网 ---- verilog在线刷题----时序逻辑部分----VL31题
(2)描述
(3)分析
A串行输入数据累加器,既是数据发送方也是数据接收方:
在接收输入的加数时,累加器是数据接收方;
在将结算结果进行输出时,累加器是数据发送方;
B累加器作为数据接收方
Valid_a信号:由前面发送方提供;
Ready_a信号:在累加器运算好结果后,但这个结果还未被送出,累加器就不能接收数据,就需要将Ready_a拉低,其他时候均可以接收数据;
assign ready_a = ((cnt_4 == 'd0) && (valid_b) && (!ready_b))?1'b0:1'b1;
C累加器作为数据发送方
Valid_b信号:在计算好结果后,将Valid_b信号拉高,在从机接收完了数据后,将Valid_b信号拉低;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
valid_b <= 1'b0;
else if((cnt_4 == 2'd3) && (ready_a && valid_a))
valid_b <= 1'b1;
else if(valid_b && ready_b)
valid_b <= 1'b0;
else
valid_b <= valid_b;
end
Ready_b信号:由后方累加结果的数据接收方提供;
(4)完整代码
module valid_ready(
input clk ,
input rst_n ,
input [7:0] data_in ,
input valid_a ,
input ready_b ,
output ready_a ,
output reg valid_b ,
output reg [9:0] data_out
);
//模块准备好标志信号*****************************
assign ready_a = ((cnt_4 == 'd0) && (valid_b) && (!ready_b))?1'b0:1'b1;
//状态计数器
reg [1:0] cnt_4;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_4 <= 'd0;
else if(ready_a && valid_a)
if(cnt_4 == 2'd3)
cnt_4 <= 'd0;
else if(cnt_4 == 2'd0)
if(ready_b)
cnt_4 <= cnt_4 + 1'b1;
else
cnt_4 <= cnt_4;
else
cnt_4 <= cnt_4 + 1'b1;
else
cnt_4 <= cnt_4;
end
//结果累加
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
data_out <= 'd0;
else if(ready_a && valid_a)
if(cnt_4 == 2'd0)
data_out <= data_in;
else
data_out <= data_out + data_in;
else
data_out <= data_out;
end
//结果有效信号*****************************
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
valid_b <= 1'b0;
else if((cnt_4 == 2'd3) && (ready_a && valid_a))
valid_b <= 1'b1;
else if(valid_b && ready_b)
valid_b <= 1'b0;
else
valid_b <= valid_b;
end
endmodule