题解 | #数据累加输出#
数据累加输出
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; //如果下游ready_b拉高,表示下游可以接收模块输出数据,那么此时ready_a应拉高;同时,如果valid_b为低,表示4个数据还没收完,所以也拉高继续接收。 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); 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) //提前一个周期+握手成功可以给valid_b //else if(data_cnt == 2'd3 ) valid_b <= 1'd1; else if(valid_b && ready_b)// 下游握手成功,在下个周期清除valid_b valid_b <= 1'd0; end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_out <= 'd0; else if(valid_a && ready_a && (data_cnt == 2'd0)) // 下游握手成功,输入4个数据的情况下下个周期给data //else if(ready_b && valid_a && ready_a && (data_cnt == 2'd0)) data_out <= data_in; else if(valid_a && ready_a) // 上游握手成功(前提是上一个累加和已经给下游b),实时输出当前数据。 data_out <= data_out + data_in; end endmodule