Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 1000 lines (894 sloc) 28.4 KB
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2014 Francis Bruno, All Rights Reserved
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, see <http://www.gnu.org/licenses>.
//
// This code is available under licenses for commercial use. Please contact
// Francis Bruno for more information.
//
// http://www.gplgpu.com
// http://www.asicsolutions.com
//
// Title : Drawing Engine Setup Fragment Generation
// File : des_frag_gen.v
// Author : Jim MacLeod
// Created : 14-May-2011
// RCS File : $Source:$
// Status : $Id:$
//
///////////////////////////////////////////////////////////////////////////////
//
// Description :
//
//////////////////////////////////////////////////////////////////////////////
//
// Modules Instantiated:
//
///////////////////////////////////////////////////////////////////////////////
//
// Modification History:
//
// $Log:$
//
//
///////////////////////////////////////////////////////////////////////////////
`timescale 1 ps / 1 ps
module des_frag_gen
(
input clk,
input rstn,
input ld_frag,
input last_frag,
input msk_last_frag,
input scan_dir_2,
input [2:0] clp_2,
input [31:0] clptl_2,
input [31:0] clpbr_2,
input [31:0] tex_2,
input [31:0] c3d_2,
input [31:0] start_x_fp_2,
input [31:0] start_y_fp_2,
input [31:0] end_x_fp_2,
input [31:0] end_y_fp_2,
input [15:0] current_x_fx, // 16.0
input [15:0] current_y_fx, // 16.0
input [95:0] z_cmp_fp,
input [95:0] w_cmp_fp,
input [95:0] uw_cmp_fp,
input [95:0] vw_cmp_fp,
input [95:0] a_cmp_fp,
input [95:0] r_cmp_fp,
input [95:0] g_cmp_fp,
input [95:0] b_cmp_fp,
input [95:0] f_cmp_fp,
input [95:0] rs_cmp_fp,
input [95:0] gs_cmp_fp,
input [95:0] bs_cmp_fp,
input [31:0] hith_2,
input [31:0] yon_2,
input fg_bgn,
output last_pixel,
output msk_last_pixel,
output valid_z_col_spec,
output valid_uv,
output [15:0] x_cur_o,
output [15:0] y_cur_o,
output [31:0] z_cur_fx,
output [19:0] current_u,
output [19:0] current_v,
output [31:0] current_argb,
output [23:0] current_spec,
output [7:0] current_fog,
output [3:0] lod_num,
output [5:0] lod_gamma,
output clip_xy,
output clip_uv,
output reg addr_exact,
output reg [8:0] bit_mask_x,
output reg [8:0] bit_mask_y,
// Start/End Point for 3D line.
output [15:0] l3_cpx0,
output [15:0] l3_cpy0,
output [15:0] l3_cpx1,
output [15:0] l3_cpy1,
output current_fg_bgn,
// Signal tap.
output signed [15:0] x_cur_e,
output signed [15:0] y_cur_e
);
`include "define_3d.h"
// Hither and Yon Comparisons
parameter
NEVER = 3'b000, // If Z_Enabled, CLIP
ALWAYS = 3'b001, // Always Draw, so NOT_CLIP
LESS = 3'b010, // Z < Hither or Yon
LEQUAL = 3'b011, // Z <= Hither or Yon
EQUAL = 3'b100, // Z == Hiter or Yon
GEQUAL = 3'b101, // Z >= Hiter or Yon
GREATER = 3'b110, // Z > Hiter or Yon
NOTEQUAL = 3'b111; // Z != Hiter or Yon
wire [3:0] lod_num_a;
reg [3:0] lod_num_d;
reg [3:0] lod_num_dd;
reg [5:0] lod_gamma_d;
reg [5:0] lod_gamma_dd;
reg magnification_d;
reg magnification_dd;
reg [31:0] dx_fx;
reg [31:0] dy_fx;
wire [31:0] dx_fx_d;
wire [31:0] dy_fx_d;
reg [8:0] largest_u_size;
reg [8:0] largest_v_size;
reg [24:0] frag_pipe;
reg [15:0] last_frag_pipe;
reg [15:0] msk_last_frag_pipe;
reg [13:0] uv_clip_pipe;
reg [8:0] fg_bgn_pipe;
wire [31:0] start_x_fx;
wire [31:0] start_y_fx;
wire [31:0] end_x_fx;
wire [31:0] end_y_fx;
assign l3_cpx0 = start_x_fx[31:16];
assign l3_cpy0 = start_y_fx[31:16];
assign l3_cpx1 = end_x_fx[31:16];
assign l3_cpy1 = end_y_fx[31:16];
// T2R4 Calculation.
// 11.9
wire [31:0] uwx_cur_fp;
wire [31:0] uwy_cur_fp;
wire [31:0] vwx_cur_fp;
wire [31:0] vwy_cur_fp;
wire [31:0] ux_cur_fp;
wire [31:0] uy_cur_fp;
wire [31:0] vx_cur_fp;
wire [31:0] vy_cur_fp;
reg [31:0] u_cur_fp_1;
reg [31:0] u_cur_fp_0;
reg [31:0] v_cur_fp_1;
reg [31:0] v_cur_fp_0;
wire [31:0] wx_cur_fp;
wire [31:0] wy_cur_fp;
wire [31:0] rwx_cur_fp;
wire [31:0] rwy_cur_fp;
wire [31:0] u_cur_fx_d;
wire [31:0] v_cur_fx_d;
//
// 23.9
reg [31:0] u_cur_fx;
reg [31:0] v_cur_fx;
reg [31:0] ux_cur_fx;
reg [31:0] uy_cur_fx;
reg [31:0] vx_cur_fx;
reg [31:0] vy_cur_fx;
reg [31:0] udx_fx;
reg [31:0] udy_fx;
reg [31:0] vdx_fx;
reg [31:0] vdy_fx;
reg [31:0] udx_a;
reg [31:0] udy_a;
reg [31:0] vdx_a;
reg [31:0] vdy_a;
reg signed [31:0] max_x; // 23.9
reg signed [31:0] max_y; // 23.9
reg [31:0] fCoverage; // 23.9
reg [31:0] u_addr_shifted;
reg [31:0] v_addr_shifted;
reg [31:0] u_final_address;
reg [31:0] v_final_address;
wire [31:0] w_cur_fp;
wire [31:0] rw_cur_fp;
wire [31:0] uw_cur_fp_d;
wire [31:0] vw_cur_fp_d;
wire [31:0] u_cur_fp;
wire [31:0] v_cur_fp;
//
// reg [33:0] lenx;
// reg [33:0] leny;
// reg [33:0] lenx_a; // 12.10
// reg [33:0] lenx_b; // 12.10
// reg [33:0] leny_a; // 12.10
// reg [33:0] leny_b; // 12.10
wire [9:0] fLOD; // 12.10
wire [31:0] z_cur_fp;
wire [31:0] uw_cur_fp;
wire [31:0] vw_cur_fp;
wire [31:0] a_cur_fp;
wire [31:0] r_cur_fp;
wire [31:0] g_cur_fp;
wire [31:0] b_cur_fp;
wire [31:0] f_cur_fp;
wire [31:0] rs_cur_fp;
wire [31:0] gs_cur_fp;
wire [31:0] bs_cur_fp;
wire [7:0] a_cur_fx;
wire [7:0] r_cur_fx;
wire [7:0] g_cur_fx;
wire [7:0] b_cur_fx;
wire [7:0] f_cur_fx;
wire [7:0] rs_cur_fx;
wire [7:0] gs_cur_fx;
wire [7:0] bs_cur_fx;
wire signed [15:0] xmin;
wire signed [15:0] ymin;
wire signed [15:0] xmax;
wire signed [15:0] ymax;
// wire signed [15:0] x_cur_e;
// wire signed [15:0] y_cur_e;
wire clip;
reg xl_xmin;
reg xmaxl_x;
reg ymaxl_y;
reg yl_ymin;
wire [3:0] out_code;
reg signed [15:0] xmin_uv;
reg signed [15:0] ymin_uv;
reg signed [15:0] xmax_uv;
reg signed [15:0] ymax_uv;
wire uv_clip;
reg xl_xmin_uv;
reg xmaxl_x_uv;
reg ymaxl_y_uv;
reg yl_ymin_uv;
wire [3:0] out_code_uv;
flt_fx u0_flt_fx(start_x_fp_2, start_x_fx); // 16.16
flt_fx u1_flt_fx(start_y_fp_2, start_y_fx); // 16.16
flt_fx u2_flt_fx(end_x_fp_2, end_x_fx); // 16.16
flt_fx u3_flt_fx(end_y_fp_2, end_y_fx); // 16.16
always @(posedge clk, negedge rstn)
if(!rstn) begin
dx_fx <= 32'h0;
dy_fx <= 32'h0;
frag_pipe <= 25'h0;
last_frag_pipe <= 16'h0;
msk_last_frag_pipe <= 16'h0;
uv_clip_pipe <= 14'h0;
fg_bgn_pipe <= 11'h0;
end else begin
dx_fx <= {current_x_fx, 16'h0} - start_x_fx;
dy_fx <= {current_y_fx, 16'h0} - start_y_fx;
frag_pipe <= {frag_pipe[23:0], ld_frag};
last_frag_pipe <= {last_frag_pipe[14:0], (last_frag & ld_frag)};
msk_last_frag_pipe <= {msk_last_frag_pipe[14:0], msk_last_frag};
uv_clip_pipe <= {uv_clip_pipe[12:0], uv_clip};
fg_bgn_pipe <= {fg_bgn_pipe[7:0], fg_bgn};
end
assign last_pixel = last_frag_pipe[8];
assign msk_last_pixel = msk_last_frag_pipe[8];
assign valid_z_col_spec = frag_pipe[8];
assign valid_uv = frag_pipe[24];
assign clip_xy = clip;
assign clip_uv = uv_clip_pipe[13];
assign current_fg_bgn = fg_bgn_pipe[8];
gen_pipe_1 #(32, 9) xy_gen_pipe
(
.clk (clk),
.din ({current_x_fx, current_y_fx}),
.dout_1 ({x_cur_e, y_cur_e}), // One cycle early.
.dout ({x_cur_o, y_cur_o})
);
/////////////////// 2D Clipping ///////////////////////////////////
//
assign xmin = clptl_2[31:16];
assign ymin = clptl_2[15:0];
assign xmax = clpbr_2[31:16];
assign ymax = clpbr_2[15:0];
always @(posedge clk) begin
if(x_cur_e < xmin) xl_xmin <= 1'b1;
else xl_xmin <= 1'b0;
if(xmax < x_cur_e) xmaxl_x <= 1'b1;
else xmaxl_x <= 1'b0;
if(ymax < y_cur_e) ymaxl_y <= 1'b1;
else ymaxl_y <= 1'b0;
if(y_cur_e < ymin) yl_ymin <= 1'b1;
else yl_ymin <= 1'b0;
end
assign out_code = {xl_xmin, xmaxl_x, ymaxl_y, yl_ymin};
assign clip = ((clp_2[1:0] == 2'b10) && (out_code != 4'b0000)) ? 1'b1 :
((clp_2[1:0] == 2'b11) && (out_code == 4'b0000)) ? 1'b1 : 1'b0;
// UV must have additional space
always @(posedge clk)
if(clp_2[1:0] == 2'b10) begin
xmin_uv <= clptl_2[31:16] - 16'h1;
ymin_uv <= clptl_2[15:0] - 16'h1;
xmax_uv <= clpbr_2[31:16] + 16'h1;
ymax_uv <= clpbr_2[15:0] + 16'h1;
end else begin
xmin_uv <= clptl_2[31:16] + 16'h1;
ymin_uv <= clptl_2[15:0] + 16'h1;
xmax_uv <= clpbr_2[31:16] - 16'h1;
ymax_uv <= clpbr_2[15:0] - 16'h1;
end
always @(posedge clk) begin
if(x_cur_e < xmin_uv) xl_xmin_uv <= 1'b1;
else xl_xmin_uv <= 1'b0;
if(xmax_uv < x_cur_e) xmaxl_x_uv <= 1'b1;
else xmaxl_x_uv <= 1'b0;
if(ymax_uv < y_cur_e) ymaxl_y_uv <= 1'b1;
else ymaxl_y_uv <= 1'b0;
if(y_cur_e < ymin_uv) yl_ymin_uv <= 1'b1;
else yl_ymin_uv <= 1'b0;
end
assign out_code_uv = {xl_xmin_uv, xmaxl_x_uv, ymaxl_y_uv, yl_ymin_uv};
assign uv_clip = ((clp_2[1:0] == 2'b10) && (out_code_uv != 4'b0000)) ? 1'b1 :
((clp_2[1:0] == 2'b11) && (out_code_uv == 4'b0000)) ? 1'b1 : 1'b0;
/////////////////// 3D ///////////////////////////////////
des_comp_gen u_des_comp_gen_w
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx),
.dy_fx (dy_fx),
.cmp_i (w_cmp_fp),
// Outputs.
.curr_i (rw_cur_fp)
);
des_comp_gen u_des_comp_gen_u
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx),
.dy_fx (dy_fx),
.cmp_i (uw_cmp_fp),
// Outputs.
.curr_i (uw_cur_fp)
);
des_comp_gen u_des_comp_gen_v
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx),
.dy_fx (dy_fx),
.cmp_i (vw_cmp_fp),
// Outputs.
.curr_i (vw_cur_fp)
);
des_comp_gen u_des_comp_gen_z
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx),
.dy_fx (dy_fx),
.cmp_i (z_cmp_fp),
// Outputs.
.curr_i (z_cur_fp)
);
/*
// These Do not need to be floats (CHANGE).
des_comp_gen u_des_comp_gen_argbf_spec[3:0]
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx),
.dy_fx (dy_fx),
.cmp_i ({
a_cmp_fp,
r_cmp_fp,
g_cmp_fp,
b_cmp_fp
// f_cmp_fp,
// rs_cmp_fp,
// gs_cmp_fp,
// bs_cmp_fp
}),
// Outputs.
.curr_i ({
a_cur_fp,
r_cur_fp,
g_cur_fp,
b_cur_fp
// f_cur_fp,
// rs_cur_fp,
// gs_cur_fp,
// bs_cur_fp
})
);
*/
gen_pipe #(64, 5) argb_gen_pipe(.clk(clk), .din({dx_fx, dy_fx}), .dout({dx_fx_d, dy_fx_d}));
des_comp_gen_fx_color u_des_comp_gen_argb_fspec[7:0]
(
// Inputs.
.clk (clk),
.rstn (rstn),
.dx_fx (dx_fx_d),
.dy_fx (dy_fx_d),
.cmp_i ({
a_cmp_fp,
r_cmp_fp,
g_cmp_fp,
b_cmp_fp,
f_cmp_fp,
rs_cmp_fp,
gs_cmp_fp,
bs_cmp_fp
}),
// Outputs.
.curr_i ({
a_cur_fx,
r_cur_fx,
g_cur_fx,
b_cur_fx,
f_cur_fx,
rs_cur_fx,
gs_cur_fx,
bs_cur_fx
})
);
// Convert to Fixed point.
// FIXME Check Conversions, FOG
flt_fx_24p8 u4_flt_fx(z_cur_fp, z_cur_fx);
// flt_fx u5_flt_fx(a_cur_fp, a_cur_fx);
// flt_fx u6_flt_fx(r_cur_fp, r_cur_fx);
// flt_fx u7_flt_fx(g_cur_fp, g_cur_fx);
// flt_fx u8_flt_fx(b_cur_fp, b_cur_fx);
// flt_fx u9_flt_fx(f_cur_fp, f_cur_fx);
// flt_fx u10_flt_fx(rs_cur_fp, rs_cur_fx);
// flt_fx u11_flt_fx(gs_cur_fp, gs_cur_fx);
// flt_fx u12_flt_fx(bs_cur_fp, bs_cur_fx);
// assign current_argb = {a_cur_fx[23:16], r_cur_fx[23:16], g_cur_fx[23:16], b_cur_fx[23:16]};
assign current_argb = {a_cur_fx, r_cur_fx, g_cur_fx, b_cur_fx};
assign current_spec = {rs_cur_fx, gs_cur_fx, bs_cur_fx};
assign current_fog = f_cur_fx;
//////////////////////////////////////////////////////////////////////////////
// LOD calculations.
//
// Computes level of detail for standard trilinear mipmapping, in which
// the four texture index gradients are consolidated into a single number
// to select level of detail.
//
// The basic approach is to compute the lengths of the pixel coverage for
// the X and Y extent of the approximate pixel coverage area. These two
// lengths are then combined in for the single LOD result.
//
//
// Take the reciprical of RW (6 clocks).
flt_recip u_flt_recip(.clk(clk), .denom(rw_cur_fp), .recip(w_cur_fp));
gen_pipe #(64, 6) uv_gen_pipe(.clk(clk), .din({uw_cur_fp, vw_cur_fp}), .dout({uw_cur_fp_d, vw_cur_fp_d}));
// Multiply UW and VW by 1/W(3 clocks).
flt_mult u0_flt_mult(clk, rstn, w_cur_fp, uw_cur_fp_d, u_cur_fp);
flt_mult u1_flt_mult(clk, rstn, w_cur_fp, vw_cur_fp_d, v_cur_fp);
// Calculate previous WX, (3 cycles).
flt_add_sub u_flt_add_sub_rwx
(
.clk (clk),
.sub (~scan_dir_2),
.afl (rw_cur_fp),
.bfl (w_cmp_fp[63:32]),
.fl (rwx_cur_fp)
);
// Calculate previous WY, (3 cycles).
flt_add_sub u_flt_add_sub_rwy
(
.clk (clk),
.sub (1'b1),
.afl (rw_cur_fp),
.bfl (w_cmp_fp[31:0]),
.fl (rwy_cur_fp)
);
// Calculate previous UX, (3 cycles).
flt_add_sub u_flt_add_sub_uwx
(
.clk (clk),
.sub (~scan_dir_2),
.afl (uw_cur_fp_d),
.bfl (uw_cmp_fp[63:32]),
.fl (uwx_cur_fp)
);
// Calculate previous UY, (3 cycles).
flt_add_sub u_flt_add_sub_uwy
(
.clk (clk),
.sub (1'b1),
.afl (uw_cur_fp_d),
.bfl (uw_cmp_fp[31:0]),
.fl (uwy_cur_fp)
);
// Calculate previous VX, (3 cycles).
flt_add_sub u_flt_add_sub_vwx
(
.clk (clk),
.sub (~scan_dir_2),
.afl (vw_cur_fp_d),
.bfl (vw_cmp_fp[63:32]),
.fl (vwx_cur_fp)
);
// Calculate previous VY, (3 cycles).
flt_add_sub u_flt_add_sub_vwy
(
.clk (clk),
.sub (1'b1),
.afl (vw_cur_fp_d),
.bfl (vw_cmp_fp[31:0]),
.fl (vwy_cur_fp)
);
// Six Cycles.
// 1/WX and 1/WY.
flt_recip u_flt_recip_wx(.clk(clk), .denom(rwx_cur_fp), .recip(wx_cur_fp));
flt_recip u_flt_recip_wy(.clk(clk), .denom(rwy_cur_fp), .recip(wy_cur_fp));
// Multiply UW and VW by 1/W(3 clocks).
flt_mult u_flt_mult_ux(clk, rstn, wx_cur_fp, uwx_cur_fp, ux_cur_fp);
flt_mult u_flt_mult_uy(clk, rstn, wy_cur_fp, uwy_cur_fp, uy_cur_fp);
flt_mult u_flt_mult_vx(clk, rstn, wx_cur_fp, vwx_cur_fp, vx_cur_fp);
flt_mult u_flt_mult_vy(clk, rstn, wy_cur_fp, vwy_cur_fp, vy_cur_fp);
// Convert to Fixed Point (24.24).
// Need 3 pipline delays.
always @(posedge clk) begin
u_cur_fx <= flt_fx_23p9(u_cur_fp_1); // 24.24
u_cur_fp_1 <= u_cur_fp_0;
u_cur_fp_0 <= u_cur_fp;
v_cur_fx <= flt_fx_23p9(v_cur_fp_1); // 24.24
v_cur_fp_1 <= v_cur_fp_0;
v_cur_fp_0 <= v_cur_fp;
end
always @* ux_cur_fx = flt_fx_23p9(ux_cur_fp); // 23.9
always @* uy_cur_fx = flt_fx_23p9(uy_cur_fp); // 23.9
always @* vx_cur_fx = flt_fx_23p9(vx_cur_fp); // 23.9
always @* vy_cur_fx = flt_fx_23p9(vy_cur_fp); // 23.9
always @* begin
// 23.9 - 23.9 = 23.9
// Calculate the Perspective distance to previous U and V.
udx_fx = u_cur_fx - ux_cur_fx;
udy_fx = u_cur_fx - uy_cur_fx;
vdx_fx = v_cur_fx - vx_cur_fx;
vdy_fx = v_cur_fx - vy_cur_fx;
end
always @(posedge clk) begin
if(udx_fx[31]) udx_a <= ~udx_fx + 1;
else udx_a <= udx_fx;
if(udy_fx[31]) udy_a <= ~udy_fx + 1;
else udy_a <= udy_fx;
if(vdx_fx[31]) vdx_a <= ~vdx_fx + 1;
else vdx_a <= vdx_fx;
if(vdy_fx[31]) vdy_a <= ~vdy_fx + 1;
else vdy_a <= vdy_fx;
end
//////////////////////////////////////////////////////////////////////////////
// Find the largest (T2R4 Method).
// always @(posedge clk) begin
always @* begin
max_x = (udx_a > vdx_a) ? udx_a : vdx_a; // 23.9
max_y = (udy_a > vdy_a) ? udy_a : vdy_a; // 23.9
fCoverage = (max_x > max_y) ? max_x : max_y; // 23.9
end
//////////////////////////////////////////////////////////////////////////////
// 22.18
// tex_2`T_MLM // trilinear enable.
// tex_2`T_MLP // trilinear pass.
log2_table u_log2_table
(
.clk (clk),
.val (fCoverage), // i[23:9], f[8:0]
.trilinear_en (tex_2`T_MLM), // Trilinear Enable
.log2 (fLOD)
);
reg [3:0] new_mm_no;
// Trilinear Pass Select.
always @* begin
if ( (tex_2`T_MLM) & (tex_2`T_MLP) & (|(fLOD[9:6]))) new_mm_no = fLOD[9:6] - 1;
else new_mm_no = fLOD[9:6];
end
assign lod_num_a = (tex_2`T_MM & (new_mm_no > tex_2`T_MMN)) ? tex_2`T_MMN :
(tex_2`T_MM) ? new_mm_no : 4'b0000;
/////////////////////////////////////////////////////////////////////////////
// Shift according to LOD.
// always @* begin
// Match the delays.
gen_pipe #(64, 2) uv_cur_gen_pipe(.clk(clk), .din({u_cur_fx, v_cur_fx}), .dout({u_cur_fx_d, v_cur_fx_d}));
always @(posedge clk) begin
lod_num_d <= lod_num_a;
lod_gamma_d <= (tex_2`T_MM) ? fLOD[5:0] : 6'b000000;
// lod_gamma_d <= (tex_2`T_MM) ? 5'b10000 : 5'b00000;
magnification_d <= ~|lod_num_a & ~(tex_2`T_MLM);
u_addr_shifted <= u_cur_fx_d >> lod_num_a;
v_addr_shifted <= v_cur_fx_d >> lod_num_a;
end
//////////////////////////////////////////////////////////////////////////////
// Adjust u,v address.
// always @* begin
always @(posedge clk) begin
lod_num_dd <= lod_num_d;
lod_gamma_dd <= lod_gamma_d;
magnification_dd <= magnification_d;
casex ({tex_2`T_NMM, tex_2`T_NMG, magnification_d, c3d_2`D3_RSC}) /* synopsys parallel_case full_case */
// For Bilinear Mode and spac_cent at 0.5, subtract 0.5.
4'b0x01, 4'bx011: begin
u_final_address <= u_addr_shifted - 9'h100;
v_final_address <= v_addr_shifted - 9'h100;
end
// For Bilinear Mode and spac_cent at 1.0, leave address alone.
4'b0x00, 4'bx010: begin
u_final_address <= u_addr_shifted;
v_final_address <= v_addr_shifted;
end
// For Nearest Mode and spac_cent at 0.5, leave address alone.
4'bx111, 4'b1x01: begin
u_final_address <= u_addr_shifted;
v_final_address <= v_addr_shifted;
end
// For Nearest Mode and spac_cent at 1.0, add 0.5
4'bx110, 4'b1x00: begin
u_final_address <= u_addr_shifted + 9'h100;
v_final_address <= v_addr_shifted + 9'h100;
end
endcase
end
//////////////////////////////////////////////////////////////////////////////
//
always @* begin
if ((tex_2`T_NMM & !magnification_dd) | (tex_2`T_NMG & magnification_dd) |
!((|(u_final_address[8:0])) | (|(v_final_address[8:0]))))
addr_exact = 1'b1;
else addr_exact = 1'b0;
end
//////////////////////////////////////////////////////////////////////////////
//
// Clamping.
// Decode tex size.
always @* begin
casex(tex_2`T_MMSZX) /* synopsys parallel_case */
4'b0000: largest_u_size = 9'b000000001;
4'b0001: largest_u_size = 9'b000000001;
4'b0010: largest_u_size = 9'b000000011;
4'b0011: largest_u_size = 9'b000000111;
4'b0100: largest_u_size = 9'b000001111;
4'b0101: largest_u_size = 9'b000011111;
4'b0110: largest_u_size = 9'b000111111;
4'b0111: largest_u_size = 9'b001111111;
4'b1000: largest_u_size = 9'b011111111;
4'b1001: largest_u_size = 9'b111111111;
default: largest_u_size = 9'b111111111;
endcase
casex(tex_2`T_MMSZY) /* synopsys parallel_case */
4'b0000: largest_v_size = 9'b000000001;
4'b0001: largest_v_size = 9'b000000001;
4'b0010: largest_v_size = 9'b000000011;
4'b0011: largest_v_size = 9'b000000111;
4'b0100: largest_v_size = 9'b000001111;
4'b0101: largest_v_size = 9'b000011111;
4'b0110: largest_v_size = 9'b000111111;
4'b0111: largest_v_size = 9'b001111111;
4'b1000: largest_v_size = 9'b011111111;
4'b1001: largest_v_size = 9'b111111111;
default: largest_v_size = 9'b111111111;
endcase
end
// Bitmask generation
always @* begin
bit_mask_x = largest_u_size >> lod_num_dd;
bit_mask_y = largest_v_size >> lod_num_dd;
end
//////////////////////////////////////////////////////////////////////////////
//
// Speed up u and v final address: 20 bit address 11.9 format
assign current_u = {u_final_address[31], |(u_final_address[30:18]), u_final_address[17:0]};
assign current_v = {v_final_address[31], |(v_final_address[30:18]), v_final_address[17:0]};
assign lod_gamma = lod_gamma_dd;
assign lod_num = lod_num_dd;
//////////////////////////////////////////////////////////////////
// Float to fixed converts floating point numbers to 16.16 sign
//
//
function [47:0] flt_fx_24p24;
input [31:0] fp_in; // Floating point in IEEE fmt
//
// 23.9, UV.
//
reg [7:0] bias_exp; /* Real exponent -127 - 128 */
reg [7:0] bias_exp2; /* Real exponent 2's comp */
reg [47:0] bias_mant; /* mantissa expanded to 16.16 fmt */
reg [48:0] fixed_out;
begin
bias_mant = {25'h0001, fp_in[22:0]};
bias_exp = fp_in[30:23] - 'd127;
bias_exp2 = ~bias_exp + 1;
// infinity or NaN - Don't do anything special, will overflow
// zero condition
if (fp_in[30:0] == 31'b0) fixed_out = 0;
// negative exponent
else if (bias_exp[7]) fixed_out = bias_mant >> bias_exp2;
// positive exponent
else fixed_out = bias_mant << bias_exp;
flt_fx_24p24 = (fp_in[31]) ? ~{fixed_out[46:0],1'b0} + 1 : {fixed_out[46:0],1'b0};
end
endfunction
//////////////////////////////////////////////////////////////////
// Float to fixed converts floating point numbers to 16.16 sign
//
//
function [31:0] flt_fx_23p9;
input [31:0] fp_in; // Floating point in IEEE fmt
//
// 23.9, UV.
//
reg [7:0] bias_exp; /* Real exponent -127 - 128 */
reg [7:0] bias_exp2; /* Real exponent 2's comp */
reg [47:0] bias_mant; /* mantissa expanded to 16.16 fmt */
reg [47:0] int_fixed_out;
reg [31:0] fixed_out;
begin
bias_mant = {25'h0001, fp_in[22:0]};
bias_exp = fp_in[30:23] - 8'd127;
bias_exp2 = ~bias_exp + 8'h1;
// infinity or NaN - Don't do anything special, will overflow
// zero condition
if (fp_in[30:0] == 31'b0) int_fixed_out = 0;
// negative exponent
else if (bias_exp[7]) int_fixed_out = bias_mant >> bias_exp2;
// positive exponent
else int_fixed_out = bias_mant << bias_exp;
fixed_out = int_fixed_out[45:14];
flt_fx_23p9 = (fp_in[31]) ? ~fixed_out + 1 : fixed_out;
end
endfunction
/////////////////////// Hither and Yon Compares ///////////////////////////////
// Z Stuff
/*
always @* begin
new_z[15:0] = znew[15:0];
new_hither[15:0] = hither[15:0];
new_yon[15:0] = yon[15:0];
// 24bpz = 32bpp & zfloat_2
if (ps32_2) begin
new_z[23:16] = znew[23:16];
new_hither[23:16] = hither[23:16];
new_yon[23:16] = yon[23:16];
end
else begin
new_z[23:16] = 8'h00;
new_hither[23:16] = 8'h00;
new_yon[23:16] = 8'h00;
end
end
//
// Z Hither and Yon Comparisons
//
always @* begin
if ((z_buf_en) && ((hither_comp_op == NEVER) || (yon_comp_op == NEVER))) begin
z_clip = 1'b1;
end
// else if (hith AND yon ALWAYS OR z_enable_OFF), NOT_clip
else if ((!z_buf_en) || ((hither_comp_op == ALWAYS) && (yon_comp_op == ALWAYS))) begin
z_clip = 1'b0;
end
// else now check individually:
// start with clip for hith and yon
// if (always) NOT_clip
//
else begin
if (hither_comp_op == ALWAYS) begin
hith_1clip = 1'b0;
end
else begin
hith_1clip = 1'b1;
end
if (yon_comp_op == ALWAYS) begin
yon_1clip = 1'b0;
end
else begin
yon_1clip = 1'b1;
end
//
// Generate residue value (pos, zero, or neg)
// if (zero && 3 or 4 or 5) NOT_clip
//
if ((new_z == new_hither) && ((hither_comp_op >= LEQUAL) && (hither_comp_op) <= GEQUAL)) begin
hith_345clip = 1'b0;
end
else begin
hith_345clip = 1'b1;
end
if ((new_z == new_yon) && ((yon_comp_op >= LEQUAL) && (yon_comp_op) <= GEQUAL)) begin
yon_345clip = 1'b0;
end
else begin
yon_345clip = 1'b1;
end
//
// if (pos && 5 or 6 or 7 ) NOT_clip
//
if ((new_z > new_hither) && ((hither_comp_op >= GEQUAL) && (hither_comp_op) <= NOTEQUAL)) begin
hith_567clip = 1'b0;
end
else begin
hith_567clip = 1'b1;
end
if ((new_z > new_yon) && ((yon_comp_op >= GEQUAL) && (yon_comp_op) <= NOTEQUAL)) begin
yon_567clip = 1'b0;
end
else begin
yon_567clip = 1'b1;
end
//
// if (neg && 2 or 3 or 7 ) NOT_clip
//
if ((new_z < new_hither) && ((hither_comp_op == LESS) ||
(hither_comp_op == LEQUAL) ||
(hither_comp_op) == NOTEQUAL)) begin
hith_237clip = 1'b0;
end
else begin
hith_237clip = 1'b1;
end
if ((new_z < new_yon) && ((yon_comp_op == LESS) ||
(yon_comp_op == LEQUAL) || (yon_comp_op) == NOTEQUAL)) begin
yon_237clip = 1'b0;
end
else begin
yon_237clip = 1'b1;
end
//
// if (1clip AND 345clip AND 567clip AND 237clip)
// clip
// else NOT_clip
//
if ( hith_1clip && hith_345clip && hith_567clip && hith_237clip)
begin
hither_clip = 1'b1;
end
else begin
hither_clip = 1'b0;
end
if ( yon_1clip && yon_345clip && yon_567clip && yon_237clip)
begin
yon_clip = 1'b1;
end
else begin
yon_clip = 1'b0;
end
//
// if (NOT_clip_h AND NOT_clip_y) NOT_CLIP
//
if ( hither_clip || yon_clip ) begin
z_clip = 1'b1;
end
else begin
z_clip = 1'b0;
end
end
end
*/
/////////////////////////// Fog Table /////////////////////////////////////////
/*
/////////////////////////////////////////////////////////////////////////////////////
// Correct Method.
// ((11.0f/32.0f)*(uwx_a + vwx_a) + (21.0f/32.0f)*max(uwx_a, vwx_a));
// 11/32 = 0.34375, 32'h5800.
// 21/32 = 0.65625, 32'hA800.
//
always @* begin
max_x = (udx_fx > vdx_fx) ? udx_fx : vdx_fx; // 22.18
max_y = (udy_fx > vdy_fx) ? udy_fx : vdy_fx; // 22.18
sum_x = udx_fx + vdx_fx; // 22.18
sum_y = udy_fx + vdy_fx; // 22.18
lenx = lenx_a + lenx_b; // 24.10
leny = leny_a + leny_b; // 24.10
fCoverage = (lenx + leny) >> 1; // AVERAGE // 24.10
end
// 24.5 * 0.5 = 24.10
always @(posedge clk) begin
begin
lenx_a <= max_x[33:5] * 5'b10101;
lenx_b <= sum_x[33:5] * 5'b01011;
leny_a <= max_y[33:5] * 5'b10101;
leny_b <= sum_y[33:5] * 5'b01011;
end
end
*/
endmodule