add prep state for ANALYZE_DATA to cut timing path due to indexing with lane

This commit is contained in:
AngeloJacobo 2025-12-22 13:11:20 +08:00
parent c605135dd9
commit a3edea5e00
1 changed files with 39 additions and 23 deletions

View File

@ -111,7 +111,7 @@ module ddr3_controller #(
input wire[wb_sel_bits - 1:0] i_wb_sel, //byte strobe for write (1 = write the byte) input wire[wb_sel_bits - 1:0] i_wb_sel, //byte strobe for write (1 = write the byte)
input wire[AUX_WIDTH - 1:0] i_aux, //for AXI-interface compatibility (given upon strobe) input wire[AUX_WIDTH - 1:0] i_aux, //for AXI-interface compatibility (given upon strobe)
// Wishbone outputs // Wishbone outputs
output wire o_wb_stall, //1 = busy, cannot accept requests output reg o_wb_stall, //1 = busy, cannot accept requests
output wire o_wb_ack, //1 = read/write request has completed output wire o_wb_ack, //1 = read/write request has completed
output wire o_wb_err, //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0) output wire o_wb_err, //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
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[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
@ -363,18 +363,19 @@ module ddr3_controller #(
ISSUE_READ = 11, ISSUE_READ = 11,
//ISSUE_READ_2 = 12, //ISSUE_READ_2 = 12,
READ_DATA = 12, READ_DATA = 12,
ANALYZE_DATA = 13, ANALYZE_DATA_PREP = 13,
CHECK_STARTING_DATA = 14, ANALYZE_DATA = 14,
BITSLIP_DQS_TRAIN_3 = 15, CHECK_STARTING_DATA = 15,
//WRITE_ZERO = 16, BITSLIP_DQS_TRAIN_3 = 16,
BURST_WRITE = 17, //WRITE_ZERO = 17,
BURST_READ = 18, BURST_WRITE = 18,
RANDOM_WRITE = 19, BURST_READ = 19,
RANDOM_READ = 20, RANDOM_WRITE = 20,
ALTERNATE_WRITE_READ = 21, RANDOM_READ = 21,
FINISH_READ = 22, ALTERNATE_WRITE_READ = 22,
DONE_CALIBRATE = 23, FINISH_READ = 23,
ANALYZE_DATA_LOW_FREQ = 24; DONE_CALIBRATE = 24,
ANALYZE_DATA_LOW_FREQ = 25;
localparam STORED_DQS_SIZE = 5, //must be >= 2 localparam STORED_DQS_SIZE = 5, //must be >= 2
REPEAT_DQS_ANALYZE = 1, REPEAT_DQS_ANALYZE = 1,
@ -580,7 +581,9 @@ module ddr3_controller #(
reg write_calib_dq = 0; reg write_calib_dq = 0;
reg prev_write_level_feedback = 1; reg prev_write_level_feedback = 1;
reg[wb_data_bits-1:0] read_data_store = 0; reg[wb_data_bits-1:0] read_data_store = 0;
reg[63:0] read_data_store_lane;
reg[127:0] write_pattern = 0; reg[127:0] write_pattern = 0;
reg[63:0] write_pattern_lane = 0;
reg[$clog2(64):0] data_start_index[LANES-1:0]; reg[$clog2(64):0] data_start_index[LANES-1:0];
reg[LANES-1:0] lane_write_dq_late = 0; reg[LANES-1:0] lane_write_dq_late = 0;
reg[LANES-1:0] lane_read_dq_early = 0; reg[LANES-1:0] lane_read_dq_early = 0;
@ -1989,10 +1992,12 @@ module ddr3_controller #(
end end
end //end of always block end //end of always block
assign force_o_wb_stall_high_d = !final_calibration_done || !instruction[REF_IDLE]; always @* begin
assign force_o_wb_stall_calib_high_d = !instruction[REF_IDLE]; force_o_wb_stall_high_d = !final_calibration_done || !instruction[REF_IDLE];
assign o_wb_stall = o_wb_stall_int_q || force_o_wb_stall_high_q; force_o_wb_stall_calib_high_d = !instruction[REF_IDLE];
assign o_wb_stall_calib = o_wb_stall_int_q || force_o_wb_stall_calib_high_q; o_wb_stall = o_wb_stall_int_q || force_o_wb_stall_high_q;
o_wb_stall_calib = o_wb_stall_int_q || force_o_wb_stall_calib_high_q;
end
// register previous value of cmd_ck_en // register previous value of cmd_ck_en
always @(posedge i_controller_clk) begin always @(posedge i_controller_clk) begin
@ -2291,7 +2296,9 @@ module ddr3_controller #(
calib_data <= 0; calib_data <= 0;
pause_counter <= 0; pause_counter <= 0;
read_data_store <= 0; read_data_store <= 0;
read_data_store_lane <= 0;
write_pattern <= 0; write_pattern <= 0;
write_pattern_lane <= 0;
added_read_pipe_max <= 0; added_read_pipe_max <= 0;
dqs_start_index_stored <= 0; dqs_start_index_stored <= 0;
dqs_start_index_repeat <= 0; dqs_start_index_repeat <= 0;
@ -2769,7 +2776,7 @@ module ddr3_controller #(
READ_DATA: if({o_aux[AUX_WIDTH-((ECC_ENABLE == 3)? 6 : 1) : 0], o_wb_ack_uncalibrated}== {{(AUX_WIDTH-((ECC_ENABLE == 3)? 6 : 1)){1'b0}}, 1'b1, 1'b1}) begin //wait for the read ack (which has AUX ID of 1} READ_DATA: if({o_aux[AUX_WIDTH-((ECC_ENABLE == 3)? 6 : 1) : 0], o_wb_ack_uncalibrated}== {{(AUX_WIDTH-((ECC_ENABLE == 3)? 6 : 1)){1'b0}}, 1'b1, 1'b1}) begin //wait for the read ack (which has AUX ID of 1}
read_data_store <= o_wb_data_uncalibrated; // read data on address 0 read_data_store <= o_wb_data_uncalibrated; // read data on address 0
calib_stb <= 0; calib_stb <= 0;
state_calibrate <= DLL_OFF? ANALYZE_DATA_LOW_FREQ : ANALYZE_DATA; state_calibrate <= DLL_OFF? ANALYZE_DATA_LOW_FREQ : ANALYZE_DATA_PREP;
// data_start_index[lane] <= 0; // dont set to zero since this may have been already set by previous CHECK_STARTING_DATA // data_start_index[lane] <= 0; // dont set to zero since this may have been already set by previous CHECK_STARTING_DATA
// Possible Patterns (strong autocorrel stat) // Possible Patterns (strong autocorrel stat)
//0x80dbcfd275f12c3d //0x80dbcfd275f12c3d
@ -2874,6 +2881,15 @@ module ddr3_controller #(
`endif `endif
end end
end end
ANALYZE_DATA_PREP: begin
write_pattern_lane <= write_pattern[ (lane_write_dq_late[lane]? 0 : data_start_index[lane]) +: 64];
read_data_store_lane <= {read_data_store[((DQ_BITS*LANES)*7 + {29'd0, lane}<<3) +: 8], read_data_store[((DQ_BITS*LANES)*6 + {29'd0, lane}<<3) +: 8],
read_data_store[((DQ_BITS*LANES)*5 + {29'd0, lane}<<3) +: 8], read_data_store[((DQ_BITS*LANES)*4 + {29'd0, lane}<<3) +: 8], read_data_store[((DQ_BITS*LANES)*3 + {29'd0, lane}<<3) +: 8],
read_data_store[((DQ_BITS*LANES)*2 + {29'd0, lane}<<3) +: 8],read_data_store[((DQ_BITS*LANES)*1 + {29'd0, lane}<<3) +: 8],read_data_store[((DQ_BITS*LANES)*0 + {29'd0, lane}<<3) +: 8] };
state_calibrate <= ANALYZE_DATA;
end
// extract burst_0-to-burst_7 data for a specified lane then determine which byte in write_pattern does it starts (ASSUMPTION: the DQ is too early [3d_9177298cd0ad51]c1 is written) // extract burst_0-to-burst_7 data for a specified lane then determine which byte in write_pattern does it starts (ASSUMPTION: the DQ is too early [3d_9177298cd0ad51]c1 is written)
// NOTE TO SELF: all "8" here assume DQ_BITS are 8? parameterize this properly // NOTE TO SELF: all "8" here assume DQ_BITS are 8? parameterize this properly
// data_start_index for a specified lane determine how many bits are off the data from the write command // data_start_index for a specified lane determine how many bits are off the data from the write command
@ -2881,9 +2897,7 @@ module ddr3_controller #(
// e.g. LANE={burst7, burst6, burst5, burst4, burst3, burst2, burst1, burst0} then with 1 ddr3 cycle delay between DQ and command // e.g. LANE={burst7, burst6, burst5, burst4, burst3, burst2, burst1, burst0} then with 1 ddr3 cycle delay between DQ and command
// burst0 will not be written but only starting on burst1 // burst0 will not be written but only starting on burst1
// if lane_write_dq_late is already set to 1 for this lane, then current lane should already be fixed without changing the data_start_index // if lane_write_dq_late is already set to 1 for this lane, then current lane should already be fixed without changing the data_start_index
ANALYZE_DATA: if(write_pattern[ (lane_write_dq_late[lane]? 0 : data_start_index[lane]) +: 64] == {read_data_store[((DQ_BITS*LANES)*7 + 8*lane) +: 8], read_data_store[((DQ_BITS*LANES)*6 + 8*lane) +: 8], ANALYZE_DATA: if(write_pattern_lane == read_data_store_lane) begin
read_data_store[((DQ_BITS*LANES)*5 + 8*lane) +: 8], read_data_store[((DQ_BITS*LANES)*4 + 8*lane) +: 8], read_data_store[((DQ_BITS*LANES)*3 + 8*lane) +: 8],
read_data_store[((DQ_BITS*LANES)*2 + 8*lane) +: 8],read_data_store[((DQ_BITS*LANES)*1 + 8*lane) +: 8],read_data_store[((DQ_BITS*LANES)*0 + 8*lane) +: 8] }) begin
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
if(lane == LANES - 1) begin if(lane == LANES - 1) begin
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
@ -2899,11 +2913,12 @@ module ddr3_controller #(
else begin else begin
lane <= lane + 1; lane <= lane + 1;
data_start_index[lane+1] <= 0; data_start_index[lane+1] <= 0;
state_calibrate <= ANALYZE_DATA_PREP;
`ifdef UART_DEBUG_ALIGN `ifdef UART_DEBUG_ALIGN
uart_start_send <= 1'b1; uart_start_send <= 1'b1;
uart_text <= {"state=ANALYZE_DATA, Done lane=",hex_to_ascii(lane),8'h0a,"-----------------",8'h0a}; uart_text <= {"state=ANALYZE_DATA, Done lane=",hex_to_ascii(lane),8'h0a,"-----------------",8'h0a};
state_calibrate <= WAIT_UART; state_calibrate <= WAIT_UART;
state_calibrate_next <= ANALYZE_DATA; state_calibrate_next <= ANALYZE_DATA_PREP;
`endif `endif
end end
end end
@ -2948,6 +2963,7 @@ module ddr3_controller #(
`ifdef UART_DEBUG_ALIGN `ifdef UART_DEBUG_ALIGN
else begin else begin
uart_start_send <= 1'b1; uart_start_send <= 1'b1;
state_calibrate <= ANALYZE_DATA_PREP;
uart_text <= {"state=ANALYZE_DATA, lane=",hex_to_ascii(lane), ", data_start_index[lane]=0x", uart_text <= {"state=ANALYZE_DATA, lane=",hex_to_ascii(lane), ", data_start_index[lane]=0x",
hex_to_ascii(data_start_index[lane][6:4]),hex_to_ascii(data_start_index[lane][3:0]),8'h0a,8'h0a,8'h0a,8'h0a, hex_to_ascii(data_start_index[lane][6:4]),hex_to_ascii(data_start_index[lane][3:0]),8'h0a,8'h0a,8'h0a,8'h0a,
{read_data_store[((DQ_BITS*LANES)*7 + 8*lane) +: 8], read_data_store[((DQ_BITS*LANES)*6 + 8*lane) +: 8], {read_data_store[((DQ_BITS*LANES)*7 + 8*lane) +: 8], read_data_store[((DQ_BITS*LANES)*6 + 8*lane) +: 8],
@ -2956,7 +2972,7 @@ module ddr3_controller #(
8'h0a,8'h0a,8'h0a,8'h0a 8'h0a,8'h0a,8'h0a,8'h0a
}; };
state_calibrate <= WAIT_UART; state_calibrate <= WAIT_UART;
state_calibrate_next <= ANALYZE_DATA; state_calibrate_next <= ANALYZE_DATA_PREP;
end end
`endif `endif
end end