├── .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 |
--------------------------------------------------------------------------------