applied :retab

This commit is contained in:
Angelo Jacobo 2023-03-30 18:27:58 +08:00 committed by GitHub
parent 7e1a145238
commit 192a9950e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 260 additions and 262 deletions

View File

@ -52,7 +52,7 @@ module ddr3_controller #(
input wire[wb_sel_bits - 1:0] i_wb_sel, //byte strobe for write (1 = write the byte)
input wire i_aux, //for AXI-interface compatibility (given upon strobe)
// Wishbone outputs
output reg o_wb_stall, //1 = busy, cannot accept requests
output reg o_wb_stall, //1 = busy, cannot accept requests
output reg o_wb_ack, //1 = read/write request has completed
output reg[wb_data_bits - 1:0] o_wb_data, //read data, for a 4:1 controller data width is 8 times the number of pins on the device
output reg o_aux //for AXI-interface compatibility (returned upon ack)
@ -75,11 +75,11 @@ module ddr3_controller #(
CMD_ZQC = 4'b0110; // ZQ Calibration (A10-AP: 0 = ZQ Calibration Short, 1 = ZQ Calibration Long)
localparam RST_DONE = 27, // Command bit that determines if reset seqeunce had aready finished. non-persistent (only needs to be toggled once),
REF_IDLE = 27, // No refresh is about to start and no ongoing refresh. (same bit as RST_DONE)
USE_TIMER = 26, // Command bit that determines if timer will be used (if delay is zero, USE_TIMER must be LOW)
A10_CONTROL = 25, //Command bit that determines if A10 AutoPrecharge will be high
CLOCK_EN = 24, //Clock-enable to DDR3
RESET_N = 23; //Reset_n to DDR3
REF_IDLE = 27, // No refresh is about to start and no ongoing refresh. (same bit as RST_DONE)
USE_TIMER = 26, // Command bit that determines if timer will be used (if delay is zero, USE_TIMER must be LOW)
A10_CONTROL = 25, //Command bit that determines if A10 AutoPrecharge will be high
CLOCK_EN = 24, //Clock-enable to DDR3
RESET_N = 23; //Reset_n to DDR3
// ddr3_metadata partitioning
localparam CMD_LEN = 4 + BA_BITS + ROW_BITS, //4 is the width of a single ddr3 command (precharge,actvate, etc.) plus bank bits plus row bits
@ -313,18 +313,17 @@ module ddr3_controller #(
//clear bank_status and bank_active_row to zero
integer index;
initial begin
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
bank_status_q[index] = 0;
bank_status_d[index] = 0;
bank_status_d[index] = 0;
bank_active_row_q[index] = 0;
bank_active_row_d[index] = 0;
bank_active_row_d[index] = 0;
end
end
reg request_we = 0;
reg request_pending_q = 0, request_pending_d = 0;
reg request_pending_q = 0, request_pending_d = 0;
reg[COL_BITS-1:0] request_col = 0;
reg[BA_BITS-1:0] request_bank = 0;
reg[ROW_BITS-1:0] request_row = 0;
@ -334,31 +333,31 @@ module ddr3_controller #(
reg[3:0] delay_before_activate_counter_q[(1<<BA_BITS)-1:0], delay_before_activate_counter_d[(1<<BA_BITS)-1:0] ;
reg[3:0] delay_before_write_counter_q[(1<<BA_BITS)-1:0], delay_before_write_counter_d[(1<<BA_BITS)-1:0] ;
reg[3:0] delay_before_read_counter_q[(1<<BA_BITS)-1:0] , delay_before_read_counter_d[(1<<BA_BITS)-1:0] ;
reg[3:0] delay_before_precharge_mask_q[(1<<BA_BITS)-1:0], delay_before_precharge_mask_d[(1<<BA_BITS)-1:0]; //command slot mask
reg[3:0] delay_before_precharge_mask_q[(1<<BA_BITS)-1:0], delay_before_precharge_mask_d[(1<<BA_BITS)-1:0]; //command slot mask
reg[3:0] delay_before_activate_mask_q[(1<<BA_BITS)-1:0], delay_before_activate_mask_d[(1<<BA_BITS)-1:0] ;
reg[3:0] delay_before_write_mask_q[(1<<BA_BITS)-1:0], delay_before_write_mask_d[(1<<BA_BITS)-1:0] ;
reg[3:0] delay_before_read_mask_q[(1<<BA_BITS)-1:0] , delay_before_read_mask_d[(1<<BA_BITS)-1:0] ;
(*keep*) reg[7:0] delay_before_precharge_added_delay;
(*keep*) reg[7:0] delay_before_activate_added_delay;
(*keep*) reg[7:0] delay_before_write_added_delay;
(*keep*) reg[7:0] delay_before_read_added_delay;
initial begin
(*keep*) reg[7:0] delay_before_precharge_added_delay;
(*keep*) reg[7:0] delay_before_activate_added_delay;
(*keep*) reg[7:0] delay_before_write_added_delay;
(*keep*) reg[7:0] delay_before_read_added_delay;
initial begin
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_q[index] = 0;
delay_before_activate_counter_q[index] = 0;
delay_before_write_counter_q[index] = 0;
delay_before_read_counter_q[index] = 0;
delay_before_precharge_mask_q[index] = -1;
delay_before_activate_mask_q[index] = -1;
delay_before_write_mask_q[index] = -1;
delay_before_read_mask_q[index] = -1;
end
delay_before_precharge_counter_q[index] = 0;
delay_before_activate_counter_q[index] = 0;
delay_before_write_counter_q[index] = 0;
delay_before_read_counter_q[index] = 0;
delay_before_precharge_mask_q[index] = -1;
delay_before_activate_mask_q[index] = -1;
delay_before_write_mask_q[index] = -1;
delay_before_read_mask_q[index] = -1;
end
end
(* keep *) reg[CMD_LEN-1:0] cmd_q[3:0], cmd_d[3:0];
reg o_wb_stall_d;
reg o_wb_ack_d;
@ -367,7 +366,7 @@ module ddr3_controller #(
cmd_q[1] = -1;
cmd_q[2] = -1;
cmd_q[3] = -1;
cmd_d[0] = -1;
cmd_d[0] = -1;
cmd_d[1] = -1;
cmd_d[2] = -1;
cmd_d[3] = -1;
@ -378,18 +377,18 @@ module ddr3_controller #(
if(!i_rst_n ) begin
o_wb_stall <= 1'b1;
o_wb_ack <= 1'b0;
request_pending_q <= 0;
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_q[index] <= 0;
delay_before_activate_counter_q[index] <= 0;
delay_before_write_counter_q[index] <= 0;
delay_before_read_counter_q[index] <= 0;
delay_before_precharge_mask_q[index] <= -1;
delay_before_activate_mask_q[index] <= -1;
delay_before_write_mask_q[index] <= -1;
delay_before_read_mask_q[index] <= -1;
end
request_pending_q <= 0;
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_q[index] <= 0;
delay_before_activate_counter_q[index] <= 0;
delay_before_write_counter_q[index] <= 0;
delay_before_read_counter_q[index] <= 0;
delay_before_precharge_mask_q[index] <= -1;
delay_before_activate_mask_q[index] <= -1;
delay_before_write_mask_q[index] <= -1;
delay_before_read_mask_q[index] <= -1;
end
cmd_q[0] <= -1;
cmd_q[1] <= -1;
cmd_q[2] <= -1;
@ -408,23 +407,23 @@ module ddr3_controller #(
else if(1/*reset_done*/) begin /////////////////////////////////////// else if(reset_done) begin
o_wb_stall <= o_wb_stall_d;
o_wb_ack <= o_wb_ack_d;
request_pending_q <= request_pending_d;
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_q[index] <= delay_before_precharge_counter_d[index];
delay_before_activate_counter_q[index] <= delay_before_activate_counter_d[index];
delay_before_write_counter_q[index] <= delay_before_write_counter_d[index];
delay_before_read_counter_q[index] <= delay_before_read_counter_d[index];
delay_before_precharge_mask_q[index] <= delay_before_precharge_mask_d[index];
delay_before_activate_mask_q[index] <= delay_before_activate_mask_d[index] ;
delay_before_write_mask_q[index] <= delay_before_write_mask_d[index];
delay_before_read_mask_q[index] <= delay_before_read_mask_d[index];
end
request_pending_q <= request_pending_d;
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_q[index] <= delay_before_precharge_counter_d[index];
delay_before_activate_counter_q[index] <= delay_before_activate_counter_d[index];
delay_before_write_counter_q[index] <= delay_before_write_counter_d[index];
delay_before_read_counter_q[index] <= delay_before_read_counter_d[index];
delay_before_precharge_mask_q[index] <= delay_before_precharge_mask_d[index];
delay_before_activate_mask_q[index] <= delay_before_activate_mask_d[index] ;
delay_before_write_mask_q[index] <= delay_before_write_mask_d[index];
delay_before_read_mask_q[index] <= delay_before_read_mask_d[index];
end
for(index=0; index < (1<<4); index=index+1) begin
for(integer index=0; index < (1<<4); index=index+1) begin
cmd_q[index] <= cmd_d[index];
end
for(index=0; index < (1<<BA_BITS); index=index+1) begin
for(integer index=0; index < (1<<BA_BITS); index=index+1) begin
bank_status_q[index] <= bank_status_d[index];
bank_active_row_q[index] <= bank_active_row_d[index];
end
@ -448,7 +447,7 @@ module ddr3_controller #(
// when not in refresh, transaction can only be processed when i_wb_cyc is high and not stall
if(i_wb_cyc && !o_wb_stall) begin
o_wb_stall <= i_wb_stb; // accept request only when stb is high and stall is low
request_pending_q <= i_wb_stb;
request_pending_q <= i_wb_stb;
request_we <= i_wb_we; //write-enable
request_col <= { i_wb_addr[(COL_BITS- $clog2(serdes_ratio*2)-1):0], {{$clog2(serdes_ratio*2)}{1'b0}} }; //column address (n-burst word-aligned)
request_bank <= i_wb_addr[(BA_BITS + COL_BITS- $clog2(serdes_ratio*2) - 1) : (COL_BITS- $clog2(serdes_ratio*2))]; //bank_address
@ -474,7 +473,7 @@ module ddr3_controller #(
//note: all delays after write counts only after the data burst (except for write-to-write tCCD)
//
//
// Example scenario on how this works:
// Example scenario on how this works:
// Say we have done precharge this clock cycle, the delay before
// the next activate is dictated by tRP. Say tRP needs 12nCK (DD3
// clock cycles) and the slot number for precharge is 2:
@ -502,58 +501,58 @@ module ddr3_controller #(
// Notice also that since this is arithmetically right shifted the
// 1s are preserved and the thread will remain all 1s until it is
// overwritten
always @* begin
request_pending_d = request_pending_q;
request_pending_d = request_pending_q;
o_wb_ack_d = 0;
cmd_d[0] = -1;
cmd_d[1] = -1;
cmd_d[2] = -1;
cmd_d[3] = -1;
delay_before_precharge_added_delay = 0;
delay_before_activate_added_delay = 0;
delay_before_write_added_delay = 0;
delay_before_read_added_delay = 0;
delay_before_precharge_added_delay = 0;
delay_before_activate_added_delay = 0;
delay_before_write_added_delay = 0;
delay_before_read_added_delay = 0;
for(integer index=0; index < (1<<BA_BITS); index=index+1) begin
bank_status_d[index] = bank_status_q[index];
bank_active_row_d[index] = bank_active_row_q[index];
end
// free-running shift registers (shift right arithmetic by 4 per controller clock cycle)
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_d[index] = (delay_before_precharge_counter_q[index] == 0)? 0: delay_before_precharge_counter_q[index] - 1;
delay_before_activate_counter_d[index] = (delay_before_activate_counter_q[index] == 0)? 0: delay_before_activate_counter_q[index] - 1;
delay_before_write_counter_d[index] = (delay_before_write_counter_q[index] == 0)? 0:delay_before_write_counter_q[index] - 1;
delay_before_read_counter_d[index] = (delay_before_read_counter_q[index] == 0)? 0:delay_before_read_counter_q[index] - 1;
delay_before_precharge_mask_d[index] = (delay_before_precharge_counter_q[index] == 0)? -1 : delay_before_precharge_mask_q[index];
delay_before_activate_mask_d[index] = (delay_before_activate_counter_q[index] == 0)? -1 : delay_before_activate_mask_q[index];
delay_before_write_mask_d[index] = (delay_before_write_counter_q[index] == 0)? -1 : delay_before_write_mask_q[index] ;
delay_before_read_mask_d[index] = (delay_before_read_counter_q[index] == 0)? -1 : delay_before_read_mask_q[index] ;
end
for(integer index=0; index< (1<<BA_BITS); index=index+1) begin
delay_before_precharge_counter_d[index] = (delay_before_precharge_counter_q[index] == 0)? 0: delay_before_precharge_counter_q[index] - 1;
delay_before_activate_counter_d[index] = (delay_before_activate_counter_q[index] == 0)? 0: delay_before_activate_counter_q[index] - 1;
delay_before_write_counter_d[index] = (delay_before_write_counter_q[index] == 0)? 0:delay_before_write_counter_q[index] - 1;
delay_before_read_counter_d[index] = (delay_before_read_counter_q[index] == 0)? 0:delay_before_read_counter_q[index] - 1;
delay_before_precharge_mask_d[index] = (delay_before_precharge_counter_q[index] == 0)? -1 : delay_before_precharge_mask_q[index];
delay_before_activate_mask_d[index] = (delay_before_activate_counter_q[index] == 0)? -1 : delay_before_activate_mask_q[index];
delay_before_write_mask_d[index] = (delay_before_write_counter_q[index] == 0)? -1 : delay_before_write_mask_q[index] ;
delay_before_read_mask_d[index] = (delay_before_read_counter_q[index] == 0)? -1 : delay_before_read_mask_q[index] ;
end
//if there is a pending request (stall is high), update the current stage
if(request_pending_q) begin
o_wb_stall_d = 1'b1;
request_pending_d = 1'b1;
request_pending_d = 1'b1;
//right row is already active so go straight to read/write
if(bank_status_q[request_bank] && bank_active_row_q[request_bank] == request_row) begin //read/write operation
//write request
if(request_we && delay_before_write_mask_q[request_bank][WRITE_SLOT] && delay_before_write_counter_q[request_bank] == 0) begin
o_wb_stall_d = 0;
request_pending_d = 0;
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_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_write_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{tCCD % 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_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor(tCCD/4) - 1): ($floor(tCCD/4) - 1 + 1);
delay_before_read_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{(CWL_nCK + 3'd4 + ns_to_nCK(tWTR)) % 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_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor((CWL_nCK + 4 + ns_to_nCK(tWTR))/4) - 1): ($floor((CWL_nCK + 4 + ns_to_nCK(tWTR))/4) - 1 + 1);
request_pending_d = 0;
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_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_write_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{tCCD % 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_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor(tCCD/4) - 1): ($floor(tCCD/4) - 1 + 1);
delay_before_read_added_delay = {{8{1'b1}}, added_delay(WRITE_SLOT), {{(CWL_nCK + 3'd4 + ns_to_nCK(tWTR)) % 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_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor((CWL_nCK + 4 + ns_to_nCK(tWTR))/4) - 1): ($floor((CWL_nCK + 4 + ns_to_nCK(tWTR))/4) - 1 + 1);
if(COL_BITS <= 10) begin
cmd_d[WRITE_SLOT] = {1'b0, CMD_WR[2:0], {{ROW_BITS+BA_BITS-4'd11}{1'b0}} , 1'b0 , request_col[9:0]};
@ -566,19 +565,19 @@ module ddr3_controller #(
//read request
else if(!request_we && delay_before_read_mask_q[request_bank][READ_SLOT] && delay_before_read_counter_q[request_bank]==0) begin
o_wb_stall_d = 0;
request_pending_d = 0;
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_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_read_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{tCCD % 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_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor(tCCD/4) - 1): ($floor(tCCD/4) - 1 + 1);
delay_before_write_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{(CL_nCK + tCCD + 3'd2 - CWL_nCK) % 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_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor((CL_nCK + tCCD + 2 - CWL_nCK)/4) - 1): ($floor((CL_nCK + tCCD + 2 - CWL_nCK)/4) - 1 + 1);
request_pending_d = 0;
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_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_read_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{tCCD % 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_counter_d[request_bank] = delay_before_read_added_delay[3:0]? ($floor(tCCD/4) - 1): ($floor(tCCD/4) - 1 + 1);
delay_before_write_added_delay = {{8{1'b1}}, added_delay(READ_SLOT), {{(CL_nCK + tCCD + 3'd2 - CWL_nCK) % 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_counter_d[request_bank] = delay_before_write_added_delay[3:0]? ($floor((CL_nCK + tCCD + 2 - CWL_nCK)/4) - 1): ($floor((CL_nCK + tCCD + 2 - CWL_nCK)/4) - 1 + 1);
if(COL_BITS <= 10) begin
cmd_d[READ_SLOT] = {1'b0, CMD_RD[2:0], {{ROW_BITS+BA_BITS-4'd11}{1'b0}} , 1'b0 , request_col[9:0]};
@ -587,69 +586,69 @@ module ddr3_controller #(
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
end
//bank is idle so activate it
end
//bank is idle so activate it
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_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_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_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_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_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_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_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);
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[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
bank_status_d[request_bank] = 1'b1;
bank_active_row_d[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[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
bank_status_d[request_bank] = 1'b1;
bank_active_row_d[request_bank] = request_row;
end
//bank is not idle but wrong row is activated so do precharge
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_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);
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[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[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[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;
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_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);
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[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[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[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;
end
//anticipated activate and precharge commands will only be allowed during the read/write cycles
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
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_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);
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] } };
bank_status_d[next_bank] = 1'b0;
end //end of anticipate precharge
//anticipated bank is idle so do activate
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_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_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_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};
bank_status_d[next_bank] = 1'b1;
bank_active_row_d[next_bank] = next_row;
end //end of anticipate activate
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_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] } };
bank_status_d[next_bank] = 1'b0;
end //end of anticipate precharge
//anticipated bank is idle so do activate
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_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_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_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};
bank_status_d[next_bank] = 1'b1;
bank_active_row_d[next_bank] = next_row;
end //end of anticipate activate
end //end of anticipate block
end //end of if(request_pending_q) block
else begin
o_wb_stall_d = 0;
end
else begin
o_wb_stall_d = 0;
end
end //end of always block
@ -680,7 +679,7 @@ module ddr3_controller #(
function [DELAY_SLOT_WIDTH - 1:0] nCK_to_ns (input integer nCK);
nCK_to_ns = $rtoi($ceil(nCK*1.0*DDR3_CLK_PERIOD)); //Without $rtoi: YOSYS ERROR: Non-constant expression in constant function
endfunction
// functions used to infer some localparam values
function integer max(input integer a, input integer b);
if(a >= b) max = a;
@ -767,45 +766,45 @@ module ddr3_controller #(
`ifndef YOSYS
///YOSYS: System task `$display' called with invalid/unsupported format specifier
initial begin
$display("Test ns_to_cycles() function:");
$display("\tns_to_cycles(15) = 3 = %0d [exact]", ns_to_cycles(15) );
$display("\tns_to_cycles(14.5) = 3 = %0d [round-off]", ns_to_cycles(14.5) );
$display("\tns_to_cycles(11) = 3 = %0d [round-up]\n", ns_to_cycles(11) );
$display("Test nCK_to_cycles() function:");
$display("\tns_to_cycles(16) = 4 = %0d [exact]", nCK_to_cycles(16) );
$display("\tns_to_cycles(15) = 4 = %0d [round-off]", nCK_to_cycles(15) );
$display("\tns_to_cycles(13) = 4 = %0d [round-up]\n", nCK_to_cycles(13) );
$display("Test ns_to_nCK() function:");
$display("\tns_to_cycles(15) = 12 = %0d [exact]", ns_to_nCK(15) );
$display("\tns_to_cycles(14.875) = 12 = %0d [round-off]", ns_to_nCK(14.875) );
$display("\tns_to_cycles(13.875) = 12 = %0d [round-up]", ns_to_nCK(13.875) );
$display("\tns_to_nCK(tRCD) = 11 = %0d [WRONG]", ns_to_nCK(tRCD));
$display("\ttRTP = 7.5 = %f ", tRTP);
$display("\tns_to_nCK(tRTP) = 6= %f [WRONG]\n", ns_to_nCK(tRTP) );
$display("Test nCK_to_ns() function:");
$display("\tns_to_cycles(4) = 5 = %0d [exact]", nCK_to_ns(4) );
$display("\tns_to_cycles(14.875) = 4 = %0d [round-off]", nCK_to_ns(3) );
$display("\tns_to_cycles(13.875) = 7 = %0d [round-up]\n", nCK_to_ns(5) );
$display("Test nCK_to_ns() function:");
$display("\tns_to_cycles(4) = 5 = %0d [exact]", nCK_to_ns(4) );
$display("\tns_to_cycles(14.875) = 4 = %0d [round-off]", nCK_to_ns(3) );
$display("\tns_to_cycles(13.875) = 7 = %0d [round-up]\n", nCK_to_ns(5) );
$display("Test added_delay() function:");
$display("\tadded_delay(0) = 0xffffffff = 0x%h", added_delay(0) );
$display("\tadded_delay(1) = 0xfffffffe = 0x%h", added_delay(1) );
$display("\tadded_delay(2) = 0xfffffffc = 0x%h", added_delay(2) );
$display("\tadded_delay(3) = 0xfffffff8 = 0x%h\n", added_delay(3) );
$display("Test $floor() function:");
$display("\t$floor(5/2) = 2.5 = %0d", $floor(5/2) );
$display("\t$floor(9/4) = 2.25 = %0d", $floor(9/4) );
$display("\t$floor(9/4) = 2 = %0d", $floor(8/4) );
$display("\t$floor(9/5) = 1.8 = %0d\n", $floor(9/5) );
$display("Test ns_to_cycles() function:");
$display("\tns_to_cycles(15) = 3 = %0d [exact]", ns_to_cycles(15) );
$display("\tns_to_cycles(14.5) = 3 = %0d [round-off]", ns_to_cycles(14.5) );
$display("\tns_to_cycles(11) = 3 = %0d [round-up]\n", ns_to_cycles(11) );
$display("Test nCK_to_cycles() function:");
$display("\tns_to_cycles(16) = 4 = %0d [exact]", nCK_to_cycles(16) );
$display("\tns_to_cycles(15) = 4 = %0d [round-off]", nCK_to_cycles(15) );
$display("\tns_to_cycles(13) = 4 = %0d [round-up]\n", nCK_to_cycles(13) );
$display("Test ns_to_nCK() function:");
$display("\tns_to_cycles(15) = 12 = %0d [exact]", ns_to_nCK(15) );
$display("\tns_to_cycles(14.875) = 12 = %0d [round-off]", ns_to_nCK(14.875) );
$display("\tns_to_cycles(13.875) = 12 = %0d [round-up]", ns_to_nCK(13.875) );
$display("\tns_to_nCK(tRCD) = 11 = %0d [WRONG]", ns_to_nCK(tRCD));
$display("\ttRTP = 7.5 = %f ", tRTP);
$display("\tns_to_nCK(tRTP) = 6= %f [WRONG]\n", ns_to_nCK(tRTP) );
$display("Test nCK_to_ns() function:");
$display("\tns_to_cycles(4) = 5 = %0d [exact]", nCK_to_ns(4) );
$display("\tns_to_cycles(14.875) = 4 = %0d [round-off]", nCK_to_ns(3) );
$display("\tns_to_cycles(13.875) = 7 = %0d [round-up]\n", nCK_to_ns(5) );
$display("Test nCK_to_ns() function:");
$display("\tns_to_cycles(4) = 5 = %0d [exact]", nCK_to_ns(4) );
$display("\tns_to_cycles(14.875) = 4 = %0d [round-off]", nCK_to_ns(3) );
$display("\tns_to_cycles(13.875) = 7 = %0d [round-up]\n", nCK_to_ns(5) );
$display("Test added_delay() function:");
$display("\tadded_delay(0) = 0xffffffff = 0x%h", added_delay(0) );
$display("\tadded_delay(1) = 0xfffffffe = 0x%h", added_delay(1) );
$display("\tadded_delay(2) = 0xfffffffc = 0x%h", added_delay(2) );
$display("\tadded_delay(3) = 0xfffffff8 = 0x%h\n", added_delay(3) );
$display("Test $floor() function:");
$display("\t$floor(5/2) = 2.5 = %0d", $floor(5/2) );
$display("\t$floor(9/4) = 2.25 = %0d", $floor(9/4) );
$display("\t$floor(9/4) = 2 = %0d", $floor(8/4) );
$display("\t$floor(9/5) = 1.8 = %0d\n", $floor(9/5) );
$display("\nDELAY_COUNTER_WIDTH = %0d", DELAY_COUNTER_WIDTH);
$display("DELAY_SLOT_WIDTH = %0d", DELAY_SLOT_WIDTH);
@ -817,22 +816,22 @@ module ddr3_controller #(
$display("wb_sel_bits = %0d\n\n",wb_sel_bits);
$display("request_row_width = %0d = %0d", ROW_BITS, $bits(i_wb_addr[ (ROW_BITS + BA_BITS + COL_BITS- $clog2(serdes_ratio*2) - 1) : (BA_BITS + COL_BITS- $clog2(serdes_ratio*2)) ]));
$display("request_col_width = %0d = %0d", COL_BITS, $bits({ i_wb_addr[(COL_BITS- $clog2(serdes_ratio*2)-1):0], {{$clog2(serdes_ratio*2)}{1'b0}} }));
$display("request_bank_width = %0d = %0d", BA_BITS, $bits(i_wb_addr[(BA_BITS + COL_BITS- $clog2(serdes_ratio*2) - 1) : (COL_BITS- $clog2(serdes_ratio*2))]));
$display("request_bank_width = %0d = %0d", BA_BITS, $bits(i_wb_addr[(BA_BITS + COL_BITS- $clog2(serdes_ratio*2) - 1) : (COL_BITS- $clog2(serdes_ratio*2))]));
$display("READ_SLOT = %0d", READ_SLOT);
$display("WRITE_SLOT = %0d", WRITE_SLOT);
$display("ANTICIPATE_ACTIVATE_SLOT = %0d", ANTICIPATE_ACTIVATE_SLOT);
$display("ANTICIPATE_PRECHARGE_SLOT = %0d", ANTICIPATE_PRECHARGE_SLOT);
$display("\n\nDELAYS:");
$display("\tns_to_nCK(tRCD): %0d", ns_to_nCK(tRCD));
$display("\tns_to_nCK(tRP): %0d", ns_to_nCK(tRP));
$display("\tns_to_nCK(tRTP): %0d", ns_to_nCK(tRTP));
$display("\ttCCD: %0d", tCCD);
$display("\t(CL_nCK + tCCD + 3'd2 - CWL_nCK): %0d", (CL_nCK + tCCD + 3'd2 - CWL_nCK));
$display("\t(CWL_nCK + 3'd4 + ns_to_nCK(tWR)): %0d", (CWL_nCK + 3'd4 + ns_to_nCK(tWR)));
$display("\t(CWL_nCK + 3'd4 + ns_to_nCK(tWTR)): %0d", (CWL_nCK + 3'd4 + ns_to_nCK(tWTR)));
$display("\t$signed(4'b1100)>>>4: %b", $signed(4'b1100) >>> 4);
$display("\n\nDELAYS:");
$display("\tns_to_nCK(tRCD): %0d", ns_to_nCK(tRCD));
$display("\tns_to_nCK(tRP): %0d", ns_to_nCK(tRP));
$display("\tns_to_nCK(tRTP): %0d", ns_to_nCK(tRTP));
$display("\ttCCD: %0d", tCCD);
$display("\t(CL_nCK + tCCD + 3'd2 - CWL_nCK): %0d", (CL_nCK + tCCD + 3'd2 - CWL_nCK));
$display("\t(CWL_nCK + 3'd4 + ns_to_nCK(tWR)): %0d", (CWL_nCK + 3'd4 + ns_to_nCK(tWR)));
$display("\t(CWL_nCK + 3'd4 + ns_to_nCK(tWTR)): %0d", (CWL_nCK + 3'd4 + ns_to_nCK(tWTR)));
$display("\t$signed(4'b1100)>>>4: %b", $signed(4'b1100) >>> 4);
end
`endif
@ -878,10 +877,10 @@ module ddr3_controller #(
assert(f_addr == instruction_address); //f_addr is the shadow of instruction_address (thus f_addr is the address of NEXT instruction)
f_read_inst = read_rom_instruction(f_read); //f_read is the address of CURRENT instruction
assert(f_read_inst == read_rom_instruction(f_read)); // needed for induction to make sure the engine will not create his own instruction
if(f_addr == 0) begin
f_read_inst = INITIAL_RESET_INSTRUCTION; //will only happen at the very start: f_addr (0) -> f_read (0) where we are reading the initial reset instruction and not the rom
end
assert(f_read_inst == instruction); // f_read_inst is the shadow of current instruction
if(f_addr == 0) begin
f_read_inst = INITIAL_RESET_INSTRUCTION; //will only happen at the very start: f_addr (0) -> f_read (0) where we are reading the initial reset instruction and not the rom
end
assert(f_read_inst == instruction); // f_read_inst is the shadow of current instruction
end
// main assertions for the reset sequence
@ -924,22 +923,22 @@ module ddr3_controller #(
end
//sanity checking for the comment "delay_counter will be zero AT NEXT CLOCK CYCLE when counter is now one"
if($past(delay_counter) == 1) begin
assert(delay_counter == 0 && delay_counter_is_zero);
end
if($past(delay_counter) == 1) begin
assert(delay_counter == 0 && delay_counter_is_zero);
end
//assert the relationship between the stages FOR RESET SEQUENCE
if(!reset_done) begin
if(f_addr == 0) begin
assert(f_read == 0); //will only happen at the very start: f_addr (0) -> f_read (0)
end
else if(f_read == 0) begin
assert(f_addr <= 1); //will only happen at the very first two cycles: f_addr (1) -> f_read (0) or f_addr (0) -> f_read (0)
end
//else if($past(reset_done)) assert(f_read == $past(f_read)); //reset instruction does not repeat after reaching end address thus it must saturate when pipeline reaches end
else begin
assert(f_read + 1 == f_addr); //address increments continuously
end
assert($past(f_read) <= 14); //only instruction address 0-to-13 is for reset sequence (reset_done is asserted at address 14)
if(!reset_done) begin
if(f_addr == 0) begin
assert(f_read == 0); //will only happen at the very start: f_addr (0) -> f_read (0)
end
else if(f_read == 0) begin
assert(f_addr <= 1); //will only happen at the very first two cycles: f_addr (1) -> f_read (0) or f_addr (0) -> f_read (0)
end
//else if($past(reset_done)) assert(f_read == $past(f_read)); //reset instruction does not repeat after reaching end address thus it must saturate when pipeline reaches end
else begin
assert(f_read + 1 == f_addr); //address increments continuously
end
assert($past(f_read) <= 14); //only instruction address 0-to-13 is for reset sequence (reset_done is asserted at address 14)
end
//assert the relationship between the stages FOR REFRESH SEQUENCE
@ -970,7 +969,7 @@ module ddr3_controller #(
always @* begin
//there MUST BE no instruction which USE_TIMER is high but delay is zero since it can cause the logic to lock-up (delay must be at least 1)
if(a[USE_TIMER]) begin
assert( a[DELAY_COUNTER_WIDTH - 1:0] > 0);
assert( a[DELAY_COUNTER_WIDTH - 1:0] > 0);
end
end
@ -995,44 +994,43 @@ module ddr3_controller #(
//create a formal assertion that says during refresh ack should be low always
//make an assertion that there will be no request pending before actual refresh starts at instruction 4'd12
reg[24:0] f_wb_inputs[13:0];
reg[4:0] f_index = 0;
reg[5:0] f_counter = 0;
initial begin
f_wb_inputs[0] = {1'b0, {14'd0,3'd1, 7'd0}}; //read
f_wb_inputs[1] = {1'b0, {14'd0,3'd1, 7'd8}}; //read on same bank (tCCD)
f_wb_inputs[2] = {1'b1, {14'd0,3'd1, 7'd16}}; //write on same bank (tRTW)
f_wb_inputs[3] = {1'b1, {14'd0,3'd1, 7'd24}}; //write on same bank (tCCD)
f_wb_inputs[4] = {1'b0, {14'd0,3'd2, 7'd0}}; //read on different bank
f_wb_inputs[5] = {1'b1, {14'd0,3'd2, 7'd8}}; //write on same bank (tRTW)
f_wb_inputs[6] = {1'b1, {14'd0,3'd1, 7'd32}}; //write on different bank (already activated)
f_wb_inputs[7] = {1'b1, {14'd0,3'd1, 7'd40}}; //write (tCCD)
f_wb_inputs[8] = {1'b1, {14'd1,3'd2, 7'd0}}; //write on different bank (already activated but wrong row)
f_wb_inputs[9] = {1'b1, {14'd1,3'd2, 7'd8}}; //write (tCCD)
f_wb_inputs[10] = {1'b1, {14'd1,3'd2, 7'd16}}; //write (tCCD)
f_wb_inputs[11] = {1'b0, {14'd2,3'd2, 7'd24}}; //read (same bank but wrong row so precharge first)
f_wb_inputs[12] = {1'b0, {14'd2,3'd2, 7'd32}}; //read (tCCD)
f_wb_inputs[13] = {1'b0, {14'd2,3'd2, 7'd40}}; //read (tCCD)
end
always @(posedge i_clk) begin
if(o_wb_ack) begin
f_index <= f_index + 1;
f_counter <= 0;
end
else begin
f_counter <= f_counter + 1;
end
end
always @* begin
assume(i_wb_cyc == 1);
assume(i_wb_stb == 1);
if(f_index>1) assume(i_rst_n);
assume(i_wb_we == f_wb_inputs[f_index][24]);
assume(i_wb_addr == f_wb_inputs[f_index][23:0]);
cover(f_index == 3);
end
reg[24:0] f_wb_inputs[13:0];
reg[4:0] f_index = 0;
reg[5:0] f_counter = 0;
initial begin
f_wb_inputs[0] = {1'b0, {14'd0,3'd1, 7'd0}}; //read
f_wb_inputs[1] = {1'b0, {14'd0,3'd1, 7'd8}}; //read on same bank (tCCD)
f_wb_inputs[2] = {1'b1, {14'd0,3'd1, 7'd16}}; //write on same bank (tRTW)
f_wb_inputs[3] = {1'b1, {14'd0,3'd1, 7'd24}}; //write on same bank (tCCD)
f_wb_inputs[4] = {1'b0, {14'd0,3'd2, 7'd0}}; //read on different bank
f_wb_inputs[5] = {1'b1, {14'd0,3'd2, 7'd8}}; //write on same bank (tRTW)
f_wb_inputs[6] = {1'b1, {14'd0,3'd1, 7'd32}}; //write on different bank (already activated)
f_wb_inputs[7] = {1'b1, {14'd0,3'd1, 7'd40}}; //write (tCCD)
f_wb_inputs[8] = {1'b1, {14'd1,3'd2, 7'd0}}; //write on different bank (already activated but wrong row)
f_wb_inputs[9] = {1'b1, {14'd1,3'd2, 7'd8}}; //write (tCCD)
f_wb_inputs[10] = {1'b1, {14'd1,3'd2, 7'd16}}; //write (tCCD)
f_wb_inputs[11] = {1'b0, {14'd2,3'd2, 7'd24}}; //read (same bank but wrong row so precharge first)
f_wb_inputs[12] = {1'b0, {14'd2,3'd2, 7'd32}}; //read (tCCD)
f_wb_inputs[13] = {1'b0, {14'd2,3'd2, 7'd40}}; //read (tCCD)
end
always @(posedge i_clk) begin
if(o_wb_ack) begin
f_index <= f_index + 1;
f_counter <= 0;
end
else begin
f_counter <= f_counter + 1;
end
end
always @* begin
assume(i_wb_cyc == 1);
assume(i_wb_stb == 1);
if(f_index>1) assume(i_rst_n);
assume(i_wb_we == f_wb_inputs[f_index][24]);
assume(i_wb_addr == f_wb_inputs[f_index][23:0]);
cover(f_index == 3);
end
`endif
endmodule