tf.v
6.69 KB
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module: tf
// description: Top level for texture filter unit. 2 pipe stages.
//
// designer: Phil Gossett
// date: 6/15/95
//
////////////////////////////////////////////////////////////////////////
module tf (clk, start_gclk, st_span, ncyc, bilerp0m, bilerp1m, convert_one, mid_texel,
k0_coeff, k1_coeff, k2_coeff, k3_coeff,
lod_frac, sfrac_rg, tfrac_rg, sfrac_ba, tfrac_ba,
tm_ra, tm_ga, tm_ba, tm_aa,
tm_rb, tm_gb, tm_bb, tm_ab,
tm_rc, tm_gc, tm_bc, tm_ac,
tm_rd, tm_gd, tm_bd, tm_ad,
tf_r, tf_g, tf_b, tf_a, tf_lod_frac);
input clk;
input start_gclk;
input st_span; // start of span (to sync cycle count)
input ncyc; // number of cycles per pixel (- 1)
input bilerp0m; // cycle 0 mode bit
input bilerp1m; // cycle 1 mode bit
input convert_one; // loopback mode
input mid_texel; // mid mode (for 4 texel average)
input [8:0] k0_coeff; // color convert coefficients
input [8:0] k1_coeff;
input [8:0] k2_coeff;
input [8:0] k3_coeff;
input [8:0] lod_frac; // pipe thru to CCU
input [7:0] sfrac_rg; // bilerp alphas
input [7:0] tfrac_rg;
input [7:0] sfrac_ba;
input [7:0] tfrac_ba;
input [8:0] tm_ra; // this texel
input [8:0] tm_ga;
input [8:0] tm_ba;
input [8:0] tm_aa;
input [8:0] tm_rb; // horizontal texel
input [8:0] tm_gb;
input [8:0] tm_bb;
input [8:0] tm_ab;
input [8:0] tm_rc; // vertical texel
input [8:0] tm_gc;
input [8:0] tm_bc;
input [8:0] tm_ac;
input [8:0] tm_rd; // other (opposite) texel
input [8:0] tm_gd;
input [8:0] tm_bd;
input [8:0] tm_ad;
output [8:0] tf_r; // texture filter unit outputs
output [8:0] tf_g;
output [8:0] tf_b;
output [8:0] tf_a;
output [8:0] tf_lod_frac; // pipe thru to CCU
reg force_cycle; // temp
reg cycle; // cycle counter (0 if 1 cycle pixel)
reg bilerp; // control for 1st stage muxes
reg mid_rg; // mid mode active
reg mid_ba;
reg [7:0] sfrac_sh_rg; // bilerp alphas (shifted for mid mode)
reg [7:0] tfrac_sh_rg;
reg [7:0] sfrac_sh_ba;
reg [7:0] tfrac_sh_ba;
reg loopback; // mux control for second stage
reg [8:0] rg_reg_a; // 1st multiply input (pre mux)
reg [8:0] ba_reg_a;
reg [8:0] rg_reg_b; // 2nd multiply input (pre mux)
reg [8:0] ba_reg_b;
reg [8:0] r_reg_c; // final lerp add (pre mux)
reg [8:0] g_reg_c;
reg [8:0] b_reg_c;
reg [8:0] a_reg_c;
reg [8:0] r_reg_xa; // 1st positive subtract input
reg [8:0] g_reg_xa;
reg [8:0] b_reg_xa;
reg [8:0] a_reg_xa;
reg [8:0] r_reg_ya; // 1st negative subtract input
reg [8:0] g_reg_ya;
reg [8:0] b_reg_ya;
reg [8:0] a_reg_ya;
reg [8:0] r_reg_xb; // 2nd positive subtract input
reg [8:0] g_reg_xb;
reg [8:0] b_reg_xb;
reg [8:0] a_reg_xb;
reg [8:0] r_reg_yb; // 2nd negative subtract input
reg [8:0] g_reg_yb;
reg [8:0] b_reg_yb;
reg [8:0] a_reg_yb;
reg [8:0] r_reg_t; // for mid mode average (1's comp)
reg [8:0] g_reg_t;
reg [8:0] b_reg_t;
reg [8:0] a_reg_t;
reg [8:0] r_reg_o; // for mid mode average
reg [8:0] g_reg_o;
reg [8:0] b_reg_o;
reg [8:0] a_reg_o;
reg [8:0] reg_lod_frac; // pipe thru to CCU
wire [8:0] rg_a; // 1st multiply input
wire [8:0] ba_a;
wire [8:0] rg_b; // 2nd multiply input
wire [8:0] ba_b;
wire [8:0] r_c; // final lerp add
wire [8:0] g_c;
wire [8:0] b_c;
wire [8:0] a_c;
wire [8:0] r_mp; // final carry-propagated sum
wire [8:0] g_mp;
wire [8:0] b_mp;
wire [8:0] a_mp;
reg [8:0] tf_r; // texture filter unit outputs
reg [8:0] tf_g;
reg [8:0] tf_b;
reg [8:0] tf_a;
reg [8:0] tf_lod_frac; // pipe thru to CCU
always @(posedge clk)
if (start_gclk) begin
force_cycle = st_span || cycle;
cycle <= !(force_cycle || !ncyc);
end
always @(posedge clk)
if (start_gclk) begin
bilerp = cycle ? bilerp1m : bilerp0m;
mid_rg = bilerp && mid_texel &&
(sfrac_rg[7:3] == 5'b10000) &&
(tfrac_rg[7:3] == 5'b10000);
mid_ba = bilerp && mid_texel &&
(sfrac_ba[7:3] == 5'b10000) &&
(tfrac_ba[7:3] == 5'b10000);
sfrac_sh_rg = mid_rg ? {1'b0,sfrac_rg[7:1]} : sfrac_rg;
tfrac_sh_rg = mid_rg ? {1'b0,tfrac_rg[7:1]} : tfrac_rg;
sfrac_sh_ba = mid_ba ? {1'b0,sfrac_ba[7:1]} : sfrac_ba;
tfrac_sh_ba = mid_ba ? {1'b0,tfrac_ba[7:1]} : tfrac_ba;
loopback <= convert_one && cycle;
rg_reg_a <= bilerp ? {1'b0,sfrac_sh_rg} : tm_ra; // u
ba_reg_a <= bilerp ? {1'b0,sfrac_sh_ba} : tm_ra;
rg_reg_b <= bilerp ? {1'b0,tfrac_sh_rg} : tm_ga; // v
ba_reg_b <= bilerp ? {1'b0,tfrac_sh_ba} : tm_ga;
r_reg_c <= bilerp ? tm_ra : tm_ba; // y
g_reg_c <= bilerp ? tm_ga : tm_ba;
b_reg_c <= bilerp ? tm_ba : tm_ba;
a_reg_c <= bilerp ? tm_aa : tm_ba;
r_reg_xa <= bilerp ? tm_rb : 9'b000000000;
g_reg_xa <= bilerp ? tm_gb : k1_coeff;
b_reg_xa <= bilerp ? tm_bb : k3_coeff;
a_reg_xa <= bilerp ? tm_ab : 9'b000000000;
r_reg_ya <= bilerp ? tm_ra : 9'b000000000;
g_reg_ya <= bilerp ? tm_ga : ~k1_coeff;
b_reg_ya <= bilerp ? tm_ba : ~k3_coeff;
a_reg_ya <= bilerp ? tm_aa : 9'b000000000;
r_reg_xb <= bilerp ? tm_rc : k0_coeff;
g_reg_xb <= bilerp ? tm_gc : k2_coeff;
b_reg_xb <= bilerp ? tm_bc : 9'b000000000;
a_reg_xb <= bilerp ? tm_ac : 9'b000000000;
r_reg_yb <= bilerp ? tm_ra : ~k0_coeff;
g_reg_yb <= bilerp ? tm_ga : ~k2_coeff;
b_reg_yb <= bilerp ? tm_ba : 9'b000000000;
a_reg_yb <= bilerp ? tm_aa : 9'b000000000;
r_reg_t <= ~({9{mid_rg}} & tm_ra);
g_reg_t <= ~({9{mid_rg}} & tm_ga);
b_reg_t <= ~({9{mid_ba}} & tm_ba);
a_reg_t <= ~({9{mid_ba}} & tm_aa);
r_reg_o <= {9{mid_rg}} & tm_rd;
g_reg_o <= {9{mid_rg}} & tm_gd;
b_reg_o <= {9{mid_ba}} & tm_bd;
a_reg_o <= {9{mid_ba}} & tm_ad;
reg_lod_frac <= lod_frac;
end
// don't optimize the following instanced stuff:
tf_mux9 tfmuxra (.s(loopback), .i0i(rg_reg_a), .i1i(tf_r), .z(rg_a));
tf_mux9 tfmuxga (.s(loopback), .i0i(ba_reg_a), .i1i(tf_r), .z(ba_a));
tf_mux9 tfmuxrb (.s(loopback), .i0i(rg_reg_b), .i1i(tf_g), .z(rg_b));
tf_mux9 tfmuxgb (.s(loopback), .i0i(ba_reg_b), .i1i(tf_g), .z(ba_b));
tf_mux9 tfmuxrc (.s(loopback), .i0i(r_reg_c), .i1i(tf_b), .z(r_c));
tf_mux9 tfmuxbc (.s(loopback), .i0i(g_reg_c), .i1i(tf_b), .z(g_c));
tf_mux9 tfmuxgc (.s(loopback), .i0i(b_reg_c), .i1i(tf_b), .z(b_c));
tf_mux9 tfmuxac (.s(loopback), .i0i(a_reg_c), .i1i(tf_b), .z(a_c));
tf_lerp tflerpr (.xa(r_reg_xa), .ya(r_reg_ya), .a(rg_a),
.xb(r_reg_xb), .yb(r_reg_yb), .b(rg_b),
.c(r_c), .t(r_reg_t), .o(r_reg_o), .mp(r_mp));
tf_lerp tflerpg (.xa(g_reg_xa), .ya(g_reg_ya), .a(rg_a),
.xb(g_reg_xb), .yb(g_reg_yb), .b(rg_b),
.c(g_c), .t(g_reg_t), .o(g_reg_o), .mp(g_mp));
tf_lerp tflerpb (.xa(b_reg_xa), .ya(b_reg_ya), .a(ba_a),
.xb(b_reg_xb), .yb(b_reg_yb), .b(ba_b),
.c(b_c), .t(b_reg_t), .o(b_reg_o), .mp(b_mp));
tf_lerp tflerpa (.xa(a_reg_xa), .ya(a_reg_ya), .a(ba_a),
.xb(a_reg_xb), .yb(a_reg_yb), .b(ba_b),
.c(a_c), .t(a_reg_t), .o(a_reg_o), .mp(a_mp));
always @(posedge clk)
if (start_gclk) begin
tf_r <= r_mp;
tf_g <= g_mp;
tf_b <= b_mp;
tf_a <= a_mp;
tf_lod_frac <= reg_lod_frac;
end
endmodule // tf