From 6176aa7b8006c1e6afce86cd7df3b4fb799f887e Mon Sep 17 00:00:00 2001 From: Andrey Filippov Date: Mon, 2 Jun 2014 12:31:15 -0600 Subject: [PATCH] fixed DCI and ODT for all tested modes --- .project | 30 ++++---- ddrc_control.v | 39 ++++++++-- ddrc_test01.v | 25 ++++++- ddrc_test01_testbench.sav | 31 ++++---- ddrc_test01_testbench.tf | 152 +++++++++++++++++++++++--------------- phy/ddrc_sequencer.v | 4 + phy/phy_cmd.v | 8 +- phy/phy_top.v | 32 +++++--- 8 files changed, 209 insertions(+), 112 deletions(-) diff --git a/.project b/.project index 787daf3..366bed0 100644 --- a/.project +++ b/.project @@ -56,77 +56,77 @@ vivado_logs/VivadoBitstream.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoBitstream-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoBitstream-20140602122428009.log vivado_logs/VivadoOpt.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140602122428009.log vivado_logs/VivadoOptPhys.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPhys-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPhys-20140602122428009.log vivado_logs/VivadoOptPower.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140602122428009.log vivado_logs/VivadoPlace.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140602122428009.log vivado_logs/VivadoRoute.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoRoute-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoRoute-20140602122428009.log vivado_logs/VivadoSynthesis.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140531222614445.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140602115135083.log vivado_logs/VivadoTimimgSummaryReportImplemented.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportImplemented-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportImplemented-20140602122428009.log vivado_logs/VivadoTimimgSummaryReportSynthesis.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140531222614445.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140602115135083.log vivado_logs/VivadoTimingReportImplemented.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportImplemented-20140531223145240.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportImplemented-20140602122428009.log vivado_logs/VivadoTimingReportSynthesis.log 1 - /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140531222614445.log + /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140602115135083.log vivado_state/eddr3-opt-phys.dcp 1 - /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-opt-phys-20140531223145240.dcp + /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-opt-phys-20140602122428009.dcp vivado_state/eddr3-place.dcp 1 - /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140531223145240.dcp + /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140602122428009.dcp vivado_state/eddr3-route.dcp 1 - /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-route-20140531223145240.dcp + /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-route-20140602122428009.dcp vivado_state/eddr3-synth.dcp 1 - /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140531222614445.dcp + /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140602115135083.dcp diff --git a/ddrc_control.v b/ddrc_control.v index 8ec7108..64781fc 100644 --- a/ddrc_control.v +++ b/ddrc_control.v @@ -41,14 +41,19 @@ module ddrc_control #( parameter WBUF_DELAY_REL_MASK = 'h3ff, // address mask to set extra delay parameter PAGES_REL = 'h023, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]} parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns - parameter CMDA_EN_REL = 'h024, // address to enable('h823)/disable('h822) command/address outputs + parameter CMDA_EN_REL = 'h024, // address to enable('h825)/disable('h824) command/address outputs parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter SDRST_ACT_REL = 'h026, // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory + parameter SDRST_ACT_REL = 'h026, // address to activate('h827)/deactivate('h826) active-low reset signal to DDR3 memory parameter SDRST_ACT_REL_MASK = 'h3fe, // address mask for reset DDR3 - parameter CKE_EN_REL = 'h028, // address to enable('h827)/disable('h826) CKE signal to memory + parameter CKE_EN_REL = 'h028, // address to enable('h829)/disable('h828) CKE signal to memory parameter CKE_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter EXTRA_REL = 'h02a, // address to set extra parameters (currently just inv_clk_div) + parameter DCI_RST_REL = 'h02a, // address to activate('h82b)/deactivate('h82a) Zynq DCI calibrate circuitry + parameter DCI_RST_REL_MASK = 'h3fe, // address mask for DCI calibrate circuitry + parameter DLY_RST_REL = 'h02c, // address to activate('h82d)/deactivate('h82c) delay calibration circuitry + parameter DLY_RST_REL_MASK = 'h3fe, // address mask for delay calibration circuitry + parameter EXTRA_REL = 'h02e, // address to set extra parameters (currently just inv_clk_div) parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters + )( input clk, input mclk, @@ -73,6 +78,8 @@ module ddrc_control #( // control: additional signals output cmda_en, // tri-state all command and address lines to DDR chip output ddr_rst, // generate DDR3 memory reset signal + output dci_rst, // active high - reset DCI circuitry + output dly_rst, // active high - delay calibration circuitry output ddr_cke, // control DDR3 memory CKE signal output inv_clk_div, // invert clk_div to ISERDES @@ -118,6 +125,13 @@ module ddrc_control #( localparam SDRST_ACT_ADDR = CONTROL_ADDR | SDRST_ACT_REL; // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory localparam SDRST_ACT_ADDR_MASK =CONTROL_ADDR_MASK | SDRST_ACT_REL_MASK; // address mask for reset DDR3 + + localparam DCI_RST_ADDR = CONTROL_ADDR | DCI_RST_REL; // address to activate/deactivate Zynq DCI calibrate circuitry + localparam DCI_RST_ADDR_MASK = CONTROL_ADDR_MASK | DCI_RST_REL_MASK; // address mask for DCI calibrate circuitry + localparam DLY_RST_ADDR = CONTROL_ADDR | DLY_RST_REL; // address to activate/deactivate delay calibration circuitry + localparam DLY_RST_ADDR_MASK = CONTROL_ADDR_MASK | DLY_RST_REL_MASK; // address mask for delay calibration circuitry + + localparam CKE_EN_ADDR = CONTROL_ADDR | CKE_EN_REL; // address to enable('h827)/disable('h826) CKE signal to memory localparam CKE_EN_ADDR_MASK = CONTROL_ADDR_MASK | CKE_EN_REL_MASK; // address mask for CKE @@ -147,6 +161,8 @@ module ddrc_control #( reg [ 1:0] port1_int_page_r; // port 1 PHY-side buffer read page (to be controlled by arbiter later, set to 2'b0) reg cmda_en_r; // enable (tri-state off) all command and address lines to DDR chip reg ddr_rst_r; // generate DDR3 memory reset + reg dci_rst_r; // active high - reset DCI circuitry + reg dly_rst_r; // active high - reset delay calibration circuitry reg ddr_cke_r; // enable CKE to memory reg inv_clk_div_r; // invert clk_div to ISERDES @@ -179,7 +195,10 @@ module ddrc_control #( assign port1_page = port1_page_r[1:0]; assign port1_int_page = port1_int_page_r[1:0]; assign cmda_en = cmda_en_r; - assign ddr_rst= ddr_rst_r; + assign ddr_rst = ddr_rst_r; + assign dci_rst = dci_rst_r; + assign dly_rst = dly_rst_r; + assign ddr_cke= ddr_cke_r; assign inv_clk_div = inv_clk_div_r; @@ -235,6 +254,16 @@ module ddrc_control #( else if (fifo_re && (((waddr_fifo_out ^ SDRST_ACT_ADDR) & SDRST_ACT_ADDR_MASK)==0)) ddr_rst_r <= waddr_fifo_out[0]; + if (rst) dci_rst_r <= 1'b0; // reset DCI circuitry off (it is ORed with rst later) + else if (fifo_re && (((waddr_fifo_out ^ DCI_RST_ADDR) & DCI_RST_ADDR_MASK)==0)) + dci_rst_r <= waddr_fifo_out[0]; + + if (rst) dly_rst_r <= 1'b0; // reset DCI circuitry off (it is ORed with rst later) + else if (fifo_re && (((waddr_fifo_out ^ DLY_RST_ADDR) & DLY_RST_ADDR_MASK)==0)) + dly_rst_r <= waddr_fifo_out[0]; + + + if (rst) ddr_cke_r <= 1'b0; else if (fifo_re && (((waddr_fifo_out ^ CKE_EN_ADDR) & CKE_EN_ADDR_MASK)==0)) ddr_cke_r <= waddr_fifo_out[0]; diff --git a/ddrc_test01.v b/ddrc_test01.v index 745cbe7..8ed4c56 100644 --- a/ddrc_test01.v +++ b/ddrc_test01.v @@ -83,13 +83,17 @@ module ddrc_test01 #( parameter WBUF_DELAY_REL_MASK = 'h3ff, // address mask to set extra delay parameter PAGES_REL = 'h023, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]} parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns - parameter CMDA_EN_REL = 'h024, // address to enable('h823)/disable('h822) command/address outputs + parameter CMDA_EN_REL = 'h024, // address to enable('h825)/disable('h824) command/address outputs parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter SDRST_ACT_REL = 'h026, // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory + parameter SDRST_ACT_REL = 'h026, // address to activate('h827)/deactivate('h826) active-low reset signal to DDR3 memory parameter SDRST_ACT_REL_MASK = 'h3fe, // address mask for reset DDR3 - parameter CKE_EN_REL = 'h028, // address to enable('h827)/disable('h826) CKE signal to memory + parameter CKE_EN_REL = 'h028, // address to enable('h829)/disable('h828) CKE signal to memory parameter CKE_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter EXTRA_REL = 'h02a, // address to set extra parameters (currently just inv_clk_div) + parameter DCI_RST_REL = 'h02a, // address to activate('h82b)/deactivate('h82a) Zynq DCI calibrate circuitry + parameter DCI_RST_REL_MASK = 'h3fe, // address mask for DCI calibrate circuitry + parameter DLY_RST_REL = 'h02a, // address to activate('h82d)/deactivate('h82c) delay calibration circuitry + parameter DLY_RST_REL_MASK = 'h3fe, // address mask for delay calibration circuitry + parameter EXTRA_REL = 'h02e, // address to set extra parameters (currently just inv_clk_div) parameter EXTRA_REL_MASK = 'h3ff // address mask for extra parameters )( // DDR3 interface @@ -225,6 +229,11 @@ module ddrc_test01 #( // additional control signals wire cmda_en; // enable DDR3 memory control and addreee outputs wire ddr_rst; // generate DDR3 memory reset (active hight) + wire dci_rst; // active high - reset DCI circuitry + wire dly_rst; // active high - reset delay calibration circuitry + + + wire ddr_cke; // control of the DDR3 memory CKE signal wire inv_clk_div; // input @@ -384,6 +393,10 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0])); .SDRST_ACT_REL_MASK(SDRST_ACT_REL_MASK), .CKE_EN_REL (CKE_EN_REL), .CKE_EN_REL_MASK (CKE_EN_REL_MASK), + .DCI_RST_REL (DCI_RST_REL), + .DCI_RST_REL_MASK (DCI_RST_REL_MASK), + .DLY_RST_REL (DLY_RST_REL), + .DLY_RST_REL_MASK (DLY_RST_REL_MASK), .EXTRA_REL (EXTRA_REL), .EXTRA_REL_MASK (EXTRA_REL_MASK) ) ddrc_control_i ( @@ -405,6 +418,8 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0])); .dly_set (set), // output .cmda_en (cmda_en), // output .ddr_rst (ddr_rst), // output + .dci_rst (dci_rst), // output + .dly_rst (dly_rst), // output .ddr_cke (ddr_cke), // output .inv_clk_div (inv_clk_div), // output .dqs_pattern (dqs_pattern[7:0]), // output[7:0] @@ -532,6 +547,8 @@ BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0])); .port1_data (axiwr_bram_wdata[31:0]), // input[31:0] .cmda_en (cmda_en), // input .ddr_rst (ddr_rst), // input + .dci_rst (dci_rst), // input + .dly_rst (dly_rst), // input .ddr_cke (ddr_cke), // input .inv_clk_div (inv_clk_div), // input .dqs_pattern (dqs_pattern), // input[7:0] diff --git a/ddrc_test01_testbench.sav b/ddrc_test01_testbench.sav index d3a9f49..193e75d 100644 --- a/ddrc_test01_testbench.sav +++ b/ddrc_test01_testbench.sav @@ -1,21 +1,22 @@ [*] [*] GTKWave Analyzer v3.3.49 (w)1999-2013 BSI -[*] Sun Jun 1 23:19:02 2014 +[*] Mon Jun 2 06:48:00 2014 [*] -[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140601171040635.lxt" -[dumpfile_mtime] "Sun Jun 1 23:14:06 2014" -[dumpfile_size] 76198101 +[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140602003755521.lxt" +[dumpfile_mtime] "Mon Jun 2 06:40:41 2014" +[dumpfile_size] 76024228 [savefile] "/data/vdt/vdt-projects/eddr3/ddrc_test01_testbench.sav" -[timestart] 116772900 +[timestart] 102360000 [size] 1920 1180 [pos] 0 108 -*-16.459938 116901250 114486875 114489375 114571875 114574375 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-22.533184 131161875 114486875 114489375 114571875 114574375 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] ddrc_test01_testbench. [treeopen] ddrc_test01_testbench.ddrc_test01_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_read_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_write_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i. +[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i. [treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0]. [treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i. @@ -36,9 +37,9 @@ [treeopen] ddrc_test01_testbench.simul_axi_master_rdaddr_i. [treeopen] ddrc_test01_testbench.simul_axi_master_wraddr_i. [sst_width] 334 -[signals_width] 407 +[signals_width] 403 [sst_expanded] 1 -[sst_vpaned_height] 820 +[sst_vpaned_height] 755 @28 ddrc_test01_testbench.RST[0] ddrc_test01_testbench.CLK[0] @@ -1306,8 +1307,12 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.set[0] -ddrc_sequencer @800200 -ddr_sequencer_i_selected -@c00200 -tristate_control +@28 +ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDODT[0] +ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dqs[0] +ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dq[0] +ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dci_in[0] @22 ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i.dqs_tri_pattern_r[15:0] @28 @@ -1332,7 +1337,7 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri_in[0] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri[7:0] @28 ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.iobufs_dqs_i.T[0] -@1401200 +@1000200 -tristate_control @28 ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.sdclk[0] @@ -1391,7 +1396,7 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.cmd0_clk[0] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.cmd0_data[31:0] @28 ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.cmd0_we[0] -@23 +@22 ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.cmd_addr[9:0] @800028 ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.cmd_busy[2:0] @@ -1822,7 +1827,7 @@ ddrc_test01_testbench.ddrc_test01_i.axibram_write_i.wdata_i.we[0] ddrc_test01_testbench.ddrc_test01_i.axibram_write_i.wdata_i.wem[0] @1401200 -wdata_i -@800200 +@c00200 -axibram_read_i @28 ddrc_test01_testbench.ddrc_test01_i.axibram_read_i.aclk[0] @@ -1922,7 +1927,7 @@ ddrc_test01_testbench.SIMUL_AXI_FULL[0] ddrc_test01_testbench.rstb[0] @200 - -@1000200 +@1401200 -axibram_read_i @c00200 -ddrc_status diff --git a/ddrc_test01_testbench.tf b/ddrc_test01_testbench.tf index e8c0961..56872a5 100644 --- a/ddrc_test01_testbench.tf +++ b/ddrc_test01_testbench.tf @@ -42,7 +42,7 @@ module ddrc_test01_testbench #( parameter CLKFBOUT_MULT_REF = 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE parameter CLKFBOUT_DIV_REF = 3, // To get 300MHz for the reference clock `endif - parameter DIVCLK_DIVIDE= 1, // | 3 + parameter DIVCLK_DIVIDE= 1, // parameter CLKFBOUT_PHASE = 0.000, parameter SDCLK_PHASE = 0.000, parameter CLK_PHASE = 0.000, @@ -83,14 +83,18 @@ module ddrc_test01_testbench #( parameter WBUF_DELAY_REL_MASK = 'h3ff, // address mask to set extra delay parameter PAGES_REL = 'h023, // address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]} parameter PAGES_REL_MASK = 'h3ff, // address mask to set DQM and DQS patterns - parameter CMDA_EN_REL = 'h024, // address to enable('h823)/disable('h822) command/address outputs + parameter CMDA_EN_REL = 'h024, // address to enable('h825)/disable('h824) command/address outputs parameter CMDA_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter SDRST_ACT_REL = 'h026, // address to activate('h825)/deactivate('h8242) active-low reset signal to DDR3 memory + parameter SDRST_ACT_REL = 'h026, // address to activate('h827)/deactivate('h826) active-low reset signal to DDR3 memory parameter SDRST_ACT_REL_MASK = 'h3fe, // address mask for reset DDR3 - parameter CKE_EN_REL = 'h028, // address to enable('h827)/disable('h826) CKE signal to memory + parameter CKE_EN_REL = 'h028, // address to enable('h829)/disable('h828) CKE signal to memory parameter CKE_EN_REL_MASK = 'h3fe, // address mask for command/address outputs - parameter EXTRA_REL = 'h02a, // address to set extra parameters (currently just inv_clk_div) - parameter EXTRA_REL_MASK = 'h3ff, // address mask for extra parameters + parameter DCI_RST_REL = 'h02a, // address to activate('h82b)/deactivate('h82a) Zynq DCI calibrate circuitry + parameter DCI_RST_REL_MASK = 'h3fe, // address mask for DCI calibrate circuitry + parameter DLY_RST_REL = 'h02a, // address to activate('h82d)/deactivate('h82c) delay calibration circuitry + parameter DLY_RST_REL_MASK = 'h3fe, // address mask for delay calibration circuitry + parameter EXTRA_REL = 'h02e, // address to set extra parameters (currently just inv_clk_div) + parameter EXTRA_REL_MASK = 'h3ff, // address mask for extra parameters // simulation-specific parameters parameter integer AXI_RDADDR_LATENCY=2, @@ -127,9 +131,15 @@ module ddrc_test01_testbench #( localparam BASEADDR_PAGES = BASEADDR_CTRL | (PAGES_REL<<2); // 'h023, address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]} localparam BASEADDR_CMDA_EN = BASEADDR_CTRL | (CMDA_EN_REL<<2); // 'h024, address to enable('h825)/disable('h824) command/address outputs localparam BASEADDR_SDRST_ACT = BASEADDR_CTRL | (SDRST_ACT_REL<<2); // 'h026 address to activate('h827)/deactivate('h826) active-low reset signal to DDR3 memory - localparam BASEADDR_CKE_EN = BASEADDR_CTRL | (CKE_EN_REL<<2); // 'h028 + localparam BASEADDR_CKE_EN = BASEADDR_CTRL | (CKE_EN_REL<<2); // 'h028 + +// SuppressWarnings VEditor + localparam BASEADDR_DCI_RST = BASEADDR_CTRL | (DCI_RST_REL<<2); // 'h02a (+1 - enable) +// SuppressWarnings VEditor + localparam BASEADDR_DLY_RST = BASEADDR_CTRL | (DLY_RST_REL<<2); // 'h02c (+1 - enable) + // SuppressWarnings VEditor - localparam BASEADDR_EXTRA = BASEADDR_CTRL | (EXTRA_REL<<2); // 'h02a, address to set extra parameters (currently just inv_clk_div) + localparam BASEADDR_EXTRA = BASEADDR_CTRL | (EXTRA_REL<<2); // 'h02e, address to set extra parameters (currently just inv_clk_div) localparam BASEADDRESS_LANE0_ODELAY = BASEADDR_DLY_LD; localparam BASEADDRESS_LANE0_IDELAY = BASEADDR_DLY_LD+('h10<<2); @@ -583,9 +593,12 @@ assign bresp= ddrc_test01_i.ps7_i.MAXIGP0BRESP; .SDRST_ACT_REL_MASK (SDRST_ACT_REL_MASK), .CKE_EN_REL (CKE_EN_REL), .CKE_EN_REL_MASK (CKE_EN_REL_MASK), + .DCI_RST_REL (DCI_RST_REL), + .DCI_RST_REL_MASK (DCI_RST_REL_MASK), + .DLY_RST_REL (DLY_RST_REL), + .DLY_RST_REL_MASK (DLY_RST_REL_MASK), .EXTRA_REL (EXTRA_REL), .EXTRA_REL_MASK (EXTRA_REL_MASK) - ) ddrc_test01_i ( .SDRST (SDRST), // DDR3 reset (active low) .SDCLK (SDCLK), // output @@ -1070,7 +1083,7 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(5,0); // tMOD + data <= encode_seq_skip(5,0,0,0); // tMOD @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1201,7 +1214,7 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(2,0); // tWR = 15ns (6 cycles for 2.5ns) from end of write (not write command) + data <= encode_seq_skip(2,0,1,0); // keep dci enabled @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1218,19 +1231,37 @@ simul_axi_read simul_axi_read_i( 1'b0, // phy_dq_en_in; 1'b0, // phy_dqs_en_in; 1'b0, // phy_dqs_toggle_en; - 1'b0, // phy_dci_en_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + 1'b1, // phy_dci_en_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) 1'b0, // phy_buf_wr; // connect to external buffer 1'b0, // phy_buf_rd; // connect to external buffer 1'b0); // add NOP after the current command, keep other data @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(5,0); // tMOD + data <= encode_seq_skip(5,0,1,0 ); // tMOD (keep DCI enabled) + @(posedge CLK) + axi_write_single(cmd_addr, data); + cmd_addr <= cmd_addr + 4; +// Turn off DCI + data <= encode_seq_word( + 15'h0, // [14:0] phy_addr_in; + mr3_norm[17:15], // [ 2:0] phy_bank_in; //TODO: debug! + 3'b000, // [ 2:0] phy_rcw_in; // {ras,cas,we}, positive + 1'b0, // phy_odt_in; // may be optimized? + 1'b0, // phy_cke_inv; // may be optimized? + 1'b0, // phy_sel_in == 1; + 1'b0, // phy_dq_en_in; + 1'b0, // phy_dqs_en_in; + 1'b0, // phy_dqs_toggle_en; + 1'b0, // phy_dci_en_in; + 1'b0, // phy_buf_wr; // connect to external buffer + 1'b0, // phy_buf_rd; // connect to external buffer + 1'b0); // add NOP after the current command, keep other data @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(0,1); // end of sequence + data <= encode_seq_skip(0,1,0,0); // end of sequence (no dci, no odt) @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1268,7 +1299,7 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; // see if pause is needed . See when buffer read should be started - maybe before WR command - data <= encode_seq_skip(1,0); // tRCD + data <= encode_seq_skip(1,0,0,0); @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1398,12 +1429,13 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - - data <= encode_seq_skip(2,0); // tWR = 15ns (6 cycles for 2.5ns) from end of write (not write command) + // tRTP = 4*tCK is already satisfied, no skip here +/* + data <= encode_seq_skip(1,0,1,0); // keep DCI // What delay is needed tRTP (4 tCK or 7.5ns) @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - +*/ // precharge data <= { ra[14:0], @@ -1415,7 +1447,7 @@ simul_axi_read simul_axi_read_i( 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b0, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) 1'b0, // phy_dqs_toggle_en; - 1'b0, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + 1'b1, // phy_dci_en_in, // keep DCI enabled 1'b0, // phy_buf_wr, // connect to external buffer (but only if not paused) 1'b0, // phy_buf_rd, // connect to external buffer (but only if not paused) 1'b0, // add NOP after the current command, keep other data @@ -1425,12 +1457,12 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(2,0); // + data <= encode_seq_skip(2,0,1,0); // keep DCI @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(0,1); // end of sequence + data <= encode_seq_skip(0,1,0,0); // end of sequence . TODO: verify DCI is disabled here - yes, OK @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1468,7 +1500,7 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; // see if pause is needed . See when buffer read should be started - maybe before WR command - data <= encode_seq_skip(1,0); // tRCD + data <= encode_seq_skip(1,0,0,0); // tRCD @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1478,8 +1510,8 @@ simul_axi_read simul_axi_read_i( {5'b0,ca[9:0]}, ba[2:0], //phy_bank_in[2:0], 3'b011, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b1, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b0, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1498,8 +1530,8 @@ simul_axi_read simul_axi_read_i( 15'b0, // skip 0 ba[2:0], //phy_bank_in[2:0], 3'b000, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b1, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1521,8 +1553,8 @@ simul_axi_read simul_axi_read_i( {5'b0,ca[9:0]} + (i<<3), ba[2:0], //phy_bank_in[2:0], 3'b011, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b1, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b1, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1544,7 +1576,7 @@ simul_axi_read simul_axi_read_i( 15'b0, // skip 0 ba[2:0], //phy_bank_in[2:0], 3'b000, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? + 1'b1, // phy_odt_in, // may be optimized? 1'b0, // phy_cke_inv, // may be optimized? 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b1, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) @@ -1564,8 +1596,8 @@ simul_axi_read simul_axi_read_i( 15'b0, // skip 0 ba[2:0], //phy_bank_in[2:0], 3'b000, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b1, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1585,8 +1617,8 @@ simul_axi_read simul_axi_read_i( 15'b0, // skip 0 ba[2:0], //phy_bank_in[2:0], 3'b000, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b1, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1600,13 +1632,13 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - - data <= encode_seq_skip(2,0); // tWR = 15ns (6 cycles for 2.5ns) from end of write (not write command) +// ODT off, it has latency + data <= encode_seq_skip(2,0,0,0); // tWR = 15ns (6 cycles for 2.5ns) from end of write (not write command) @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; -// precharge +// precharge, ODT off data <= { ra[14:0], ba[2:0], //phy_bank_in[2:0], @@ -1627,12 +1659,12 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(2,0); // + data <= encode_seq_skip(2,0,0,0); // @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(0,1); // end of sequence + data <= encode_seq_skip(0,1,0,0); // end of sequence @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1687,7 +1719,7 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(13,0); // tWLDQSEN=25tCK + data <= encode_seq_skip(13,0,0,0); // tWLDQSEN=25tCK @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1697,8 +1729,8 @@ simul_axi_read simul_axi_read_i( dqs_low_rpt, // 16 tCK 3'b0, //phy_bank_in[2:0], 3'b0, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? - 1'b0, // phy_cke_inv, // may be optimized? + 1'b1, // phy_odt_in, + 1'b0, // phy_cke_inv, 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) @@ -1712,10 +1744,6 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; -// data <= encode_seq_skip(2,0); // Adjust skip -// @(posedge CLK) -// axi_write_single(cmd_addr, data); -// cmd_addr <= cmd_addr + 4; // Toggle DQS as needed for write leveling, write to buffer data <= { // encode_seq_skip(nrep,0); // Adjust skip @@ -1723,13 +1751,13 @@ simul_axi_read simul_axi_read_i( nrep_minus_1[CMD_PAUSE_BITS-1:0], 3'b0, //phy_bank_in[2:0], 3'b0, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? + 1'b1, // phy_odt_in, // may be optimized? 1'b0, // phy_cke_inv, // may be optimized? 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_toggle_en; - 1'b0, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + 1'b1, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) 1'b1, // phy_buf_wr, // connect to external buffer (but only if not paused) 1'b0, // phy_buf_rd, // connect to external buffer (but only if not paused) 1'b0, // add NOP after the current command, keep other data @@ -1743,13 +1771,13 @@ simul_axi_read simul_axi_read_i( 15'h4, // 4 cycles 3'b0, //phy_bank_in[2:0], 3'b0, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? + 1'b1, // phy_odt_in, // may be optimized? 1'b0, // phy_cke_inv, // may be optimized? 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_en_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) 1'b1, // phy_dqs_toggle_en; - 1'b0, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + 1'b1, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) 1'b0, // phy_buf_wr, // no write 1'b0, // phy_buf_rd, // connect to external buffer (but only if not paused) 1'b0, // add NOP after the current command, keep other data @@ -1760,14 +1788,14 @@ simul_axi_read simul_axi_read_i( cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(2,0); // Adjust skip + data <= encode_seq_skip(2,0,1,1); // Keep DCI and ODT active @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - // exit write leveling mode + // exit write leveling mode, ODT off, DCI off data <= encode_seq_word( mr1_norm[14:0], // [14:0] phy_addr_in; mr1_norm[17:15], // [ 2:0] phy_bank_in; //TODO: debug! @@ -1786,12 +1814,12 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(5,0); // tMOD + data <= encode_seq_skip(5,0,0,0); // tMOD @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; // Ready for normal operation - data <= encode_seq_skip(10,1); // sequence done bit, skip length is ignored + data <= encode_seq_skip(10,1,0,0); // sequence done bit, skip length is ignored @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1857,7 +1885,7 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(1,0); // 6 cycles between mrs commands + data <= encode_seq_skip(1,0,0,0); // 6 cycles between mrs commands @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1879,7 +1907,7 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; // TODO: function - does not check arguments number - data <= encode_seq_skip(0,0); // 5 cycles between mrs commands (next command has phy_sel_in == 1) + data <= encode_seq_skip(0,0,0,0); // 5 cycles between mrs commands (next command has phy_sel_in == 1) @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1901,7 +1929,7 @@ simul_axi_read simul_axi_read_i( @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(2,0); // 7 cycles between mrs commands ( prev. command had phy_sel_in == 1) + data <= encode_seq_skip(2,0,0,0); // 7 cycles between mrs commands ( prev. command had phy_sel_in == 1) @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1924,7 +1952,7 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(5,0); // tMOD = 12 CK or 15ns, (tMOD/2)-1 + data <= encode_seq_skip(5,0,0,0); // tMOD = 12 CK or 15ns, (tMOD/2)-1 @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -1947,12 +1975,12 @@ simul_axi_read simul_axi_read_i( axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; - data <= encode_seq_skip(256,0); // 512 clock cycles after ZQCL + data <= encode_seq_skip(256,0,0,0); // 512 clock cycles after ZQCL @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; // Ready for normal operation - data <= encode_seq_skip(10,1); // sequence done bit, skip length is ignored + data <= encode_seq_skip(10,1,0,0); // sequence done bit, skip length is ignored @(posedge CLK) axi_write_single(cmd_addr, data); cmd_addr <= cmd_addr + 4; @@ -2023,6 +2051,8 @@ simul_axi_read simul_axi_read_i( function [31:0] encode_seq_skip; input [CMD_PAUSE_BITS-1:0] skip; input done; + input dci_en; + input odt_en; begin encode_seq_skip={ {14-CMD_DONE_BIT{1'b0}}, @@ -2030,13 +2060,13 @@ simul_axi_read simul_axi_read_i( skip[CMD_PAUSE_BITS-1:0], 3'b0, //phy_bank_in[2:0], 3'b0, // phy_rcw_in[2:0], // {ras,cas,we} - 1'b0, // phy_odt_in, // may be optimized? + odt_en, // phy_odt_in, 1'b0, // phy_cke_in, // may be optimized? 1'b0, // phy_sel_in, // first/second half-cycle, other will be nop (cke+odt applicable to both) 1'b0, // phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) 1'b0, // phy_dqs_en_in, //phy_dqs_tri_in, // tristate DQS lines (internal timing sequencer for 0->1 and 1->0) 1'b0, //enable toggle DQS according to the pattern - 1'b0, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + dci_en, // phy_dci_en_in, //phy_dci_in, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) 1'b0, // phy_buf_wr, // connect to external buffer (but only if not paused) 1'b0, // phy_buf_rd, // connect to external buffer (but only if not paused) 1'b0, // add NOP after the current command, keep other data diff --git a/phy/ddrc_sequencer.v b/phy/ddrc_sequencer.v index f54f59f..dbe6631 100644 --- a/phy/ddrc_sequencer.v +++ b/phy/ddrc_sequencer.v @@ -111,6 +111,8 @@ module ddrc_sequencer #( // extras input cmda_en, // enable (!tristate) command and address lines // not likely to be used input ddr_rst, // generate reset to DDR3 memory (active high) + input dci_rst, // active high - reset DCI circuitry + input dly_rst, // active high - delay calibration circuitry input ddr_cke, // DDR clock enable , XOR-ed with command bit input inv_clk_div, input [7:0] dqs_pattern, // 8'h55 @@ -380,6 +382,8 @@ module ddrc_sequencer #( .buf_rd (buf_rd), // output .cmda_en (cmda_en), // input .ddr_rst (ddr_rst), // input + .dci_rst (dci_rst), // input + .dly_rst (dly_rst), // input .ddr_cke (ddr_cke), // input .inv_clk_div (inv_clk_div), // input .dqs_pattern (dqs_pattern), // input[7:0] diff --git a/phy/phy_cmd.v b/phy/phy_cmd.v index 680e374..5d7c6f6 100644 --- a/phy/phy_cmd.v +++ b/phy/phy_cmd.v @@ -97,6 +97,8 @@ module phy_cmd#( // input cmda_tri, // tristate command and address lines // not likely to be used input cmda_en, // tristate command and address lines // not likely to be used input ddr_rst, // generate reset to DDR3 memory (active high) + input dci_rst, // active high - reset DCI circuitry + input dly_rst, // active high - delay calibration circuitry input ddr_cke, // DDR clock enable , XOR-ed with command bit input inv_clk_div, input [7:0] dqs_pattern, // 8'h55 @@ -180,7 +182,7 @@ module phy_cmd#( phy_addr_in, phy_bank_in, phy_rcw_pos, // {ras,cas,we} - phy_odt_in, // may be optimized? + phy_odt_in, // phy_cke_dis, // disable cke (0 - enable), also controlled by a command bit ddr_cke (XOR-ed) phy_sel_in, // fitst/second half-cycle, oter will be nop (cke+odt applicable to both) phy_dq_en_in, //phy_dq_tri_in, // tristate DQ lines (internal timing sequencer for 0->1 and 1->0) @@ -248,7 +250,7 @@ module phy_cmd#( assign phy_dqs_tri= (dqs_tri_prev==phy_dqs_tri_in)?{{8{phy_dqs_tri_in}}}: (dqs_tri_prev?{dqs_tri_on_pattern,dqs_tri_on_pattern}:{dqs_tri_off_pattern,dqs_tri_off_pattern}); assign phy_dci_dis_dq = phy_dci_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) - assign phy_dci_dis_dqs = phy_dci_in; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0) + assign phy_dci_dis_dqs = phy_dci_in || phy_odt_cur; // In write leveling mode phy_dci_in = 0, phy_odt_cur=1 - use DCI on DQ only, no DQS assign locked = locked_r2; assign ps_rdy = ps_rdy_r2; @@ -380,6 +382,8 @@ module phy_cmd#( .rst_in (rst_in), // input .ddr_rst (ddr_rst), // input + .dci_rst (dci_rst), // input + .dly_rst (dly_rst), // input .in_a (phy_addr[2*ADDRESS_NUMBER-1:0]), // input[29:0] .in_ba (phy_bank[5:0]), // input[5:0] .in_we ({phy_rcw[3],phy_rcw[0]}), // input[1:0] diff --git a/phy/phy_top.v b/phy/phy_top.v index 631eceb..0f350cd 100644 --- a/phy/phy_top.v +++ b/phy/phy_top.v @@ -76,7 +76,10 @@ module phy_top #( output clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W), BUFR output output mclk, // same as clk_div, through separate BUFG and static phase adjust input rst_in, // reset delays/serdes - input ddr_rst, // active high - generate NRST to memory + input ddr_rst, // active high - generate NRST to memory + input dci_rst, // active high - reset DCI circuitry + input dly_rst, // active high - delay calibration circuitry + input [2*ADDRESS_NUMBER-1:0] in_a, // input address, 2 bits per signal (first, second) (29:0) for 4Gb device input [5:0] in_ba, // input bank address, 2 bits per signal (first, second) input [1:0] in_we, // input WE, 2 bits (first, second) @@ -108,7 +111,8 @@ module phy_top #( output [PHASE_WIDTH-1:0] ps_out ); reg rst=1'b0; - always @(posedge clk_div or posedge rst_in) begin +// always @(posedge clk_div or posedge rst_in) begin // got min hold violation + always @(negedge clk_div or posedge rst_in) begin if (rst_in) rst <= 1'b1; else rst <= 1'b0; end @@ -118,8 +122,8 @@ module phy_top #( wire ld_mmcm= (dly_addr[6:0] == 7'h60) && ld_delay ; wire clkfb_ref, clk_ref_pre; wire clk_ref; // 200MHz/300Mhz to calibrate I/O delays - wire locked_mmcm,locked_pll, dly_ready; - assign locked=locked_mmcm && locked_pll && dly_ready; // both PLL ready, I/O delay calibrated + wire locked_mmcm,locked_pll, dly_ready, dci_ready; + assign locked=locked_mmcm && locked_pll && dly_ready && dci_ready; // both PLL ready, I/O delay calibrated /* memory reset */ obuf #( @@ -345,15 +349,19 @@ BUFG mclk_i (.O(mclk),.I(mclk_pre) ); .clkfbout(clkfb_ref), // output .locked(locked_pll) // output ); -// Does it need to be re-calibrated periodically? -idelay_ctrl# ( - .IODELAY_GRP("IODELAY_MEMORY") -) idelay_ctrl_i ( - .refclk(clk_ref), - .rst(rst), - .rdy(dly_ready) -); +// Does it need to be re-calibrated periodically - yes when temperature changes, same as dci_reset + idelay_ctrl# ( + .IODELAY_GRP("IODELAY_MEMORY") + ) idelay_ctrl_i ( + .refclk(clk_ref), + .rst(rst || dly_rst), + .rdy(dly_ready) + ); + dci_reset dci_reset_i ( + .reset(rst || dci_rst), // input + .ready(dci_ready) // output + ); endmodule -- 2.18.1