ISP/Crop/Crop.sv

104 lines
2.6 KiB
Systemverilog

module Crop #(
parameter reg [15:0] IN_WIDTH = 1934,
parameter reg [15:0] IN_HEIGHT = 1086,
parameter reg [15:0] OFFSET_X = 7,
parameter reg [15:0] OFFSET_Y = 3,
parameter reg [15:0] OUT_WIDTH = 640,
parameter reg [15:0] OUT_HEIGHT = 480,
parameter reg [4:0] COLOR_DEPTH = 8
) (
input wire clk,
input wire reset,
input wire in_en,
output wire out_ready,
output wire out_receive,
input wire [COLOR_DEPTH - 1:0] in_data[3],
input wire in_ready,
input wire in_receive,
output reg out_en,
output reg [COLOR_DEPTH - 1:0] out_data[3]
);
reg [1:0] state, nextState;
localparam reg [1:0] READ_DATA = 0;
localparam reg [1:0] HANDLE_DATA = 1;
localparam reg [1:0] SEND_DATA = 2;
reg [15:0] cnt_x, cnt_y;
reg [COLOR_DEPTH - 1:0] data[3];
wire is_valid;
// 状态切换
always @(posedge clk) begin
if (reset) state <= READ_DATA;
else state <= nextState;
end
// 下一状态更新
always @(*) begin
case (state)
READ_DATA: nextState = in_en ? HANDLE_DATA : READ_DATA;
HANDLE_DATA: nextState = SEND_DATA;
SEND_DATA: nextState = (is_valid && !in_receive) ? SEND_DATA : READ_DATA;
default: nextState = READ_DATA;
endcase
end
assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0;
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
assign is_valid = ((OFFSET_Y <= cnt_y && cnt_y <= (OFFSET_Y + OUT_HEIGHT - 1)) &&
(OFFSET_X <= cnt_x && cnt_x <= (OFFSET_X + OUT_WIDTH))) ? 1 : 0;
always @(posedge clk) begin
if (reset) begin
cnt_x <= 0;
cnt_y <= 0;
data[0] <= 0;
data[1] <= 0;
data[2] <= 0;
out_en <= 0;
out_data[0] <= 0;
out_data[1] <= 0;
out_data[2] <= 0;
end else begin
case (state)
READ_DATA: begin
if (in_en) begin
data[0] <= in_data[0];
data[1] <= in_data[1];
data[2] <= in_data[2];
end
end
HANDLE_DATA: begin
if (cnt_x >= IN_WIDTH - 1) begin
cnt_x <= 0;
cnt_y <= cnt_y + 1;
end else begin
cnt_x <= cnt_x + 1;
end
end
SEND_DATA: begin
if (cnt_y >= IN_HEIGHT) begin
cnt_y <= 0;
end
if (in_ready && !in_receive && is_valid) begin
out_en <= 1;
out_data[0] <= data[0];
out_data[1] <= data[1];
out_data[2] <= data[2];
end else out_en <= 0;
end
default: ;
endcase
end
end
endmodule