Line 126... |
Line 126... |
|
|
// Can we preload the next bank?
|
// Can we preload the next bank?
|
reg [13:0] r_nxt_row;
|
reg [13:0] r_nxt_row;
|
reg [2:0] r_nxt_bank;
|
reg [2:0] r_nxt_bank;
|
|
|
|
reg need_close_bank, need_close_this_bank,
|
|
last_close_bank, maybe_close_next_bank,
|
|
last_maybe_close,
|
|
need_open_bank, last_open_bank, maybe_open_next_bank,
|
|
last_maybe_open,
|
|
valid_bank, last_valid_bank;
|
|
reg [(`DDR_CMDLEN-1):0] close_bank_cmd, activate_bank_cmd,
|
|
maybe_close_cmd, maybe_open_cmd, rw_cmd;
|
//
|
//
|
// tWTR = 7.5
|
// tWTR = 7.5
|
// tRRD = 7.5
|
// tRRD = 7.5
|
// tREFI= 7.8
|
// tREFI= 7.8
|
// tFAW = 45
|
// tFAW = 45
|
Line 165... |
Line 173... |
// memory: reset_address. Each memory location provides either a "command" to
|
// memory: reset_address. Each memory location provides either a "command" to
|
// the DDR3 SDRAM, or a timer to wait until the next command. Further, the
|
// the DDR3 SDRAM, or a timer to wait until the next command. Further, the
|
// timer commands indicate whether or not the command during the timer is to
|
// timer commands indicate whether or not the command during the timer is to
|
// be set to idle, or whether the command is instead left as it was.
|
// be set to idle, or whether the command is instead left as it was.
|
reg reset_override, reset_ztimer;
|
reg reset_override, reset_ztimer;
|
reg [3:0] reset_address;
|
reg [4:0] reset_address;
|
reg [(`DDR_CMDLEN-1):0] reset_cmd, cmd, refresh_cmd;
|
reg [(`DDR_CMDLEN-1):0] reset_cmd, cmd, refresh_cmd;
|
reg [24:0] reset_instruction;
|
reg [24:0] reset_instruction;
|
reg [16:0] reset_timer;
|
reg [16:0] reset_timer;
|
initial reset_override = 1'b1;
|
initial reset_override = 1'b1;
|
initial reset_address = 4'h0;
|
initial reset_address = 5'h0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_reset)
|
if (i_reset)
|
begin
|
begin
|
reset_override <= 1'b1;
|
reset_override <= 1'b1;
|
reset_cmd <= { `DDR_NOOP, reset_instruction[16:0]};
|
reset_cmd <= { `DDR_NOOP, reset_instruction[16:0]};
|
Line 212... |
Line 220... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_reset)
|
if (i_reset)
|
reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
|
reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
|
else if (reset_ztimer) case(reset_address) // RSTDONE, TIMER, CKE, ??
|
else if (reset_ztimer) case(reset_address) // RSTDONE, TIMER, CKE, ??
|
// 1. Reset asserted (active low) for 200 us. (@200MHz)
|
// 1. Reset asserted (active low) for 200 us. (@200MHz)
|
4'h0: reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
|
5'h0: reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
|
// 2. Reset de-asserted, wait 500 us before asserting CKE
|
// 2. Reset de-asserted, wait 500 us before asserting CKE
|
4'h1: reset_instruction <= { 4'h6, `DDR_NOOP, 17'd100_000 };
|
5'h1: reset_instruction <= { 4'h6, `DDR_NOOP, 17'd100_000 };
|
// 3. Assert CKE, wait minimum of Reset CKE Exit time
|
// 3. Assert CKE, wait minimum of Reset CKE Exit time
|
4'h2: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckXPR };
|
5'h2: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckXPR };
|
// 4. Look MR2. (1CK, no TIMER)
|
// 4. Look MR2. (1CK, no TIMER)
|
4'h3: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h2,
|
5'h3: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h2,
|
3'h0, 2'b00, 1'b0, 1'b0, 1'b1, 3'b0, 3'b0 }; // MRS2
|
3'h0, 2'b00, 1'b0, 1'b0, 1'b1, 3'b0, 3'b0 }; // MRS2
|
// 3. Wait 4 clocks (tMRD)
|
// 3. Wait 4 clocks (tMRD)
|
4'h4: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
|
5'h4: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
|
// 5. Set MR1
|
// 5. Set MR1
|
4'h5: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h1,
|
5'h5: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h1,
|
1'h0, // Reserved for Future Use (RFU)
|
1'h0, // Reserved for Future Use (RFU)
|
1'b0, // Qoff - output buffer enabled
|
1'b0, // Qoff - output buffer enabled
|
1'b1, // TDQS ... enabled
|
1'b1, // TDQS ... enabled
|
1'b0, // RFU
|
1'b0, // RFU
|
1'b0, // High order bit, Rtt_Nom (3'b011)
|
1'b0, // High order bit, Rtt_Nom (3'b011)
|
Line 239... |
Line 247... |
2'b0, // Additive latency = 0
|
2'b0, // Additive latency = 0
|
1'b1, // Low order bit of Rtt_Nom
|
1'b1, // Low order bit of Rtt_Nom
|
1'b1, // DIC set to 2'b01
|
1'b1, // DIC set to 2'b01
|
1'b1 }; // MRS1, DLL enable
|
1'b1 }; // MRS1, DLL enable
|
// 7. Wait another 4 clocks
|
// 7. Wait another 4 clocks
|
4'h6: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
|
5'h6: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
|
// 8. Send MRS0
|
// 8. Send MRS0
|
4'h7: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h0,
|
5'h7: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h0,
|
1'b0, // Reserved for future use
|
1'b0, // Reserved for future use
|
1'b0, // PPD control, (slow exit(DLL off))
|
1'b0, // PPD control, (slow exit(DLL off))
|
3'b1, // Write recovery for auto precharge
|
3'b1, // Write recovery for auto precharge
|
1'b0, // DLL Reset (No)
|
1'b0, // DLL Reset (No)
|
//
|
//
|
Line 253... |
Line 261... |
3'b01, // High 3-bits, CAS latency (=4'b0010 = 4'd5)
|
3'b01, // High 3-bits, CAS latency (=4'b0010 = 4'd5)
|
1'b0, // Read burst type = nibble sequential
|
1'b0, // Read burst type = nibble sequential
|
1'b0, // Low bit of cas latency
|
1'b0, // Low bit of cas latency
|
2'b0 }; // Burst length = 8 (Fixed)
|
2'b0 }; // Burst length = 8 (Fixed)
|
// 9. Wait tMOD, is max(12 clocks, 15ns)
|
// 9. Wait tMOD, is max(12 clocks, 15ns)
|
4'h8: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h0a };
|
5'h8: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h0a };
|
// 10. Issue a ZQCL command to start ZQ calibration, A10 is high
|
// 10. Issue a ZQCL command to start ZQ calibration, A10 is high
|
4'h9: reset_instruction <= { 4'h3, `DDR_ZQS, 6'h0, 1'b1, 10'h0};
|
5'h9: reset_instruction <= { 4'h3, `DDR_ZQS, 6'h0, 1'b1, 10'h0};
|
//11.Wait for both tDLLK and tZQinit completed, both are 512 cks
|
//11.Wait for both tDLLK and tZQinit completed, both are 512 cks
|
4'ha: reset_instruction <= { 4'h7, `DDR_NOOP, 17'd512 };
|
5'ha: reset_instruction <= { 4'h7, `DDR_NOOP, 17'd512 };
|
// 12. Precharge all command
|
// 12. Precharge all command
|
4'hb: reset_instruction <= { 4'h3, `DDR_PRECHARGE, 6'h0, 1'b1, 10'h0 };
|
5'hb: reset_instruction <= { 4'h3, `DDR_PRECHARGE, 6'h0, 1'b1, 10'h0 };
|
// 13. Wait for the precharge to complete
|
// 13. Wait for the precharge to complete
|
4'hc: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRP };
|
5'hc: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRP };
|
// 14. A single Auto Refresh commands
|
// 14. A single Auto Refresh commands
|
4'hd: reset_instruction <= { 4'h3, `DDR_REFRESH, 17'h00 };
|
5'hd: reset_instruction <= { 4'h3, `DDR_REFRESH, 17'h00 };
|
// 15. Wait for the auto refresh to complete
|
// 15. Wait for the auto refresh to complete
|
4'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
|
5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
|
// Two Auto Refresh commands
|
// Two Auto Refresh commands
|
default:
|
default:
|
reset_instruction <={4'hb, `DDR_NOOP, 17'd00_000 };
|
reset_instruction <={4'hb, `DDR_NOOP, 17'd00_000 };
|
endcase
|
endcase
|
// reset_instruction <= reset_mem[reset_address];
|
// reset_instruction <= reset_mem[reset_address];
|
|
|
initial reset_address = 4'h0;
|
initial reset_address = 5'h0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_reset)
|
if (i_reset)
|
reset_address <= 4'h1;
|
reset_address <= 5'h1;
|
else if (reset_ztimer)
|
else if ((reset_ztimer)&&(reset_override))
|
reset_address <= reset_address + 4'h1;
|
reset_address <= reset_address + 5'h1;
|
//
|
//
|
// initial reset_mem =
|
// initial reset_mem =
|
// 0. !DONE, TIMER,RESET_N=0, CKE=0, CMD = NOOP, TIMER = 200us ( 40,000)
|
// 0. !DONE, TIMER,RESET_N=0, CKE=0, CMD = NOOP, TIMER = 200us ( 40,000)
|
// 1. !DONE, TIMER,RESET_N=1, CKE=0, CMD = NOOP, TIMER = 500us (100,000)
|
// 1. !DONE, TIMER,RESET_N=1, CKE=0, CMD = NOOP, TIMER = 500us (100,000)
|
// 2. !DONE, TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = (Look me up)
|
// 2. !DONE, TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = (Look me up)
|
Line 310... |
Line 318... |
//
|
//
|
reg need_refresh;
|
reg need_refresh;
|
|
|
wire w_precharge_all;
|
wire w_precharge_all;
|
reg banks_are_closing, all_banks_closed;
|
reg banks_are_closing, all_banks_closed;
|
reg [2:0] bank_status[7:0];
|
reg [3:0] bank_status [0:7];
|
|
reg [13:0] bank_address [0:7];
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
bank_status[0] = { bank_status[0][1:0], bank_status[0][0] };
|
bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
|
bank_status[1] = { bank_status[1][1:0], bank_status[1][0] };
|
bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
|
bank_status[2] = { bank_status[2][1:0], bank_status[2][0] };
|
bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
|
bank_status[3] = { bank_status[3][1:0], bank_status[3][0] };
|
bank_status[3] <= { bank_status[3][2:0], bank_status[3][0] };
|
bank_status[4] = { bank_status[4][1:0], bank_status[4][0] };
|
bank_status[4] <= { bank_status[4][2:0], bank_status[4][0] };
|
bank_status[5] = { bank_status[5][1:0], bank_status[5][0] };
|
bank_status[5] <= { bank_status[5][2:0], bank_status[5][0] };
|
bank_status[6] = { bank_status[6][1:0], bank_status[6][0] };
|
bank_status[6] <= { bank_status[6][2:0], bank_status[6][0] };
|
bank_status[7] = { bank_status[7][1:0], bank_status[7][0] };
|
bank_status[7] <= { bank_status[7][2:0], bank_status[7][0] };
|
all_banks_closed <= (bank_status[0][1:0] == 2'b00)
|
all_banks_closed <= (bank_status[0][2:0] == 3'b00)
|
&&(bank_status[1][1:0] == 2'b00)
|
&&(bank_status[1][2:0] == 3'b00)
|
&&(bank_status[2][1:0] == 2'b00)
|
&&(bank_status[2][2:0] == 3'b00)
|
&&(bank_status[3][1:0] == 2'b00)
|
&&(bank_status[3][2:0] == 3'b00)
|
&&(bank_status[4][1:0] == 2'b00)
|
&&(bank_status[4][2:0] == 3'b00)
|
&&(bank_status[5][1:0] == 2'b00)
|
&&(bank_status[5][2:0] == 3'b00)
|
&&(bank_status[6][1:0] == 2'b00)
|
&&(bank_status[6][2:0] == 3'b00)
|
&&(bank_status[7][1:0] == 2'b00);
|
&&(bank_status[7][2:0] == 3'b00);
|
if ((!reset_override)&&(need_refresh)||(w_precharge_all))
|
if ((!reset_override)&&(need_refresh)||(w_precharge_all))
|
begin
|
begin
|
bank_status[0][0] = 1'b0;
|
bank_status[0][0] <= 1'b0;
|
bank_status[1][0] = 1'b0;
|
bank_status[1][0] <= 1'b0;
|
bank_status[2][0] = 1'b0;
|
bank_status[2][0] <= 1'b0;
|
bank_status[3][0] = 1'b0;
|
bank_status[3][0] <= 1'b0;
|
bank_status[4][0] = 1'b0;
|
bank_status[4][0] <= 1'b0;
|
bank_status[5][0] = 1'b0;
|
bank_status[5][0] <= 1'b0;
|
bank_status[6][0] = 1'b0;
|
bank_status[6][0] <= 1'b0;
|
bank_status[7][0] = 1'b0;
|
bank_status[7][0] <= 1'b0;
|
banks_are_closing <= 1'b1;
|
banks_are_closing <= 1'b1;
|
end else if (need_close_bank)
|
end else if (need_close_bank)
|
begin
|
begin
|
bank_status[r_bank][0] = 1'b0;
|
bank_status[close_bank_cmd[16:14]]
|
|
<= { bank_status[close_bank_cmd[16:14]][2:0], 1'b1 };
|
|
// bank_status[close_bank_cmd[16:14]][0] <= 1'b0;
|
end else if (need_open_bank)
|
end else if (need_open_bank)
|
begin
|
begin
|
bank_status[r_bank][0] = 1'b1;
|
bank_status[activate_bank_cmd[16:14]]
|
|
<= { bank_status[activate_bank_cmd[16:14]][2:0], 1'b1 };
|
|
// bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
|
|
all_banks_closed <= 1'b0;
|
|
banks_are_closing <= 1'b0;
|
|
end else if ((valid_bank)&&(!r_move))
|
|
;
|
|
else if (maybe_close_next_bank)
|
|
begin
|
|
bank_status[maybe_close_cmd[16:14]]
|
|
<= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b1 };
|
|
end else if (maybe_open_next_bank)
|
|
begin
|
|
bank_status[maybe_open_cmd[16:14]]
|
|
<= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
|
|
// bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
|
all_banks_closed <= 1'b0;
|
all_banks_closed <= 1'b0;
|
banks_are_closing <= 1'b0;
|
banks_are_closing <= 1'b0;
|
end
|
end
|
end
|
end
|
|
|
Line 383... |
Line 410... |
if ((reset_override)||(refresh_clear))
|
if ((reset_override)||(refresh_clear))
|
refresh_clk <= CKREFI4;
|
refresh_clk <= CKREFI4;
|
else if (|refresh_clk)
|
else if (|refresh_clk)
|
refresh_clk <= refresh_clk-1;
|
refresh_clk <= refresh_clk-1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
need_refresh <= (refresh_clk == 0)||(midrefresh);
|
if (refresh_clk == 0)
|
|
need_refresh <= 1'b1;
|
|
else if (endrefresh)
|
|
need_refresh <= 1'b0;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (!need_refresh)
|
if (!need_refresh)
|
refresh_cmd <= { `DDR_NOOP, 17'h00 };
|
refresh_cmd <= { `DDR_NOOP, 17'h00 };
|
else if (~banks_are_closing)
|
else if (~banks_are_closing)
|
refresh_cmd <= { `DDR_PRECHARGE, 3'h0, 3'h0, 1'b1, 10'h00 };
|
refresh_cmd <= { `DDR_PRECHARGE, 3'h0, 3'h0, 1'b1, 10'h00 };
|
Line 397... |
Line 428... |
refresh_cmd <= { `DDR_REFRESH, 17'h00 };
|
refresh_cmd <= { `DDR_REFRESH, 17'h00 };
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
midrefresh <= (need_refresh)&&(all_banks_closed)&&(~refresh_clear);
|
midrefresh <= (need_refresh)&&(all_banks_closed)&&(~refresh_clear);
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (!midrefresh)
|
if (!need_refresh)
|
midrefresh_hctr <= 3'h4;
|
midrefresh_hctr <= 3'h0;
|
else if ((midrefresh_lctr == 0)&&(|midrefresh_hctr))
|
else if ((midrefresh_lctr == 0)&&(!midrefresh_hctr[2]))
|
midrefresh_hctr <= midrefresh_hctr - 1;
|
midrefresh_hctr <= midrefresh_hctr + 3'h1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((!need_refresh)||(!midrefresh))
|
if ((!need_refresh)||(!midrefresh))
|
endrefresh <= 1'b0;
|
endrefresh <= 1'b0;
|
else if (midrefresh_hctr == 3'h0)
|
else if (midrefresh_hctr == 3'h0)
|
endrefresh <= 1'b1;
|
endrefresh <= 1'b1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (!midrefresh)
|
if (!need_refresh)
|
midrefresh_lctr <= CKRFC;
|
midrefresh_lctr <= CKRFC;
|
else if (midrefresh_lctr == 0)
|
else if (midrefresh_lctr == 0)
|
midrefresh_lctr <= 0;
|
|
else
|
|
midrefresh_lctr <= CKRFC;
|
midrefresh_lctr <= CKRFC;
|
|
else
|
|
midrefresh_lctr <= midrefresh_lctr-1;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
refresh_clear <= (need_refresh)&&(endrefresh)&&(midrefresh_lctr == 0);
|
refresh_clear <= (need_refresh)&&(endrefresh)&&(midrefresh_lctr == 0);
|
|
|
|
|
Line 485... |
Line 516... |
r_bank <= i_wb_addr[11:9];
|
r_bank <= i_wb_addr[11:9];
|
r_col <= { i_wb_addr[8:2], 3'b000 }; // 9:2
|
r_col <= { i_wb_addr[8:2], 3'b000 }; // 9:2
|
r_sub <= i_wb_addr[1:0];
|
r_sub <= i_wb_addr[1:0];
|
|
|
// pre-emptive work
|
// pre-emptive work
|
r_nxt_row <= i_wb_addr[25:12]+14'h1;
|
r_nxt_row <= (i_wb_addr[11:9]==3'h7)?i_wb_addr[25:12]+14'h1:i_wb_addr[25:12];
|
r_nxt_bank <= i_wb_addr[11:9]+3'h1;
|
r_nxt_bank <= i_wb_addr[11:9]+3'h1;
|
end
|
end
|
end
|
end
|
|
|
reg [2:0] bank_active[7:0];
|
wire w_need_close_this_bank, w_need_open_bank;
|
reg [13:0] bank_address[7:0];
|
assign w_need_close_this_bank = (r_pending)&&(bank_status[r_bank][0])
|
|
&&(r_row != bank_address[r_bank]);
|
|
assign w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00);
|
|
|
reg [(`DDR_CMDLEN-1):0] close_bank_cmd, activate_bank_cmd, rw_cmd;
|
wire w_this_closing_bank, w_this_opening_bank,
|
reg need_close_bank, need_close_this_bank,
|
w_this_maybe_close, w_this_maybe_open;
|
last_close_bank, maybe_close_next_bank,
|
reg last_closing_bank, last_opening_bank;
|
need_open_bank, last_open_bank, maybe_open_next_bank,
|
|
valid_bank, last_valid_bank;
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
need_close_bank <= (r_pending)&&(bank_active[r_bank][0])
|
need_close_bank <= (w_need_close_this_bank)
|
&&(r_row != bank_address[r_bank])&&(!last_close_bank);
|
&&(!w_this_closing_bank)&&(!last_closing_bank);
|
need_close_this_bank <= (r_pending)&&(bank_active[r_bank][0])
|
|
&&(r_row != bank_address[r_bank]);
|
|
last_close_bank <= need_close_bank;
|
|
|
|
maybe_close_next_bank <= (r_pending)
|
maybe_close_next_bank <= (r_pending)
|
&&(bank_active[r_nxt_bank][0])
|
&&(bank_status[r_nxt_bank][0])
|
&&(r_nxt_row != bank_address[r_nxt_bank])
|
&&(r_nxt_row != bank_address[r_nxt_bank])
|
&&(!need_close_this_bank);
|
&&(!w_this_maybe_close)&&(!last_maybe_close);
|
|
|
close_bank_cmd <= (maybe_close_next_bank)
|
close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
|
? { `DDR_PRECHARGE, r_nxt_bank, r_nxt_row[13:11], 1'b0, r_nxt_row[9:0] }
|
maybe_close_cmd <= { `DDR_PRECHARGE, r_nxt_bank, r_nxt_row[13:11], 1'b0, r_nxt_row[9:0] };
|
: { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
|
|
|
|
|
|
need_open_bank <= (r_pending)&&(bank_active[r_bank][1:0]==2'b00)
|
need_open_bank <= (w_need_open_bank)
|
&&(!last_open_bank);
|
&&(!w_this_opening_bank)&&(!last_opening_bank);
|
last_open_bank <= need_open_bank;
|
last_open_bank <= (w_this_opening_bank);
|
|
|
maybe_open_next_bank <= (r_pending)
|
maybe_open_next_bank <= (r_pending)
|
&&(bank_active[r_nxt_bank][1:0] == 2'b00)
|
&&(bank_status[r_bank][0] == 1'b1)
|
&&(!need_open_bank)&&(!need_close_bank);
|
&&(bank_status[r_nxt_bank][1:0] == 2'b00)
|
|
&&(!w_this_maybe_open)&&(!last_maybe_open);
|
|
last_maybe_open <= (w_this_maybe_open);
|
|
|
activate_bank_cmd <= (maybe_open_next_bank)
|
activate_bank_cmd<= { `DDR_ACTIVATE, r_bank, r_row[13:0] };
|
? { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] }
|
maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
|
: { `DDR_ACTIVATE, r_bank, r_row[13:0] };
|
|
|
|
|
|
|
|
valid_bank <= (r_pending)&&(bank_active[r_bank][1:0]==2'b11)
|
valid_bank <= (r_pending)&&(bank_status[r_bank][3])
|
&&(bank_address[r_bank]==r_row)
|
&&(bank_address[r_bank]==r_row)
|
&&(!last_valid_bank);
|
&&(!last_valid_bank)&&(!r_move)
|
last_valid_bank <= valid_bank;
|
&&(!bus_active[0]);
|
|
last_valid_bank <= r_move;
|
|
|
rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (~r_pending)?`DDR_NOOP:((r_we)?`DDR_WRITE:`DDR_READ);
|
rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (~r_pending)?`DDR_NOOP:((r_we)?`DDR_WRITE:`DDR_READ);
|
rw_cmd[`DDR_WEBIT-1:0] <= { r_bank, 3'h0, 1'b0, r_col };
|
rw_cmd[`DDR_WEBIT-1:0] <= { r_bank, 3'h0, 1'b0, r_col };
|
end
|
end
|
|
|
Line 581... |
Line 610... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_reset)
|
if (i_reset)
|
o_ddr_cke <= 1'b0;
|
o_ddr_cke <= 1'b0;
|
else if (reset_ztimer)
|
else if (reset_ztimer)
|
o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
|
o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
|
always @(posedge i_clk)
|
|
begin
|
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_maybe_close = (!reset_override)&&(!need_refresh)
|
|
&&(!need_close_bank)&&(!need_open_bank)
|
|
&&((!valid_bank)||(r_move))
|
|
&&(maybe_close_next_bank);
|
|
assign w_this_maybe_open = (!reset_override)&&(!need_refresh)
|
|
&&(!need_close_bank)&&(!need_open_bank)
|
|
&&((!valid_bank)||(r_move))
|
|
&&(!maybe_close_next_bank)
|
|
&&(maybe_open_next_bank);
|
|
always @(posedge i_clk)
|
|
begin
|
|
last_opening_bank <= 1'b0;
|
|
last_closing_bank <= 1'b0;
|
|
last_maybe_open <= 1'b0;
|
|
last_maybe_close <= 1'b0;
|
r_move <= 1'b0;
|
r_move <= 1'b0;
|
if (reset_override)
|
if (reset_override)
|
cmd <= reset_cmd[`DDR_CSBIT:0];
|
cmd <= reset_cmd[`DDR_CSBIT:0];
|
else if (need_refresh)
|
else if (need_refresh)
|
begin
|
begin
|
cmd <= refresh_cmd; // The command from the refresh logc
|
cmd <= refresh_cmd; // The command from the refresh logc
|
end else if (need_close_bank)
|
end else if (need_close_bank)
|
|
begin
|
cmd <= close_bank_cmd;
|
cmd <= close_bank_cmd;
|
else if (need_open_bank)
|
last_closing_bank <= 1'b1;
|
|
end else if (need_open_bank)
|
|
begin
|
cmd <= activate_bank_cmd;
|
cmd <= activate_bank_cmd;
|
else if ((valid_bank)&&(bus_active[2:0]==3'h0))
|
last_opening_bank <= 1'b1;
|
|
end else if ((valid_bank)&&(!r_move))
|
begin
|
begin
|
cmd <= rw_cmd;
|
cmd <= rw_cmd;
|
r_move <= 1'b1;
|
r_move <= 1'b1;
|
|
end else if (maybe_close_next_bank)
|
|
begin
|
|
cmd <= maybe_close_cmd;
|
|
last_maybe_close <= 1'b1;
|
|
end else if (maybe_open_next_bank)
|
|
begin
|
|
cmd <= maybe_open_cmd;
|
|
last_maybe_open <= 1'b1;
|
end else
|
end else
|
cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] };
|
cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] };
|
end
|
end
|
|
|
reg [31:0] bus_data[8:0];
|
reg [31:0] bus_data[8:0];
|