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
);
reg [1:0] num_cnt = 0;
reg full_flag = 0;
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
num_cnt <= 2'd0;
data_out <= 10'd0;
full_flag <= 1'b0;
valid_b <= 1'b0;
end
else begin
if(valid_a == 1'b1 && ready_a == 1'b1)begin
if(num_cnt == 2'd3 && full_flag == 1'b0)begin
full_flag <= 1'b1;
data_out <= data_out + data_in;
valid_b <= 1'b1;
end
else begin
valid_b <= 1'b0;
if(num_cnt == 2'd0)begin
num_cnt <= num_cnt + 1'b1;
data_out <= data_in;
end
else begin
num_cnt <= num_cnt + 1'b1;
data_out <= data_out + data_in;
end
end
end
end
end
assign ready_a = (valid_b == 1 && ready_b == 0) ? 0 : 1;
always@(*)begin
if(valid_b == 1'b1)begin
if(ready_b == 1'b1)begin
num_cnt = 2'd0;
full_flag = 1'b0;
end
end
end
endmodule
需要注意的是 只有当valid_a 与 ready_a同时为1才能累加数据,ready_b为高时清空计数器,在下一个时钟上升沿valid_b拉低。ready_a与ready_b之间是组合逻辑的关系,累加4个之后,valid_b拉高 然后若是ready_b为低则立刻将ready_a拉低,表示没准备好接收上游数据,数据被锁存住。核心:只有valid_a ready_a同时为高才能累加数据,只有valid_b ready_b同时为高 才能将累加结果输出,并在下一时钟上升沿重新开始累加。