at_bl.v 10.1 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_bl.v,v 1.1 2002/03/28 00:26:12 berndt Exp $

////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module:      at_bl
// description:	Attribute buffers for blend 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_bl (gclk, reset_l, cs_st_prim, cs_st_attr, cs_cmd, cs_ew_d,
	st_dxz, st_dyz,
	color_image, z_image, tex_image,
	blend_color, fog_color, fill_color,
	other_modes, prim_depth);

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 [31:0] st_dxz;		// s15.16 (quad buffer)
output [21:0] st_dyz;		// s15.6  (triple buffer)
output [55:0] color_image;	// 3f 55:51, 43:32, 25:0 (unsynced)
output [55:0] z_image;		// 3e               25:0 (unsynced)
output [55:0] tex_image;	// 3d 55:51, 43:32, 25:0 (unsynced)
output [55:0] blend_color;	// 39 31:0		 (unsynced)
output [55:0] fog_color;	// 38 31:0		 (unsynced)
output [55:0] fill_color;	// 37 31:0		 (unsynced)
output [55:0] other_modes;	// 2f 53:0		 (unsynced)
output [55:0] prim_depth;	// 2e 31:16, 15:0	 (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;
reg [2:0] code_29d;
reg [2:0] code_30d;
reg [2:0] code_31d;
reg [2:0] code_32d;
reg [2:0] code_33d;
reg [2:0] code_34d;
reg [2:0] code_35d;
reg [2:0] code_36d;
reg [2:0] code_37d;
reg [2:0] code_38d;
reg [2:0] code_39d;
reg [2:0] code_40d;
reg [2:0] code_41d;

wire [1:0] dxz_g;	// latch enables
wire [1:0] dxz_a_g;
wire [1:0] dxz_b_g;
wire [1:0] dxz_c_g;
wire [1:0] dxz_d_g;
wire [1:0] dyz_g;
wire [1:0] dyz_a_g;
wire [1:0] dyz_b_g;
wire [1:0] dyz_c_g;
wire ci_g;
wire zi_g;
wire ti_g;
wire bl_g;
wire fg_g;
wire fl_g;
wire ot_g;
wire pd_g;
wire pd_a_g;
wire pd_b_g;
wire pd_c_g;
wire pd_d_g;

wire [31:0] st_dxz_a;	// latch outputs
wire [31:0] st_dxz_b;
wire [31:0] st_dxz_c;
wire [31:0] st_dxz_d;
wire [31:0] st_dyz_a;
wire [31:0] st_dyz_b;
wire [31:0] st_dyz_c;
wire [55:0] color_image_a;
wire [55:0] z_image_a;
wire [55:0] tex_image_a;
wire [55:0] blend_color_a;
wire [55:0] fog_color_a;
wire [55:0] fill_color_a;
wire [55:0] other_modes_a;
wire [55:0] prim_depth_a;
wire [55:0] prim_depth_b;
wire [55:0] prim_depth_c;
wire [55:0] prim_depth_d;

wire dxz_s;	// read counter increment strobes
wire dyz_s;
wire pdm_s;
wire pdl_s;

wire [1:0] dxz_sel;	// read counter selects
wire [1:0] dyz_sel;
wire [1:0] pdm_sel;
wire [1:0] pdl_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;
	code_29d <= code_28d;
	code_30d <= code_29d;
	code_31d <= code_30d;
	code_32d <= code_31d;
	code_33d <= code_32d;
	code_34d <= code_33d;
	code_35d <= code_34d;
	code_36d <= code_35d;
	code_37d <= code_36d;
	code_38d <= code_37d;
	code_39d <= code_38d;
	code_40d <= code_39d;
	code_41d <= code_40d;
end

// generate latch enables for single buffers
assign dxz_g[1] = code_12d[2];
assign dxz_g[0] = code_12d[2];
assign dyz_g[1] = code_21d[2];
assign dyz_g[0] = code_21d[2];
assign ci_g     = (code_0d[6:0] == 7'h7f);
assign zi_g     = (code_0d[6:0] == 7'h7e);
assign ti_g     = (code_0d[6:0] == 7'h7d);
assign bl_g     = (code_0d[6:0] == 7'h79);
assign fg_g     = (code_0d[6:0] == 7'h78);
assign fl_g     = (code_0d[6:0] == 7'h77);
assign ot_g     = (code_0d[6:0] == 7'h6f);
assign pd_g     = (code_0d[6:0] == 7'h6e);

// generate latch enables for multi buffers
at_ctw4 ctdxzmg	(.clk(gclk), .rst(reset), .enb(dxz_g[1]),
	 .a(dxz_a_g[1]), .b(dxz_b_g[1]), .c(dxz_c_g[1]), .d(dxz_d_g[1]));
at_ctw4 ctdxzlg	(.clk(gclk), .rst(reset), .enb(dxz_g[0]),
	 .a(dxz_a_g[0]), .b(dxz_b_g[0]), .c(dxz_c_g[0]), .d(dxz_d_g[0]));
at_ctw3 ctdyzmg	(.clk(gclk), .rst(reset), .enb(dyz_g[1]),
	 .a(dyz_a_g[1]), .b(dyz_b_g[1]), .c(dyz_c_g[1]));
at_ctw3 ctdyzlg	(.clk(gclk), .rst(reset), .enb(dyz_g[0]),
	 .a(dyz_a_g[0]), .b(dyz_b_g[0]), .c(dyz_c_g[0]));
at_ctw4 pdg	(.clk(gclk), .rst(reset), .enb(pd_g),
	 .a(pd_a_g), .b(pd_b_g), .c(pd_c_g), .d(pd_d_g));

// instanciated latches
at_latch64 dlat   (.clkn( gclk),   .i(cs_ew_d), .z(d_lat));
at_latch32 sdxza (.clk(gclk),.g(dxz_a_g),.i(   d_lat[31: 0]  ),.z(st_dxz_a));
at_latch32 sdxzb (.clk(gclk),.g(dxz_b_g),.i(   d_lat[31: 0]  ),.z(st_dxz_b));
at_latch32 sdxzc (.clk(gclk),.g(dxz_c_g),.i(   d_lat[31: 0]  ),.z(st_dxz_c));
at_latch32 sdxzd (.clk(gclk),.g(dxz_d_g),.i(   d_lat[31: 0]  ),.z(st_dxz_d));
at_latch32 sdyza (.clk(gclk),.g(dyz_a_g),.i(   d_lat[31: 0]  ),.z(st_dyz_a));
at_latch32 sdyzb (.clk(gclk),.g(dyz_b_g),.i(   d_lat[31: 0]  ),.z(st_dyz_b));
at_latch32 sdyzc (.clk(gclk),.g(dyz_c_g),.i(   d_lat[31: 0]  ),.z(st_dyz_c));
at_latch56 cia (.clk(gclk), .g(  ci_g), .i(d_lat[55:0]), .z(color_image_a));
at_latch56 zia (.clk(gclk), .g(  zi_g), .i(d_lat[55:0]), .z(z_image_a));
at_latch56 tia (.clk(gclk), .g(  ti_g), .i(d_lat[55:0]), .z(tex_image_a));
at_latch56 bla (.clk(gclk), .g(  bl_g), .i(d_lat[55:0]), .z(blend_color_a));
at_latch56 fga (.clk(gclk), .g(  fg_g), .i(d_lat[55:0]), .z(fog_color_a));
at_latch56 fla (.clk(gclk), .g(  fl_g), .i(d_lat[55:0]), .z(fill_color_a));
at_latch56 ota (.clk(gclk), .g(  ot_g), .i(d_lat[55:0]), .z(other_modes_a));
at_latch56 pda (.clk(gclk), .g(pd_a_g), .i(d_lat[55:0]), .z(prim_depth_a));
at_latch56 pdb (.clk(gclk), .g(pd_b_g), .i(d_lat[55:0]), .z(prim_depth_b));
at_latch56 pdc (.clk(gclk), .g(pd_c_g), .i(d_lat[55:0]), .z(prim_depth_c));
at_latch56 pdd (.clk(gclk), .g(pd_d_g), .i(d_lat[55:0]), .z(prim_depth_d));

// generate strobes for incrementing read pointers
assign dxz_s   = code_39d[2];				// 41
assign dyz_s   = code_39d[2];				// 41
assign pdm_s   = code_41d[0];				// 42
assign pdl_s   = code_40d[0];				// 41

// generate read pointers for multi buffers
at_ctr4 ctdxzs	(.clk(gclk), .rst(reset), .enb(dxz_s), .z(dxz_sel));
at_ctr3 ctdyzs	(.clk(gclk), .rst(reset), .enb(dyz_s), .z(dyz_sel));
at_ctr4 pdms	(.clk(gclk), .rst(reset), .enb(pdm_s), .z(pdm_sel));
at_ctr4 pdls	(.clk(gclk), .rst(reset), .enb(pdl_s), .z(pdl_sel));

// read latches with bit assignments and padding (unused latches eaten)
assign st_dxz =  dxz_sel[1] ?	(dxz_sel[0] ?	st_dxz_d :	  // s15.16
						st_dxz_c) :
				(dxz_sel[0] ?	st_dxz_b :
						st_dxz_a);

assign st_dyz =  dyz_sel[1] ?			st_dyz_c[31:10] : // s15.6
				(dyz_sel[0] ?	st_dyz_b[31:10] :
						st_dyz_a[31:10]);
assign color_image = {	color_image_a[55:51], 7'b0,
			color_image_a[43:32], 6'b0,
			color_image_a[25:0]};
assign z_image = {30'b0,    z_image_a[25:0]};
assign tex_image = {	  tex_image_a[55:51], 7'b0,
			  tex_image_a[43:32], 6'b0,
			  tex_image_a[25:0]};
assign blend_color = blend_color_a[31:0];
assign fog_color = fog_color_a[31:0];
assign fill_color = fill_color_a[31:0];
assign other_modes = other_modes_a[55:0];
assign prim_depth[55:16] = pdm_sel[1] ?
				(pdm_sel[0] ?	prim_depth_d[31:16] :
						prim_depth_c[31:16]) :
				(pdm_sel[0] ?	prim_depth_b[31:16] :
						prim_depth_a[31:16]);
assign prim_depth[15:0] =  pdl_sel[1] ?
				(pdl_sel[0] ?	prim_depth_d[15:0] :
						prim_depth_c[15:0]) :
				(pdl_sel[0] ?	prim_depth_b[15:0] :
						prim_depth_a[15:0]);

endmodule // at_bl