`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