URL
https://opencores.org/ocsvn/wbddr3/wbddr3/trunk
Subversion Repositories wbddr3
Compare Revisions
- This comparison shows the changes necessary to convert path
/wbddr3
- from Rev 6 to Rev 7
- ↔ Reverse comparison
Rev 6 → Rev 7
/trunk/bench/cpp/ddrsdram_tb.cpp
83,6 → 83,7
m_core->o_ddr_data); |
|
bool writeout = (!m_core->v__DOT__reset_override); |
writeout = true; |
|
if (writeout) { |
int cmd; |
122,7 → 123,21
(m_core->i_ddr_data), |
(m_core->o_ddr_data)); |
|
/* |
printf(" FIFO[%x,%x](%d,%d,%08x-%08x-%08x)", |
m_core->v__DOT__bus_fifo_head, |
m_core->v__DOT__bus_fifo_tail, |
m_core->v__DOT__bus_fifo_new[m_core->v__DOT__bus_fifo_tail], |
m_core->v__DOT__bus_fifo_sub[m_core->v__DOT__bus_fifo_tail], |
m_core->v__DOT__r_data, |
m_core->v__DOT__bus_fifo_data[(m_core->v__DOT__bus_fifo_head-1)&15], |
m_core->v__DOT__bus_fifo_data[m_core->v__DOT__bus_fifo_tail]); |
|
printf(" BUS[%03x/%03x/%03x/%d]", |
(m_core->v__DOT__bus_active), |
(m_core->v__DOT__bus_read), |
(m_core->v__DOT__bus_new), |
(m_core->v__DOT__bus_subaddr[8])); |
|
// Reset logic |
printf(" RST(%06x%s[%d] - %08x->%08x)", |
m_core->v__DOT__reset_timer, |
130,7 → 145,6
(m_core->v__DOT__reset_address), |
(m_core->v__DOT__reset_instruction), |
(m_core->v__DOT__reset_cmd)); |
*/ |
|
printf(" %s%03x[%d]%04x:%d", |
(m_core->v__DOT__r_pending)?"R":" ", |
139,13 → 153,14
(m_core->v__DOT__r_col),0); |
// (m_core->v__DOT__r_sub)); |
printf(" %s%s%s", |
(m_core->v__DOT__all_banks_closed)?"b":"B", |
"B", |
// (m_core->v__DOT__all_banks_closed)?"b":"B", |
(m_core->v__DOT__need_close_bank)?"C":"N", |
//:(m_core->v__DOT__maybe_close_next_bank)?"c":"N", |
(m_core->v__DOT__need_open_bank)?"O":"K"); |
// :(m_core->v__DOT__maybe_open_next_bank)?"o":"K"); |
for(int i=0; i<8; i++) { |
printf("%s%x@%05x%s", |
printf("%s%x@%x%s", |
(m_core->v__DOT__r_bank==i)?"R":"[", |
m_core->v__DOT__bank_status[i], |
m_core->v__DOT__bank_address[i], |
156,22 → 171,22
extern int gbl_state, gbl_counts; |
printf(" %2d:%08x ", gbl_state, gbl_counts); |
|
printf(" %s%s%s%s%s:%08x:%08x", |
printf(" %s%s%s%s%s%s%s:%08x:%08x", |
(m_core->v__DOT__reset_override)?"R":" ", |
(m_core->v__DOT__need_refresh)?"N":" ", |
(m_core->v__DOT__need_close_bank)?"C":" ", |
(m_core->v__DOT__need_open_bank)?"O":" ", |
(m_core->v__DOT__valid_bank)?"V":" ", |
(m_core->v__DOT__r_move)?"R":" ", |
(m_core->v__DOT__m_move)?"M":" ", |
m_core->v__DOT__activate_bank_cmd, |
m_core->v__DOT__cmd); |
|
printf(" F%05x:%d%d%d:%d:%08x", |
m_core->v__DOT__refresh_clk, |
m_core->v__DOT__need_refresh, |
m_core->v__DOT__midrefresh, |
m_core->v__DOT__endrefresh, |
m_core->v__DOT__midrefresh_hctr, |
m_core->v__DOT__midrefresh_lctr); |
printf(" F%s%05x:%x/%s", |
(m_core->v__DOT__refresh_ztimer)?"Z":" ", |
m_core->v__DOT__refresh_counter, |
m_core->v__DOT__refresh_addr, |
(m_core->v__DOT__need_refresh)?"N":" "); |
|
if (m_core->v__DOT__reset_override) |
printf(" OVERRIDE"); |
413,7 → 428,7
printf("Giving the core 140k cycles to start up\n"); |
// Before testing, let's give the unit time enough to warm up |
tb->reset(); |
for(int i=0; i<140850; i++) |
for(int i=0; i<141195; i++) |
tb->wb_tick(); |
|
printf("Getting some memory ...\n"); |
/trunk/bench/cpp/ddrsdramsim.cpp
193,6 → 193,7
gbl_state = m_reset_state; |
gbl_counts= m_reset_counts; |
m_nrefresh_issued = nREF; |
m_clocks_since_refresh++; |
} else if (!cke) { |
assert(0&&"Clock not enabled!"); |
} else if ((cmd == DDR_REFRESH)||(m_nrefresh_issued < (int)nREF)) { |
199,7 → 200,7
if (DDR_REFRESH == cmd) { |
m_clocks_since_refresh = 0; |
if (m_nrefresh_issued >= (int)nREF) |
m_nrefresh_issued = 0; |
m_nrefresh_issued = 1; |
else |
m_nrefresh_issued++; |
} else { |
208,11 → 209,18
} |
for(int i=0; i<NBANKS; i++) |
m_bank[i].tick(DDR_REFRESH,0); |
|
if (m_nrefresh_issued == nREF) |
printf("DDRSDRAM::Refresh cycle complete\n"); |
} else { |
// In operational mode!! |
|
m_clocks_since_refresh++; |
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) { |
case DDR_MRSET: |
assert(0&&"Modes should only be set in reset startup"); |
238,6 → 246,8
} |
break; |
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); |
for(int i=0; i<NBANKS; i++) |
if (i!=ba) m_bank[i].tick(DDR_NOOP,0); |
249,32 → 259,38
m_bank[ba].tick(DDR_WRITE, addr); |
for(int i=0; i<NBANKS; i++) |
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr); |
unsigned addr = m_bank[ba].m_row; |
addr <<= 13; |
addr |= ba; |
addr <<= 10; |
addr |= addr; |
addr &= ~3; |
unsigned caddr = m_bank[ba].m_row; |
caddr <<= 13; |
caddr |= ba; |
caddr <<= 10; |
caddr |= addr; |
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; |
int offset = m_busloc+ckCL+1; |
|
tp = &m_bus[(m_busloc+ckCL+0)&(NTIMESLOTS-1)]; |
tp->m_addr = addr ; |
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); |
tp->m_addr = caddr ; |
tp->m_used = 1; |
tp->m_read = 0; |
|
tp = &m_bus[(m_busloc+ckCL+1)&(NTIMESLOTS-1)]; |
tp->m_addr = addr+1; |
tp = &m_bus[(offset+1)&(NTIMESLOTS-1)]; |
tp->m_addr = caddr+1; |
tp->m_used = 1; |
tp->m_read = 0; |
|
tp = &m_bus[(m_busloc+ckCL+2)&(NTIMESLOTS-1)]; |
tp->m_addr = addr+2; |
tp = &m_bus[(offset+2)&(NTIMESLOTS-1)]; |
tp->m_addr = caddr+2; |
tp->m_used = 1; |
tp->m_read = 0; |
|
tp = &m_bus[(m_busloc+ckCL+3)&(NTIMESLOTS-1)]; |
tp->m_addr = addr+3; |
tp = &m_bus[(offset+3)&(NTIMESLOTS-1)]; |
tp->m_addr = caddr+3; |
tp->m_used = 1; |
tp->m_read = 0; |
} break; |
285,36 → 301,37
m_bank[ba].tick(DDR_READ, addr); |
for(int i=0; i<NBANKS; i++) |
if (i!=ba)m_bank[i].tick(DDR_NOOP,addr); |
unsigned addr = m_bank[ba].m_row; |
addr <<= 13; |
addr |= ba; |
addr <<= 10; |
addr |= addr; |
addr &= ~3; |
unsigned caddr = m_bank[ba].m_row; |
caddr <<= 13; |
caddr |= ba; |
caddr <<= 10; |
caddr |= addr; |
caddr &= ~7; |
caddr >>= 1; |
|
BUSTIMESLOT *tp; |
|
tp = &m_bus[(m_busloc+ckCL+0)&(NTIMESLOTS-1)]; |
tp->m_data = m_mem[addr]; |
tp->m_addr = addr; |
tp->m_data = m_mem[caddr]; |
tp->m_addr = caddr; |
tp->m_used = 1; |
tp->m_read = 1; |
|
tp = &m_bus[(m_busloc+ckCL+1)&(NTIMESLOTS-1)]; |
tp->m_data = m_mem[addr+1]; |
tp->m_addr = addr+1; |
tp->m_data = m_mem[caddr+1]; |
tp->m_addr = caddr+1; |
tp->m_used = 1; |
tp->m_read = 1; |
|
tp = &m_bus[(m_busloc+ckCL+2)&(NTIMESLOTS-1)]; |
tp->m_data = m_mem[addr+2]; |
tp->m_addr = addr+2; |
tp->m_data = m_mem[caddr+2]; |
tp->m_addr = caddr+2; |
tp->m_used = 1; |
tp->m_read = 1; |
|
tp = &m_bus[(m_busloc+ckCL+3)&(NTIMESLOTS-1)]; |
tp->m_data = m_mem[addr+3]; |
tp->m_addr = addr+3; |
tp->m_data = m_mem[caddr+3]; |
tp->m_addr = caddr+3; |
tp->m_used = 1; |
tp->m_read = 1; |
} break; |
335,13 → 352,21
m_busloc = (m_busloc+1)&(NTIMESLOTS-1); |
|
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; |
assert( ((!ts->m_used)||(busoe)) |
|| ((ts->m_used)&&(ts->m_read))); |
|
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; |
} |
ts->m_used = 0; |
ts->m_read = 0; |
ts->m_addr = -1; |
/trunk/rtl/wbddrsdram.v
55,6 → 55,12
`define DDR_RSTTIMER 23 // Does this reset command take multiple clocks? |
`define DDR_RSTBIT 22 // Value to place on reset_n |
`define DDR_CKEBIT 21 // Should this reset command set CKE? |
// |
// Refresh command bit fields |
`define DDR_NEEDREFRESH 23 |
`define DDR_RFTIMER 22 |
`define DDR_RFBEGIN 21 |
// |
`define DDR_CMDLEN 21 |
`define DDR_CSBIT 20 |
`define DDR_RASBIT 19 |
63,6 → 69,9
`define DDR_NOPTIMER 16 // Steal this from BA bits |
`define DDR_BABITS 3 // BABITS are really from 18:16, they are 3 bits |
`define DDR_ADDR_BITS 14 |
// |
`define BUSREG 7 |
`define BUSNOW 8 |
|
module wbddrsdram(i_clk, i_reset, |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
73,7 → 82,7
o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data, |
o_cmd_accepted); |
parameter CKREFI4 = 13'd6240, // 4 * 7.8us at 200 MHz clock |
CKRFC = 140, |
CKRFC = 320, |
CKXPR = CKRFC+5+2; // Clocks per tXPR timeout |
input i_clk, i_reset; |
// Wishbone inputs |
96,7 → 105,7
output reg [2:0] o_ddr_ba; |
// And the data inputs and outputs |
output reg [31:0] o_ddr_data; |
input i_ddr_data; |
input [31:0] i_ddr_data; |
// And just for the test bench |
output reg o_cmd_accepted; |
|
136,6 → 145,11
valid_bank, last_valid_bank; |
reg [(`DDR_CMDLEN-1):0] close_bank_cmd, activate_bank_cmd, |
maybe_close_cmd, maybe_open_cmd, rw_cmd; |
|
wire w_this_closing_bank, w_this_opening_bank, |
w_this_maybe_close, w_this_maybe_open, |
w_this_rw_move, w_this_refresh; |
reg last_closing_bank, last_opening_bank; |
// |
// tWTR = 7.5 |
// tRRD = 7.5 |
341,7 → 355,7
&&(bank_status[5][2:0] == 3'b00) |
&&(bank_status[6][2:0] == 3'b00) |
&&(bank_status[7][2:0] == 3'b00); |
if ((!reset_override)&&(need_refresh)||(w_precharge_all)) |
if (reset_override) |
begin |
bank_status[0][0] <= 1'b0; |
bank_status[1][0] <= 1'b0; |
352,6 → 366,17
bank_status[6][0] <= 1'b0; |
bank_status[7][0] <= 1'b0; |
banks_are_closing <= 1'b1; |
end else if ((need_refresh)||(w_precharge_all)) |
begin |
bank_status[0][0] <= 1'b0; |
bank_status[1][0] <= 1'b0; |
bank_status[2][0] <= 1'b0; |
bank_status[3][0] <= 1'b0; |
bank_status[4][0] <= 1'b0; |
bank_status[5][0] <= 1'b0; |
bank_status[6][0] <= 1'b0; |
bank_status[7][0] <= 1'b0; |
banks_are_closing <= 1'b1; |
end else if (need_close_bank) |
begin |
bank_status[close_bank_cmd[16:14]] |
402,53 → 427,73
// |
// |
// |
reg midrefresh, refresh_clear, endrefresh; |
reg [12:0] refresh_clk; |
reg [2:0] midrefresh_hctr; // How many refresh cycles? |
reg [8:0] midrefresh_lctr; // How many clks in this refresh cycle |
reg refresh_ztimer; |
reg [16:0] refresh_counter; |
reg [3:0] refresh_addr; |
reg [23:0] refresh_instruction; |
always @(posedge i_clk) |
if ((reset_override)||(refresh_clear)) |
refresh_clk <= CKREFI4; |
else if (|refresh_clk) |
refresh_clk <= refresh_clk-1; |
always @(posedge i_clk) |
if (refresh_clk == 0) |
need_refresh <= 1'b1; |
else if (endrefresh) |
need_refresh <= 1'b0; |
if (reset_override) |
refresh_addr <= 4'hf; |
else if (refresh_ztimer) |
refresh_addr <= refresh_addr + 1; |
else if (refresh_instruction[`DDR_RFBEGIN]) |
refresh_addr <= 4'h0; |
|
always @(posedge i_clk) |
if (!need_refresh) |
refresh_cmd <= { `DDR_NOOP, 17'h00 }; |
else if (~banks_are_closing) |
refresh_cmd <= { `DDR_PRECHARGE, 3'h0, 3'h0, 1'b1, 10'h00 }; |
else if (~all_banks_closed) |
refresh_cmd <= { `DDR_NOOP, 17'h00 }; |
else |
refresh_cmd <= { `DDR_REFRESH, 17'h00 }; |
always @(posedge i_clk) |
midrefresh <= (need_refresh)&&(all_banks_closed)&&(~refresh_clear); |
if (reset_override) |
begin |
refresh_ztimer <= 1'b1; |
refresh_counter <= 17'd0; |
end else if (!refresh_ztimer) |
begin |
refresh_ztimer <= (refresh_counter == 17'h1); |
refresh_counter <= (refresh_counter - 17'h1); |
end else if (refresh_instruction[`DDR_RFTIMER]) |
begin |
refresh_ztimer <= 1'b0; |
refresh_counter <= refresh_instruction[16:0]; |
end |
|
wire [16:0] w_ckREFIn, w_ckREFRst; |
assign w_ckREFIn[ 12: 0] = CKREFI4-5*CKRFC-2-10; |
assign w_ckREFIn[ 16:13] = 4'h0; |
assign w_ckREFRst[12: 0] = CKRFC-2-6; |
assign w_ckREFRst[16:13] = 4'h0; |
|
always @(posedge i_clk) |
if (!need_refresh) |
midrefresh_hctr <= 3'h0; |
else if ((midrefresh_lctr == 0)&&(!midrefresh_hctr[2])) |
midrefresh_hctr <= midrefresh_hctr + 3'h1; |
if (reset_override) |
refresh_instruction <= { 3'h0, `DDR_NOOP, w_ckREFIn }; |
else if (refresh_ztimer) |
refresh_cmd <= refresh_instruction[20:0]; |
always @(posedge i_clk) |
if ((!need_refresh)||(!midrefresh)) |
endrefresh <= 1'b0; |
else if (midrefresh_hctr == 3'h0) |
endrefresh <= 1'b1; |
always @(posedge i_clk) |
if (!need_refresh) |
midrefresh_lctr <= CKRFC; |
else if (midrefresh_lctr == 0) |
midrefresh_lctr <= CKRFC; |
else |
midrefresh_lctr <= midrefresh_lctr-1; |
if (reset_override) |
need_refresh <= 1'b0; |
else if (refresh_ztimer) |
need_refresh <= refresh_instruction[`DDR_NEEDREFRESH]; |
|
always @(posedge i_clk) |
refresh_clear <= (need_refresh)&&(endrefresh)&&(midrefresh_lctr == 0); |
if (refresh_ztimer) |
case(refresh_addr)//NEED-RFC, HAVE-TIMER, |
4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn }; |
// 17'd10 = time to complete write, plus write recovery time |
// minus two (cause we can't count zero or one) |
// = WL+4+tWR-2 = 10 |
// = 5+4+3-2 = 10 |
4'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 }; |
4'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 }; |
4'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 }; |
4'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 }; |
4'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC }; |
4'h6: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 }; |
4'h7: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC }; |
4'h8: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 }; |
4'h9: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC }; |
4'ha: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 }; |
4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC }; |
4'hc: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC }; |
default: |
refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 }; |
endcase |
|
|
// |
457,13 → 502,14
// writing? |
// |
// |
reg [8:0] bus_active, bus_read; |
reg [1:0] bus_subaddr [8:0]; |
reg [`BUSNOW:0] bus_active, bus_read, bus_new; |
reg [1:0] bus_subaddr [`BUSNOW:0]; |
initial bus_active = 0; |
always @(posedge i_clk) |
begin |
bus_active[8:0] <= { bus_active[7:0], 1'b0 }; |
bus_read[8:0] <= { bus_read[7:0], 1'b0 }; // Drive the d-bus? |
bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 }; |
bus_read[`BUSNOW:0] <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus? |
bus_new[`BUSNOW:0] <= { bus_new[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus? |
//bus_mask[8:0] <= { bus_mask[7:0], 1'b1 }; // Write this value? |
bus_subaddr[8] <= bus_subaddr[7]; |
bus_subaddr[7] <= bus_subaddr[6]; |
474,8 → 520,7
bus_subaddr[2] <= bus_subaddr[1]; |
bus_subaddr[1] <= bus_subaddr[0]; |
bus_subaddr[0] <= 2'h3; |
if ((!reset_override)&&(!need_refresh)&&(!need_close_bank) |
&&(!need_open_bank)&&(valid_bank)) |
if (w_this_rw_move) |
begin |
bus_active[3:0]<= 4'hf; // Once per clock |
bus_read[3:0] <= 4'hf; // These will be reads |
482,6 → 527,7
bus_subaddr[3] <= 2'h0; |
bus_subaddr[2] <= 2'h1; |
bus_subaddr[1] <= 2'h2; |
bus_new[{ 2'b0, (2'h3-r_sub) }] <= 1'b1; |
|
bus_read[3:0] <= (r_we)? 4'h0:4'hf; |
end |
488,7 → 534,7
end |
|
always @(posedge i_clk) |
drive_dqs <= (~bus_read[8])&&(|bus_active[8:7]); |
drive_dqs <= (~bus_read[`BUSREG])&&(|bus_active[`BUSREG]); |
|
// |
// |
501,7 → 547,7
begin |
r_pending <= 1'b1; |
o_wb_stall <= 1'b1; |
end else if ((r_move)||(m_move)) |
end else if ((m_move)||(w_this_rw_move)) |
begin |
r_pending <= 1'b0; |
o_wb_stall <= 1'b0; |
528,9 → 574,6
&&(r_row != bank_address[r_bank]); |
assign w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00); |
|
wire w_this_closing_bank, w_this_opening_bank, |
w_this_maybe_close, w_this_maybe_open; |
reg last_closing_bank, last_opening_bank; |
always @(posedge i_clk) |
begin |
need_close_bank <= (w_need_close_this_bank) |
573,9 → 616,15
|
// Match registers, to see if we can move forward without sending a |
// new command |
reg [2:0] m_clock; |
reg m_timeout; |
always @(posedge i_clk) |
begin |
if (r_move) |
if (|m_clock) |
m_clock <= m_clock - 3'h1; |
if (!m_timeout) |
m_timeout <= (m_clock[2:1] == 2'b00); |
if (w_this_rw_move) |
begin |
m_pending <= r_pending; |
m_we <= r_we; |
584,7 → 633,9
m_bank <= r_bank; |
m_col <= r_col; |
m_sub <= r_sub; |
end else if (m_match) |
m_clock<= 3'h7; |
m_timeout <= 1'b0; |
end else if ((m_match)&&(!m_timeout)) |
m_sub <= r_sub; |
|
m_match <= (m_pending)&&(r_pending)&&(r_we == m_we) |
613,10 → 664,16
else if (reset_ztimer) |
o_ddr_cke <= reset_instruction[`DDR_CKEBIT]; |
|
assign w_this_refresh = (!reset_override)&&(need_refresh) |
&&(refresh_cmd[`DDR_CSBIT:`DDR_WEBIT] == `DDR_REFRESH); |
|
assign w_this_closing_bank = (!reset_override)&&(!need_refresh) |
&&(need_close_bank); |
assign w_this_opening_bank = (!reset_override)&&(!need_refresh) |
&&(!need_close_bank)&&(need_open_bank); |
assign w_this_rw_move = (!reset_override)&&(!need_refresh) |
&&(!need_close_bank)&&(!need_open_bank) |
&&(valid_bank)&&(!r_move); |
assign w_this_maybe_close = (!reset_override)&&(!need_refresh) |
&&(!need_close_bank)&&(!need_open_bank) |
&&((!valid_bank)||(r_move)) |
662,8 → 719,44
cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] }; |
end |
|
reg [31:0] bus_data[8:0]; |
`define LGFIFOLN 4 |
`define FIFOLEN 16 |
reg [(`LGFIFOLN-1):0] bus_fifo_head, bus_fifo_tail; |
reg [31:0] bus_fifo_data [0:(`FIFOLEN-1)]; |
reg [1:0] bus_fifo_sub [0:(`FIFOLEN-1)]; |
reg bus_fifo_new [0:(`FIFOLEN-1)]; |
reg pre_ack; |
|
// The bus R/W FIFO |
wire w_bus_fifo_read_next_transaction; |
assign w_bus_fifo_read_next_transaction = (bus_fifo_sub[bus_fifo_tail]==bus_subaddr[`BUSREG])&&(bus_active[`BUSREG])&&(bus_new[`BUSREG] == bus_fifo_new[bus_fifo_tail]); |
always @(posedge i_clk) |
begin |
pre_ack <= 1'b0; |
o_ddr_dm <= 1'b0; |
if ((i_reset)||(reset_override)) |
begin |
bus_fifo_head <= 4'h0; |
bus_fifo_tail <= 4'h0; |
o_ddr_dm <= 1'b0; |
end else begin |
if ((w_this_rw_move)||(m_move)) |
bus_fifo_head <= bus_fifo_head + 4'h1; |
|
o_ddr_dm <= (bus_active[`BUSREG])&&(!bus_read[`BUSREG]); |
if (w_bus_fifo_read_next_transaction) |
begin |
bus_fifo_tail <= bus_fifo_tail + 4'h1; |
pre_ack <= 1'b1; |
o_ddr_dm <= 1'b0; |
end |
end |
bus_fifo_data[bus_fifo_head] <= r_data; |
bus_fifo_sub[bus_fifo_head] <= r_sub; |
bus_fifo_new[bus_fifo_head] <= w_this_rw_move; |
end |
|
|
assign o_ddr_cs_n = cmd[`DDR_CSBIT]; |
assign o_ddr_ras_n = cmd[`DDR_RASBIT]; |
assign o_ddr_cas_n = cmd[`DDR_CASBIT]; |
671,17 → 764,22
assign o_ddr_dqs = drive_dqs; |
assign o_ddr_addr = cmd[(`DDR_ADDR_BITS-1):0]; |
assign o_ddr_ba = cmd[(`DDR_BABITS+`DDR_ADDR_BITS-1):`DDR_ADDR_BITS]; |
assign o_ddr_data = bus_data[8]; |
always @(posedge i_clk) |
o_ddr_data <= bus_fifo_data[bus_fifo_tail]; |
assign w_precharge_all = (cmd[`DDR_CSBIT:`DDR_WEBIT]==`DDR_PRECHARGE) |
&&(o_ddr_addr[10]); // 5 bits |
|
// Need to set o_wb_dqs high one clock prior to any read. |
// As per spec, ODT = 0 during reads |
assign o_ddr_bus_oe = ~bus_read[8]; |
assign o_ddr_bus_oe = ~bus_read[`BUSNOW]; |
|
// ODT must be in high impedence while reset_n=0, then it can be set |
// to low or high. |
assign o_ddr_odt = o_ddr_bus_oe; |
|
always @(posedge i_clk) |
o_wb_ack <= pre_ack; |
always @(posedge i_clk) |
o_wb_data <= i_ddr_data; |
|
endmodule |