blob: 0d4f3ddd1fc3cd64fd315ba58b92865c3ae5acd0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
`timescale 1ns / 1ps
module line_buffer #(
parameter DATA_WIDTH=8,
parameter IMAGE_SIZE=5,
parameter NUM_LINES=3,
parameter PADDING=1
)(
input wire clk,
input wire rst,
input wire pixel_valid,
input wire [DATA_WIDTH-1:0] pixel_in,
output wire [DATA_WIDTH*NUM_LINES*NUM_LINES-1:0] window,
output reg window_valid
);
localparam IMAGE_SIZE_PADDED = IMAGE_SIZE+2*PADDING;
localparam FIFO_DEPTH = IMAGE_SIZE * IMAGE_SIZE;
// Padding registers
reg [$clog2(IMAGE_SIZE_PADDED)-1:0] col_count_pad;
reg [$clog2(IMAGE_SIZE_PADDED)-1:0] row_count_pad;
reg [DATA_WIDTH-1:0] fifo [0:FIFO_DEPTH-1];
reg [$clog2(FIFO_DEPTH)-1:0] write_ptr;
reg [$clog2(FIFO_DEPTH)-1:0] read_ptr;
reg fifo_empty;
reg is_padding;
// Padded pixel output
reg [DATA_WIDTH-1:0] padded_pixel;
reg padded_pixel_valid;
// Line buffer registers
reg [DATA_WIDTH-1:0] line_buf [0:NUM_LINES-1][0:IMAGE_SIZE_PADDED-1];
reg [DATA_WIDTH-1:0] window_bufs [0:NUM_LINES-1][0:NUM_LINES-1];
reg [$clog2(IMAGE_SIZE_PADDED)-1:0] buf_ptr;
reg [$clog2(NUM_LINES)-1:0] row_count;
reg [$clog2(IMAGE_SIZE*IMAGE_SIZE):0] window_count;
reg frame_complete;
integer i, j;
// Padding logic
always @(*) begin
if (PADDING) begin
is_padding = (row_count_pad == 0) || (row_count_pad == IMAGE_SIZE_PADDED-1) ||
(col_count_pad == 0) || (col_count_pad == IMAGE_SIZE_PADDED-1);
if (!is_padding) begin
padded_pixel = fifo[read_ptr];
padded_pixel_valid = !fifo_empty;
end else begin
padded_pixel = 0;
padded_pixel_valid = pixel_valid;
end
end else begin
padded_pixel = pixel_in;
padded_pixel_valid = pixel_valid;
end
end
// FIFO and counter
always @(posedge clk) begin
if (rst) begin
col_count_pad <= 0;
row_count_pad <= 0;
write_ptr <= 0;
read_ptr <= 0;
fifo_empty <= 1'b1;
end else if (PADDING) begin
if (pixel_valid) begin
fifo[write_ptr] <= pixel_in;
write_ptr <= (write_ptr == FIFO_DEPTH-1) ? 0 : write_ptr + 1;
fifo_empty <= 1'b0;
end
if (!is_padding && !fifo_empty) begin
read_ptr <= (read_ptr == FIFO_DEPTH-1) ? 0 : read_ptr + 1;
fifo_empty <= (read_ptr + 1 == write_ptr);
end
if (col_count_pad == IMAGE_SIZE_PADDED-1) begin
col_count_pad <= 0;
row_count_pad <= (row_count_pad == IMAGE_SIZE_PADDED-1) ? 0 : row_count_pad + 1;
end else begin
col_count_pad <= col_count_pad + 1;
end
end
end
// Line buffer shifting
always @(posedge clk) begin
if (rst) begin
buf_ptr <= 0;
row_count <= 0;
window_valid <= 0;
window_count <= 0;
frame_complete <= 0;
end else begin
for (i=NUM_LINES-1; i>0; i=i-1) begin
line_buf[i][buf_ptr] <= line_buf[i-1][buf_ptr];
end
line_buf[0][buf_ptr] <= padded_pixel;
if (buf_ptr == IMAGE_SIZE_PADDED-1) begin
buf_ptr <= 0;
row_count <= (row_count == NUM_LINES) ? row_count : row_count + 1;
end else begin
buf_ptr <= buf_ptr + 1;
end
window_valid <= (!frame_complete && row_count == NUM_LINES && buf_ptr >= NUM_LINES-1) ? 1 : 0;
if (window_valid) begin
if (window_count == (IMAGE_SIZE*IMAGE_SIZE)-1) begin
window_valid <= 0;
window_count <= 0;
frame_complete <= 1;
end else begin
window_count <= window_count + 1;
end
end
end
end
// Window buffer shifting
always @(posedge clk) begin
if (rst) begin
for (i=0; i<NUM_LINES; i=i+1) begin
for (j=0; j<NUM_LINES; j=j+1) begin
window_bufs[i][j] <= 0;
end
end
end else begin
for (i=0; i<NUM_LINES; i=i+1) begin
window_bufs[i][NUM_LINES-1] <= line_buf[i][buf_ptr];
for (j=NUM_LINES-1; j>0; j=j-1) begin
window_bufs[i][j-1] <= window_bufs[i][j];
end
end
end
end
// Window output generation
generate
genvar k, l;
for (k=0; k<NUM_LINES; k=k+1) begin
for (l=0; l<NUM_LINES; l=l+1) begin
assign window[((NUM_LINES-1-k)*NUM_LINES+l)*DATA_WIDTH+:DATA_WIDTH] = window_bufs[k][l];
end
end
endgenerate
endmodule
|