tc_frac.v 5.98 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: tc_frac.v,v 1.2 2002/11/22 00:34:20 rws Exp $

////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module:	tc_frac
// description:	Texture coordinate fraction module. 
//		Determine tile coordinate fractions for RG and
//		BA Tmem halves.
//
// designer:	Tony DeLaurier
// date:	7/5/94
//
////////////////////////////////////////////////////////////////////////

module tc_frac (clk, start_gclk, s_frac, t_frac, copy_1d, yuv_tex, a_byte, tlut_en, 
		s_frac_ba_out, t_frac_ba_out, s_frac_rg_out, t_frac_rg_out, 
		swap_ba_1d, swap_rg_1d);

  input clk, start_gclk;			// RDP gated clock
  input [4:0] s_frac;           // s fraction
  input [4:0] t_frac;           // t fraction
  input copy_1d;                // copy delayed 1 cycle
  input yuv_tex;                // tile texel type is yuv
  input a_byte;   	        // byte bit of texel address A 
  input tlut_en;                // enable texture lookup table

  output [7:0] s_frac_ba_out;   // s interp fraction to filter (BA)
  wire [7:0] s_frac_ba_out;     // s interp fraction to filter (BA)
  output [7:0] t_frac_ba_out;   // t interp fraction to filter (BA)
  wire [7:0] t_frac_ba_out;     // t interp fraction to filter (BA)
  output [7:0] s_frac_rg_out;   // s interp fraction to filter (RG)
  wire [7:0] s_frac_rg_out;     // s interp fraction to filter (RG)
  output [7:0] t_frac_rg_out;   // t interp fraction to filter (RG)
  wire [7:0] t_frac_rg_out;     // t interp fraction to filter (RG)
  output swap_ba_1d;   	      	// swap texels (BA) delayed 1 cycle
  reg swap_ba_1d;   	      	// swap texels (BA) delayed 1 cycle
  output swap_rg_1d;   	      	// swap texels (RG) delayed 1 cycle
  reg swap_rg_1d;   	      	// swap texels (RG) delayed 1 cycle

  reg copy_2d;               	// copy delayed 2 cycles
  reg swap_ba;   	      	// swap texels (BA)
  reg swap_rg;   	      	// swap texels (RG)
  reg [4:0] t_frac_tc;       	// 2's comp of t_frac
  reg [4:0] s_frac_mod;       	// modified s fraction

  reg [7:3] s_frac_ba;      	// s interp fraction to filter (BA)
  reg [7:3] s_frac_ba_1d;      	// s_frac_ba delayed 1
  reg [7:3] s_frac_ba_2d;      	// s_frac_ba delayed 2
  reg [7:3] s_frac_ba_3d;      	// s_frac_ba delayed 3
  reg [7:3] s_frac_ba_dly;      // s_frac_ba delayed 1 or 3

  reg [7:3] t_frac_ba;      	// t interp fraction to filter (BA)
  reg [7:3] t_frac_ba_1d;      	// t_frac_ba delayed 1
  reg [7:3] t_frac_ba_2d;      	// t_frac_ba delayed 2
  reg [7:3] t_frac_ba_3d;      	// t_frac_ba delayed 3
  reg [7:3] t_frac_ba_dly;      // t_frac_ba delayed 1 or 3

  reg [7:3] s_frac_rg;       	// s interp fraction to filter (RG)
  reg [7:3] s_frac_rg_1d;      	// s_frac_rg delayed 1
  reg [7:3] s_frac_rg_2d;      	// s_frac_rg delayed 2
  reg [7:3] s_frac_rg_3d;      	// s_frac_rg delayed 3
  reg [7:3] s_frac_rg_dly;      // s_frac_rg delayed 1 or 3

  reg [7:3] t_frac_rg;       	// t interp fraction to filter (RG)
  reg [7:3] t_frac_rg_1d;       // t_frac_rg delayed 1
  reg [7:3] t_frac_rg_2d;       // t_frac_rg delayed 2
  reg [7:3] t_frac_rg_3d;       // t_frac_rg delayed 3
  reg [7:3] t_frac_rg_dly;      // t_frac_rg delayed 1 or 3

  reg tlut_en_1d;               // tlut_en delayed 1
  reg tlut_en_2d;               // tlut_en delayed 2

  wire [6:0] one = 6'h20;	// 1.0

  always @(posedge clk)
   if (start_gclk) begin

    // delay tlut_en by 2 cycles

    tlut_en_1d <= tlut_en;
    tlut_en_2d <= tlut_en_1d;

    // delay copy_1d by 1 cycle

    copy_2d <= copy_1d;

    // determine whether in upper or lower half of texel interval (BA)

    swap_ba = ((s_frac[4:0] + t_frac[4:0]) >= one) && !copy_2d;

    // determine s_frac_ba

    s_frac_ba[7:3] <= swap_ba ? -s_frac[4:0] : s_frac[4:0];

    s_frac_ba_1d <= s_frac_ba;
    s_frac_ba_2d <= s_frac_ba_1d;
    s_frac_ba_3d <= s_frac_ba_2d;

    s_frac_ba_dly <= tlut_en_2d ? s_frac_ba_3d : s_frac_ba_1d;

    // determine 2's comp of t_frac

    t_frac_tc[4:0] = -t_frac[4:0]; 

    // determine t_frac_ba

    t_frac_ba[7:3] <= swap_ba ? t_frac_tc[4:0] : t_frac[4:0];

    t_frac_ba_1d <= t_frac_ba;
    t_frac_ba_2d <= t_frac_ba_1d;
    t_frac_ba_3d <= t_frac_ba_2d;

    t_frac_ba_dly <= tlut_en_2d ? t_frac_ba_3d : t_frac_ba_1d;

    // determine s_frac_mod

    s_frac_mod[4:0] = yuv_tex ? {a_byte, s_frac[4:1]} : s_frac[4:0];

    // determine swap_rg

    swap_rg = ((s_frac_mod[4:0] + t_frac[4:0]) >= one) && !copy_2d;

    // determine s_frac_rg

    s_frac_rg[7:3] <= swap_rg ? -s_frac_mod[4:0] : s_frac_mod[4:0];

    s_frac_rg_1d <= s_frac_rg;
    s_frac_rg_2d <= s_frac_rg_1d;
    s_frac_rg_3d <= s_frac_rg_2d;

    s_frac_rg_dly <= tlut_en_2d ? s_frac_rg_3d : s_frac_rg_1d;

    // determine t_frac_rg

    t_frac_rg[7:3] <= swap_rg ? t_frac_tc[4:0] : t_frac[4:0];

    t_frac_rg_1d <= t_frac_rg;
    t_frac_rg_2d <= t_frac_rg_1d;
    t_frac_rg_3d <= t_frac_rg_2d;

    t_frac_rg_dly <= tlut_en_2d ? t_frac_rg_3d : t_frac_rg_1d;

    // delay swap flags and output

    swap_ba_1d <= swap_ba;
    swap_rg_1d <= swap_rg;
  end // always

  assign s_frac_ba_out = {s_frac_ba_dly, 3'b0};
  assign t_frac_ba_out = {t_frac_ba_dly, 3'b0};
  assign s_frac_rg_out = {s_frac_rg_dly, 3'b0};
  assign t_frac_rg_out = {t_frac_rg_dly, 3'b0};

endmodule // tc_frac