Line 79... |
Line 79... |
o_ddr_reset_n, o_ddr_cke,
|
o_ddr_reset_n, o_ddr_cke,
|
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
|
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
|
o_ddr_dqs, o_ddr_dm, o_ddr_odt, o_ddr_bus_oe,
|
o_ddr_dqs, o_ddr_dm, o_ddr_odt, o_ddr_bus_oe,
|
o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data);
|
o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data);
|
parameter CKRBITS = 13, // Bits in CKREFI4
|
parameter CKRBITS = 13, // Bits in CKREFI4
|
CKREFI4 = 13'd6240, // 4 * 7.8us at 200 MHz clock
|
CKREFI = 13'd1560, // 4 * 7.8us at 200 MHz clock
|
CKRFC = 320,
|
CKRFC = 320,
|
CKWR = 3,
|
CKWR = 3,
|
CKXPR = CKRFC+5+2; // Clocks per tXPR timeout
|
CKXPR = CKRFC+5+2; // Clocks per tXPR timeout
|
input i_clk, i_reset;
|
input i_clk, i_reset;
|
// Wishbone inputs
|
// Wishbone inputs
|
Line 160... |
Line 160... |
wire w_this_closing_bank, w_this_opening_bank,
|
wire w_this_closing_bank, w_this_opening_bank,
|
w_this_maybe_close, w_this_maybe_open,
|
w_this_maybe_close, w_this_maybe_open,
|
w_this_rw_move;
|
w_this_rw_move;
|
reg last_closing_bank, last_opening_bank;
|
reg last_closing_bank, last_opening_bank;
|
wire w_need_close_this_bank, w_need_open_bank,
|
wire w_need_close_this_bank, w_need_open_bank,
|
w_r_valid, w_s_valid;
|
w_r_valid, w_s_valid, w_s_match;
|
//
|
//
|
// tWTR = 7.5
|
// tWTR = 7.5
|
// tRRD = 7.5
|
// tRRD = 7.5
|
// tREFI= 7.8
|
// tREFI= 7.8
|
// tFAW = 45
|
// tFAW = 45
|
Line 237... |
Line 237... |
reset_ztimer <= 1'b0;
|
reset_ztimer <= 1'b0;
|
reset_timer <= reset_instruction[16:0];
|
reset_timer <= reset_instruction[16:0];
|
end
|
end
|
|
|
wire [16:0] w_ckXPR = CKXPR, w_ckRST = 4, w_ckRP = 3,
|
wire [16:0] w_ckXPR = CKXPR, w_ckRST = 4, w_ckRP = 3,
|
w_ckRFC = CKRFC;
|
w_ckRFC_first = CKRFC-2-9;
|
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)
|
Line 267... |
Line 267... |
1'b0, // Disable write-leveling
|
1'b0, // Disable write-leveling
|
1'b1, // Mid order bit of Rtt_Nom
|
1'b1, // Mid order bit of Rtt_Nom
|
1'b0, // High order bit of Output Drvr Impedence Ctrl
|
1'b0, // High order bit of Output Drvr Impedence Ctrl
|
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'b0, // DIC set to 2'b00
|
1'b1 }; // MRS1, DLL enable
|
1'b0 }; // MRS1, DLL enable
|
// 7. Wait another 4 clocks
|
// 7. Wait another 4 clocks
|
5'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
|
5'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
|
Line 296... |
Line 296... |
// 13. Wait for the precharge to complete
|
// 13. Wait for the precharge to complete
|
5'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
|
5'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
|
5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
|
5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC_first };
|
// 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];
|
Line 345... |
Line 345... |
reg banks_are_closing, all_banks_closed;
|
reg banks_are_closing, all_banks_closed;
|
reg [3:0] bank_status [0:7];
|
reg [3:0] bank_status [0:7];
|
reg [13:0] bank_address [0:7];
|
reg [13:0] bank_address [0:7];
|
reg [3:0] bank_wr_ck [0:7]; // tWTR
|
reg [3:0] bank_wr_ck [0:7]; // tWTR
|
reg bank_wr_ckzro [0:7]; // tWTR
|
reg bank_wr_ckzro [0:7]; // tWTR
|
|
reg [7:0] bank_open;
|
|
reg [7:0] bank_closed;
|
|
|
wire [3:0] write_recycle_clocks;
|
wire [3:0] write_recycle_clocks;
|
assign write_recycle_clocks = CKWR+4+4;
|
assign write_recycle_clocks = CKWR+4+4;
|
|
|
|
initial bank_open = 8'h00;
|
|
initial bank_closed = 8'hff;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
|
bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
|
bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
|
bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
|
bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
|
bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
|
Line 386... |
Line 390... |
bank_wr_ckzro[4] <= (bank_wr_ck[4][3:1]==3'b00);
|
bank_wr_ckzro[4] <= (bank_wr_ck[4][3:1]==3'b00);
|
bank_wr_ckzro[5] <= (bank_wr_ck[5][3:1]==3'b00);
|
bank_wr_ckzro[5] <= (bank_wr_ck[5][3:1]==3'b00);
|
bank_wr_ckzro[6] <= (bank_wr_ck[6][3:1]==3'b00);
|
bank_wr_ckzro[6] <= (bank_wr_ck[6][3:1]==3'b00);
|
bank_wr_ckzro[7] <= (bank_wr_ck[7][3:1]==3'b00);
|
bank_wr_ckzro[7] <= (bank_wr_ck[7][3:1]==3'b00);
|
|
|
|
bank_open[0] <= (bank_status[0][1:0] == 2'h3);
|
|
bank_open[1] <= (bank_status[1][1:0] == 2'h3);
|
|
bank_open[2] <= (bank_status[2][1:0] == 2'h3);
|
|
bank_open[3] <= (bank_status[3][1:0] == 2'h3);
|
|
bank_open[4] <= (bank_status[4][1:0] == 2'h3);
|
|
bank_open[5] <= (bank_status[5][1:0] == 2'h3);
|
|
bank_open[6] <= (bank_status[6][1:0] == 2'h3);
|
|
bank_open[7] <= (bank_status[7][1:0] == 2'h3);
|
|
|
|
bank_closed[0] <= (bank_status[0][0] == 1'b0);
|
|
bank_closed[1] <= (bank_status[1][0] == 1'b0);
|
|
bank_closed[2] <= (bank_status[2][0] == 1'b0);
|
|
bank_closed[3] <= (bank_status[3][0] == 1'b0);
|
|
bank_closed[4] <= (bank_status[4][0] == 1'b0);
|
|
bank_closed[5] <= (bank_status[5][0] == 1'b0);
|
|
bank_closed[6] <= (bank_status[6][0] == 1'b0);
|
|
bank_closed[7] <= (bank_status[7][0] == 1'b0);
|
|
|
if (w_this_rw_move)
|
if (w_this_rw_move)
|
bank_wr_ck[rw_cmd[16:14]] <= (rw_cmd[`DDR_WEBIT])? 4'h0
|
bank_wr_ck[rw_cmd[16:14]] <= (rw_cmd[`DDR_WEBIT])? 4'h0
|
: write_recycle_clocks;
|
: write_recycle_clocks;
|
|
|
if (reset_override)
|
if (maintenance_override)
|
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_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;
|
|
bank_closed <= 8'hff;
|
|
bank_open <= 8'h00;
|
end else if (need_close_bank)
|
end else if (need_close_bank)
|
begin
|
begin
|
bank_status[close_bank_cmd[16:14]]
|
bank_status[close_bank_cmd[16:14]]
|
<= { bank_status[close_bank_cmd[16:14]][2:0], 1'b0 };
|
<= { bank_status[close_bank_cmd[16:14]][2:0], 1'b0 };
|
|
bank_open[close_bank_cmd[16:14]] <= 1'b0;
|
// bank_status[close_bank_cmd[16:14]][0] <= 1'b0;
|
// 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[activate_bank_cmd[16:14]]
|
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]][2:0], 1'b1 };
|
// bank_status[activate_bank_cmd[16:14]][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 else if ((valid_bank)&&(!r_move))
|
bank_closed[activate_bank_cmd[16:14]] <= 1'b0;
|
|
end else if (valid_bank)
|
;
|
;
|
else if (maybe_close_next_bank)
|
else if (maybe_close_next_bank)
|
begin
|
begin
|
bank_status[maybe_close_cmd[16:14]]
|
bank_status[maybe_close_cmd[16:14]]
|
<= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b0 };
|
<= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b0 };
|
|
bank_open[maybe_close_cmd[16:14]] <= 1'b0;
|
end else if (maybe_open_next_bank)
|
end else if (maybe_open_next_bank)
|
begin
|
begin
|
bank_status[maybe_open_cmd[16:14]]
|
bank_status[maybe_open_cmd[16:14]]
|
<= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
|
<= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
|
// bank_status[activate_bank_cmd[16:14]][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;
|
|
bank_closed[maybe_open_cmd[16:14]] <= 1'b0;
|
end
|
end
|
end
|
end
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
// if (cmd[22:19] == `DDR_ACTIVATE)
|
// if (cmd[22:19] == `DDR_ACTIVATE)
|
Line 467... |
Line 484... |
//
|
//
|
//
|
//
|
//
|
//
|
reg refresh_ztimer;
|
reg refresh_ztimer;
|
reg [16:0] refresh_counter;
|
reg [16:0] refresh_counter;
|
reg [3:0] refresh_addr;
|
reg [2:0] refresh_addr;
|
reg [23:0] refresh_instruction;
|
reg [23:0] refresh_instruction;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (reset_override)
|
if (reset_override)
|
refresh_addr <= 4'hf;
|
refresh_addr <= 3'hf;
|
else if (refresh_ztimer)
|
else if (refresh_ztimer)
|
refresh_addr <= refresh_addr + 1;
|
refresh_addr <= refresh_addr + 3'h1;
|
else if (refresh_instruction[`DDR_RFBEGIN])
|
else if (refresh_instruction[`DDR_RFBEGIN])
|
refresh_addr <= 4'h0;
|
refresh_addr <= 3'h0;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (reset_override)
|
if (reset_override)
|
begin
|
begin
|
refresh_ztimer <= 1'b1;
|
refresh_ztimer <= 1'b1;
|
Line 492... |
Line 509... |
begin
|
begin
|
refresh_ztimer <= 1'b0;
|
refresh_ztimer <= 1'b0;
|
refresh_counter <= refresh_instruction[16:0];
|
refresh_counter <= refresh_instruction[16:0];
|
end
|
end
|
|
|
|
`ifdef QUADRUPLE_REFRESH
|
|
// REFI4 = 13'd6240
|
wire [16:0] w_ckREFIn, w_ckREFRst;
|
wire [16:0] w_ckREFIn, w_ckREFRst;
|
assign w_ckREFIn[(CKRBITS-1): 0] = CKREFI4-5*CKRFC-2-10;
|
assign w_ckREFIn[(CKRBITS-1): 0] = CKREFI4-5*CKRFC-2-10;
|
assign w_ckREFIn[ 16:(CKRBITS)] = 0;
|
assign w_ckREFIn[ 16:(CKRBITS)] = 0;
|
assign w_ckREFRst = CKRFC-2-12;
|
assign w_ckREFRst = CKRFC-2-12;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (reset_override)
|
|
refresh_cmd <= { `DDR_NOOP, w_ckREFIn };
|
|
else if (refresh_ztimer)
|
|
refresh_cmd <= refresh_instruction[20:0];
|
|
always @(posedge i_clk)
|
|
if (reset_override)
|
|
need_refresh <= 1'b0;
|
|
else if (refresh_ztimer)
|
|
need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
|
|
|
|
always @(posedge i_clk)
|
|
if (refresh_ztimer)
|
if (refresh_ztimer)
|
case(refresh_addr)//NEED-RFC, HAVE-TIMER,
|
case(refresh_addr)//NEED-RFC, HAVE-TIMER,
|
4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
|
4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
|
// 17'd10 = time to complete write, plus write recovery time
|
// 17'd10 = time to complete write, plus write recovery time
|
// minus two (cause we can't count zero or one)
|
// minus two (cause we can't count zero or one)
|
Line 531... |
Line 539... |
4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
|
4'hc: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFRst };
|
4'hc: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFRst };
|
default:
|
default:
|
refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
|
refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
|
endcase
|
endcase
|
|
`else
|
|
wire [16:0] w_ckREFI_left, w_ckRFC_nxt;
|
|
assign w_ckREFI_left[12:0] = CKREFI-CKRFC-2-19;
|
|
assign w_ckREFI_left[16:13] = 0;
|
|
assign w_ckRFC_nxt[8:0] = CKRFC+9'h2;
|
|
assign w_ckRFC_nxt[16:9] = 0;
|
|
|
|
always @(posedge i_clk)
|
|
if (refresh_ztimer)
|
|
case(refresh_addr)//NEED-REFRESH, HAVE-TIMER, BEGIN(start-over)
|
|
3'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFI_left };
|
|
3'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 };
|
|
3'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 };
|
|
3'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 };
|
|
3'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
|
|
3'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC_nxt };
|
|
default:
|
|
refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
|
|
endcase
|
|
`endif
|
|
|
|
always @(posedge i_clk)
|
|
if (reset_override)
|
|
refresh_cmd <= { `DDR_NOOP, w_ckREFI_left };
|
|
else if (refresh_ztimer)
|
|
refresh_cmd <= refresh_instruction[20:0];
|
|
always @(posedge i_clk)
|
|
if (reset_override)
|
|
need_refresh <= 1'b0;
|
|
else if (refresh_ztimer)
|
|
need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
|
|
|
|
|
//
|
//
|
//
|
//
|
// Let's track: when will our bus be active? When will we be reading or
|
// Let's track: when will our bus be active? When will we be reading or
|
Line 542... |
Line 581... |
//
|
//
|
//
|
//
|
reg [`BUSNOW:0] bus_active, bus_read, bus_new, bus_ack;
|
reg [`BUSNOW:0] bus_active, bus_read, bus_new, bus_ack;
|
reg [1:0] bus_subaddr [`BUSNOW:0];
|
reg [1:0] bus_subaddr [`BUSNOW:0];
|
initial bus_active = 0;
|
initial bus_active = 0;
|
|
initial bus_ack = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 };
|
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_read[`BUSNOW:0] <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
|
// Is this a new command? i.e., the start of a transaction?
|
// Is this a new command? i.e., the start of a transaction?
|
Line 571... |
Line 611... |
bus_active[3:0]<= 4'hf; // Once per clock
|
bus_active[3:0]<= 4'hf; // Once per clock
|
bus_subaddr[3] <= 2'h0;
|
bus_subaddr[3] <= 2'h0;
|
bus_subaddr[2] <= 2'h1;
|
bus_subaddr[2] <= 2'h1;
|
bus_subaddr[1] <= 2'h2;
|
bus_subaddr[1] <= 2'h2;
|
bus_new[{ 2'b0, rw_sub }] <= 1'b1;
|
bus_new[{ 2'b0, rw_sub }] <= 1'b1;
|
|
bus_ack[3:0] <= 4'h0;
|
bus_ack[{ 2'b0, rw_sub }] <= 1'b1;
|
bus_ack[{ 2'b0, rw_sub }] <= 1'b1;
|
|
|
bus_read[3:0] <= (rw_we)? 4'h0:4'hf;
|
bus_read[3:0] <= (rw_we)? 4'h0:4'hf;
|
end else if ((s_pending)&&(!pipe_stall))
|
end else if ((s_pending)&&(!pipe_stall))
|
begin
|
begin
|
Line 582... |
Line 623... |
bus_ack[4] <= 1'b1;
|
bus_ack[4] <= 1'b1;
|
if (bus_subaddr[2] == s_sub)
|
if (bus_subaddr[2] == s_sub)
|
bus_ack[3] <= 1'b1;
|
bus_ack[3] <= 1'b1;
|
if (bus_subaddr[1] == s_sub)
|
if (bus_subaddr[1] == s_sub)
|
bus_ack[2] <= 1'b1;
|
bus_ack[2] <= 1'b1;
|
|
if (bus_subaddr[0] == s_sub)
|
|
bus_ack[1] <= 1'b1;
|
end
|
end
|
end
|
end
|
|
|
// Need to set o_wb_dqs high one clock prior to any read.
|
// Need to set o_wb_dqs high one clock prior to any read.
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
Line 595... |
Line 638... |
//
|
//
|
//
|
//
|
// Now, let's see, can we issue a read command?
|
// Now, let's see, can we issue a read command?
|
//
|
//
|
//
|
//
|
wire w_s_match;
|
reg pre_valid;
|
|
always @(posedge i_clk)
|
|
if ((refresh_ztimer)&&(refresh_instruction[`DDR_NEEDREFRESH]))
|
|
pre_valid <= 1'b0;
|
|
else if (need_refresh)
|
|
pre_valid <= 1'b0;
|
|
else if (w_this_rw_move)
|
|
pre_valid <= 1'b0;
|
|
else if (bus_active[0])
|
|
pre_valid <= 1'b0;
|
|
else
|
|
pre_valid <= 1'b1;
|
|
|
|
assign w_r_valid = (pre_valid)&&(r_pending)
|
|
&&(bank_status[r_bank][1])
|
|
&&(bank_address[r_bank]==r_row)
|
|
&&((r_we)||(bank_wr_ckzro[r_bank]));
|
|
assign w_s_valid = (pre_valid)&&(s_pending)
|
|
&&(bank_status[s_bank][1])
|
|
&&(bank_address[s_bank]==s_row)
|
|
&&((s_we)||(bank_wr_ckzro[s_bank]));
|
assign w_s_match = (s_pending)&&(r_pending)&&(r_we == s_we)
|
assign w_s_match = (s_pending)&&(r_pending)&&(r_we == s_we)
|
&&(r_row == s_row)&&(r_bank == s_bank)
|
&&(r_row == s_row)&&(r_bank == s_bank)
|
&&(r_col == s_col)
|
&&(r_col == s_col)
|
&&(r_sub > s_sub);
|
&&(r_sub > s_sub);
|
|
|
reg pipe_stall;
|
reg pipe_stall;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
r_pending <= (i_wb_stb)&&(~o_wb_stall)
|
r_pending <= (i_wb_stb)&&(~o_wb_stall)
|
||(r_pending)&&(pipe_stall);
|
||(r_pending)&&(pipe_stall);
|
Line 652... |
Line 716... |
|
|
// s_match <= w_s_match;
|
// s_match <= w_s_match;
|
end
|
end
|
end
|
end
|
|
|
assign w_need_close_this_bank = (r_pending)&&(bank_status[r_bank][0])
|
assign w_need_close_this_bank = (r_pending)
|
|
&&(bank_open[r_bank])
|
&&(bank_wr_ckzro[r_bank])
|
&&(bank_wr_ckzro[r_bank])
|
&&(r_row != bank_address[r_bank])
|
&&(r_row != bank_address[r_bank])
|
||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][0])
|
||(pipe_stall)&&(s_pending)&&(bank_open[s_bank])
|
&&(s_row != bank_address[s_bank]);
|
&&(s_row != bank_address[s_bank]);
|
assign w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00)
|
assign w_need_open_bank = (r_pending)&&(bank_closed[r_bank])
|
||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][1:0]==2'b00);
|
||(pipe_stall)&&(s_pending)&&(bank_closed[s_bank]);
|
assign w_r_valid = (!need_refresh)&&(r_pending)
|
|
&&(bank_status[r_bank][3])
|
|
&&(bank_address[r_bank]==r_row)
|
|
&&((r_we)||(bank_wr_ckzro[r_bank]))
|
|
&&(!bus_active[0]);
|
|
assign w_s_valid = (!need_refresh)&&(s_pending)
|
|
&&(bank_status[s_bank][3])
|
|
&&(bank_address[s_bank]==s_row)
|
|
&&((r_we)||(bank_wr_ckzro[s_bank]))
|
|
&&(!bus_active[0]);
|
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
need_close_bank <= (w_need_close_this_bank)
|
need_close_bank <= (w_need_close_this_bank)
|
&&(!need_open_bank)
|
&&(!need_open_bank)
|
&&(!need_close_bank)
|
&&(!need_close_bank)
|
&&(!w_this_closing_bank)&&(!last_closing_bank);
|
&&(!w_this_closing_bank);
|
|
|
maybe_close_next_bank <= (r_pending)
|
maybe_close_next_bank <= (s_pending)
|
&&(bank_status[r_nxt_bank][0])
|
&&(bank_open[s_nxt_bank])
|
&&(bank_wr_ckzro[r_nxt_bank])
|
&&(bank_wr_ckzro[s_nxt_bank])
|
&&(r_nxt_row != bank_address[r_nxt_bank])
|
&&(s_nxt_row != bank_address[s_nxt_bank])
|
&&(!w_this_maybe_close)&&(!last_maybe_close);
|
&&(!w_this_maybe_close)&&(!last_maybe_close);
|
|
|
close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
|
close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
|
maybe_close_cmd <= { `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] };
|
|
|
|
|
need_open_bank <= (w_need_open_bank)
|
need_open_bank <= (w_need_open_bank)
|
&&(!w_this_opening_bank)&&(!last_opening_bank);
|
&&(!w_this_opening_bank);
|
last_open_bank <= (w_this_opening_bank);
|
last_open_bank <= (w_this_opening_bank);
|
|
|
maybe_open_next_bank <= (r_pending)
|
maybe_open_next_bank <= (s_pending)
|
&&(bank_status[r_bank][0] == 1'b1)
|
&&(!need_close_bank)
|
&&(bank_status[r_nxt_bank][1:0] == 2'b00)
|
&&(!need_open_bank)
|
&&(!w_this_maybe_open)&&(!last_maybe_open);
|
&&(bank_closed[s_nxt_bank])
|
|
&&(!w_this_maybe_open); // &&(!last_maybe_open);
|
|
|
activate_bank_cmd<= { `DDR_ACTIVATE, r_bank, r_row[13:0] };
|
activate_bank_cmd<= { `DDR_ACTIVATE, r_bank, r_row[13:0] };
|
maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
|
maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
|
|
|
|
|
|
|
valid_bank <= ((w_r_valid)||(pipe_stall)&&(w_s_valid))
|
valid_bank <= ((w_r_valid)||((pipe_stall)&&(w_s_valid)))
|
&&(!last_valid_bank)&&(!r_move);
|
&&(!last_valid_bank)&&(!r_move)
|
|
&&(!w_this_rw_move);
|
last_valid_bank <= r_move;
|
last_valid_bank <= r_move;
|
|
|
if ((s_pending)&&(pipe_stall))
|
if ((s_pending)&&(pipe_stall))
|
rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (s_we)?`DDR_WRITE:`DDR_READ;
|
rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (s_we)?`DDR_WRITE:`DDR_READ;
|
else if (r_pending)
|
else if (r_pending)
|
Line 760... |
Line 817... |
&&(need_close_bank);
|
&&(need_close_bank);
|
assign w_this_opening_bank = (!maintenance_override)
|
assign w_this_opening_bank = (!maintenance_override)
|
&&(!need_close_bank)&&(need_open_bank);
|
&&(!need_close_bank)&&(need_open_bank);
|
assign w_this_rw_move = (!maintenance_override)
|
assign w_this_rw_move = (!maintenance_override)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&(valid_bank)&&(!r_move);
|
&&(valid_bank);
|
assign w_this_maybe_close = (!maintenance_override)
|
assign w_this_maybe_close = (!maintenance_override)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&((!valid_bank)||(r_move))
|
&&(!valid_bank)
|
&&(maybe_close_next_bank);
|
&&(maybe_close_next_bank);
|
assign w_this_maybe_open = (!maintenance_override)
|
assign w_this_maybe_open = (!maintenance_override)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&(!need_close_bank)&&(!need_open_bank)
|
&&((!valid_bank)||(r_move))
|
&&(!valid_bank)
|
&&(!maybe_close_next_bank)
|
&&(!maybe_close_next_bank)
|
&&(maybe_open_next_bank);
|
&&(maybe_open_next_bank);
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
last_opening_bank <= 1'b0;
|
last_opening_bank <= 1'b0;
|
Line 787... |
Line 844... |
last_closing_bank <= 1'b1;
|
last_closing_bank <= 1'b1;
|
end else if (need_open_bank)
|
end else if (need_open_bank)
|
begin
|
begin
|
cmd <= activate_bank_cmd;
|
cmd <= activate_bank_cmd;
|
last_opening_bank <= 1'b1;
|
last_opening_bank <= 1'b1;
|
end else if ((valid_bank)&&(!r_move))
|
end else if (valid_bank)
|
begin
|
begin
|
cmd <= rw_cmd;
|
cmd <= rw_cmd;
|
r_move <= 1'b1;
|
r_move <= 1'b1;
|
end else if (maybe_close_next_bank)
|
end else if (maybe_close_next_bank)
|
begin
|
begin
|
Line 803... |
Line 860... |
last_maybe_open <= 1'b1;
|
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
|
|
|
`define LGFIFOLN 3
|
`define LGFIFOLN 4
|
`define FIFOLEN 8
|
`define FIFOLEN 16
|
reg [(`LGFIFOLN-1):0] bus_fifo_head, bus_fifo_tail;
|
reg [(`LGFIFOLN-1):0] bus_fifo_head, bus_fifo_tail;
|
reg [31:0] bus_fifo_data [0:(`FIFOLEN-1)];
|
reg [31:0] bus_fifo_data [0:(`FIFOLEN-1)];
|
reg [1:0] bus_fifo_sub [0:(`FIFOLEN-1)];
|
reg [1:0] bus_fifo_sub [0:(`FIFOLEN-1)];
|
reg bus_fifo_new [0:(`FIFOLEN-1)];
|
reg bus_fifo_new [0:(`FIFOLEN-1)];
|
reg pre_ack;
|
reg pre_ack;
|