diff options
Diffstat (limited to 'rtl/gfx/gfx_pkg.sv')
| -rw-r--r-- | rtl/gfx/gfx_pkg.sv | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/rtl/gfx/gfx_pkg.sv b/rtl/gfx/gfx_pkg.sv new file mode 100644 index 0000000..7072967 --- /dev/null +++ b/rtl/gfx/gfx_pkg.sv @@ -0,0 +1,271 @@ +package gfx; + + typedef logic[31:0] word; + + typedef word uword; + typedef logic signed[$bits(word) - 1:0] sword; + typedef logic[$bits(word) / 2 - 1:0] uhword; + typedef logic signed[$bits(word) / 2 - 1:0] shword; + typedef logic[2 * $bits(word) - 1:0] udword; + typedef logic signed[2 * $bits(word) - 1:0] sdword; + typedef logic signed[4 * $bits(word) - 1:0] qword; + typedef logic signed[8 * $bits(word) - 1:0] oword; + + localparam int SUBWORD_BITS = $clog2($bits(word)) - $clog2($bits(byte)); + localparam int BYTES_PER_WORD = 1 << SUBWORD_BITS; + + typedef logic[$bits(word) - SUBWORD_BITS - 1:0] word_ptr; + typedef logic[$bits(word_ptr) - 1 - 1:0] dword_ptr; + typedef logic[$bits(word_ptr) - 2 - 1:0] qword_ptr; + typedef logic[$bits(word_ptr) - 3 - 1:0] oword_ptr; + + typedef logic[7:0] float_exp; + typedef logic[$bits(word) - $bits(float_exp) - 2:0] float_mant; + typedef logic[$bits(float_mant):0] float_mant_full; // Incluye '1.' explícito + typedef logic[$bits(float_mant_full) + 1:0] float_mant_ext; // Considera overflow + + localparam float_exp FLOAT_EXP_BIAS = (1 << ($bits(float_exp) - 1)) - 1; + localparam float_exp FLOAT_EXP_MAX = {($bits(float_exp)){1'b1}}; + + function float_mant_full full_mant(float_mant in); + full_mant = {1'b1, in}; + endfunction + + function float_mant implicit_mant(float_mant_full in); + assert (in[$bits(in) - 1]); + implicit_mant = in[$bits(in) - 2:0]; + endfunction + + typedef struct packed + { + logic sign; + float_exp exp; + float_mant mant; + } float; + + /* Explicación de guard, round, sticky: + * https://drilian.com/2023/01/10/floating-point-numbers-and-rounding/ + */ + typedef struct packed + { + float normal; + logic slow, + zero, + guard, + round, + sticky; + } float_round; + + typedef struct packed + { + logic exp_max, + exp_min, + mant_zero; + } float_class; + + function float_class classify_float(float in); + classify_float.exp_max = &in.exp; + classify_float.exp_min = ~|in.exp; + classify_float.mant_zero = ~|in.mant; + endfunction + + function logic is_float_special(float_class in); + is_float_special = in.exp_max | (in.exp_min & ~in.mant_zero); + endfunction + + function float_mant_ext float_prepare_round(float in, float_class in_class); + float_prepare_round = {~in_class.exp_min, in.mant, 2'b00}; + endfunction + + typedef struct packed + { + logic setup_mul_float, + setup_unit_b, + mnorm_put_hi, + mnorm_put_lo, + mnorm_put_mul, + mnorm_zero_b, + mnorm_zero_flags, + minmax_abs, + minmax_swap, + minmax_zero_min, + minmax_copy_flags, + shiftr_int_signed, + addsub_copy_flags, + addsub_int_operand, + clz_force_nop, + shiftl_copy_flags, + round_copy_flags, + round_enable, + encode_enable, + writeback; + } fpint_op; + + typedef struct packed + { + logic todo; + } mem_op; + + typedef struct packed + { + logic todo; + } sfu_op; + + typedef struct packed + { + logic todo; + } group_op; + + // Q22.10 + typedef logic[9:0] fixed_frac; + typedef logic[$bits(word) - $bits(fixed_frac) - 1:0] fixed_int; + + typedef struct packed signed + { + fixed_int fint; // 'int' es una keyword + fixed_frac frac; + } fixed; + + typedef struct packed + { + fixed x, + y; + } fixed_xy; + + typedef struct packed + { + fixed a, + b, + c; + } vtx_fixed; + + typedef struct packed + { + fixed_xy a, + b, + c; + } vtx_xy; + + localparam int RASTER_BITS = 2; + localparam int RASTER_SUB_BITS = 4; + localparam int RASTER_SIZE = 1 << RASTER_BITS; + localparam int RASTER_COARSE_FRAGS = RASTER_SIZE * RASTER_SIZE; + + typedef logic[RASTER_BITS - 1:0] raster_index; + + // Caso RASTER_BITS = 2: -> 4,4,4,4 -> 8,8-> 16 + localparam int RASTER_OUT_CLZ_DEPTH = 3; + + // Asume RASTER_BITS == 2, hay que ajustarlo si cambia + typedef struct packed + { + // Esto ahorra muchos flops + // + // offsets[0] = inc * 0 = 0 + // offsets[1] = inc * 1 = raster2_times1 + // offsets[2] = inc * 2 = raster2_times1 << 1 + // offsets[3] = inc * 3 = raster2_times3 + fixed raster2_times1, + raster2_times3; + } raster_offsets; + + function fixed raster_idx(raster_offsets offsets, raster_index idx); + unique case (idx) + RASTER_BITS'(0): + return '0; + + RASTER_BITS'(1): + return offsets.raster2_times1; + + RASTER_BITS'(2): + return offsets.raster2_times1 << 1; + + RASTER_BITS'(3): + return offsets.raster2_times3; + endcase + endfunction + + function raster_offsets make_raster_offsets(fixed inc); + make_raster_offsets.raster2_times1 = inc; + make_raster_offsets.raster2_times3 = inc + (inc << 1); + endfunction + + typedef struct packed + { + raster_offsets x, + y; + } raster_offsets_xy; + + typedef struct packed + { + logic[RASTER_SUB_BITS - 1:0] num; + logic[$bits(fixed_frac) - RASTER_SUB_BITS - 1:0] prec; + } raster_sub; + + localparam int RASTER_COARSE_DIM_BITS = $bits(fixed) - $bits(raster_index) - $bits(raster_sub); + + typedef logic signed[RASTER_COARSE_DIM_BITS - 1:0] raster_coarse_dim; + + typedef struct packed + { + raster_coarse_dim x, + y; + } raster_coarse_xy; + + typedef struct packed signed + { + raster_coarse_dim coarse; + raster_index fine; + raster_sub sub; + } raster_prec; + + typedef struct packed + { + raster_prec x, + y; + } raster_prec_xy; + + // Definir el número de lanes a partir de las dimensiones del + // rasterizer es una decisión crucial, el diseño entero depende de esto + + localparam int SHADER_LANES = RASTER_COARSE_FRAGS; + + typedef logic[RASTER_SIZE - 1:0] lane_no; + typedef logic[SHADER_LANES - 1:0] lane_mask; + + typedef logic[5:0] group_id; + + localparam int REGFILE_STAGES = 3; + localparam int REG_READ_STAGES = 2 + REGFILE_STAGES + 1; + + typedef gfx_isa::sgpr_num sgpr_num; + typedef gfx_isa::vgpr_num vgpr_num; + typedef gfx_isa::xgpr_num xgpr_num; + typedef gfx_isa::pc_offset pc_offset; + + typedef struct packed + { + // No incluye p0 porque p0 no tiene señal ready + logic p1, + p2, + p3, + valid; + } shader_dispatch; + + typedef struct + { + group_id group; + xgpr_num dest; + logic dest_scalar; + } wave_exec; + + localparam int FIXED_MULADD_DEPTH = 5; + localparam int FIXED_DOTADD_DEPTH = 2 * FIXED_MULADD_DEPTH; + + localparam word BOOTROM_BASE = 32'h0010_0000; + + localparam int SCHED_BRAM_WORDS = 2048; // 8KiB + + typedef word irq_lines; + +endpackage |
