public int CachedWriteWord(int addr,int value) {
	int windex = WriteWord(addr,value);

	if (cache && windex >= 0) {
	    cycles += 1;	// cache lookup takes one cycle

	    // check the appropriate line of each subcache
	    int aline = (addr >> lineShift) & lineMask;
	    int atag = (addr >> tagShift) & tagMask;
	    int index = aline;
	    for (int way = 0; way < nWays; way += 1) {
		if (valid[index] && tag[index] == atag) {
		    // hit!
		    writeHits += 1;
		    if (writeBack) dirty[index] = true;
		    else cycles += writeCycleCount;
		    if (replacementStrategy == LRU) age[index] = cycles;

		    if (parent.simulation == null)
			Message("addr=0x"+Integer.toHexString(addr)+": HIT @ way="+way+", line="+aline);

		    return windex;
		}
		index += nLines;
	    }

	    // miss -- select replacement and refill
	    Replace(addr,aline,atag,writeBack);

	    // write-through caches also write word to memory
	    if (!writeBack) cycles += writeCycleCount;
	} else cycles += writeCycleCount;

	writeMisses += 1;
	return windex;
    }