`timescale 1ns / 1ps
module Windows #(
parameter reg [ 4:0] DATA_WIDTH = 16       // 输入/输出数据位宽
)(
    // 基本信号
    input wire clk,
    input wire reset,
    //  数据线
    input wire [DATA_WIDTH - 1:0] in_data [3],     // 0、1、2分别表示第一、二、三行
    output reg [DATA_WIDTH - 1:0] out_data [3*3],   // 数据输出线
    //  有效信号
    input wire in_valid,    // 上一模块输出数据有效
    output wire out_valid,   // 当前模块输出数据有效
    //  准备信号
    input wire in_ready,    // 下一模块可接受新数据
    output wire out_ready    // 当前模块可接收新数据
);

  localparam PIPILINE = 3;

  reg [PIPILINE-1:0] pipeline_valid;

  //out_ready ：只要本模块可以接收数据就一直拉高
  assign out_ready = (pipeline_valid != {PIPILINE{1'b1}}) | ((pipeline_valid == {PIPILINE{1'b1}}) && in_ready);
  //out_valid ：只要本模块可以发出数据就一直拉高
  assign out_valid = (pipeline_valid == {PIPILINE{1'b1}});

  integer i;
  always @(posedge clk) begin
    if(reset) begin
      for(i=0;i<9;i=i+1) out_data[i] <= 0;
      pipeline_valid <= 0;
    end else begin
      if((pipeline_valid != {PIPILINE{1'b1}}) || ((pipeline_valid == {PIPILINE{1'b1}}) && in_ready))begin
        pipeline_valid[0] <= in_valid;
        out_data[6] <= in_data[0];
        out_data[7] <= in_data[1];
        out_data[8] <= in_data[2];
      end
      if((pipeline_valid[2] == 0) || (pipeline_valid[1] == 0) || ((pipeline_valid == {PIPILINE{1'b1}}) && in_ready))begin
        pipeline_valid[1] <= pipeline_valid[0];
        out_data[3] <= out_data[6];
        out_data[4] <= out_data[7];
        out_data[5] <= out_data[8];
      end
      if((pipeline_valid[2] == 0) || ((pipeline_valid == {PIPILINE{1'b1}}) && in_ready))begin
        pipeline_valid[2] <= pipeline_valid[1];
        out_data[0] <= out_data[3];
        out_data[1] <= out_data[4];
        out_data[2] <= out_data[5];
      end
    end
  end

endmodule

