Newer
Older
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
module gl_painter_image (
// Clock
input logic CLOCK, RESET,
// Arguments
input logic [19:0] IMG_BASE,
input logic [9:0] W, H,
input logic [9:0] X[6], Y[6],
// Transparency
input logic [15:0] TRANSPARENCY,
// Status Control
input logic EN,
output logic DONE,
input logic PAINT_BUFFER,
// Memory read connection
output logic fb_GL_REQ,
output logic [19:0] fb_GL_ADDR,
input logic [15:0] fb_GL_DATA,
input logic fb_GL_READY,
// Memory write connection
output logic fb_PAINT_REQ,
output logic [9:0] fb_PAINT_X, fb_PAINT_Y,
output logic [15:0] fb_PAINT_RGB16,
input logic fb_PAINT_READY,
// Redraw cache connection
output logic [19:0] RC_ADDR,
output logic RC_DATA_WR,
output logic RC_WE,
input logic RC_DATA_RD
);
logic [2:0] i, i_in;
logic [19:0] img_ptr, img_ptr_in;
logic [9:0] x, y, x_in, y_in;
logic [15:0] color, color_in;
logic paint_req_in, read_req_in;
enum logic[3:0] {
s_idle, s_fetch, s_paint, s_fin
} state, state_next;
assign fb_PAINT_X = X[i] + x;
assign fb_PAINT_Y = Y[i] + y;
assign fb_PAINT_RGB16 = color;
assign RC_ADDR = {fb_PAINT_X, fb_PAINT_Y[8:0], PAINT_BUFFER};
assign RC_DATA_WR = 1'b1;
assign fb_GL_ADDR = img_ptr;
always_ff @(posedge CLOCK) begin
if(RESET | ~EN) begin
state <= s_idle;
x <= 0;
y <= 0;
i <= 0;
fb_PAINT_REQ <= 1'b0;
fb_GL_REQ <= 1'b0;
color <= {5'b0, 6'b0, 5'b11111};
img_ptr <= IMG_BASE;
end else begin
state <= state_next;
x <= x_in;
y <= y_in;
i <= i_in;
fb_PAINT_REQ <= paint_req_in;
fb_GL_REQ <= read_req_in;
color <= color_in;
state <= state_next;
img_ptr <= img_ptr_in;
end
end
always_comb begin
// Default values
state_next = state;
x_in = x;
y_in = y;
color_in = color;
i_in = i;
DONE = 1'b0;
RC_WE = 1'b0;
paint_req_in = 1'b0;
read_req_in = 1'b0;
img_ptr_in = img_ptr;
case (state)
s_idle: begin
state_next = s_fetch;
x_in = 0;
y_in = 0;
i_in = 0;
paint_req_in = 1'b0;
read_req_in = 1'b1;
img_ptr_in = IMG_BASE;
end
s_fetch: begin
if (~fb_GL_READY) begin
// Continue reading
read_req_in = 1'b1;
end else begin
// Done. Save data and start drawing
color_in = fb_GL_DATA;
if (color_in == TRANSPARENCY) begin
// Skip the pixel
x_in = x + 1;
img_ptr_in = img_ptr + 1;
if (x_in == W) begin
// Move to next row
x_in = 0;
y_in = y_in + 1;
if (y_in == H) begin
// Completely done.
state_next = s_fin;
DONE = 1'b1;
end
end
end else begin
// Paint the pixel
i_in = 0;
paint_req_in = 1'b1;
state_next = s_paint;
end
end
end
s_paint: begin
paint_req_in = 1'b1;
RC_WE = 1'b1;
if(fb_PAINT_READY) begin
// Value written, move to next location
i_in = i + 1;
if (Y[i_in][9] || i_in == 6) begin
if (x_in == W) begin
// Move to next row
x_in = 0;
y_in = y_in + 1;
if (y_in == H) begin
// Completely done.
state_next = s_fin;
DONE = 1'b1;
end
end
end
end
end
s_fin: begin
DONE = 1'b1;
end
endcase
end
endmodule