use a 4-bit counter plus a 4-bit mask for tracking delay in every bank
this is the optimized delay-tracking mechanism on which the 32-bit shift regs is replaced by a 4-bit counter plus a 4-bit mask. This uses lower resources but still able to track the delays and the exact slot number where the delay is already satisfied (hence no added latency)
This commit is contained in:
parent
fa3f5e0d65
commit
fa5fcc2615
|
|
@ -89,8 +89,8 @@ module ddr3_controller #(
|
||||||
|
|
||||||
localparam READ_SLOT = get_slot(CMD_RD),
|
localparam READ_SLOT = get_slot(CMD_RD),
|
||||||
WRITE_SLOT = get_slot(CMD_WR),
|
WRITE_SLOT = get_slot(CMD_WR),
|
||||||
ACTIVATE_SLOT = get_slot(CMD_ACT),
|
ANTICIPATE_ACTIVATE_SLOT = get_slot(CMD_ACT),
|
||||||
PRECHARGE_SLOT = get_slot(CMD_PRE);
|
ANTICIPATE_PRECHARGE_SLOT = get_slot(CMD_PRE);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
@ -503,7 +503,6 @@ module ddr3_controller #(
|
||||||
// 1s are preserved and the thread will remain all 1s until it is
|
// 1s are preserved and the thread will remain all 1s until it is
|
||||||
// overwritten
|
// overwritten
|
||||||
|
|
||||||
(*keep*) reg[1:0] f_stage;
|
|
||||||
always @* begin
|
always @* begin
|
||||||
request_pending_d = request_pending_q;
|
request_pending_d = request_pending_q;
|
||||||
o_wb_ack_d = 0;
|
o_wb_ack_d = 0;
|
||||||
|
|
@ -544,7 +543,6 @@ module ddr3_controller #(
|
||||||
o_wb_stall_d = 0;
|
o_wb_stall_d = 0;
|
||||||
request_pending_d = 0;
|
request_pending_d = 0;
|
||||||
o_wb_ack_d = 1;
|
o_wb_ack_d = 1;
|
||||||
|
|
||||||
delay_before_precharge_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{((CWL_nCK + 3'd4 + ns_to_nCK(tWR)) % 3'd4)}{1'b0}}};
|
delay_before_precharge_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{((CWL_nCK + 3'd4 + ns_to_nCK(tWR)) % 3'd4)}{1'b0}}};
|
||||||
delay_before_precharge_mask_d[request_bank] = delay_before_precharge_added_delay[3:0]? delay_before_precharge_added_delay[3:0]:delay_before_precharge_added_delay[7:4];
|
delay_before_precharge_mask_d[request_bank] = delay_before_precharge_added_delay[3:0]? delay_before_precharge_added_delay[3:0]:delay_before_precharge_added_delay[7:4];
|
||||||
delay_before_precharge_counter_d[request_bank] = delay_before_precharge_added_delay[3:0]? ($floor((CWL_nCK + 4 + ns_to_nCK(tWR))/4) - 1): ($floor((CWL_nCK + 4 + ns_to_nCK(tWR))/4) - 1 + 1);
|
delay_before_precharge_counter_d[request_bank] = delay_before_precharge_added_delay[3:0]? ($floor((CWL_nCK + 4 + ns_to_nCK(tWR))/4) - 1): ($floor((CWL_nCK + 4 + ns_to_nCK(tWR))/4) - 1 + 1);
|
||||||
|
|
@ -563,7 +561,6 @@ module ddr3_controller #(
|
||||||
else begin
|
else begin
|
||||||
cmd_d[WRITE_SLOT] = {1'b0, CMD_WR[2:0], {{ROW_BITS+BA_BITS-4'd12}{1'b0}} , request_col[10] , 1'b0 , request_col[9:0]};
|
cmd_d[WRITE_SLOT] = {1'b0, CMD_WR[2:0], {{ROW_BITS+BA_BITS-4'd12}{1'b0}} , request_col[10] , 1'b0 , request_col[9:0]};
|
||||||
end
|
end
|
||||||
f_stage = 3;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
//read request
|
//read request
|
||||||
|
|
@ -571,7 +568,6 @@ module ddr3_controller #(
|
||||||
o_wb_stall_d = 0;
|
o_wb_stall_d = 0;
|
||||||
request_pending_d = 0;
|
request_pending_d = 0;
|
||||||
o_wb_ack_d = 1;
|
o_wb_ack_d = 1;
|
||||||
|
|
||||||
delay_before_precharge_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{ns_to_nCK(tRTP) % 3'd4}{1'b0}}};
|
delay_before_precharge_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{ns_to_nCK(tRTP) % 3'd4}{1'b0}}};
|
||||||
delay_before_precharge_mask_d[request_bank] = delay_before_precharge_added_delay[3:0]? delay_before_precharge_added_delay[3:0]:delay_before_precharge_added_delay[7:4];
|
delay_before_precharge_mask_d[request_bank] = delay_before_precharge_added_delay[3:0]? delay_before_precharge_added_delay[3:0]:delay_before_precharge_added_delay[7:4];
|
||||||
delay_before_precharge_counter_d[request_bank] = delay_before_precharge_added_delay[3:0]? ($floor(ns_to_nCK(tRTP)/4) - 1): ($floor(ns_to_nCK(tRTP)/4) - 1 + 1);
|
delay_before_precharge_counter_d[request_bank] = delay_before_precharge_added_delay[3:0]? ($floor(ns_to_nCK(tRTP)/4) - 1): ($floor(ns_to_nCK(tRTP)/4) - 1 + 1);
|
||||||
|
|
@ -590,12 +586,11 @@ module ddr3_controller #(
|
||||||
else begin
|
else begin
|
||||||
cmd_d[READ_SLOT] = {1'b0, CMD_RD[2:0], {{ROW_BITS+BA_BITS-4'd12}{1'b0}} , request_col[10] , 1'b0 , request_col[9:0]};
|
cmd_d[READ_SLOT] = {1'b0, CMD_RD[2:0], {{ROW_BITS+BA_BITS-4'd12}{1'b0}} , request_col[10] , 1'b0 , request_col[9:0]};
|
||||||
end
|
end
|
||||||
f_stage = 3;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
//bank is idle so activate it
|
//bank is idle so activate it
|
||||||
else if(!bank_status_q[request_bank]) begin
|
else if(!bank_status_q[request_bank] && delay_before_activate_mask_q[request_bank][3:0] && delay_before_activate_counter_q[request_bank] == 0) begin
|
||||||
delay_before_read_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[request_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
delay_before_read_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[request_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
||||||
delay_before_read_mask_d[request_bank] = delay_before_read_added_delay[3:0]? delay_before_read_added_delay[3:0]:delay_before_read_added_delay[7:4];
|
delay_before_read_mask_d[request_bank] = delay_before_read_added_delay[3:0]? delay_before_read_added_delay[3:0]:delay_before_read_added_delay[7:4];
|
||||||
delay_before_read_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor(ns_to_nCK(tRCD) /4) - 1): ($floor(ns_to_nCK(tRCD) /4) - 1 + 1);
|
delay_before_read_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor(ns_to_nCK(tRCD) /4) - 1): ($floor(ns_to_nCK(tRCD) /4) - 1 + 1);
|
||||||
|
|
@ -603,80 +598,56 @@ module ddr3_controller #(
|
||||||
delay_before_write_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[request_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
delay_before_write_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[request_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
||||||
delay_before_write_mask_d[request_bank] = delay_before_write_added_delay[3:0]? delay_before_write_added_delay[3:0]:delay_before_write_added_delay[7:4];
|
delay_before_write_mask_d[request_bank] = delay_before_write_added_delay[3:0]? delay_before_write_added_delay[3:0]:delay_before_write_added_delay[7:4];
|
||||||
delay_before_write_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor(ns_to_nCK(tRCD)/4) - 1): ($floor(ns_to_nCK(tRCD)/4) - 1 + 1);
|
delay_before_write_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor(ns_to_nCK(tRCD)/4) - 1): ($floor(ns_to_nCK(tRCD)/4) - 1 + 1);
|
||||||
|
|
||||||
if(delay_before_activate_mask_q[request_bank][3:0] && delay_before_activate_counter_q[request_bank] == 0) begin
|
cmd_d[0] = {!delay_before_activate_mask_q[request_bank][0], CMD_ACT[2:0] , request_bank , request_row};
|
||||||
cmd_d[0] = {!delay_before_activate_mask_q[request_bank][0], CMD_ACT[2:0] , request_bank , request_row};
|
cmd_d[1] = {(delay_before_activate_mask_q[request_bank][1] ~^ delay_before_activate_mask_q[request_bank][0]), CMD_ACT[2:0] , request_bank , request_row};
|
||||||
cmd_d[1] = {(delay_before_activate_mask_q[request_bank][1] ~^ delay_before_activate_mask_q[request_bank][0]), CMD_ACT[2:0] , request_bank , request_row};
|
cmd_d[2] = {(delay_before_activate_mask_q[request_bank][2] ~^ delay_before_activate_mask_q[request_bank][1]), CMD_ACT[2:0] , request_bank , request_row};
|
||||||
cmd_d[2] = {(delay_before_activate_mask_q[request_bank][2] ~^ delay_before_activate_mask_q[request_bank][1]), CMD_ACT[2:0] , request_bank , request_row};
|
cmd_d[3] = {(delay_before_activate_mask_q[request_bank][3] ~^ delay_before_activate_mask_q[request_bank][2]), CMD_ACT[2:0] , request_bank , request_row}; //4 + 3 + 14 = 21
|
||||||
cmd_d[3] = {(delay_before_activate_mask_q[request_bank][3] ~^ delay_before_activate_mask_q[request_bank][2]), CMD_ACT[2:0] , request_bank , request_row}; //4 + 3 + 14 = 21
|
bank_status_d[request_bank] = 1'b1;
|
||||||
bank_status_d[request_bank] = 1'b1;
|
bank_active_row_d[request_bank] = request_row;
|
||||||
bank_active_row_d[request_bank] = request_row;
|
|
||||||
f_stage = 2;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
//bank is not idle but wrong row is activated so do precharge
|
//bank is not idle but wrong row is activated so do precharge
|
||||||
else begin
|
else if(bank_status_q[request_bank] && bank_active_row_q[request_bank] != request_row && delay_before_precharge_mask_q[request_bank][3:0] && delay_before_precharge_counter_q[request_bank] ==0) begin
|
||||||
delay_before_activate_added_delay = {{8{1'b1}}, delay_before_precharge_mask_q[request_bank], {{ns_to_nCK(tRP) % 3'd4}{1'b0}}};
|
delay_before_activate_added_delay = {{8{1'b1}}, delay_before_precharge_mask_q[request_bank], {{ns_to_nCK(tRP) % 3'd4}{1'b0}}};
|
||||||
delay_before_activate_mask_d[request_bank] = delay_before_activate_added_delay[3:0]? delay_before_activate_added_delay[3:0]:delay_before_activate_added_delay[7:4];
|
delay_before_activate_mask_d[request_bank] = delay_before_activate_added_delay[3:0]? delay_before_activate_added_delay[3:0]:delay_before_activate_added_delay[7:4];
|
||||||
delay_before_activate_counter_d[request_bank] = delay_before_activate_added_delay[3:0]? ($floor(ns_to_nCK(tRP)/4) - 1): ($floor(ns_to_nCK(tRP)/4) - 1 + 1);
|
delay_before_activate_counter_d[request_bank] = delay_before_activate_added_delay[3:0]? ($floor(ns_to_nCK(tRP)/4) - 1): ($floor(ns_to_nCK(tRP)/4) - 1 + 1);
|
||||||
|
|
||||||
//delay_before_activate_d[request_bank][31:ns_to_nCK(tRP) - 4] = delay_before_precharge_q[request_bank]; //this will get overwritten at next cock cycle
|
cmd_d[0] = {!delay_before_precharge_mask_q[request_bank][0], CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
||||||
if(delay_before_precharge_mask_q[request_bank][3:0] && delay_before_precharge_counter_q[request_bank] ==0) begin
|
cmd_d[1] = {(delay_before_precharge_mask_q[request_bank][1] ~^ delay_before_precharge_mask_q[request_bank][0]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
||||||
cmd_d[0] = {!delay_before_precharge_mask_q[request_bank][0], CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
cmd_d[2] = {(delay_before_precharge_mask_q[request_bank][2] ~^ delay_before_precharge_mask_q[request_bank][1]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
||||||
cmd_d[1] = {(delay_before_precharge_mask_q[request_bank][1] ~^ delay_before_precharge_mask_q[request_bank][0]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
cmd_d[3] = {(delay_before_precharge_mask_q[request_bank][3] ~^ delay_before_precharge_mask_q[request_bank][2]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
||||||
cmd_d[2] = {(delay_before_precharge_mask_q[request_bank][2] ~^ delay_before_precharge_mask_q[request_bank][1]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
bank_status_d[request_bank] = 1'b0;
|
||||||
cmd_d[3] = {(delay_before_precharge_mask_q[request_bank][3] ~^ delay_before_precharge_mask_q[request_bank][2]), CMD_PRE[2:0], request_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
|
||||||
bank_status_d[request_bank] = 1'b0;
|
|
||||||
f_stage = 1;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
/*
|
|
||||||
//anticipated activate and precharge commands will only be allowed during the read/write cycles
|
//anticipated activate and precharge commands will only be allowed during the read/write cycles
|
||||||
if(bank_status[request_bank] && bank_active_row[request_bank] == request_row) begin
|
if(bank_status_q[request_bank] && bank_active_row_q[request_bank] == request_row) begin
|
||||||
//anticipated bank is not idle but wrong row is currently activated so do precharge
|
//anticipated bank is not idle but wrong row is currently activated so do precharge
|
||||||
if(bank_status[next_bank] && bank_active_row[next_bank] != next_row) begin
|
if(bank_status_q[next_bank] && bank_active_row_q[next_bank] != next_row && delay_before_precharge_mask_q[next_bank][ANTICIPATE_PRECHARGE_SLOT] && delay_before_precharge_counter_q[next_bank] ==0) begin
|
||||||
delay_before_activate_added_delay = {{8{1'b1}}, delay_before_precharge_mask_q[next_bank], {{ns_to_nCK(tRP) % 3'd4}{1'b0}}};
|
delay_before_activate_added_delay = {{8{1'b1}}, delay_before_precharge_mask_q[next_bank], {{ns_to_nCK(tRP) % 3'd4}{1'b0}}};
|
||||||
delay_before_activate_mask_d[next_bank] = delay_before_activate_added_delay[3:0]? delay_before_activate_added_delay[3:0]:delay_before_activate_added_delay[7:4];
|
delay_before_activate_mask_d[next_bank] = delay_before_activate_added_delay[3:0]? delay_before_activate_added_delay[3:0]:delay_before_activate_added_delay[7:4];
|
||||||
delay_before_activate_counter_d[next_bank] = delay_before_activate_added_delay[3:0]? ($floor(ns_to_nCK(tRP)/4) - 1): ($floor(ns_to_nCK(tRP)/4) - 1 + 1);
|
delay_before_activate_counter_d[next_bank] = delay_before_activate_added_delay[3:0]? ($floor(ns_to_nCK(tRP)/4) - 1): ($floor(ns_to_nCK(tRP)/4) - 1 + 1);
|
||||||
|
cmd_d[ANTICIPATE_PRECHARGE_SLOT] = {1'b0, CMD_PRE[2:0], next_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , next_row[9:0] } };
|
||||||
if(delay_before_precharge_mask_q[next_bank][3:0] && delay_before_precharge_counter_q[next_bank] ==0) begin
|
bank_status_d[next_bank] = 1'b0;
|
||||||
cmd_d[0] = {!delay_before_precharge_mask_q[next_bank][0], CMD_PRE[2:0], next_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
|
||||||
cmd_d[1] = {(delay_before_precharge_mask_q[next_bank][1] ~^ delay_before_precharge_mask_q[next_bank][0]), CMD_PRE[2:0], next_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
|
||||||
cmd_d[2] = {(delay_before_precharge_mask_q[next_bank][2] ~^ delay_before_precharge_mask_q[next_bank][1]), CMD_PRE[2:0], next_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
|
||||||
cmd_d[3] = {(delay_before_precharge_mask_q[next_bank][3] ~^ delay_before_precharge_mask_q[next_bank][2]), CMD_PRE[2:0], next_bank, { {{ROW_BITS-4'd11}{1'b0}} , 1'b0 , request_row[9:0] } };
|
|
||||||
bank_status_d[next_bank] = 1'b0;
|
|
||||||
f_stage = 1;
|
|
||||||
end
|
|
||||||
end //end of anticipate precharge
|
end //end of anticipate precharge
|
||||||
|
|
||||||
//anticipated bank is idle so do activate
|
//anticipated bank is idle so do activate
|
||||||
else if(!bank_status_q[next_bank]) begin
|
else if(!bank_status_q[next_bank] && delay_before_activate_mask_q[next_bank][ANTICIPATE_ACTIVATE_SLOT] && delay_before_activate_counter_q[next_bank] == 0) begin
|
||||||
delay_before_read_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[next_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
delay_before_read_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[next_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
||||||
delay_before_read_mask_d[next_bank] = delay_before_read_added_delay[3:0]? delay_before_read_added_delay[3:0]:delay_before_read_added_delay[7:4];
|
delay_before_read_mask_d[next_bank] = delay_before_read_added_delay[3:0]? delay_before_read_added_delay[3:0]:delay_before_read_added_delay[7:4];
|
||||||
delay_before_read_counter_d[next_bank] = delay_before_read_added_delay[3:0]? ($floor(ns_to_nCK(tRCD) /4) - 1): ($floor(ns_to_nCK(tRCD) /4) - 1 + 1);
|
delay_before_read_counter_d[next_bank] = delay_before_read_added_delay[3:0]? ($floor(ns_to_nCK(tRCD) /4) - 1): ($floor(ns_to_nCK(tRCD) /4) - 1 + 1);
|
||||||
|
|
||||||
delay_before_write_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[next_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
delay_before_write_added_delay = {{8{1'b1}}, delay_before_activate_mask_q[next_bank], {{ns_to_nCK(tRCD) % 3'd4}{1'b0}}};
|
||||||
delay_before_write_mask_d[next_bank] = delay_before_write_added_delay[3:0]? delay_before_write_added_delay[3:0]:delay_before_write_added_delay[7:4];
|
delay_before_write_mask_d[next_bank] = delay_before_write_added_delay[3:0]? delay_before_write_added_delay[3:0]:delay_before_write_added_delay[7:4];
|
||||||
delay_before_write_counter_d[next_bank] = delay_before_write_added_delay[3:0]? ($floor(ns_to_nCK(tRCD)/4) - 1): ($floor(ns_to_nCK(tRCD)/4) - 1 + 1);
|
delay_before_write_counter_d[next_bank] = delay_before_write_added_delay[3:0]? ($floor(ns_to_nCK(tRCD)/4) - 1): ($floor(ns_to_nCK(tRCD)/4) - 1 + 1);
|
||||||
|
cmd_d[ANTICIPATE_ACTIVATE_SLOT] = {!delay_before_activate_mask_q[next_bank][0], CMD_ACT[2:0] , next_bank , next_row};
|
||||||
if(delay_before_activate_mask_q[next_bank][3:0] && delay_before_activate_counter_q[next_bank] == 0) begin
|
bank_status_d[next_bank] = 1'b1;
|
||||||
cmd_d[0] = {!delay_before_activate_mask_q[next_bank][0], CMD_ACT[2:0] , next_bank , request_row};
|
bank_active_row_d[next_bank] = next_row;
|
||||||
cmd_d[1] = {(delay_before_activate_mask_q[next_bank][1] ~^ delay_before_activate_mask_q[next_bank][0]), CMD_ACT[2:0] , next_bank , request_row};
|
|
||||||
cmd_d[2] = {(delay_before_activate_mask_q[next_bank][2] ~^ delay_before_activate_mask_q[next_bank][1]), CMD_ACT[2:0] , next_bank , request_row};
|
|
||||||
cmd_d[3] = {(delay_before_activate_mask_q[next_bank][3] ~^ delay_before_activate_mask_q[next_bank][2]), CMD_ACT[2:0] , next_bank , request_row}; //4 + 3 + 14 = 21
|
|
||||||
bank_status_d[next_bank] = 1'b1;
|
|
||||||
bank_active_row_d[next_bank] = request_row;
|
|
||||||
f_stage = 2;
|
|
||||||
end
|
|
||||||
end //end of anticipate activate
|
end //end of anticipate activate
|
||||||
end //end of anticipate block
|
end //end of anticipate block
|
||||||
*/
|
|
||||||
end //end of if(request_pending_q) block
|
end //end of if(request_pending_q) block
|
||||||
|
|
||||||
else begin
|
else begin
|
||||||
o_wb_stall_d = 0;
|
o_wb_stall_d = 0;
|
||||||
f_stage = 0;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end //end of always block
|
end //end of always block
|
||||||
|
|
@ -748,7 +719,7 @@ module ddr3_controller #(
|
||||||
function[1:0] get_slot (input[3:0] cmd); //cmd can either be CMD_PRE,CMD_ACT, CMD_WR, CMD_RD
|
function[1:0] get_slot (input[3:0] cmd); //cmd can either be CMD_PRE,CMD_ACT, CMD_WR, CMD_RD
|
||||||
integer slot_number;
|
integer slot_number;
|
||||||
integer delay;
|
integer delay;
|
||||||
integer read_slot, write_slot, activate_slot, precharge_slot;
|
integer read_slot, write_slot, anticipate_activate_slot, anticipate_precharge_slot;
|
||||||
begin
|
begin
|
||||||
// find read command slot number
|
// find read command slot number
|
||||||
delay = CL_nCK;
|
delay = CL_nCK;
|
||||||
|
|
@ -764,29 +735,29 @@ module ddr3_controller #(
|
||||||
end
|
end
|
||||||
write_slot = slot_number[1:0];
|
write_slot = slot_number[1:0];
|
||||||
|
|
||||||
// find activate command slot number
|
// find anticipate activate command slot number
|
||||||
if(CL_nCK > CWL_nCK) slot_number = read_slot;
|
if(CL_nCK > CWL_nCK) slot_number = read_slot;
|
||||||
else slot_number = write_slot;
|
else slot_number = write_slot;
|
||||||
delay = ns_to_nCK(tRCD);
|
delay = ns_to_nCK(tRCD);
|
||||||
for(slot_number = slot_number; delay != 0; delay = delay - 1) begin
|
for(slot_number = slot_number; delay != 0; delay = delay - 1) begin
|
||||||
slot_number[1:0] = slot_number[1:0] - 1'b1;
|
slot_number[1:0] = slot_number[1:0] - 1'b1;
|
||||||
end
|
end
|
||||||
activate_slot = slot_number[1:0];
|
anticipate_activate_slot = slot_number[1:0];
|
||||||
// if computed activate_slot is same with either write_slot or read_slot, decrement slot number until
|
// if computed anticipate_activate_slot is same with either write_slot or read_slot, decrement slot number until
|
||||||
while(activate_slot[1:0] == write_slot[1:0] || activate_slot[1:0] == read_slot[1:0]) begin
|
while(anticipate_activate_slot[1:0] == write_slot[1:0] || anticipate_activate_slot[1:0] == read_slot[1:0]) begin
|
||||||
activate_slot[1:0] = activate_slot[1:0] - 1'b1;
|
anticipate_activate_slot[1:0] = anticipate_activate_slot[1:0] - 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
//the remaining slot will be for precharge command
|
//the remaining slot will be for precharge command
|
||||||
precharge_slot = 0;
|
anticipate_precharge_slot = 0;
|
||||||
while(precharge_slot == write_slot || precharge_slot == read_slot || precharge_slot == activate_slot) begin
|
while(anticipate_precharge_slot == write_slot || anticipate_precharge_slot == read_slot || anticipate_precharge_slot == anticipate_activate_slot) begin
|
||||||
precharge_slot[1:0] = precharge_slot[1:0] - 1'b1;
|
anticipate_precharge_slot[1:0] = anticipate_precharge_slot[1:0] - 1'b1;
|
||||||
end
|
end
|
||||||
case(cmd)
|
case(cmd)
|
||||||
CMD_RD: get_slot = read_slot;
|
CMD_RD: get_slot = read_slot;
|
||||||
CMD_WR: get_slot = write_slot;
|
CMD_WR: get_slot = write_slot;
|
||||||
CMD_ACT: get_slot = activate_slot;
|
CMD_ACT: get_slot = anticipate_activate_slot;
|
||||||
CMD_PRE: get_slot = precharge_slot;
|
CMD_PRE: get_slot = anticipate_precharge_slot;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
|
|
@ -850,8 +821,8 @@ module ddr3_controller #(
|
||||||
|
|
||||||
$display("READ_SLOT = %0d", READ_SLOT);
|
$display("READ_SLOT = %0d", READ_SLOT);
|
||||||
$display("WRITE_SLOT = %0d", WRITE_SLOT);
|
$display("WRITE_SLOT = %0d", WRITE_SLOT);
|
||||||
$display("ACTIVATE_SLOT = %0d", ACTIVATE_SLOT);
|
$display("ANTICIPATE_ACTIVATE_SLOT = %0d", ANTICIPATE_ACTIVATE_SLOT);
|
||||||
$display("PRECHARGE_SLOT = %0d", PRECHARGE_SLOT);
|
$display("ANTICIPATE_PRECHARGE_SLOT = %0d", ANTICIPATE_PRECHARGE_SLOT);
|
||||||
|
|
||||||
$display("\n\nDELAYS:");
|
$display("\n\nDELAYS:");
|
||||||
$display("\tns_to_nCK(tRCD): %0d", ns_to_nCK(tRCD));
|
$display("\tns_to_nCK(tRCD): %0d", ns_to_nCK(tRCD));
|
||||||
|
|
@ -1018,7 +989,7 @@ module ddr3_controller #(
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
//make sure each command has distinct slot number (except for read/write which can have the same or different slot number)
|
//make sure each command has distinct slot number (except for read/write which can have the same or different slot number)
|
||||||
assert((WRITE_SLOT != ACTIVATE_SLOT != PRECHARGE_SLOT) && (READ_SLOT != ACTIVATE_SLOT != PRECHARGE_SLOT) );
|
assert((WRITE_SLOT != ANTICIPATE_ACTIVATE_SLOT != ANTICIPATE_PRECHARGE_SLOT) && (READ_SLOT != ANTICIPATE_ACTIVATE_SLOT != ANTICIPATE_PRECHARGE_SLOT) );
|
||||||
//make sure slot number for read command is correct
|
//make sure slot number for read command is correct
|
||||||
end
|
end
|
||||||
//create a formal assertion that says during refresh ack should be low always
|
//create a formal assertion that says during refresh ack should be low always
|
||||||
|
|
@ -1060,7 +1031,8 @@ module ddr3_controller #(
|
||||||
if(f_index>1) assume(i_rst_n);
|
if(f_index>1) assume(i_rst_n);
|
||||||
assume(i_wb_we == f_wb_inputs[f_index][24]);
|
assume(i_wb_we == f_wb_inputs[f_index][24]);
|
||||||
assume(i_wb_addr == f_wb_inputs[f_index][23:0]);
|
assume(i_wb_addr == f_wb_inputs[f_index][23:0]);
|
||||||
cover(f_index == 13);
|
cover(f_index == 3);
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue