@@ -375,20 +375,47 @@ end
375375// Index management logic: determines which part of the input image we are
376376// working on and where to place the output;
377377
378- // TODO: define correct widths for idx and nxt_idx. we probably need two
379- // indices.
380- logic [31 : 0 ] idx, nxt_idx;
378+ // Calculate tile dimensions
379+ localparam D0_BITS = $clog2 (D0 );
380+ localparam D1_BITS = $clog2 (D1 );
381+ localparam bit [D0_BITS : 0 ] TILES_Y = (D0 - 2 )/ 2 ; // Number of tile rows
382+ localparam bit [D1_BITS : 0 ] TILES_X = (D1 - 2 )/ 2 ; // Number of tile columns
381383
382- wire last_chunk; // TODO: Condition for when we have reached the last index.
384+ // Two explicit tile indices to avoid division/modulo
385+ logic [D0_BITS : 0 ] tile_i, nxt_tile_i;
386+ logic [D1_BITS : 0 ] tile_j, nxt_tile_j;
387+
388+ // Last tile condition
389+ wire last_chunk = (tile_i == TILES_Y - 1 ) && (tile_j == TILES_X - 1 );
383390
384391always_comb begin
385- nxt_idx = idx;
386- if (st == Recv_Conv && conv_valid_o) nxt_idx = idx + 1 ;
387- else if (st == Writing && ready_o) nxt_idx = 0 ;
392+ nxt_tile_i = tile_i;
393+ nxt_tile_j = tile_j;
394+
395+ if (st == Recv_Conv && conv_valid_o) begin
396+ if (tile_j == TILES_X - 1 ) begin
397+ // End of row, move to next row, reset column
398+ nxt_tile_j = 0 ;
399+ nxt_tile_i = tile_i + 1 ;
400+ end else begin
401+ // Move to next column in same row
402+ nxt_tile_j = tile_j + 1 ;
403+ end
404+ end else if (st == Writing && ready_o) begin
405+ // Reset to beginning
406+ nxt_tile_i = 0 ;
407+ nxt_tile_j = 0 ;
408+ end
388409end
410+
389411always_ff @ (posedge clk) begin
390- if (reset) idx <= '0 ;
391- else idx <= nxt_idx;
412+ if (reset) begin
413+ tile_i <= '0 ;
414+ tile_j <= '0 ;
415+ end else begin
416+ tile_i <= nxt_tile_i;
417+ tile_j <= nxt_tile_j;
418+ end
392419end
393420
394421
@@ -398,14 +425,29 @@ always_comb begin
398425 else conv_valid_i = 0 ;
399426end
400427always_comb begin
401- // TODO: define the input pixels to be sent.
428+ conv_in = '0 ;
429+ // Extract 4x4 window starting at (2*tile_i, 2*tile_j)
430+ // Flatten to 16 elements for Conv2D
431+ for (int r = 0 ; r < 4 ; r++ ) begin
432+ for (int c = 0 ; c < 4 ; c++ ) begin
433+ conv_in[r* 4 + c] = image[2 * tile_i + r][2 * tile_j + c];
434+ end
435+ end
402436end
403437
404438// Capture output when valid
405439logic [D0 - 3 : 0 ][D1 - 3 : 0 ][7 : 0 ] tmp_out;
406440always_comb begin
441+ tmp_out = out; // Preserve existing values
407442 if (st == Recv_Conv && conv_valid_o) begin
408- // TODO: capture the pixels in the right location
443+ // Conv2D returns 16 values as 4x4, extract center 2x2
444+ // Place at output[2*tile_i:2*tile_i+1][2*tile_j:2*tile_j+1]
445+ // Center 2x2 from 4x4 are at indices [1][1], [1][2], [2][1], [2][2]
446+ // In flattened array: 5, 6, 9, 10
447+ tmp_out[2 * tile_i][2 * tile_j] = conv_out[5 ]; // [1][1]
448+ tmp_out[2 * tile_i][2 * tile_j+ 1 ] = conv_out[6 ]; // [1][2]
449+ tmp_out[2 * tile_i+ 1 ][2 * tile_j] = conv_out[9 ]; // [2][1]
450+ tmp_out[2 * tile_i+ 1 ][2 * tile_j+ 1 ] = conv_out[10 ]; // [2][2]
409451 end
410452end
411453always_ff @ (posedge clk) begin
0 commit comments