├── .editor_defines ├── .gitignore ├── .gitlab-ci.yml ├── .project ├── .pydevproject ├── .settings ├── com.elphel.vdt.FPGA_project.prefs ├── com.elphel.vdt.ISExst.prefs ├── com.elphel.vdt.VivadoBitstream.prefs ├── com.elphel.vdt.VivadoPlace.prefs ├── com.elphel.vdt.VivadoSynthesis.prefs ├── com.elphel.vdt.VivadoTimimgSummaryReportSynthesis.prefs ├── com.elphel.vdt.VivadoTimingReportSynthesis.prefs ├── com.elphel.vdt.iverilog.prefs └── com.elphel.vdt.prefs ├── OSERDESE1.diff ├── README.md ├── axi ├── axibram.v ├── axibram_read.v ├── axibram_write.v └── macros393.v ├── ddr3 ├── 1024Mb_ddr3_parameters.vh ├── 2048Mb_ddr3_parameters.vh ├── 4096Mb_ddr3_parameters.vh ├── ddr3.v └── readme.txt ├── ddr_refresh.v ├── ddrc_control.v ├── ddrc_status.v ├── ddrc_test01.v ├── ddrc_test01.xcf ├── ddrc_test01.xdc ├── ddrc_test01_testbench.sav ├── ddrc_test01_testbench.tf ├── ddrc_test01_timing.xdc ├── glbl.v ├── hardware_tests └── eddr3_eye02.ods ├── phy ├── byte_lane.v ├── cmd_addr.v ├── cmda_single.v ├── ddrc_sequencer.v ├── dm_single.v ├── dq_single.v ├── dqs_single.v ├── dqs_single_nofine.v ├── phy_cmd.v ├── phy_top.v ├── test_dqs.v ├── test_dqs01.v ├── test_dqs01_placement.xdc ├── test_dqs02.v ├── test_dqs02_placement.xdc ├── test_dqs03.v ├── test_dqs03_placement.xdc ├── test_dqs04.v ├── test_dqs04_placement.xdc ├── test_dqs05.v ├── test_dqs05_placement.xdc ├── test_dqs06.v ├── test_dqs06_placement.xdc ├── test_dqs07.v ├── test_dqs07_placement.xdc └── test_phy_top_01.xdc ├── python ├── ddrtests.py ├── exp_gpio.py ├── mem.py ├── memdump.py └── mon_gpio.py ├── simulation_modules ├── simul_axi_fifo_out.v ├── simul_axi_master_rdaddr.v ├── simul_axi_master_wdata.v ├── simul_axi_master_wraddr.v ├── simul_axi_read.v ├── simul_axi_slow_ready.v └── simul_fifo.v ├── unisims_patches └── OSERDESE1.diff ├── util_modules ├── dly01_16.v ├── fifo_cross_clocks.v └── fifo_same_clock.v └── wrap ├── dci_reset.v ├── idelay_ctrl.v ├── idelay_fine_pipe.v ├── idelay_nofine.v ├── iserdes_mem.v ├── mmcm_adv.v ├── mmcm_phase_cntr.v ├── obuf.v ├── oddr.v ├── oddr_ds.v ├── odelay_fine_pipe.v ├── odelay_pipe.v ├── oserdes_mem.v ├── pll_base.v ├── ram_1kx32_1kx32.v ├── ram_1kx32w_512x64r.v └── ram_512x64w_1kx32r.v /.editor_defines: -------------------------------------------------------------------------------- 1 | // This file may be used to define same pre-processor macros to be included into each parsed file 2 | // It can be used to check different `ifdef branches 3 | //`define XIL_TIMING //Simprim 4 | `define IVERILOG -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | unisims 2 | vivado_* 3 | syntax_* 4 | simulation/* 5 | ise_* 6 | attic/* 7 | IVERILOG_INCLUDE.v 8 | eddr3.prj -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | compile_test: 2 | tags: 3 | - latex3 4 | image: tianon/latex 5 | variables: 6 | CI_DEBUG_TRACE: "false" 7 | script: 8 | - echo $CI_JOB_ID 9 | - echo "test" > artifact.txt 10 | artifacts: 11 | paths: 12 | - artifact.txt 13 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | eddr3 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | com.elphel.vdt.veditor.simulateBuilder 15 | 16 | 17 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.CleanCommand 18 | echo 'Clean' 19 | 20 | 21 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.buildOrder 22 | 0 23 | 24 | 25 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.command 26 | echo 'No Build Configuration Specified' 27 | 28 | 29 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.enable 30 | true 31 | 32 | 33 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.name 34 | Default 35 | 36 | 37 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.parser 38 | 39 | 40 | 41 | com.elphel.vdt.veditor.simulateBuilder.00000000Default.workFolder 42 | 43 | 44 | 45 | 46 | 47 | 48 | com.elphel.vdt.veditor.HdlNature 49 | org.python.pydev.pythonNature 50 | 51 | 52 | 53 | ise_logs/ISExst.log 54 | 1 55 | /data/vdt/vdt-projects/eddr3/ise_logs/ISExst-20140607155721361.log 56 | 57 | 58 | ise_state/eddr3-synth.tgz 59 | 1 60 | /data/vdt/vdt-projects/eddr3/ise_state/eddr3-synth-20140607155721361.tgz 61 | 62 | 63 | vivado_logs/VivadoBitstream.log 64 | 1 65 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoBitstream-20140611174132808.log 66 | 67 | 68 | vivado_logs/VivadoOpt.log 69 | 1 70 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOpt-20140611174132808.log 71 | 72 | 73 | vivado_logs/VivadoOptPhys.log 74 | 1 75 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPhys-20140611174132808.log 76 | 77 | 78 | vivado_logs/VivadoOptPower.log 79 | 1 80 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoOptPower-20140611174132808.log 81 | 82 | 83 | vivado_logs/VivadoPlace.log 84 | 1 85 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoPlace-20140611174132808.log 86 | 87 | 88 | vivado_logs/VivadoRoute.log 89 | 1 90 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoRoute-20140611174132808.log 91 | 92 | 93 | vivado_logs/VivadoSynthesis.log 94 | 1 95 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoSynthesis-20140611174056482.log 96 | 97 | 98 | vivado_logs/VivadoTimimgSummaryReportImplemented.log 99 | 1 100 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportImplemented-20140611174132808.log 101 | 102 | 103 | vivado_logs/VivadoTimimgSummaryReportSynthesis.log 104 | 1 105 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimimgSummaryReportSynthesis-20140611174132808.log 106 | 107 | 108 | vivado_logs/VivadoTimingReportImplemented.log 109 | 1 110 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportImplemented-20140611174132808.log 111 | 112 | 113 | vivado_logs/VivadoTimingReportSynthesis.log 114 | 1 115 | /data/vdt/vdt-projects/eddr3/vivado_logs/VivadoTimingReportSynthesis-20140611174132808.log 116 | 117 | 118 | vivado_state/eddr3-opt-phys.dcp 119 | 1 120 | /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-opt-phys-20140611174132808.dcp 121 | 122 | 123 | vivado_state/eddr3-place.dcp 124 | 1 125 | /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-place-20140611174132808.dcp 126 | 127 | 128 | vivado_state/eddr3-route.dcp 129 | 1 130 | /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-route-20140611174132808.dcp 131 | 132 | 133 | vivado_state/eddr3-synth.dcp 134 | 1 135 | /data/vdt/vdt-projects/eddr3/vivado_state/eddr3-synth-20140610113942407.dcp 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | Default 4 | python 2.7 5 | 6 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.FPGA_project.prefs: -------------------------------------------------------------------------------- 1 | FPGA_project_0_SimulationTopFile=ddrc_test01_testbench.tf 2 | FPGA_project_1_SimulationTopModule=ddrc_test01_testbench 3 | FPGA_project_2_ImplementationTopFile=ddrc_test01.v 4 | FPGA_project_4_part=xc7z030fbg484-1 5 | com.elphel.store.context.FPGA_project=FPGA_project_2_ImplementationTopFile<-@\#\#@->FPGA_project_4_part<-@\#\#@->FPGA_project_0_SimulationTopFile<-@\#\#@->FPGA_project_1_SimulationTopModule<-@\#\#@-> 6 | eclipse.preferences.version=1 7 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.ISExst.prefs: -------------------------------------------------------------------------------- 1 | ISExst_170_constraints=ddrc_test01.xcf 2 | com.elphel.store.context.ISExst=ISExst_170_constraints<-@\#\#@-> 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.VivadoBitstream.prefs: -------------------------------------------------------------------------------- 1 | VivadoBitstream_103_PreBitstreamTCL=set_property BITSTREAM.STARTUP.MATCH_CYCLE NoWait [current_design]<-@\#\#@-> 2 | VivadoBitstream_105_force=true 3 | com.elphel.store.context.VivadoBitstream=VivadoBitstream_105_force<-@\#\#@->VivadoBitstream_103_PreBitstreamTCL<-@\#\#@-> 4 | eclipse.preferences.version=1 5 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.VivadoPlace.prefs: -------------------------------------------------------------------------------- 1 | VivadoPlace_111_verbose_place=true 2 | com.elphel.store.context.VivadoPlace=VivadoPlace_111_verbose_place<-@\#\#@-> 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.VivadoSynthesis.prefs: -------------------------------------------------------------------------------- 1 | VivadoSynthesis_102_ConstraintsFiles=ddrc_test01.xdc<-@\#\#@->ddrc_test01_timing.xdc<-@\#\#@-> 2 | VivadoSynthesis_115_flatten_hierarchy=none 3 | VivadoSynthesis_95_ShowInfo=false 4 | com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->VivadoSynthesis_95_ShowInfo<-@\#\#@->VivadoSynthesis_115_flatten_hierarchy<-@\#\#@-> 5 | eclipse.preferences.version=1 6 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.VivadoTimimgSummaryReportSynthesis.prefs: -------------------------------------------------------------------------------- 1 | VivadoTimimgSummaryReportSynthesis_102_DisableVivadoTimingSummary=true 2 | com.elphel.store.context.VivadoTimimgSummaryReportSynthesis=VivadoTimimgSummaryReportSynthesis_102_DisableVivadoTimingSummary<-@\#\#@-> 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.VivadoTimingReportSynthesis.prefs: -------------------------------------------------------------------------------- 1 | VivadoTimingReportSynthesis_102_DisableVivadoTiming=true 2 | com.elphel.store.context.VivadoTimingReportSynthesis=VivadoTimingReportSynthesis_102_DisableVivadoTiming<-@\#\#@-> 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.iverilog.prefs: -------------------------------------------------------------------------------- 1 | com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->iverilog_84_IncludeDir<-@\#\#@-> 2 | eclipse.preferences.version=1 3 | iverilog_77_Param_Exe=/usr/local/bin/iverilog 4 | iverilog_78_VVP_Exe=/usr/local/bin/vvp 5 | iverilog_81_TopModulesOther=glbl<-@\#\#@-> 6 | iverilog_83_ExtraFiles=glbl.v<-@\#\#@-> 7 | iverilog_84_IncludeDir=/data/vdt/vdt-projects/eddr3/ddr3<-@\#\#@-> 8 | iverilog_88_ShowNoProblem=true 9 | iverilog_99_GrepFindErrWarn=error|warning|sorry 10 | -------------------------------------------------------------------------------- /.settings/com.elphel.vdt.prefs: -------------------------------------------------------------------------------- 1 | com.elphel.store.context.=com.elphel.vdt.PROJECT_DESING_MENU<-@\#\#@-> 2 | com.elphel.vdt.PROJECT_DESING_MENU=MainDesignMenu 3 | eclipse.preferences.version=1 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | eddr3 2 | ===== 3 | 4 | ddr3 subproject for Elphel 393 camera 5 | 6 | This subproject is started to create a DDR3 memory controller for Elphel camera that does not depend on any non-documented 7 | features of Xilinx Zynq and can be simulated by Free Software tools (Icarus Verilog + GTKWave) without use of any encrypted 8 | modules. Everything in plain Verilog and constraints. 9 | 10 | Detailed description of the project is available in the blog post: http://blog.elphel.com/2014/06/ddr3-memory-interface-on-xilinx-zynq-soc-free-software-compatible/ 11 | -------------------------------------------------------------------------------- /axi/macros393.v: -------------------------------------------------------------------------------- 1 | /* 2 | ** -----------------------------------------------------------------------------** 3 | ** macros353.v 4 | ** 5 | ** temporary, modules to be moved 6 | ** 7 | ** Copyright (C) 2002 Elphel, Inc 8 | ** 9 | ** -----------------------------------------------------------------------------** 10 | ** This file is part of X353 11 | ** X353 is free software - hardware description language (HDL) code. 12 | ** 13 | ** This program is free software: you can redistribute it and/or modify 14 | ** it under the terms of the GNU General Public License as published by 15 | ** the Free Software Foundation, either version 3 of the License, or 16 | ** (at your option) any later version. 17 | ** 18 | ** This program is distributed in the hope that it will be useful, 19 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | ** GNU General Public License for more details. 22 | ** 23 | ** You should have received a copy of the GNU General Public License 24 | ** along with this program. If not, see . 25 | ** -----------------------------------------------------------------------------** 26 | ** 27 | */ 28 | 29 | 30 | module ram_WxD 31 | #( 32 | parameter integer DATA_WIDTH=16, 33 | parameter integer DATA_DEPTH=4, 34 | parameter integer DATA_2DEPTH=(1< . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module ddr_refresh( 24 | input rst, 25 | input clk, 26 | input [7:0] refresh_period, // in 16*clk 27 | input set, // and reset counters 28 | output want, // turns off next cycle after grant (or stays on if more are needed) 29 | output need, 30 | input grant // 1 cycle 31 | ); 32 | reg [3:0] pre_div; 33 | reg [4:0] pending_rq; // can accumulate up to 31 requests, datasheet allows up to 16 34 | reg [7:0] period_cntr; 35 | reg cry; 36 | wire over=(period_cntr == 0) && cry; 37 | reg refresh_due; 38 | assign want = pending_rq != 0; 39 | assign need = pending_rq[4:3] != 0; 40 | always @ (posedge rst or posedge clk) begin 41 | if (rst) pre_div <= 0; 42 | else if (set) pre_div <= 0; 43 | else pre_div <= pre_div +1; 44 | 45 | if (rst) cry <= 0; 46 | else if (set) cry <= 0; 47 | else cry <= (pre_div == 4'hf); 48 | 49 | if (rst) period_cntr <= 0; 50 | else if (set) period_cntr <= 0; 51 | else if (over) period_cntr <= refresh_period; 52 | else if (cry) period_cntr <= period_cntr -1; 53 | 54 | if (rst) refresh_due <= 0; 55 | else refresh_due <= over; 56 | 57 | if (rst) pending_rq <= 0; 58 | else if (set) pending_rq <= 0; 59 | else if ( refresh_due && !grant) pending_rq <= pending_rq+1; 60 | else if (!refresh_due && grant) pending_rq <= pending_rq-1; 61 | end 62 | endmodule 63 | 64 | -------------------------------------------------------------------------------- /ddrc_status.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: ddrc_status 3 | * Date:2014-05-19 4 | * Author: Andrey Filippov 5 | * Description: Read status/radback information from the DDR controller 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * ddrc_status.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * ddrc_status.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module ddrc_status 24 | //#( 25 | // parameter AXI_RD_ADDR_BITS= 12 26 | // parameter SELECT_ADDR = 'h800, // address to select this module 27 | // parameter SELECT_ADDR_MASK = 'h800, // address mask to select this module 28 | // parameter BUSY_ADDR = 'hc00, // address to generate busy 29 | // parameter BUSY_ADDR_MASK = 'hc00 // address mask to generate busy 30 | //) 31 | ( 32 | // input clk, 33 | // input mclk, 34 | // input rst, 35 | // input [AXI_RD_ADDR_BITS-1:0] pre_raddr, // AXI reade address, before actual reads (to generate busy), valid@start_burst 36 | // input start_rburst, // burst start - should generate ~ready (should be AND-ed with !busy internally) 37 | // input [AXI_RD_ADDR_BITS-1:0] raddr, // read address, valid with rd_en 38 | // input rd_en, // read enable 39 | output [31:0] rdata, // read data, should valid with raddr and rd_en 40 | output busy, // interface busy (combinatorial delay from start_wburst and pre_addr 41 | // status/readback signals 42 | // input run_done, // sequencer done (add busy?) 43 | input run_busy, // sequencer busy 44 | input locked, // MMCM and PLL locked 45 | input locked_mmcm, 46 | input locked_pll, 47 | input dly_ready, 48 | input dci_ready, 49 | input ps_rdy, // MMCM phase shift control ready 50 | input [ 7:0] ps_out // MMCM phase shift value (in 1/56 of the Fvco period) 51 | ); 52 | assign busy=0; 53 | assign rdata={17'b0,dly_ready,dci_ready, locked_mmcm, locked_pll, run_busy,locked,ps_rdy,ps_out[7:0]}; 54 | 55 | 56 | endmodule 57 | 58 | -------------------------------------------------------------------------------- /ddrc_test01_timing.xdc: -------------------------------------------------------------------------------- 1 | ################################################################################# 2 | # Filename: ddrc_test01_timing.xdc 3 | # Date:2014-05-20 4 | # Author: Andrey Filippov 5 | # Description: DDR3 controller test with axi constraints 6 | # 7 | # Copyright (c) 2014 Elphel, Inc. 8 | # ddrc_test01_timing.xdc is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # ddrc_test01_timing.xdc is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | ################################################################################# 21 | 22 | create_clock -name axi_aclk -period 20 [get_nets -hierarchical *axi_aclk] 23 | 24 | 25 | #Clock Period Waveform Attributes Sources 26 | #axi_aclk 10.00000 {0.00000 5.00000} P {bufg_axi_aclk_i/O} 27 | #clk_fb 10.00000 {0.00000 5.00000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/MMCME2_ADV_i/CLKFBOUT} 28 | #sdclk_pre 2.50000 {0.00000 1.25000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/MMCME2_ADV_i/CLKOUT0} 29 | #clk_pre 2.50000 {0.00000 1.25000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/MMCME2_ADV_i/CLKOUT1} 30 | #clk_div_pre 5.00000 {0.00000 2.50000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/MMCME2_ADV_i/CLKOUT2} 31 | #mclk_pre 5.00000 {1.25000 3.75000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/MMCME2_ADV_i/CLKOUT3} 32 | #clkfb_ref 10.00000 {0.00000 5.00000} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/pll_base_i/PLLE2_BASE_i/CLKFBOUT} 33 | #clk_ref_pre 3.33333 {0.00000 1.66667} P,G {ddrc_sequencer_i/phy_cmd_i/phy_top_i/pll_base_i/PLLE2_BASE_i/CLKOUT0} 34 | 35 | #Each list contains 2 elements - warning later in DRC 36 | #create_generated_clock -name ddr3_sdclk [get_nets -hierarchical sdclk_pre] 37 | #create_generated_clock -name ddr3_clk [get_nets -hierarchical clk_pre] 38 | #create_generated_clock -name ddr3_clk_div [get_nets -hierarchical clk_div_pre] 39 | #create_generated_clock -name ddr3_mclk [get_nets -hierarchical mclk_pre] 40 | #create_generated_clock -name ddr3_clk_ref [get_nets -hierarchical clk_ref_pre] 41 | 42 | #Not available initially 43 | #create_generated_clock -name ddr3_sdclk [get_nets ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/sdclk_pre] 44 | #create_generated_clock -name ddr3_clk [get_netsddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/clk_pre] 45 | #create_generated_clock -name ddr3_clk_div [get_nets ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/clk_div_pre] 46 | #create_generated_clock -name ddr3_mclk [get_nets ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/mclk_pre] 47 | #create_generated_clock -name ddr3_clk_ref [get_nets ddrc_sequencer_i/phy_cmd_i/phy_top_i/pll_base_i/clk_ref_pre] 48 | 49 | # try use first from list - seems that 2 are created from the same name 50 | # ddrc_sequencer_i/phy_cmd_i/phy_top_i/sdclk_pre 51 | # ddrc_sequencer_i/phy_cmd_i/phy_top_i/mmcm_phase_cntr_i/sdclk_pre 52 | # lindex is not supported in xdc 53 | #create_generated_clock -name ddr3_sdclk [lindex [get_nets -hierarchical sdclk_pre] 0 ] 54 | #create_generated_clock -name ddr3_clk [lindex [get_nets -hierarchical clk_pre] 0 ] 55 | #create_generated_clock -name ddr3_clk_div [lindex [get_nets -hierarchical clk_div_pre] 0 ] 56 | #create_generated_clock -name ddr3_mclk [lindex [get_nets -hierarchical mclk_pre] 0 ] 57 | #create_generated_clock -name ddr3_clk_ref [lindex [get_nets -hierarchical clk_ref_pre] 0 ] 58 | 59 | ##create_generated_clock -name ddr3_sdclk [get_nets -hierarchical sdclk_pre -filter {NAME !~ */mmcm_phase_cntr_i*} ] 60 | ##create_generated_clock -name ddr3_clk [get_nets -hierarchical clk_pre -filter {NAME !~ */mmcm_phase_cntr_i*} ] 61 | ##create_generated_clock -name ddr3_clk_div [get_nets -hierarchical clk_div_pre -filter {NAME !~ */mmcm_phase_cntr_i*} ] 62 | ##create_generated_clock -name ddr3_mclk [get_nets -hierarchical mclk_pre -filter {NAME !~ */mmcm_phase_cntr_i*} ] 63 | ##create_generated_clock -name ddr3_clk_ref [get_nets -hierarchical clk_ref_pre -filter {NAME !~ */pll_base_i*} ] 64 | 65 | create_generated_clock -name ddr3_sdclk [get_nets */sdclk_pre ] 66 | create_generated_clock -name ddr3_clk [get_nets */clk_pre ] 67 | create_generated_clock -name ddr3_clk_div [get_nets */clk_div_pre ] 68 | create_generated_clock -name ddr3_mclk [get_nets */mclk_pre ] 69 | create_generated_clock -name ddr3_clk_ref [get_nets */clk_ref_pre] 70 | 71 | #create_generated_clock -name ddr3_sdclk [get_nets -hierarchical *sdclk_pre ] 72 | #create_generated_clock -name ddr3_clk [get_nets -hierarchical *clk_pre ] 73 | #create_generated_clock -name ddr3_clk_div [get_nets -hierarchical *clk_div_pre ] 74 | #create_generated_clock -name ddr3_mclk [get_nets -hierarchical *mclk_pre ] 75 | #create_generated_clock -name ddr3_clk_ref [get_nets -hierarchical *clk_ref_pre ] 76 | 77 | 78 | 79 | # do not check timing between axi_aclk and other clocks. Code should provide correct asynchronous crossing of the clock boundary. 80 | set_clock_groups -name ps_async_clock -asynchronous -group {axi_aclk} 81 | -------------------------------------------------------------------------------- /glbl.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | module glbl (); 3 | parameter ROC_WIDTH = 100000; 4 | parameter TOC_WIDTH = 0; 5 | 6 | //SuppressWarnings VEditor - this value is used in other modules through global reference 7 | wire GSR; 8 | //SuppressWarnings VEditor - this value is used in other modules through global reference 9 | wire GTS; 10 | //SuppressWarnings VEditor - this value is used in other modules through global reference 11 | wire PRLD; 12 | //SuppressWarnings VEditor - this value is used in other modules through global reference 13 | wire PLL_LOCKG; 14 | 15 | reg GSR_int; 16 | reg GTS_int; 17 | reg PRLD_int; 18 | 19 | assign (weak1, weak0) GSR = GSR_int; 20 | assign (weak1, weak0) GTS = GTS_int; 21 | assign (weak1, weak0) PRLD = PRLD_int; 22 | 23 | initial begin 24 | GSR_int = 1'b1; 25 | PRLD_int = 1'b1; 26 | #(ROC_WIDTH) 27 | GSR_int = 1'b0; 28 | PRLD_int = 1'b0; 29 | end 30 | 31 | initial begin 32 | GTS_int = 1'b1; 33 | #(TOC_WIDTH) 34 | GTS_int = 1'b0; 35 | end 36 | endmodule 37 | -------------------------------------------------------------------------------- /hardware_tests/eddr3_eye02.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Elphel/eddr3/444ce3df65fd1564d57aa52e835e69af2a579247/hardware_tests/eddr3_eye02.ods -------------------------------------------------------------------------------- /phy/byte_lane.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: byte_lane 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: DDR3 byte lane, including DQS I/O, 8xDQ I/O and DM output 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * byte_lane.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * byte_lane.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | // minimizing total DQS in delay to match DQ (finedelay stage adds some?) 23 | //`define NOFINEDELAY_DQS 1 24 | module byte_lane #( 25 | parameter IODELAY_GRP ="IODELAY_MEMORY", 26 | parameter IBUF_LOW_PWR ="TRUE", 27 | parameter IOSTANDARD_DQ = "SSTL15_T_DCI", 28 | parameter IOSTANDARD_DQS = "DIFF_SSTL15_T_DCI", 29 | parameter SLEW_DQ = "SLOW", 30 | parameter SLEW_DQS = "SLOW", 31 | parameter real REFCLK_FREQUENCY = 300.0, 32 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 33 | )( 34 | inout [7:0] dq, // DQ I/O pads 35 | // inout dm, // DM I/O pad (actually only output) 36 | output dm, // DM I/O pad (actually only output) 37 | inout dqs, // DQS I/O pad 38 | inout ndqs, // ~DQS I/O pad 39 | input clk, // free-running system clock, same frequency as iclk (shared for R/W) 40 | input clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W) 41 | input inv_clk_div, // invert clk_div for R channels (clk_div is shared between R and W) 42 | input rst, 43 | input dci_disable_dqs, // disable DCI termination during writes and idle for dqs 44 | input dci_disable_dq, // disable DCI termination during writes and idle for dq and dm signals 45 | input [31:0] din, // parallel data to be sent out (4 bits per DG I/)) 46 | input [3:0] din_dm, // parallel data to be sent out over DM 47 | input [3:0] tin_dq, // tristate for data out (sent out earlier than data!) and dm 48 | input [3:0] din_dqs, // parallel data to be sent out over DQS 49 | input [3:0] tin_dqs, // tristate for DQS out (sent out earlier than data!) 50 | output [31:0] dout, // parallel data received from DDR3 memory, 4 bits per DQ I/O 51 | input [7:0] dly_data, // delay value (3 LSB - fine delay) 52 | input [4:0] dly_addr, // select which delay to program 53 | input ld_delay, // load delay data to selected iodelay (clk_div synchronous) 54 | input set // clk_div synchronous set all delays from previously loaded values 55 | ); 56 | 57 | //(* CLOCK_DEDICATED_ROUTE = "FALSE" *) // does not seem to work 58 | wire dqs_read; 59 | wire iclk; // source-synchronous clock (BUFR from DQS) 60 | reg [31:0] din_r=0; 61 | // Preventing register removal of equivalent registers 62 | (* keep = "true" *) reg [3:0] din_dm_r=0, din_dqs_r=0, tin_dq_r=4'hf, tin_dqs_r=4'hf; 63 | (* keep = "true" *) reg [7:0] dly_data_r=0; 64 | (* keep = "true" *) reg set_r=0; 65 | (* keep = "true" *) reg dci_disable_dqs_r, dci_disable_dq_r; 66 | reg [7:0] ld_odly=8'b0, ld_idly=8'b0; 67 | reg ld_odly_dqs,ld_idly_dqs,ld_odly_dm; 68 | BUFR iclk_i (.O(iclk),.I(dqs_read), .CLR(1'b0),.CE(1'b1)); // OK, works with constraint? Seems now work w/o 69 | wire [9:0] decode_sel={ 70 | (dly_addr[3:0]==9)?1'b1:1'b0, 71 | (dly_addr[3:0]==8)?1'b1:1'b0, 72 | (dly_addr[3:0]==7)?1'b1:1'b0, 73 | (dly_addr[3:0]==6)?1'b1:1'b0, 74 | (dly_addr[3:0]==5)?1'b1:1'b0, 75 | (dly_addr[3:0]==4)?1'b1:1'b0, 76 | (dly_addr[3:0]==3)?1'b1:1'b0, 77 | (dly_addr[3:0]==2)?1'b1:1'b0, 78 | (dly_addr[3:0]==1)?1'b1:1'b0, 79 | (dly_addr[3:0]==0)?1'b1:1'b0}; 80 | 81 | always @ (posedge clk_div or posedge rst) begin 82 | if (rst) begin 83 | din_r <= 32'b0; din_dm_r<=0; din_dqs_r<=0; tin_dq_r<=4'hf; tin_dqs_r<=4'hf; 84 | dly_data_r<=8'b0;set_r<=1'b0; 85 | dci_disable_dqs_r <= 1'b1; dci_disable_dq_r <=1'b1; 86 | ld_odly<=8'b0; ld_idly<=8'b0; ld_odly_dqs<=1'b0; ld_idly_dqs<=1'b0; ld_odly_dm<=1'b0; 87 | end else begin 88 | din_r<=din[31:0]; din_dm_r<=din_dm; din_dqs_r<=din_dqs; tin_dq_r<=tin_dq; tin_dqs_r<=tin_dqs; 89 | dly_data_r<=dly_data; set_r<=set; 90 | dci_disable_dqs_r <= dci_disable_dqs; dci_disable_dq_r <= dci_disable_dq; 91 | {ld_odly_dm,ld_odly_dqs,ld_odly[7:0]} <= {10{(~dly_addr[4]) & ld_delay}} & decode_sel; 92 | { ld_idly_dqs,ld_idly[7:0]} <= {9 {( dly_addr[4]) & ld_delay}} & decode_sel[8:0]; 93 | end 94 | end 95 | 96 | generate 97 | genvar i; 98 | for (i=0; i < 8; i=i+1) begin: dq_block 99 | dq_single #( 100 | .IODELAY_GRP(IODELAY_GRP), 101 | .IBUF_LOW_PWR(IBUF_LOW_PWR), 102 | .IOSTANDARD(IOSTANDARD_DQ), 103 | .SLEW(SLEW_DQ), 104 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 105 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 106 | ) dq_i( 107 | .dq(dq[i]), // I/O pad 108 | .iclk(iclk), // source-synchronous clock (BUFR from DQS) 109 | .clk(clk), // free-running system clock, same frequency as iclk (shared for R/W) 110 | .clk_div(clk_div), // free-running half clk frequency, front aligned to clk (shared for R/W) 111 | .inv_clk_div(inv_clk_div), // invert clk_div for R channel (clk_div is shared between R and W) 112 | .rst(rst), 113 | .dci_disable(dci_disable_dq_r), // disable DCI termination during writes and idle 114 | .dly_data(dly_data_r), // delay value (3 LSB - fine delay) 115 | .din({din_r[i+24],din_r[i+16],din_r[i+8],din_r[i]}) , // parallel data to be sent out 116 | // .din(din_r[4*i+3:4*i]) , // parallel data to be sent out 117 | // .din(din_r[4*i+3-:4]) , // parallel data to be sent out 118 | .tin(tin_dq_r), // tristate for data out (sent out earlier than data!) 119 | .dout({dout[i+24],dout[i+16],dout[i+8],dout[i]}), // parallel data received from DDR3 memory 120 | // .dout(dout[4*i+3:4*i]), // parallel data received from DDR3 memory 121 | .set_odelay(set_r), // clk_div synchronous load odelay value from dly_data 122 | .ld_odelay(ld_odly[i]), // clk_div synchronous set odealy value from loaded 123 | .set_idelay(set_r), // clk_div synchronous load idelay value from dly_data 124 | .ld_idelay(ld_idly[i]) // clk_div synchronous set idealy value from loaded 125 | ); 126 | end 127 | endgenerate 128 | 129 | dm_single #( 130 | .IODELAY_GRP(IODELAY_GRP), 131 | .IBUF_LOW_PWR(IBUF_LOW_PWR), 132 | .IOSTANDARD(IOSTANDARD_DQ), 133 | .SLEW(SLEW_DQ), 134 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 135 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 136 | ) dm_i( 137 | .dm(dm), // DM output pad 138 | .clk(clk), // free-running system clock, same frequency as iclk (shared for R/W) 139 | .clk_div(clk_div), // free-running half clk frequency, front aligned to clk (shared for R/W) 140 | .rst(rst), 141 | .dci_disable(dci_disable_dq_r), // disable DCI termination during writes and idle 142 | .dly_data(dly_data_r), // delay value (3 LSB - fine delay) 143 | .din(din_dm_r[3:0]) , // parallel data to be sent out 144 | .tin(tin_dq_r), // tristate for data out (sent out earlier than data!) 145 | .set_odelay(set_r), // clk_div synchronous load odelay value from dly_data 146 | .ld_odelay(ld_odly_dm) // clk_div synchronous set odealy value from loaded 147 | ); 148 | 149 | `ifdef NOFINEDELAY_DQS 150 | dqs_single_nofine #( 151 | `else 152 | dqs_single #( 153 | `endif 154 | .IODELAY_GRP(IODELAY_GRP), 155 | .IBUF_LOW_PWR(IBUF_LOW_PWR), 156 | .IOSTANDARD(IOSTANDARD_DQS), 157 | .SLEW(SLEW_DQS), 158 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 159 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 160 | ) dqs_i ( 161 | .dqs(dqs), 162 | .ndqs(ndqs), 163 | .clk(clk), 164 | .clk_div(clk_div), 165 | .rst(rst), 166 | .dqs_received_dly(dqs_read), 167 | .dci_disable(dci_disable_dqs_r), // disable DCI termination during writes and idle 168 | .dly_data(dly_data_r[7:0]), 169 | .din(din_dqs_r[3:0]), 170 | .tin(tin_dqs_r[3:0]), 171 | .set_odelay(set_r), 172 | .ld_odelay(ld_odly_dqs), 173 | .set_idelay(set_r), 174 | .ld_idelay(ld_idly_dqs) 175 | ); 176 | endmodule 177 | 178 | -------------------------------------------------------------------------------- /phy/cmda_single.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: cmda_single 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Single-bit CMD/address output 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * cmda_single.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * cmda_single.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module cmda_single #( 24 | parameter IODELAY_GRP ="IODELAY_MEMORY", 25 | parameter integer ODELAY_VALUE = 0, 26 | parameter IOSTANDARD = "SSTL15", 27 | parameter SLEW = "SLOW", 28 | parameter real REFCLK_FREQUENCY = 300.0, 29 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 30 | )( 31 | output dq, // I/O pad (appears on the output 1/2 clk_div earlier, than DDR data) 32 | input clk, // free-running system clock, same frequency as iclk (shared for R/W) 33 | input clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W) 34 | input rst, 35 | input [7:0] dly_data, // delay value (3 LSB - fine delay) 36 | input [1:0] din, // parallel data to be sent out 37 | // input [1:0] tin, // tristate for data out (sent out earlier than data!) 38 | input tin, // tristate for data out (sent out earlier than data!) 39 | input set_delay, // clk_div synchronous load odelay value from dly_data 40 | input ld_delay // clk_div synchronous set odealy value from loaded 41 | ); 42 | wire d_ser; 43 | wire dq_tri; 44 | wire dq_data_dly; 45 | 46 | oserdes_mem#( 47 | .MODE_DDR("FALSE") 48 | ) oserdes_i ( 49 | .clk(clk), // serial output clock 50 | .clk_div(clk_div), // oclk divided by 2, front aligned 51 | .rst(rst), // reset 52 | .din(din[1:0]), // parallel data in 53 | // .tin(tin[1:0]), // parallel tri-state in 54 | .tin(tin), // parallel tri-state in 55 | .dout_dly(d_ser), // data out to be connected to odelay input 56 | .dout_iob(), // data out to be connected directly to the output buffer 57 | .tout_dly(), // tristate out to be connected to odelay input 58 | .tout_iob(dq_tri) // tristate out to be connected directly to the tristate control of the output buffer 59 | ); 60 | odelay_fine_pipe # ( 61 | .IODELAY_GRP(IODELAY_GRP), 62 | .DELAY_VALUE(ODELAY_VALUE), 63 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 64 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 65 | ) dqs_out_dly_i( 66 | .clk(clk_div), 67 | .rst(rst), 68 | .set(set_delay), 69 | .ld(ld_delay), 70 | .delay(dly_data[7:0]), 71 | .data_in(d_ser), 72 | .data_out(dq_data_dly) 73 | ); 74 | 75 | OBUFT #( 76 | .IOSTANDARD(IOSTANDARD), 77 | .SLEW(SLEW) 78 | ) iobufs_dqs_i ( 79 | .O(dq), 80 | .I(dq_data_dly), 81 | .T(dq_tri)); 82 | 83 | endmodule 84 | 85 | -------------------------------------------------------------------------------- /phy/dm_single.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: dm_single 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Single-bit DDR3 DQ I/O, same used for DM 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * dm_single.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * dm_single.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | // ISE 14.7 does not have OBUFT_DCIEN 23 | `define USE_IOBUF 1 24 | module dm_single #( 25 | parameter IODELAY_GRP ="IODELAY_MEMORY", 26 | // parameter integer IDELAY_VALUE = 0, 27 | parameter integer ODELAY_VALUE = 0, 28 | parameter IBUF_LOW_PWR ="TRUE", //SuppressThisWarning VEditor not used in OBUF_DCIEN 29 | parameter IOSTANDARD = "SSTL15_T_DCI", 30 | parameter SLEW = "SLOW", 31 | parameter real REFCLK_FREQUENCY = 300.0, 32 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 33 | )( 34 | output dm, // I/O pad 35 | input clk, // free-running system clock, same frequency as iclk (shared for R/W) 36 | input clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W) 37 | input rst, 38 | input dci_disable, // disable DCI termination during writes and idle 39 | input [7:0] dly_data, // delay value (3 LSB - fine delay) 40 | input [3:0] din, // parallel data to be sent out 41 | input [3:0] tin, // tristate for data out (sent out earlier than data!) 42 | input set_odelay, // clk_div synchronous load odelay value from dly_data 43 | input ld_odelay // clk_div synchronous set odealy value from loaded 44 | ); 45 | wire d_ser; 46 | wire dq_tri; 47 | wire dq_data_dly; 48 | oserdes_mem#( 49 | .MODE_DDR("TRUE") 50 | ) oserdes_i ( 51 | .clk(clk), // serial output clock 52 | .clk_div(clk_div), // oclk divided by 2, front aligned 53 | .rst(rst), // reset 54 | .din(din[3:0]), // parallel data in 55 | .tin(tin[3:0]), // parallel tri-state in 56 | .dout_dly(d_ser), // data out to be connected to odelay input 57 | .dout_iob(), // data out to be connected directly to the output buffer 58 | .tout_dly(), // tristate out to be connected to odelay input 59 | .tout_iob(dq_tri) // tristate out to be connected directly to the tristate control of the output buffer 60 | ); 61 | odelay_fine_pipe # ( 62 | .IODELAY_GRP(IODELAY_GRP), 63 | .DELAY_VALUE(ODELAY_VALUE), 64 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 65 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 66 | ) dm_out_dly_i( 67 | .clk(clk_div), 68 | .rst(rst), 69 | .set(set_odelay), 70 | .ld(ld_odelay), 71 | .delay(dly_data[7:0]), 72 | .data_in(d_ser), 73 | .data_out(dq_data_dly) 74 | ); 75 | `ifdef USE_IOBUF 76 | IOBUF_DCIEN #( 77 | .IBUF_LOW_PWR(IBUF_LOW_PWR), // 78 | .IOSTANDARD(IOSTANDARD), 79 | .SLEW(SLEW), 80 | .USE_IBUFDISABLE("FALSE") 81 | // SuppressWarnings VivadoSynthesis : VivadoSynthesis: [Synth 8-4446] all outputs are unconnected for this instance and logic may be removed 82 | ) iobufs_dm_i ( 83 | // .O(dq_di), 84 | .O(), 85 | .IO(dm), 86 | .DCITERMDISABLE(dci_disable), 87 | .IBUFDISABLE(1'b0), 88 | .I(dq_data_dly), //dqs_data), 89 | .T(dq_tri)); 90 | `else 91 | /* Instance template for module OBUFT_DCIEN */ 92 | OBUFT_DCIEN #( 93 | .IOSTANDARD(IOSTANDARD), 94 | .SLEW(SLEW) 95 | ) iobufs_dm_i ( 96 | .O(dm), // output 97 | .DCITERMDISABLE(dci_disable), // input 98 | .I(dq_data_dly), // input 99 | .T(dq_tri) // input 100 | ); 101 | `endif 102 | 103 | endmodule 104 | 105 | -------------------------------------------------------------------------------- /phy/dq_single.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: dq_single 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Single-bit DDR3 DQ I/O, same used for DM 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * dq_single.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * dq_single.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module dq_single #( 24 | parameter IODELAY_GRP ="IODELAY_MEMORY", 25 | parameter integer IDELAY_VALUE = 0, 26 | parameter integer ODELAY_VALUE = 0, 27 | parameter IBUF_LOW_PWR ="TRUE", 28 | parameter IOSTANDARD = "SSTL15_T_DCI", 29 | parameter SLEW = "SLOW", 30 | parameter real REFCLK_FREQUENCY = 300.0, 31 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 32 | )( 33 | inout dq, // I/O pad 34 | input iclk, // source-synchronous clock (BUFR from DQS) 35 | input clk, // free-running system clock, same frequency as iclk (shared for R/W) 36 | input clk_div, // free-running half clk frequency, front aligned to clk (shared for R/W) 37 | input inv_clk_div, // invert clk_div for R channel (clk_div is shared between R and W) 38 | input rst, 39 | input dci_disable, // disable DCI termination during writes and idle 40 | input [7:0] dly_data, // delay value (3 LSB - fine delay) 41 | input [3:0] din, // parallel data to be sent out 42 | input [3:0] tin, // tristate for data out (sent out earlier than data!) 43 | output [3:0] dout, // parallel data received from DDR3 memory 44 | input set_odelay, // clk_div synchronous load odelay value from dly_data 45 | input ld_odelay, // clk_div synchronous set odealy value from loaded 46 | input set_idelay, // clk_div synchronous load idelay value from dly_data 47 | input ld_idelay // clk_div synchronous set idealy value from loaded 48 | ); 49 | wire d_ser; 50 | wire dq_tri; 51 | wire dq_data_dly; 52 | wire dq_dly; 53 | // keep IOBUF_DCIEN.O to user as output only (UDM/LDM), so the rest of tyhe read channel will be optimized out, but I/O will stay the same 54 | //(* keep = "true" *) 55 | wire dq_di; 56 | 57 | 58 | oserdes_mem#( 59 | .MODE_DDR("TRUE") 60 | ) oserdes_i ( 61 | .clk(clk), // serial output clock 62 | .clk_div(clk_div), // oclk divided by 2, front aligned 63 | .rst(rst), // reset 64 | .din(din[3:0]), // parallel data in 65 | .tin(tin[3:0]), // parallel tri-state in 66 | .dout_dly(d_ser), // data out to be connected to odelay input 67 | .dout_iob(), // data out to be connected directly to the output buffer 68 | .tout_dly(), // tristate out to be connected to odelay input 69 | .tout_iob(dq_tri) // tristate out to be connected directly to the tristate control of the output buffer 70 | ); 71 | odelay_fine_pipe # ( 72 | .IODELAY_GRP(IODELAY_GRP), 73 | .DELAY_VALUE(ODELAY_VALUE), 74 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 75 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 76 | ) dq_out_dly_i( 77 | .clk(clk_div), 78 | .rst(rst), 79 | .set(set_odelay), 80 | .ld(ld_odelay), 81 | .delay(dly_data[7:0]), 82 | .data_in(d_ser), 83 | .data_out(dq_data_dly) 84 | ); 85 | 86 | IOBUF_DCIEN #( 87 | .IBUF_LOW_PWR(IBUF_LOW_PWR), // 88 | .IOSTANDARD(IOSTANDARD), 89 | .SLEW(SLEW), 90 | .USE_IBUFDISABLE("FALSE") 91 | ) iobufs_dq_i ( 92 | .O(dq_di), 93 | .IO(dq), 94 | .DCITERMDISABLE(dci_disable), 95 | .IBUFDISABLE(1'b0), 96 | .I(dq_data_dly), //dqs_data), 97 | .T(dq_tri)); 98 | 99 | idelay_fine_pipe # ( 100 | .IODELAY_GRP(IODELAY_GRP), 101 | .DELAY_VALUE(IDELAY_VALUE), 102 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 103 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 104 | ) dq_in_dly_i( 105 | .clk(clk_div), 106 | .rst(rst), 107 | .set(set_idelay), 108 | .ld(ld_idelay), 109 | .delay(dly_data[7:0]), 110 | .data_in(dq_di), 111 | .data_out(dq_dly) 112 | ); 113 | 114 | iserdes_mem #( 115 | .DYN_CLKDIV_INV_EN("FALSE") 116 | ) iserdes_mem_i ( 117 | .iclk(iclk), // source-synchronous clock 118 | .oclk(clk), // system clock, phase should allow iclk-to-oclk jitter with setup/hold margin 119 | .oclk_div(clk_div), // oclk divided by 2, front aligned 120 | .inv_clk_div(inv_clk_div), // invert oclk_div (this clock is shared between iserdes and oserdes. Works only in MEMORY_DDR3 mode? 121 | .rst(rst), // reset 122 | .d_direct(1'b0), // direct input from IOB, normally not used, controlled by IOBDELAY parameter (set to "NONE") 123 | .ddly(dq_dly), // serial input from idelay 124 | .dout(dout[3:0]) // parallel data out 125 | ); 126 | 127 | endmodule 128 | 129 | -------------------------------------------------------------------------------- /phy/dqs_single.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: dqs_single 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Single-bit DDR3 DQS I/O 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * dqs_single.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * dqs_single.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | module dqs_single #( 23 | parameter IODELAY_GRP ="IODELAY_MEMORY", 24 | parameter integer IDELAY_VALUE = 0, 25 | parameter integer ODELAY_VALUE = 0, 26 | parameter IBUF_LOW_PWR ="TRUE", 27 | parameter IOSTANDARD = "DIFF_SSTL15_T_DCI", 28 | parameter SLEW = "SLOW", 29 | parameter real REFCLK_FREQUENCY = 300.0, 30 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 31 | )( 32 | inout dqs, 33 | inout ndqs, 34 | input clk, 35 | input clk_div, 36 | input rst, 37 | output dqs_received_dly, 38 | // output dqs_di, // debugging: 39 | //Input buffer ddrc_sequencer_i/phy_cmd_i/phy_top_i/byte_lane0_i/dqs_i/iobufs_dqs_i/IBUFDS/IBUFDS_S (in ddrc_sequencer_i/phy_cmd_i/phy_top_i/byte_lane0_i/dqs_i/iobufs_dqs_i macro) has no loads. An input buffer must drive an internal load. 40 | 41 | input dci_disable, // disable DCI termination during writes and idle 42 | input [7:0] dly_data, 43 | input [3:0] din, 44 | input [3:0] tin, 45 | input set_odelay, 46 | input ld_odelay, 47 | input set_idelay, 48 | input ld_idelay 49 | ); 50 | wire d_ser; 51 | wire dqs_tri; 52 | wire dqs_data_dly; 53 | wire dqs_di; 54 | 55 | 56 | oserdes_mem oserdes_i ( 57 | .clk(clk), // serial output clock 58 | .clk_div(clk_div), // oclk divided by 2, front aligned 59 | .rst(rst), // reset 60 | .din(din[3:0]), // parallel data in 61 | .tin(tin[3:0]), // parallel tri-state in 62 | .dout_dly(d_ser), // data out to be connected to odelay input 63 | .dout_iob(), // data out to be connected directly to the output buffer 64 | .tout_dly(), // tristate out to be connected to odelay input 65 | .tout_iob(dqs_tri) // tristate out to be connected directly to the tristate control of the output buffer 66 | ); 67 | odelay_fine_pipe # ( 68 | .IODELAY_GRP(IODELAY_GRP), 69 | .DELAY_VALUE(ODELAY_VALUE), 70 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 71 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 72 | ) dqs_out_dly_i( 73 | .clk(clk_div), 74 | .rst(rst), 75 | .set(set_odelay), 76 | .ld(ld_odelay), 77 | .delay(dly_data[7:0]), 78 | .data_in(d_ser), 79 | .data_out(dqs_data_dly) 80 | ); 81 | 82 | IOBUFDS_DCIEN #( 83 | .DIFF_TERM("FALSE"), 84 | .DQS_BIAS("TRUE"), // outputs 1'b0 when IOB is floating 85 | .IBUF_LOW_PWR(IBUF_LOW_PWR), // 86 | .IOSTANDARD(IOSTANDARD), 87 | .SLEW(SLEW), 88 | .USE_IBUFDISABLE("FALSE") 89 | ) iobufs_dqs_i ( 90 | .O(dqs_di), 91 | .IO(dqs), 92 | .IOB(ndqs), 93 | .DCITERMDISABLE(dci_disable), 94 | .IBUFDISABLE(1'b0), 95 | .I(dqs_data_dly), //dqs_data), 96 | .T(dqs_tri)); 97 | idelay_fine_pipe # ( 98 | .IODELAY_GRP(IODELAY_GRP), 99 | .DELAY_VALUE(IDELAY_VALUE), 100 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 101 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 102 | ) dqs_in_dly_i( 103 | .clk(clk_div), 104 | .rst(rst), 105 | .set(set_idelay), 106 | .ld(ld_idelay), 107 | .delay(dly_data[7:0]), 108 | .data_in(dqs_di), 109 | .data_out(dqs_received_dly) 110 | ); 111 | endmodule 112 | 113 | -------------------------------------------------------------------------------- /phy/dqs_single_nofine.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: dqs_single_nofine 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Single-bit DDR3 DQS I/O 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * dqs_single_nofine.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * dqs_single_nofine.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | module dqs_single_nofine #( 23 | parameter IODELAY_GRP ="IODELAY_MEMORY", 24 | parameter integer IDELAY_VALUE = 0, // same scale as for fine delay 25 | parameter integer ODELAY_VALUE = 0, 26 | parameter IBUF_LOW_PWR ="TRUE", 27 | parameter IOSTANDARD = "DIFF_SSTL15_T_DCI", 28 | parameter SLEW = "SLOW", 29 | parameter real REFCLK_FREQUENCY = 300.0, 30 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 31 | 32 | )( 33 | inout dqs, 34 | inout ndqs, 35 | input clk, 36 | input clk_div, 37 | input rst, 38 | output dqs_received_dly, 39 | // output dqs_di, // debugging: 40 | //Input buffer ddrc_sequencer_i/phy_cmd_i/phy_top_i/byte_lane0_i/dqs_i/iobufs_dqs_i/IBUFDS/IBUFDS_S (in ddrc_sequencer_i/phy_cmd_i/phy_top_i/byte_lane0_i/dqs_i/iobufs_dqs_i macro) has no loads. An input buffer must drive an internal load. 41 | 42 | input dci_disable, // disable DCI termination during writes and idle 43 | input [7:0] dly_data, 44 | input [3:0] din, 45 | input [3:0] tin, 46 | input set_odelay, 47 | input ld_odelay, 48 | input set_idelay, 49 | input ld_idelay 50 | ); 51 | wire d_ser; 52 | wire dqs_tri; 53 | wire dqs_data_dly; 54 | wire dqs_di; 55 | 56 | 57 | oserdes_mem oserdes_i ( 58 | .clk(clk), // serial output clock 59 | .clk_div(clk_div), // oclk divided by 2, front aligned 60 | .rst(rst), // reset 61 | .din(din[3:0]), // parallel data in 62 | .tin(tin[3:0]), // parallel tri-state in 63 | .dout_dly(d_ser), // data out to be connected to odelay input 64 | .dout_iob(), // data out to be connected directly to the output buffer 65 | .tout_dly(), // tristate out to be connected to odelay input 66 | .tout_iob(dqs_tri) // tristate out to be connected directly to the tristate control of the output buffer 67 | ); 68 | odelay_fine_pipe # ( 69 | .IODELAY_GRP(IODELAY_GRP), 70 | .DELAY_VALUE(ODELAY_VALUE), 71 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 72 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 73 | ) dqs_out_dly_i( 74 | .clk(clk_div), 75 | .rst(rst), 76 | .set(set_odelay), 77 | .ld(ld_odelay), 78 | .delay(dly_data[7:0]), 79 | .data_in(d_ser), 80 | .data_out(dqs_data_dly) 81 | ); 82 | 83 | IOBUFDS_DCIEN #( 84 | .DIFF_TERM("FALSE"), 85 | .DQS_BIAS("TRUE"), // outputs 1'b0 when IOB is floating 86 | .IBUF_LOW_PWR(IBUF_LOW_PWR), // 87 | .IOSTANDARD(IOSTANDARD), 88 | .SLEW(SLEW), 89 | .USE_IBUFDISABLE("FALSE") 90 | ) iobufs_dqs_i ( 91 | .O(dqs_di), 92 | .IO(dqs), 93 | .IOB(ndqs), 94 | .DCITERMDISABLE(dci_disable), 95 | .IBUFDISABLE(1'b0), 96 | .I(dqs_data_dly), //dqs_data), 97 | .T(dqs_tri)); 98 | idelay_nofine # ( 99 | .IODELAY_GRP(IODELAY_GRP), 100 | .DELAY_VALUE(IDELAY_VALUE>>3), 101 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 102 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE) 103 | ) dqs_in_dly_i( 104 | .clk(clk_div), 105 | .rst(rst), 106 | .set(set_idelay), 107 | .ld(ld_idelay), 108 | .delay(dly_data[7:3]), 109 | .data_in(dqs_di), 110 | .data_out(dqs_received_dly) 111 | ); 112 | endmodule 113 | 114 | -------------------------------------------------------------------------------- /phy/test_dqs.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs( 24 | input rst, // reset 25 | input refclk, // 200MHz/300MHz for delay calibration 26 | input clk_in, 27 | input set, 28 | input ld_dly_data, 29 | input ld_dly_tri, 30 | input [7:0] dly_data, 31 | input [3:0] data_in, 32 | input [3:0] tri_in, 33 | inout dqs, 34 | inout ndqs, 35 | output dqs_received, 36 | output dly_ready, 37 | // input dqs_tri_a, 38 | output dqs_tri 39 | 40 | ); 41 | wire refclk_b=refclk; // use buffer 42 | wire clk, clk_div; 43 | //wire dqs_data,dqs_tri; // after odelay 44 | wire dqs_data; // after odelay 45 | wire pre_dqs_data,pre_dqs_tri; // before odelay 46 | 47 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 48 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 49 | 50 | oserdes_mem oserdes_dqs_i( 51 | .clk(clk), // serial output clock 52 | .clk_div(clk_div), // oclk divided by 2, front aligned 53 | .rst(rst), // reset 54 | .din(data_in), // parallel data in 55 | .tin(tri_in), // parallel tri-state in 56 | .dout_dly(), // data out to be connected to odelay input 57 | .dout_iob(pre_dqs_data), // data out to be connected directly to the output buffer 58 | .tout_dly(), // tristate out to be connected to odelay input 59 | .tout_iob(pre_dqs_tri) // tristate out to be connected directly to the tristate control of the output buffer 60 | ); 61 | 62 | idelay_ctrl# ( 63 | .IODELAY_GRP("IODELAY_MEMORY") 64 | ) idelay_ctrl_i ( 65 | .refclk(refclk_b), 66 | .rst(rst), 67 | .rdy(dly_ready) 68 | ); 69 | 70 | odelay_fine_pipe # ( 71 | .IODELAY_GRP("IODELAY_MEMORY"), 72 | .DELAY_VALUE(0), 73 | .REFCLK_FREQUENCY(300.0), 74 | .HIGH_PERFORMANCE_MODE("FALSE") 75 | ) dqs_data_dly_i( 76 | .clk(clk_div), 77 | .rst(rst), 78 | .set(set), 79 | .ld(ld_dly_data), 80 | .delay(dly_data), 81 | .data_in(pre_dqs_data), 82 | .data_out(dqs_data) 83 | ); 84 | 85 | odelay_fine_pipe # ( 86 | .IODELAY_GRP("IODELAY_MEMORY"), 87 | .DELAY_VALUE(0), 88 | .REFCLK_FREQUENCY(300.0), 89 | .HIGH_PERFORMANCE_MODE("FALSE") 90 | ) dqs_tri_dly_i( 91 | .clk(clk_div), 92 | .rst(rst), 93 | .set(set), 94 | .ld(ld_dly_tri), 95 | .delay(dly_data), 96 | .data_in(pre_dqs_tri), 97 | .data_out(dqs_tri) 98 | ); 99 | //wire dqs_tri_a; 100 | //(* keep = "true" *) BUF buf0_i(.O(dqs_tri_a), .I(dqs_tri)); 101 | 102 | IOBUFDS #( 103 | .DQS_BIAS("FALSE"), 104 | .IBUF_LOW_PWR("TRUE"), 105 | .IOSTANDARD("DEFAULT"), 106 | .SLEW("SLOW") 107 | ) iobufs_dqs_i ( 108 | .O(dqs_received), 109 | .IO(dqs), 110 | .IOB(ndqs), 111 | .I(dqs_data), 112 | // .T(dqs_tri_a)); 113 | .T(1'b0)); 114 | 115 | endmodule 116 | 117 | -------------------------------------------------------------------------------- /phy/test_dqs01.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs01 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs01.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs01.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs01( 24 | input [1:0] dqs_data, 25 | inout [1:0] dqs, 26 | inout [1:0] ndqs, 27 | output [1:0] dqs_received, 28 | input [1:0] dqs_tri 29 | 30 | ); 31 | 32 | 33 | 34 | IOBUFDS #( 35 | .DQS_BIAS("FALSE"), 36 | .IBUF_LOW_PWR("TRUE"), 37 | .IOSTANDARD("DEFAULT"), 38 | .SLEW("SLOW") 39 | ) iobufs_dqs_i0 ( 40 | .O(dqs_received[0]), 41 | .IO(dqs[0]), 42 | .IOB(ndqs[0]), 43 | .I(dqs_data[0]), 44 | .T(dqs_tri[0])); 45 | 46 | IOBUFDS #( 47 | .DQS_BIAS("FALSE"), 48 | .IBUF_LOW_PWR("TRUE"), 49 | .IOSTANDARD("DEFAULT"), 50 | .SLEW("SLOW") 51 | ) iobufs_dqs_i1 ( 52 | .O(dqs_received[1]), 53 | .IO(dqs[1]), 54 | .IOB(ndqs[1]), 55 | .I(dqs_data[1]), 56 | .T(dqs_tri[1])); 57 | 58 | endmodule 59 | 60 | -------------------------------------------------------------------------------- /phy/test_dqs01_placement.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 2 | set_property SLEW FAST [get_ports {dqs}] 3 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 4 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs}] 5 | 6 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 7 | set_property SLEW FAST [get_ports {ndqs}] 8 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 9 | 10 | 11 | # input dqs_data, 12 | # inout dqs, 13 | # inout ndqs, 14 | # output dqs_received, 15 | # input dqs_tri 16 | 17 | 18 | #set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 19 | #set_property IOSTANDARD LVCMOS15 [get_ports {refclk}] 20 | #set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 21 | #set_property IOSTANDARD LVCMOS15 [get_ports {set}] 22 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_data}] 23 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_tri}] 24 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 25 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 26 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 27 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 28 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 29 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 30 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 31 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 32 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[3]}] 33 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[2]}] 34 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[1]}] 35 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[0]}] 36 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[3]}] 37 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[2]}] 38 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[1]}] 39 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[0]}] 40 | 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 42 | set_property PACKAGE_PIN K4 [get_ports {dqs_received}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_data}] 44 | set_property PACKAGE_PIN K6 [get_ports {dqs_data}] 45 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 46 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs_date}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 48 | set_property PACKAGE_PIN K7 [get_ports {dqs_tri}] 49 | 50 | 51 | # input rst, // reset 52 | # input refclk, // 200MHz/300MHz for delay calibration 53 | # input clk_in, 54 | # input set, 55 | # input ld_dly_data, 56 | # input ld_dly_tri, 57 | # input [7:0] dly_data, 58 | # input [3:0] data_in, 59 | # input [3:0] tri_in, 60 | # inout dqs, 61 | # inout ndqs, 62 | # output dqs_received, 63 | # output dly_ready, 64 | # input dqs_tri_a, 65 | # output dqs_tri 66 | 67 | 68 | 69 | 70 | 71 | #set_property PACKAGE_PIN A1 [get_ports {COUNT[2]}] 72 | #set_property PACKAGE_PIN B2 [get_ports {COUNT[1]}] 73 | #set_property PACKAGE_PIN C2 [get_ports {COUNT[0]}] 74 | #set_property PULLUP true [get_ports {COUNT[3]}] 75 | #set_property PULLUP true [get_ports {COUNT[2]}] 76 | #set_property PULLUP true [get_ports {COUNT[1]}] 77 | #set_property PULLUP true [get_ports {COUNT[0]}] 78 | #set_property PACKAGE_PIN A4 [get_ports ENABLE] 79 | #set_property PACKAGE_PIN B4 [get_ports RESET] 80 | 81 | #set_property PACKAGE_PIN C1 [get_ports CLK] 82 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 83 | 84 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[3]}] 85 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[2]}] 86 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[1]}] 87 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[0]}] 88 | #set_property IOSTANDARD LVCMOS18 [get_ports ENABLE] 89 | #set_property IOSTANDARD LVCMOS18 [get_ports RESET] 90 | #set_property IOSTANDARD LVCMOS18 [get_ports CLK] 91 | 92 | 93 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 94 | set_property CFGBVS GND [current_design] 95 | set_property CONFIG_VOLTAGE 1.8 [current_design] -------------------------------------------------------------------------------- /phy/test_dqs02.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs02 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs02.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs02.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs02( 24 | input rst, // reset 25 | input refclk, // 200MHz/300MHz for delay calibration 26 | input clk_in, 27 | // input set, 28 | // input ld_dly_data, 29 | // input ld_dly_tri, 30 | // input [7:0] dly_data, 31 | input [3:0] data_in, 32 | // input [3:0] tri_in, 33 | inout dqs, 34 | // inout ndqs, 35 | output dqs_received, 36 | output dly_ready 37 | // input dqs_tri_a, 38 | // output dqs_tri 39 | // output dqs_data 40 | 41 | ); 42 | wire refclk_b=refclk; // use buffer 43 | wire clk, clk_div; 44 | //wire dqs_data,dqs_tri; // after odelay 45 | //wire dqs_data; // after odelay 46 | //wire pre_dqs_data,pre_dqs_tri; // before odelay 47 | wire dqs_data; 48 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 49 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 50 | 51 | oserdes_mem oserdes_dqs_i( 52 | .clk(clk), // serial output clock 53 | .clk_div(clk_div), // oclk divided by 2, front aligned 54 | .rst(rst), // reset 55 | .din(data_in), // parallel data in 56 | // .tin(tri_in), // parallel tri-state in 57 | .tin(), // parallel tri-state in 58 | .dout_dly(), //pre_dqs_data), // data out to be connected to odelay input 59 | .dout_iob(dqs_data), // data out to be connected directly to the output buffer 60 | .tout_dly(), // tristate out to be connected to odelay input 61 | // .tout_iob(pre_dqs_tri) // tristate out to be connected directly to the tristate control of the output buffer 62 | .tout_iob() // tristate out to be connected directly to the tristate control of the output buffer 63 | ); 64 | 65 | idelay_ctrl# ( 66 | .IODELAY_GRP("IODELAY_MEMORY") 67 | ) idelay_ctrl_i ( 68 | .refclk(refclk_b), 69 | .rst(rst), 70 | .rdy(dly_ready) 71 | ); 72 | 73 | /* 74 | odelay_fine_pipe # ( 75 | .IODELAY_GRP("IODELAY_MEMORY"), 76 | .DELAY_VALUE(0), 77 | .REFCLK_FREQUENCY(300.0), 78 | .HIGH_PERFORMANCE_MODE("FALSE") 79 | ) dqs_data_dly_i( 80 | .clk(clk_div), 81 | .rst(rst), 82 | .set(set), 83 | .ld(ld_dly_data), 84 | .delay(dly_data), 85 | .data_in(pre_dqs_data), 86 | .data_out(dqs_data) 87 | ); 88 | */ 89 | 90 | /* 91 | odelay_pipe # ( 92 | .IODELAY_GRP("IODELAY_MEMORY"), 93 | .DELAY_VALUE(0), 94 | .REFCLK_FREQUENCY(300.0), 95 | .HIGH_PERFORMANCE_MODE("FALSE") 96 | ) dqs_data_dly_i( 97 | .clk(clk_div), 98 | .rst(rst), 99 | .set(set), 100 | .ld(ld_dly_data), 101 | .delay(dly_data[7:3]), 102 | .data_in(pre_dqs_data), 103 | .data_out(dqs_data) 104 | ); 105 | */ 106 | /* 107 | odelay_fine_pipe # ( 108 | .IODELAY_GRP("IODELAY_MEMORY"), 109 | .DELAY_VALUE(0), 110 | .REFCLK_FREQUENCY(300.0), 111 | .HIGH_PERFORMANCE_MODE("FALSE") 112 | ) dqs_tri_dly_i( 113 | .clk(clk_div), 114 | .rst(rst), 115 | .set(set), 116 | .ld(ld_dly_tri), 117 | .delay(dly_data), 118 | .data_in(pre_dqs_tri), 119 | .data_out(dqs_tri) 120 | ); 121 | */ 122 | 123 | //wire dqs_tri_a; 124 | //(* keep = "true" *) BUF buf0_i(.O(dqs_tri_a), .I(dqs_tri)); 125 | 126 | /* 127 | IOBUFDS #( 128 | .DQS_BIAS("FALSE"), 129 | .IBUF_LOW_PWR("TRUE"), 130 | .IOSTANDARD("DEFAULT"), 131 | .SLEW("SLOW") 132 | ) iobufs_dqs_i ( 133 | .O(dqs_received), 134 | .IO(dqs), 135 | .IOB(ndqs), 136 | .I(dqs_data), 137 | // .T(dqs_tri)); 138 | .T()); 139 | */ 140 | IOBUF #( 141 | // .DQS_BIAS("FALSE"), 142 | .IBUF_LOW_PWR("TRUE"), 143 | .IOSTANDARD("DEFAULT"), 144 | .SLEW("SLOW") 145 | ) iobufs_dqs_i ( 146 | .O(dqs_received), 147 | .IO(dqs), 148 | .I(dqs_data), 149 | // .T(dqs_tri)); 150 | .T(dqs_data)); 151 | 152 | 153 | endmodule 154 | 155 | -------------------------------------------------------------------------------- /phy/test_dqs02_placement.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 2 | set_property SLEW FAST [get_ports {dqs}] 3 | #set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 4 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs}] 5 | 6 | #set_property PACKAGE_PIN N6 [get_ports {ndqs}] 7 | #set_property SLEW FAST [get_ports {ndqs}] 8 | #set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 9 | 10 | 11 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 12 | set_property IOSTANDARD LVCMOS15 [get_ports {refclk}] 13 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 14 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 15 | set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_data}] 16 | set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_tri}] 17 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 18 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 19 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 20 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 21 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 22 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 23 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 24 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 25 | set_property IOSTANDARD LVCMOS15 [get_ports {data_in[3]}] 26 | set_property IOSTANDARD LVCMOS15 [get_ports {data_in[2]}] 27 | set_property IOSTANDARD LVCMOS15 [get_ports {data_in[1]}] 28 | set_property IOSTANDARD LVCMOS15 [get_ports {data_in[0]}] 29 | set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[3]}] 30 | set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[2]}] 31 | set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[1]}] 32 | set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[0]}] 33 | 34 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 35 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 36 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri_a}] 37 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 38 | 39 | 40 | # input rst, // reset 41 | # input refclk, // 200MHz/300MHz for delay calibration 42 | # input clk_in, 43 | # input set, 44 | # input ld_dly_data, 45 | # input ld_dly_tri, 46 | # input [7:0] dly_data, 47 | # input [3:0] data_in, 48 | # input [3:0] tri_in, 49 | # inout dqs, 50 | # inout ndqs, 51 | # output dqs_received, 52 | # output dly_ready, 53 | # input dqs_tri_a, 54 | # output dqs_tri 55 | 56 | 57 | 58 | 59 | 60 | #set_property PACKAGE_PIN A1 [get_ports {COUNT[2]}] 61 | #set_property PACKAGE_PIN B2 [get_ports {COUNT[1]}] 62 | #set_property PACKAGE_PIN C2 [get_ports {COUNT[0]}] 63 | #set_property PULLUP true [get_ports {COUNT[3]}] 64 | #set_property PULLUP true [get_ports {COUNT[2]}] 65 | #set_property PULLUP true [get_ports {COUNT[1]}] 66 | #set_property PULLUP true [get_ports {COUNT[0]}] 67 | #set_property PACKAGE_PIN A4 [get_ports ENABLE] 68 | #set_property PACKAGE_PIN B4 [get_ports RESET] 69 | 70 | #set_property PACKAGE_PIN C1 [get_ports CLK] 71 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 72 | 73 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[3]}] 74 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[2]}] 75 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[1]}] 76 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[0]}] 77 | #set_property IOSTANDARD LVCMOS18 [get_ports ENABLE] 78 | #set_property IOSTANDARD LVCMOS18 [get_ports RESET] 79 | #set_property IOSTANDARD LVCMOS18 [get_ports CLK] 80 | 81 | 82 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 83 | -------------------------------------------------------------------------------- /phy/test_dqs03.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs03 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs03.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs03.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs03( 24 | input dqs_data, 25 | inout dqs, 26 | inout ndqs, 27 | input clk_in, 28 | input clk_ref_in, 29 | input rst, 30 | output dqs_received, 31 | input dqs_tri, 32 | output dly_ready, 33 | 34 | input [4:0] dly_data, 35 | input set, 36 | input ld 37 | 38 | ); 39 | //SuppressWarnings all 40 | wire clk; 41 | wire clk_div,clk_ref; 42 | wire dqs_data_dly; 43 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 44 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 45 | BUFG ref_clk_i (.I(clk_ref_in),.O(clk_ref)); 46 | idelay_ctrl# ( 47 | .IODELAY_GRP("IODELAY_MEMORY") 48 | ) idelay_ctrl_i ( 49 | .refclk(clk_ref), 50 | .rst(rst), 51 | .rdy(dly_ready) 52 | ); 53 | 54 | odelay_pipe # ( 55 | .IODELAY_GRP("IODELAY_MEMORY"), 56 | .DELAY_VALUE(0), 57 | .REFCLK_FREQUENCY(300.0), 58 | .HIGH_PERFORMANCE_MODE("FALSE") 59 | ) dqs_data_dly_i( 60 | .clk(clk_div), 61 | .rst(rst), 62 | .set(set), 63 | .ld(ld), 64 | .delay(dly_data), 65 | .data_in(dqs_data), 66 | .data_out(dqs_data_dly) 67 | ); 68 | 69 | 70 | IOBUFDS #( 71 | .DQS_BIAS("FALSE"), 72 | .IBUF_LOW_PWR("TRUE"), 73 | .IOSTANDARD("DEFAULT"), 74 | .SLEW("SLOW") 75 | ) iobufs_dqs_i ( 76 | .O(dqs_received), 77 | .IO(dqs), 78 | .IOB(ndqs), 79 | .I(dqs_data_dly), //dqs_data), 80 | .T(dqs_tri)); 81 | 82 | endmodule 83 | 84 | -------------------------------------------------------------------------------- /phy/test_dqs03_placement.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 2 | set_property SLEW FAST [get_ports {dqs}] 3 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 4 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs}] 5 | 6 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 7 | set_property SLEW FAST [get_ports {ndqs}] 8 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 9 | 10 | 11 | # input dqs_data, 12 | # inout dqs, 13 | # inout ndqs, 14 | # output dqs_received, 15 | # input dqs_tri 16 | 17 | 18 | #set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 19 | #set_property IOSTANDARD LVCMOS15 [get_ports {refclk}] 20 | #set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 21 | #set_property IOSTANDARD LVCMOS15 [get_ports {set}] 22 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_data}] 23 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_tri}] 24 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 25 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 26 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 27 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 28 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 29 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 30 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 31 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 32 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[3]}] 33 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[2]}] 34 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[1]}] 35 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[0]}] 36 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[3]}] 37 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[2]}] 38 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[1]}] 39 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[0]}] 40 | 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 42 | set_property PACKAGE_PIN K4 [get_ports {dqs_received}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_data}] 44 | set_property PACKAGE_PIN K6 [get_ports {dqs_data}] 45 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 46 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs_date}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 48 | set_property PACKAGE_PIN K7 [get_ports {dqs_tri}] 49 | 50 | # input dqs_data, 51 | # inout dqs, 52 | # inout ndqs, 53 | # output dqs_received, 54 | # input dqs_tri, 55 | 56 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 57 | set_property PACKAGE_PIN M5 [get_ports {clk_in}] 58 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_ref_in}] 59 | set_property PACKAGE_PIN L4 [get_ports {clk_ref_in}] 60 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 61 | set_property PACKAGE_PIN L5 [get_ports {rst}] 62 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 63 | set_property PACKAGE_PIN M2 [get_ports {dly_ready}] 64 | 65 | 66 | # input clk_in, 67 | # input clk_ref_in, 68 | # input rst, 69 | # output dly_ready 70 | 71 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 72 | set_property PACKAGE_PIN J1 [get_ports {dly_data[4]}] 73 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 74 | set_property PACKAGE_PIN J3 [get_ports {dly_data[3]}] 75 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 76 | set_property PACKAGE_PIN J4 [get_ports {dly_data[2]}] 77 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 78 | set_property PACKAGE_PIN J5 [get_ports {dly_data[1]}] 79 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 80 | set_property PACKAGE_PIN J6 [get_ports {dly_data[0]}] 81 | 82 | 83 | 84 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 85 | set_property PACKAGE_PIN L6 [get_ports {set}] 86 | set_property IOSTANDARD LVCMOS15 [get_ports {ld}] 87 | set_property PACKAGE_PIN L7 [get_ports {ld}] 88 | 89 | 90 | 91 | 92 | # input rst, // reset 93 | # input refclk, // 200MHz/300MHz for delay calibration 94 | # input clk_in, 95 | # input set, 96 | # input ld_dly_data, 97 | # input ld_dly_tri, 98 | # input [7:0] dly_data, 99 | # input [3:0] data_in, 100 | # input [3:0] tri_in, 101 | # inout dqs, 102 | # inout ndqs, 103 | # output dqs_received, 104 | # output dly_ready, 105 | # input dqs_tri_a, 106 | # output dqs_tri 107 | 108 | 109 | 110 | 111 | 112 | #set_property PACKAGE_PIN A1 [get_ports {COUNT[2]}] 113 | #set_property PACKAGE_PIN B2 [get_ports {COUNT[1]}] 114 | #set_property PACKAGE_PIN C2 [get_ports {COUNT[0]}] 115 | #set_property PULLUP true [get_ports {COUNT[3]}] 116 | #set_property PULLUP true [get_ports {COUNT[2]}] 117 | #set_property PULLUP true [get_ports {COUNT[1]}] 118 | #set_property PULLUP true [get_ports {COUNT[0]}] 119 | #set_property PACKAGE_PIN A4 [get_ports ENABLE] 120 | #set_property PACKAGE_PIN B4 [get_ports RESET] 121 | 122 | #set_property PACKAGE_PIN C1 [get_ports CLK] 123 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 124 | 125 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[3]}] 126 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[2]}] 127 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[1]}] 128 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[0]}] 129 | #set_property IOSTANDARD LVCMOS18 [get_ports ENABLE] 130 | #set_property IOSTANDARD LVCMOS18 [get_ports RESET] 131 | #set_property IOSTANDARD LVCMOS18 [get_ports CLK] 132 | 133 | 134 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 135 | set_property CFGBVS GND [current_design] 136 | set_property CONFIG_VOLTAGE 1.8 [current_design] 137 | 138 | 139 | #ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable 140 | # for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. 141 | # However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override 142 | # this clock rule. 143 | # < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] > 144 | # clk_ref_in_IBUF_inst (IBUF.O) is locked to IOB_X1Y123 145 | # ref_clk_i (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31 146 | # Resolution: Poor placement of an IO pin and a BUFG has resulted in the router using a non-dedicated path between the two. 147 | # There are several things that could trigger this DRC, each of which can cause unpredictable clock insertion delays that 148 | # result in poor timing. This DRC could be caused by any of the following: (a) a clock port was placed on a pin that is 149 | # not a CCIO-pin (b)the BUFG has not been placed in the same half of the device or SLR as the CCIO-pin (c) a single ended 150 | # clock has been placed on the N-Side of a differential pair CCIO-pin. 151 | 152 | # set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] 153 | -------------------------------------------------------------------------------- /phy/test_dqs04.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs04 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs04.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs04.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs04( 24 | input dqs_data, 25 | inout dqs, 26 | inout ndqs, 27 | input clk_in, 28 | input clk_ref_in, 29 | input rst, 30 | output dqs_received, 31 | // input dqs_tri, 32 | output dly_ready, 33 | 34 | input [4:0] dly_data, 35 | input set, 36 | input ld 37 | 38 | ); 39 | wire clk,clk_div,clk_ref; 40 | wire dqs_data_dly; 41 | wire dly_ready_0; 42 | assign dly_ready= dly_ready_0 && dqs_data; 43 | wire d_ser; 44 | wire dqs_tri1; 45 | 46 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 47 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 48 | BUFG ref_clk_i (.I(clk_ref_in),.O(clk_ref)); 49 | 50 | OSERDESE2 #( 51 | .DATA_RATE_OQ ("DDR"), 52 | .DATA_RATE_TQ ("DDR"), 53 | .DATA_WIDTH (4), 54 | .INIT_OQ (1'b0), 55 | .INIT_TQ (1'b0), 56 | .SERDES_MODE ("MASTER"), 57 | .SRVAL_OQ (1'b0), 58 | .SRVAL_TQ (1'b0), 59 | .TRISTATE_WIDTH (4), 60 | .TBYTE_CTL ("FALSE"), 61 | .TBYTE_SRC ("FALSE") 62 | ) oserdes_i ( 63 | .OFB (d_ser), 64 | .OQ (), // dout_iob), 65 | .SHIFTOUT1 (), 66 | .SHIFTOUT2 (), 67 | .TFB (), 68 | .TQ (dqs_tri1), 69 | .CLK (clk), 70 | .CLKDIV (clk_div), 71 | .D1 (dly_data[0]), 72 | .D2 (dly_data[1]), 73 | .D3 (dly_data[2]), 74 | .D4 (dly_data[3]), 75 | .D5 (), 76 | .D6 (), 77 | .D7 (), 78 | .D8 (), 79 | .OCE (1'b1), 80 | .RST (rst), 81 | .SHIFTIN1 (), 82 | .SHIFTIN2 (), 83 | .T1 (dly_data[4]), 84 | .T2 (dly_data[4]), 85 | .T3 (dly_data[4]), 86 | .T4 (dly_data[4]), 87 | .TCE (1'b1), 88 | .TBYTEOUT (), 89 | .TBYTEIN () 90 | ); 91 | 92 | idelay_ctrl# ( 93 | .IODELAY_GRP("IODELAY_MEMORY") 94 | ) idelay_ctrl_i ( 95 | .refclk(clk_ref), 96 | .rst(rst), 97 | .rdy(dly_ready_0) 98 | ); 99 | 100 | odelay_pipe # ( 101 | .IODELAY_GRP("IODELAY_MEMORY"), 102 | .DELAY_VALUE(0), 103 | .REFCLK_FREQUENCY(300.0), 104 | .HIGH_PERFORMANCE_MODE("FALSE") 105 | ) dqs_data_dly_i( 106 | .clk(clk_div), 107 | .rst(rst), 108 | .set(set), 109 | .ld(ld), 110 | .delay(dly_data), 111 | .data_in(d_ser), //dqs_data), 112 | .data_out(dqs_data_dly) 113 | ); 114 | 115 | 116 | IOBUFDS #( 117 | .DQS_BIAS("FALSE"), 118 | .IBUF_LOW_PWR("TRUE"), 119 | .IOSTANDARD("DEFAULT"), 120 | .SLEW("SLOW") 121 | ) iobufs_dqs_i ( 122 | .O(dqs_received), 123 | .IO(dqs), 124 | .IOB(ndqs), 125 | .I(dqs_data_dly), //dqs_data), 126 | .T(dqs_tri1)); 127 | 128 | endmodule 129 | 130 | -------------------------------------------------------------------------------- /phy/test_dqs04_placement.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 2 | set_property SLEW FAST [get_ports {dqs}] 3 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 4 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs}] 5 | 6 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 7 | set_property SLEW FAST [get_ports {ndqs}] 8 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 9 | 10 | 11 | # input dqs_data, 12 | # inout dqs, 13 | # inout ndqs, 14 | # output dqs_received, 15 | # input dqs_tri 16 | 17 | 18 | #set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 19 | #set_property IOSTANDARD LVCMOS15 [get_ports {refclk}] 20 | #set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 21 | #set_property IOSTANDARD LVCMOS15 [get_ports {set}] 22 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_data}] 23 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_tri}] 24 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 25 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 26 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 27 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 28 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 29 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 30 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 31 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 32 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[3]}] 33 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[2]}] 34 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[1]}] 35 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[0]}] 36 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[3]}] 37 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[2]}] 38 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[1]}] 39 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[0]}] 40 | 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 42 | set_property PACKAGE_PIN K4 [get_ports {dqs_received}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_data}] 44 | set_property PACKAGE_PIN K6 [get_ports {dqs_data}] 45 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 46 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs_date}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 48 | set_property PACKAGE_PIN K7 [get_ports {dqs_tri}] 49 | 50 | # input dqs_data, 51 | # inout dqs, 52 | # inout ndqs, 53 | # output dqs_received, 54 | # input dqs_tri, 55 | 56 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 57 | set_property PACKAGE_PIN M5 [get_ports {clk_in}] 58 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_ref_in}] 59 | set_property PACKAGE_PIN L4 [get_ports {clk_ref_in}] 60 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 61 | set_property PACKAGE_PIN L5 [get_ports {rst}] 62 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 63 | set_property PACKAGE_PIN M2 [get_ports {dly_ready}] 64 | 65 | 66 | # input clk_in, 67 | # input clk_ref_in, 68 | # input rst, 69 | # output dly_ready 70 | 71 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 72 | set_property PACKAGE_PIN J1 [get_ports {dly_data[4]}] 73 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 74 | set_property PACKAGE_PIN J3 [get_ports {dly_data[3]}] 75 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 76 | set_property PACKAGE_PIN J4 [get_ports {dly_data[2]}] 77 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 78 | set_property PACKAGE_PIN J5 [get_ports {dly_data[1]}] 79 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 80 | set_property PACKAGE_PIN J6 [get_ports {dly_data[0]}] 81 | 82 | 83 | 84 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 85 | set_property PACKAGE_PIN L6 [get_ports {set}] 86 | set_property IOSTANDARD LVCMOS15 [get_ports {ld}] 87 | set_property PACKAGE_PIN L7 [get_ports {ld}] 88 | 89 | 90 | 91 | 92 | # input rst, // reset 93 | # input refclk, // 200MHz/300MHz for delay calibration 94 | # input clk_in, 95 | # input set, 96 | # input ld_dly_data, 97 | # input ld_dly_tri, 98 | # input [7:0] dly_data, 99 | # input [3:0] data_in, 100 | # input [3:0] tri_in, 101 | # inout dqs, 102 | # inout ndqs, 103 | # output dqs_received, 104 | # output dly_ready, 105 | # input dqs_tri_a, 106 | # output dqs_tri 107 | 108 | 109 | 110 | 111 | 112 | #set_property PACKAGE_PIN A1 [get_ports {COUNT[2]}] 113 | #set_property PACKAGE_PIN B2 [get_ports {COUNT[1]}] 114 | #set_property PACKAGE_PIN C2 [get_ports {COUNT[0]}] 115 | #set_property PULLUP true [get_ports {COUNT[3]}] 116 | #set_property PULLUP true [get_ports {COUNT[2]}] 117 | #set_property PULLUP true [get_ports {COUNT[1]}] 118 | #set_property PULLUP true [get_ports {COUNT[0]}] 119 | #set_property PACKAGE_PIN A4 [get_ports ENABLE] 120 | #set_property PACKAGE_PIN B4 [get_ports RESET] 121 | 122 | #set_property PACKAGE_PIN C1 [get_ports CLK] 123 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 124 | 125 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[3]}] 126 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[2]}] 127 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[1]}] 128 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[0]}] 129 | #set_property IOSTANDARD LVCMOS18 [get_ports ENABLE] 130 | #set_property IOSTANDARD LVCMOS18 [get_ports RESET] 131 | #set_property IOSTANDARD LVCMOS18 [get_ports CLK] 132 | 133 | 134 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 135 | set_property CFGBVS GND [current_design] 136 | set_property CONFIG_VOLTAGE 1.8 [current_design] 137 | 138 | 139 | #ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable 140 | # for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. 141 | # However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override 142 | # this clock rule. 143 | # < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] > 144 | # clk_ref_in_IBUF_inst (IBUF.O) is locked to IOB_X1Y123 145 | # ref_clk_i (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31 146 | # Resolution: Poor placement of an IO pin and a BUFG has resulted in the router using a non-dedicated path between the two. 147 | # There are several things that could trigger this DRC, each of which can cause unpredictable clock insertion delays that 148 | # result in poor timing. This DRC could be caused by any of the following: (a) a clock port was placed on a pin that is 149 | # not a CCIO-pin (b)the BUFG has not been placed in the same half of the device or SLR as the CCIO-pin (c) a single ended 150 | # clock has been placed on the N-Side of a differential pair CCIO-pin. 151 | 152 | # set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] 153 | -------------------------------------------------------------------------------- /phy/test_dqs05.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs05 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs05.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs05.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs05( 24 | input dqs_data, 25 | inout dqs, 26 | inout ndqs, 27 | input clk_in, 28 | input clk_ref_in, 29 | input rst, 30 | output dqs_received, 31 | input dqs_tri, 32 | output dly_ready, 33 | 34 | input [4:0] dly_data, 35 | input set, 36 | input ld, 37 | input ldt 38 | 39 | ); 40 | wire clk,clk_div,clk_ref; 41 | wire dqs_data_dly; 42 | wire dly_ready_0; 43 | assign dly_ready= dly_ready_0 && dqs_data; 44 | wire d_ser; 45 | wire dqs_tri1; 46 | 47 | //wire d_tri; 48 | 49 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 50 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 51 | BUFG ref_clk_i (.I(clk_ref_in),.O(clk_ref)); 52 | 53 | OSERDESE2 #( 54 | .DATA_RATE_OQ ("DDR"), 55 | // .DATA_RATE_TQ ("DDR"), 56 | .DATA_RATE_TQ ("BUF"), 57 | .DATA_WIDTH (4), 58 | .INIT_OQ (1'b0), 59 | .INIT_TQ (1'b0), 60 | .SERDES_MODE ("MASTER"), 61 | .SRVAL_OQ (1'b0), 62 | .SRVAL_TQ (1'b0), 63 | .TRISTATE_WIDTH (1), 64 | .TBYTE_CTL ("FALSE"), 65 | .TBYTE_SRC ("FALSE") 66 | ) oserdes_i ( 67 | .OFB (d_ser), 68 | .OQ (), 69 | .SHIFTOUT1 (), 70 | .SHIFTOUT2 (), 71 | .TFB (), 72 | // .TFB (d_tri), 73 | // .TQ (dqs_tri1), 74 | .TQ (), 75 | .CLK (clk), 76 | .CLKDIV (clk_div), 77 | .D1 (dly_data[0]), 78 | .D2 (dly_data[1]), 79 | .D3 (dly_data[2]), 80 | .D4 (dly_data[3]), 81 | .D5 (), 82 | .D6 (), 83 | .D7 (), 84 | .D8 (), 85 | .OCE (1'b1), 86 | .RST (rst), 87 | .SHIFTIN1 (), 88 | .SHIFTIN2 (), 89 | // .T1 (dly_data[4]), 90 | // .T2 (dly_data[4]), 91 | // .T3 (dly_data[4]), 92 | // .T4 (dly_data[4]), 93 | .T1 (), 94 | .T2 (), 95 | .T3 (), 96 | .T4 (), 97 | // .TCE (1'b1), 98 | .TCE (), 99 | .TBYTEOUT (), 100 | .TBYTEIN () 101 | ); 102 | 103 | idelay_ctrl# ( 104 | .IODELAY_GRP("IODELAY_MEMORY") 105 | ) idelay_ctrl_i ( 106 | .refclk(clk_ref), 107 | .rst(rst), 108 | .rdy(dly_ready_0) 109 | ); 110 | 111 | 112 | 113 | 114 | odelay_pipe # ( 115 | .IODELAY_GRP("IODELAY_MEMORY"), 116 | .DELAY_VALUE(0), 117 | .REFCLK_FREQUENCY(300.0), 118 | .HIGH_PERFORMANCE_MODE("FALSE") 119 | ) dqs_data_dly_i( 120 | .clk(clk_div), 121 | .rst(rst), 122 | .set(set), 123 | .ld(ld), 124 | .delay(dly_data), 125 | .data_in(d_ser), //dqs_data), 126 | .data_out(dqs_data_dly) 127 | ); 128 | 129 | odelay_pipe # ( 130 | .IODELAY_GRP("IODELAY_MEMORY"), 131 | .DELAY_VALUE(0), 132 | .REFCLK_FREQUENCY(300.0), 133 | .HIGH_PERFORMANCE_MODE("FALSE") 134 | ) dqs_tri_dly_i( 135 | .clk(clk_div), 136 | .rst(rst), 137 | .set(set), 138 | .ld(ldt), 139 | .delay(dly_data), 140 | .data_in(dqs_tri), //d_tri), //dqs_data), 141 | .data_out(dqs_tri1) 142 | ); 143 | 144 | 145 | 146 | 147 | IOBUFDS #( 148 | .DQS_BIAS("FALSE"), 149 | .IBUF_LOW_PWR("TRUE"), 150 | .IOSTANDARD("DEFAULT"), 151 | .SLEW("SLOW") 152 | ) iobufs_dqs_i ( 153 | .O(dqs_received), 154 | .IO(dqs), 155 | .IOB(ndqs), 156 | .I(dqs_data_dly), //dqs_data), 157 | .T(dqs_tri1)); 158 | 159 | endmodule 160 | /* 161 | Does not work. 162 | http://forums.xilinx.com/t5/7-Series-FPGAs/How-to-use-2-odelya-on-one-IOB-on-V7/m-p/361317#M2312 163 | There is only one ODELAY per IOI/IOB, therefore to use a second ODELAY you would require the use of a second IOI/IOB. 164 | Secondly the DATAOUT of an ODELAY can ONLY be connected to OBUF (or IOBUF), it will not route to a T port of an IOBUF. 165 | Thirdly when you are using an OSERDES followed by an IOBUFT the T port needs to be driven from the TQ of the OSERDES. 166 | 167 | What you can do is take the DATAOUT of the Tristate ODELAY and drive an IOBUFT and then use the input side of the buffer 168 | drive the T1 port of the OSERDES and connect the TQ port of the data IOBUFT. The obvious down side to this is the use of 169 | the second IOB/IOI and the routing delay from IOB to the T1 port of the OSERDES. 170 | 171 | Another option would be to use the IDELAY in the data IOB/IOI using the DATAIN port and the DELAY_src=> "DATAIN", you can 172 | LOC the IDELAY to the same site (tools won’t automatically choose this location). You will still have the routing delays 173 | as the output of the IDELAY goes into Fabric to get back to the OSERDES T1 port but it only uses data IOB/IOI. 174 | */ 175 | -------------------------------------------------------------------------------- /phy/test_dqs05_placement.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 2 | set_property SLEW FAST [get_ports {dqs}] 3 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 4 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs}] 5 | 6 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 7 | set_property SLEW FAST [get_ports {ndqs}] 8 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 9 | 10 | 11 | # input dqs_data, 12 | # inout dqs, 13 | # inout ndqs, 14 | # output dqs_received, 15 | # input dqs_tri 16 | 17 | 18 | #set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 19 | #set_property IOSTANDARD LVCMOS15 [get_ports {refclk}] 20 | #set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 21 | #set_property IOSTANDARD LVCMOS15 [get_ports {set}] 22 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_data}] 23 | #set_property IOSTANDARD LVCMOS15 [get_ports {ld_dly_tri}] 24 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 25 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 26 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 27 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 28 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 29 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 30 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 31 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 32 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[3]}] 33 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[2]}] 34 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[1]}] 35 | #set_property IOSTANDARD LVCMOS15 [get_ports {data_in[0]}] 36 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[3]}] 37 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[2]}] 38 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[1]}] 39 | #set_property IOSTANDARD LVCMOS15 [get_ports {tri_in[0]}] 40 | 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 42 | set_property PACKAGE_PIN K4 [get_ports {dqs_received}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_data}] 44 | set_property PACKAGE_PIN K6 [get_ports {dqs_data}] 45 | #set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 46 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs_date}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 48 | set_property PACKAGE_PIN K7 [get_ports {dqs_tri}] 49 | 50 | # input dqs_data, 51 | # inout dqs, 52 | # inout ndqs, 53 | # output dqs_received, 54 | # input dqs_tri, 55 | 56 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 57 | set_property PACKAGE_PIN M5 [get_ports {clk_in}] 58 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_ref_in}] 59 | set_property PACKAGE_PIN L4 [get_ports {clk_ref_in}] 60 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 61 | set_property PACKAGE_PIN L5 [get_ports {rst}] 62 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 63 | set_property PACKAGE_PIN M2 [get_ports {dly_ready}] 64 | 65 | 66 | # input clk_in, 67 | # input clk_ref_in, 68 | # input rst, 69 | # output dly_ready 70 | 71 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 72 | set_property PACKAGE_PIN J1 [get_ports {dly_data[4]}] 73 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 74 | set_property PACKAGE_PIN J3 [get_ports {dly_data[3]}] 75 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 76 | set_property PACKAGE_PIN J4 [get_ports {dly_data[2]}] 77 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 78 | set_property PACKAGE_PIN J5 [get_ports {dly_data[1]}] 79 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 80 | set_property PACKAGE_PIN J6 [get_ports {dly_data[0]}] 81 | 82 | 83 | 84 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 85 | set_property PACKAGE_PIN L6 [get_ports {set}] 86 | set_property IOSTANDARD LVCMOS15 [get_ports {ld}] 87 | set_property PACKAGE_PIN L7 [get_ports {ld}] 88 | set_property IOSTANDARD LVCMOS15 [get_ports {ldt}] 89 | set_property PACKAGE_PIN M3 [get_ports {ldt}] 90 | 91 | 92 | 93 | 94 | # input rst, // reset 95 | # input refclk, // 200MHz/300MHz for delay calibration 96 | # input clk_in, 97 | # input set, 98 | # input ld_dly_data, 99 | # input ld_dly_tri, 100 | # input [7:0] dly_data, 101 | # input [3:0] data_in, 102 | # input [3:0] tri_in, 103 | # inout dqs, 104 | # inout ndqs, 105 | # output dqs_received, 106 | # output dly_ready, 107 | # input dqs_tri_a, 108 | # output dqs_tri 109 | 110 | 111 | 112 | 113 | 114 | #set_property PACKAGE_PIN A1 [get_ports {COUNT[2]}] 115 | #set_property PACKAGE_PIN B2 [get_ports {COUNT[1]}] 116 | #set_property PACKAGE_PIN C2 [get_ports {COUNT[0]}] 117 | #set_property PULLUP true [get_ports {COUNT[3]}] 118 | #set_property PULLUP true [get_ports {COUNT[2]}] 119 | #set_property PULLUP true [get_ports {COUNT[1]}] 120 | #set_property PULLUP true [get_ports {COUNT[0]}] 121 | #set_property PACKAGE_PIN A4 [get_ports ENABLE] 122 | #set_property PACKAGE_PIN B4 [get_ports RESET] 123 | 124 | #set_property PACKAGE_PIN C1 [get_ports CLK] 125 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 126 | 127 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[3]}] 128 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[2]}] 129 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[1]}] 130 | #set_property IOSTANDARD LVCMOS18 [get_ports {COUNT[0]}] 131 | #set_property IOSTANDARD LVCMOS18 [get_ports ENABLE] 132 | #set_property IOSTANDARD LVCMOS18 [get_ports RESET] 133 | #set_property IOSTANDARD LVCMOS18 [get_ports CLK] 134 | 135 | 136 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 137 | set_property CFGBVS GND [current_design] 138 | set_property CONFIG_VOLTAGE 1.8 [current_design] 139 | 140 | 141 | #ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable 142 | # for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. 143 | # However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override 144 | # this clock rule. 145 | # < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] > 146 | # clk_ref_in_IBUF_inst (IBUF.O) is locked to IOB_X1Y123 147 | # ref_clk_i (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31 148 | # Resolution: Poor placement of an IO pin and a BUFG has resulted in the router using a non-dedicated path between the two. 149 | # There are several things that could trigger this DRC, each of which can cause unpredictable clock insertion delays that 150 | # result in poor timing. This DRC could be caused by any of the following: (a) a clock port was placed on a pin that is 151 | # not a CCIO-pin (b)the BUFG has not been placed in the same half of the device or SLR as the CCIO-pin (c) a single ended 152 | # clock has been placed on the N-Side of a differential pair CCIO-pin. 153 | 154 | # set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] 155 | -------------------------------------------------------------------------------- /phy/test_dqs06.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs06 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs06.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs06.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs06( 24 | inout dqs, 25 | inout ndqs, 26 | output dqs_received, 27 | input clk_in, 28 | input clk_ref_in, 29 | input rst, 30 | input dci_disable, 31 | input [7:0] dly_data, 32 | input set, 33 | input ld, 34 | output dly_ready 35 | ); 36 | wire clk,clk_div,clk_ref; 37 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 38 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 39 | BUFG ref_clk_i (.I(clk_ref_in),.O(clk_ref)); 40 | 41 | idelay_ctrl# ( 42 | .IODELAY_GRP("IODELAY_MEMORY") 43 | ) idelay_ctrl_i ( 44 | .refclk(clk_ref), 45 | .rst(rst), 46 | .rdy(dly_ready) 47 | ); 48 | 49 | 50 | dqs_single #( 51 | .IBUF_LOW_PWR("FALSE"), 52 | .IOSTANDARD("DIFF_SSTL15_T_DCI"), 53 | .SLEW("FAST"), 54 | .REFCLK_FREQUENCY(300.0) 55 | )dqs_single_i( 56 | .dqs(dqs), 57 | .ndqs(ndqs), 58 | .clk(clk), 59 | .clk_div(clk_div), 60 | .rst(rst), 61 | .dqs_received_dly(dqs_received), 62 | .dci_disable(dci_disable), // disable DCI termination during writes and idle 63 | .dly_data(dly_data[7:0]), 64 | .din(dly_data[3:0]), 65 | .tin({4{dly_data[4]}}), 66 | .set_odelay(set), 67 | .ld_odelay(ld), 68 | .set_idelay(set), 69 | .ld_idelay(ld) 70 | ); 71 | 72 | 73 | endmodule 74 | 75 | -------------------------------------------------------------------------------- /phy/test_dqs06_placement.xdc: -------------------------------------------------------------------------------- 1 | 2 | 3 | # inout dqs, 4 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 5 | set_property SLEW FAST [get_ports {dqs}] 6 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 7 | 8 | # inout ndqs, 9 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 10 | set_property SLEW FAST [get_ports {ndqs}] 11 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 12 | 13 | # output dqs_received, 14 | set_property IOSTANDARD LVCMOS15 [get_ports {dqs_received}] 15 | set_property PACKAGE_PIN K4 [get_ports {dqs_received}] 16 | 17 | # input clk_in, 18 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 19 | set_property PACKAGE_PIN M5 [get_ports {clk_in}] 20 | 21 | # input clk_ref_in, 22 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_ref_in}] 23 | set_property PACKAGE_PIN L4 [get_ports {clk_ref_in}] 24 | 25 | # input rst, 26 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 27 | set_property PACKAGE_PIN L5 [get_ports {rst}] 28 | 29 | # input dci_disable, 30 | set_property IOSTANDARD LVCMOS15 [get_ports {dci_disable}] 31 | set_property PACKAGE_PIN K6 [get_ports {dci_disable}] 32 | 33 | # input [7:0] dly_data, 34 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 35 | set_property PACKAGE_PIN H1 [get_ports {dly_data[7]}] 36 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 37 | set_property PACKAGE_PIN H2 [get_ports {dly_data[6]}] 38 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 39 | set_property PACKAGE_PIN H3 [get_ports {dly_data[5]}] 40 | 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 42 | set_property PACKAGE_PIN J1 [get_ports {dly_data[4]}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 44 | set_property PACKAGE_PIN J3 [get_ports {dly_data[3]}] 45 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 46 | set_property PACKAGE_PIN J4 [get_ports {dly_data[2]}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 48 | set_property PACKAGE_PIN J5 [get_ports {dly_data[1]}] 49 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 50 | set_property PACKAGE_PIN J6 [get_ports {dly_data[0]}] 51 | 52 | # input set, 53 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 54 | set_property PACKAGE_PIN L6 [get_ports {set}] 55 | 56 | # input ld, 57 | set_property IOSTANDARD LVCMOS15 [get_ports {ld}] 58 | set_property PACKAGE_PIN L7 [get_ports {ld}] 59 | 60 | # output dly_ready 61 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 62 | set_property PACKAGE_PIN M2 [get_ports {dly_ready}] 63 | 64 | 65 | #set_property IOSTANDARD LVCMOS15 [get_ports {dqs_tri}] 66 | #set_property PACKAGE_PIN K7 [get_ports {dqs_tri}] 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 85 | set_property CFGBVS GND [current_design] 86 | set_property CONFIG_VOLTAGE 1.8 [current_design] 87 | 88 | 89 | #ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable 90 | # for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. 91 | # However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override 92 | # this clock rule. 93 | # < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] > 94 | # clk_ref_in_IBUF_inst (IBUF.O) is locked to IOB_X1Y123 95 | # ref_clk_i (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31 96 | # Resolution: Poor placement of an IO pin and a BUFG has resulted in the router using a non-dedicated path between the two. 97 | # There are several things that could trigger this DRC, each of which can cause unpredictable clock insertion delays that 98 | # result in poor timing. This DRC could be caused by any of the following: (a) a clock port was placed on a pin that is 99 | # not a CCIO-pin (b)the BUFG has not been placed in the same half of the device or SLR as the CCIO-pin (c) a single ended 100 | # clock has been placed on the N-Side of a differential pair CCIO-pin. 101 | 102 | # set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] 103 | -------------------------------------------------------------------------------- /phy/test_dqs07.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: test_dqs07 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: Testing DQS implementation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * test_dqs07.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * test_dqs07.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module test_dqs07( 24 | inout dqs, 25 | inout ndqs, 26 | // output dqs_received, 27 | input clk_in, 28 | input clk_ref_in, 29 | input rst, 30 | input dci_disable_dqs, 31 | input [7:0] dly_data, 32 | input set, 33 | input ld, 34 | output dly_ready, 35 | 36 | inout dq, 37 | output [3:0] dout, 38 | input dci_disable_dq 39 | ); 40 | wire clk,clk_div,clk_ref; 41 | (* CLOCK_DEDICATED_ROUTE = "FALSE" *) wire dqs_read; // does not seem to work 42 | wire iclk; 43 | 44 | BUFR #(.BUFR_DIVIDE("2")) clk_div_i (.I(clk_in),.O(clk_div),.CLR(rst), .CE(1'b1)); 45 | BUFR #(.BUFR_DIVIDE("BYPASS")) clk_i (.I(clk_in),.O(clk), .CLR(1'b0),.CE(1'b1)); 46 | BUFG ref_clk_i (.I(clk_ref_in),.O(clk_ref)); 47 | //set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets dqs_single_i/dqs_in_dly_i/dqs_read] 48 | //BUFR iclk_i (.O(iclk),.I(dqs_read), .CLR(1'b0),.CE(1'b1)); // OK, works with constraint above 49 | BUFIO iclk_i (.O(iclk),.I(dqs_read)); // Fails even with the constraint 50 | idelay_ctrl# ( 51 | .IODELAY_GRP("IODELAY_MEMORY") 52 | ) idelay_ctrl_i ( 53 | .refclk(clk_ref), 54 | .rst(rst), 55 | .rdy(dly_ready) 56 | ); 57 | 58 | 59 | dqs_single #( 60 | .IODELAY_GRP("IODELAY_MEMORY"), 61 | .IBUF_LOW_PWR("TRUE"), 62 | .IOSTANDARD("DIFF_SSTL15_T_DCI"), 63 | .SLEW("FAST"), 64 | .REFCLK_FREQUENCY(300.0), 65 | .HIGH_PERFORMANCE_MODE("FALSE") 66 | ) dqs_single_i ( 67 | .dqs(dqs), 68 | .ndqs(ndqs), 69 | .clk(clk), 70 | .clk_div(clk_div), 71 | .rst(rst), 72 | .dqs_received_dly(dqs_read), 73 | .dci_disable(dci_disable_dqs), // disable DCI termination during writes and idle 74 | .dly_data(dly_data[7:0]), 75 | .din(dly_data[3:0]), 76 | .tin({4{dly_data[4]}}), 77 | .set_odelay(set), 78 | .ld_odelay(ld), 79 | .set_idelay(set), 80 | .ld_idelay(ld) 81 | ); 82 | dq_single #( 83 | .IODELAY_GRP("IODELAY_MEMORY"), 84 | .IBUF_LOW_PWR("TRUE"), 85 | .IOSTANDARD("SSTL15_T_DCI"), 86 | .SLEW("FAST"), 87 | .REFCLK_FREQUENCY(300.0), 88 | .HIGH_PERFORMANCE_MODE("FALSE") 89 | ) dq_single_i ( 90 | .dq(dq), 91 | .iclk(iclk), // source-synchronous clock (BUFR from DQS) 92 | .clk(clk), // free-running system clock, same frequency as iclk (shared for R/W) 93 | .clk_div(clk_div), // free-running half clk frequency, front aligned to clk (shared for R/W) 94 | .inv_clk_div(1'b0), // invert clk_div for R channel (clk_div is shared between R and W) 95 | .rst(rst), 96 | .dci_disable(dci_disable_dq), // disable DCI termination during writes and idle 97 | .dly_data(dly_data[7:0]), // delay value (3 LSB - fine delay) 98 | .din(dly_data[3:0]), // parallel data to be sent out 99 | .tin({4{dly_data[4]}}), // tristate for data out (sent out earlier than data!) 100 | .dout(dout[3:0]), // parallel data received from DDR3 memory 101 | .set_odelay(set), // clk_div synchronous load odelay value from dly_data 102 | .ld_odelay(ld), // clk_div synchronous set odealy value from loaded 103 | .set_idelay(set), // clk_div synchronous load idelay value from dly_data 104 | .ld_idelay(ld) // clk_div synchronous set idealy value from loaded 105 | ); 106 | 107 | endmodule 108 | 109 | -------------------------------------------------------------------------------- /phy/test_dqs07_placement.xdc: -------------------------------------------------------------------------------- 1 | # inout dqs, 2 | set_property PACKAGE_PIN N7 [get_ports {dqs}] 3 | set_property SLEW FAST [get_ports {dqs}] 4 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {dqs}] 5 | 6 | # inout ndqs, 7 | set_property PACKAGE_PIN N6 [get_ports {ndqs}] 8 | set_property SLEW FAST [get_ports {ndqs}] 9 | set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ndqs}] 10 | 11 | 12 | 13 | 14 | 15 | # input clk_in, 16 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_in}] 17 | set_property PACKAGE_PIN M5 [get_ports {clk_in}] 18 | 19 | # input clk_ref_in, 20 | set_property IOSTANDARD LVCMOS15 [get_ports {clk_ref_in}] 21 | set_property PACKAGE_PIN L4 [get_ports {clk_ref_in}] 22 | 23 | # input rst, 24 | set_property IOSTANDARD LVCMOS15 [get_ports {rst}] 25 | set_property PACKAGE_PIN L5 [get_ports {rst}] 26 | 27 | # input dci_disable, 28 | set_property IOSTANDARD LVCMOS15 [get_ports {dci_disable_dqs}] 29 | set_property PACKAGE_PIN K6 [get_ports {dci_disable_dqs}] 30 | 31 | # input [7:0] dly_data, 32 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[7]}] 33 | set_property PACKAGE_PIN H1 [get_ports {dly_data[7]}] 34 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[6]}] 35 | set_property PACKAGE_PIN H2 [get_ports {dly_data[6]}] 36 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[5]}] 37 | set_property PACKAGE_PIN H3 [get_ports {dly_data[5]}] 38 | 39 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[4]}] 40 | set_property PACKAGE_PIN J1 [get_ports {dly_data[4]}] 41 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[3]}] 42 | set_property PACKAGE_PIN J3 [get_ports {dly_data[3]}] 43 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[2]}] 44 | set_property PACKAGE_PIN J4 [get_ports {dly_data[2]}] 45 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[1]}] 46 | set_property PACKAGE_PIN J5 [get_ports {dly_data[1]}] 47 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_data[0]}] 48 | set_property PACKAGE_PIN J6 [get_ports {dly_data[0]}] 49 | 50 | # input set, 51 | set_property IOSTANDARD LVCMOS15 [get_ports {set}] 52 | set_property PACKAGE_PIN L6 [get_ports {set}] 53 | 54 | # input ld, 55 | set_property IOSTANDARD LVCMOS15 [get_ports {ld}] 56 | set_property PACKAGE_PIN L7 [get_ports {ld}] 57 | 58 | # output dly_ready 59 | set_property IOSTANDARD LVCMOS15 [get_ports {dly_ready}] 60 | set_property PACKAGE_PIN M2 [get_ports {dly_ready}] 61 | 62 | 63 | # inout dq, 64 | set_property IOSTANDARD SSTL15_T_DCI [get_ports {dq}] 65 | set_property PACKAGE_PIN F6 [get_ports {dq}] 66 | 67 | # output [3:0] dout, 68 | set_property IOSTANDARD LVCMOS15 [get_ports {dout[3]}] 69 | set_property PACKAGE_PIN K1 [get_ports {dout[3]}] 70 | set_property IOSTANDARD LVCMOS15 [get_ports {dout[2]}] 71 | set_property PACKAGE_PIN K2 [get_ports {dout[2]}] 72 | set_property IOSTANDARD LVCMOS15 [get_ports {dout[1]}] 73 | set_property PACKAGE_PIN K3 [get_ports {dout[1]}] 74 | set_property IOSTANDARD LVCMOS15 [get_ports {dout[0]}] 75 | set_property PACKAGE_PIN K4 [get_ports {dout[0]}] 76 | 77 | # input dci_disable_dq 78 | set_property IOSTANDARD LVCMOS15 [get_ports {dci_disable_dq}] 79 | set_property PACKAGE_PIN K7 [get_ports {dci_disable_dq}] 80 | 81 | 82 | set_property INTERNAL_VREF 0.750 [get_iobanks 34] 83 | set_property CFGBVS GND [current_design] 84 | set_property CONFIG_VOLTAGE 1.8 [current_design] 85 | 86 | 87 | #ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable 88 | # for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. 89 | # However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override 90 | # this clock rule. 91 | # < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] > 92 | # clk_ref_in_IBUF_inst (IBUF.O) is locked to IOB_X1Y123 93 | # ref_clk_i (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y31 94 | # Resolution: Poor placement of an IO pin and a BUFG has resulted in the router using a non-dedicated path between the two. 95 | # There are several things that could trigger this DRC, each of which can cause unpredictable clock insertion delays that 96 | # result in poor timing. This DRC could be caused by any of the following: (a) a clock port was placed on a pin that is 97 | # not a CCIO-pin (b)the BUFG has not been placed in the same half of the device or SLR as the CCIO-pin (c) a single ended 98 | # clock has been placed on the N-Side of a differential pair CCIO-pin. 99 | 100 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_ref_in_IBUF] 101 | 102 | #trying to force BUFR to use fabric input 103 | #set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets dqs_single_i/dqs_in_dly_i/dqs_received] 104 | #puts [get_property CLOCK_DEDICATED_ROUTE [get_nets dqs_single_i/dqs_in_dly_i/dqs_received]] -------------------------------------------------------------------------------- /python/exp_gpio.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | # Copyright (C) 2013, Elphel.inc. 5 | # Export range of GPIO (EMIO)registers 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | # 19 | __author__ = "Andrey Filippov" 20 | __copyright__ = "Copyright 2014, Elphel, Inc." 21 | __license__ = "GPL" 22 | __version__ = "3.0+" 23 | __maintainer__ = "Andrey Filippov" 24 | __email__ = "andrey@elphel.com" 25 | __status__ = "Development" 26 | 27 | import sys 28 | if len(sys.argv) < 3 or (sys.argv[1] != "in" and sys.argv[1] != "out") : 29 | print ("Usage: ", sys.argv[0]+" []") 30 | exit (0) 31 | mode = sys.argv[1] 32 | 33 | gpio_low_n=int(sys.argv[2]) 34 | if len(sys.argv)>3: 35 | gpio_high_n=int(sys.argv[3]) 36 | else: 37 | gpio_high_n=gpio_low_n 38 | print ("exporting as \""+mode+"\":", end=""), 39 | for gpio_n in range (gpio_low_n, gpio_high_n+1): 40 | print (" %d"%gpio_n, end="") 41 | print() 42 | # bash> echo 240 > /sys/class/gpio/export 43 | # bash> echo out > /sys/class/gpio/gpio240/direction 44 | # bash> echo 1 > /sys/class/gpio/gpio240/value 45 | 46 | for gpio_n in range (gpio_low_n, gpio_high_n+1): 47 | try: 48 | with open ("/sys/class/gpio/export","w") as f: 49 | print (gpio_n,file=f) 50 | except: 51 | print ("failed \"echo %d > /sys/class/gpio/export"%gpio_n) 52 | try: 53 | with open ("/sys/class/gpio/gpio%d/direction"%gpio_n,"w") as f: 54 | print (mode,file=f) 55 | except: 56 | print ("failed \"echo %s > /sys/class/gpio/gpio%d/direction"%(mode,gpio_n)) 57 | 58 | -------------------------------------------------------------------------------- /python/mem.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (C) 2013, Elphel.inc. 4 | # Read/write memory locations as 32-bit values 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | # 18 | __author__ = "Andrey Filippov" 19 | __copyright__ = "Copyright 2014, Elphel, Inc." 20 | __license__ = "GPL" 21 | __version__ = "3.0+" 22 | __maintainer__ = "Andrey Filippov" 23 | __email__ = "andrey@elphel.com" 24 | __status__ = "Development" 25 | import mmap 26 | import sys 27 | import struct 28 | PAGE_SIZE=4096 29 | endian="<" # little, ">" for big 30 | if len(sys.argv)<2: 31 | print "Usage: ", sys.argv[0]+" address [data]" 32 | exit (0) 33 | addr=int(sys.argv[1],16) & 0xfffffffc 34 | data=0 35 | writeMode=len(sys.argv)>2 36 | if (writeMode): 37 | data=int(sys.argv[2],16) 38 | with open("/dev/mem", "r+b") as f: 39 | page_addr=addr & (~(PAGE_SIZE-1)) 40 | page_offs=addr-page_addr 41 | if (page_addr>=0x80000000): 42 | page_addr-= (1<<32) 43 | mm = mmap.mmap(f.fileno(), PAGE_SIZE, offset=page_addr) 44 | if writeMode: 45 | packedData=struct.pack(endian+"L",data) 46 | d=struct.unpack(endian+"L",packedData)[0] 47 | mm[page_offs:page_offs+4]=packedData 48 | print ("0x%08x <== 0x%08x (%d)"%(addr,d,d)) 49 | else: 50 | data=struct.unpack(endian+"L",mm[page_offs:page_offs+4]) 51 | d=data[0] 52 | print ("0x%08x ==> 0x%08x (%d)"%(addr,d,d)) 53 | mm.close() 54 | -------------------------------------------------------------------------------- /python/memdump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (C) 2013, Elphel.inc. 4 | # Dump a range of memory locations (physical) 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | # 18 | __author__ = "Andrey Filippov" 19 | __copyright__ = "Copyright 2014, Elphel, Inc." 20 | __license__ = "GPL" 21 | __version__ = "3.0+" 22 | __maintainer__ = "Andrey Filippov" 23 | __email__ = "andrey@elphel.com" 24 | __status__ = "Development" 25 | import mmap 26 | import sys 27 | import struct 28 | PAGE_SIZE=4096 29 | endian="<" # little, ">" for big 30 | if len(sys.argv)<=1: 31 | print "Usage: ", sys.argv[0]+" start_address end_address" 32 | exit (0) 33 | start_addr=int(sys.argv[1],16) & 0xfffffffc 34 | if len(sys.argv)>2: 35 | end_addr=int(sys.argv[2],16) & 0xfffffffc 36 | else: 37 | end_addr=start_addr 38 | data=0 39 | writeMode=len(sys.argv)>2 40 | with open("/dev/mem", "r+b") as f: 41 | for addr in range (start_addr,end_addr+4,4): 42 | page_addr=addr & (~(PAGE_SIZE-1)) 43 | if (addr == start_addr) or ((addr & 0x3f) == 0): 44 | print ("\n0x%08x:"%addr), 45 | page_offs=addr-page_addr 46 | if (page_addr>=0x80000000): 47 | page_addr-= (1<<32) 48 | mm = mmap.mmap(f.fileno(), PAGE_SIZE, offset=page_addr) 49 | data=struct.unpack(endian+"L",mm[page_offs:page_offs+4]) 50 | d=data[0] 51 | print ("%08x"%d), 52 | mm.close() 53 | -------------------------------------------------------------------------------- /python/mon_gpio.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | # Copyright (C) 2013, Elphel.inc. 5 | # Monitor a range of GPIO bits (should be exported first) 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | # 19 | __author__ = "Andrey Filippov" 20 | __copyright__ = "Copyright 2014, Elphel, Inc." 21 | __license__ = "GPL" 22 | __version__ = "3.0+" 23 | __maintainer__ = "Andrey Filippov" 24 | __email__ = "andrey@elphel.com" 25 | __status__ = "Development" 26 | import sys 27 | if len(sys.argv) < 2 : 28 | print ("Usage: ", sys.argv[0]+" []") 29 | exit (0) 30 | gpio_low_n=int(sys.argv[1]) 31 | if len(sys.argv)>2: 32 | gpio_high_n=int(sys.argv[2]) 33 | else: 34 | gpio_high_n=gpio_low_n 35 | print ("gpio %d.%d: "%(gpio_high_n,gpio_low_n), end=""), 36 | # bash> echo 240 > /sys/class/gpio/export 37 | # bash> echo out > /sys/class/gpio/gpio240/direction 38 | # bash> echo 1 > /sys/class/gpio/gpio240/value 39 | 40 | for gpio_n in range (gpio_high_n, gpio_low_n-1,-1): 41 | if gpio_n != gpio_high_n and ((gpio_n-gpio_low_n+1) % 4) == 0: 42 | print (".",end="") 43 | try: 44 | with open ("/sys/class/gpio/gpio%d/value"%gpio_n,"r") as f: 45 | print (f.read(1),end="") 46 | except: 47 | print ("X",end="") 48 | print() 49 | -------------------------------------------------------------------------------- /simulation_modules/simul_axi_fifo_out.v: -------------------------------------------------------------------------------- 1 | /************************************** 2 | * Module: simul_axi_fifo 3 | * Date:2014-03-23 4 | * Author: andrey 5 | * 6 | * Description: 7 | ***************************************/ 8 | `timescale 1ns/1ps 9 | 10 | module simul_axi_fifo 11 | #( 12 | parameter integer WIDTH= 64, // total number of output bits 13 | parameter integer LATENCY=0, // minimal delay between inout and output ( 0 - next cycle) 14 | parameter integer DEPTH=8, // maximal number of commands in FIFO 15 | // parameter OUT_DELAY = 3.5, 16 | parameter integer FIFO_DEPTH=LATENCY+DEPTH+1 17 | // parameter integer DATA_2DEPTH=(1< . 20 | *******************************************************************************/ 21 | 22 | `timescale 1ns/1ps 23 | 24 | module simul_axi_master_rdaddr 25 | #( 26 | parameter integer ID_WIDTH=12, 27 | parameter integer ADDRESS_WIDTH=32, 28 | parameter integer LATENCY=0, // minimal delay between inout and output ( 0 - next cycle) 29 | parameter integer DEPTH=8, // maximal number of commands in FIFO 30 | parameter DATA_DELAY = 3.5, 31 | parameter VALID_DELAY = 4.0 32 | 33 | // parameter integer DATA_2DEPTH=(1< . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module simul_axi_master_wdata#( 24 | parameter integer ID_WIDTH=12, 25 | parameter integer DATA_WIDTH=32, 26 | parameter integer WSTB_WIDTH= 4, 27 | parameter integer LATENCY=0, // minimal delay between inout and output ( 0 - next cycle) 28 | parameter integer DEPTH=8, // maximal number of commands in FIFO 29 | parameter DATA_DELAY = 3.5, 30 | parameter VALID_DELAY = 4.0 31 | )( 32 | input clk, 33 | input reset, 34 | input [ID_WIDTH-1:0] wid_in, 35 | input [DATA_WIDTH-1:0] wdata_in, 36 | input [WSTB_WIDTH-1:0] wstrb_in, 37 | input wlast_in, 38 | output [ID_WIDTH-1:0] wid, 39 | output [DATA_WIDTH-1:0] wdata, 40 | output [WSTB_WIDTH-1:0] wstrb, 41 | output wlast, 42 | output wvalid, 43 | input wready, 44 | 45 | input set_cmd, // latch all other input data at posedge of clock 46 | output ready // command/data FIFO can accept command 47 | ); 48 | 49 | wire [ID_WIDTH-1:0] wid_out; 50 | wire [DATA_WIDTH-1:0] wdata_out; 51 | wire [WSTB_WIDTH-1:0] wstrb_out; 52 | wire wlast_out; 53 | wire wvalid_out; 54 | 55 | assign #(DATA_DELAY) wid= wid_out; 56 | assign #(DATA_DELAY) wdata= wdata_out; 57 | assign #(DATA_DELAY) wstrb= wstrb_out; 58 | assign #(DATA_DELAY) wlast= wlast_out; 59 | assign #(VALID_DELAY) wvalid= wvalid_out; 60 | 61 | simul_axi_fifo 62 | #( 63 | .WIDTH(ID_WIDTH+DATA_WIDTH+WSTB_WIDTH+1), // total number of output bits 64 | .LATENCY(LATENCY), // minimal delay between inout and output ( 0 - next cycle) 65 | .DEPTH(DEPTH) // maximal number of commands in FIFO 66 | ) simul_axi_fifo_i ( 67 | .clk(clk), // input clk, 68 | .reset(reset), // input reset, 69 | .data_in({wid_in, wdata_in, wstrb_in, wlast_in}), // input [WIDTH-1:0] data_in, 70 | .load(set_cmd), // input load, 71 | .input_ready(ready), // output input_ready, 72 | .data_out({wid_out, wdata_out, wstrb_out, wlast_out}), // output [WIDTH-1:0] data_out, 73 | .valid(wvalid_out), // output valid, 74 | .ready(wready)); // input ready); 75 | 76 | endmodule 77 | 78 | -------------------------------------------------------------------------------- /simulation_modules/simul_axi_master_wraddr.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: simul_axi_master_wraddr 3 | * Date:2014-03-24 4 | * Author: Andrey Filippov 5 | * Description: Simulation model for AXI write address channel 6 | * 7 | * Copyright (c) 2014 Elphel, Inc.. 8 | * simul_axi_master_wraddr.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * simul_axi_master_wraddr.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module simul_axi_master_wraddr 24 | #( 25 | parameter integer ID_WIDTH=12, 26 | parameter integer ADDRESS_WIDTH=32, 27 | parameter integer LATENCY=0, // minimal delay between inout and output ( 0 - next cycle) 28 | parameter integer DEPTH=8, // maximal number of commands in FIFO 29 | parameter DATA_DELAY = 3.5, 30 | parameter VALID_DELAY = 4.0 31 | )( 32 | input clk, 33 | input reset, 34 | input [ID_WIDTH-1:0] awid_in, 35 | input [ADDRESS_WIDTH-1:0] awaddr_in, 36 | input [3:0] awlen_in, 37 | input [2:0] awsize_in, 38 | input [1:0] awburst_in, 39 | input [3:0] awcache_in, 40 | input [2:0] awprot_in, 41 | 42 | output [ID_WIDTH-1:0] awid, 43 | output [ADDRESS_WIDTH-1:0] awaddr, 44 | output [3:0] awlen, 45 | output [2:0] awsize, 46 | output [1:0] awburst, 47 | output [3:0] awcache, 48 | output [2:0] awprot, 49 | output awvalid, 50 | input awready, 51 | 52 | input set_cmd, // latch all other input data at posedge of clock 53 | output ready // command/data FIFO can accept command 54 | ); 55 | wire [ID_WIDTH-1:0] awid_out; 56 | wire [ADDRESS_WIDTH-1:0] awaddr_out; 57 | wire [3:0] awlen_out; 58 | wire [2:0] awsize_out; 59 | wire [1:0] awburst_out; 60 | wire [3:0] awcache_out; 61 | wire [2:0] awprot_out; 62 | wire awvalid_out; 63 | 64 | assign #(DATA_DELAY) awid= awid_out; 65 | assign #(DATA_DELAY) awaddr= awaddr_out; 66 | assign #(DATA_DELAY) awlen= awlen_out; 67 | assign #(DATA_DELAY) awsize= awsize_out; 68 | assign #(DATA_DELAY) awburst= awburst_out; 69 | assign #(DATA_DELAY) awcache= awcache_out; 70 | assign #(DATA_DELAY) awprot= awprot_out; 71 | assign #(VALID_DELAY) awvalid= awvalid_out; 72 | 73 | simul_axi_fifo 74 | #( 75 | .WIDTH(ID_WIDTH+ADDRESS_WIDTH+16), // total number of output bits 76 | .LATENCY(LATENCY), // minimal delay between inout and output ( 0 - next cycle) 77 | .DEPTH(DEPTH) // maximal number of commands in FIFO 78 | // parameter OUT_DELAY = 3.5, 79 | ) simul_axi_fifo_i ( 80 | .clk(clk), // input clk, 81 | .reset(reset), // input reset, 82 | .data_in({awid_in,awaddr_in,awlen_in,awsize_in,awburst_in,awcache_in,awprot_in}), // input [WIDTH-1:0] data_in, 83 | .load(set_cmd), // input load, 84 | .input_ready(ready), // output input_ready, 85 | .data_out({awid_out,awaddr_out,awlen_out,awsize_out,awburst_out,awcache_out,awprot_out}), // output [WIDTH-1:0] data_out, 86 | .valid(awvalid_out), // output valid, 87 | .ready(awready)); // input ready); 88 | 89 | endmodule 90 | 91 | -------------------------------------------------------------------------------- /simulation_modules/simul_axi_read.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: simul_axi_read 3 | * Date:2014-04-06 4 | * Author: Andrey Filippov 5 | * Description: simulation of read data through maxi channel 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * simul_axi_read.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * simul_axi_read.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module simul_axi_read( 24 | input clk, 25 | input reset, 26 | input last, // last data word in burst 27 | input data_stb, // data strobe (RVALID & RREADY) genearted externally 28 | input [ 9:0] raddr, // read burst address as written by axi master, 10 significant bits [11:2], valid at rcmd 29 | input [ 3:0] rlen, // burst length as written by axi master, valid at rcmd 30 | input rcmd, // read command (address+length) strobe 31 | output [ 9:0] addr_out, // output address 32 | output burst, // burst in progress 33 | output reg err_out); // data last does not match predicted or FIFO over/under run 34 | 35 | wire [ 9:0] raddr_fifo; // raddr after fifo 36 | wire [ 3:0] rlen_fifo; // rlen after fifo 37 | wire fifo_valid; // fifo out valid 38 | // wire fifo_re; // fifo read strobe 39 | reg burst_r=0; 40 | reg [ 3:0] left_plus_1; 41 | // wire start_burst=fifo_valid && (!burst_r || (last && data_stb)); 42 | // wire start_burst=fifo_valid && data_stb && (!burst_r || last ); 43 | wire start_burst=fifo_valid && data_stb && !burst_r; 44 | wire generated_last= burst?(left_plus_1==1): ( fifo_valid && (rlen_fifo==0)) ; 45 | wire fifo_in_rdy; 46 | wire error_w= (data_stb && (last != generated_last)) || (rcmd && !fifo_in_rdy) || (start_burst && !fifo_valid); 47 | reg [ 9:0] adr_out_r; 48 | // reg was_last; 49 | 50 | assign burst=burst_r || start_burst; 51 | assign addr_out=start_burst?raddr_fifo:adr_out_r; 52 | always @ (posedge reset or posedge clk) begin 53 | if (reset) burst_r <= 0; 54 | else if (start_burst) burst_r <= rlen_fifo!=0; 55 | // else if (last && data_stb) burst_r <= 0; 56 | else if (generated_last && data_stb) burst_r <= 0; 57 | if (reset) left_plus_1 <= 0; 58 | else if (start_burst) left_plus_1 <= rlen_fifo; 59 | else if (data_stb) left_plus_1 <= left_plus_1-1; 60 | if (reset) err_out <= 0; 61 | else err_out <= error_w; 62 | // if (reset) was_last <= 0; 63 | // else if (data_stb) was_last <= last; 64 | 65 | end 66 | always @ (posedge clk) begin 67 | if (start_burst) adr_out_r <= raddr_fifo+1; // simulating only address incremental mode 68 | else if (data_stb) adr_out_r <= adr_out_r + 1; 69 | 70 | end 71 | simul_fifo 72 | #( 73 | .WIDTH(14), 74 | .DEPTH(64) 75 | )simmul_fifo_i( 76 | .clk(clk), 77 | .reset(reset), 78 | // .data_in({rlen[3:0],raddr[11:2]}), // did not detect raddr[11:2] for input [ 9:0] raddr 79 | .data_in({rlen[3:0],raddr}), 80 | .load(rcmd), 81 | .input_ready(fifo_in_rdy), 82 | .data_out({rlen_fifo, raddr_fifo}), 83 | .valid(fifo_valid), 84 | .ready(start_burst)); 85 | endmodule 86 | 87 | -------------------------------------------------------------------------------- /simulation_modules/simul_axi_slow_ready.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: simul_axi_slow_ready 3 | * Date:2014-03-24 4 | * Author: Andrey Filippov 5 | * Description: Simulation model for AXI: slow ready generation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc.. 8 | * simul_axi_slow_ready.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * simul_axi_slow_ready.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module simul_axi_slow_ready( 24 | input clk, 25 | input reset, 26 | input [3:0] delay, 27 | input valid, 28 | output ready 29 | ); 30 | reg [14:0] rdy_reg; 31 | assign ready=(delay==0)?1'b1: ((((rdy_reg[14:0] >> (delay-1)) & 1) != 0)?1'b1:1'b0); 32 | always @ (posedge clk or posedge reset) begin 33 | if (reset) rdy_reg <=0; 34 | else if (!valid || ready) rdy_reg <=0; 35 | else rdy_reg <={rdy_reg[13:0],valid}; 36 | end 37 | 38 | 39 | endmodule 40 | 41 | -------------------------------------------------------------------------------- /simulation_modules/simul_fifo.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: simul_fifo 3 | * Date:2014-04-06 4 | * Author: Andrey Filippov 5 | * Description: simple fifo for simulation 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * simul_fifo.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * simul_fifo.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module simul_fifo 24 | #( 25 | parameter integer WIDTH= 32, // total number of output bits 26 | parameter integer DEPTH= 64, // maximal number of words in FIFO 27 | // parameter OUT_DELAY = 3.5, 28 | parameter integer FIFO_DEPTH=DEPTH+1 29 | // parameter integer DATA_2DEPTH=(1< . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module dly01_16( 24 | input clk, 25 | input rst, 26 | input [3:0] dly, 27 | input din, 28 | output reg dout 29 | ); 30 | reg [15:0] sr=0; 31 | always @ (posedge rst or posedge clk) begin 32 | if (rst) sr <=0; 33 | else sr <= {sr[14:0],din}; 34 | end 35 | 36 | always @ (sr or dly) case (dly) 37 | 4'h0: dout <= sr[ 0]; 38 | 4'h1: dout <= sr[ 1]; 39 | 4'h2: dout <= sr[ 2]; 40 | 4'h3: dout <= sr[ 3]; 41 | 4'h4: dout <= sr[ 4]; 42 | 4'h5: dout <= sr[ 5]; 43 | 4'h6: dout <= sr[ 6]; 44 | 4'h7: dout <= sr[ 7]; 45 | 4'h8: dout <= sr[ 8]; 46 | 4'h9: dout <= sr[ 9]; 47 | 4'ha: dout <= sr[10]; 48 | 4'hb: dout <= sr[11]; 49 | 4'hc: dout <= sr[12]; 50 | 4'hd: dout <= sr[13]; 51 | 4'he: dout <= sr[14]; 52 | 4'hf: dout <= sr[15]; 53 | endcase 54 | endmodule 55 | 56 | -------------------------------------------------------------------------------- /util_modules/fifo_cross_clocks.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: fifo_cross_clocks 3 | * Date:2014-05-20 4 | * Author: Andrey Filippov 5 | * Description: Configurable FIFO with separate read and write clocks 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * fifo_cross_clocks.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * fifo_cross_clocks.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module fifo_cross_clocks 24 | #( 25 | parameter integer DATA_WIDTH=16, 26 | parameter integer DATA_DEPTH=4 // >=3 27 | ) ( 28 | input rst, // reset, active high 29 | input rclk, // read clock - positive edge 30 | input wclk, // write clock - positive edge 31 | input we, // write enable 32 | input re, // read enable 33 | input [DATA_WIDTH-1:0] data_in, // input data 34 | output [DATA_WIDTH-1:0] data_out, // output data 35 | output nempty, // FIFO has some data (sync to rclk) 36 | output half_empty // FIFO half full (wclk) -(not more than 5/8 full) 37 | ); 38 | localparam integer DATA_2DEPTH=(1< . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | `define DEBUG_FIFO 1 23 | module fifo_same_clock 24 | #( 25 | parameter integer DATA_WIDTH=16, 26 | parameter integer DATA_DEPTH=4 27 | ) 28 | ( 29 | input rst, // reset, active high 30 | input clk, // clock - positive edge 31 | input we, // write enable 32 | input re, // read enable 33 | input [DATA_WIDTH-1:0] data_in, // input data 34 | output [DATA_WIDTH-1:0] data_out, // output data 35 | output nempty, // FIFO has some data 36 | output reg half_full // FIFO half full 37 | `ifdef DEBUG_FIFO 38 | ,output reg under, // debug outputs - under - attempt to read from empty 39 | output reg over, // overwritten 40 | output reg [DATA_DEPTH-1:0] wcount, 41 | output reg [DATA_DEPTH-1:0] rcount, 42 | output [DATA_DEPTH-1:0] num_in_fifo 43 | 44 | `endif 45 | ); 46 | localparam integer DATA_2DEPTH=(1<. This FF/Latch will be trimmed during the optimization process. 48 | //ISExst: FF/Latch ddrc_test01.axibram_read_i.raddr_i.fill[4] has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. 49 | //ISExst: FF/Latch ddrc_test01.axibram_write_i.wdata_i.fill[4] has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. 50 | // Do not understand - why? 51 | reg [DATA_DEPTH-1:0] fill=0; // RAM fill 52 | reg [DATA_WIDTH-1:0] inreg; 53 | reg [DATA_WIDTH-1:0] outreg; 54 | reg [DATA_DEPTH-1:0] ra; 55 | reg [DATA_DEPTH-1:0] wa; 56 | wire [DATA_DEPTH-1:0] next_fill; 57 | reg wem; 58 | wire rem; 59 | reg out_full=0; //output register full 60 | reg [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH]; 61 | 62 | reg ram_nempty; 63 | 64 | assign next_fill = fill[DATA_DEPTH-1:0]+((wem && ~rem)?1:((~wem && rem && ram_nempty)?-1:0)); 65 | assign rem= ram_nempty && (re || !out_full); 66 | assign data_out=outreg; 67 | assign nempty=out_full; 68 | 69 | `ifdef DEBUG_FIFO 70 | assign num_in_fifo=fill[DATA_DEPTH-1:0]; 71 | `endif 72 | 73 | always @ (posedge clk or posedge rst) begin 74 | if (rst) fill <= 0; 75 | else fill <= next_fill; 76 | if (rst) wem <= 0; 77 | else wem <= we; 78 | if (rst) ram_nempty <= 0; 79 | else ram_nempty <= (next_fill != 0); 80 | 81 | if (rst) wa <= 0; 82 | else if (wem) wa <= wa+1; 83 | if (rst) ra <= 0; 84 | else if (rem) ra <= ra+1; 85 | else if (!ram_nempty) ra <= wa; // Just recover from bit errors 86 | 87 | if (rst) out_full <= 0; 88 | else if (rem && ~re) out_full <= 1; 89 | else if (re && ~rem) out_full <= 0; 90 | 91 | `ifdef DEBUG_FIFO 92 | if (rst) wcount <= 0; 93 | else if (we) wcount <= wcount + 1; 94 | 95 | if (rst) rcount <= 0; 96 | else if (re) rcount <= rcount + 1; 97 | `endif 98 | end 99 | 100 | // no reset elements 101 | always @ (posedge clk) begin 102 | half_full <=(fill & (1<<(DATA_DEPTH-1)))!=0; 103 | if (wem) ram[wa] <= inreg; 104 | if (we) inreg <= data_in; 105 | if (rem) outreg <= ram[ra]; 106 | `ifdef DEBUG_FIFO 107 | under <= ~we & re & ~nempty; // underrun error 108 | over <= we & ~re & (fill == (1<< (DATA_DEPTH-1))); // overrun error 109 | `endif 110 | end 111 | endmodule 112 | -------------------------------------------------------------------------------- /wrap/dci_reset.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: dci_reset 3 | * Date:2014-06-01 4 | * Author: Andrey Filippov 5 | * Description: DCIRESET primitivbe wrapper 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * dci_reset.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * dci_reset.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module dci_reset( 24 | input reset, 25 | output ready 26 | ); 27 | DCIRESET DCIRESET_i ( 28 | .LOCKED(ready), // output 29 | .RST(reset) // input 30 | ); 31 | 32 | endmodule 33 | 34 | -------------------------------------------------------------------------------- /wrap/idelay_ctrl.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: idelay_ctrl 3 | * Date:2014-04-25 4 | * Author: Andrey Filippov 5 | * Description: IDELAYCTRL wrapper 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * idelay_ctrl.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * idelay_ctrl.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module idelay_ctrl 24 | //SuppressWarnings VEditor - IODELAY_GRP used in (* *) construnt 25 | # ( parameter IODELAY_GRP = "IODELAY_MEMORY" 26 | ) ( 27 | input refclk, 28 | input rst, 29 | output rdy 30 | ); 31 | 32 | (* IODELAY_GROUP = IODELAY_GRP *) 33 | IDELAYCTRL idelay_ctrl_i( 34 | .RDY(rdy), 35 | .REFCLK(refclk), 36 | .RST(rst)); 37 | endmodule 38 | 39 | -------------------------------------------------------------------------------- /wrap/idelay_fine_pipe.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: idelay_fine_pipe 3 | * Date:2014-04-25 4 | * Author: Andrey Filippov 5 | * Description: IDELAYE2_FINEDELAY wrapper with fine control pipelined 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * idelay_fine_pipe.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * idelay_fine_pipe.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module idelay_fine_pipe 24 | //SuppressWarnings VEditor - IODELAY_GRP used in (* *) construnt 25 | # ( parameter IODELAY_GRP = "IODELAY_MEMORY", 26 | parameter integer DELAY_VALUE = 0, 27 | parameter real REFCLK_FREQUENCY = 200.0, 28 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 29 | ) ( 30 | input clk, 31 | input rst, 32 | input set, 33 | input ld, 34 | input [7:0] delay, 35 | input data_in, 36 | output data_out 37 | ); 38 | 39 | reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0]; 40 | always @ (posedge clk or posedge rst) begin 41 | if (rst) fdly_pre <= DELAY_VALUE[2:0]; 42 | else if (ld) fdly_pre <= delay[2:0]; 43 | if (rst) fdly <= DELAY_VALUE[2:0]; 44 | else if (set) fdly <= fdly_pre; 45 | end 46 | `ifdef IVERILOG 47 | always @ (fdly_pre) begin 48 | if (fdly_pre > 3'h4) $display ("ERROR: fine idelay value should be <5, specified %d @ %t", fdly_pre,$time); 49 | end 50 | `endif 51 | (* IODELAY_GROUP = IODELAY_GRP *) IDELAYE2_FINEDELAY 52 | #( 53 | .CINVCTRL_SEL("FALSE"), 54 | .DELAY_SRC("IDATAIN"), 55 | .FINEDELAY("ADD_DLY"), 56 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), 57 | .IDELAY_TYPE("VAR_LOAD_PIPE"), 58 | .IDELAY_VALUE(DELAY_VALUE>>3), 59 | // .IS_C_INVERTED(1'b0), // ISE does not have this parameter 60 | // .IS_DATAIN_INVERTED(1'b0), // ISE does not have this parameter 61 | // .IS_IDATAIN_INVERTED(1'b0), // ISE does not have this parameter 62 | .PIPE_SEL("TRUE"), 63 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 64 | .SIGNAL_PATTERN("DATA") 65 | ) 66 | idelay2_finedelay_i( 67 | .CNTVALUEOUT(), 68 | .DATAOUT(data_out), 69 | .C(clk), 70 | .CE(1'b0), 71 | .CINVCTRL(1'b0), 72 | .CNTVALUEIN(delay[7:3]), 73 | .DATAIN(1'b0), 74 | .IDATAIN(data_in), 75 | .IFDLY(fdly), 76 | .INC(1'b0), 77 | .LD(set), 78 | .LDPIPEEN(ld), 79 | .REGRST(rst) 80 | ); 81 | 82 | endmodule 83 | 84 | -------------------------------------------------------------------------------- /wrap/idelay_nofine.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: idelay_nofine 3 | * Date:2014-04-25 4 | * Author: Andrey Filippov 5 | * Description: IDELAYE2 wrapper without fine delay 6 | * Copyright (c) 2014 Elphel, Inc. 7 | * idelay_nofine.v is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * idelay_nofine.v is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | *******************************************************************************/ 20 | `timescale 1ns/1ps 21 | 22 | module idelay_nofine 23 | //SuppressWarnings VEditor - IODELAY_GRP used in (* *) construnt 24 | # ( parameter IODELAY_GRP = "IODELAY_MEMORY", 25 | parameter integer DELAY_VALUE = 0, 26 | parameter real REFCLK_FREQUENCY = 200.0, 27 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 28 | ) ( 29 | input clk, 30 | input rst, 31 | input set, 32 | input ld, 33 | input [4:0] delay, 34 | input data_in, 35 | output data_out 36 | ); 37 | (* IODELAY_GROUP = IODELAY_GRP *) IDELAYE2 38 | #( 39 | .CINVCTRL_SEL("FALSE"), 40 | .DELAY_SRC("IDATAIN"), 41 | // .FINEDELAY("ADD_DLY"), 42 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), 43 | .IDELAY_TYPE("VAR_LOAD_PIPE"), 44 | .IDELAY_VALUE(DELAY_VALUE), 45 | // .IS_C_INVERTED(1'b0), // ISE does not have this parameter 46 | // .IS_DATAIN_INVERTED(1'b0), // ISE does not have this parameter 47 | // .IS_IDATAIN_INVERTED(1'b0), // ISE does not have this parameter 48 | .PIPE_SEL("TRUE"), 49 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 50 | .SIGNAL_PATTERN("DATA") 51 | ) 52 | idelay2_i( 53 | .CNTVALUEOUT(), 54 | .DATAOUT(data_out), 55 | .C(clk), 56 | .CE(1'b0), 57 | .CINVCTRL(1'b0), 58 | .CNTVALUEIN(delay[4:0]), 59 | .DATAIN(1'b0), 60 | .IDATAIN(data_in), 61 | // .IFDLY(fdly), 62 | .INC(1'b0), 63 | .LD(set), 64 | .LDPIPEEN(ld), 65 | .REGRST(rst) 66 | ); 67 | 68 | endmodule 69 | 70 | -------------------------------------------------------------------------------- /wrap/iserdes_mem.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: iserdes_mem 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: ISERDESE2/ISERDESE1 wrapper to use for DDR3 memory w/o phasers 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * iserdes_mem.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * iserdes_mem.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | //`define IVERILOG // uncomment just to chenck syntax (by the editor) in the corresponding branch 23 | module iserdes_mem # 24 | ( 25 | parameter DYN_CLKDIV_INV_EN="FALSE", 26 | parameter IOBDELAY = "IFD" // "NONE", "IBUF", "IFD", "BOTH" 27 | ) ( 28 | input iclk, // source-synchronous clock 29 | input oclk, // system clock, phase should allow iclk-to-oclk jitter with setup/hold margin 30 | input oclk_div, // oclk divided by 2, front aligned 31 | input inv_clk_div, // invert oclk_div (this clock is shared between iserdes and oserdes 32 | input rst, // reset 33 | input d_direct, // direct input from IOB, normally not used, controlled by IOBDELAY parameter (set to "NONE") 34 | input ddly, // serial input from idelay 35 | output [3:0] dout 36 | ); 37 | 38 | `ifndef IVERILOG // Not using simulator - instantiate actual ISERDESE2 (can not be simulated because of encrypted ) 39 | ISERDESE2 #( 40 | .DATA_RATE ("DDR"), 41 | .DATA_WIDTH (4), 42 | .DYN_CLKDIV_INV_EN (DYN_CLKDIV_INV_EN), 43 | .DYN_CLK_INV_EN ("FALSE"), 44 | .INIT_Q1 (1'b0), 45 | .INIT_Q2 (1'b0), 46 | .INIT_Q3 (1'b0), 47 | .INIT_Q4 (1'b0), 48 | .INTERFACE_TYPE ("MEMORY"), 49 | .NUM_CE (1), 50 | .IOBDELAY (IOBDELAY), 51 | 52 | .OFB_USED ("FALSE"), 53 | .SERDES_MODE ("MASTER"), 54 | .SRVAL_Q1 (1'b0), 55 | .SRVAL_Q2 (1'b0), 56 | .SRVAL_Q3 (1'b0), 57 | .SRVAL_Q4 (1'b0) 58 | ) 59 | iserdes_i 60 | ( 61 | .O (), 62 | .Q1 (dout[3]), 63 | .Q2 (dout[2]), 64 | .Q3 (dout[1]), 65 | .Q4 (dout[0]), 66 | .Q5 (), 67 | .Q6 (), 68 | .Q7 (), 69 | .Q8 (), 70 | .SHIFTOUT1 (), 71 | .SHIFTOUT2 (), 72 | .BITSLIP (1'b0), 73 | .CE1 (1'b1), 74 | .CE2 (1'b1), 75 | .CLK (iclk), 76 | .CLKB (!iclk), 77 | .CLKDIVP (), // used with phasers, source-sync 78 | .CLKDIV (oclk_div), 79 | .DDLY (ddly), 80 | .D (d_direct), // direct connection to IOB bypassing idelay 81 | .DYNCLKDIVSEL (inv_clk_div), 82 | .DYNCLKSEL (1'b0), 83 | .OCLK (oclk), 84 | .OCLKB (!oclk), 85 | .OFB (), 86 | .RST (rst), 87 | .SHIFTIN1 (1'b0), 88 | .SHIFTIN2 (1'b0) 89 | ); 90 | `else // Simulating, use Virtex 6 module that does not have encrypted functionality 91 | ISERDESE1 #( 92 | .DATA_RATE ("DDR"), 93 | .DATA_WIDTH (4), 94 | .DYN_CLKDIV_INV_EN (DYN_CLKDIV_INV_EN), 95 | .DYN_CLK_INV_EN ("FALSE"), 96 | .INIT_Q1 (1'b0), 97 | .INIT_Q2 (1'b0), 98 | .INIT_Q3 (1'b0), 99 | .INIT_Q4 (1'b0), 100 | .INTERFACE_TYPE ("MEMORY"), 101 | .NUM_CE (1), 102 | .IOBDELAY (IOBDELAY), 103 | .OFB_USED ("FALSE"), 104 | .SERDES_MODE ("MASTER"), 105 | .SRVAL_Q1 (1'b0), 106 | .SRVAL_Q2 (1'b0), 107 | .SRVAL_Q3 (1'b0), 108 | .SRVAL_Q4 (1'b0) 109 | ) 110 | iserdes_i 111 | ( 112 | .O (), 113 | .Q1 (dout[3]), 114 | .Q2 (dout[2]), 115 | .Q3 (dout[1]), 116 | .Q4 (dout[0]), 117 | .Q5 (), 118 | .Q6 (), 119 | .SHIFTOUT1 (), 120 | .SHIFTOUT2 (), 121 | 122 | .BITSLIP (1'b0), 123 | .CE1 (1'b1), 124 | .CE2 (1'b1), 125 | .CLK (iclk), 126 | .CLKB (!iclk), 127 | .CLKDIV (oclk_div), 128 | .DDLY (ddly), 129 | .D (d_direct), // direct connection to IOB bypassing idelay 130 | .DYNCLKDIVSEL (inv_clk_div), 131 | .DYNCLKSEL (1'b0), 132 | .OCLK (oclk), 133 | .OFB (), 134 | .RST (rst), 135 | .SHIFTIN1 (1'b0), 136 | .SHIFTIN2 (1'b0) 137 | ); 138 | `endif 139 | endmodule 140 | 141 | -------------------------------------------------------------------------------- /wrap/obuf.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: obuf 3 | * Date:2014-05-27 4 | * Author: Andrey Filippov 5 | * Description: Wrapper for OBUF primitive 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * obuf.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * obuf.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module obuf # ( 24 | parameter CAPACITANCE="DONT_CARE", 25 | parameter DRIVE = 12, 26 | parameter IOSTANDARD = "DEFAULT", 27 | parameter SLEW = "SLOW" 28 | ) ( 29 | output O, 30 | input I 31 | ); 32 | OBUF #( 33 | .CAPACITANCE(CAPACITANCE), 34 | .DRIVE(DRIVE), 35 | .IOSTANDARD(IOSTANDARD), 36 | .SLEW(SLEW) 37 | ) OBUF_i ( 38 | .O(O), // output 39 | .I(I) // input 40 | ); 41 | endmodule 42 | 43 | -------------------------------------------------------------------------------- /wrap/oddr.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: oddr 3 | * Date:2014-05-13 4 | * Author: Andrey Filippov 5 | * Description: ODDR wrapper 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * oddr.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * oddr.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module oddr#( 24 | parameter DDR_CLK_EDGE = "OPPOSITE_EDGE", 25 | parameter INIT = 1'b0, 26 | parameter SRTYPE = "SYNC" 27 | )( 28 | input clk, 29 | input ce, 30 | input rst, 31 | input set, 32 | input [1:0] din, 33 | output dq 34 | ); 35 | /* Instance template for module ODDR */ 36 | ODDR #( 37 | .DDR_CLK_EDGE(DDR_CLK_EDGE), 38 | .INIT(INIT), 39 | .SRTYPE(SRTYPE) 40 | ) ODDR_i ( 41 | .Q(dq), // output 42 | .C(clk), // input 43 | .CE(ce), // input 44 | .D1(din[0]), // input 45 | .D2(din[1]), // input 46 | .R(rst), // input 47 | .S(set) // input 48 | ); 49 | 50 | 51 | endmodule 52 | 53 | -------------------------------------------------------------------------------- /wrap/oddr_ds.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: oddr_ds 3 | * Date:2014-05-13 4 | * Author: Andrey Filippov 5 | * Description: wrapper for ODDR+OBUFDS 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * oddr_ds.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * oddr_ds.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module oddr_ds # ( 24 | parameter CAPACITANCE = "DONT_CARE", 25 | parameter IOSTANDARD = "DIFF_SSTL15", 26 | parameter SLEW = "SLOW", 27 | parameter DDR_CLK_EDGE = "OPPOSITE_EDGE", 28 | parameter INIT = 1'b0, 29 | parameter SRTYPE = "SYNC" 30 | )( 31 | input clk, 32 | input ce, 33 | input rst, 34 | input set, 35 | input [1:0] din, 36 | input tin, // tristate control 37 | output dq, 38 | output ndq 39 | ); 40 | wire idq; 41 | /* Instance template for module ODDR */ 42 | ODDR #( 43 | .DDR_CLK_EDGE(DDR_CLK_EDGE), 44 | .INIT(INIT), 45 | .SRTYPE(SRTYPE) 46 | ) ODDR_i ( 47 | .Q(idq), // output 48 | .C(clk), // input 49 | .CE(ce), // input 50 | .D1(din[0]), // input 51 | .D2(din[1]), // input 52 | .R(rst), // input 53 | .S(set) // input 54 | ); 55 | 56 | /* Instance template for module OBUFDS */ 57 | /* 58 | OBUFDS #( 59 | .CAPACITANCE(CAPACITANCE), 60 | .IOSTANDARD(IOSTANDARD), 61 | .SLEW(SLEW) 62 | ) OBUFDS_i ( 63 | .O(dq), // output 64 | .OB(ndq), // output 65 | .I(idq) // input 66 | ); 67 | */ 68 | /* Instance template for module OBUFTDS */ 69 | OBUFTDS #( 70 | .CAPACITANCE (CAPACITANCE), 71 | .IOSTANDARD (IOSTANDARD), 72 | .SLEW (SLEW) 73 | ) OBUFDS_i ( 74 | .O (dq), // output 75 | .OB (ndq), // output 76 | .I (idq), // input 77 | // .T (tin || rst) // input 78 | .T (tin) // input 79 | ); 80 | 81 | endmodule 82 | 83 | -------------------------------------------------------------------------------- /wrap/odelay_fine_pipe.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: odelay_fine_pipe 3 | * Date:2014-04-25 4 | * Author: Andrey Filippov 5 | * Description: ODELAYE2_FINEDELAY wrapper with fine control pipelined 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * idelay_fine_pipe.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * odelay_fine_pipe.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module odelay_fine_pipe 24 | //SuppressWarnings VEditor - IODELAY_GRP used in (* *) construnt 25 | # ( parameter IODELAY_GRP = "IODELAY_MEMORY", 26 | parameter [7:0] DELAY_VALUE = 0, 27 | parameter real REFCLK_FREQUENCY = 200.0, 28 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 29 | ) ( 30 | input clk, 31 | input rst, 32 | input set, 33 | input ld, 34 | input [7:0] delay, 35 | input data_in, 36 | output data_out 37 | ); 38 | reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0]; 39 | always @ (posedge clk or posedge rst) begin 40 | if (rst) fdly_pre <= DELAY_VALUE[2:0]; 41 | else if (ld) fdly_pre <= delay[2:0]; 42 | if (rst) fdly <= DELAY_VALUE[2:0]; 43 | else if (set) fdly <= fdly_pre; 44 | end 45 | `ifdef IVERILOG 46 | always @ (fdly_pre) begin 47 | if (fdly_pre > 3'h4) $display ("ERROR: fine odelay value should be <5, specified %d @ %t", fdly_pre,$time); 48 | end 49 | `endif 50 | 51 | (* IODELAY_GROUP = IODELAY_GRP *) ODELAYE2_FINEDELAY 52 | #( 53 | .CINVCTRL_SEL("FALSE"), 54 | .DELAY_SRC("ODATAIN"), 55 | .FINEDELAY("ADD_DLY"), 56 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), 57 | .ODELAY_TYPE("VAR_LOAD_PIPE"), 58 | .ODELAY_VALUE(DELAY_VALUE>>3), 59 | // .IS_C_INVERTED(1'b0), // ISE does not have this parameter 60 | // .IS_ODATAIN_INVERTED(1'b0), // ISE does not have this parameter 61 | .PIPE_SEL("TRUE"), 62 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 63 | .SIGNAL_PATTERN("DATA") 64 | ) 65 | odelay2_finedelay_i( 66 | .CNTVALUEOUT(), 67 | .DATAOUT(data_out), 68 | .C(clk), 69 | .CE(1'b0), 70 | .CINVCTRL(1'b0), 71 | .CNTVALUEIN(delay[7:3]), 72 | .CLKIN(1'b0), 73 | .ODATAIN(data_in), 74 | .OFDLY(fdly), 75 | .INC(1'b0), 76 | .LD(set), 77 | .LDPIPEEN(ld), 78 | .REGRST(rst) 79 | ); 80 | 81 | endmodule 82 | 83 | -------------------------------------------------------------------------------- /wrap/odelay_pipe.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: odelay_pipe 3 | * Date:2014-04-25 4 | * Author: Andrey Filippov 5 | * Description: ODELAYE2 wrapper pipelined 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * idelay_fine_pipe.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * odelay_pipe.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module odelay_pipe 24 | //SuppressWarnings VEditor - IODELAY_GRP used in (* *) construnt 25 | # ( parameter IODELAY_GRP = "IODELAY_MEMORY", 26 | parameter integer DELAY_VALUE = 0, 27 | parameter real REFCLK_FREQUENCY = 200.0, 28 | parameter HIGH_PERFORMANCE_MODE = "FALSE" 29 | ) ( 30 | input clk, 31 | input rst, 32 | input set, 33 | input ld, 34 | input [4:0] delay, 35 | input data_in, 36 | output data_out 37 | ); 38 | 39 | (* IODELAY_GROUP = IODELAY_GRP *) ODELAYE2 40 | #( 41 | .CINVCTRL_SEL("FALSE"), 42 | .DELAY_SRC("ODATAIN"), 43 | // .FINEDELAY("ADD_DLY"), 44 | .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), 45 | .ODELAY_TYPE("VAR_LOAD_PIPE"), 46 | .ODELAY_VALUE(DELAY_VALUE), 47 | .IS_C_INVERTED(1'b0), 48 | .IS_ODATAIN_INVERTED(1'b0), 49 | .PIPE_SEL("TRUE"), 50 | .REFCLK_FREQUENCY(REFCLK_FREQUENCY), 51 | .SIGNAL_PATTERN("DATA") 52 | ) 53 | odelay2_finedelay_i( 54 | .CNTVALUEOUT(), 55 | .DATAOUT(data_out), 56 | .C(clk), 57 | .CE(1'b0), 58 | .CINVCTRL(1'b0), 59 | .CNTVALUEIN(delay[4:0]), 60 | .CLKIN(1'b0), 61 | .ODATAIN(data_in), 62 | .INC(1'b0), 63 | .LD(set), 64 | .LDPIPEEN(ld), 65 | .REGRST(rst) 66 | ); 67 | 68 | endmodule 69 | 70 | -------------------------------------------------------------------------------- /wrap/oserdes_mem.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: oserdes_mem 3 | * Date:2014-04-26 4 | * Author: Andrey Filippov 5 | * Description: OSERDESE2/OSERDESE1 wrapper to use for DDR3 memory w/o phasers 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * oserdes_mem.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * oserdes_mem.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | //`define IVERILOG // uncomment just to chenck syntax (by the editor) in the corresponding branch 23 | module oserdes_mem #( 24 | parameter MODE_DDR="TRUE" 25 | ) ( 26 | input clk, // serial output clock 27 | input clk_div, // oclk divided by 2, front aligned 28 | input rst, // reset 29 | input [((MODE_DDR=="TRUE")?3:1):0] din, // parallel data in 30 | // input [((MODE_DDR=="TRUE")?3:1):0] tin, // parallel tri-state in 31 | input [((MODE_DDR=="TRUE")?3:0):0] tin, // parallel tri-state in 32 | output dout_dly, // data out to be connected to odelay input 33 | output dout_iob, // data out to be connected directly to the output buffer 34 | output tout_dly, // tristate out to be connected to odelay input 35 | output tout_iob // tristate out to be connected directly to the tristate control of the output buffer 36 | ); 37 | //localparam integer MODE_DDR_BIN=(MODE_DDR=="TRUE")?1:0; 38 | localparam DATA_RATE= (MODE_DDR=="TRUE")?"DDR":"SDR"; 39 | localparam integer DATA_WIDTH= (MODE_DDR=="TRUE")?4:2; 40 | localparam integer DATA_WIDTH_TRI= (MODE_DDR=="TRUE")?4:1; 41 | //localparam integer DDR3_DATA= (MODE_DDR=="TRUE")?1:0; 42 | /* 43 | Serialized data will go through odelay elements (with fine delay adjustment), tristate output will 44 | go directly. Luckily the active time for DQ/DQS may be extended (there is at least 1 full clock period 45 | between READ and WRITE DQS active (more for DQ), so extending write preamble and postabmble by 1/2 period 46 | seems to be OK. 47 | */ 48 | 49 | `ifndef IVERILOG // Not using simulator - instantiate actual ISERDESE2 (can not be simulated because of encrypted ) 50 | OSERDESE2 #( 51 | .DATA_RATE_OQ (DATA_RATE), 52 | .DATA_RATE_TQ (DATA_RATE), 53 | .DATA_WIDTH (DATA_WIDTH), 54 | .INIT_OQ (1'b1), 55 | .INIT_TQ (1'b1), 56 | .SERDES_MODE ("MASTER"), 57 | .SRVAL_OQ (1'b1), 58 | .SRVAL_TQ (1'b1), 59 | .TRISTATE_WIDTH (DATA_WIDTH_TRI), 60 | .TBYTE_CTL ("FALSE"), 61 | .TBYTE_SRC ("FALSE") 62 | ) oserdes_i ( 63 | .OFB (dout_dly), 64 | .OQ (dout_iob), 65 | .SHIFTOUT1 (), 66 | .SHIFTOUT2 (), 67 | .TFB (tout_dly), 68 | .TQ (tout_iob), 69 | .CLK (clk), 70 | .CLKDIV (clk_div), 71 | .D1 (din[0]), 72 | .D2 (din[1]), 73 | .D3 ((MODE_DDR=="TRUE")?din[2]:1'b0), 74 | .D4 ((MODE_DDR=="TRUE")?din[3]:1'b0), 75 | .D5 (), 76 | .D6 (), 77 | .D7 (), 78 | .D8 (), 79 | .OCE (1'b1), 80 | .RST (rst), 81 | .SHIFTIN1 (), 82 | .SHIFTIN2 (), 83 | .T1 (tin[0]), 84 | .T2 ((MODE_DDR=="TRUE")?tin[1]:1'b0), 85 | .T3 ((MODE_DDR=="TRUE")?tin[2]:1'b0), 86 | .T4 ((MODE_DDR=="TRUE")?tin[3]:1'b0), 87 | .TCE (1'b1), 88 | .TBYTEOUT (), 89 | .TBYTEIN () 90 | ); 91 | `else // Simulating, use Virtex 6 module that does not have encrypted functionality 92 | OSERDESE1 #( 93 | .DATA_RATE_OQ (DATA_RATE), 94 | .DATA_RATE_TQ (DATA_RATE), 95 | .DATA_WIDTH (DATA_WIDTH), 96 | // .DDR3_DATA (DDR3_DATA), //For DDR3 DQ, DQS: 1, Address, ctrl, clock - 0 97 | .INIT_OQ (1'b1), 98 | .INIT_TQ (1'b1), 99 | .INTERFACE_TYPE ("DEFAULT"), //"DEFAULT", "MEMORY_DDR3" 100 | .ODELAY_USED (0), // 1 available only for MEMORY_DDR3 101 | .SERDES_MODE ("MASTER"), 102 | .SRVAL_OQ (1'b1), 103 | .SRVAL_TQ (1'b1), 104 | .TRISTATE_WIDTH (DATA_WIDTH_TRI) 105 | ) oserdes_i ( 106 | .OFB (dout_dly), 107 | .OQ (dout_iob), 108 | .SHIFTOUT1 (), 109 | .SHIFTOUT2 (), 110 | .TFB (tout_dly), 111 | .TQ (tout_iob), 112 | .CLK (clk), 113 | .CLKDIV (clk_div), 114 | .D1 (din[0]), 115 | .D2 (din[1]), 116 | .D3 ((MODE_DDR=="TRUE")?din[2]:1'b0), 117 | .D4 ((MODE_DDR=="TRUE")?din[3]:1'b0), 118 | .D5 (), 119 | .D6 (), 120 | .OCE (1'b1), 121 | .RST (rst), 122 | .SHIFTIN1 (), 123 | .SHIFTIN2 (), 124 | .T1 (tin[0]), 125 | .T2 (tin[1]), 126 | .T3 ((MODE_DDR=="TRUE")?tin[2]:1'b0), 127 | .T4 ((MODE_DDR=="TRUE")?tin[3]:1'b0), 128 | .TCE (1'b1), 129 | // not in OSERDES2E: 130 | .WC (1'b0), 131 | .OCBEXTEND (), 132 | .CLKPERF (1'b0), 133 | .CLKPERFDELAY (1'b0), 134 | .ODV (1'b0) 135 | ); 136 | `endif 137 | endmodule 138 | 139 | -------------------------------------------------------------------------------- /wrap/pll_base.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Module: pll_base 3 | * Date:2014-05-01 4 | * Author: Andrey Filippov 5 | * Description: PLLE2_BASE wrapper 6 | * 7 | * Copyright (c) 2014 Elphel, Inc. 8 | * pll_base.v is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * pll_base.v is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | *******************************************************************************/ 21 | `timescale 1ns/1ps 22 | 23 | module pll_base#( 24 | parameter CLKIN_PERIOD = 0.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps 25 | parameter BANDWIDTH = "OPTIMIZED", // "OPTIMIZED", "HIGH","LOW" 26 | parameter CLKFBOUT_MULT = 1, // integer 1 to 64 . Together with CLKOUT#_DIVIDE and DIVCLK_DIVIDE 27 | parameter CLKFBOUT_PHASE = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000) 28 | parameter CLKOUT0_PHASE = 0.000, // CLOCK0 phase in degrees (3 significant digits, -360.000...+360.000) 29 | parameter CLKOUT1_PHASE = 0.000, // Initial/static fine phase shift, 1/(56*Fvco) actual step 30 | parameter CLKOUT2_PHASE = 0.000, 31 | parameter CLKOUT3_PHASE = 0.000, 32 | parameter CLKOUT4_PHASE = 0.000, 33 | parameter CLKOUT5_PHASE = 0.000, 34 | parameter CLKOUT0_DUTY_CYCLE= 0.5, // CLOCK 0 output duty factor, 3 significant digits 35 | parameter CLKOUT1_DUTY_CYCLE= 0.5, 36 | parameter CLKOUT2_DUTY_CYCLE= 0.5, 37 | parameter CLKOUT3_DUTY_CYCLE= 0.5, 38 | parameter CLKOUT4_DUTY_CYCLE= 0.5, 39 | parameter CLKOUT5_DUTY_CYCLE= 0.5, 40 | parameter CLKOUT0_DIVIDE = 1, // CLK0 outout divide, integer 1..128 41 | parameter CLKOUT1_DIVIDE = 1, // CLK1 outout divide, integer 1..128 (determins a phase step as a fraction of pi/4) 42 | parameter CLKOUT2_DIVIDE = 1, 43 | parameter CLKOUT3_DIVIDE = 1, 44 | parameter CLKOUT4_DIVIDE = 1, 45 | parameter CLKOUT5_DIVIDE = 1, 46 | parameter DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN 47 | parameter REF_JITTER1 = 0.010, // Expectet jitter on CLKIN1 (0.000..0.999) 48 | parameter STARTUP_WAIT = "FALSE" // Delays "DONE" signal until MMCM is locked 49 | ) 50 | ( 51 | input clkin, // General clock input 52 | input clkfbin, // Feedback clock input 53 | input rst, // asynchronous reset input 54 | input pwrdwn, // power down input 55 | output clkout0, // output 0, HPC BUFR/BUFIO capable 56 | output clkout1, // output 1, HPC BUFR/BUFIO capable 57 | output clkout2, // output 2, HPC BUFR/BUFIO capable 58 | output clkout3, // output 3, HPC BUFR/BUFIO capable 59 | output clkout4, // output 4, HPC BUFR/BUFIO not capable 60 | output clkout5, // output 5, HPC BUFR/BUFIO not capable 61 | output clkfbout, // dedicate feedback output 62 | output locked // PLL locked output 63 | ); 64 | PLLE2_BASE #( 65 | .BANDWIDTH (BANDWIDTH), 66 | .CLKFBOUT_MULT (CLKFBOUT_MULT), 67 | .CLKFBOUT_PHASE (CLKFBOUT_PHASE), 68 | .CLKIN1_PERIOD (CLKIN_PERIOD), 69 | .CLKOUT0_DIVIDE (CLKOUT0_DIVIDE), 70 | .CLKOUT0_DUTY_CYCLE (CLKOUT0_DUTY_CYCLE), 71 | .CLKOUT0_PHASE (CLKOUT0_PHASE), 72 | .CLKOUT1_DIVIDE (CLKOUT1_DIVIDE), 73 | .CLKOUT1_DUTY_CYCLE (CLKOUT1_DUTY_CYCLE), 74 | .CLKOUT1_PHASE (CLKOUT1_PHASE), 75 | .CLKOUT2_DIVIDE (CLKOUT2_DIVIDE), 76 | .CLKOUT2_DUTY_CYCLE (CLKOUT2_DUTY_CYCLE), 77 | .CLKOUT2_PHASE (CLKOUT2_PHASE), 78 | .CLKOUT3_DIVIDE (CLKOUT3_DIVIDE), 79 | .CLKOUT3_DUTY_CYCLE (CLKOUT3_DUTY_CYCLE), 80 | .CLKOUT3_PHASE (CLKOUT3_PHASE), 81 | .CLKOUT4_DIVIDE (CLKOUT4_DIVIDE), 82 | .CLKOUT4_DUTY_CYCLE (CLKOUT4_DUTY_CYCLE), 83 | .CLKOUT4_PHASE (CLKOUT4_PHASE), 84 | .CLKOUT5_DIVIDE (CLKOUT5_DIVIDE), 85 | .CLKOUT5_DUTY_CYCLE (CLKOUT5_DUTY_CYCLE), 86 | .CLKOUT5_PHASE (CLKOUT5_PHASE), 87 | .DIVCLK_DIVIDE (DIVCLK_DIVIDE), 88 | .REF_JITTER1 (REF_JITTER1), 89 | .STARTUP_WAIT (STARTUP_WAIT) 90 | ) PLLE2_BASE_i ( 91 | .CLKFBOUT (clkfbout), // output 92 | .CLKOUT0 (clkout0), // output 93 | .CLKOUT1 (clkout1), // output 94 | .CLKOUT2 (clkout2), // output 95 | .CLKOUT3 (clkout3), // output 96 | .CLKOUT4 (clkout4), // output 97 | .CLKOUT5 (clkout5), // output 98 | .LOCKED (locked), // output 99 | .CLKFBIN (clkfbin), // input 100 | .CLKIN1 (clkin), // input 101 | .PWRDWN (pwrdwn), // input 102 | .RST (rst) // input 103 | ); 104 | endmodule 105 | -------------------------------------------------------------------------------- /wrap/ram_1kx32_1kx32.v: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 Elphel, Inc. 3 | * ram_1kx32_1kx32.v is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * ram_1kx32_1kx32.v is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | *******************************************************************************/ 16 | /* 17 | Address/data widths 18 | Connect unused data to 1b0, unused addresses - to 1'b1 19 | 20 | RAMB18E1 in True Dual Port (TDP) Mode - each port individually 21 | +-----------+---------+---------+---------+ 22 | |Data Width | Address | Data | Parity | 23 | +-----------+---------+---------+---------+ 24 | | 1 | A[13:0] | D[0] | --- | 25 | | 2 | A[13:1] | D[1:0] | --- | 26 | | 4 | A[13:2] | D[3:0[ | --- | 27 | | 9 | A[13:3] | D[7:0] | DP[0] | 28 | | 18 | A[13:4] | D[15:0] | DP[1:0] | 29 | +-----------+---------+---------+---------+ 30 | 31 | RAMB18E1 in Simple Dual Port (SDP) Mode 32 | one of the ports (r or w) - 32/36 bits, other - variable 33 | +------------+---------+---------+---------+ 34 | |Data Widths | Address | Data | Parity | 35 | +------------+---------+---------+---------+ 36 | | 32/ 1 | A[13:0] | D[0] | --- | 37 | | 32/ 2 | A[13:1] | D[1:0] | --- | 38 | | 32/ 4 | A[13:2] | D[3:0[ | --- | 39 | | 36/ 9 | A[13:3] | D[7:0] | DP[0] | 40 | | 36/ 18 | A[13:4] | D[15:0] | DP[1:0] | 41 | | 36/ 36 | A[13:5] | D[31:0] | DP[3:0] | 42 | +------------+---------+---------+---------+ 43 | 44 | RAMB36E1 in True Dual Port (TDP) Mode - each port individually 45 | +-----------+---------+---------+---------+ 46 | |Data Width | Address | Data | Parity | 47 | +-----------+---------+---------+---------+ 48 | | 1 | A[14:0] | D[0] | --- | 49 | | 2 | A[14:1] | D[1:0] | --- | 50 | | 4 | A[14:2] | D[3:0[ | --- | 51 | | 9 | A[14:3] | D[7:0] | DP[0] | 52 | | 18 | A[14:4] | D[15:0] | DP[1:0] | 53 | | 36 | A[14:5] | D[31:0] | DP[3:0] | 54 | |1(Cascade) | A[15:0] | D[0] | --- | 55 | +-----------+---------+---------+---------+ 56 | 57 | RAMB36E1 in Simple Dual Port (SDP) Mode 58 | one of the ports (r or w) - 64/72 bits, other - variable 59 | +------------+---------+---------+---------+ 60 | |Data Widths | Address | Data | Parity | 61 | +------------+---------+---------+---------+ 62 | | 64/ 1 | A[14:0] | D[0] | --- | 63 | | 64/ 2 | A[14:1] | D[1:0] | --- | 64 | | 64/ 4 | A[14:2] | D[3:0[ | --- | 65 | | 64/ 9 | A[14:3] | D[7:0] | DP[0] | 66 | | 64/ 18 | A[14:4] | D[15:0] | DP[1:0] | 67 | | 64/ 36 | A[14:5] | D[31:0] | DP[3:0] | 68 | | 64/ 72 | A[14:6] | D[63:0] | DP[7:0] | 69 | +------------+---------+---------+---------+ 70 | */ 71 | module ram_1kx32_1kx32 72 | #( 73 | parameter integer REGISTERS = 0 // 1 - registered output 74 | ) 75 | ( 76 | input rclk, // clock for read port 77 | input [ 9:0] raddr, // read address 78 | input ren, // read port enable 79 | input regen, // output register enable 80 | output [31:0] data_out, // data out 81 | 82 | input wclk, // clock for read port 83 | input [ 9:0] waddr, // write address 84 | input we, // write port enable 85 | input [ 3:0] web, // write byte enable 86 | input [31:0] data_in // data out 87 | ); 88 | RAMB36E1 89 | #( 90 | .RSTREG_PRIORITY_A("RSTREG"), // Valid: "RSTREG" or "REGCE" 91 | .RSTREG_PRIORITY_B("RSTREG"), // Valid: "RSTREG" or "REGCE" 92 | .DOA_REG(REGISTERS), // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36) 93 | .DOB_REG(REGISTERS), // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36) 94 | .RAM_EXTENSION_A("NONE"), // Cascading, valid: "NONE","UPPER", LOWER" 95 | .RAM_EXTENSION_B("NONE"), // Cascading, valid: "NONE","UPPER", LOWER" 96 | .READ_WIDTH_A(36), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) 97 | .READ_WIDTH_B(0), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) 98 | .WRITE_WIDTH_A(0), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) 99 | .WRITE_WIDTH_B(36), // Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used) 100 | .RAM_MODE("TDP"), // Valid "TDP" (true dual-port) and "SDP" - simple dual-port 101 | .WRITE_MODE_A("WRITE_FIRST"), // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE" 102 | .WRITE_MODE_B("WRITE_FIRST"), // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE" 103 | .RDADDR_COLLISION_HWCONFIG("DELAYED_WRITE"),// Valid: "DELAYED_WRITE","PERFORMANCE" (no access to the same page) 104 | .SIM_COLLISION_CHECK("ALL"), // Valid: "ALL", "GENERATE_X_ONLY", "NONE", and "WARNING_ONLY" 105 | .INIT_FILE("NONE"), // "NONE" or filename with initialization data 106 | .SIM_DEVICE("7SERIES"), // Simulation device family - "VIRTEX6", "VIRTEX5" and "7_SERIES" // "7SERIES" 107 | 108 | .EN_ECC_READ("FALSE"), // Valid:"FALSE","TRUE" (ECC decoder circuitry) 109 | .EN_ECC_WRITE("FALSE") // Valid:"FALSE","TRUE" (ECC decoder circuitry) 110 | // .INIT_A(36'h0), // Output latches initialization data 111 | // .INIT_B(36'h0), // Output latches initialization data 112 | // .SRVAL_A(36'h0), // Output latches initialization data (copied at when RSTRAM/RSTREG activated) 113 | // .SRVAL_B(36'h0) // Output latches initialization data (copied at when RSTRAM/RSTREG activated) 114 | /* 115 | parameter IS_CLKARDCLK_INVERTED = 1'b0; 116 | parameter IS_CLKBWRCLK_INVERTED = 1'b0; 117 | parameter IS_ENARDEN_INVERTED = 1'b0; 118 | parameter IS_ENBWREN_INVERTED = 1'b0; 119 | parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; 120 | parameter IS_RSTRAMB_INVERTED = 1'b0; 121 | parameter IS_RSTREGARSTREG_INVERTED = 1'b0; 122 | parameter IS_RSTREGB_INVERTED = 1'b0; 123 | */ 124 | 125 | ) RAMB36E1_i 126 | ( 127 | // Port A (Read port in SDP mode): 128 | .DOADO(data_out[31:0]), // Port A data/LSB data[31:0], output 129 | .DOPADOP(), // Port A parity/LSB parity[3:0], output 130 | .DIADI(32'h0), // Port A data/LSB data[31:0], input 131 | .DIPADIP(4'h0), // Port A parity/LSB parity[3:0], input 132 | .ADDRARDADDR({1'b1,raddr[9:0],5'b11111}), // Port A (read port in SDP) address [15:0]. used from [14] down, unused should be high, input 133 | .CLKARDCLK(rclk), // Port A (read port in SDP) clock, input 134 | .ENARDEN(ren), // Port A (read port in SDP) Enable, input 135 | .REGCEAREGCE(regen), // Port A (read port in SDP) register enable, input 136 | .RSTRAMARSTRAM(1'b0), // Port A (read port in SDP) set/reset, input 137 | .RSTREGARSTREG(1'b0), // Port A (read port in SDP) register set/reset, input 138 | .WEA(4'b0), // Port A (read port in SDP) Write Enable[3:0], input 139 | // Port B 140 | .DOBDO(), // Port B data/MSB data[31:0], output 141 | .DOPBDOP(), // Port B parity/MSB parity[3:0], output 142 | .DIBDI(data_in[31:0]), // Port B data/MSB data[31:0], input 143 | .DIPBDIP(4'b0), // Port B parity/MSB parity[3:0], input 144 | .ADDRBWRADDR({1'b1,waddr[9:0],5'b11111}), // Port B (write port in SDP) address [15:0]. used from [14] down, unused should be high, input 145 | .CLKBWRCLK(wclk), // Port B (write port in SDP) clock, input 146 | .ENBWREN(we), // Port B (write port in SDP) Enable, input 147 | .REGCEB(1'b0), // Port B (write port in SDP) register enable, input 148 | .RSTRAMB(1'b0), // Port B (write port in SDP) set/reset, input 149 | .RSTREGB(1'b0), // Port B (write port in SDP) register set/reset, input 150 | .WEBWE({4'b0,web[3:0]}), // Port B (write port in SDP) Write Enable[7:0], input 151 | // Error correction circuitry 152 | .SBITERR(), // Single bit error status, output 153 | .DBITERR(), // Double bit error status, output 154 | .ECCPARITY(), // Genearted error correction parity [7:0], output 155 | .RDADDRECC(), // ECC read address[8:0], output 156 | .INJECTSBITERR(1'b0),// inject a single-bit error, input 157 | .INJECTDBITERR(1'b0),// inject a double-bit error, input 158 | // Cascade signals to create 64Kx1 159 | .CASCADEOUTA(), // A-port cascade, output 160 | .CASCADEOUTB(), // B-port cascade, output 161 | .CASCADEINA(1'b0), // A-port cascade, input 162 | .CASCADEINB(1'b0) // B-port cascade, input 163 | ); 164 | 165 | endmodule 166 | 167 | --------------------------------------------------------------------------------