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
|
`include "gfx/gfx_defs.sv"
module gfx_raster_coarse
(
input logic clk,
rst_n,
input raster_xy pos_ref,
input coarse_dim span_x,
span_y,
input raster_offsets_tri offsets,
input fixed_tri edge_refs,
coarse_x_offsets,
coarse_y_offsets,
coarse_test_offsets,
input logic in_valid,
output logic in_ready,
input logic out_ready,
output logic out_valid,
output raster_xy pos,
output fixed_tri corners,
output raster_offsets_tri fine_offsets
);
fixed reference_x;
logic end_x, end_y, running, send, send_valid, skid_ready, stall;
raster_xy next_pos;
fixed_tri edge_fns, edge_tests, edge_vert, edge_vert_next;
coarse_dim stride_x, stride_y, width;
logic[2:0] edge_signs;
raster_offsets_tri hold_offsets;
fixed_tri hold_coarse_x_offsets, hold_coarse_y_offsets, hold_coarse_test_offsets;
struct packed
{
raster_xy pos;
fixed_tri corners;
raster_offsets_tri fine_offsets;
} out, skid_out;
assign pos = skid_out.pos;
assign corners = skid_out.corners;
assign fine_offsets = skid_out.fine_offsets;
assign end_x = stride_x == 0;
assign end_y = stride_y == 0;
assign send = &edge_signs && send_valid;
assign in_ready = skid_ready && !running;
gfx_skid_buf #(.WIDTH($bits(out))) skid_buf
(
.in(out),
.out(skid_out),
.*
);
gfx_skid_flow skid_flow
(
.in_ready(skid_ready),
.in_valid(send),
.*
);
always_comb
for (integer i = 0; i < 3; ++i) begin
edge_tests[i] = edge_fns[i] + hold_coarse_test_offsets[i];
edge_vert_next[i] = edge_vert[i] + hold_coarse_y_offsets[i];
end
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin
running <= 0;
send_valid <= 0;
end else if (!stall) begin
if (running)
running <= !end_x || !end_y;
else
running <= in_ready && in_valid;
send_valid <= running;
end
always_ff @(posedge clk)
if (!stall) begin
out.pos <= next_pos;
out.corners <= edge_fns;
out.fine_offsets <= hold_offsets;
stride_x <= stride_x - 1;
next_pos.x <= next_pos.x + (1 << (`FIXED_FRAC + `GFX_RASTER_BITS));
if (end_x) begin
next_pos.x <= reference_x;
next_pos.y <= next_pos.y + (1 << (`FIXED_FRAC + `GFX_RASTER_BITS));
stride_x <= width;
stride_y <= stride_y - 1;
end
if (in_ready && in_valid) begin
next_pos <= pos_ref;
reference_x <= pos_ref.x;
width <= span_x;
stride_x <= span_x;
stride_y <= span_y;
hold_offsets <= offsets;
hold_coarse_x_offsets <= coarse_x_offsets;
hold_coarse_y_offsets <= coarse_y_offsets;
hold_coarse_test_offsets <= coarse_test_offsets;
end
for (integer i = 0; i < 3; ++i) begin
edge_fns[i] <= edge_fns[i] + hold_coarse_x_offsets[i];
if (end_x) begin
edge_fns[i] <= edge_vert_next[i];
edge_vert[i] <= edge_vert_next[i];
end
if (in_ready && in_valid) begin
edge_fns[i] <= edge_refs[i];
edge_vert[i] <= edge_refs[i];
end
edge_signs[i] <= !edge_tests[i][$bits(fixed) - 1];
end
end
endmodule
|