题解 | #数据累加输出#
数据累加输出
https://www.nowcoder.com/practice/956fa4fa03e4441d85262dc1ec46a3bd
`timescale 1ns/1ns 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] data_cnt; assign ready_a = !valid_b | ready_b;//下游准备好了或者上游来的数据还没接完,就可以告诉上有我还可以接 always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_cnt <= 'd0; else if(valid_a && ready_a) data_cnt <= (data_cnt == 2'd3) ? 'd0 : (data_cnt + 1'd1); //计数器0-3循环 end always @(posedge clk or negedge rst_n ) begin if(!rst_n) valid_b <= 'd0; else if(data_cnt == 2'd3 && valid_a && ready_a) //上游正常灌入并且计数到3的时候拉高下游使能。 valid_b <= 1'd1; else if(valid_b && ready_b) //下游接收完数据又可以接收的时候就拉低,保证只会在4数之和求出时拉高 valid_b <= 1'd0; end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_out <= 'd0; else if(ready_b && valid_a && ready_a && (data_cnt == 2'd0)) //求出4数之和后cnt清零,在上游正常写入的情况下,在可以往下游写入时输出数据 data_out <= data_in; else if(valid_a && ready_a) //正常写入时即可以计算累加 data_out <= data_out + data_in; end endmodule
这个题目关键在于理解上下游双向握手和无气泡传输的要求,双向握手就是两边都要准备好的时候才可以发起操作,无气泡就是操作完可以立即输出,而不是等待一个时钟