at_tc.v
9.43 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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
*************************************************************************/
// $Id: at_tc.v,v 1.1 2002/03/28 00:26:12 berndt Exp $
////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module: at_tc
// description: Attribute buffers for tc unit. Primitives data updates
// the cycle before it is needed (via mux), but is only used
// the following cycle. Hardware synchronized attribute data
// is updated the cycle of the attribute (via mux), but is
// only used the following cycle, which lines up with the
// first cycle of a following primitive. QTV will barf on
// this, since it will see the update cycle as not making
// timing, while only the following cycle really matters.
// Unsynchronized attributes update immediately, producing
// trash for one cycle, followed by good data the next cycle.
// The csim should generate garbage (0xDEADBEEF, for example)
// during this trashed update cycle. Some logically synced
// data require no special buffering because the timing
// just works out (scissor, the EW dx's and dy's). Unsynced
// attributes must be maintained by software, using the
// sync_tile and sync_pipe commands after the last primitive
// before any unsynced attribute update commands if necessary.
//
// designer: Phil Gossett
// date: 6/9/95
//
////////////////////////////////////////////////////////////////////////
module at_tc (gclk, reset_l,
cs_st_prim, cs_st_attr, cs_cmd, cs_ew_d,
st_dxs, st_dxt, st_dxw,
shift_coord, level, tile);
input gclk;
input reset_l;
input cs_st_prim;
input cs_st_attr;
input [5:0] cs_cmd;
input [63:0] cs_ew_d;
output [26:0] st_dxs; // s15.11 (double buffer)
output [26:0] st_dxt; // s15.11 (double buffer)
output [26:0] st_dxw; // s15.11 (double buffer)
output shift_coord; // load_block(33),tlut(34) (quad buffer)
output [2:0] level; // primitives (36,24,25,0f-08) (quad buffer)
output [2:0] tile; // primitives (36,24,25,0f-08) (quad buffer)
wire [63:0] d_lat; // delayed latched input
wire [7:0] code_0d; // control pipeline input
reg [2:0] code_1d; // pipeline for control
reg [2:0] code_2d;
reg [2:0] code_3d;
reg [2:0] code_4d;
reg [2:0] code_5d;
reg [2:0] code_6d;
reg [2:0] code_7d;
reg [2:0] code_8d;
reg [2:0] code_9d;
reg [2:0] code_10d;
reg [2:0] code_11d;
reg [2:0] code_12d;
reg [2:0] code_13d;
reg [2:0] code_14d;
reg [2:0] code_15d;
reg [2:0] code_16d;
reg [2:0] code_17d;
reg [2:0] code_18d;
reg [2:0] code_19d;
reg [2:0] code_20d;
reg [2:0] code_21d;
reg [2:0] code_22d;
reg [2:0] code_23d;
reg [2:0] code_24d;
reg [2:0] code_25d;
reg [2:0] code_26d;
reg [2:0] code_27d;
reg [2:0] code_28d;
wire [1:0] dxs_g;
wire [1:0] dxs_a_g;
wire [1:0] dxs_b_g;
wire [1:0] dxt_g;
wire [1:0] dxt_a_g;
wire [1:0] dxt_b_g;
wire [1:0] dxw_g;
wire [1:0] dxw_a_g;
wire [1:0] dxw_b_g;
wire sh_co_g;
wire sh_co_a_g;
wire sh_co_b_g;
wire sh_co_c_g;
wire sh_co_d_g;
wire level_g;
wire level_a_g;
wire level_b_g;
wire level_c_g;
wire level_d_g;
wire tile_g;
wire tile_a_g;
wire tile_b_g;
wire tile_c_g;
wire tile_d_g;
wire d_sh; // synthesized for primitives
wire [31:0] st_dxs_a;
wire [31:0] st_dxs_b;
wire [31:0] st_dxt_a;
wire [31:0] st_dxt_b;
wire [31:0] st_dxw_a;
wire [31:0] st_dxw_b;
wire shift_coord_a;
wire shift_coord_b;
wire shift_coord_c;
wire shift_coord_d;
wire [2:0] level_a;
wire [2:0] level_b;
wire [2:0] level_c;
wire [2:0] level_d;
wire [2:0] tile_a;
wire [2:0] tile_b;
wire [2:0] tile_c;
wire [2:0] tile_d;
wire dxs_s; // read counter increment strobes
wire dxt_s;
wire dxw_s;
wire sh_co_s;
wire level_s;
wire tile_s;
wire dxs_sel;
wire dxt_sel;
wire dxw_sel;
wire [1:0] sh_co_sel;
wire [1:0] level_sel;
wire [1:0] tile_sel;
wire reset;
// invert reset (this week)
assign reset = ~reset_l;
// control pipeline input
assign code_0d = {cs_st_prim,cs_st_attr,cs_cmd};
// pipeline for control
always @(posedge gclk)
begin
code_1d <= {code_0d[7], (code_0d[6:0] == 7'h7a), // prim color
(code_0d[6:0] == 7'h6e)}; // prim depth
code_2d <= code_1d;
code_3d <= code_2d;
code_4d <= code_3d;
code_5d <= code_4d;
code_6d <= code_5d;
code_7d <= code_6d;
code_8d <= code_7d;
code_9d <= code_8d;
code_10d <= code_9d;
code_11d <= code_10d;
code_12d <= code_11d;
code_13d <= code_12d;
code_14d <= code_13d;
code_15d <= code_14d;
code_16d <= code_15d;
code_17d <= code_16d;
code_18d <= code_17d;
code_19d <= code_18d;
code_20d <= code_19d;
code_21d <= code_20d;
code_22d <= code_21d;
code_23d <= code_22d;
code_24d <= code_23d;
code_25d <= code_24d;
code_26d <= code_25d;
code_27d <= code_26d;
code_28d <= code_27d;
end
// generate latch enables for single buffers
assign dxs_g[1] = code_5d[2];
assign dxs_g[0] = code_4d[2];
assign dxt_g[1] = code_5d[2];
assign dxt_g[0] = code_4d[2];
assign dxw_g[1] = code_7d[2];
assign dxw_g[0] = code_6d[2];
assign sh_co_g = code_0d[7];
assign level_g = code_0d[7];
assign tile_g = code_0d[7];
assign d_sh = (code_0d[5:0] == 6'h33) || // load block
(code_0d[5:0] == 6'h30); // load tlut
// generate latch enables for multi buffers
at_ctw2 ctdxsmg (.clk(gclk), .rst(reset), .enb(dxs_g[1]),
.a(dxs_a_g[1]), .b(dxs_b_g[1]));
at_ctw2 ctdxslg (.clk(gclk), .rst(reset), .enb(dxs_g[0]),
.a(dxs_a_g[0]), .b(dxs_b_g[0]));
at_ctw2 ctdxtmg (.clk(gclk), .rst(reset), .enb(dxt_g[1]),
.a(dxt_a_g[1]), .b(dxt_b_g[1]));
at_ctw2 ctdxtlg (.clk(gclk), .rst(reset), .enb(dxt_g[0]),
.a(dxt_a_g[0]), .b(dxt_b_g[0]));
at_ctw2 ctdxwmg (.clk(gclk), .rst(reset), .enb(dxw_g[1]),
.a(dxw_a_g[1]), .b(dxw_b_g[1]));
at_ctw2 ctdxwlg (.clk(gclk), .rst(reset), .enb(dxw_g[0]),
.a(dxw_a_g[0]), .b(dxw_b_g[0]));
at_ctw4 ctshcog (.clk(gclk), .rst(reset), .enb(sh_co_g),
.a(sh_co_a_g), .b(sh_co_b_g), .c(sh_co_c_g), .d(sh_co_d_g));
at_ctw4 ctlvlg (.clk(gclk), .rst(reset), .enb(level_g),
.a(level_a_g), .b(level_b_g), .c(level_c_g), .d(level_d_g));
at_ctw4 cttileg (.clk(gclk), .rst(reset), .enb(tile_g),
.a(tile_a_g), .b(tile_b_g), .c(tile_c_g), .d(tile_d_g));
// instanciated latches
at_latch64 dlat (.clkn( gclk), .i(cs_ew_d), .z(d_lat));
at_latch32 sdxsa (.clk(gclk),.g(dxs_a_g),.i({2{d_lat[31:16]}}),.z(st_dxs_a));
at_latch32 sdxsb (.clk(gclk),.g(dxs_b_g),.i({2{d_lat[31:16]}}),.z(st_dxs_b));
at_latch32 sdxta (.clk(gclk),.g(dxt_a_g),.i({2{d_lat[15: 0]}}),.z(st_dxt_a));
at_latch32 sdxtb (.clk(gclk),.g(dxt_b_g),.i({2{d_lat[15: 0]}}),.z(st_dxt_b));
at_latch32 sdxwa (.clk(gclk),.g(dxw_a_g),.i({2{d_lat[31:16]}}),.z(st_dxw_a));
at_latch32 sdxwb (.clk(gclk),.g(dxw_b_g),.i({2{d_lat[31:16]}}),.z(st_dxw_b));
at_latch1 shcoa (.clk(gclk), .g(sh_co_a_g), .i(d_sh), .z(shift_coord_a));
at_latch1 shcob (.clk(gclk), .g(sh_co_b_g), .i(d_sh), .z(shift_coord_b));
at_latch1 shcoc (.clk(gclk), .g(sh_co_c_g), .i(d_sh), .z(shift_coord_c));
at_latch1 shcod (.clk(gclk), .g(sh_co_d_g), .i(d_sh), .z(shift_coord_d));
at_latch3 levla (.clk(gclk), .g(level_a_g), .i(d_lat[53:51]), .z(level_a));
at_latch3 levlb (.clk(gclk), .g(level_b_g), .i(d_lat[53:51]), .z(level_b));
at_latch3 levlc (.clk(gclk), .g(level_c_g), .i(d_lat[53:51]), .z(level_c));
at_latch3 levld (.clk(gclk), .g(level_d_g), .i(d_lat[53:51]), .z(level_d));
at_latch3 tilea (.clk(gclk), .g( tile_a_g), .i(d_lat[50:48]), .z(tile_a));
at_latch3 tileb (.clk(gclk), .g( tile_b_g), .i(d_lat[50:48]), .z(tile_b));
at_latch3 tilec (.clk(gclk), .g( tile_c_g), .i(d_lat[50:48]), .z(tile_c));
at_latch3 tiled (.clk(gclk), .g( tile_d_g), .i(d_lat[50:48]), .z(tile_d));
// generate strobes for incrementing read pointers
assign dxs_s = code_21d[2]; // 23
assign dxt_s = code_21d[2]; // 23
assign dxw_s = code_19d[2]; // 21
assign sh_co_s = code_28d[2]; // 30
assign level_s = code_25d[2]; // 27
assign tile_s = code_25d[2]; // 27
// generate read pointers for multi buffers
at_ctr2 ctdxss (.clk(gclk), .rst(reset), .enb(dxs_s), .z(dxs_sel));
at_ctr2 ctdxts (.clk(gclk), .rst(reset), .enb(dxt_s), .z(dxt_sel));
at_ctr2 ctdxws (.clk(gclk), .rst(reset), .enb(dxw_s), .z(dxw_sel));
at_ctr4 ctshcos (.clk(gclk), .rst(reset), .enb(sh_co_s), .z(sh_co_sel));
at_ctr4 ctlvls (.clk(gclk), .rst(reset), .enb(level_s), .z(level_sel));
at_ctr4 cttiles (.clk(gclk), .rst(reset), .enb(tile_s), .z(tile_sel));
// read latches with bit assignments and padding (unused latches eaten)
assign st_dxs = dxs_sel ? st_dxs_b[31:5] : st_dxs_a[31:5]; // s15.11
assign st_dxt = dxt_sel ? st_dxt_b[31:5] : st_dxt_a[31:5];
assign st_dxw = dxw_sel ? st_dxw_b[31:5] : st_dxw_a[31:5];
assign shift_coord = sh_co_sel[1] ?
(sh_co_sel[0] ? shift_coord_d :
shift_coord_c) :
(sh_co_sel[0] ? shift_coord_b :
shift_coord_a);
assign level = level_sel[1] ?
(level_sel[0] ? level_d :
level_c) :
(level_sel[0] ? level_b :
level_a);
assign tile = tile_sel[1] ?
(tile_sel[0] ? tile_d :
tile_c) :
(tile_sel[0] ? tile_b :
tile_a);
endmodule // at_tc