public String toString()
	{
		String stats = "";
		
		DecimalFormat f = new DecimalFormat("###.##");
		stats += "-------- SIMULATION STATISTICS --------\n";
		stats += "Cycles: " + getCycles() + "\n";
		stats += "Executed instructions: " + getInstructions() + "\n";
		stats += "Performed fetches: " + getFetches() + "\n";
		if(icache || dcache)
		{
			stats += "Cache statistics:\n";
			stats += "Icache: " + ((icache)?("used"):("not used")) + " rpol: " + icache_replacement_policy + " lines: " + icache_line_no + " associativity: " + icache_associativity + " line_size: " + icache_line_size + " total size: " + icache_size + "\n";
			if(icache)
			{
				stats += "Accesses:" + icache_accesses  + " hits: " + icache_hits + " misses: " + icache_misses;
				if(icache_accesses > 0)
				{
					stats += " hit rate: " + f.format((double)icache_hits/(double)icache_accesses * (double)100) + "%";
				}
				stats += " loaded words: " + icache_words_loaded + "\n";
			}
			stats += "Dcache: " + ((dcache)?("used"):("not used")) + " rpol: " + dcache_replacement_policy + " wpol: " + dcache_write_policy + " lines: " + dcache_line_no + " associativity: " + dcache_associativity + " line_size: " + dcache_line_size + " total size: " + dcache_size + "\n";
			if(dcache)
			{
				stats += "Accesses: " + dcache_accesses + " hits: " + dcache_hits + " misses: " + dcache_misses;
				if(dcache_accesses > 0)
				{
					stats += " hit rate: " + f.format((double)dcache_hits/(double)dcache_accesses * (double)100) + "%";
				}
				stats += " loaded words: " + dcache_words_loaded + "\n";
			}
		}
		stats += "Jumps: " + (getJumps_taken()+getJumps_nottaken()) + " (taken: " + getJumps_taken() + ", not taken: " + getJumps_nottaken() + ") branches_likely: " + getJumps_likely() +  " branches_and_link: " + getJumps_link() + "\n";
		stats += "Branch Target Buffer (" + getBtb_size() + ", " + getBtb_predictor() + "): hits: " + getBtb_hits() + " misses: " + getBtb_misses() + "\n";
		stats += "Jumps correctly predicted: " + getJumps_correctly_predicted() + " mispredicted: " + getJumps_mispredicted();
		if(getJumps_correctly_predicted()+getJumps_mispredicted()>0)
		{
			stats += " misprediction rate: " + f.format(((double)getJumps_mispredicted())/((double)(getJumps_correctly_predicted()+getJumps_mispredicted()))*100) + "%";
		}
		stats += "\n";
		stats += "Number of unique jumps: " + getBranches_map().size() + "\n";
		stats += printBranchInformation(0);
		stats += "Memory accesses: " + (getMemory_reads() + getMemory_writes()) + " (reads: " + getMemory_reads() + ", writes: " + getMemory_writes() + ")\n";
		stats += "ALU forwarded values: " + (getAlu_forward_from_ex() + getAlu_forward_from_mem() + getAlu_forward_from_wb()) + " (from execute: " + getAlu_forward_from_ex() + ", memory stage: " + getAlu_forward_from_mem() + ", write back: " + getAlu_forward_from_wb() + ")\n";
		stats += "BCRTL forwarded values: " + (getBcrtl_forward_from_ex() + getBcrtl_forward_from_mem() + getBcrtl_forward_from_wb()) + " (from execute: " + getBcrtl_forward_from_ex() + ", memory stage: " + getBcrtl_forward_from_mem() + ", write back: " + getBcrtl_forward_from_wb() + ")\n";
		stats += "STORE forwarded values: " + (getStore_forward_from_ex() + getStore_forward_from_mem() + getStore_forward_from_wb()) + " (from execute: " + getStore_forward_from_ex() + ", memory stage: " + getStore_forward_from_mem() + ", write back: " + getStore_forward_from_wb() + ")\n";
		stats += "Total forwarded values: " + (getForward_from_ex() + getForward_from_mem() + getForward_from_wb()) + " (from execute: " + getForward_from_ex() + ", memory stage: " + getForward_from_mem() + ", write back: " + getForward_from_wb() + ")\n";
		stats += "-------- SIMULATION STATISTICS --------\n";
		
		return stats;
	}