`timescale 1ns / 1ps module Windows #( parameter DATA_WIDTH = 16, parameter IMAGE_WIDTH = 1936, parameter IMAGE_HEIGHT = 1088, parameter WINDOWS_WIDTH = 3, parameter WINDOWS_ANCHOR_X = 1, //禁止大于WINDOWS_WIDTH-1 parameter WINDOWS_ANCHOR_Y = 1 //禁止大于WINDOWS_WIDTH-1 ) ( // 基本信号 input wire clk, input wire reset, // 数据线 input wire [DATA_WIDTH - 1:0] in_data, output reg [DATA_WIDTH - 1:0] out_data[WINDOWS_WIDTH*WINDOWS_WIDTH], // 数据输出线 // 有效信号 input wire in_valid, // 上一模块输出数据有效 output reg out_valid, // 当前模块输出数据有效 // 准备信号 Windows模块无法停止,因此默认不处理准备信号 input wire in_ready, output wire out_ready ); assign out_ready = 1'b1; reg [DATA_WIDTH - 1:0] regx_in_data [WINDOWS_WIDTH-1]; reg [DATA_WIDTH - 1:0] regx_out_data[WINDOWS_WIDTH-1]; reg [WINDOWS_WIDTH - 2:0] regx_in_valid, regx_out_valid; reg [DATA_WIDTH - 1:0] data_out_shift[WINDOWS_WIDTH-1][2*(WINDOWS_WIDTH-1)]; /* outdata[x]: SHIFT_REG1 -> 0 3 6 . . SHIFT_REG0 -> 1 4 7 . . in_data -> 2 5 8 . . . . . . . . */ reg [15:0] pos_x, pos_y; always @(posedge clk) begin if (reset) begin pos_x <= 0; pos_y <= 0; end else if (regx_out_valid[WINDOWS_WIDTH-2]) begin pos_x <= (pos_x >= IMAGE_WIDTH - 1) ? (0) : (pos_x + 1); pos_y <= (pos_x >= IMAGE_WIDTH - 1)?((pos_y >= IMAGE_HEIGHT - 1)?(0):(pos_y + 1)):(pos_y); end else begin pos_x <= pos_x; pos_y <= pos_y; end end integer i, j; always @(posedge clk) begin if (reset) begin for (i = 0; i < WINDOWS_WIDTH * WINDOWS_WIDTH; i = i + 1) out_data[i] <= 0; out_valid <= 0; end else if (regx_out_valid[WINDOWS_WIDTH-2]) begin for (i = 0; i < WINDOWS_WIDTH; i = i + 1) begin for (j = 0; j < WINDOWS_WIDTH; j = j + 1) begin if (i == WINDOWS_WIDTH - 1) begin if (j == 0) out_data[(WINDOWS_WIDTH*i)+j] <= regx_out_data[WINDOWS_WIDTH-2]; else out_data[(WINDOWS_WIDTH*i)+j] <= data_out_shift[j-1][2*i-1]; end else out_data[(WINDOWS_WIDTH*i)+j] <= out_data[(WINDOWS_WIDTH*(i+1))+j]; end end out_valid <= ~((pos_y <= WINDOWS_WIDTH-WINDOWS_ANCHOR_Y-1 && pos_x < WINDOWS_WIDTH-WINDOWS_ANCHOR_X-1) || (pos_y < WINDOWS_WIDTH-WINDOWS_ANCHOR_Y-1)); end else begin for (i = 0; i < WINDOWS_WIDTH * WINDOWS_WIDTH - 1; i = i + 1) out_data[i] <= out_data[i]; out_valid <= 0; end end always @(posedge clk) begin if (reset) for (i = 0; i < WINDOWS_WIDTH - 1; i = i + 1) for (j = 0; j < WINDOWS_WIDTH - 1; j = j + 1) data_out_shift[i][j] <= 0; else for (i = 0; i < WINDOWS_WIDTH - 1; i = i + 1) begin for (j = 0; j < 2 * (WINDOWS_WIDTH - 1); j = j + 1) begin if (i == WINDOWS_WIDTH - 2 && j == 0) data_out_shift[i][j] <= in_data; else if (j == 0) data_out_shift[i][j] <= regx_out_data[(WINDOWS_WIDTH-2-i)-1]; else data_out_shift[i][j] <= data_out_shift[i][j-1]; end end end always @(*) begin for (i = 0; i < WINDOWS_WIDTH - 1; i = i + 1) begin if (i == 0) regx_in_data[i] = in_data; else regx_in_data[i] = regx_out_data[i-1]; end for (i = 0; i < WINDOWS_WIDTH - 1; i = i + 1) begin if (i == 0) regx_in_valid[i] = in_valid; else regx_in_valid[i] = regx_out_valid[i-1]; end end generate genvar o; for (o = 0; o < WINDOWS_WIDTH - 1; o = o + 1'b1) begin : shift_register SHIFT_REGISTER #( .DATA_WIDTH (DATA_WIDTH), .IMAGE_WIDTH(IMAGE_WIDTH), .IFOUTIMME (1'b1) ) shift_registerx ( .clk (clk), .reset (reset), .in_data (regx_in_data[o]), .out_data (regx_out_data[o]), .in_valid (regx_in_valid[o]), .out_valid(regx_out_valid[o]) ); end endgenerate endmodule