ec82764bef
RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression (272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps, and all dump-derived textures/traces) is excluded via .gitignore and stays local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
752 lines
44 KiB
Systemverilog
752 lines
44 KiB
Systemverilog
// retroDE_ps2 — tb_gs_swizzle_psmt8 (Ch131)
|
||
//
|
||
// Source-locked focused contract for `gs_swizzle_psmt8_stub`.
|
||
// Mirrors the Ch125 PSMCT16 TB shape — 5-phase verification with
|
||
// independent source-table locks for both the column and block
|
||
// tables, plus a full-page bijectivity sweep over 128×64 = 8192
|
||
// pixels. Per Codex's Ch131 framing: PSMT8 is the third PSM
|
||
// swizzle math primitive (after Ch119 PSMCT32 + Ch125 PSMCT16);
|
||
// byte-aligned (1 byte/pixel) so simpler than PSMT4's nibble
|
||
// packing, but with a wider 128 px page (vs 64 px for direct-
|
||
// color PSMs) and the new FBW>>1 page-stride constant.
|
||
//
|
||
// SOURCE-TABLE PROVENANCE (per Codex's Ch125/Ch131 guidance):
|
||
// - PCSX2 master HEAD commit
|
||
// 3000e113e2b3a76357c08dfa80d3c747f40e2706 (current at TB
|
||
// creation).
|
||
// - File pcsx2/GS/GSTables.cpp, blob SHA
|
||
// 3581209b8217378f473f9de22a9dbc8c45ca49b6.
|
||
// - blockTable8 at lines 53–59 (4 rows × 8 cols, indexed
|
||
// [block_y_in_page][block_x_in_page]).
|
||
// - columnTable8 at lines 111–145 (16 rows × 16 cols, indexed
|
||
// [yb][xb], values are byte-within-block 0..255).
|
||
// - Cross-check: GSLocalMemory.h:551 BlockNumber8 +
|
||
// pxOffset template at GSTables.cpp:247–258 (blockSize=256,
|
||
// pageSize=8192, pageWidth=128) + GSLocalMemory.h:553 asserts
|
||
// `(bw & 1) == 0` for PSMT8 (FBW must be even).
|
||
//
|
||
// Phase layout:
|
||
// 1 — spot-checks at hand-computed corners (origin, intra-
|
||
// block, block-grid origins, page boundaries, FBP shift).
|
||
// 2a — INDEPENDENT column-table source lock: 256 hard-coded
|
||
// check() calls (one per (yb, xb) inside block (0,0)) where
|
||
// the expected byte index is taken VERBATIM from PCSX2
|
||
// columnTable8 with `1 * <literal>` arithmetic, NOT derived
|
||
// from the in-TB ref_col_idx8 function. Catches any case
|
||
// where DUT and ref_col_idx8 happen to share the same
|
||
// miscopy (the same kind of trap Ch125 added Phase 2a for
|
||
// with PSMCT16's column table).
|
||
// 2b — within-block 16×16 walk via the in-TB ref_col_idx8.
|
||
// Self-check that ref_col_idx8 agrees with the DUT (the
|
||
// bijectivity sweep below relies on ref_col_idx8 being
|
||
// correct).
|
||
// 3 — INDEPENDENT block-table source lock: 32 hard-coded
|
||
// check() calls (one per block in page 0). Expected block
|
||
// index taken VERBATIM from PCSX2 blockTable8.
|
||
// 4 — block-swizzle walk via the in-TB ref_block_idx8.
|
||
// 5 — bijectivity sweep over the 128×64 page (8192 pixels).
|
||
// Every pixel must hit a unique byte address in [0, 8192)
|
||
// and agree with ref_addr8.
|
||
// + multi-page sanity at FBW=4 (bw_pg=2) crossing both page-x
|
||
// and page-y, plus non-page-aligned FBP coverage.
|
||
//
|
||
// Standalone — no other modules in the dependency chain.
|
||
|
||
`timescale 1ns/1ps
|
||
|
||
module tb_gs_swizzle_psmt8;
|
||
|
||
// -----------------------------------------------------------
|
||
// DUT
|
||
// -----------------------------------------------------------
|
||
logic [8:0] fbp;
|
||
logic [5:0] fbw;
|
||
logic [11:0] x;
|
||
logic [11:0] y;
|
||
logic [31:0] addr;
|
||
|
||
gs_swizzle_psmt8_stub u_dut (
|
||
.fbp(fbp), .fbw(fbw), .x(x), .y(y), .addr(addr)
|
||
);
|
||
|
||
int errors;
|
||
initial errors = 0;
|
||
|
||
// -----------------------------------------------------------
|
||
// Helpers.
|
||
// -----------------------------------------------------------
|
||
task automatic compute(
|
||
input logic [8:0] fbp_v,
|
||
input logic [5:0] fbw_v,
|
||
input logic [11:0] x_v,
|
||
input logic [11:0] y_v,
|
||
output logic [31:0] addr_o);
|
||
fbp = fbp_v; fbw = fbw_v; x = x_v; y = y_v;
|
||
#1;
|
||
addr_o = addr;
|
||
endtask
|
||
|
||
task automatic check(
|
||
input logic [8:0] fbp_v,
|
||
input logic [5:0] fbw_v,
|
||
input logic [11:0] x_v,
|
||
input logic [11:0] y_v,
|
||
input logic [31:0] expected,
|
||
input string tag);
|
||
logic [31:0] got;
|
||
compute(fbp_v, fbw_v, x_v, y_v, got);
|
||
if (got !== expected) begin
|
||
$error("[%s] fbp=%0d fbw=%0d (x=%0d,y=%0d) got 0x%08x expected 0x%08x",
|
||
tag, fbp_v, fbw_v, x_v, y_v, got, expected);
|
||
errors = errors + 1;
|
||
end
|
||
endtask
|
||
|
||
// -----------------------------------------------------------
|
||
// Reference tables (verbatim from pcsx2/GS/GSTables.cpp).
|
||
// -----------------------------------------------------------
|
||
function automatic int ref_block_idx8(input int by, input int bx);
|
||
// _blockTable8[4][8]:
|
||
// by=0: { 0, 1, 4, 5,16,17,20,21}
|
||
// by=1: { 2, 3, 6, 7,18,19,22,23}
|
||
// by=2: { 8, 9,12,13,24,25,28,29}
|
||
// by=3: {10,11,14,15,26,27,30,31}
|
||
case ({by[1:0], bx[2:0]})
|
||
// by=0
|
||
5'd0: return 0; 5'd1: return 1; 5'd2: return 4; 5'd3: return 5;
|
||
5'd4: return 16; 5'd5: return 17; 5'd6: return 20; 5'd7: return 21;
|
||
// by=1
|
||
5'd8: return 2; 5'd9: return 3; 5'd10: return 6; 5'd11: return 7;
|
||
5'd12: return 18; 5'd13: return 19; 5'd14: return 22; 5'd15: return 23;
|
||
// by=2
|
||
5'd16: return 8; 5'd17: return 9; 5'd18: return 12; 5'd19: return 13;
|
||
5'd20: return 24; 5'd21: return 25; 5'd22: return 28; 5'd23: return 29;
|
||
// by=3
|
||
5'd24: return 10; 5'd25: return 11; 5'd26: return 14; 5'd27: return 15;
|
||
5'd28: return 26; 5'd29: return 27; 5'd30: return 30; default: return 31;
|
||
endcase
|
||
endfunction
|
||
|
||
function automatic int ref_col_idx8(input int yb, input int xb);
|
||
// columnTable8[16][16] (PCSX2 master GSTables.cpp lines 111–145):
|
||
// yb=0: 0 4 16 20 32 36 48 52 2 6 18 22 34 38 50 54
|
||
// yb=1: 8 12 24 28 40 44 56 60 10 14 26 30 42 46 58 62
|
||
// yb=2: 33 37 49 53 1 5 17 21 35 39 51 55 3 7 19 23
|
||
// yb=3: 41 45 57 61 9 13 25 29 43 47 59 63 11 15 27 31
|
||
// yb=4: 96 100 112 116 64 68 80 84 98 102 114 118 66 70 82 86
|
||
// yb=5: 104 108 120 124 72 76 88 92 106 110 122 126 74 78 90 94
|
||
// yb=6: 65 69 81 85 97 101 113 117 67 71 83 87 99 103 115 119
|
||
// yb=7: 73 77 89 93 105 109 121 125 75 79 91 95 107 111 123 127
|
||
// yb=8: 128 132 144 148 160 164 176 180 130 134 146 150 162 166 178 182
|
||
// yb=9: 136 140 152 156 168 172 184 188 138 142 154 158 170 174 186 190
|
||
// yb=10: 161 165 177 181 129 133 145 149 163 167 179 183 131 135 147 151
|
||
// yb=11: 169 173 185 189 137 141 153 157 171 175 187 191 139 143 155 159
|
||
// yb=12: 224 228 240 244 192 196 208 212 226 230 242 246 194 198 210 214
|
||
// yb=13: 232 236 248 252 200 204 216 220 234 238 250 254 202 206 218 222
|
||
// yb=14: 193 197 209 213 225 229 241 245 195 199 211 215 227 231 243 247
|
||
// yb=15: 201 205 217 221 233 237 249 253 203 207 219 223 235 239 251 255
|
||
case ({yb[3:0], xb[3:0]})
|
||
// yb=0
|
||
8'd0: return 0; 8'd1: return 4; 8'd2: return 16; 8'd3: return 20;
|
||
8'd4: return 32; 8'd5: return 36; 8'd6: return 48; 8'd7: return 52;
|
||
8'd8: return 2; 8'd9: return 6; 8'd10: return 18; 8'd11: return 22;
|
||
8'd12: return 34; 8'd13: return 38; 8'd14: return 50; 8'd15: return 54;
|
||
// yb=1
|
||
8'd16: return 8; 8'd17: return 12; 8'd18: return 24; 8'd19: return 28;
|
||
8'd20: return 40; 8'd21: return 44; 8'd22: return 56; 8'd23: return 60;
|
||
8'd24: return 10; 8'd25: return 14; 8'd26: return 26; 8'd27: return 30;
|
||
8'd28: return 42; 8'd29: return 46; 8'd30: return 58; 8'd31: return 62;
|
||
// yb=2
|
||
8'd32: return 33; 8'd33: return 37; 8'd34: return 49; 8'd35: return 53;
|
||
8'd36: return 1; 8'd37: return 5; 8'd38: return 17; 8'd39: return 21;
|
||
8'd40: return 35; 8'd41: return 39; 8'd42: return 51; 8'd43: return 55;
|
||
8'd44: return 3; 8'd45: return 7; 8'd46: return 19; 8'd47: return 23;
|
||
// yb=3
|
||
8'd48: return 41; 8'd49: return 45; 8'd50: return 57; 8'd51: return 61;
|
||
8'd52: return 9; 8'd53: return 13; 8'd54: return 25; 8'd55: return 29;
|
||
8'd56: return 43; 8'd57: return 47; 8'd58: return 59; 8'd59: return 63;
|
||
8'd60: return 11; 8'd61: return 15; 8'd62: return 27; 8'd63: return 31;
|
||
// yb=4
|
||
8'd64: return 96; 8'd65: return 100; 8'd66: return 112; 8'd67: return 116;
|
||
8'd68: return 64; 8'd69: return 68; 8'd70: return 80; 8'd71: return 84;
|
||
8'd72: return 98; 8'd73: return 102; 8'd74: return 114; 8'd75: return 118;
|
||
8'd76: return 66; 8'd77: return 70; 8'd78: return 82; 8'd79: return 86;
|
||
// yb=5
|
||
8'd80: return 104; 8'd81: return 108; 8'd82: return 120; 8'd83: return 124;
|
||
8'd84: return 72; 8'd85: return 76; 8'd86: return 88; 8'd87: return 92;
|
||
8'd88: return 106; 8'd89: return 110; 8'd90: return 122; 8'd91: return 126;
|
||
8'd92: return 74; 8'd93: return 78; 8'd94: return 90; 8'd95: return 94;
|
||
// yb=6
|
||
8'd96: return 65; 8'd97: return 69; 8'd98: return 81; 8'd99: return 85;
|
||
8'd100: return 97; 8'd101: return 101; 8'd102: return 113; 8'd103: return 117;
|
||
8'd104: return 67; 8'd105: return 71; 8'd106: return 83; 8'd107: return 87;
|
||
8'd108: return 99; 8'd109: return 103; 8'd110: return 115; 8'd111: return 119;
|
||
// yb=7
|
||
8'd112: return 73; 8'd113: return 77; 8'd114: return 89; 8'd115: return 93;
|
||
8'd116: return 105; 8'd117: return 109; 8'd118: return 121; 8'd119: return 125;
|
||
8'd120: return 75; 8'd121: return 79; 8'd122: return 91; 8'd123: return 95;
|
||
8'd124: return 107; 8'd125: return 111; 8'd126: return 123; 8'd127: return 127;
|
||
// yb=8
|
||
8'd128: return 128; 8'd129: return 132; 8'd130: return 144; 8'd131: return 148;
|
||
8'd132: return 160; 8'd133: return 164; 8'd134: return 176; 8'd135: return 180;
|
||
8'd136: return 130; 8'd137: return 134; 8'd138: return 146; 8'd139: return 150;
|
||
8'd140: return 162; 8'd141: return 166; 8'd142: return 178; 8'd143: return 182;
|
||
// yb=9
|
||
8'd144: return 136; 8'd145: return 140; 8'd146: return 152; 8'd147: return 156;
|
||
8'd148: return 168; 8'd149: return 172; 8'd150: return 184; 8'd151: return 188;
|
||
8'd152: return 138; 8'd153: return 142; 8'd154: return 154; 8'd155: return 158;
|
||
8'd156: return 170; 8'd157: return 174; 8'd158: return 186; 8'd159: return 190;
|
||
// yb=10
|
||
8'd160: return 161; 8'd161: return 165; 8'd162: return 177; 8'd163: return 181;
|
||
8'd164: return 129; 8'd165: return 133; 8'd166: return 145; 8'd167: return 149;
|
||
8'd168: return 163; 8'd169: return 167; 8'd170: return 179; 8'd171: return 183;
|
||
8'd172: return 131; 8'd173: return 135; 8'd174: return 147; 8'd175: return 151;
|
||
// yb=11
|
||
8'd176: return 169; 8'd177: return 173; 8'd178: return 185; 8'd179: return 189;
|
||
8'd180: return 137; 8'd181: return 141; 8'd182: return 153; 8'd183: return 157;
|
||
8'd184: return 171; 8'd185: return 175; 8'd186: return 187; 8'd187: return 191;
|
||
8'd188: return 139; 8'd189: return 143; 8'd190: return 155; 8'd191: return 159;
|
||
// yb=12
|
||
8'd192: return 224; 8'd193: return 228; 8'd194: return 240; 8'd195: return 244;
|
||
8'd196: return 192; 8'd197: return 196; 8'd198: return 208; 8'd199: return 212;
|
||
8'd200: return 226; 8'd201: return 230; 8'd202: return 242; 8'd203: return 246;
|
||
8'd204: return 194; 8'd205: return 198; 8'd206: return 210; 8'd207: return 214;
|
||
// yb=13
|
||
8'd208: return 232; 8'd209: return 236; 8'd210: return 248; 8'd211: return 252;
|
||
8'd212: return 200; 8'd213: return 204; 8'd214: return 216; 8'd215: return 220;
|
||
8'd216: return 234; 8'd217: return 238; 8'd218: return 250; 8'd219: return 254;
|
||
8'd220: return 202; 8'd221: return 206; 8'd222: return 218; 8'd223: return 222;
|
||
// yb=14
|
||
8'd224: return 193; 8'd225: return 197; 8'd226: return 209; 8'd227: return 213;
|
||
8'd228: return 225; 8'd229: return 229; 8'd230: return 241; 8'd231: return 245;
|
||
8'd232: return 195; 8'd233: return 199; 8'd234: return 211; 8'd235: return 215;
|
||
8'd236: return 227; 8'd237: return 231; 8'd238: return 243; 8'd239: return 247;
|
||
// yb=15
|
||
8'd240: return 201; 8'd241: return 205; 8'd242: return 217; 8'd243: return 221;
|
||
8'd244: return 233; 8'd245: return 237; 8'd246: return 249; 8'd247: return 253;
|
||
8'd248: return 203; 8'd249: return 207; 8'd250: return 219; 8'd251: return 223;
|
||
8'd252: return 235; 8'd253: return 239; 8'd254: return 251; default: return 255;
|
||
endcase
|
||
endfunction
|
||
|
||
function automatic logic [31:0] ref_addr8(
|
||
input int fbp_v, input int fbw_v, input int x_v, input int y_v);
|
||
int page_x, page_y, bw_pg_v, page_idx, page_base;
|
||
int by, bx, blk_idx, xb, yb, byte_idx;
|
||
int addr_v;
|
||
page_x = x_v / 128;
|
||
page_y = y_v / 64;
|
||
bw_pg_v = fbw_v / 2;
|
||
page_idx = page_y * bw_pg_v + page_x;
|
||
page_base = fbp_v * 2048 + page_idx * 8192;
|
||
by = (y_v % 64) / 16;
|
||
bx = (x_v % 128) / 16;
|
||
blk_idx = ref_block_idx8(by, bx);
|
||
xb = x_v % 16;
|
||
yb = y_v % 16;
|
||
byte_idx = ref_col_idx8(yb, xb);
|
||
addr_v = page_base + blk_idx * 256 + byte_idx;
|
||
return addr_v[31:0];
|
||
endfunction
|
||
|
||
initial begin
|
||
fbp = 9'd0;
|
||
fbw = 6'd2; // PSMT8: FBW must be even (PCSX2 asserts (bw & 1) == 0)
|
||
x = 12'd0;
|
||
y = 12'd0;
|
||
#1;
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 1 — spot-checks (hand-computed corners). FBW=2 →
|
||
// bw_pg=1, so a single page per row of pages.
|
||
// -----------------------------------------------------------
|
||
// (0, 0) → block (0,0)=0, byte=0 → addr 0.
|
||
check(9'd0, 6'd2, 12'd0, 12'd0, 32'd0, "origin");
|
||
// (1, 0) → block 0, xb=1 yb=0 → byte=4 → addr 4.
|
||
check(9'd0, 6'd2, 12'd1, 12'd0, 32'd4, "intra-block-x1");
|
||
// (4, 0) → block 0, xb=4 yb=0 → byte=32.
|
||
check(9'd0, 6'd2, 12'd4, 12'd0, 32'd32, "intra-block-x4");
|
||
// (8, 0) → block 0, xb=8 yb=0 → byte=2.
|
||
check(9'd0, 6'd2, 12'd8, 12'd0, 32'd2, "intra-block-x8");
|
||
// (0, 1) → block 0, xb=0 yb=1 → byte=8.
|
||
check(9'd0, 6'd2, 12'd0, 12'd1, 32'd8, "intra-block-y1");
|
||
// (15, 15) → last byte of block (0,0): xb=15 yb=15 → byte=255.
|
||
check(9'd0, 6'd2, 12'd15, 12'd15, 32'd255, "block-(0,0)-last");
|
||
// (16, 0) → block (0,1) (by=0, bx=1) → blockTable8[0][1]=1 →
|
||
// block_base=256. xb=0 yb=0 → byte=0 → addr 256.
|
||
check(9'd0, 6'd2, 12'd16, 12'd0, 32'd256, "block-(0,1)-origin");
|
||
// (0, 16) → block (1,0) (by=1, bx=0) → blockTable8[1][0]=2 →
|
||
// block_base=512.
|
||
check(9'd0, 6'd2, 12'd0, 12'd16, 32'd512, "block-(1,0)-origin");
|
||
// (32, 0) → block (0,2) → blockTable8[0][2]=4 → block_base=1024.
|
||
check(9'd0, 6'd2, 12'd32, 12'd0, 32'd1024, "block-(0,2)-origin");
|
||
// (0, 32) → block (2,0) → blockTable8[2][0]=8 → block_base=2048.
|
||
check(9'd0, 6'd2, 12'd0, 12'd32, 32'd2048, "block-(2,0)-origin");
|
||
// (64, 0) → block (0,4) → blockTable8[0][4]=16 → block_base=4096.
|
||
check(9'd0, 6'd2, 12'd64, 12'd0, 32'd4096, "block-(0,4)-origin");
|
||
// (127, 63) → last pixel of last block of page 0:
|
||
// block (3,7) → blockTable8[3][7]=31 → block_base=7936.
|
||
// xb=15 yb=15 → byte=255 → addr = 7936 + 255 = 8191.
|
||
check(9'd0, 6'd2, 12'd127, 12'd63, 32'd8191, "page0-last-pixel");
|
||
// (128, 0) → start of page 1 (FBW=2, bw_pg=1) → page_idx=1,
|
||
// page_base=8192 → addr 8192.
|
||
check(9'd0, 6'd2, 12'd128, 12'd0, 32'd8192, "page1-x-origin");
|
||
// (0, 64) → start of page-row 1 (bw_pg=1) → page_idx=1,
|
||
// page_base=8192.
|
||
check(9'd0, 6'd2, 12'd0, 12'd64, 32'd8192, "page1-y-origin");
|
||
// FBP=4 → FBP*2048=8192 = 1 page. (0,0) → addr 8192.
|
||
check(9'd4, 6'd2, 12'd0, 12'd0, 32'd8192, "fbp4-origin");
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 2a — INDEPENDENT column-table source lock. 256 hard-
|
||
// coded address checks (one per (yb, xb) inside block (0,0))
|
||
// where the expected byte index is taken VERBATIM from PCSX2
|
||
// columnTable8, NOT derived from the in-TB ref_col_idx8.
|
||
// pixel (xb, yb) at FBP=0, FBW=2 lands in page (0,0), block
|
||
// (0,0) → swizzle 0 → block_base 0; expected addr = byte.
|
||
// -----------------------------------------------------------
|
||
// yb=0: 0 4 16 20 32 36 48 52 2 6 18 22 34 38 50 54
|
||
check(9'd0, 6'd2, 12'd0, 12'd0, 32'd0, "col-yb0-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd0, 32'd4, "col-yb0-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd0, 32'd16, "col-yb0-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd0, 32'd20, "col-yb0-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd0, 32'd32, "col-yb0-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd0, 32'd36, "col-yb0-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd0, 32'd48, "col-yb0-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd0, 32'd52, "col-yb0-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd0, 32'd2, "col-yb0-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd0, 32'd6, "col-yb0-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd0, 32'd18, "col-yb0-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd0, 32'd22, "col-yb0-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd0, 32'd34, "col-yb0-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd0, 32'd38, "col-yb0-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd0, 32'd50, "col-yb0-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd0, 32'd54, "col-yb0-xb15");
|
||
// yb=1: 8 12 24 28 40 44 56 60 10 14 26 30 42 46 58 62
|
||
check(9'd0, 6'd2, 12'd0, 12'd1, 32'd8, "col-yb1-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd1, 32'd12, "col-yb1-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd1, 32'd24, "col-yb1-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd1, 32'd28, "col-yb1-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd1, 32'd40, "col-yb1-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd1, 32'd44, "col-yb1-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd1, 32'd56, "col-yb1-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd1, 32'd60, "col-yb1-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd1, 32'd10, "col-yb1-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd1, 32'd14, "col-yb1-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd1, 32'd26, "col-yb1-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd1, 32'd30, "col-yb1-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd1, 32'd42, "col-yb1-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd1, 32'd46, "col-yb1-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd1, 32'd58, "col-yb1-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd1, 32'd62, "col-yb1-xb15");
|
||
// yb=2: 33 37 49 53 1 5 17 21 35 39 51 55 3 7 19 23
|
||
check(9'd0, 6'd2, 12'd0, 12'd2, 32'd33, "col-yb2-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd2, 32'd37, "col-yb2-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd2, 32'd49, "col-yb2-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd2, 32'd53, "col-yb2-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd2, 32'd1, "col-yb2-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd2, 32'd5, "col-yb2-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd2, 32'd17, "col-yb2-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd2, 32'd21, "col-yb2-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd2, 32'd35, "col-yb2-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd2, 32'd39, "col-yb2-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd2, 32'd51, "col-yb2-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd2, 32'd55, "col-yb2-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd2, 32'd3, "col-yb2-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd2, 32'd7, "col-yb2-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd2, 32'd19, "col-yb2-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd2, 32'd23, "col-yb2-xb15");
|
||
// yb=3: 41 45 57 61 9 13 25 29 43 47 59 63 11 15 27 31
|
||
check(9'd0, 6'd2, 12'd0, 12'd3, 32'd41, "col-yb3-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd3, 32'd45, "col-yb3-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd3, 32'd57, "col-yb3-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd3, 32'd61, "col-yb3-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd3, 32'd9, "col-yb3-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd3, 32'd13, "col-yb3-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd3, 32'd25, "col-yb3-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd3, 32'd29, "col-yb3-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd3, 32'd43, "col-yb3-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd3, 32'd47, "col-yb3-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd3, 32'd59, "col-yb3-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd3, 32'd63, "col-yb3-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd3, 32'd11, "col-yb3-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd3, 32'd15, "col-yb3-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd3, 32'd27, "col-yb3-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd3, 32'd31, "col-yb3-xb15");
|
||
// yb=4: 96 100 112 116 64 68 80 84 98 102 114 118 66 70 82 86
|
||
check(9'd0, 6'd2, 12'd0, 12'd4, 32'd96, "col-yb4-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd4, 32'd100, "col-yb4-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd4, 32'd112, "col-yb4-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd4, 32'd116, "col-yb4-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd4, 32'd64, "col-yb4-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd4, 32'd68, "col-yb4-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd4, 32'd80, "col-yb4-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd4, 32'd84, "col-yb4-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd4, 32'd98, "col-yb4-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd4, 32'd102, "col-yb4-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd4, 32'd114, "col-yb4-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd4, 32'd118, "col-yb4-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd4, 32'd66, "col-yb4-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd4, 32'd70, "col-yb4-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd4, 32'd82, "col-yb4-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd4, 32'd86, "col-yb4-xb15");
|
||
// yb=5: 104 108 120 124 72 76 88 92 106 110 122 126 74 78 90 94
|
||
check(9'd0, 6'd2, 12'd0, 12'd5, 32'd104, "col-yb5-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd5, 32'd108, "col-yb5-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd5, 32'd120, "col-yb5-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd5, 32'd124, "col-yb5-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd5, 32'd72, "col-yb5-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd5, 32'd76, "col-yb5-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd5, 32'd88, "col-yb5-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd5, 32'd92, "col-yb5-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd5, 32'd106, "col-yb5-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd5, 32'd110, "col-yb5-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd5, 32'd122, "col-yb5-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd5, 32'd126, "col-yb5-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd5, 32'd74, "col-yb5-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd5, 32'd78, "col-yb5-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd5, 32'd90, "col-yb5-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd5, 32'd94, "col-yb5-xb15");
|
||
// yb=6: 65 69 81 85 97 101 113 117 67 71 83 87 99 103 115 119
|
||
check(9'd0, 6'd2, 12'd0, 12'd6, 32'd65, "col-yb6-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd6, 32'd69, "col-yb6-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd6, 32'd81, "col-yb6-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd6, 32'd85, "col-yb6-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd6, 32'd97, "col-yb6-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd6, 32'd101, "col-yb6-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd6, 32'd113, "col-yb6-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd6, 32'd117, "col-yb6-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd6, 32'd67, "col-yb6-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd6, 32'd71, "col-yb6-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd6, 32'd83, "col-yb6-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd6, 32'd87, "col-yb6-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd6, 32'd99, "col-yb6-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd6, 32'd103, "col-yb6-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd6, 32'd115, "col-yb6-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd6, 32'd119, "col-yb6-xb15");
|
||
// yb=7: 73 77 89 93 105 109 121 125 75 79 91 95 107 111 123 127
|
||
check(9'd0, 6'd2, 12'd0, 12'd7, 32'd73, "col-yb7-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd7, 32'd77, "col-yb7-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd7, 32'd89, "col-yb7-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd7, 32'd93, "col-yb7-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd7, 32'd105, "col-yb7-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd7, 32'd109, "col-yb7-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd7, 32'd121, "col-yb7-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd7, 32'd125, "col-yb7-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd7, 32'd75, "col-yb7-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd7, 32'd79, "col-yb7-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd7, 32'd91, "col-yb7-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd7, 32'd95, "col-yb7-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd7, 32'd107, "col-yb7-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd7, 32'd111, "col-yb7-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd7, 32'd123, "col-yb7-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd7, 32'd127, "col-yb7-xb15");
|
||
// yb=8: 128 132 144 148 160 164 176 180 130 134 146 150 162 166 178 182
|
||
check(9'd0, 6'd2, 12'd0, 12'd8, 32'd128, "col-yb8-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd8, 32'd132, "col-yb8-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd8, 32'd144, "col-yb8-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd8, 32'd148, "col-yb8-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd8, 32'd160, "col-yb8-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd8, 32'd164, "col-yb8-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd8, 32'd176, "col-yb8-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd8, 32'd180, "col-yb8-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd8, 32'd130, "col-yb8-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd8, 32'd134, "col-yb8-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd8, 32'd146, "col-yb8-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd8, 32'd150, "col-yb8-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd8, 32'd162, "col-yb8-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd8, 32'd166, "col-yb8-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd8, 32'd178, "col-yb8-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd8, 32'd182, "col-yb8-xb15");
|
||
// yb=9: 136 140 152 156 168 172 184 188 138 142 154 158 170 174 186 190
|
||
check(9'd0, 6'd2, 12'd0, 12'd9, 32'd136, "col-yb9-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd9, 32'd140, "col-yb9-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd9, 32'd152, "col-yb9-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd9, 32'd156, "col-yb9-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd9, 32'd168, "col-yb9-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd9, 32'd172, "col-yb9-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd9, 32'd184, "col-yb9-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd9, 32'd188, "col-yb9-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd9, 32'd138, "col-yb9-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd9, 32'd142, "col-yb9-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd9, 32'd154, "col-yb9-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd9, 32'd158, "col-yb9-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd9, 32'd170, "col-yb9-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd9, 32'd174, "col-yb9-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd9, 32'd186, "col-yb9-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd9, 32'd190, "col-yb9-xb15");
|
||
// yb=10: 161 165 177 181 129 133 145 149 163 167 179 183 131 135 147 151
|
||
check(9'd0, 6'd2, 12'd0, 12'd10, 32'd161, "col-yb10-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd10, 32'd165, "col-yb10-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd10, 32'd177, "col-yb10-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd10, 32'd181, "col-yb10-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd10, 32'd129, "col-yb10-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd10, 32'd133, "col-yb10-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd10, 32'd145, "col-yb10-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd10, 32'd149, "col-yb10-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd10, 32'd163, "col-yb10-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd10, 32'd167, "col-yb10-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd10, 32'd179, "col-yb10-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd10, 32'd183, "col-yb10-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd10, 32'd131, "col-yb10-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd10, 32'd135, "col-yb10-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd10, 32'd147, "col-yb10-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd10, 32'd151, "col-yb10-xb15");
|
||
// yb=11: 169 173 185 189 137 141 153 157 171 175 187 191 139 143 155 159
|
||
check(9'd0, 6'd2, 12'd0, 12'd11, 32'd169, "col-yb11-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd11, 32'd173, "col-yb11-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd11, 32'd185, "col-yb11-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd11, 32'd189, "col-yb11-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd11, 32'd137, "col-yb11-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd11, 32'd141, "col-yb11-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd11, 32'd153, "col-yb11-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd11, 32'd157, "col-yb11-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd11, 32'd171, "col-yb11-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd11, 32'd175, "col-yb11-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd11, 32'd187, "col-yb11-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd11, 32'd191, "col-yb11-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd11, 32'd139, "col-yb11-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd11, 32'd143, "col-yb11-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd11, 32'd155, "col-yb11-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd11, 32'd159, "col-yb11-xb15");
|
||
// yb=12: 224 228 240 244 192 196 208 212 226 230 242 246 194 198 210 214
|
||
check(9'd0, 6'd2, 12'd0, 12'd12, 32'd224, "col-yb12-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd12, 32'd228, "col-yb12-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd12, 32'd240, "col-yb12-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd12, 32'd244, "col-yb12-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd12, 32'd192, "col-yb12-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd12, 32'd196, "col-yb12-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd12, 32'd208, "col-yb12-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd12, 32'd212, "col-yb12-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd12, 32'd226, "col-yb12-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd12, 32'd230, "col-yb12-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd12, 32'd242, "col-yb12-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd12, 32'd246, "col-yb12-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd12, 32'd194, "col-yb12-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd12, 32'd198, "col-yb12-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd12, 32'd210, "col-yb12-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd12, 32'd214, "col-yb12-xb15");
|
||
// yb=13: 232 236 248 252 200 204 216 220 234 238 250 254 202 206 218 222
|
||
check(9'd0, 6'd2, 12'd0, 12'd13, 32'd232, "col-yb13-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd13, 32'd236, "col-yb13-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd13, 32'd248, "col-yb13-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd13, 32'd252, "col-yb13-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd13, 32'd200, "col-yb13-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd13, 32'd204, "col-yb13-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd13, 32'd216, "col-yb13-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd13, 32'd220, "col-yb13-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd13, 32'd234, "col-yb13-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd13, 32'd238, "col-yb13-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd13, 32'd250, "col-yb13-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd13, 32'd254, "col-yb13-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd13, 32'd202, "col-yb13-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd13, 32'd206, "col-yb13-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd13, 32'd218, "col-yb13-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd13, 32'd222, "col-yb13-xb15");
|
||
// yb=14: 193 197 209 213 225 229 241 245 195 199 211 215 227 231 243 247
|
||
check(9'd0, 6'd2, 12'd0, 12'd14, 32'd193, "col-yb14-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd14, 32'd197, "col-yb14-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd14, 32'd209, "col-yb14-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd14, 32'd213, "col-yb14-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd14, 32'd225, "col-yb14-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd14, 32'd229, "col-yb14-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd14, 32'd241, "col-yb14-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd14, 32'd245, "col-yb14-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd14, 32'd195, "col-yb14-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd14, 32'd199, "col-yb14-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd14, 32'd211, "col-yb14-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd14, 32'd215, "col-yb14-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd14, 32'd227, "col-yb14-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd14, 32'd231, "col-yb14-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd14, 32'd243, "col-yb14-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd14, 32'd247, "col-yb14-xb15");
|
||
// yb=15: 201 205 217 221 233 237 249 253 203 207 219 223 235 239 251 255
|
||
check(9'd0, 6'd2, 12'd0, 12'd15, 32'd201, "col-yb15-xb0");
|
||
check(9'd0, 6'd2, 12'd1, 12'd15, 32'd205, "col-yb15-xb1");
|
||
check(9'd0, 6'd2, 12'd2, 12'd15, 32'd217, "col-yb15-xb2");
|
||
check(9'd0, 6'd2, 12'd3, 12'd15, 32'd221, "col-yb15-xb3");
|
||
check(9'd0, 6'd2, 12'd4, 12'd15, 32'd233, "col-yb15-xb4");
|
||
check(9'd0, 6'd2, 12'd5, 12'd15, 32'd237, "col-yb15-xb5");
|
||
check(9'd0, 6'd2, 12'd6, 12'd15, 32'd249, "col-yb15-xb6");
|
||
check(9'd0, 6'd2, 12'd7, 12'd15, 32'd253, "col-yb15-xb7");
|
||
check(9'd0, 6'd2, 12'd8, 12'd15, 32'd203, "col-yb15-xb8");
|
||
check(9'd0, 6'd2, 12'd9, 12'd15, 32'd207, "col-yb15-xb9");
|
||
check(9'd0, 6'd2, 12'd10, 12'd15, 32'd219, "col-yb15-xb10");
|
||
check(9'd0, 6'd2, 12'd11, 12'd15, 32'd223, "col-yb15-xb11");
|
||
check(9'd0, 6'd2, 12'd12, 12'd15, 32'd235, "col-yb15-xb12");
|
||
check(9'd0, 6'd2, 12'd13, 12'd15, 32'd239, "col-yb15-xb13");
|
||
check(9'd0, 6'd2, 12'd14, 12'd15, 32'd251, "col-yb15-xb14");
|
||
check(9'd0, 6'd2, 12'd15, 12'd15, 32'd255, "col-yb15-xb15");
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 2b — within-block 16×16 walk via the in-TB
|
||
// ref_col_idx8. Self-check that ref_col_idx8 agrees with
|
||
// the DUT.
|
||
// -----------------------------------------------------------
|
||
for (int yb_i = 0; yb_i < 16; yb_i++) begin
|
||
for (int xb_i = 0; xb_i < 16; xb_i++) begin
|
||
logic [31:0] expected;
|
||
expected = 32'(ref_col_idx8(yb_i, xb_i));
|
||
check(9'd0, 6'd2, 12'(xb_i), 12'(yb_i), expected,
|
||
"within-block-col-table");
|
||
end
|
||
end
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 3 — INDEPENDENT block-table source lock. 32 hard-
|
||
// coded address checks, one per block in page 0. Expected
|
||
// block index taken VERBATIM from PCSX2 blockTable8 (NOT
|
||
// derived from ref_block_idx8). For each block (block_y,
|
||
// block_x), we use the pixel (16*block_x, 16*block_y) which
|
||
// lands at xb=yb=0 → byte=0 within the block;
|
||
// total addr = block_idx * 256.
|
||
//
|
||
// blockTable8[4][8] (PCSX2 master GSTables.cpp lines 53–59):
|
||
// by=0: 0 1 4 5 16 17 20 21
|
||
// by=1: 2 3 6 7 18 19 22 23
|
||
// by=2: 8 9 12 13 24 25 28 29
|
||
// by=3: 10 11 14 15 26 27 30 31
|
||
// -----------------------------------------------------------
|
||
// by=0
|
||
check(9'd0, 6'd2, 12'(0*16), 12'(0*16), 32'(0*256), "src-lock-by0bx0");
|
||
check(9'd0, 6'd2, 12'(1*16), 12'(0*16), 32'(1*256), "src-lock-by0bx1");
|
||
check(9'd0, 6'd2, 12'(2*16), 12'(0*16), 32'(4*256), "src-lock-by0bx2");
|
||
check(9'd0, 6'd2, 12'(3*16), 12'(0*16), 32'(5*256), "src-lock-by0bx3");
|
||
check(9'd0, 6'd2, 12'(4*16), 12'(0*16), 32'(16*256), "src-lock-by0bx4");
|
||
check(9'd0, 6'd2, 12'(5*16), 12'(0*16), 32'(17*256), "src-lock-by0bx5");
|
||
check(9'd0, 6'd2, 12'(6*16), 12'(0*16), 32'(20*256), "src-lock-by0bx6");
|
||
check(9'd0, 6'd2, 12'(7*16), 12'(0*16), 32'(21*256), "src-lock-by0bx7");
|
||
// by=1
|
||
check(9'd0, 6'd2, 12'(0*16), 12'(1*16), 32'(2*256), "src-lock-by1bx0");
|
||
check(9'd0, 6'd2, 12'(1*16), 12'(1*16), 32'(3*256), "src-lock-by1bx1");
|
||
check(9'd0, 6'd2, 12'(2*16), 12'(1*16), 32'(6*256), "src-lock-by1bx2");
|
||
check(9'd0, 6'd2, 12'(3*16), 12'(1*16), 32'(7*256), "src-lock-by1bx3");
|
||
check(9'd0, 6'd2, 12'(4*16), 12'(1*16), 32'(18*256), "src-lock-by1bx4");
|
||
check(9'd0, 6'd2, 12'(5*16), 12'(1*16), 32'(19*256), "src-lock-by1bx5");
|
||
check(9'd0, 6'd2, 12'(6*16), 12'(1*16), 32'(22*256), "src-lock-by1bx6");
|
||
check(9'd0, 6'd2, 12'(7*16), 12'(1*16), 32'(23*256), "src-lock-by1bx7");
|
||
// by=2
|
||
check(9'd0, 6'd2, 12'(0*16), 12'(2*16), 32'(8*256), "src-lock-by2bx0");
|
||
check(9'd0, 6'd2, 12'(1*16), 12'(2*16), 32'(9*256), "src-lock-by2bx1");
|
||
check(9'd0, 6'd2, 12'(2*16), 12'(2*16), 32'(12*256), "src-lock-by2bx2");
|
||
check(9'd0, 6'd2, 12'(3*16), 12'(2*16), 32'(13*256), "src-lock-by2bx3");
|
||
check(9'd0, 6'd2, 12'(4*16), 12'(2*16), 32'(24*256), "src-lock-by2bx4");
|
||
check(9'd0, 6'd2, 12'(5*16), 12'(2*16), 32'(25*256), "src-lock-by2bx5");
|
||
check(9'd0, 6'd2, 12'(6*16), 12'(2*16), 32'(28*256), "src-lock-by2bx6");
|
||
check(9'd0, 6'd2, 12'(7*16), 12'(2*16), 32'(29*256), "src-lock-by2bx7");
|
||
// by=3
|
||
check(9'd0, 6'd2, 12'(0*16), 12'(3*16), 32'(10*256), "src-lock-by3bx0");
|
||
check(9'd0, 6'd2, 12'(1*16), 12'(3*16), 32'(11*256), "src-lock-by3bx1");
|
||
check(9'd0, 6'd2, 12'(2*16), 12'(3*16), 32'(14*256), "src-lock-by3bx2");
|
||
check(9'd0, 6'd2, 12'(3*16), 12'(3*16), 32'(15*256), "src-lock-by3bx3");
|
||
check(9'd0, 6'd2, 12'(4*16), 12'(3*16), 32'(26*256), "src-lock-by3bx4");
|
||
check(9'd0, 6'd2, 12'(5*16), 12'(3*16), 32'(27*256), "src-lock-by3bx5");
|
||
check(9'd0, 6'd2, 12'(6*16), 12'(3*16), 32'(30*256), "src-lock-by3bx6");
|
||
check(9'd0, 6'd2, 12'(7*16), 12'(3*16), 32'(31*256), "src-lock-by3bx7");
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 4 — block-swizzle walk. Cross-checks the in-TB
|
||
// ref_block_idx8 against the DUT (the bijectivity sweep
|
||
// below relies on ref_block_idx8 being correct).
|
||
// -----------------------------------------------------------
|
||
for (int by_i = 0; by_i < 4; by_i++) begin
|
||
for (int bx_i = 0; bx_i < 8; bx_i++) begin
|
||
logic [31:0] expected;
|
||
expected = 32'(ref_block_idx8(by_i, bx_i) * 256);
|
||
check(9'd0, 6'd2, 12'(bx_i*16), 12'(by_i*16), expected,
|
||
"block-swizzle-walk");
|
||
end
|
||
end
|
||
|
||
// -----------------------------------------------------------
|
||
// Phase 5 — bijectivity sweep over the 128×64 page (8192
|
||
// pixels = 8192 byte slots since PSMT8 is 1 byte/pixel).
|
||
// Every pixel must hit a unique byte address in [0, 8192)
|
||
// and agree with ref_addr8. Catches any swap in either table.
|
||
// -----------------------------------------------------------
|
||
begin : sweep
|
||
logic seen [0:8191];
|
||
for (int i = 0; i < 8192; i++) seen[i] = 1'b0;
|
||
for (int yy = 0; yy < 64; yy++) begin
|
||
for (int xx = 0; xx < 128; xx++) begin
|
||
logic [31:0] got, ref_;
|
||
int byte_slot;
|
||
compute(9'd0, 6'd2, 12'(xx), 12'(yy), got);
|
||
ref_ = ref_addr8(0, 2, xx, yy);
|
||
if (got !== ref_) begin
|
||
$error("sweep: (%0d,%0d) DUT=0x%08x ref=0x%08x",
|
||
xx, yy, got, ref_);
|
||
errors = errors + 1;
|
||
end
|
||
if (got >= 32'd8192) begin
|
||
$error("sweep: (%0d,%0d) addr=0x%08x out of page bounds",
|
||
xx, yy, got);
|
||
errors = errors + 1;
|
||
end
|
||
byte_slot = got[12:0];
|
||
if (seen[byte_slot]) begin
|
||
$error("sweep: (%0d,%0d) addr=0x%08x duplicate (slot=%0d)",
|
||
xx, yy, got, byte_slot);
|
||
errors = errors + 1;
|
||
end
|
||
seen[byte_slot] = 1'b1;
|
||
end
|
||
end
|
||
for (int i = 0; i < 8192; i++) begin
|
||
if (!seen[i]) begin
|
||
$error("sweep: byte_slot %0d never reached", i);
|
||
errors = errors + 1;
|
||
end
|
||
end
|
||
end
|
||
|
||
// -----------------------------------------------------------
|
||
// Multi-page sanity at FBW=4 (bw_pg=2): pixel (192, 16) →
|
||
// page (1, 0) horizontally.
|
||
// page_x = 192/128 = 1, page_y = 0, page_idx = 0*2+1 = 1,
|
||
// page_base = 1 * 8192 = 8192.
|
||
// bx = (192 % 128) / 16 = 64/16 = 4.
|
||
// by = (16 % 64) / 16 = 16/16 = 1.
|
||
// block (by=1, bx=4) → blockTable8[1][4] = 18 →
|
||
// block_base = 8192 + 18*256 = 12800.
|
||
// xb = 192%16 = 0, yb = 16%16 = 0 → byte = 0.
|
||
// addr = 12800.
|
||
// -----------------------------------------------------------
|
||
check(9'd0, 6'd4, 12'd192, 12'd16, 32'd12800, "fbw4-multi-page-x");
|
||
// FBW=4 + page-y crossing: (0, 64) → page (0, 1),
|
||
// page_idx = 1*2 + 0 = 2, page_base = 16384.
|
||
check(9'd0, 6'd4, 12'd0, 12'd64, 32'd16384, "fbw4-page-y-origin");
|
||
|
||
// -----------------------------------------------------------
|
||
// Non-page-aligned FBP coverage (real PS2 supports any
|
||
// 2048-byte-aligned FBP). FBP=1 → base 2048; FBP=2 → 4096;
|
||
// FBP=3 → 6144. (0,0) → addr = FBP*2048.
|
||
// -----------------------------------------------------------
|
||
check(9'd1, 6'd2, 12'd0, 12'd0, 32'd2048, "fbp1-mid-page-origin");
|
||
check(9'd2, 6'd2, 12'd0, 12'd0, 32'd4096, "fbp2-mid-page-origin");
|
||
check(9'd3, 6'd2, 12'd0, 12'd0, 32'd6144, "fbp3-mid-page-origin");
|
||
// FBP=3 + FBW=4 + intra-block + page-(1,1) crossing:
|
||
// (129, 65) → page (1, 1), page_idx = 1*2+1 = 3,
|
||
// page_base = 6144 + 3*8192 = 30720.
|
||
// bx = (129 % 128) / 16 = 1/16 = 0.
|
||
// by = (65 % 64) / 16 = 1/16 = 0.
|
||
// block (0,0) → swizzle 0 → block_base = 30720.
|
||
// xb = 129%16 = 1, yb = 65%16 = 1.
|
||
// byte = ref_col_idx8(1,1) = 12 → addr = 30732.
|
||
check(9'd3, 6'd4, 12'd129, 12'd65, 32'd30732,
|
||
"fbp3-fbw4-page1-1-intra");
|
||
|
||
$display("[tb_gs_swizzle_psmt8] errors=%0d", errors);
|
||
if (errors == 0) $display("[tb_gs_swizzle_psmt8] PASS");
|
||
else $display("[tb_gs_swizzle_psmt8] FAIL");
|
||
$finish;
|
||
end
|
||
|
||
initial begin
|
||
#500000;
|
||
$error("[tb_gs_swizzle_psmt8] timeout");
|
||
$finish;
|
||
end
|
||
|
||
endmodule : tb_gs_swizzle_psmt8
|