From a72aaded223f7f31b55e13ff7013959a36a4c375 Mon Sep 17 00:00:00 2001 From: thejayman77 Date: Mon, 20 Jul 2026 21:31:14 -0400 Subject: [PATCH] Add FOG_ENABLE param, prune fog cone on the board profile (fix -6.165ns setup) The fog blend's tex_color*F multiply landed on the texture->color critical path (u_texcache RAM -> u_tex|tex_color -> mult_126 -> raster_pixel_color_q, 46ns, -6.165ns setup). Fog is a proven no-op for the current board scene (96.5% F=255), so pay zero for it here. FOG_ENABLE (default 1, byte-identical fog) added to gs_stub; each fog mux gated (FOG_ENABLE && ras_fge) so FOG_ENABLE=0 constant-folds the entire fog cone away (multiply, FOGCOL adders, s2_fog_f/persp_fog_f5 interp). Threaded through top_psmct32_raster_demo_bram; set FOG_ENABLE(1'b0) on the active GS_SH3_LPDDR_FB board arm (elsif at :1086, the one the QSF profile compiles). Fog stays default-on everywhere else. Verified: FOG_ENABLE=1 fog TBs unchanged PASS; FOG_ENABLE=0 (new tb_gs_fog_disabled + board scene TB) emits raw color = pre-fog datapath; board elaborates clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- rtl/gif_gs/gs_stub.sv | 18 ++- rtl/top/de25_nano_psmct32_raster_demo_top.sv | 6 + rtl/top/top_psmct32_raster_demo_bram.sv | 5 + sim/Makefile | 14 +- sim/tb/gif_gs/tb_gs_fog_disabled.sv | 137 ++++++++++++++++++ .../top/tb_top_psmct32_sh3_zint640_shared.sv | 5 + 6 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 sim/tb/gif_gs/tb_gs_fog_disabled.sv diff --git a/rtl/gif_gs/gs_stub.sv b/rtl/gif_gs/gs_stub.sv index b928609..4378fdf 100644 --- a/rtl/gif_gs/gs_stub.sv +++ b/rtl/gif_gs/gs_stub.sv @@ -450,6 +450,14 @@ module gs_stub // out, so every existing TB / the flat production build is byte-identical // (zero DSP/ALM/M20K cost). Only a perspective demo build sets it 1. parameter bit PERSPECTIVE_CORRECT = 1'b0, + // GS per-vertex FOG compile gate. Default 1 = fog blend active (byte- + // identical to the fog build). 0 = every fog application collapses to the + // pre-fog color at elaboration (FOG_ENABLE is a constant), so the + // synthesizer constant-folds the entire fog cone — the texel*F/color*F + // multiplies, the FOGCOL adders/mux, AND the s2_fog_f / persp_fog_f5 + // interpolation pipes that feed ONLY fog — off the texture->color critical + // path. Set 0 on board profiles whose scene fog is a functional no-op. + parameter bit FOG_ENABLE = 1'b1, // Preserve the low four XYZ2/XYZF2 screen-coordinate bits and evaluate // triangle coverage at the GS 12.4 pixel center. Default off retains the // integer/corner raster contract used by every pre-Ch416 fixture. @@ -5307,7 +5315,7 @@ module gs_stub // consumer (s2_natural_abgr pack, the PSMCT32 emit, the Z-tested emit color) // sees the fogged color. Gated on ras_fge → FGE=0 is byte-identical. logic [63:0] s2_sprite_color64; - assign s2_sprite_color64 = ras_fge + assign s2_sprite_color64 = (FOG_ENABLE && ras_fge) ? {s2_sprite_color64_raw[63:32], fog_blend_abgr(s2_sprite_color64_raw[31:0], s2_fog_f, fogcol_q)} : s2_sprite_color64_raw; @@ -5326,7 +5334,7 @@ module gs_stub // GS per-vertex FOG — blend the post-texture/post-Gouraud RGB toward FOGCOL // when FGE=1 (see the SPRITE note above). Gated → FGE=0 byte-identical. logic [63:0] s2_tri_color64; - assign s2_tri_color64 = ras_fge + assign s2_tri_color64 = (FOG_ENABLE && ras_fge) ? {s2_tri_color64_raw[63:32], fog_blend_abgr(s2_tri_color64_raw[31:0], s2_fog_f, fogcol_q)} : s2_tri_color64_raw; @@ -6982,7 +6990,7 @@ module gs_stub // GS per-vertex FOG — fog the held bilinear-perspective texel // with its captured +5-aligned F. Gated → FGE=0 byte-identical. raster_pixel_color_q <= {32'd0, - ras_fge + (FOG_ENABLE && ras_fge) ? fog_blend_abgr(comb_modulate ? persp_bili_mod_color : s1_tex_color, persp_bili_fog_q, fogcol_q) @@ -7076,7 +7084,7 @@ module gs_stub // GS per-vertex FOG — fog the source RGB BEFORE the blend // when FGE=1 (sprite fog is flat: s2_fog_f == ras_f0). // Source alpha is NOT fogged. FGE=0 → byte-identical. - s3_cs_q <= ras_fge + s3_cs_q <= (FOG_ENABLE && ras_fge) ? {ras_color[63:32], fog_blend_abgr(ras_color[31:0], s2_fog_f, fogcol_q)} : ras_color; @@ -7161,7 +7169,7 @@ module gs_stub // F (persp_fog_f5). Gated on ras_fge → FGE=0 byte-identical // to the pre-fog perspective emit. raster_pixel_color_q <= {32'd0, - ras_fge + (FOG_ENABLE && ras_fge) ? fog_blend_abgr(comb_modulate ? modulated_s1_tex_color : s1_tex_color, persp_fog_f5, fogcol_q) diff --git a/rtl/top/de25_nano_psmct32_raster_demo_top.sv b/rtl/top/de25_nano_psmct32_raster_demo_top.sv index df02bc5..5391443 100644 --- a/rtl/top/de25_nano_psmct32_raster_demo_top.sv +++ b/rtl/top/de25_nano_psmct32_raster_demo_top.sv @@ -1108,6 +1108,12 @@ module de25_nano_psmct32_raster_demo_top ( .BIN_BUFFER_ENABLE (1'b0), .HEARTBEAT_SPLICE_ENABLE (1'b0), .PERSPECTIVE_CORRECT(1'b1), + // GS per-vertex FOG pruned for the board scene: 96.5% of this frame's + // vertices have F=255 (fog is a functional no-op here), so gate it OUT + // to keep the texel*F multiply off the tex-cache->raster_pixel_color + // critical path (recovers the -6.165 ns setup fail). Covers the + // FB/_Z/_640/_SCHED/_MULTI variants, which all share this instance. + .FOG_ENABLE (1'b0), .SUBPIXEL_XY (1'b1), // Ch416 — preserve native XYZ 12.4 and sample pixel centers .PERSP_RECIP_IDX_BITS(11), .BILINEAR_ENABLE (1'b1), diff --git a/rtl/top/top_psmct32_raster_demo_bram.sv b/rtl/top/top_psmct32_raster_demo_bram.sv index d9ca4db..b4637fa 100644 --- a/rtl/top/top_psmct32_raster_demo_bram.sv +++ b/rtl/top/top_psmct32_raster_demo_bram.sv @@ -195,6 +195,10 @@ module top_psmct32_raster_demo_bram // Default 0 generate-guards all perspective logic out (zero cost); only the // GS_PERSP_DEMO board profile sets it 1. parameter bit PERSPECTIVE_CORRECT = 1'b0, + // GS per-vertex FOG compile gate, forwarded to gs_stub. Default 1 (fog + // active). Board profiles whose scene fog is a functional no-op set 0 to + // prune the fog cone off the texture->color critical path. + parameter bit FOG_ENABLE = 1'b1, parameter bit SUBPIXEL_XY = 1'b0, parameter int PERSP_RECIP_IDX_BITS = 8, // Ch351 — perspective reciprocal LUT width (far-W -> 11) parameter int GRAD_DIV_CYCLES = 1, // Ch352 — triangle-setup divide settle cycles (board fits -> 4) @@ -1017,6 +1021,7 @@ module top_psmct32_raster_demo_bram .FB_RD_REGISTERED (1'b1), .Z_RD_REGISTERED (1'b1), .PERSPECTIVE_CORRECT(PERSPECTIVE_CORRECT), // Ch301 — forwarded board param (default 0) + .FOG_ENABLE (FOG_ENABLE), // per-vertex fog gate; 0 prunes the fog cone .SUBPIXEL_XY (SUBPIXEL_XY), // Ch416 — native GS 12.4 coverage (default 0) .PERSP_RECIP_IDX_BITS(PERSP_RECIP_IDX_BITS), // Ch351 — perspective reciprocal LUT width (far-W -> 11) .GRAD_DIV_CYCLES(GRAD_DIV_CYCLES), // Ch352 — triangle-setup divide settle cycles (board -> 4) diff --git a/sim/Makefile b/sim/Makefile index 1d25fad..ba8879d 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -660,7 +660,7 @@ VERILATOR_FLAGS := --lint-only -sv -Wall -Wno-UNUSED -Wno-DECLFILENAME \ tb_ee_core_branch_zero tb_ee_core_lbu tb_ee_core_divu_mflo tb_ee_core_multu_mflo \ tb_ee_core_align tb_ee_core_align_exc tb_ee_core_bev \ tb_ee_core_cop0_count tb_ee_bootstrap_mmio tb_ee_biu_mmio \ - tb_ee_core_gif_packed tb_ee_core_gif_reglist tb_ee_core_gif_primitive tb_ee_core_gif_primitive_observer tb_ee_core_gif_primitive_strip tb_ee_core_gif_primitive_gouraud tb_ee_core_gif_pixel_emit tb_ee_core_gif_pixel_emit_psm tb_ee_core_gif_raster_basic tb_ee_core_gif_raster_topleft tb_ee_core_gif_raster_gouraud tb_ee_core_gif_raster_queue tb_gs_raster_queue_full_pop tb_gs_raster_pipeline tb_gs_prim_list_feeder tb_gs_vram_writeback tb_vram_stub tb_vram_bram_stub_equivalence tb_vram_normalize_write tb_gs_scanout_basic tb_gs_scanout_dbx_dby tb_gs_scanout_display_window tb_gs_scanout_magh_magv tb_gs_scanout_psm16 tb_gs_scanout_psmt8 tb_gs_scanout_psmt8_clut tb_gs_tex0_clut tb_gs_clut_load tb_gs_clut_load_ct16 tb_gs_clut_load_cld_modes tb_gs_clut_load_csa_window tb_gs_scanout_psmt4_clut tb_gs_psmt4_round_trip tb_gs_raster_psmct16 tb_gs_raster_psmt8 tb_gs_textured_sprite tb_gs_textured_alpha_sprite tb_gs_psmt8_alpha_sprite tb_gs_psmt8_clut_triangle tb_clut_loader_csm1 tb_gs_raster_psmct4 tb_gs_demo_psmt4_e2e tb_gs_demo_psmt4_e2e_packed tb_gs_demo_psmt4_e2e_dmac tb_gs_demo_psmt4_e2e_trxdir tb_gs_demo_psmt4_e2e_eemmio tb_gs_demo_psmt4_e2e_eemap tb_gs_demo_psmt4_e2e_ee_program tb_gs_demo_psmt4_e2e_ee_full_bootlet tb_ee_ram_cpu_dmac_contention tb_gs_image_xfer_psmct16 tb_gs_image_xfer_psmt8 tb_gs_image_xfer_psmt4 tb_gs_swizzle_psmct32 tb_gs_swizzle_psmct16 tb_gs_swizzle_psmt8 tb_gs_swizzle_psmt4 tb_gs_scanout_swizzle_psmt4 tb_gs_image_xfer_swizzle_psmt4 tb_gs_raster_swizzle_psmt4 tb_gs_demo_psmt4_swizzle_e2e tb_gs_demo_psmt4_swizzle_trxdir_e2e tb_top_psmct32_raster_demo tb_top_psmct32_textured_demo tb_top_psmct32_raster_demo_bram tb_top_psmct32_raster_demo_bram_textured tb_top_psmct32_raster_demo_bram_ch171 tb_gs_raster_backpressure_stress tb_ps2_hps_bridge tb_gs_raster_bram_psmct16 tb_gs_raster_bram_psmt8 tb_gs_raster_bram_psmt4 tb_gs_scanout_bram_psmct16 tb_gs_scanout_bram_psmt8 tb_de25_nano_psmct32_raster_demo_top tb_hdmi_i2c_wake_smoke tb_gs_scanout_swizzle_psmt8 tb_gs_image_xfer_swizzle_psmt8 tb_gs_raster_swizzle_psmt8 tb_gs_demo_psmt8_swizzle_e2e tb_gs_demo_psmt8_swizzle_trxdir_e2e tb_gs_scanout_swizzle_psmct16 tb_gs_image_xfer_swizzle_psmct16 tb_gs_scanout_swizzle_psmct32 tb_gs_image_xfer_swizzle_psmct32 tb_gs_raster_swizzle_psmct32 tb_gs_raster_swizzle_psmct16 tb_gs_demo_psmct32_swizzle_e2e tb_gs_demo_psmct32_swizzle_trxdir_e2e tb_gs_demo_psmct16_swizzle_e2e tb_gs_demo_psmct16_swizzle_trxdir_e2e tb_ee_core_varshift tb_ee_install_agent_smoke tb_ee_install_agent_external_image tb_tile_ram_cdc tb_sio2_input_stub tb_bridge_iop_pad_input tb_pad_state_via_sif_to_ee tb_ee_pad_buffer_branch tb_lpddr_tex_staging tb_osd_platform_cell_adapter tb_ee_core_elf_runner tb_ee_core_sq tb_ee_core_daddu tb_ee_core_syscall_hle tb_ee_core_beql tb_ee_core_sd tb_ee_core_dsll tb_ee_core_bnel tb_ee_core_pcpyld tb_ee_core_lq tb_ee_core_psubb tb_ee_core_pnor tb_ee_core_pand tb_ee_core_pcpyud tb_ee_core_ld tb_ee_core_ei tb_ee_dmac_ctrl_stub tb_ee_dmac_passive_chan_stub tb_ee_core_sync tb_ee_core_pcpyh tb_ee_core_dsubu tb_gs_async_fifo tb_gs_lpddr_fb_writer tb_gs_lpddr_axi_master tb_gs_lpddr_axi_master_elastic tb_gs_lpddr_scanout_fb tb_gs_lpddr_rd_probe tb_gs_lpddr_scanout tb_gs_lpddr_scanout_psm32 tb_gs_lpddr_scanout_concurrency tb_gs_lpddr_scanout_lb_psm32 tb_gs_lpddr_scanout_lb_psm32_256 tb_gs_lpddr_rd_arb tb_gs_lpddr_scanout_lb tb_gs_texture_cache tb_gs_lpddr_wr_probe tb_gs_lpddr_wr_arb tb_gs_tile_reload tb_gs_tile_reload_grid tb_gs_z_flush_writer tb_gs_alpha_blend tb_top_psmct32_alpha_blend_demo tb_top_psmct32_texalpha_demo tb_gs_zbuffer tb_top_psmct32_zbuffer_demo tb_gs_tri_interp tb_gs_fog tb_gs_fog_persp tb_gs_feeder_fog_e2e tb_top_psmct32_triangle_demo tb_gs_textured_triangle tb_top_psmct32_raster_demo_bram_tritex tb_top_psmct32_raster_demo_bram_lpddrtex tb_gs_texture_psmt8_clut tb_gs_texture_wrap tb_gs_texture_bilinear tb_top_psmct32_raster_demo_bram_clut tb_gs_texture_psmt4_clut tb_gs_texture_swizzle_psmt4_clut tb_top_psmct32_raster_demo_bram_clut4 tb_top_psmct32_raster_demo_bram_swz4 tb_gs_texture_swizzle_psmt8_clut tb_top_psmct32_raster_demo_bram_swz8 tb_gs_texture_swizzle_psmct32 tb_top_psmct32_raster_demo_bram_swz32 tb_gs_reciprocal tb_gs_persp_uv tb_gs_persp_uv_farw tb_gs_grad_divider tb_top_psmct32_perspective_demo tb_top_psmct32_persp_floor_demo tb_top_psmct32_combined_demo tb_gs_tile_ram tb_top_psmct32_tile_demo tb_gs_tile_zflush tb_gs_tile_spill_reload tb_gs_tile_spill_lpddr tb_gs_tile_spill_grid_lpddr tb_gs_tile_spill_grid8x8_lpddr tb_gs_tile_spill_lpddr_neg tb_top_psmct32_tile2x2_demo tb_top_psmct32_tile_multiprim_demo tb_top_psmct32_tile_scissor_demo tb_top_psmct32_tile_wrap_demo tb_top_psmct32_tile_psmct16_demo tb_top_psmct32_tile_alpha_demo tb_top_psmct32_tile_bilinear_demo tb_top_psmct32_tile_bin_demo tb_top_psmct32_tile_bin4x4_demo tb_top_psmct32_tile_psmct16fb_demo tb_top_psmct32_tile_lpddr128_demo tb_top_psmct32_tile_palbilinear_demo tb_top_psmct32_tile_cap_demo tb_top_psmct32_tile_cap_overflow_demo tb_top_psmct32_tile_sprite18_demo tb_top_psmct32_tile_cap64_demo tb_top_psmct32_feeder_equiv_demo tb_top_psmct32_feeder_runtime_demo tb_top_psmct32_feeder_bridge_demo tb_top_psmct32_feeder_scenes_demo tb_top_psmct32_feeder_shapes_demo tb_top_psmct32_feeder_colors_demo tb_top_psmct32_feeder_native_demo tb_top_psmct32_feeder_gouraud_demo tb_top_psmct32_feeder_accum_demo tb_top_psmct32_feeder_scene_retrigger_demo tb_top_psmct32_feeder_zpersist_demo tb_top_psmct32_feeder_persp_demo tb_top_psmct32_feeder_sprite_demo tb_top_psmct32_tile_late_demo tb_top_psmct32_tile_lpddrfb_demo \ + tb_ee_core_gif_packed tb_ee_core_gif_reglist tb_ee_core_gif_primitive tb_ee_core_gif_primitive_observer tb_ee_core_gif_primitive_strip tb_ee_core_gif_primitive_gouraud tb_ee_core_gif_pixel_emit tb_ee_core_gif_pixel_emit_psm tb_ee_core_gif_raster_basic tb_ee_core_gif_raster_topleft tb_ee_core_gif_raster_gouraud tb_ee_core_gif_raster_queue tb_gs_raster_queue_full_pop tb_gs_raster_pipeline tb_gs_prim_list_feeder tb_gs_vram_writeback tb_vram_stub tb_vram_bram_stub_equivalence tb_vram_normalize_write tb_gs_scanout_basic tb_gs_scanout_dbx_dby tb_gs_scanout_display_window tb_gs_scanout_magh_magv tb_gs_scanout_psm16 tb_gs_scanout_psmt8 tb_gs_scanout_psmt8_clut tb_gs_tex0_clut tb_gs_clut_load tb_gs_clut_load_ct16 tb_gs_clut_load_cld_modes tb_gs_clut_load_csa_window tb_gs_scanout_psmt4_clut tb_gs_psmt4_round_trip tb_gs_raster_psmct16 tb_gs_raster_psmt8 tb_gs_textured_sprite tb_gs_textured_alpha_sprite tb_gs_psmt8_alpha_sprite tb_gs_psmt8_clut_triangle tb_clut_loader_csm1 tb_gs_raster_psmct4 tb_gs_demo_psmt4_e2e tb_gs_demo_psmt4_e2e_packed tb_gs_demo_psmt4_e2e_dmac tb_gs_demo_psmt4_e2e_trxdir tb_gs_demo_psmt4_e2e_eemmio tb_gs_demo_psmt4_e2e_eemap tb_gs_demo_psmt4_e2e_ee_program tb_gs_demo_psmt4_e2e_ee_full_bootlet tb_ee_ram_cpu_dmac_contention tb_gs_image_xfer_psmct16 tb_gs_image_xfer_psmt8 tb_gs_image_xfer_psmt4 tb_gs_swizzle_psmct32 tb_gs_swizzle_psmct16 tb_gs_swizzle_psmt8 tb_gs_swizzle_psmt4 tb_gs_scanout_swizzle_psmt4 tb_gs_image_xfer_swizzle_psmt4 tb_gs_raster_swizzle_psmt4 tb_gs_demo_psmt4_swizzle_e2e tb_gs_demo_psmt4_swizzle_trxdir_e2e tb_top_psmct32_raster_demo tb_top_psmct32_textured_demo tb_top_psmct32_raster_demo_bram tb_top_psmct32_raster_demo_bram_textured tb_top_psmct32_raster_demo_bram_ch171 tb_gs_raster_backpressure_stress tb_ps2_hps_bridge tb_gs_raster_bram_psmct16 tb_gs_raster_bram_psmt8 tb_gs_raster_bram_psmt4 tb_gs_scanout_bram_psmct16 tb_gs_scanout_bram_psmt8 tb_de25_nano_psmct32_raster_demo_top tb_hdmi_i2c_wake_smoke tb_gs_scanout_swizzle_psmt8 tb_gs_image_xfer_swizzle_psmt8 tb_gs_raster_swizzle_psmt8 tb_gs_demo_psmt8_swizzle_e2e tb_gs_demo_psmt8_swizzle_trxdir_e2e tb_gs_scanout_swizzle_psmct16 tb_gs_image_xfer_swizzle_psmct16 tb_gs_scanout_swizzle_psmct32 tb_gs_image_xfer_swizzle_psmct32 tb_gs_raster_swizzle_psmct32 tb_gs_raster_swizzle_psmct16 tb_gs_demo_psmct32_swizzle_e2e tb_gs_demo_psmct32_swizzle_trxdir_e2e tb_gs_demo_psmct16_swizzle_e2e tb_gs_demo_psmct16_swizzle_trxdir_e2e tb_ee_core_varshift tb_ee_install_agent_smoke tb_ee_install_agent_external_image tb_tile_ram_cdc tb_sio2_input_stub tb_bridge_iop_pad_input tb_pad_state_via_sif_to_ee tb_ee_pad_buffer_branch tb_lpddr_tex_staging tb_osd_platform_cell_adapter tb_ee_core_elf_runner tb_ee_core_sq tb_ee_core_daddu tb_ee_core_syscall_hle tb_ee_core_beql tb_ee_core_sd tb_ee_core_dsll tb_ee_core_bnel tb_ee_core_pcpyld tb_ee_core_lq tb_ee_core_psubb tb_ee_core_pnor tb_ee_core_pand tb_ee_core_pcpyud tb_ee_core_ld tb_ee_core_ei tb_ee_dmac_ctrl_stub tb_ee_dmac_passive_chan_stub tb_ee_core_sync tb_ee_core_pcpyh tb_ee_core_dsubu tb_gs_async_fifo tb_gs_lpddr_fb_writer tb_gs_lpddr_axi_master tb_gs_lpddr_axi_master_elastic tb_gs_lpddr_scanout_fb tb_gs_lpddr_rd_probe tb_gs_lpddr_scanout tb_gs_lpddr_scanout_psm32 tb_gs_lpddr_scanout_concurrency tb_gs_lpddr_scanout_lb_psm32 tb_gs_lpddr_scanout_lb_psm32_256 tb_gs_lpddr_rd_arb tb_gs_lpddr_scanout_lb tb_gs_texture_cache tb_gs_lpddr_wr_probe tb_gs_lpddr_wr_arb tb_gs_tile_reload tb_gs_tile_reload_grid tb_gs_z_flush_writer tb_gs_alpha_blend tb_top_psmct32_alpha_blend_demo tb_top_psmct32_texalpha_demo tb_gs_zbuffer tb_top_psmct32_zbuffer_demo tb_gs_tri_interp tb_gs_fog tb_gs_fog_persp tb_gs_feeder_fog_e2e tb_gs_fog_disabled tb_top_psmct32_triangle_demo tb_gs_textured_triangle tb_top_psmct32_raster_demo_bram_tritex tb_top_psmct32_raster_demo_bram_lpddrtex tb_gs_texture_psmt8_clut tb_gs_texture_wrap tb_gs_texture_bilinear tb_top_psmct32_raster_demo_bram_clut tb_gs_texture_psmt4_clut tb_gs_texture_swizzle_psmt4_clut tb_top_psmct32_raster_demo_bram_clut4 tb_top_psmct32_raster_demo_bram_swz4 tb_gs_texture_swizzle_psmt8_clut tb_top_psmct32_raster_demo_bram_swz8 tb_gs_texture_swizzle_psmct32 tb_top_psmct32_raster_demo_bram_swz32 tb_gs_reciprocal tb_gs_persp_uv tb_gs_persp_uv_farw tb_gs_grad_divider tb_top_psmct32_perspective_demo tb_top_psmct32_persp_floor_demo tb_top_psmct32_combined_demo tb_gs_tile_ram tb_top_psmct32_tile_demo tb_gs_tile_zflush tb_gs_tile_spill_reload tb_gs_tile_spill_lpddr tb_gs_tile_spill_grid_lpddr tb_gs_tile_spill_grid8x8_lpddr tb_gs_tile_spill_lpddr_neg tb_top_psmct32_tile2x2_demo tb_top_psmct32_tile_multiprim_demo tb_top_psmct32_tile_scissor_demo tb_top_psmct32_tile_wrap_demo tb_top_psmct32_tile_psmct16_demo tb_top_psmct32_tile_alpha_demo tb_top_psmct32_tile_bilinear_demo tb_top_psmct32_tile_bin_demo tb_top_psmct32_tile_bin4x4_demo tb_top_psmct32_tile_psmct16fb_demo tb_top_psmct32_tile_lpddr128_demo tb_top_psmct32_tile_palbilinear_demo tb_top_psmct32_tile_cap_demo tb_top_psmct32_tile_cap_overflow_demo tb_top_psmct32_tile_sprite18_demo tb_top_psmct32_tile_cap64_demo tb_top_psmct32_feeder_equiv_demo tb_top_psmct32_feeder_runtime_demo tb_top_psmct32_feeder_bridge_demo tb_top_psmct32_feeder_scenes_demo tb_top_psmct32_feeder_shapes_demo tb_top_psmct32_feeder_colors_demo tb_top_psmct32_feeder_native_demo tb_top_psmct32_feeder_gouraud_demo tb_top_psmct32_feeder_accum_demo tb_top_psmct32_feeder_scene_retrigger_demo tb_top_psmct32_feeder_zpersist_demo tb_top_psmct32_feeder_persp_demo tb_top_psmct32_feeder_sprite_demo tb_top_psmct32_tile_late_demo tb_top_psmct32_tile_lpddrfb_demo \ dirs all_checks full_checks golden_nop compare_ee_fetch test_compare all: run @@ -1355,6 +1355,16 @@ tb_gs_feeder_fog_e2e: dirs @echo "=== run tb_gs_feeder_fog_e2e ===" @cd $(TRACE_DIR) && $(VVP) $(BUILD_DIR)/tb_gs_feeder_fog_e2e.vvp +# GS per-vertex FOG compile-OUT: gs_stub #(.FOG_ENABLE(0)) prunes fog -> raw color. +tb_gs_fog_disabled: dirs + @echo "=== build tb_gs_fog_disabled ===" + $(IVERILOG) $(IVERILOG_FLGS) \ + -o $(BUILD_DIR)/tb_gs_fog_disabled.vvp \ + -s tb_gs_fog_disabled \ + $(RTL_SRCS) $(TB_ROOT)/gif_gs/tb_gs_fog_disabled.sv + @echo "=== run tb_gs_fog_disabled ===" + @cd $(TRACE_DIR) && $(VVP) $(BUILD_DIR)/tb_gs_fog_disabled.vvp + # Brick 3 — top-level non-axis-aligned triangle demo on the BRAM board path. tb_top_psmct32_triangle_demo: dirs top_psmct32_raster_demo_mem @echo "=== build tb_top_psmct32_triangle_demo ===" @@ -6264,7 +6274,7 @@ run: tb_ee_fetch tb_gs tb_intc tb_platform_video tb_bgcolor_via_dma tb_sif_mailb tb_ee_core_branch_zero tb_ee_core_lbu tb_ee_core_divu_mflo tb_ee_core_multu_mflo \ tb_ee_core_align tb_ee_core_align_exc tb_ee_core_bev \ tb_ee_core_cop0_count tb_ee_bootstrap_mmio tb_ee_biu_mmio \ - tb_ee_core_gif_packed tb_ee_core_gif_reglist tb_ee_core_gif_primitive tb_ee_core_gif_primitive_observer tb_ee_core_gif_primitive_strip tb_ee_core_gif_primitive_gouraud tb_ee_core_gif_pixel_emit tb_ee_core_gif_pixel_emit_psm tb_ee_core_gif_raster_basic tb_ee_core_gif_raster_topleft tb_ee_core_gif_raster_gouraud tb_ee_core_gif_raster_queue tb_gs_raster_queue_full_pop tb_gs_raster_pipeline tb_gs_prim_list_feeder tb_gs_vram_writeback tb_vram_stub tb_vram_bram_stub_equivalence tb_vram_normalize_write tb_gs_scanout_basic tb_gs_scanout_dbx_dby tb_gs_scanout_display_window tb_gs_scanout_magh_magv tb_gs_scanout_psm16 tb_gs_scanout_psmt8 tb_gs_scanout_psmt8_clut tb_gs_tex0_clut tb_gs_clut_load tb_gs_clut_load_ct16 tb_gs_clut_load_cld_modes tb_gs_clut_load_csa_window tb_gs_scanout_psmt4_clut tb_gs_psmt4_round_trip tb_gs_raster_psmct16 tb_gs_raster_psmt8 tb_gs_textured_sprite tb_gs_textured_alpha_sprite tb_gs_psmt8_alpha_sprite tb_gs_psmt8_clut_triangle tb_clut_loader_csm1 tb_gs_raster_psmt4 tb_gs_demo_psmt4_e2e tb_gs_demo_psmt4_e2e_packed tb_gs_demo_psmt4_e2e_dmac tb_gs_demo_psmt4_e2e_trxdir tb_gs_demo_psmt4_e2e_eemmio tb_gs_demo_psmt4_e2e_eemap tb_gs_demo_psmt4_e2e_ee_program tb_gs_demo_psmt4_e2e_ee_full_bootlet tb_ee_ram_cpu_dmac_contention tb_gs_image_xfer_psmct16 tb_gs_image_xfer_psmt8 tb_gs_image_xfer_psmt4 tb_gs_swizzle_psmct32 tb_gs_swizzle_psmct16 tb_gs_swizzle_psmt8 tb_gs_swizzle_psmt4 tb_gs_scanout_swizzle_psmt4 tb_gs_image_xfer_swizzle_psmt4 tb_gs_raster_swizzle_psmt4 tb_gs_demo_psmt4_swizzle_e2e tb_gs_demo_psmt4_swizzle_trxdir_e2e tb_top_psmct32_raster_demo tb_top_psmct32_textured_demo tb_top_psmct32_raster_demo_bram tb_top_psmct32_raster_demo_bram_textured tb_top_psmct32_raster_demo_bram_ch171 tb_gs_raster_backpressure_stress tb_ps2_hps_bridge tb_gs_raster_bram_psmct16 tb_gs_raster_bram_psmt8 tb_gs_raster_bram_psmt4 tb_gs_scanout_bram_psmct16 tb_gs_scanout_bram_psmt8 tb_de25_nano_psmct32_raster_demo_top tb_hdmi_i2c_wake_smoke tb_gs_scanout_swizzle_psmt8 tb_gs_image_xfer_swizzle_psmt8 tb_gs_raster_swizzle_psmt8 tb_gs_demo_psmt8_swizzle_e2e tb_gs_demo_psmt8_swizzle_trxdir_e2e tb_gs_scanout_swizzle_psmct16 tb_gs_image_xfer_swizzle_psmct16 tb_gs_scanout_swizzle_psmct32 tb_gs_image_xfer_swizzle_psmct32 tb_gs_raster_swizzle_psmct32 tb_gs_raster_swizzle_psmct16 tb_gs_demo_psmct32_swizzle_e2e tb_gs_demo_psmct32_swizzle_trxdir_e2e tb_gs_demo_psmct16_swizzle_e2e tb_gs_demo_psmct16_swizzle_trxdir_e2e tb_ee_core_varshift tb_ee_install_agent_smoke tb_ee_install_agent_external_image tb_tile_ram_cdc tb_sio2_input_stub tb_bridge_iop_pad_input tb_pad_state_via_sif_to_ee tb_ee_pad_buffer_branch tb_lpddr_tex_staging tb_osd_platform_cell_adapter tb_ee_core_elf_runner tb_ee_core_sq tb_ee_core_daddu tb_ee_core_syscall_hle tb_ee_core_beql tb_ee_core_sd tb_ee_core_dsll tb_ee_core_bnel tb_ee_core_pcpyld tb_ee_core_lq tb_ee_core_psubb tb_ee_core_pnor tb_ee_core_pand tb_ee_core_pcpyud tb_ee_core_ld tb_ee_core_ei tb_ee_dmac_ctrl_stub tb_ee_dmac_passive_chan_stub tb_ee_core_sync tb_ee_core_pcpyh tb_ee_core_dsubu tb_gs_async_fifo tb_gs_lpddr_fb_writer tb_gs_lpddr_axi_master tb_gs_lpddr_axi_master_elastic tb_gs_lpddr_scanout_fb tb_gs_lpddr_rd_probe tb_gs_lpddr_scanout tb_gs_lpddr_scanout_psm32 tb_gs_lpddr_scanout_concurrency tb_gs_lpddr_scanout_lb_psm32 tb_gs_lpddr_scanout_lb_psm32_256 tb_gs_lpddr_rd_arb tb_gs_lpddr_scanout_lb tb_gs_texture_cache tb_gs_lpddr_wr_probe tb_gs_lpddr_wr_arb tb_gs_tile_reload tb_gs_tile_reload_grid tb_gs_z_flush_writer tb_gs_alpha_blend tb_top_psmct32_alpha_blend_demo tb_top_psmct32_texalpha_demo tb_gs_zbuffer tb_top_psmct32_zbuffer_demo tb_gs_tri_interp tb_gs_fog tb_gs_fog_persp tb_gs_feeder_fog_e2e tb_top_psmct32_triangle_demo tb_gs_textured_triangle tb_top_psmct32_raster_demo_bram_tritex tb_top_psmct32_raster_demo_bram_lpddrtex tb_gs_texture_psmt8_clut tb_gs_texture_wrap tb_gs_texture_bilinear tb_top_psmct32_raster_demo_bram_clut tb_gs_texture_psmt4_clut tb_gs_texture_swizzle_psmt4_clut tb_top_psmct32_raster_demo_bram_clut4 tb_top_psmct32_raster_demo_bram_swz4 tb_gs_texture_swizzle_psmt8_clut tb_top_psmct32_raster_demo_bram_swz8 tb_gs_texture_swizzle_psmct32 tb_top_psmct32_raster_demo_bram_swz32 tb_gs_reciprocal tb_gs_persp_uv tb_gs_persp_uv_farw tb_gs_grad_divider tb_top_psmct32_perspective_demo tb_top_psmct32_persp_floor_demo tb_top_psmct32_combined_demo tb_gs_tile_ram tb_top_psmct32_tile_demo tb_gs_tile_zflush tb_gs_tile_spill_reload tb_gs_tile_spill_lpddr tb_gs_tile_spill_grid_lpddr tb_gs_tile_spill_grid8x8_lpddr tb_gs_tile_spill_lpddr_neg tb_top_psmct32_tile2x2_demo tb_top_psmct32_tile_multiprim_demo tb_top_psmct32_tile_scissor_demo tb_top_psmct32_tile_wrap_demo tb_top_psmct32_tile_psmct16_demo tb_top_psmct32_tile_alpha_demo tb_top_psmct32_tile_bilinear_demo tb_top_psmct32_tile_bin_demo tb_top_psmct32_tile_bin4x4_demo tb_top_psmct32_tile_psmct16fb_demo tb_top_psmct32_tile_lpddr128_demo tb_top_psmct32_tile_palbilinear_demo tb_top_psmct32_tile_cap_demo tb_top_psmct32_tile_cap_overflow_demo tb_top_psmct32_tile_sprite18_demo tb_top_psmct32_tile_cap64_demo tb_top_psmct32_feeder_equiv_demo tb_top_psmct32_feeder_runtime_demo tb_top_psmct32_feeder_bridge_demo tb_top_psmct32_feeder_scenes_demo tb_top_psmct32_feeder_shapes_demo tb_top_psmct32_feeder_colors_demo tb_top_psmct32_feeder_native_demo tb_top_psmct32_feeder_gouraud_demo tb_top_psmct32_feeder_accum_demo tb_top_psmct32_feeder_scene_retrigger_demo tb_top_psmct32_feeder_zpersist_demo tb_top_psmct32_feeder_persp_demo tb_top_psmct32_feeder_sprite_demo tb_top_psmct32_tile_late_demo tb_top_psmct32_tile_lpddrfb_demo + tb_ee_core_gif_packed tb_ee_core_gif_reglist tb_ee_core_gif_primitive tb_ee_core_gif_primitive_observer tb_ee_core_gif_primitive_strip tb_ee_core_gif_primitive_gouraud tb_ee_core_gif_pixel_emit tb_ee_core_gif_pixel_emit_psm tb_ee_core_gif_raster_basic tb_ee_core_gif_raster_topleft tb_ee_core_gif_raster_gouraud tb_ee_core_gif_raster_queue tb_gs_raster_queue_full_pop tb_gs_raster_pipeline tb_gs_prim_list_feeder tb_gs_vram_writeback tb_vram_stub tb_vram_bram_stub_equivalence tb_vram_normalize_write tb_gs_scanout_basic tb_gs_scanout_dbx_dby tb_gs_scanout_display_window tb_gs_scanout_magh_magv tb_gs_scanout_psm16 tb_gs_scanout_psmt8 tb_gs_scanout_psmt8_clut tb_gs_tex0_clut tb_gs_clut_load tb_gs_clut_load_ct16 tb_gs_clut_load_cld_modes tb_gs_clut_load_csa_window tb_gs_scanout_psmt4_clut tb_gs_psmt4_round_trip tb_gs_raster_psmct16 tb_gs_raster_psmt8 tb_gs_textured_sprite tb_gs_textured_alpha_sprite tb_gs_psmt8_alpha_sprite tb_gs_psmt8_clut_triangle tb_clut_loader_csm1 tb_gs_raster_psmt4 tb_gs_demo_psmt4_e2e tb_gs_demo_psmt4_e2e_packed tb_gs_demo_psmt4_e2e_dmac tb_gs_demo_psmt4_e2e_trxdir tb_gs_demo_psmt4_e2e_eemmio tb_gs_demo_psmt4_e2e_eemap tb_gs_demo_psmt4_e2e_ee_program tb_gs_demo_psmt4_e2e_ee_full_bootlet tb_ee_ram_cpu_dmac_contention tb_gs_image_xfer_psmct16 tb_gs_image_xfer_psmt8 tb_gs_image_xfer_psmt4 tb_gs_swizzle_psmct32 tb_gs_swizzle_psmct16 tb_gs_swizzle_psmt8 tb_gs_swizzle_psmt4 tb_gs_scanout_swizzle_psmt4 tb_gs_image_xfer_swizzle_psmt4 tb_gs_raster_swizzle_psmt4 tb_gs_demo_psmt4_swizzle_e2e tb_gs_demo_psmt4_swizzle_trxdir_e2e tb_top_psmct32_raster_demo tb_top_psmct32_textured_demo tb_top_psmct32_raster_demo_bram tb_top_psmct32_raster_demo_bram_textured tb_top_psmct32_raster_demo_bram_ch171 tb_gs_raster_backpressure_stress tb_ps2_hps_bridge tb_gs_raster_bram_psmct16 tb_gs_raster_bram_psmt8 tb_gs_raster_bram_psmt4 tb_gs_scanout_bram_psmct16 tb_gs_scanout_bram_psmt8 tb_de25_nano_psmct32_raster_demo_top tb_hdmi_i2c_wake_smoke tb_gs_scanout_swizzle_psmt8 tb_gs_image_xfer_swizzle_psmt8 tb_gs_raster_swizzle_psmt8 tb_gs_demo_psmt8_swizzle_e2e tb_gs_demo_psmt8_swizzle_trxdir_e2e tb_gs_scanout_swizzle_psmct16 tb_gs_image_xfer_swizzle_psmct16 tb_gs_scanout_swizzle_psmct32 tb_gs_image_xfer_swizzle_psmct32 tb_gs_raster_swizzle_psmct32 tb_gs_raster_swizzle_psmct16 tb_gs_demo_psmct32_swizzle_e2e tb_gs_demo_psmct32_swizzle_trxdir_e2e tb_gs_demo_psmct16_swizzle_e2e tb_gs_demo_psmct16_swizzle_trxdir_e2e tb_ee_core_varshift tb_ee_install_agent_smoke tb_ee_install_agent_external_image tb_tile_ram_cdc tb_sio2_input_stub tb_bridge_iop_pad_input tb_pad_state_via_sif_to_ee tb_ee_pad_buffer_branch tb_lpddr_tex_staging tb_osd_platform_cell_adapter tb_ee_core_elf_runner tb_ee_core_sq tb_ee_core_daddu tb_ee_core_syscall_hle tb_ee_core_beql tb_ee_core_sd tb_ee_core_dsll tb_ee_core_bnel tb_ee_core_pcpyld tb_ee_core_lq tb_ee_core_psubb tb_ee_core_pnor tb_ee_core_pand tb_ee_core_pcpyud tb_ee_core_ld tb_ee_core_ei tb_ee_dmac_ctrl_stub tb_ee_dmac_passive_chan_stub tb_ee_core_sync tb_ee_core_pcpyh tb_ee_core_dsubu tb_gs_async_fifo tb_gs_lpddr_fb_writer tb_gs_lpddr_axi_master tb_gs_lpddr_axi_master_elastic tb_gs_lpddr_scanout_fb tb_gs_lpddr_rd_probe tb_gs_lpddr_scanout tb_gs_lpddr_scanout_psm32 tb_gs_lpddr_scanout_concurrency tb_gs_lpddr_scanout_lb_psm32 tb_gs_lpddr_scanout_lb_psm32_256 tb_gs_lpddr_rd_arb tb_gs_lpddr_scanout_lb tb_gs_texture_cache tb_gs_lpddr_wr_probe tb_gs_lpddr_wr_arb tb_gs_tile_reload tb_gs_tile_reload_grid tb_gs_z_flush_writer tb_gs_alpha_blend tb_top_psmct32_alpha_blend_demo tb_top_psmct32_texalpha_demo tb_gs_zbuffer tb_top_psmct32_zbuffer_demo tb_gs_tri_interp tb_gs_fog tb_gs_fog_persp tb_gs_feeder_fog_e2e tb_gs_fog_disabled tb_top_psmct32_triangle_demo tb_gs_textured_triangle tb_top_psmct32_raster_demo_bram_tritex tb_top_psmct32_raster_demo_bram_lpddrtex tb_gs_texture_psmt8_clut tb_gs_texture_wrap tb_gs_texture_bilinear tb_top_psmct32_raster_demo_bram_clut tb_gs_texture_psmt4_clut tb_gs_texture_swizzle_psmt4_clut tb_top_psmct32_raster_demo_bram_clut4 tb_top_psmct32_raster_demo_bram_swz4 tb_gs_texture_swizzle_psmt8_clut tb_top_psmct32_raster_demo_bram_swz8 tb_gs_texture_swizzle_psmct32 tb_top_psmct32_raster_demo_bram_swz32 tb_gs_reciprocal tb_gs_persp_uv tb_gs_persp_uv_farw tb_gs_grad_divider tb_top_psmct32_perspective_demo tb_top_psmct32_persp_floor_demo tb_top_psmct32_combined_demo tb_gs_tile_ram tb_top_psmct32_tile_demo tb_gs_tile_zflush tb_gs_tile_spill_reload tb_gs_tile_spill_lpddr tb_gs_tile_spill_grid_lpddr tb_gs_tile_spill_grid8x8_lpddr tb_gs_tile_spill_lpddr_neg tb_top_psmct32_tile2x2_demo tb_top_psmct32_tile_multiprim_demo tb_top_psmct32_tile_scissor_demo tb_top_psmct32_tile_wrap_demo tb_top_psmct32_tile_psmct16_demo tb_top_psmct32_tile_alpha_demo tb_top_psmct32_tile_bilinear_demo tb_top_psmct32_tile_bin_demo tb_top_psmct32_tile_bin4x4_demo tb_top_psmct32_tile_psmct16fb_demo tb_top_psmct32_tile_lpddr128_demo tb_top_psmct32_tile_palbilinear_demo tb_top_psmct32_tile_cap_demo tb_top_psmct32_tile_cap_overflow_demo tb_top_psmct32_tile_sprite18_demo tb_top_psmct32_tile_cap64_demo tb_top_psmct32_feeder_equiv_demo tb_top_psmct32_feeder_runtime_demo tb_top_psmct32_feeder_bridge_demo tb_top_psmct32_feeder_scenes_demo tb_top_psmct32_feeder_shapes_demo tb_top_psmct32_feeder_colors_demo tb_top_psmct32_feeder_native_demo tb_top_psmct32_feeder_gouraud_demo tb_top_psmct32_feeder_accum_demo tb_top_psmct32_feeder_scene_retrigger_demo tb_top_psmct32_feeder_zpersist_demo tb_top_psmct32_feeder_persp_demo tb_top_psmct32_feeder_sprite_demo tb_top_psmct32_tile_late_demo tb_top_psmct32_tile_lpddrfb_demo @echo @echo "=== all testbenches complete ===" diff --git a/sim/tb/gif_gs/tb_gs_fog_disabled.sv b/sim/tb/gif_gs/tb_gs_fog_disabled.sv new file mode 100644 index 0000000..651f2ae --- /dev/null +++ b/sim/tb/gif_gs/tb_gs_fog_disabled.sv @@ -0,0 +1,137 @@ +// retroDE_ps2 — tb_gs_fog_disabled +// +// Proves the FOG_ENABLE=0 compile gate: with gs_stub #(.FOG_ENABLE(1'b0)), +// a PRIM.FGE=1 primitive carrying real per-vertex fog + a nonzero FOGCOL emits +// the RAW (unfogged) post-texture/Gouraud color. Because FOG_ENABLE is a param +// constant, `(FOG_ENABLE && ras_fge)` folds to 0 and each fog mux selects the +// raw color — the exact pre-fog datapath the synthesizer keeps (fog cone, +// including s2_fog_f, pruned). Functional equivalence to the raw color here is +// the observable proof that the fold target is the pre-fog path. + +`timescale 1ns/1ps + +module tb_gs_fog_disabled; + logic clk; logic rst_n; + initial clk = 1'b0; always #5 clk = ~clk; + + logic gif_reg_wr_en; logic [7:0] gif_reg_num; logic [63:0] gif_reg_data; + logic [7:0] bg_r, bg_g, bg_b; + logic [63:0] prim_q, rgbaq_q, xyz2_q, xyzf2_q, frame_1_q, zbuf_1_q; + logic prim_complete; logic [31:0] prim_complete_count; + logic [63:0] prim_v0_q, prim_v1_q, prim_v2_q, prim_color_q; + logic [63:0] prim_color_v0_q, prim_color_v1_q, prim_color_v2_q; + trace_pkg::vertex_t prim_v0_decoded_q, prim_v1_decoded_q, prim_v2_decoded_q; + trace_pkg::color_t prim_v0_color_decoded_q, prim_v1_color_decoded_q, prim_v2_color_decoded_q; + logic pixel_emit; logic [31:0] pixel_emit_count; + logic [11:0] pixel_x_q, pixel_y_q; logic [63:0] pixel_color_q; + logic [8:0] pixel_fbp_q; logic [5:0] pixel_fbw_q, pixel_psm_q; logic [31:0] pixel_fb_addr_q; + logic raster_pixel_emit; logic [31:0] raster_pixel_emit_count; + logic [11:0] raster_pixel_x_q, raster_pixel_y_q; logic [63:0] raster_pixel_color_q; + logic [31:0] raster_pixel_fb_addr_q; logic [3:0] raster_pixel_be_q; + logic [31:0] raster_pixel_mask_q; logic [5:0] raster_pixel_psm_q; + logic raster_active, raster_overflow, raster_fifo_full, raster_degenerate; + logic tex_rd_en; logic [31:0] tex_rd_addr; + logic fb_rd_en; logic [31:0] fb_rd_addr; + logic z_rd_en; logic [31:0] z_rd_addr; + logic ev_valid; trace_pkg::subsys_e ev_subsys; trace_pkg::event_e ev_event; + logic [63:0] ev_arg0, ev_arg1, ev_arg2, ev_arg3; logic [31:0] ev_flags; + + // Fog compiled OUT. + gs_stub #(.FOG_ENABLE(1'b0)) u_gs ( + .clk(clk), .rst_n(rst_n), + .reg_wr_en(1'b0), .reg_wr_addr(16'd0), .reg_wr_data(64'd0), + .gif_reg_wr_en(gif_reg_wr_en), .gif_reg_num(gif_reg_num), .gif_reg_data(gif_reg_data), + .bg_r(bg_r), .bg_g(bg_g), .bg_b(bg_b), + .prim_q(prim_q), .rgbaq_q(rgbaq_q), .xyz2_q(xyz2_q), .xyzf2_q(xyzf2_q), + .frame_1_q(frame_1_q), .zbuf_1_q(zbuf_1_q), + .prim_complete(prim_complete), .prim_complete_count(prim_complete_count), + .prim_v0_q(prim_v0_q), .prim_v1_q(prim_v1_q), .prim_v2_q(prim_v2_q), .prim_color_q(prim_color_q), + .prim_color_v0_q(prim_color_v0_q), .prim_color_v1_q(prim_color_v1_q), .prim_color_v2_q(prim_color_v2_q), + .prim_v0_decoded_q(prim_v0_decoded_q), .prim_v1_decoded_q(prim_v1_decoded_q), .prim_v2_decoded_q(prim_v2_decoded_q), + .prim_v0_color_decoded_q(prim_v0_color_decoded_q), .prim_v1_color_decoded_q(prim_v1_color_decoded_q), .prim_v2_color_decoded_q(prim_v2_color_decoded_q), + .pixel_emit(pixel_emit), .pixel_emit_count(pixel_emit_count), + .pixel_x_q(pixel_x_q), .pixel_y_q(pixel_y_q), .pixel_color_q(pixel_color_q), + .pixel_fbp_q(pixel_fbp_q), .pixel_fbw_q(pixel_fbw_q), .pixel_psm_q(pixel_psm_q), .pixel_fb_addr_q(pixel_fb_addr_q), + .raster_pixel_emit(raster_pixel_emit), .raster_pixel_emit_count(raster_pixel_emit_count), + .raster_pixel_x_q(raster_pixel_x_q), .raster_pixel_y_q(raster_pixel_y_q), .raster_pixel_color_q(raster_pixel_color_q), + .raster_pixel_fb_addr_q(raster_pixel_fb_addr_q), .raster_pixel_be_q(raster_pixel_be_q), + .raster_pixel_mask_q(raster_pixel_mask_q), .raster_pixel_psm_q(raster_pixel_psm_q), + .raster_active(raster_active), .raster_overflow(raster_overflow), + .raster_fifo_full(raster_fifo_full), .raster_degenerate(raster_degenerate), + .tex_rd_en(tex_rd_en), .tex_rd_addr(tex_rd_addr), .tex_rd_data(32'd0), + .fb_rd_en(fb_rd_en), .fb_rd_addr(fb_rd_addr), .fb_rd_data(32'd0), + .z_rd_en(z_rd_en), .z_rd_addr(z_rd_addr), .z_rd_data(32'd0), + .ev_valid(ev_valid), .ev_subsys(ev_subsys), .ev_event(ev_event), + .ev_arg0(ev_arg0), .ev_arg1(ev_arg1), .ev_arg2(ev_arg2), .ev_arg3(ev_arg3), .ev_flags(ev_flags)); + + task automatic drive_reg(input logic [7:0] num, input logic [63:0] data); + @(negedge clk); gif_reg_wr_en=1'b1; gif_reg_num=num; gif_reg_data=data; @(posedge clk); + endtask + task automatic drive_idle(); + @(negedge clk); gif_reg_wr_en=1'b0; gif_reg_num=8'd0; gif_reg_data=64'd0; @(posedge clk); + endtask + function automatic logic [63:0] xyzf2(input int x, input int y, input int f); + return {8'(f), 24'd0, 12'(y), 4'd0, 12'(x), 4'd0}; + endfunction + function automatic logic [63:0] rgbaq(input int r, input int g, input int b, input int a); + return {32'd0, 8'(a), 8'(b), 8'(g), 8'(r)}; + endfunction + + localparam logic [7:0] R_PRIM=8'h00, R_RGBAQ=8'h01, R_XYZF2=8'h04, R_FOGCOL=8'h3D, R_FRAME_1=8'h4C; + localparam logic [63:0] PRIM_TRI_FGE = 64'd3 | (64'd1<<5); + localparam logic [63:0] FRAME_1_VAL = 64'h0000_0000_0001_0000; + localparam int TC_R=8'hC0, TC_G=8'h80, TC_B=8'h30, TC_A=8'hFF; + + bit covered [0:15][0:15]; + logic [31:0] cap_c [0:15][0:15]; + bit cap_armed; + always_ff @(posedge clk) if (rst_n && cap_armed && raster_pixel_emit + && raster_pixel_x_q < 16 && raster_pixel_y_q < 16) begin + covered[raster_pixel_y_q][raster_pixel_x_q] <= 1'b1; + cap_c [raster_pixel_y_q][raster_pixel_x_q] <= raster_pixel_color_q[31:0]; + end + + int errors, checks; + task automatic chk_raw(input int x, input int y); + // With FOG_ENABLE=0, even FGE=1 + FOGCOL!=0 must emit the RAW flat color. + if (!covered[y][x]) begin $error("[fogoff] (%0d,%0d) not covered", x, y); errors++; end + else if (cap_c[y][x][7:0]!==TC_R[7:0] || cap_c[y][x][15:8]!==TC_G[7:0] || + cap_c[y][x][23:16]!==TC_B[7:0] || cap_c[y][x][31:24]!==TC_A[7:0]) begin + $error("[fogoff] (%0d,%0d) got %08x expected RAW (%0d,%0d,%0d,a=%0d) — fog NOT pruned", + x, y, cap_c[y][x], TC_R, TC_G, TC_B, TC_A); errors++; + end else begin + $display("[fogoff] (%0d,%0d) RAW color (fog pruned) OK", x, y); checks++; + end + endtask + + initial begin + errors=0; checks=0; cap_armed=0; + for (int y=0;y<16;y++) for (int x=0;x<16;x++) begin covered[y][x]=0; cap_c[y][x]=0; end + rst_n=0; gif_reg_wr_en=0; gif_reg_num=0; gif_reg_data=0; + repeat(4) @(posedge clk); rst_n=1; repeat(2) @(posedge clk); + + // FGE=1 triangle with DISTINCT per-vertex F and a NONZERO FOGCOL: if fog + // were active these would be visibly blended; with FOG_ENABLE=0 they are not. + cap_armed=1; + drive_reg(R_FOGCOL, 64'h00_60_40_20); // nonzero FOGCOL (would change pixels if fog on) + drive_reg(R_PRIM, PRIM_TRI_FGE); + drive_reg(R_FRAME_1, FRAME_1_VAL); + drive_reg(R_RGBAQ, rgbaq(TC_R,TC_G,TC_B,TC_A)); + drive_reg(R_XYZF2, xyzf2(2,1,8'h10)); + drive_reg(R_RGBAQ, rgbaq(TC_R,TC_G,TC_B,TC_A)); + drive_reg(R_XYZF2, xyzf2(13,2,8'hF0)); + drive_reg(R_RGBAQ, rgbaq(TC_R,TC_G,TC_B,TC_A)); + drive_reg(R_XYZF2, xyzf2(5,7,8'h80)); // closes + drive_idle(); + repeat(300) @(posedge clk); cap_armed=0; @(posedge clk); + + chk_raw(7,3); chk_raw(5,4); chk_raw(6,2); + if (checks==0) begin $error("[fogoff] no interior pixels verified"); errors++; end + + $display("[tb_gs_fog_disabled] checks=%0d errors=%0d", checks, errors); + if (errors==0) $display("[tb_gs_fog_disabled] PASS"); + else $display("[tb_gs_fog_disabled] FAIL"); + $finish; + end + initial begin #3000000; $error("[tb_gs_fog_disabled] timeout"); $finish; end +endmodule : tb_gs_fog_disabled diff --git a/sim/tb/top/tb_top_psmct32_sh3_zint640_shared.sv b/sim/tb/top/tb_top_psmct32_sh3_zint640_shared.sv index de83c35..0b20114 100644 --- a/sim/tb/top/tb_top_psmct32_sh3_zint640_shared.sv +++ b/sim/tb/top/tb_top_psmct32_sh3_zint640_shared.sv @@ -116,6 +116,11 @@ module tb_top_psmct32_sh3_zint640_shared; .BIN_BUFFER_ENABLE(1'b0), .HEARTBEAT_SPLICE_ENABLE(1'b0), .FEEDER_ENABLE(1'b1), .FEEDER_STG_WORDS(STG_WORDS), .FEEDER_AUTOSTART(1'b0), .PERSPECTIVE_CORRECT(1'b1), .PERSP_RECIP_IDX_BITS(`SH3_SHARED_RECIP_BITS), + // Mirror the fitted board config: the GS_SH3_LPDDR_FB profile prunes + // per-vertex fog (FOG_ENABLE=0) to keep the texel*F multiply off the + // texture->color critical path. With fog pruned the scene must match the + // non-fog reference this scoreboard already checks. + .FOG_ENABLE(1'b0), `ifdef SH3_SUBPIXEL_XY .SUBPIXEL_XY(1'b1), `endif