Line 191... |
Line 191... |
}
|
}
|
|
|
gbl_state = m_reset_state;
|
gbl_state = m_reset_state;
|
gbl_counts= m_reset_counts;
|
gbl_counts= m_reset_counts;
|
m_nrefresh_issued = nREF;
|
m_nrefresh_issued = nREF;
|
|
m_clocks_since_refresh++;
|
} else if (!cke) {
|
} else if (!cke) {
|
assert(0&&"Clock not enabled!");
|
assert(0&&"Clock not enabled!");
|
} else if ((cmd == DDR_REFRESH)||(m_nrefresh_issued < (int)nREF)) {
|
} else if ((cmd == DDR_REFRESH)||(m_nrefresh_issued < (int)nREF)) {
|
if (DDR_REFRESH == cmd) {
|
if (DDR_REFRESH == cmd) {
|
m_clocks_since_refresh = 0;
|
m_clocks_since_refresh = 0;
|
if (m_nrefresh_issued >= (int)nREF)
|
if (m_nrefresh_issued >= (int)nREF)
|
m_nrefresh_issued = 0;
|
m_nrefresh_issued = 1;
|
else
|
else
|
m_nrefresh_issued++;
|
m_nrefresh_issued++;
|
} else {
|
} else {
|
m_clocks_since_refresh++;
|
m_clocks_since_refresh++;
|
assert(DDR_NOOP == cmd);
|
assert(DDR_NOOP == cmd);
|
}
|
}
|
for(int i=0; i<NBANKS; i++)
|
for(int i=0; i<NBANKS; i++)
|
m_bank[i].tick(DDR_REFRESH,0);
|
m_bank[i].tick(DDR_REFRESH,0);
|
|
|
|
if (m_nrefresh_issued == nREF)
|
|
printf("DDRSDRAM::Refresh cycle complete\n");
|
} else {
|
} else {
|
// In operational mode!!
|
// In operational mode!!
|
|
|
m_clocks_since_refresh++;
|
m_clocks_since_refresh++;
|
assert(m_clocks_since_refresh < (int)ckREFIn);
|
assert(m_clocks_since_refresh < (int)ckREFIn);
|
|
printf("Clocks to refresh should be %4d-%4d = %4d = 0x%04x\n",
|
|
ckREFIn, m_clocks_since_refresh,
|
|
ckREFIn- m_clocks_since_refresh,
|
|
ckREFIn- m_clocks_since_refresh);
|
switch(cmd) {
|
switch(cmd) {
|
case DDR_MRSET:
|
case DDR_MRSET:
|
assert(0&&"Modes should only be set in reset startup");
|
assert(0&&"Modes should only be set in reset startup");
|
for(int i=0; i<NBANKS; i++)
|
for(int i=0; i<NBANKS; i++)
|
m_bank[i].tick(DDR_MRSET,0);
|
m_bank[i].tick(DDR_MRSET,0);
|
Line 236... |
Line 244... |
if (ba != i)
|
if (ba != i)
|
m_bank[i].tick(DDR_NOOP,0);
|
m_bank[i].tick(DDR_NOOP,0);
|
}
|
}
|
break;
|
break;
|
case DDR_ACTIVATE:
|
case DDR_ACTIVATE:
|
|
printf("DDRSIM::ACTIVE, clocks_since_refresh = %d >= %d\n", m_clocks_since_refresh, ckRFC);
|
|
assert(m_clocks_since_refresh >= (int)ckRFC);
|
m_bank[ba].tick(DDR_ACTIVATE,addr);
|
m_bank[ba].tick(DDR_ACTIVATE,addr);
|
for(int i=0; i<NBANKS; i++)
|
for(int i=0; i<NBANKS; i++)
|
if (i!=ba) m_bank[i].tick(DDR_NOOP,0);
|
if (i!=ba) m_bank[i].tick(DDR_NOOP,0);
|
break;
|
break;
|
case DDR_WRITE:
|
case DDR_WRITE:
|
Line 247... |
Line 257... |
// This SIM doesn't handle out of order writes
|
// This SIM doesn't handle out of order writes
|
assert((addr&7)==0);
|
assert((addr&7)==0);
|
m_bank[ba].tick(DDR_WRITE, addr);
|
m_bank[ba].tick(DDR_WRITE, addr);
|
for(int i=0; i<NBANKS; i++)
|
for(int i=0; i<NBANKS; i++)
|
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
|
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
|
unsigned addr = m_bank[ba].m_row;
|
unsigned caddr = m_bank[ba].m_row;
|
addr <<= 13;
|
caddr <<= 13;
|
addr |= ba;
|
caddr |= ba;
|
addr <<= 10;
|
caddr <<= 10;
|
addr |= addr;
|
caddr |= addr;
|
addr &= ~3;
|
caddr &= ~7;
|
|
caddr >>= 1;
|
|
|
|
printf("DDRSDRAM::WRITE ADDR = %04x|%d|%04x|%d -> %06x\n",
|
|
m_bank[ba].m_row, ba, addr, 0, caddr);
|
|
|
BUSTIMESLOT *tp;
|
BUSTIMESLOT *tp;
|
|
int offset = m_busloc+ckCL+1;
|
|
|
tp = &m_bus[(m_busloc+ckCL+0)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+0)&(NTIMESLOTS-1)];
|
tp->m_addr = addr ;
|
printf("Setting bus timeslots from (now=%d)+%d=%d to now+%d+3\n", m_busloc, ckCL,(m_busloc+ckCL)&(NTIMESLOTS-1), ckCL);
|
|
tp->m_addr = caddr ;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 0;
|
tp->m_read = 0;
|
|
|
tp = &m_bus[(m_busloc+ckCL+1)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
|
tp->m_addr = addr+1;
|
tp->m_addr = caddr+1;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 0;
|
tp->m_read = 0;
|
|
|
tp = &m_bus[(m_busloc+ckCL+2)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+2)&(NTIMESLOTS-1)];
|
tp->m_addr = addr+2;
|
tp->m_addr = caddr+2;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 0;
|
tp->m_read = 0;
|
|
|
tp = &m_bus[(m_busloc+ckCL+3)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+3)&(NTIMESLOTS-1)];
|
tp->m_addr = addr+3;
|
tp->m_addr = caddr+3;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 0;
|
tp->m_read = 0;
|
} break;
|
} break;
|
case DDR_READ:
|
case DDR_READ:
|
{
|
{
|
// This SIM doesn't handle out of order reads
|
// This SIM doesn't handle out of order reads
|
assert((addr&7)==0);
|
assert((addr&7)==0);
|
m_bank[ba].tick(DDR_READ, addr);
|
m_bank[ba].tick(DDR_READ, addr);
|
for(int i=0; i<NBANKS; i++)
|
for(int i=0; i<NBANKS; i++)
|
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
|
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
|
unsigned addr = m_bank[ba].m_row;
|
unsigned caddr = m_bank[ba].m_row;
|
addr <<= 13;
|
caddr <<= 13;
|
addr |= ba;
|
caddr |= ba;
|
addr <<= 10;
|
caddr <<= 10;
|
addr |= addr;
|
caddr |= addr;
|
addr &= ~3;
|
caddr &= ~7;
|
|
caddr >>= 1;
|
|
|
BUSTIMESLOT *tp;
|
BUSTIMESLOT *tp;
|
|
|
tp = &m_bus[(m_busloc+ckCL+0)&(NTIMESLOTS-1)];
|
tp = &m_bus[(m_busloc+ckCL+0)&(NTIMESLOTS-1)];
|
tp->m_data = m_mem[addr];
|
tp->m_data = m_mem[caddr];
|
tp->m_addr = addr;
|
tp->m_addr = caddr;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 1;
|
tp->m_read = 1;
|
|
|
tp = &m_bus[(m_busloc+ckCL+1)&(NTIMESLOTS-1)];
|
tp = &m_bus[(m_busloc+ckCL+1)&(NTIMESLOTS-1)];
|
tp->m_data = m_mem[addr+1];
|
tp->m_data = m_mem[caddr+1];
|
tp->m_addr = addr+1;
|
tp->m_addr = caddr+1;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 1;
|
tp->m_read = 1;
|
|
|
tp = &m_bus[(m_busloc+ckCL+2)&(NTIMESLOTS-1)];
|
tp = &m_bus[(m_busloc+ckCL+2)&(NTIMESLOTS-1)];
|
tp->m_data = m_mem[addr+2];
|
tp->m_data = m_mem[caddr+2];
|
tp->m_addr = addr+2;
|
tp->m_addr = caddr+2;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 1;
|
tp->m_read = 1;
|
|
|
tp = &m_bus[(m_busloc+ckCL+3)&(NTIMESLOTS-1)];
|
tp = &m_bus[(m_busloc+ckCL+3)&(NTIMESLOTS-1)];
|
tp->m_data = m_mem[addr+3];
|
tp->m_data = m_mem[caddr+3];
|
tp->m_addr = addr+3;
|
tp->m_addr = caddr+3;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 1;
|
tp->m_read = 1;
|
} break;
|
} break;
|
case DDR_ZQS:
|
case DDR_ZQS:
|
assert(0&&"Sim does not support ZQS outside of startup");
|
assert(0&&"Sim does not support ZQS outside of startup");
|
Line 333... |
Line 350... |
}
|
}
|
|
|
m_busloc = (m_busloc+1)&(NTIMESLOTS-1);
|
m_busloc = (m_busloc+1)&(NTIMESLOTS-1);
|
|
|
BUSTIMESLOT *ts = &m_bus[m_busloc];
|
BUSTIMESLOT *ts = &m_bus[m_busloc];
|
|
if (ts->m_used) {
|
|
printf("Current timeslot = %2d, used", m_busloc);
|
|
if (ts->m_read)
|
|
printf(", read");
|
|
printf("\n");
|
|
}
|
unsigned vl = ts->m_data;
|
unsigned vl = ts->m_data;
|
assert( ((!ts->m_used)||(busoe))
|
assert( ((!ts->m_used)||(busoe))
|
|| ((ts->m_used)&&(ts->m_read)));
|
|| ((ts->m_used)&&(ts->m_read)));
|
|
|
assert((!ts->m_used)||(ts->m_addr < (unsigned)m_memlen));
|
assert((!ts->m_used)||(ts->m_addr < (unsigned)m_memlen));
|
if ((ts->m_used)&&(!ts->m_read)&&(!dm))
|
if ((ts->m_used)&&(!ts->m_read)&&(!dm)) {
|
|
printf("Setting MEM[%08x] = %08x\n", ts->m_addr, data);
|
m_mem[ts->m_addr] = data;
|
m_mem[ts->m_addr] = data;
|
|
}
|
ts->m_used = 0;
|
ts->m_used = 0;
|
ts->m_read = 0;
|
ts->m_read = 0;
|
ts->m_addr = -1;
|
ts->m_addr = -1;
|
return (!busoe)?vl:data;
|
return (!busoe)?vl:data;
|
}
|
}
|