ISP/rtl/BayerProcess/Windows.sv

120 lines
4.1 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`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