// File: dramninjasUMD[P]BOBSim/SimpleController.cpp
// Function: BOBSim::SimpleController::SimpleController(BOBSim::DRAMChannel*)
SimpleController::SimpleController(DRAMChannel *parent) :
	refreshCounter(0),
	readCounter(0),
	writeCounter(0),
	commandQueueMax(0),
	commandQueueAverage(0),
	numIdleBanksAverage(0),
	numActBanksAverage(0),
	numPreBanksAverage(0),
	numRefBanksAverage(0),
	RRQFull(0),
	waitingACTS(0),
	idd2nCount(0),
	rankBitWidth(log2(NUM_RANKS)),
	bankBitWidth(log2(NUM_BANKS)),
	rowBitWidth(log2(NUM_ROWS)),
	colBitWidth(log2(NUM_COLS)),
	busOffsetBitWidth(log2(BUS_ALIGNMENT_SIZE)),
	channelBitWidth(log2(NUM_CHANNELS)),
	cacheOffset(log2(CACHE_LINE_SIZE)),
	outstandingReads(0)

{
	/*
	  HACK!!! - QEMU does not support the huge memory sizes BOB can simulate.
	  Removing bits from the row address will have the least impact on function
	*/
	uint qemuMemoryBitWidth = log2(QEMU_MEMORY_SIZE);
	uint bitDifference = (busOffsetBitWidth + colBitWidth + rowBitWidth + channelBitWidth + rankBitWidth + bankBitWidth) - qemuMemoryBitWidth;
	rowBitWidth = rowBitWidth - bitDifference;
	//end hack

	//Registers the parent channel object
	channel = parent;

	//Initialize
	currentClockCycle = 0;

	//Make the bank state objects
	bankStates = (BankState**) malloc(sizeof(BankState*)*(NUM_RANKS));
	for(unsigned i=0; i<NUM_RANKS; i++)
	{
		bankStates[i]= (BankState*) calloc(sizeof(BankState), NUM_BANKS);
	}

	//Used to keep track of refreshes 
	refreshCounters = vector<unsigned>(NUM_RANKS,0);

	//make tFAW sliding window - one per rank
	tFAWWindow.reserve(NUM_RANKS);
	for(unsigned i=0; i<NUM_RANKS; i++)
	{
		tFAWWindow.push_back(vector<unsigned>());
	}


	//init power fields
	backgroundEnergy = vector<uint64_t>(NUM_RANKS,0);
	burstEnergy = vector<uint64_t>(NUM_RANKS,0);
	actpreEnergy = vector<uint64_t>(NUM_RANKS,0);
	refreshEnergy = vector<uint64_t>(NUM_RANKS,0);
	idd2nCount = vector<unsigned>(NUM_RANKS,0);


	//init refresh counters
	for(unsigned i=0; i<NUM_RANKS; i++)
	{
		refreshCounters[i] = ((7800/tCK)/NUM_RANKS)*(i+1);
	}
	//Prints all of the initialized refresh counters
	if(DEBUG_CHANNEL)
	{
		for(unsigned i=0; i<NUM_RANKS; i++)
		{
			PRINT(i<<"  "<<refreshCounters[i]);
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0xb5a0
movq -0x150(%rbp), %rdi
leaq 0x13ccf(%rip), %rax     # 0x37d70
movq %rax, (%rdi)
movl $0x0, 0x10(%rdi)
movl $0x0, 0x14(%rdi)
movl $0x0, 0x18(%rdi)
movl $0x0, 0x1c(%rdi)
movl $0x0, 0x20(%rdi)
movl $0x0, 0x24(%rdi)
addq $0x28, %rdi
movq %rdi, -0x198(%rbp)
callq 0x1a690
movq -0x150(%rbp), %rdi
subq $-0x80, %rdi
movq %rdi, -0x190(%rbp)
callq 0xb600
movq -0x150(%rbp), %rdi
addq $0x98, %rdi
movq %rdi, -0x188(%rbp)
callq 0x230b0
movq -0x150(%rbp), %rdi
addq $0xb0, %rdi
movq %rdi, -0x180(%rbp)
callq 0x16d00
movq -0x150(%rbp), %rdi
addq $0xc8, %rdi
movq %rdi, -0x178(%rbp)
callq 0xb600
movq -0x150(%rbp), %rdi
movl $0x0, 0xe0(%rdi)
movl $0x0, 0xe4(%rdi)
movl $0x0, 0xe8(%rdi)
movl $0x0, 0xec(%rdi)
movl $0x0, 0xf0(%rdi)
movl $0x0, 0xf4(%rdi)
addq $0xf8, %rdi
movq %rdi, -0x170(%rbp)
callq 0xb620
movq -0x150(%rbp), %rdi
addq $0x110, %rdi            # imm = 0x110
movq %rdi, -0x168(%rbp)
callq 0xb620
movq -0x150(%rbp), %rdi
addq $0x128, %rdi            # imm = 0x128
movq %rdi, -0x160(%rbp)
callq 0xb620
movq -0x150(%rbp), %rdi
addq $0x140, %rdi            # imm = 0x140
movq %rdi, -0x158(%rbp)
callq 0xb620
movq -0x150(%rbp), %rax
addq $0x158, %rax            # imm = 0x158
movq %rax, -0x148(%rbp)
leaq -0x11(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0xb7b0
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rdx
xorl %eax, %eax
movl %eax, %esi
callq 0x28610
jmp 0x24224
leaq -0x11(%rbp), %rdi
callq 0xb8e0
movq -0x150(%rbp), %rax
addq $0x188, %rax            # imm = 0x188
movq %rax, -0x1a8(%rbp)
movl 0x14231(%rip), %edi     # 0x38478
callq 0xb660
movl %eax, -0x19c(%rbp)
jmp 0x24254
movq -0x150(%rbp), %rax
movq -0x1a8(%rbp), %rcx
movl -0x19c(%rbp), %edx
movl %edx, (%rcx)
addq $0x18c, %rax            # imm = 0x18C
movq %rax, -0x1b8(%rbp)
movl 0x141ff(%rip), %edi     # 0x3847c
callq 0xb660
movl %eax, -0x1ac(%rbp)
jmp 0x2428a
movq -0x150(%rbp), %rax
movq -0x1b8(%rbp), %rcx
movl -0x1ac(%rbp), %edx
movl %edx, (%rcx)
addq $0x190, %rax            # imm = 0x190
movq %rax, -0x1c8(%rbp)
movl 0x141cd(%rip), %edi     # 0x38480
callq 0xb660
movl %eax, -0x1bc(%rbp)
jmp 0x242c0
movq -0x150(%rbp), %rax
movq -0x1c8(%rbp), %rcx
movl -0x1bc(%rbp), %edx
movl %edx, (%rcx)
addq $0x194, %rax            # imm = 0x194
movq %rax, -0x1d8(%rbp)
movl 0x1419f(%rip), %edi     # 0x38488
callq 0xb660
movl %eax, -0x1cc(%rbp)
jmp 0x242f6
movq -0x150(%rbp), %rax
movq -0x1d8(%rbp), %rcx
movl -0x1cc(%rbp), %edx
movl %edx, (%rcx)
addq $0x198, %rax            # imm = 0x198
movq %rax, -0x1e8(%rbp)
movl 0x14171(%rip), %edi     # 0x38490
callq 0xb660
movl %eax, -0x1dc(%rbp)
jmp 0x2432c
movq -0x150(%rbp), %rax
movq -0x1e8(%rbp), %rcx
movl -0x1dc(%rbp), %edx
movl %edx, (%rcx)
addq $0x19c, %rax            # imm = 0x19C
movq %rax, -0x1f8(%rbp)
movl 0x1413f(%rip), %edi     # 0x38494
callq 0xb660
movl %eax, -0x1ec(%rbp)
jmp 0x24362
movq -0x150(%rbp), %rax
movq -0x1f8(%rbp), %rcx
movl -0x1ec(%rbp), %edx
movl %edx, (%rcx)
addq $0x1a0, %rax            # imm = 0x1A0
movq %rax, -0x208(%rbp)
movl 0x1410d(%rip), %edi     # 0x38498
callq 0xb660
movl %eax, -0x1fc(%rbp)
jmp 0x24398
movq -0x208(%rbp), %rax
movl -0x1fc(%rbp), %ecx
movl %ecx, (%rax)
leaq 0x14182(%rip), %rax     # 0x38530
movl (%rax), %edi
callq 0xb660
movl %eax, -0x20c(%rbp)
jmp 0x243bd
movq -0x150(%rbp), %rax
movl -0x20c(%rbp), %ecx
movl %ecx, -0x28(%rbp)
movl 0x198(%rax), %ecx
addl 0x194(%rax), %ecx
addl 0x190(%rax), %ecx
addl 0x19c(%rax), %ecx
addl 0x188(%rax), %ecx
addl 0x18c(%rax), %ecx
subl -0x28(%rbp), %ecx
movl %ecx, -0x2c(%rbp)
movl 0x190(%rax), %ecx
subl -0x2c(%rbp), %ecx
movl %ecx, 0x190(%rax)
movq -0x10(%rbp), %rcx
movq %rcx, 0x170(%rax)
movq $0x0, 0x8(%rax)
movl 0x14059(%rip), %eax     # 0x38478
movl %eax, %edi
shlq $0x3, %rdi
callq 0x32c0
movq %rax, %rcx
movq -0x150(%rbp), %rax
movq %rcx, 0x78(%rax)
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl 0x14030(%rip), %eax     # 0x38478
jae 0x244a7
movl 0x1402c(%rip), %eax     # 0x3847c
movl %eax, %esi
movl $0x40, %edi
callq 0x3110
movq %rax, %rdx
movq -0x150(%rbp), %rax
movq 0x78(%rax), %rax
movl -0x30(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x2443f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x11(%rbp), %rdi
callq 0xb8e0
jmp 0x24a70
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x24a64
movl 0x13fcb(%rip), %eax     # 0x38478
movq %rax, -0x220(%rbp)
movl $0x0, -0x4c(%rbp)
leaq -0x4d(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0xb7b0
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rcx
leaq -0x48(%rbp), %rdi
leaq -0x4c(%rbp), %rdx
callq 0xb7d0
jmp 0x244e8
movq -0x150(%rbp), %rdi
addq $0xc8, %rdi
leaq -0x48(%rbp), %rsi
movq %rsi, -0x228(%rbp)
callq 0xb850
movq -0x228(%rbp), %rdi
callq 0xb880
leaq -0x4d(%rbp), %rdi
callq 0xb8e0
movq -0x150(%rbp), %rdi
addq $0xb0, %rdi
movl 0x13f49(%rip), %eax     # 0x38478
movl %eax, %esi
callq 0x28680
jmp 0x24538
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl 0x13f30(%rip), %eax     # 0x38478
jae 0x245de
movq -0x150(%rbp), %rax
addq $0xb0, %rax
movq %rax, -0x238(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movq $0x0, -0x60(%rbp)
leaq -0x70(%rbp), %rdi
movq %rdi, -0x230(%rbp)
callq 0xb600
movq -0x238(%rbp), %rdi
movq -0x230(%rbp), %rsi
callq 0x28780
jmp 0x24596
leaq -0x70(%rbp), %rdi
callq 0xb880
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x2453f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x4d(%rbp), %rdi
callq 0xb8e0
jmp 0x24a64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x70(%rbp), %rdi
callq 0xb880
jmp 0x24a64
movl 0x13e94(%rip), %eax     # 0x38478
movq %rax, -0x248(%rbp)
movq $0x0, -0x90(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0xba50
movq -0x248(%rbp), %rsi
movq -0x240(%rbp), %rcx
leaq -0x88(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0xba70
jmp 0x2462c
movq -0x150(%rbp), %rdi
addq $0xf8, %rdi
leaq -0x88(%rbp), %rsi
movq %rsi, -0x260(%rbp)
callq 0xbaf0
movq -0x260(%rbp), %rdi
callq 0xbb20
leaq -0x91(%rbp), %rdi
callq 0xbb80
movl 0x13e0d(%rip), %eax     # 0x38478
movq %rax, -0x258(%rbp)
movq $0x0, -0xb8(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0xba50
movq -0x258(%rbp), %rsi
movq -0x250(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
callq 0xba70
jmp 0x246b3
movq -0x150(%rbp), %rdi
addq $0x110, %rdi            # imm = 0x110
leaq -0xb0(%rbp), %rsi
movq %rsi, -0x278(%rbp)
callq 0xbaf0
movq -0x278(%rbp), %rdi
callq 0xbb20
leaq -0xb9(%rbp), %rdi
callq 0xbb80
movl 0x13d86(%rip), %eax     # 0x38478
movq %rax, -0x270(%rbp)
movq $0x0, -0xe0(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0xba50
movq -0x270(%rbp), %rsi
movq -0x268(%rbp), %rcx
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rdx
callq 0xba70
jmp 0x2473a
movq -0x150(%rbp), %rdi
addq $0x128, %rdi            # imm = 0x128
leaq -0xd8(%rbp), %rsi
movq %rsi, -0x290(%rbp)
callq 0xbaf0
movq -0x290(%rbp), %rdi
callq 0xbb20
leaq -0xe1(%rbp), %rdi
callq 0xbb80
movl 0x13cff(%rip), %eax     # 0x38478
movq %rax, -0x288(%rbp)
movq $0x0, -0x108(%rbp)
leaq -0x109(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0xba50
movq -0x288(%rbp), %rsi
movq -0x280(%rbp), %rcx
leaq -0x100(%rbp), %rdi
leaq -0x108(%rbp), %rdx
callq 0xba70
jmp 0x247c1
movq -0x150(%rbp), %rdi
addq $0x140, %rdi            # imm = 0x140
leaq -0x100(%rbp), %rsi
movq %rsi, -0x2a8(%rbp)
callq 0xbaf0
movq -0x2a8(%rbp), %rdi
callq 0xbb20
leaq -0x109(%rbp), %rdi
callq 0xbb80
movl 0x13c78(%rip), %eax     # 0x38478
movq %rax, -0x2a0(%rbp)
movl $0x0, -0x12c(%rbp)
leaq -0x12d(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0xb7b0
movq -0x2a0(%rbp), %rsi
movq -0x298(%rbp), %rcx
leaq -0x128(%rbp), %rdi
leaq -0x12c(%rbp), %rdx
callq 0xb7d0
jmp 0x24847
movq -0x150(%rbp), %rdi
addq $0x158, %rdi            # imm = 0x158
leaq -0x128(%rbp), %rsi
callq 0xb850
leaq -0x128(%rbp), %rdi
callq 0xb880
leaq -0x12d(%rbp), %rdi
callq 0xb8e0
movl $0x0, -0x134(%rbp)
movl -0x134(%rbp), %eax
cmpl 0x13be9(%rip), %eax     # 0x38478
jae 0x2499c
movq -0x150(%rbp), %rdi
movss 0x13bf8(%rip), %xmm1    # 0x3849c
movss 0x77e8(%rip), %xmm0     # 0x2c094
divss %xmm1, %xmm0
movl 0x13bc2(%rip), %eax     # 0x38478
cvtsi2ss %rax, %xmm1
divss %xmm1, %xmm0
movl -0x134(%rbp), %eax
incl %eax
cvtsi2ss %rax, %xmm1
mulss %xmm1, %xmm0
cvttss2si %xmm0, %rax
movl %eax, -0x2ac(%rbp)
addq $0xc8, %rdi
movl -0x134(%rbp), %eax
movl %eax, %esi
callq 0xbec0
movl -0x2ac(%rbp), %ecx
movl %ecx, (%rax)
movl -0x134(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x134(%rbp)
jmp 0x24883
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x91(%rbp), %rdi
callq 0xbb80
jmp 0x24a64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xb9(%rbp), %rdi
callq 0xbb80
jmp 0x24a64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xe1(%rbp), %rdi
callq 0xbb80
jmp 0x24a64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x109(%rbp), %rdi
callq 0xbb80
jmp 0x24a64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x12d(%rbp), %rdi
callq 0xb8e0
jmp 0x24a64
testb $0x1, 0x13ea3(%rip)     # 0x38846
je 0x24a5b
movl $0x0, -0x138(%rbp)
movl -0x138(%rbp), %eax
cmpl 0x13ab9(%rip), %eax     # 0x38478
jae 0x24a59
movl -0x138(%rbp), %esi
movq 0x135f6(%rip), %rdi     # 0x37fc8
callq 0x32d0
movq %rax, -0x2b8(%rbp)
jmp 0x249e0
movq -0x2b8(%rbp), %rdi
leaq 0x5e27(%rip), %rsi      # 0x2a815
callq 0x31c0
movq %rax, -0x2c0(%rbp)
jmp 0x249fc
movq -0x150(%rbp), %rdi
addq $0xc8, %rdi
movl -0x138(%rbp), %eax
movl %eax, %esi
callq 0xbec0
movq -0x2c0(%rbp), %rdi
movl (%rax), %esi
callq 0x32d0
movq %rax, -0x2c8(%rbp)
jmp 0x24a2e
movq -0x2c8(%rbp), %rdi
movq 0x1356c(%rip), %rsi     # 0x37fa8
callq 0x3200
jmp 0x24a43
jmp 0x24a45
movl -0x138(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x138(%rbp)
jmp 0x249b3
jmp 0x24a5b
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
movq -0x148(%rbp), %rdi
callq 0xb880
movq -0x158(%rbp), %rdi
callq 0xbb20
movq -0x160(%rbp), %rdi
callq 0xbb20
movq -0x168(%rbp), %rdi
callq 0xbb20
movq -0x170(%rbp), %rdi
callq 0xbb20
movq -0x178(%rbp), %rdi
callq 0xb880
movq -0x180(%rbp), %rdi
callq 0x16e60
movq -0x188(%rbp), %rdi
callq 0x1b2c0
movq -0x190(%rbp), %rdi
callq 0xb880
movq -0x198(%rbp), %rdi
callq 0x1a9c0
movq -0x20(%rbp), %rdi
callq 0x33a0
nopw %cs:(%rax,%rax)