Commit 01028931 authored by Andrey Filippov's avatar Andrey Filippov

bug fixes, implemented read pattern test, so all major DDR3 modes are tested:...

bug fixes, implemented read pattern test, so all major DDR3 modes are tested: write and read leveling, write and read
parent 46cf253d
......@@ -56,77 +56,77 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoBitstream-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoBitstream-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPhys-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPhys-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoRoute-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoRoute-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140531175605664.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140531222614445.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportImplemented-20140531180006073.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportImplemented-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140531175605664.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140531222614445.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportImplemented-20140531175841733.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportImplemented-20140531223145240.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140531175605664.log</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140531222614445.log</location>
</link>
<link>
<name>vivado_state/eddr3-opt-phys.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-opt-phys-20140531175841733.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-opt-phys-20140531223145240.dcp</location>
</link>
<link>
<name>vivado_state/eddr3-place.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140531175841733.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140531223145240.dcp</location>
</link>
<link>
<name>vivado_state/eddr3-route.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-route-20140531175841733.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-route-20140531223145240.dcp</location>
</link>
<link>
<name>vivado_state/eddr3-synth.dcp</name>
<type>1</type>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140531175605664.dcp</location>
<location>/data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140531222614445.dcp</location>
</link>
</linkedResources>
</projectDescription>
FPGA_project_0_SimulationTopFile=ddrc_test01_testbench.tf
FPGA_project_1_SimulationTopModule=ddrc_test01_testbench
FPGA_project_2_ImplementationTopFile=ddrc_test01.v
FPGA_project_4_part=xc7z030fbg484-2
FPGA_project_4_part=xc7z030fbg484-1
com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->FPGA_project_0_SimulationTopFile<-@\#\#@->FPGA_project_1_SimulationTopModule<-@\#\#@->
eclipse.preferences.version=1
......@@ -121,6 +121,7 @@ module axibram_read #(
reg start_read_burst_1;
reg [11:0] pre_rid0;
reg [11:0] pre_rid;
// External memory interface - synchronization with ready
assign pre_araddr= araddr_out[ADDRESS_BITS-1:0];
assign start_burst= start_read_burst_w;
......@@ -130,9 +131,8 @@ module axibram_read #(
assign bram_raddr = read_in_progress?read_address[ADDRESS_BITS-1:0]:{ADDRESS_BITS{1'b1}}; // read address
assign bram_ren = bram_reg_re_w; // read port enable
assign bram_regen = bram_reg_re_w; // output register enable
assign rdata[31:0] = bram_rdata; // data out
assign rdata[31:0] = bram_rdata; // data out
always @ (posedge aclk or posedge rst) begin
......
......@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
`define use200Mhz 1
module ddrc_test01 #(
parameter PHASE_WIDTH = 8,
parameter SLEW_DQ = "SLOW",
......@@ -27,12 +27,21 @@ module ddrc_test01 #(
parameter SLEW_CMDA = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter IBUF_LOW_PWR = "TRUE",
`ifdef use200Mhz
parameter real REFCLK_FREQUENCY = 200.0, // 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 20, // 10, //ns >1.25, 600<Fvco<1200 // Hardware 150MHz , change to | 6.667
parameter CLKFBOUT_MULT = 16, // 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 16
parameter CLKFBOUT_MULT_REF = 16, // 18, // 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 6
parameter CLKFBOUT_DIV_REF = 4, // 200Mhz 3, // To get 300MHz for the reference clock
`else
parameter real REFCLK_FREQUENCY = 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 10, //ns >1.25, 600<Fvco<1200
parameter CLKFBOUT_MULT = 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
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,
parameter CLKFBOUT_PHASE = 0.000,
parameter SDCLK_PHASE = 0.000,
......@@ -233,15 +242,23 @@ module ddrc_test01 #(
wire [ 3:0] dqs_tri_off_pattern;
wire [ 3:0] wbuf_delay;
wire port0_rd_match;
reg port0_rd_match_r; // rd address matched in previous cycle
assign port0_rd_match=(((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
// assign en_cmd0_wr= axiwr_bram_wen && (axiwr_bram_waddr[11:10]==2'h1);
// assign en_port0_rd= axird_bram_ren && (axird_bram_raddr[11:10]==2'h0);
// assign en_port0_regen= axird_bram_regen && (axird_bram_raddr[11:10]==2'h0);
// assign en_port1_wr= axiwr_bram_wen && (axiwr_bram_waddr[11:10]==2'h0);
assign en_cmd0_wr= axiwr_bram_wen && (((axiwr_bram_waddr ^ CMD0_ADDR) & CMD0_ADDR_MASK)==0);
assign en_port0_rd= axird_bram_ren && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
assign en_port0_regen= axird_bram_regen && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
// assign en_port0_rd= axird_bram_ren && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
// assign en_port0_regen= axird_bram_regen && (((axird_bram_raddr ^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
assign en_port0_rd= axird_bram_ren && port0_rd_match;
assign en_port0_regen= axird_bram_regen && port0_rd_match_r;
assign en_port1_wr= axiwr_bram_wen && (((axiwr_bram_waddr ^ PORT1_WR_ADDR) & PORT1_WR_ADDR_MASK)==0);
......@@ -249,11 +266,16 @@ module ddrc_test01 #(
assign axird_bram_rdata= select_port0? port0_rdata[31:0]:(select_status?status_rdata[31:0]:32'bx);
assign axird_dev_ready = ~axird_dev_busy; //may combine (AND) multiple sources if needed
always @ (posedge axi_aclk) begin
port0_rd_match_r <= port0_rd_match; // rd address matched in previous cycle
end
always @ (posedge axi_rst or posedge axi_aclk) begin
if (axi_rst) select_port0 <= 1'b0;
else if (axird_start_burst) select_port0 <= (((axird_pre_araddr^ PORT0_RD_ADDR) & PORT0_RD_ADDR_MASK)==0);
if (axi_rst) select_status <= 1'b0;
else if (axird_start_burst) select_status <= (((axird_pre_araddr^ STATUS_ADDR) & STATUS_ADDR_MASK)==0);
end
// Clock and reset from PS
......
[*]
[*] GTKWave Analyzer v3.3.49 (w)1999-2013 BSI
[*] Sat May 31 06:12:01 2014
[*] Sun Jun 1 23:19:02 2014
[*]
[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140531000432115.lxt"
[dumpfile_mtime] "Sat May 31 06:06:51 2014"
[dumpfile_size] 72003129
[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140601171040635.lxt"
[dumpfile_mtime] "Sun Jun 1 23:14:06 2014"
[dumpfile_size] 76198101
[savefile] "/data/vdt/vdt-projects/eddr3/ddrc_test01_testbench.sav"
[timestart] 119279350
[timestart] 116772900
[size] 1920 1180
[pos] -1920 108
*-14.213203 119337900 117826250 118403972 118403856 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[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
[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.
[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.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dqs_in_dly_i.
......@@ -27,6 +25,8 @@
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.dqs_in_dly_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dqs_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dqs_i.oserdes_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dqs_i.oserdes_i.oserdes_i.
......@@ -36,7 +36,7 @@
[treeopen] ddrc_test01_testbench.simul_axi_master_rdaddr_i.
[treeopen] ddrc_test01_testbench.simul_axi_master_wraddr_i.
[sst_width] 334
[signals_width] 305
[signals_width] 407
[sst_expanded] 1
[sst_vpaned_height] 820
@28
......@@ -1351,13 +1351,33 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.NDQSL[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.NDQSU[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDDML[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDDMU[0]
@22
@c00022
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
@28
(0)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(1)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(2)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(3)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(4)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(5)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(6)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(7)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(8)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(9)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(10)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(11)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(12)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(13)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(14)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
(15)ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDD[15:0]
@1401200
-group_end
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDODT[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDRST[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wdata[63:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_waddr_negedge[8:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wdata_negedge[63:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wr[0]
......@@ -1371,7 +1391,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]
@22
@23
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]
......@@ -1402,8 +1422,41 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.run_seq_d[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.sequence_done[0]
@200
-
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dout[31:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dout[31:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.add_pause[0]
@200
-
@c00200
-port0_buf_i
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.data_in[63:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.data_out[31:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.raddr[9:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.rclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.regen[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.ren[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.waddr[8:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.wclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.we[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.port0_buf_i.web[7:0]
@1401200
-port0_buf_i
@22
ddrc_test01_testbench.ddrc_test01_i.axird_bram_raddr[12:0]
@28
ddrc_test01_testbench.ddrc_test01_i.axird_bram_ren[0]
ddrc_test01_testbench.ddrc_test01_i.axird_bram_regen[0]
ddrc_test01_testbench.ddrc_test01_i.en_port0_rd[0]
ddrc_test01_testbench.ddrc_test01_i.en_port0_regen[0]
@200
-
@1000200
-ddr_sequencer_i_selected
@c00200
......@@ -1866,7 +1919,6 @@ ddrc_test01_testbench.SIMUL_AXI_READ[31:0]
ddrc_test01_testbench.SIMUL_AXI_ADDR[9:0]
@28
ddrc_test01_testbench.SIMUL_AXI_FULL[0]
@29
ddrc_test01_testbench.rstb[0]
@200
-
......@@ -2205,7 +2257,7 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_la
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.dqs_in_dly_i.idelay2_finedelay_i.qcntvalueout_reg[4:0]
@1401200
-dqs1_i
@c00200
@800200
-dq0_i
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.clk[0]
......@@ -2233,8 +2285,69 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_la
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dqs_in_dly_i.fdly[2:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dqs_in_dly_i.idelay2_finedelay_i.qcntvalueout_reg[4:0]
@1401200
@1000200
-dq0_i
@200
-
@800200
-dq8_i
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.clk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.clk_div[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.d_ser[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dci_disable[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.din[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dly_data[7:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dout[3:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dq[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dq_data_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dq_di[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dq_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.dq_tri[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.iclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.inv_clk_div[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.ld_idelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.ld_odelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.rst[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.set_idelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.set_odelay[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[0].dq_i.tin[3:0]
@1000200
-dq8_i
@800200
-dq9_i
@200
-
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.clk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.clk_div[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.d_ser[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dci_disable[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.din[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dly_data[7:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dout[3:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dq[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dq_data_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dq_di[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dq_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.dq_tri[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.iclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.inv_clk_div[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.ld_idelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.ld_odelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.rst[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.set_idelay[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.set_odelay[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dq_block[1].dq_i.tin[3:0]
@1000200
-dq9_i
@1401200
-byte_lane0_selected
@200
-
......
......@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
`define use200Mhz 1
module ddrc_test01_testbench #(
parameter PHASE_WIDTH = 8,
parameter SLEW_DQ = "SLOW",
......@@ -27,12 +27,21 @@ module ddrc_test01_testbench #(
parameter SLEW_CMDA = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter IBUF_LOW_PWR = "TRUE",
`ifdef use200Mhz
parameter real REFCLK_FREQUENCY = 200.0, // 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 20, // 10, //ns >1.25, 600<Fvco<1200 // Hardware 150MHz , change to | 6.667
parameter CLKFBOUT_MULT = 16, // 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 16
parameter CLKFBOUT_MULT_REF = 16, // 18, // 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 6
parameter CLKFBOUT_DIV_REF = 4, // 200Mhz 3, // To get 300MHz for the reference clock
`else
parameter real REFCLK_FREQUENCY = 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 10, //ns >1.25, 600<Fvco<1200 // Hardware 150MHz , change to | 6.667
parameter CLKFBOUT_MULT = 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 16
parameter CLKFBOUT_MULT_REF = 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 6
parameter CLKIN_PERIOD = 10, //ns >1.25, 600<Fvco<1200
parameter CLKFBOUT_MULT = 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
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 CLKFBOUT_PHASE = 0.000,
parameter SDCLK_PHASE = 0.000,
......@@ -134,11 +143,24 @@ module ddrc_test01_testbench #(
localparam STATUS_LOCKED_MASK = 'h200;
localparam STATUS_SEQ_BUSY_MASK = 'h400;
`ifdef use200Mhz
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h4c4c4b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h4c4c4b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
`else
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h5c5c5c5c5b5a59585454545453525150004c4c4c4b4a49484444444443424140; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
`endif
localparam DLY_PHASE= 8'h1c; // mmcm fine phase shift, 1/4 tCK
localparam DQSTRI_FIRST= 4'h3; // DQS tri-state control word, first when enabling output
......@@ -146,10 +168,12 @@ module ddrc_test01_testbench #(
localparam DQTRI_FIRST= 4'h7; // DQ tri-state control word, first when enabling output
localparam DQTRI_LAST= 4'he; // DQ tri-state control word, first after disabling output
localparam WBUF_DLY_DFLT= 4'h6; // extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
localparam WBUF_DLY_WLV= 4'h7; // write leveling mode: extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
// localparam DLY_PHASE= 8'hdb; // mmcm fine phase shift
localparam WRITELEV_OFFSET='h20; // write leveling start address (in words)
localparam WRITE_BLOCK_OFFSET='h100; // write block sequence start address (in words) ..'h14c
localparam WRITELEV_OFFSET= 'h20; // write leveling start address (in words)
localparam READ_PATTERN_OFFSET='h40; // read pattern to memory block sequence start address (in words) ..'h053 with 8x2*64 bits (variable)
localparam WRITE_BLOCK_OFFSET= 'h100; // write block sequence start address (in words) ..'h14c
localparam READ_BLOCK_OFFSET= 'h180; // read block sequence start address (in words)
......@@ -325,13 +349,11 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
enable_cke(1);
repeat (16) @(posedge CLK) ;
set_mrs(1);
set_write_lev(16); // write leveling, 16 times
set_write_lev(16); // write leveling, 16 times (full buffer - 128)
// set dq /dqs tristate on/off patterns
axi_write_single(BASEADDR_PATTERNS_TRI, {16'h0, DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
// set write buffer (from DDR3) WE signal delay
axi_write_single(BASEADDR_WBUF_DELAY, {28'h0, WBUF_DLY_DFLT});
#100;
......@@ -340,19 +362,67 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
wait_sequencer_ready(16);
axi_write_single(BASEADDR_PATTERNS, 32'h0055); // set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
// Set special values for DQS idelay for write leveling
axi_set_dqs_idelay_wlv;
// Set write buffer (from DDR3) WE signal delay for write leveling mode
axi_write_single(BASEADDR_WBUF_DELAY, {28'h0, WBUF_DLY_WLV});
//axi_set_dqs_idelay_nominal;
run_sequence(0,WRITELEV_OFFSET);
wait_sequencer_ready(16);
`ifdef use200Mhz
axi_set_dly_single(0,8,'h78); // was 'h74 dqs lane 0, odelay
axi_set_dly_single(2,8,'h80); // was 'h74 dqs lane 1, odelay
`else
axi_set_dly_single(0,8,'h80); // was 'h74 dqs lane 0, odelay
axi_set_dly_single(2,8,'hc0); // was 'h74 dqs lane 1, odelay
`endif
run_sequence(0,WRITELEV_OFFSET);
`ifdef use200Mhz
#120; // 140 ns delay 30; // 30 ns delay
axi_set_dly_single(2,8,'h78); // was 'h74 dqs lane 1, odelay
#10
axi_set_dly_single(0,8,'h80); // was 'h74 dqs lane 0, odelay
`else
#140; // 140 ns delay 30; // 30 ns delay
axi_set_dly_single(2,8,'hb8); // was 'h74 dqs lane 1, odelay
#20
axi_set_dly_single(0,8,'hc0); // was 'h74 dqs lane 0, odelay
`endif
wait_sequencer_ready(16);
// read writelev data over AXI (odd/even have byte1/byte0 - each byte different sample)
wait (~rstb);
SIMUL_AXI_FULL<=1'b0;
read_block_buf(32); // 32 x32 words (32 is twice 16 specified in set_write_lev(16))
wait (~rvalid && rready && (rid==LAST_ARID)); // nothing left in read queue?
SIMUL_AXI_FULL<=1'b0;
// restore normal dqs idelay (after write leveling)
axi_set_dqs_idelay_nominal;
// restore normal write buffer (from DDR3) WE signal delay
axi_write_single(BASEADDR_WBUF_DELAY, {28'h0, WBUF_DLY_DFLT});
// test reading pattern
set_read_pattern(8); // 8x2*64 bits, 32x32 bits to read
run_sequence(0,READ_PATTERN_OFFSET);
// TODO: add timing variation during read
wait_sequencer_ready(16);
// read pattern data over AXI
wait (~rstb);
SIMUL_AXI_FULL<=1'b0;
read_block_buf(32); // 32 x32 words (32 is twice 16 specified in set_write_lev(16))
wait (~rvalid && rready && (rid==LAST_ARID)); // nothing left in read queue?
SIMUL_AXI_FULL<=1'b0;
// test write block;
write_block_buf; // fill block memory
set_write_block(
......@@ -369,16 +439,17 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
15'h1234, // row address
10'h100 // column address
);
run_sequence(0,READ_BLOCK_OFFSET);
// add read block over AXI
// read block over AXI
wait_sequencer_ready(16);
wait (~rstb);
SIMUL_AXI_FULL<=1'b0;
read_block_buf;
read_block_buf(256); // 256 x32 words
wait (~rvalid && rready && (rid==LAST_ARID)); // nothing left in read queue?
SIMUL_AXI_FULL<=1'b0;
#100;
$display("finish testbench 0");
$finish;
......@@ -394,7 +465,7 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
// protect from never end
initial begin
// #10000000;
#150000;
#200000;
$display("finish testbench 2");
$finish;
end
......@@ -911,6 +982,7 @@ simul_axi_read simul_axi_read_i(
task write_block_buf;
integer i,j;
begin
$display ("**** write_block_buf @%t",$time);
for (i=0;i<256;i=i+16) begin
axi_write_addr_data(
i, // id
......@@ -922,6 +994,7 @@ simul_axi_read simul_axi_read_i(
4'hf, // wstrb
1'b0 // last
);
$display ("+Write block data (addr:data): 0x%x:0x%x @%t",i,i | (((i + 7) & 'hff) << 8) | (((i + 23) & 'hff) << 16) | (((i + 31) & 'hff) << 24),$time);
for (j=1;j<16;j=j+1) begin
axi_write_data(
i, // id
......@@ -929,6 +1002,8 @@ simul_axi_read simul_axi_read_i(
4'hf, // wstrb
(1==15)?1:0 // last
);
$display (" Write block data (addr:data): 0x%x:0x%x @%t",(i+j),
(i+j) | ((((i+j) + 7) & 'hff) << 8) | ((((i+j) + 23) & 'hff) << 16) | ((((i+j) + 31) & 'hff) << 24),$time);
end
end
......@@ -937,11 +1012,12 @@ simul_axi_read simul_axi_read_i(
// read memory
task read_block_buf;
input integer num_read; // number of words to read (will be rounded up to multiple of 16)
integer i; //,j;
begin
$display ("**** read_block_buf @%t",$time);
axi_set_rd_lag(0);
for (i=0;i<256;i=i+16) begin
for (i=0;i<num_read;i=i+16) begin
wait(arready);
// $display ("read_block_buf (0x%x) @%t",i,$time);
axi_read_addr(
......@@ -955,6 +1031,212 @@ simul_axi_read simul_axi_read_i(
endtask
// Set MR3, read nrep*8 words, save to buffer (port0). No ACTIVATE/PRECHARGE are needed/allowed
task set_read_pattern;
input integer nrep;
// input [ 2:0] ba;
// input [14:0] ra;
// input [ 9:0] ca;
reg [31:0] cmd_addr;
reg [31:0] data;
reg [17:0] mr3_norm;
reg [17:0] mr3_pattern;
integer i;
begin
cmd_addr <= BASEADDR_CMD0 + (READ_PATTERN_OFFSET << 2);
mr3_norm <= ddr3_mr3 (
1'h0, // mpr; // MPR mode: 0 - normal, 1 - dataflow from MPR
2'h0); // [1:0] mpr_rf; // MPR read function: 2'b00: predefined pattern 0101...
mr3_pattern <= ddr3_mr3 (
1'h1, // mpr; // MPR mode: 0 - normal, 1 - dataflow from MPR
2'h0); // [1:0] mpr_rf; // MPR read function: 2'b00: predefined pattern 0101...
// Set pattern mode
@(posedge CLK)
data <= encode_seq_word(
mr3_pattern[14:0], // [14:0] phy_addr_in;
mr3_pattern[17:15], // [ 2:0] phy_bank_in; //TODO: debug!
3'b111, // [ 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 == 0; // first/second half-cycle,
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'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
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// first read
// read
data <= {
15'h0, //{5'b0,ca[9:0]},
3'h0, //ba[2:0], //phy_bank_in[2:0],
3'b010, // 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_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)
1'b0, // phy_dqs_toggle_en;
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, // 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
1'b0 // Reserved for future use
};
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// nop
data <= {
15'b0, // skip 0
3'h0, //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_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)
1'b0, // phy_dqs_toggle_en;
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, // 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
1'b0 // Reserved for future use
};
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
//repeat remaining reads
for (i=1;i<nrep;i=i+1) begin
// read
data <= {
15'h0, //{5'b0,ca[9:0]},
3'h0, //ba[2:0], //phy_bank_in[2:0],
3'b010, // 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_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)
1'b0, // phy_dqs_toggle_en;
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'b1, // add NOP after the current command, keep other data
1'b0 // Reserved for future use
};
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
end
// nop
data <= {
15'b0, // skip 0
3'h0, //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_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)
1'b0, // phy_dqs_toggle_en;
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
1'b0 // Reserved for future use
};
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// nop
data <= {
15'b0, // skip 0
3'h0, //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_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)
1'b0, // phy_dqs_toggle_en;
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
1'b0 // Reserved for future use
};
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// nop
data <= {
15'b0, // skip 0
3'h0, //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_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)
1'b0, // phy_dqs_toggle_en;
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
1'b0 // Reserved for future use
};
@(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)
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// Turn off read pattern mode
@(posedge CLK)
data <= encode_seq_word(
mr3_norm[14:0], // [14:0] phy_addr_in;
mr3_norm[17:15], // [ 2:0] phy_bank_in; //TODO: debug!
3'b111, // [ 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 == 0; // first/second half-cycle,
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'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
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
data <= encode_seq_skip(0,1); // end of sequence
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
end
endtask
task set_read_block;
input [ 2:0] ba;
......@@ -1365,8 +1647,10 @@ simul_axi_read simul_axi_read_i(
reg [31:0] cmd_addr;
reg [31:0] data;
reg [CMD_PAUSE_BITS-1:0] dqs_low_rpt;
reg [CMD_PAUSE_BITS-1:0] nrep_minus_1;
begin
dqs_low_rpt <= 8;
nrep_minus_1 <= nrep-1;
mr1_norm <= ddr3_mr1 (
1'h0, // qoff; // output enable: 0 - DQ, DQS operate in normal mode, 1 - DQ, DQS are disabled
1'h0, // tdqs; // termination data strobe (for x8 devices) 0 - disabled, 1 - enabled
......@@ -1433,10 +1717,10 @@ simul_axi_read simul_axi_read_i(
// axi_write_single(cmd_addr, data);
// cmd_addr <= cmd_addr + 4;
// Toggle DQS as needed for write leveling
// Toggle DQS as needed for write leveling, write to buffer
data <= { // encode_seq_skip(nrep,0); // Adjust skip
{15-CMD_DONE_BIT{1'b0}},
nrep[CMD_PAUSE_BITS-1:0],
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?
......@@ -1446,7 +1730,7 @@ simul_axi_read simul_axi_read_i(
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'b0, // phy_buf_wr, // connect to external buffer (but only if not paused)
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
1'b0 // Reserved for future use
......@@ -1454,6 +1738,28 @@ simul_axi_read simul_axi_read_i(
@(posedge CLK)
axi_write_single(cmd_addr, data);
cmd_addr <= cmd_addr + 4;
// continue toggling, but disable writing to buffer (used same wbuf latency as for read)
data <= { // encode_seq_skip(nrep,0); // Adjust skip
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'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'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
1'b0 // Reserved for future use
};
@(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);
......@@ -1900,6 +2206,23 @@ simul_axi_read simul_axi_read_i(
end
endtask
task axi_set_dqs_idelay_nominal;
begin
axi_write_single(BASEADDRESS_LANE0_IDELAY + (8<<2), (DLY_LANE0_IDELAY >> (8<<3)) & 32'hff);
axi_write_single(BASEADDRESS_LANE1_IDELAY + (8<<2), (DLY_LANE1_IDELAY >> (8<<3)) & 32'hff);
axi_write_single(BASEADDR_DLY_SET, 0); // set all dealys
end
endtask
task axi_set_dqs_idelay_wlv;
begin
axi_write_single(BASEADDRESS_LANE0_IDELAY + (8<<2), DLY_LANE0_DQS_WLV_IDELAY);
axi_write_single(BASEADDRESS_LANE1_IDELAY + (8<<2), DLY_LANE1_DQS_WLV_IDELAY);
axi_write_single(BASEADDR_DLY_SET, 0); // set all dealys
end
endtask
task axi_set_dly_single;
input [2:0] group; // 0 - lane 0 odelay, 1 - lane0 idelay, 2 - lane 1 odelay, 3 - lane1 idelay, 4 - cmda odelay
input [4:0] index; // 0..7 - DQ, 8 - DQS, 9 DQM (for byte lanes)
......@@ -2125,10 +2448,7 @@ simul_axi_read simul_axi_read_i(
end
endtask
task axi_read_addr;`ifndef IVERILOG
(* dont_touch = "true" *)
`endif
task axi_read_addr;
input [11:0] id;
input [31:0] addr;
input [ 3:0] len;
......
......@@ -18,9 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/> .
#################################################################################
#create_clock -period 2.500 -name clk -waveform {0.000 1.250} [get_ports CLK]
#axi_aclk [get_pins -hierarchical *pll*CLKIN1]
create_clock -name axi_aclk -period 10 [get_nets -hierarchical *axi_aclk]
create_clock -name axi_aclk -period 20 [get_nets -hierarchical *axi_aclk]
#Clock Period Waveform Attributes Sources
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment