// Fixed geometry teaching core: one 4x4 signed-int8 frame after each reset. // Valid 3x3, stride=1, dilation=1, one channel, no padding. module cnn_window3x3 ( input logic clk, reset, input logic in_valid, output logic in_ready, input logic signed [7:0] in_pixel, output logic out_valid, input logic out_ready, output logic [1:0] out_row, out_col, output logic signed [7:0] w00, w01, w02, output logic signed [7:0] w10, w11, w12, output logic signed [7:0] w20, w21, w22, output logic input_done ); logic signed [7:0] previous [0:3]; logic signed [7:0] older [0:3]; logic signed [7:0] h00, h01, h02; logic signed [7:0] h10, h11, h12; logic signed [7:0] h20, h21, h22; logic [1:0] row, col; integer i; // A complete unconsumed window blocks all pixel-state advancement. assign in_ready = !input_done && (!out_valid || out_ready); always_ff @(posedge clk) begin if (reset) begin row <= 0; col <= 0; input_done <= 0; out_valid <= 0; out_row <= 0; out_col <= 0; h00 <= 0; h01 <= 0; h02 <= 0; h10 <= 0; h11 <= 0; h12 <= 0; h20 <= 0; h21 <= 0; h22 <= 0; w00 <= 0; w01 <= 0; w02 <= 0; w10 <= 0; w11 <= 0; w12 <= 0; w20 <= 0; w21 <= 0; w22 <= 0; for (i = 0; i < 4; i = i + 1) begin previous[i] <= 0; older[i] <= 0; end end else begin if (out_valid && out_ready) out_valid <= 0; if (in_valid && in_ready) begin older[col] <= previous[col]; previous[col] <= in_pixel; if (col == 0) begin // New row: old horizontal columns must not enter its first windows. h00 <= 0; h01 <= 0; h02 <= older[col]; h10 <= 0; h11 <= 0; h12 <= previous[col]; h20 <= 0; h21 <= 0; h22 <= in_pixel; end else begin h00 <= h01; h01 <= h02; h02 <= older[col]; h10 <= h11; h11 <= h12; h12 <= previous[col]; h20 <= h21; h21 <= h22; h22 <= in_pixel; end if (row >= 2 && col >= 2) begin // Nonblocking RHS uses the preceding two horizontal samples. out_valid <= 1; out_row <= row - 2; out_col <= col - 2; w00 <= h01; w01 <= h02; w02 <= older[col]; w10 <= h11; w11 <= h12; w12 <= previous[col]; w20 <= h21; w21 <= h22; w22 <= in_pixel; end if (col == 3) begin col <= 0; if (row == 3) input_done <= 1; else row <= row + 1; end else col <= col + 1; end end end endmodule