at_tc.v 9.43 KB
/**************************************************************************
 *                                                                        *
 *               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