`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 ); // localparam S0 = 4'd0; localparam S1 = 4'd1; localparam S2 = 4'd2; localparam S3 = 4'd3; localparam S4 = 4'd4; localparam S5 = 4'd5; // reg and wire reg [3:0]state,next_state; // assign ready_a = (state == S4 && (~ready_b))?1'b0:1'b1; // always @(posedge clk or negedge rst_n) begin if(~rst_n) begin state <= S0; end else begin state <= next_state; end end always @(*) begin if(state == S4) valid_b <= 1'b1; else begin valid_b <= 1'b0; end case(state) S0: begin if(valid_a) next_state <= S1; else begin next_state <= S0; end end S1: begin if(valid_a) next_state <= S2; else begin next_state <= S1; end end S2: begin if(valid_a) next_state <= S3; else begin next_state <= S2; end end S3: begin if(valid_a) next_state <= S4; else begin next_state <= S3; end end S4: begin if(ready_b) next_state <= S1; else begin next_state <= S4; end end default: next_state <= S0; endcase end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin // valid_b <= 1'b0; data_out <= 'd0; end else begin case(state) S0: begin // valid_b <= 1'b0; if(valid_a) data_out <= data_in; else begin data_out <= data_out; end end S1,S2,S3: begin // valid_b <= 1'b0; if(valid_a) data_out <= data_out + data_in; else begin data_out <= data_out; end end S4: begin // valid_b <= 1'b1; if(ready_b) data_out <= data_in; else begin data_out <= data_out; end end default: ; endcase end end endmodule