题解 | 数据累加输出
数据累加输出
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 ); assign ready_a = ~valid_b | ready_b; //上个数据有效且准备好接收输出数据了 wire in_flag=valid_a && ready_a;//握手成功 reg [1:0] in_count; always@(posedge clk or negedge rst_n) if(!rst_n) in_count <= 0; else if(in_flag) begin//握手成功,开始计数 if(in_count == 2'd3)//计满四个数,清零 in_count <= 0; else in_count <= in_count + 1; end //valid_b用来指示数据输出data_out的有效性; always@(posedge clk or negedge rst_n) if(!rst_n) valid_b <= 0; else if((in_count == 2'd3) && in_flag) //上游计满四个数了 valid_b <= 1;//此时data_out的值就是四个数的和,data_out有效 else if(valid_b && ready_b)//下游握手成功,数据输出 valid_b <= 0;//拉低,等待下一个有效输出数据 always@(posedge clk or negedge rst_n) if(!rst_n) data_out <= 0; else if(in_flag) begin//上游准备好了 if(in_count == 2'd0)//新数据开始进来了 data_out <={2'd0,data_in} ;//等于第一个数,相当于清零 else data_out <= data_out + {2'd0,data_in}; end endmodule
我真的是笨,整半天,虽然早就做出来了,但总感觉没太理解,自测跑出来不太对。看半天终于搞明白了。记录一下:
1.上下游:
(1)上游:给该模块发送数据的一端,发送:data_in, valid_a;该模块给上游端输出ready_a,表示自己准备好了,数据进来吧。
当valid_a=1(数据有效)+ready_a=1(可以接收数据进来)同时成立,握手成功,上游数据进来data_in;
(2)下游:接收该模块输出数据的一端。该模块发送:data_out, valid_b;下游端给该模块发送ready_b,表示可以接收data_out
当valid_b=1(数据有效)+ready_b=1(可以接收data_out)同时成立,握手成功,data_out输出给下游。
2.该模块三个输出信号:
(1)ready_a:什么时候本模块准备好接收新的data_in进来了呢?这个其实要反着思考,什么时候数据不能进来 ?
-->当前数据刚传完(valid_b=1),还没被下游接收(ready=0),下个数据你就先别进来-->ready_a=0
-->ready_a = ~(valid_b && ~ready)=~valid |ready;
注:还没被下游接收(ready=0),因为这里valid_b已经是1,如果ready为1,就握手成功,被下游接收了-->ready=0;
(2)data_out和valid_b其实是一样的。
上游握手成功后,有效data_in开始输入,计数四个数累加,然后就能得到有效的data_out和valid_b了。
但是现在我自测输出的图形是这样的,希望懂得小伙伴帮忙看看,为什么这里输出提前了一个周期,谢谢
破案了,下面是我用软件跑的,结果是对的,气死我了,用它这个自测卡了我好久,我就说怎么时序一直不对