代码头ready_a声明为了wire型,所以是暗示用组合逻辑。
对于三个输出信号,分别来看
ready_a:用来和valid_a握手,表示当前模块可以从上游模块接收数据进行累加。所以就要判断在什么情况下,当前模块是可以接收数据的。
当输入数据不足四个时,此时可以继续接收数据,标识信号是valid_b还未拉高。
当输入数据已经四个时,就要看下游是否准备好接收结果,如果下游ready_b为高,则表示结果可以送出,当前模块可以接收数据,标识信号是ready_b为高。
valid_b:在输入第四个数并且握成功的下一拍拉高,在与ready_b握手成功后拉低。
data_out:每次握手成功,上次结果与当前输入进行相加。注意在valid_b与ready_b握手成功后,data_out要接收新的数据,此时需判断valid_a与ready_a是否握手成功。
由于valid_b明确性的要在第四个数输入后就拉高,握手成功后才拉低,因此需要一个计数器进行指示第四个数据输入
`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] state_cnt ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
state_cnt <= 'd0 ;
else if(valid_a & ready_a )
state_cnt <= state_cnt + 1 ;
else
state_cnt <= state_cnt ;
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
data_out <= 'd0 ;
else if(valid_a & ready_a & valid_b & ready_b)
data_out <= data_in ;
else if(valid_a & ready_a)
data_out <= data_in + data_out ;
else
data_out <= data_out ;
end
assign ready_a = (ready_b) | (!valid_b);
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
valid_b <= 1'b0 ;
else if(state_cnt == 2'd3 & valid_a & ready_a)
valid_b <= 1'b1 ;
else if(valid_b & ready_b)
valid_b <= 1'b0 ;
else
valid_b <= valid_b ;
end
endmodule
标签:进阶,握手,累加,牛客,valid,ready,input,接收数据,data
From: https://www.cnblogs.com/icwangpu/p/17029040.html