`timescale 1ns / 1ps module Crop #( parameter IN_WIDTH = 512, parameter IN_HEIGHT = 512, parameter OFFSET_X = 120, parameter OFFSET_Y = 256, // parameter TRANSLAYT_X = 120, // parameter TRANSLAYT_Y = 120, parameter OUT_WIDTH = 512, parameter OUT_HEIGHT = 512, parameter BLANK_COLOR = 6'h000000, parameter COLOR_DEPTH = 16 ) ( input wire clk, input wire reset, input wire [COLOR_DEPTH - 1:0] in_data [3], output reg [COLOR_DEPTH - 1:0] out_data[3], input wire in_valid, output reg out_valid, input wire in_ready, output wire out_ready, input wire in_hsync, input wire in_fsync, output reg out_hsync, output reg out_fsync ); localparam PIPILINE = 3; reg [PIPILINE-1:0] pipeline_valid; wire pipeline_running; assign pipeline_running = in_ready | ~pipeline_valid[PIPILINE-1]; reg [31:0] cnt_x, cnt_y, temp_x, temp_y; reg force_dis, force_en; reg [COLOR_DEPTH-1:0] data_cache0[3]; reg [COLOR_DEPTH-1:0] data_cache1[3]; //out_ready :只要本模块可以接收数据就一直拉高 assign out_ready = pipeline_running; //out_valid :只要本模块可以发出数据就一直拉高 assign out_valid = (pipeline_valid[PIPILINE-1] & ~force_dis) | force_en; //分别表示当前像素: 显示;被裁掉;空。 reg [1:0] flag_crop; localparam CROP_ERROR = 2'b00, CROP_KEEP = 2'b01, CROP_GIVE_UP = 2'b10, CROP_BLANK = 2'b11; integer i; always @(posedge clk) begin if (reset) begin pipeline_valid <= 0; cnt_x <= 0; cnt_y <= 0; for (i = 0; i < 3; i++) data_cache0[i] <= 0; for (i = 0; i < 3; i++) data_cache1[i] <= 0; for (i = 0; i < 3; i++) out_data[i] <= 0; flag_crop <= 0; force_dis <= 0; force_en <= 0; out_hsync <= 0; out_fsync <= 0; temp_x <= 0; temp_y <= 0; end else if (pipeline_running) begin pipeline_valid <= {pipeline_valid[PIPILINE-2:0], in_valid}; if (in_valid) begin //when 00 for (i = 0; i < 3; i++) data_cache0[i] <= in_data[i]; cnt_x <= (in_hsync) ? (0) : (cnt_x + 1); cnt_y <= (in_hsync) ? ((in_fsync) ? (0) : (cnt_y + 1)) : (cnt_y); end if (pipeline_valid[0]) begin //when 00 for (i = 0; i < 3; i++) data_cache1[i] <= data_cache0[i]; temp_x <= cnt_x; temp_y <= cnt_y; if (cnt_x < OFFSET_X || cnt_y < OFFSET_Y) flag_crop <= CROP_GIVE_UP; else if (cnt_x < OFFSET_X + OUT_WIDTH && cnt_y < OFFSET_Y + OUT_HEIGHT) begin if (cnt_x < IN_WIDTH && cnt_y < IN_HEIGHT) flag_crop <= CROP_KEEP; else flag_crop <= CROP_BLANK; end else flag_crop <= CROP_ERROR; end if (pipeline_valid[1]) begin for (i = 0; i < 3; i++) out_data[i] <= data_cache1[i]; out_hsync <= (temp_x == OFFSET_X) && (temp_y >= OFFSET_Y); out_fsync <= (temp_x == OFFSET_X) && (temp_y == OFFSET_Y); case (flag_crop) CROP_ERROR: {force_dis, force_en} <= {1'b1, 1'b0}; CROP_KEEP: {force_dis, force_en} <= {1'b0, 1'b0}; CROP_GIVE_UP: {force_dis, force_en} <= {1'b1, 1'b0}; CROP_BLANK: {force_dis, force_en} <= {1'b0, 1'b0}; //应该是01, 但我还没写BLANK逻辑 endcase end end end endmodule