// File: /workspace/github_cpp_makefile_star2_O2/dramninjasUMD[P]BOBSim/Rank.cpp
// Function: BOBSim::Rank::ReceiveFromBus(BOBSim::BusPacket*)
void Rank::ReceiveFromBus(BusPacket *busPacket)
{
	if(DEBUG_CHANNEL) DEBUG("     == Rank "<<id<<" received : " << *busPacket);

	if(VERIFICATION_OUTPUT && busPacket->channel==0)
	{
		busPacket->PrintVerification(currentClockCycle);
	}

	switch(busPacket->busPacketType)
	{
	case REFRESH:
		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			if(bankStates[i].currentBankState != IDLE ||
			        bankStates[i].nextActivate > currentClockCycle)
			{
				ERROR("== Error - Refresh when not allowed in bank "<<i);
				ERROR("           NextAct : "<<bankStates[i].nextActivate);
				ERROR("           State : "<<bankStates[i].currentBankState);
				exit(0);
			}

			bankStates[i].lastCommand = REFRESH;
			bankStates[i].currentBankState = REFRESHING;
			bankStates[i].stateChangeCountdown = tRFC;
			bankStates[i].nextActivate = currentClockCycle + tRFC;
		}
		delete busPacket;
		break;
	case READ_P:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row ||
		        currentClockCycle < bankStates[busPacket->bank].nextRead)
		{
			ERROR("== Error - Rank receiving READ_P when not allowed");
			ERROR("           Current Clock Cycle : "<<currentClockCycle);
			ERROR(bankStates[busPacket->bank]);
			exit(0);
		}

		//
		//update bankstates
		//
		busPacket->busPacketType = READ_DATA;
		readReturnQueue.push_back(busPacket);
		readReturnCountdown.push_back(tCL);

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			bankStates[i].nextRead = max(bankStates[i].nextRead, currentClockCycle + tCCD);
			bankStates[i].nextWrite = max(bankStates[i].nextWrite, currentClockCycle + tCCD);
		}

		bankStates[busPacket->bank].lastCommand = READ_P;
		bankStates[busPacket->bank].stateChangeCountdown = tRTP;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tRTP + tRP;
		bankStates[busPacket->bank].nextRead = bankStates[busPacket->bank].nextActivate;
		bankStates[busPacket->bank].nextWrite = bankStates[busPacket->bank].nextActivate;
		break;
	case WRITE_P:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row ||
		        currentClockCycle < bankStates[busPacket->bank].nextWrite)
		{
			ERROR("== Error - Rank "<<id<<" receiving WRITE_P when not allowed");
			ERROR(bankStates[busPacket->bank]);
			ERROR("           currentClockCycle : "<<currentClockCycle);
			exit(0);
		}

		//
		//update bank states
		//

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			bankStates[i].nextRead = max(bankStates[i].nextRead, currentClockCycle + tCCD);
			bankStates[i].nextWrite = max(bankStates[i].nextWrite, currentClockCycle + tCCD);
		}
		bankStates[busPacket->bank].lastCommand = WRITE_P;
		bankStates[busPacket->bank].stateChangeCountdown = tCWL + TRANSACTION_SIZE/DRAM_BUS_WIDTH + tWR;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tCWL + busPacket->burstLength + tWR + tRP;
		bankStates[busPacket->bank].nextRead = bankStates[busPacket->bank].nextActivate;
		bankStates[busPacket->bank].nextWrite = bankStates[busPacket->bank].nextActivate;

		delete busPacket;
		break;
	case ACTIVATE:
		if(bankStates[busPacket->bank].currentBankState != IDLE ||
		        currentClockCycle < bankStates[busPacket->bank].nextActivate)
		{
			ERROR("== Error - Rank receiving ACT when not allowed");
			exit(0);
		}

		//
		//update bank states
		//
		bankStates[busPacket->bank].currentBankState = ROW_ACTIVE;
		bankStates[busPacket->bank].openRowAddress = busPacket->row;
		bankStates[busPacket->bank].nextRead = currentClockCycle + tRCD;
		bankStates[busPacket->bank].nextWrite = currentClockCycle + tRCD;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tRC;

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			if(i!=busPacket->bank)
			{
				bankStates[i].nextActivate = max(bankStates[i].nextActivate, currentClockCycle + tRRD);
			}
		}

		delete busPacket;
		break;
	case WRITE_DATA:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row)
		{
			ERROR("== Error - Clock Cycle : "<<currentClockCycle);
			ERROR("== Error - Rank receiving WRITE_DATA when not allowed: " << *busPacket <<endl << bankStates[busPacket->bank]);
			exit(0);
		}

		bankStates[busPacket->bank].stateChangeCountdown = tWR;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tWR + tRP;

		delete busPacket;
		break;
	default:
		ERROR("== Error - Rank receiving incorrect type of bus packet");
		break;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, (%rsp)
movl 0x4(%rsi), %eax
decl %eax
cmpl $0x7, %eax
ja 0xc5a2
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x42a6(%rip), %rcx      # 0x107a4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0xc95a
addq %rcx, %rax
movl 0x4(%rax), %ecx
cmpl 0xc(%r14), %ecx
jne 0xc95a
movq 0x8(%rbx), %rcx
cmpq 0x10(%rax), %rcx
jb 0xc95a
movl $0x7, 0x4(%r14)
leaq 0x30(%rbx), %rdi
movq %rsp, %rsi
callq 0xcd76
leaq 0x18(%rbx), %rdi
leaq 0x9d06(%rip), %rsi      # 0x16260
callq 0x90e6
movq 0x8(%rbx), %rax
movq 0x50(%rbx), %rcx
leaq 0x4(%rax), %rdx
xorl %esi, %esi
cmpq $0x200, %rsi            # imm = 0x200
je 0xc795
movq 0x10(%rcx,%rsi), %rdi
movq 0x18(%rcx,%rsi), %r8
cmpq %rdx, %rdi
cmovbeq %rdx, %rdi
cmpq %rdx, %r8
cmovbeq %rdx, %r8
movq %rdi, 0x10(%rcx,%rsi)
movq %r8, 0x18(%rcx,%rsi)
addq $0x40, %rsi
jmp 0xc56d
movq 0x9a47(%rip), %rdi      # 0x15ff0
leaq 0x2bd0(%rip), %rsi      # 0xf180
callq 0x2180
leaq 0x4217(%rip), %rsi      # 0x107d3
movq %rax, %rdi
callq 0x2180
leaq 0x2b5e(%rip), %rsi      # 0xf129
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movl $0xce, %esi
callq 0x22e0
leaq 0x2baa(%rip), %rsi      # 0xf191
movq %rax, %rdi
callq 0x2180
leaq 0x4367(%rip), %rsi      # 0x1095d
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x20b0
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x0, (%rax,%rcx)
jne 0xcba6
leaq (%rax,%rcx), %rsi
movq 0x8(%rbx), %rdx
cmpq 0x8(%rsi), %rdx
jb 0xcba6
movl $0x1, (%rsi)
movl 0xc(%r14), %esi
movl %esi, 0x4(%rax,%rcx)
leaq 0x9(%rdx), %rsi
movq %rsi, 0x10(%rax,%rcx)
movq %rsi, 0x18(%rax,%rcx)
leaq 0x21(%rdx), %rsi
movq %rsi, 0x8(%rax,%rcx)
addq $0x4, %rdx
xorl %esi, %esi
cmpq $0x200, %rsi            # imm = 0x200
je 0xc7f8
cmpq %rsi, %rcx
je 0xc68a
movq 0x8(%rax,%rsi), %rdi
cmpq %rdx, %rdi
cmovbeq %rdx, %rdi
movq %rdi, 0x8(%rax,%rsi)
addq $0x40, %rsi
jmp 0xc667
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0xca66
leaq (%rax,%rcx), %rdx
movl 0x4(%rdx), %esi
cmpl 0xc(%r14), %esi
jne 0xca66
movq 0x8(%rbx), %rsi
cmpq 0x18(%rdx), %rsi
jb 0xca66
leaq 0x4(%rsi), %rdi
xorl %r8d, %r8d
cmpq $0x200, %r8             # imm = 0x200
je 0xc7d1
movq 0x10(%rax,%r8), %r9
movq 0x18(%rax,%r8), %r10
cmpq %rdi, %r9
cmovbeq %rdi, %r9
cmpq %rdi, %r10
cmovbeq %rdi, %r10
movq %r9, 0x10(%rax,%r8)
movq %r10, 0x18(%rax,%r8)
addq $0x40, %r8
jmp 0xc6cc
movq 0x8(%rbx), %rax
movq 0x50(%rbx), %rcx
leaq 0x6b(%rax), %rdx
xorl %r12d, %r12d
movabsq $0x6b00000005, %rsi     # imm = 0x6B00000005
xorl %r15d, %r15d
cmpq $0x8, %r15
je 0xc7f8
cmpl $0x0, (%rcx,%r12)
jne 0xc811
cmpq %rax, 0x8(%rcx,%r12)
ja 0xc811
movq %rsi, 0x38(%rcx,%r12)
movl $0x3, (%rcx,%r12)
movq %rdx, 0x8(%rcx,%r12)
incq %r15
addq $0x40, %r12
jmp 0xc71d
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0xcc07
leaq (%rax,%rcx), %rdx
movl 0x4(%rdx), %esi
cmpl 0xc(%r14), %esi
jne 0xcc07
movl $0xa, 0x3c(%rdx)
movq 0x8(%rbx), %rdx
addq $0x13, %rdx
movq %rdx, 0x8(%rax,%rcx)
jmp 0xc7f8
movq (%rsp), %rdx
movl 0x10(%rdx), %edx
shlq $0x6, %rdx
movabsq $0x500000001, %rsi      # imm = 0x500000001
movq %rsi, 0x38(%rcx,%rdx)
addq $0xe, %rax
movq %rax, 0x8(%rcx,%rdx)
movq %rax, 0x10(%rcx,%rdx)
movq %rax, 0x18(%rcx,%rdx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movabsq $0x1500000003, %rdi     # imm = 0x1500000003
movq %rdi, 0x38(%rax,%rcx)
movl 0x24(%r14), %edi
addq %rdi, %rsi
addq $0x1a, %rsi
movq %rsi, 0x8(%rax,%rcx)
movq %rsi, 0x10(%rdx)
movq %rsi, 0x18(%rdx)
pushq $0x38
popq %rsi
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21b0
movq 0x97d8(%rip), %rdi      # 0x15ff0
leaq 0x2961(%rip), %rsi      # 0xf180
callq 0x2180
leaq 0x3fa8(%rip), %r13      # 0x107d3
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
leaq 0x28ec(%rip), %rbp      # 0xf129
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x5d
popq %rsi
movq %rax, %rdi
callq 0x22e0
leaq 0x2937(%rip), %r14      # 0xf191
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
leaq 0x3f70(%rip), %rsi      # 0x107dc
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movl %r15d, %esi
callq 0x2210
movq %rax, %rdi
callq 0x20b0
movq 0x9762(%rip), %r15      # 0x15ff0
movq %r15, %rdi
leaq 0x28e8(%rip), %rsi      # 0xf180
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x5e
popq %rsi
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
leaq 0x3f39(%rip), %rsi      # 0x10809
movq %rax, %rdi
callq 0x2180
movq 0x50(%rbx), %rcx
movq 0x8(%rcx,%r12), %rsi
movq %rax, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20b0
movq %r15, %rdi
leaq 0x2885(%rip), %rsi      # 0xf180
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x5f
popq %rsi
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
leaq 0x3eec(%rip), %rsi      # 0x1081f
movq %rax, %rdi
callq 0x2180
movq 0x50(%rbx), %rcx
movl (%rcx,%r12), %esi
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0x20b0
xorl %edi, %edi
callq 0x21d0
movq 0x968f(%rip), %r12      # 0x15ff0
leaq 0x2818(%rip), %rsi      # 0xf180
movq %r12, %rdi
callq 0x2180
leaq 0x3e5c(%rip), %r13      # 0x107d3
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
leaq 0x27a0(%rip), %rbp      # 0xf129
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x6f
popq %rsi
movq %rax, %rdi
callq 0x22e0
leaq 0x27eb(%rip), %r15      # 0xf191
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
leaq 0x3e7b(%rip), %rsi      # 0x10833
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq %r12, %rdi
leaq 0x27ae(%rip), %rsi      # 0xf180
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x70
popq %rsi
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
leaq 0x3e5b(%rip), %rsi      # 0x10865
movq %rax, %rdi
callq 0x2180
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20b0
movq %r12, %rdi
leaq 0x2750(%rip), %rsi      # 0xf180
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
pushq $0x71
popq %rsi
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
jmp 0xcce2
movq 0x9583(%rip), %rdi      # 0x15ff0
leaq 0x270c(%rip), %r13      # 0xf180
movq %r13, %rsi
callq 0x2180
leaq 0x3d50(%rip), %rbp      # 0x107d3
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
leaq 0x2694(%rip), %r15      # 0xf129
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
movq %rax, %rdi
movl $0x8d, %esi
callq 0x22e0
leaq 0x26dd(%rip), %r12      # 0xf191
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
leaq 0x3dc1(%rip), %rsi      # 0x10887
movq %rax, %rdi
callq 0x2180
movl 0x10(%rbx), %esi
movq %rax, %rdi
callq 0x2210
leaq 0x3db8(%rip), %rsi      # 0x10898
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0x94f9(%rip), %rdi      # 0x15ff0
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
movq %rax, %rdi
movl $0x8e, %esi
callq 0x22e0
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
movl 0x10(%r14), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0x963b
movq %rax, %rdi
callq 0x20b0
movq 0x94a0(%rip), %rdi      # 0x15ff0
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
movq %rax, %rdi
movl $0x8f, %esi
callq 0x22e0
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
leaq 0x3d2f(%rip), %rsi      # 0x108bc
movq %rax, %rdi
callq 0x2180
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x2050
jmp 0xc94b
movq 0x9443(%rip), %rdi      # 0x15ff0
leaq 0x25cc(%rip), %rsi      # 0xf180
callq 0x2180
leaq 0x3c13(%rip), %rsi      # 0x107d3
movq %rax, %rdi
callq 0x2180
leaq 0x255a(%rip), %rsi      # 0xf129
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movl $0xa8, %esi
callq 0x22e0
leaq 0x25a6(%rip), %rsi      # 0xf191
movq %rax, %rdi
callq 0x2180
leaq 0x3ce2(%rip), %rsi      # 0x108dc
movq %rax, %rdi
callq 0x2180
jmp 0xc94b
movq 0x93e2(%rip), %rdi      # 0x15ff0
leaq 0x256b(%rip), %r12      # 0xf180
movq %r12, %rsi
callq 0x2180
leaq 0x3baf(%rip), %r13      # 0x107d3
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
leaq 0x24f3(%rip), %rbp      # 0xf129
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq %rax, %rdi
movl $0xc3, %esi
callq 0x22e0
leaq 0x253c(%rip), %r15      # 0xf191
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
leaq 0x3ca4(%rip), %rsi      # 0x1090b
movq %rax, %rdi
callq 0x2180
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20b0
movq 0x9366(%rip), %rdi      # 0x15ff0
movq %r12, %rsi
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq %rax, %rdi
movl $0xc4, %esi
callq 0x22e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2180
leaq 0x3c5e(%rip), %rsi      # 0x10925
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movq %r14, %rsi
callq 0x98b8
movq %rax, %rdi
callq 0x20b0
movl 0x10(%r14), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0x963b
jmp 0xc94b
nop