Real Intel Core chips use exactly this ways-per-set structure, 8-way L1, 4-way L2, and up to 16-way shared L3, because higher associativity at larger, slower cache levels curbs conflict misses without blowing up per-access comparison cost. The LRU replacement logic you implement is a simplified version of what Intel and AMD's cache controllers approximate in hardware, since true LRU tracking becomes expensive once associativity climbs above a handful of ways.