Line 36... |
Line 36... |
//
|
//
|
//
|
//
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <assert.h>
|
#include <assert.h>
|
|
|
|
#define PREFIX "DDR3-SDRAM"
|
const unsigned ckCL = 5,
|
const unsigned ckCL = 5,
|
ckRC = 3,
|
ckRC = 3,
|
ckRFC = 320, // Clocks from refresh to activate
|
ckRFC = 320, // Clocks from refresh to activate
|
nREF = 4,
|
nREF = 4,
|
ckREFI = 1560, // 7.8us @ 200MHz = 7.8e-6 * 200e6 = 1560
|
ckREFI = 1560, // 7.8us @ 200MHz = 7.8e-6 * 200e6 = 1560
|
Line 140... |
Line 141... |
} break;
|
} break;
|
case 4:
|
case 4:
|
m_reset_counts++;
|
m_reset_counts++;
|
assert(cke);
|
assert(cke);
|
if (cmd != DDR_NOOP) {
|
if (cmd != DDR_NOOP) {
|
printf("DDR3-SDRAM::RESET-CMD[4]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
printf(PREFIX "::RESET-CMD[4]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
assert(m_reset_counts > 3);
|
assert(m_reset_counts > 3);
|
m_reset_counts = 0;
|
m_reset_counts = 0;
|
m_reset_state = 5;
|
m_reset_state = 5;
|
assert(cmd == DDR_MRSET);
|
assert(cmd == DDR_MRSET);
|
assert(ba == 0);
|
assert(ba == 0);
|
Line 152... |
Line 153... |
} break;
|
} break;
|
case 5:
|
case 5:
|
m_reset_counts++;
|
m_reset_counts++;
|
assert(cke);
|
assert(cke);
|
if (cmd != DDR_NOOP) {
|
if (cmd != DDR_NOOP) {
|
printf("DDR3-SDRAM::RESET-CMD[5]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
printf(PREFIX "::RESET-CMD[5]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
assert(m_reset_counts > 11);
|
assert(m_reset_counts > 11);
|
m_reset_counts = 0;
|
m_reset_counts = 0;
|
m_reset_state = 6;
|
m_reset_state = 6;
|
assert(cmd == DDR_ZQS);
|
assert(cmd == DDR_ZQS);
|
assert(addr == 0x400);
|
assert(addr == 0x400);
|
} break;
|
} break;
|
case 6:
|
case 6:
|
m_reset_counts++;
|
m_reset_counts++;
|
assert(cke);
|
assert(cke);
|
if (cmd != DDR_NOOP) {
|
if (cmd != DDR_NOOP) {
|
printf("DDR3-SDRAM::RESET-CMD[6]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
printf(PREFIX "::RESET-CMD[6]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
assert(m_reset_counts > 512);
|
assert(m_reset_counts > 512);
|
m_reset_counts = 0;
|
m_reset_counts = 0;
|
m_reset_state = 7;
|
m_reset_state = 7;
|
assert(cmd == DDR_PRECHARGE);
|
assert(cmd == DDR_PRECHARGE);
|
assert(addr == 0x400);
|
assert(addr == 0x400);
|
} break;
|
} break;
|
case 7:
|
case 7:
|
m_reset_counts++;
|
m_reset_counts++;
|
assert(cke);
|
assert(cke);
|
if (cmd != DDR_NOOP) {
|
if (cmd != DDR_NOOP) {
|
printf("DDR3-SDRAM::RESET-CMD[7]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
printf(PREFIX "::RESET-CMD[7]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
|
assert(m_reset_counts > 3);
|
assert(m_reset_counts > 3);
|
m_reset_counts = 0;
|
m_reset_counts = 0;
|
m_reset_state = 8;
|
m_reset_state = 8;
|
assert(cmd == DDR_REFRESH);
|
assert(cmd == DDR_REFRESH);
|
m_clocks_since_refresh = 0;
|
m_clocks_since_refresh = 0;
|
Line 187... |
Line 188... |
m_reset_counts++;
|
m_reset_counts++;
|
assert(cke);
|
assert(cke);
|
assert(cmd == DDR_NOOP);
|
assert(cmd == DDR_NOOP);
|
if (m_reset_counts > 140) {
|
if (m_reset_counts > 140) {
|
m_reset_state = 16;
|
m_reset_state = 16;
|
printf("DDR3-SDRAM: Leaving reset state\n");
|
printf(PREFIX ": Leaving reset state\n");
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
Line 215... |
Line 216... |
}
|
}
|
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)
|
if (m_nrefresh_issued == nREF)
|
printf("DDRSDRAM::Refresh cycle complete\n");
|
printf(PREFIX "::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);
|
Line 246... |
Line 247... |
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);
|
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;
|
Line 267... |
Line 267... |
caddr <<= 10;
|
caddr <<= 10;
|
caddr |= addr;
|
caddr |= addr;
|
caddr &= ~7;
|
caddr &= ~7;
|
caddr >>= 1;
|
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;
|
int offset = m_busloc+ckCL+1;
|
|
|
tp = &m_bus[(offset+0)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+0)&(NTIMESLOTS-1)];
|
printf("Setting bus timeslots from (now=%d)+%d=%d to now+%d+3\n", m_busloc, ckCL,(m_busloc+ckCL)&(NTIMESLOTS-1), ckCL);
|
// 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_addr = caddr ;
|
tp->m_used = 1;
|
tp->m_used = 1;
|
tp->m_read = 0;
|
tp->m_read = 0;
|
|
|
tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
|
tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
|
Line 353... |
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);
|
printf(PREFIX "::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;
|