# zr_pixel8 mutants: NAME<TAB>class<TAB>sed expression.  class: req = must FAIL the gate | perf = performance-only,
# reported | keep = must PASS (a property: the prefetch hint cannot change a pixel)
# MEASURED 2026-09-22 (synthetic 12 frames + attract 3 frames, hostile memory + hostile read-during-write RAM):
# 34 req killed, P1 P2 N14 kept. Classifications that differ from the first guess, each with its reason:
#   H3 req  -- was perf-only in v3-v7; under the hostile RAM model a 1-clock replay re-reads the entry in the clock
#              its fill is written, sees the collision as a miss, refills, and livelocks (hang). Load-bearing now.
#   N3 perf -- REDUNDANT BY CONSTRUCTION: S4 blocks the whole pipe, so at most the pixels in S2..S4 (4) have a read
#              in flight; the CRMAX guard can never fire. (Also the measured limit on destination-read hiding.)
#   N8 perf -- MAME-UNREACHABLE on MK4: every vertex's intensity field is the constant 65535.0 (zeus_draw_quad; zr_front
#              vfield f=5), so s1_i >= 0 and i8 == 255 always; the sign is never observable. Not chased (internal validation notes s7).
#   N14 keep -- a line is identified by (set, tag); WHICH bank holds it cannot change any texel. A property.
# ---- carried from v7 (same rules, v8 text) ----
H1	req	s/                                (dp_pend \&\& dp_pix == px.da);/                                1'b0;/
H2	req	s/ || (s3_ok \&\& s3_da == px.da) ||/ ||/
H3	req	s/fill_on <= 1'b0; rp_cnt <= 2'd2;/fill_on <= 1'b0; rp_cnt <= 2'd1;/
H4	req	s/for (int j = 0; j < 4; j++) pp\[j\] = s3_fresh ? pal_q\[j\] : s3_pal\[j\];/for (int j = 0; j < 4; j++) pp[j] = pal_q[j];/
H5	req	s/      if (pal_pend \&\& !s1_ok \&\& !s2_ok \&\& !(s3_ok \&\& s3_fresh)) begin/      if (pal_pend) begin/
H6	req	s/    return {by\[0\], bx\[0\]};/    return {1'b0, bx[0]};/
H8	req	s/s3_i8 <= s2_i8; s3_o <= s2_o;/s3_i8 <= s2_i8; s3_o <= m_obj;/
H9	req	s/ (s4_ok \&\& s4_da == px.da) ||/ /
A1	req	s/    th = top\[17:1\]; bh = bot\[17:1\];/    th = top[17:1]; bh = bot[16:0];/
A2	req	s/(s1_depth >= 0 \&\& s1_depth <= \$signed/(s1_depth >= 0 \&\& s1_depth < $signed/
W1	req	s/s4_ok <= 1'b1; s4_write <= s3b_write;/s4_ok <= 1'b1; s4_write <= 1'b1;/
W2	req	s/s4_sr <= src_r; s4_sg <= src_g; s4_sb <= src_b;/s4_sr <= src_r; s4_sg <= src_r; s4_sb <= src_b;/
V1	req	s/    return 18'({c0, 8'd0}) + 18'(unsigned'(20'(d) \* 20'(fup)));/    return 18'({c1, 8'd0}) + 18'(unsigned'(20'(d) * 20'(fup)));/
V2	req	s/    v  = 28'({th, 8'd0}) + 28'(d) \* 28'(fvp);/    v  = 28'({bh, 8'd0}) + 28'(d) * 28'(fvp);/
V4	req	s/    fa = (s4_o.bm == 3'd1) ? 32'd255 : (s4_o.bm == 3'd5) ? 32'({sa, 1'b0}) : 32'(sa);/    fa = (s4_o.bm == 3'd1) ? 32'd255 : 32'(sa);/
B1	req	s/          for (int c = 0; c < 3; c++) begin s3b_top\[c\] <= u_top\[c\]; s3b_bot\[c\] <= u_bot\[c\];/          for (int c = 0; c < 3; c++) begin s3b_top[c] <= u_bot[c]; s3b_bot[c] <= u_top[c];/
B2	req	s/(s3b_ok \&\& s3b_da == px.da) || //
B3	req	s/s3b_i8 <= s3_i8; s3b_o <= s3_o; s3b_fv <= s3_fv;/s3b_i8 <= s3_i8; s3b_o <= s3_o; s3b_fv <= s3_fu;/
C1	req	s/ (s5_ok \&\& s5_da == px.da) ||//
C2	req	s/s5_ok <= 1'b1; s5_write <= s4_write;/s5_ok <= 1'b1; s5_write <= 1'b1;/
C3	req	s/(o_blend == ADD1) ? 3'd3 :/(o_blend == ADD1) ? 3'd4 :/
C4	req	s/    xr_in.o.rdst = (o_blend \& 32'h00800000) != 0;/    xr_in.o.rdst = 1'b0;/
C5	req	s/(sdiv(ty, 1) <<< (l2 + 4'd1))/(sdiv(ty, 1) <<< (l2 + 4'd2))/
# ---- v8: the latency-tolerant front ----
#   N1 destination read ignores a posted colour write to its word    N2 cache read-during-write collision trusted
#   N3 more reads in flight than the response FIFO holds             N4 a new read overwrites an ungranted request
#   N5 S4 pops the response at advance but does not keep it          N6 first pixel of an extent uses the old object
#   N7 depth record loses the sign                                   N8 intensity record zero-extended
#   N9 texel nibble column not flipped for the right-hand texels     N10 palette word select from the live address
#   N11 first pixel issued while its palette is not loaded           N12 generator loads the next extent mid-extent
#   N13 palette response written one line early                      N14 prefetched line written into the wrong bank
N1	req	s/ || (cw_valid \&\& cw_addr == (s1_craddr \& ~32'd3))//
N2	req	s/ \&\& !tc_col\[s1_bank\[k\]\];/;/
N3	perf	s/ || cr_out >= 4'(CRMAX)//
N4	req	s/((crr_v \&\& !cr_gnt) || /((1'b0) || /
N5	req	s/          if (s3b_write \&\& s3b_o.rdst \&\& crq_v) begin s4_dst <= crq_d; s4_dst_have <= 1'b1; end//
N6	req	s/    cur_o = px.first ? xr.o : m_obj;/    cur_o = m_obj;/
N7	req	s/s1_depth <= {{16{px.dneg}}, px.d};/s1_depth <= {16'd0, px.d};/
N9	req	s/s1_col\[k\] <= px.col ^ k\[0\];/s1_col[k] <= px.col;/
N10	req	s/pal_q\[k\] = pal_q64\[k\]\[16\*pal_sel\[k\] +: 16\];/pal_q[k] = pal_q64[k][16*pal_ri[k][1:0] +: 16];/
N11	req	s/ \&\& !pl_on \&\& !pal_pend \&\& !needpal;/ \&\& !pl_on \&\& !pal_pend;/
N12	req	s/  assign ext_ready = (!g_on || g_last)/  assign ext_ready = (!g_on || g_adv)/
N13	req	s/pal_we <= 1'b1; pal_wi <= pl_rcv;/pal_we <= 1'b1; pal_wi <= pl_rcv - 6'd1;/
N14	keep	s/w0r_kind <= K_PF; w0r_bank <= pfq_d\[1:0\];/w0r_kind <= K_PF; w0r_bank <= ~pfq_d[1:0];/
# ---- properties ----
#   P1 the prefetcher's private tags are corrupted (every hint wrong): output must NOT change
#   P2 the prefetcher never issues: output must NOT change (only speed)
P1	keep	s/pt_wd\[g1_bank\[g1_k\]\] = {1'b1, g1_line\[g1_k\]\[20:9\]};/pt_wd[g1_bank[g1_k]] = {1'b1, ~g1_line[g1_k][20:9]};/
P2	keep	s/g1_mask\[k\] = !g1_solid \&\& !dup/g1_mask[k] = 1'b0 \&\& !dup/
I1	req	s/ ? 32'd255 : (s4_o.bm == 3'd5)/ ? 32'd254 : (s4_o.bm == 3'd5)/
