From 922d185643a1f8e7e6706e4f3308b31243b3e65e Mon Sep 17 00:00:00 2001 From: AngeloJacobo Date: Fri, 15 Sep 2023 19:58:36 +0800 Subject: [PATCH] now passes internal test calibration on klusterboard --- rtl/ddr3_phy.v | 60 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/rtl/ddr3_phy.v b/rtl/ddr3_phy.v index ea28d49..9a642ef 100644 --- a/rtl/ddr3_phy.v +++ b/rtl/ddr3_phy.v @@ -1,5 +1,6 @@ `default_nettype none `timescale 1ps / 1ps +//`define DEBUG_DQS module ddr3_phy #( parameter real CONTROLLER_CLK_PERIOD = 12, //ns, period of clock input to this DDR3 controller module @@ -9,7 +10,7 @@ module ddr3_phy #( DQ_BITS = 8, LANES = 8, parameter[0:0] ODELAY_SUPPORTED = 1, //set to 1 when ODELAYE2 is supported - USE_IO_TERMINATION = 1, //use IOBUF_DCIEN and IOBUFDS_DCIEN when 1 + USE_IO_TERMINATION = 0, //use IOBUF_DCIEN and IOBUFDS_DCIEN when 1 // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration parameter serdes_ratio = $rtoi(CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD), wb_data_bits = DQ_BITS*LANES*serdes_ratio*2, @@ -21,6 +22,7 @@ module ddr3_phy #( input wire i_ddr3_clk_90, //required only when ODELAY_SUPPORTED is zero input wire i_rst_n, // Controller Interface + input wire i_controller_reset, input wire[cmd_len*serdes_ratio-1:0] i_controller_cmd, input wire i_controller_dqs_tri_control, i_controller_dq_tri_control, input wire i_controller_toggle_dqs, @@ -49,7 +51,10 @@ module ddr3_phy #( inout wire[(DQ_BITS*LANES)-1:0] io_ddr3_dq, inout wire[(DQ_BITS*LANES)/8-1:0] io_ddr3_dqs, io_ddr3_dqs_n, output wire[LANES-1:0] o_ddr3_dm, - output wire o_ddr3_odt // on-die termination + output wire o_ddr3_odt, // on-die termination + // DEBUG PHY + output wire[(DQ_BITS*LANES)/8-1:0] o_ddr3_debug_read_dqs_p, + output wire[(DQ_BITS*LANES)/8-1:0] o_ddr3_debug_read_dqs_n ); // cmd bit assignment @@ -62,7 +67,7 @@ module ddr3_phy #( CMD_RESET_N = cmd_len - 7, CMD_BANK_START = BA_BITS + ROW_BITS - 1, CMD_ADDRESS_START = ROW_BITS - 1; - localparam SYNC_RESET_DELAY = $rtoi($ceil(100/CONTROLLER_CLK_PERIOD)); //52 ns of reset pulse width required for IDELAYCTRL + localparam SYNC_RESET_DELAY = $rtoi($ceil(1000/CONTROLLER_CLK_PERIOD)); //52 ns of reset pulse width required for IDELAYCTRL //cmd needs to be center-aligned to the positive edge of the //ddr3_clk. This means cmd needs to be delayed by half the ddr3 //clk period. Subtract by 600ps to include the IODELAY insertion @@ -106,10 +111,18 @@ module ddr3_phy #( assign o_controller_idelayctrl_rdy = idelayctrl_rdy && dci_locked; +`ifdef DEBUG_DQS + assign o_ddr3_debug_read_dqs_p = io_ddr3_dqs; + assign o_ddr3_debug_read_dqs_n = io_ddr3_dqs_n; +`else + assign o_ddr3_debug_read_dqs_p = 0; + assign o_ddr3_debug_read_dqs_n = 0; +`endif + //synchronous reset - always @(posedge i_controller_clk, negedge i_rst_n) begin - if(!i_rst_n) begin - sync_rst <= 1'b0; + always @(posedge i_controller_clk) begin + if(!i_rst_n || i_controller_reset) begin + sync_rst <= 1'b1; delay_before_release_reset <= SYNC_RESET_DELAY[$clog2(SYNC_RESET_DELAY):0]; toggle_dqs_q <= 0; end @@ -144,7 +157,7 @@ module ddr3_phy #( .D3(i_controller_cmd[cmd_len*2 + gen_index]), .D4(i_controller_cmd[cmd_len*3 + gen_index]), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -209,7 +222,7 @@ module ddr3_phy #( .D7(1'b1), .D8(1'b0), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -314,7 +327,7 @@ module ddr3_phy #( .T1(i_controller_dq_tri_control), .TCE(1'b1), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -430,7 +443,7 @@ module ddr3_phy #( .T1(i_controller_dq_tri_control), .TCE(1'b1), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -553,7 +566,7 @@ module ddr3_phy #( .DDLY(idelay_data[gen_index]), // 1-bit input: Serial data from IDELAYE2 .OFB(), // 1-bit input: Data feedback from OSERDESE2 .OCLKB(), // 1-bit input: High speed negative edge output clock - .RST(!idelayctrl_rdy), // 1-bit input: Active high asynchronous reset + .RST(sync_rst), // 1-bit input: Active high asynchronous reset // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports .SHIFTIN1(), .SHIFTIN2() @@ -593,7 +606,7 @@ module ddr3_phy #( .D8(i_controller_dm[gen_index + LANES*7]), .TCE(1'b0), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -683,7 +696,7 @@ module ddr3_phy #( .D8(i_controller_dm[gen_index + LANES*7]), .TCE(1'b0), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -720,8 +733,7 @@ module ddr3_phy #( // dqs: odelay -> iobuf for(gen_index = 0; gen_index < LANES; gen_index = gen_index + 1) begin - - +`ifndef DEBUG_DQS //remove the logic for dqs if needs to be debugged (directed to output instead) if(ODELAY_SUPPORTED) begin // OSERDESE2: Output SERial/DESerializer with bitslip //7 Series @@ -751,7 +763,7 @@ module ddr3_phy #( .T1(i_controller_dqs_tri_control), .TCE(1'b1), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -861,16 +873,16 @@ module ddr3_phy #( // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each) .D1(1'b1 && (i_controller_toggle_dqs || toggle_dqs_q)), //the last part will still have half dqs series .D2(1'b0 && (i_controller_toggle_dqs || toggle_dqs_q)), - .D3(1'b1 && (i_controller_toggle_dqs || toggle_dqs_q)), + .D3(1'b1 && (i_controller_toggle_dqs || toggle_dqs_q) && !i_controller_write_leveling_calib), .D4(1'b0 && (i_controller_toggle_dqs || toggle_dqs_q)), - .D5(1'b1 && i_controller_toggle_dqs), + .D5(1'b1 && i_controller_toggle_dqs && !i_controller_write_leveling_calib), .D6(1'b0 && i_controller_toggle_dqs), - .D7(1'b1 && i_controller_toggle_dqs), + .D7(1'b1 && i_controller_toggle_dqs && !i_controller_write_leveling_calib), .D8(1'b0 && i_controller_toggle_dqs), .T1(i_controller_dqs_tri_control), .TCE(1'b1), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(), @@ -995,13 +1007,13 @@ module ddr3_phy #( .DDLY(idelay_dqs[gen_index]), // 1-bit input: Serial data from IDELAYE2 .OFB(), // 1-bit input: Data feedback from OSERDESE2 .OCLKB(), // 1-bit input: High speed negative edge output clock - .RST(!idelayctrl_rdy), // 1-bit input: Active high asynchronous reset + .RST(sync_rst), // 1-bit input: Active high asynchronous reset // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports .SHIFTIN1(), .SHIFTIN2() ); // End of ISERDESE2_inst instantiation - +`endif //ISERDES train // End of IOBUF_inst instantiation @@ -1064,7 +1076,7 @@ module ddr3_phy #( .DDLY(), // 1-bit input: Serial data from IDELAYE2 .OFB(oserdes_bitslip_reference[gen_index]), // 1-bit input: Data feedback from OSERDESE2 .OCLKB(), // 1-bit input: High speed negative edge output clock - .RST(!idelayctrl_rdy), // 1-bit input: Active high asynchronous reset + .RST(sync_rst), // 1-bit input: Active high asynchronous reset // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports .SHIFTIN1(), .SHIFTIN2() @@ -1096,7 +1108,7 @@ module ddr3_phy #( .D7(1'b1), .D8(1'b1), .OCE(1'b1), // 1-bit input: Output data clock enable - .RST(!idelayctrl_rdy), // 1-bit input: Reset + .RST(sync_rst), // 1-bit input: Reset // unused signals but were added here to make vivado happy .SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT2(),