8
15
22
16
23
24
3
10
17
4
11
18
5
12
19
6
13
20
7
14
21
21
9
P1
P2
P3
t8t9t10 t11 t12 t13 t15 t16 t17 t18
t3t4t5t6t7t14
t1t2
Time slots
8
15
22
16
23
24
3
10
17
4
11
18
5
12
19
6
13
20
7
14
21
21
9
8
15
22
16
23
24
3
10
17
4
11
18
5
12
19
6
13
20
7
14
21
21
9
t19 t20 t21 t22 t23 t24 t26 t27 t28 t29
t25
The table below shows the tradeoff between machine resources and throughput for
various streaming image machines.
# processors 1/Throughput (cycles/histogram)
1 48
2 19
3 17
4 15
5
Ld_buff_1
HPFU
(P1)
HPFU
(P2)
PV_P1
PV_P2
H_top_P1
H_left_P1
H_top_P2
H_P2
H_P1
pixel_bits[1: Pixel_size*N_col*M_row
H_ptr
index_size -1 0
index[k], k = 1, …, M_row
HPDU
HP_1 [1: H_bin_size*N_bins]
S_idle_2
reset
Go
1
0
pixel_buffer_1 <= pixel_bits
pixel_buffer_1 <= 0
pixel_buffer_2 <= 0
buff_flg[k] <= 0, all k
index_[k] <= (k -1)*N_col +1
S_P4
/Incr_index[1]
Get_H[1]
S_P5
/Incr_index[1],
Get_H[1]
S_P6
/Incr_index[1],
Get_H[1]
S_P7
/Set_index[1],
Get_H[1]
index[1] is 5
index[1] is 6
index[1] is 7
index[1] is 8
S_P11
/Incr_index[2],
Get_H[2]
S_P14
/Incr_index[2],
Get_H[2]
S_P15
/Set_index[2],
Get_H[2]
index[2] is 12
index[2] is 16
Get_H[3]
S_P18
/Incr_index[3]
Get_H[3]
S_P22
/Incr_index[3],
Get_H[3]
S_P23
/Set_index[3],
Get_H[3]
index[3] is 19
index[3] is 23
index[3] is 24
S_idle_1
/ Ready
reset
Go
1
0
S_idle_3
reset
Go
1
0
index[2] is 15
S_P30
/Incr_index[4],
Get_H[4]
S_P31
/Set_index[4],
Get_H[4]
Go
1
S_P39
/Set_index_5,
Get_H[5]
Go
1
index[5] is 40
S_P47
/Set_index[6],
Get_H[6]
Go
1
index[6] is 48
index[4] is 32
S_P41
/Incr_index[6],
Get_H[6]
index[6] is 42
S_idle_4
reset
Go
1
0
S_idle_5
reset
Go
1
0
S_idle_6
reset
Go
1
0
Flip_buff_flg_[4] Flip_buff_flg_[6]Flip_buff_flg_[5]
Histogram data: Pattern 1 Histogram data: Pattern 2
Histogram data: Pattern 3 Histogram data: Pattern 4
`timescale 1ns / 10 ps
module Image_Histogram_Concurrent_Processors # (
parameter pixel_size = 8, H_bin_size = 6, N_bins = 8, N_col = 8, M_row = 6, N_Level = 8)(
output [1: H_bin_size*N_bins] Histogram_bits,
output Ready, Valid, Wait_1, Wait_2, Wait_3, Wait_4, Wait_5, Wait_6,
input [1: pixel_size * N_col * M_row] pixel_bits,
input Go, clk, reset
);
HPDU M1 (Histogram_bits, buff_flg, pixel_bits, Get_H, Incr_index, Flip_buff_flg, Set_index,
Ld_buff_1, Ld_buff_2, clk, reset);
endmodule
// Histogram Processor Functional Unit (Synchronous)
module HPFU #(parameter
pixel_size = 8, H_ptr_size = 4, H_bin_size = 6, index_size = 6, N_bins = 8, N_col = 8, M_row =
6,
L1 = 32, L2 = 64, L3 = 96, L4 = 128,
always @ (PV) begin
H_ptr = 0;
if ((0 <= PV) && (PV < L1)) begin H_ptr = 4’d1; end else
if ((L7 <= PV) && (PV < L8)) begin H_ptr = 4’d8; end
end
always @ (posedge clk) if (reset) for (k = 1; k <= N_bins; k = k + 1) H_memory [k] <= 0;
else if (Get_H == 1) begin
H_memory [1] <= H_bits_left [1: H_bin_size] + H_bits_top[1: H_bin_size] + (H_ptr == 4’d1);
H_memory [5] <= H_bits_left [4*H_bin_size + 1: 5*H_bin_size]
+ H_bits_top[4*H_bin_size + 1: 5*H_bin_size] + (H_ptr == 4’d5);
H_memory [6] <= H_bits_left [5*H_bin_size + 1: 6*H_bin_size]
+ H_bits_top[5*H_bin_size + 1: 6*H_bin_size] + (H_ptr == 4’d6);
always @ (*) begin
H_bits [1: H_bin_size] = H_memory [1];
H_bits [H_bin_size + 1: 2*H_bin_size] = H_memory [2];
// Histogram Processor Datapath Unit with Concurrent Processors
module HPDU #(parameter
pixel_size = 8, H_ptr_size = 4, H_bin_size = 6, index_size = 6, N_bins = 8, N_col = 8, M_row =
6,
L1 = 32, L2 = 64, L3 = 96, L4 = 128,
L5 = 160, L6 = 192, L7 = 224, L8 = 256)(
output [1: H_bin_size*N_bins] Histogram_bits,
output reg [1: M_row] buff_flg,
input Ld_buff_1, Ld_buff_2, clk, reset
);
reg [1: pixel_size] PV_P1, PV_P2, PV_P3, PV_P4, PV_P5, PV_P6;
integer k;
wire [1: H_bin_size*N_bins] H_P1, H_P2, H_P3, H_P4, H_P5, H_P6;
reg [1: pixel_size*N_col*M_row] pixel_buffer_1, pixel_buffer_2;
always @ (posedge clk) if (reset) begin pixel_buffer_1 <= 0; pixel_buffer_2 <= 0; end
else if (Ld_buff_1) pixel_buffer_1 <= pixel_bits;
else if (Ld_buff_2) pixel_buffer_2 <= pixel_bits;
// Assign pointers to image buffer
// Each processor has a pointer to an image buffer
// Select pixel_buffer_1 if buff_flg [k] is 0; otherwise pixel_buffer_2
always @ (posedge clk) if (reset) begin // Initialize all processors to first image
for (k = 1; k <= M_row; k = k + 1) buff_flg [k] <= 0; // Initialize pointers to image buffers
end
else begin
// Adust pixel pointer
reg [index_size -1: 0] index [1: M_row];
always @ (posedge clk) if (reset) begin // Initialize pointers to first pixel in rows
for (k = 1; k <= M_row; k = k + 1) index [k] <= (k – 1)*N_col + 1;
end
else begin
if (Incr_index [1]) index [1] <= index [1] + 1; else if (Set_index [1]) index [1] <= 6’d1;
// Instantiate Histogram Processors with last column data path management
HPFU M1 (
.H_bits (H_P1),
.H_bits_left (H_bits_left_P1),
.H_bits_top (H_bits_top_P1),
.PV (PV_P1),
.Get_H (Get_H[1]),
.clk (clk),
.reset (reset)
.reset (reset)
);
HPFU M4 (
.H_bits (H_P4),
.H_bits_left (H_bits_left_P4),
.H_bits_top (H_bits_top_P4),
.PV (PV_P4),
.Get_H (Get_H[4]),
.clk (clk),
.reset (reset)
);
.PV (PV_P6),
.Get_H (Get_H[6]),
.clk (clk),
.reset (reset)
);
//Processor P3
assign H_bits_top_P3 = (index [3] == 6’d24) ? H_P2: 0;
assign H_bits_left_P3 = (index [3] == 6’d17) ? 0: H_P3;
//Processor P4
assign H_bits_top_P4 = (index [4] == 6’d32) ? H_P3: 0;
assign H_bits_left_P4 = (index [4] == 6’d25) ? 0: H_P4;
//Processor P5
assign H_bits_top_P5 = (index [5] == 6’d40) ? H_P4: 0;
assign H_bits_left_P5 = (index [5] == 6’d33) ? 0: H_P5;
// Obtain selected pixel value based on index [1] from selected pixel buffer, based on buff_flg [1]
// Row 1
always @ (*) begin
//always @ (index [1], buff_flg [1], pixel_buffer_1, pixel_buffer_2) begin
PV_P1 = 0;
case (index [1])
1: if (buff_flg [1] == 0) PV_P1 = pixel_buffer_1 [1: pixel_size];
else PV_P1 = pixel_buffer_2 [1: pixel_size];
else PV_P1 = pixel_buffer_2 [6*pixel_size + 1: 7*pixel_size];
9: if (buff_flg [2] == 0) PV_P2 = pixel_buffer_1 [8*pixel_size + 1: 9*pixel_size];
else PV_P2 = pixel_buffer_2 [8*pixel_size + 1: 9*pixel_size];
10: if (buff_flg [2] == 0) PV_P2 = pixel_buffer_1 [9*pixel_size + 1: 10*pixel_size];
else PV_P2 = pixel_buffer_2 [9*pixel_size + 1: 10*pixel_size];
11: if (buff_flg [2] == 0) PV_P2 = pixel_buffer_1 [10*pixel_size + 1: 11*pixel_size];
else PV_P2 = pixel_buffer_2 [10*pixel_size + 1: 11*pixel_size];
12: if (buff_flg [2] == 0) PV_P2 = pixel_buffer_1 [11*pixel_size + 1: 12*pixel_size];
// Obtain selected pixel value based on index [3] from selected pixel buffer, based on buff_flg [3]
// Row 3
always @ (*) begin
//always @ (index [3], buff_flg [3], pixel_buffer_1, pixel_buffer_2) begin
PV_P3 = 0;
case (index [3])
17: if (buff_flg [3] == 0) PV_P3 = pixel_buffer_1 [16*pixel_size + 1: 17*pixel_size];
else PV_P3 = pixel_buffer_2 [16*pixel_size + 1: 17*pixel_size];
18: if (buff_flg [3] == 0) PV_P3 = pixel_buffer_1 [17*pixel_size + 1: 18*pixel_size];
// Obtain selected pixel value based on index [4] from selected pixel buffer, based on buff_flg [4]
// Row 4
always @ (*) begin
//always @ (index [4], buff_flg [4], pixel_buffer_1, pixel_buffer_2) begin
PV_P4 = 0;
case (index [4])
25: if (buff_flg [4] == 0) PV_P4 = pixel_buffer_1 [24*pixel_size + 1: 25*pixel_size];
else PV_P4 = pixel_buffer_2 [24*pixel_size + 1: 25*pixel_size];
26: if (buff_flg [4] == 0) PV_P4 = pixel_buffer_1 [25*pixel_size + 1: 26*pixel_size];
default PV_P4 = 0;
endcase
end
// Obtain selected pixel value based on index [5] from selected pixel buffer, based on buff_flg [5]
// Row 5
always @ (*) begin
// always @ (index [5], buff_flg [5], pixel_buffer_1, pixel_buffer_2) begin
PV_P5 = 0;
case (index [5])
33: if (buff_flg [5] == 0) PV_P5 = pixel_buffer_1 [32*pixel_size + 1: 33*pixel_size];
else PV_P5 = pixel_buffer_2 [32*pixel_size + 1: 33*pixel_size];
34: if (buff_flg [5] == 0) PV_P5 = pixel_buffer_1 [33*pixel_size + 1: 34*pixel_size];
default PV_P5 = 0;
endcase
end
// Obtain selected pixel value based on index [6] from selected pixel buffer, based on buff_flg [6]
// Row 6
always @ (*) begin
//always @ (index [6], buff_flg [6], pixel_buffer_1, pixel_buffer_2) begin
PV_P6 = 0;
case (index [6])
41: if (buff_flg [6] == 0) PV_P6 = pixel_buffer_1 [40*pixel_size + 1: 41*pixel_size];
else PV_P6 = pixel_buffer_2 [40*pixel_size + 1: 41*pixel_size];
42: if (buff_flg [6] == 0) PV_P6 = pixel_buffer_1 [41*pixel_size + 1: 42*pixel_size];
module HP_Control_Unit #(parameter
pixel_size = 8, H_ptr_size = 4, H_bin_size = 6, index_size = 6, N_bins = 8, N_col = 8, M_row =
6,
L1 = 32, L2 = 64, L3 = 96, L4 = 128,
L5 = 160, L6 = 192, L7 = 224, L8 = 256)(
output reg [1: M_row] Get_H,
input Go, clk, reset);
reg [7: 0] state_P1, next_state_P1;
reg [7: 0] state_P2, next_state_P2;
reg [7: 0] state_P3, next_state_P3;
parameter S_P5 = 5, S_P6 = 6;
parameter S_P7 = 7, S_P8 = 8;
parameter S_P9 = 9, S_P10 = 10;
parameter S_P11 = 11, S_P12 = 12;
parameter S_P13 = 13, S_P14 = 14;
parameter S_P15 = 15, S_P16 = 16;
parameter S_P17 = 17, S_P18 = 18;
parameter S_P19 = 19, S_P20 = 20;
parameter S_idle_1 = 50, S_load = 51;
parameter S_idle_2 = 52, S_skip_1 = 53, S_skip_2 = 54;
parameter S_idle_3 = 55, S_skip_3 = 56, S_skip_4 = 57, S_skip_5 = 58;
parameter S_idle_4 = 59, S_skip_6 = 60, S_skip_7 = 61, S_skip_8 = 62, S_skip_9 = 63;
parameter S_idle_5 = 64, S_skip_10 = 65, S_skip_11 = 66, S_skip_12 = 67,
S_skip_13 = 68, S_skip_14 = 69;
assign Ready = (state_P1 == S_idle_1);
assign Valid = ((state_P6 == S_P48) || (state_P6 == S_wait_P6));
assign Wait_1 = (state_P1 == S_wait_P1);
assign Wait_2 = (state_P2 == S_wait_P2);
always @ (posedge clk) if (reset) state_P1 <= S_idle_1; else state_P1 <= next_state_P1;
always @ (posedge clk) if (reset) state_P2 <= S_idle_2; else state_P2 <= next_state_P2;
always @ (posedge clk) if (reset) state_P3 <= S_idle_3; else state_P3 <= next_state_P3;
always @ (posedge clk) if (reset) state_P4 <= S_idle_4; else state_P4 <= next_state_P4;
next_state_P1 = S_idle_1;
case (state_P1)
S_idle_1: if (Go) begin next_state_P1 = S_load; Ld_buff_1 = 1; end
else next_state_P1 = S_idle_1;
S_load: begin next_state_P1 = S_P1; Get_H [1] = 1; Incr_index [1] = 1; end
S_P1: begin next_state_P1 = S_P2; Get_H [1] = 1; Incr_index [1] = 1; end
always @ (state_P2, Go) begin
Get_H [2] = 0;
Incr_index [2] = 0;
Set_index [2] = 0;
Flip_buff_flg [2] = 0;
next_state_P2 = S_idle_2;
case (state_P2)
S_idle_2: if (Go) next_state_P2 = S_skip_1; else next_state_P2 = S_idle_2;
S_skip_1: next_state_P2 = S_skip_2;
S_skip_2: begin next_state_P2 = S_P9; Get_H [2] = 1; Incr_index [2] = 1; end
S_P9: begin next_state_P2 = S_P10; Get_H [2] = 1; Incr_index [2] = 1; end
always @ (state_P3, Go) begin
Get_H [3] = 0;
Incr_index [3] = 0;
Set_index [3] = 0;
Flip_buff_flg [3] = 0;
S_skip_3: next_state_P3 = S_skip_4;
S_skip_4: next_state_P3 = S_skip_5;
S_skip_5: begin next_state_P3 = S_P17; Get_H [3] = 1; Incr_index [3] = 1; end
S_P17: begin next_state_P3 = S_P18; Get_H [3] = 1; Incr_index [3] = 1; end
always @ (state_P4, Go) begin
Get_H [4] = 0;
Incr_index [4] = 0;
Set_index [4] = 0;
Flip_buff_flg [4] = 0;
next_state_P4 = S_idle_4;
case (state_P4)
S_idle_4: if (Go) next_state_P4 = S_skip_6; else next_state_P4 = S_idle_4;
S_skip_6: next_state_P4 = S_skip_7;
S_skip_7: next_state_P4 = S_skip_8;
S_skip_8: next_state_P4 = S_skip_9;
S_skip_9: begin next_state_P4 = S_P25; Get_H [4] = 1; Incr_index [4] = 1; end
always @ (state_P5, Go) begin
Get_H [5] = 0;
Incr_index [5] = 0;
Set_index [5] = 0;
Flip_buff_flg [5] = 0;
S_skip_11: next_state_P5 = S_skip_12;
S_skip_12: next_state_P5 = S_skip_13;
S_skip_13: next_state_P5 = S_skip_14;
S_skip_14: begin next_state_P5 = S_P33; Get_H [5] = 1; Incr_index [5] = 1; end
S_P33: begin next_state_P5 = S_P34; Get_H [5] = 1; Incr_index [5] = 1; end
always @ (state_P6, Go) begin
Get_H [6] = 0;
Incr_index [6] = 0;
Set_index [6] = 0;
Flip_buff_flg [6] = 0;
next_state_P6 = S_idle_6;
case (state_P6)
S_idle_6: if (Go) next_state_P6 = S_skip_15; else next_state_P6 = S_idle_6;
S_skip_15: next_state_P6 = S_skip_16;
S_skip_16: next_state_P6 = S_skip_17;
S_skip_17: next_state_P6 = S_skip_18;
S_skip_18: next_state_P6 = S_skip_19;