x393_tasks_mcntrl_timing.vh 9.59 KB
Newer Older
1 2 3 4 5 6
/*!
 * @file x393_tasks_mcntrl_timing.vh
 * @date 2015-02-07  
 * @author Andrey Filippov     
 *
 * @brief Simulation tasks for programming I/O delays and other timing
7 8
 * parameters in the memory controller
 *
9 10 11 12
 * @copyright Copyright (c) 2015 Elphel, Inc.
 *
 * <b>License:</b>
 *
13 14 15 16 17 18 19 20 21 22 23 24
 * x393_tasks_mcntrl_timing.vh is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * x393_tasks_mcntrl_timing.vh is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
25 26 27 28 29 30
 *
 * Additional permission under GNU GPL version 3 section 7:
 * If you modify this Program, or any covered work, by linking or combining it
 * with independent modules provided by the FPGA vendor only (this permission
 * does not extend to any 3-rd party modules, "soft cores" or macros) under
 * different license terms solely for the purpose of generating binary "bitstream"
31
 * files and/or simulating the code, the copyright holders of this Program give
32 33
 * you the right to distribute the covered work without those independent modules
 * as long as the source code for them is available from the FPGA vendor free of
Andrey Filippov's avatar
Andrey Filippov committed
34
 * charge, and there is no dependence on any encrypted modules for simulating of
35 36 37
 * the combined code. This permission applies to you if the distributed code
 * contains all the components and scripts required to completely simulate it
 * with at least one of the Free Software programs.
38
 */
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

      task axi_set_same_delays;  //SuppressThisWarning VEditor : may be unused
        input [7:0] dq_idelay;
        input [7:0] dq_odelay;
        input [7:0] dqs_idelay;
        input [7:0] dqs_odelay;
        input [7:0] dm_odelay;
        input [7:0] cmda_odelay;
        begin
           $display("SET DELAYS(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x) @ %t",
           dq_idelay,dq_odelay,dqs_idelay,dqs_odelay,dm_odelay,cmda_odelay,$time);
            axi_set_dq_idelay(dq_idelay);
            axi_set_dq_odelay(dq_odelay);
            axi_set_dqs_idelay(dqs_idelay);
            axi_set_dqs_odelay(dqs_odelay);
            axi_set_dm_odelay(dm_odelay);
            axi_set_cmda_odelay(cmda_odelay);
        end
    endtask

    task axi_set_dqs_odelay_nominal; //SuppressThisWarning VEditor : may be unused
     begin
61 62 63 64
        $display("axi_set_dqs_odelay_nominal(0x%x,0x%x) @ %t",
        (DLY_LANE0_ODELAY >> (8<<3)) & 32'hff,
        (DLY_LANE1_ODELAY >> (8<<3)) & 32'hff,
        $time);
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
//        axi_set_dqs_idelay(
        write_contol_register(LD_DLY_LANE0_ODELAY + 8,      (DLY_LANE0_ODELAY >> (8<<3)) & 32'hff);
        write_contol_register(LD_DLY_LANE1_ODELAY + 8,      (DLY_LANE1_ODELAY >> (8<<3)) & 32'hff);
        write_contol_register(DLY_SET,0);
     end
    endtask

    task axi_set_dqs_idelay_nominal;  //SuppressThisWarning VEditor : may be unused
     begin
//        axi_set_dqs_idelay(
        write_contol_register(LD_DLY_LANE0_IDELAY + 8,      (DLY_LANE0_IDELAY >> (8<<3)) & 32'hff);
        write_contol_register(LD_DLY_LANE1_IDELAY + 8,      (DLY_LANE1_IDELAY >> (8<<3)) & 32'hff);
        write_contol_register(DLY_SET,0);
     end
    endtask
    
    task axi_set_dqs_idelay_wlv;  //SuppressThisWarning VEditor : may be unused
     begin
        write_contol_register(LD_DLY_LANE0_IDELAY + 8,      DLY_LANE0_DQS_WLV_IDELAY);
        write_contol_register(LD_DLY_LANE1_IDELAY + 8,      DLY_LANE1_DQS_WLV_IDELAY);
        write_contol_register(DLY_SET,0);
     end
    endtask

    task axi_set_delays; // set all individual delays
     integer i;
     begin
92 93
         $display("axi_set_delays @ %t",$time);
     
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
        for (i=0;i<10;i=i+1) begin
            write_contol_register(LD_DLY_LANE0_ODELAY + i,     (DLY_LANE0_ODELAY >> (i<<3)) & 32'hff);
        end
        for (i=0;i<9;i=i+1) begin
            write_contol_register(LD_DLY_LANE0_IDELAY + i,      (DLY_LANE0_IDELAY >> (i<<3)) & 32'hff);
        end
        for (i=0;i<10;i=i+1) begin
            write_contol_register(LD_DLY_LANE1_ODELAY + i,      (DLY_LANE1_ODELAY >> (i<<3)) & 32'hff);
        end
        for (i=0;i<9;i=i+1) begin
            write_contol_register(LD_DLY_LANE1_IDELAY + i,      (DLY_LANE1_IDELAY >> (i<<3)) & 32'hff);
        end
        for (i=0;i<32;i=i+1) begin
            write_contol_register(LD_DLY_CMDA + i,      (DLY_CMDA >> (i<<3)) & 32'hff);
        end
//        write_contol_register(DLY_SET,0);
        axi_set_phase(DLY_PHASE); // also sets all delays
     end
    endtask

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    task axi_get_delays; // set all individual delays
     integer i;
     begin
         $display("axi_get_delays @ %t",$time);
     
        for (i=0;i<10;i=i+1) begin
            read_contol_register(LD_DLY_LANE0_ODELAY + i);
        end
        for (i=0;i<9;i=i+1) begin
            read_contol_register(LD_DLY_LANE0_IDELAY + i);
        end
        for (i=0;i<10;i=i+1) begin
            read_contol_register(LD_DLY_LANE1_ODELAY + i);
        end
        for (i=0;i<9;i=i+1) begin
            read_contol_register(LD_DLY_LANE1_IDELAY + i);
        end
        for (i=0;i<32;i=i+1) begin
            read_contol_register(LD_DLY_CMDA + i);
        end
        read_contol_register(LD_DLY_PHASE);
     end
    endtask

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

    task axi_set_dq_idelay; // sets same delay to all dq idelay
        input [7:0] delay;
        begin
           $display("SET DQ IDELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_LANE0_IDELAY, 8, delay);
           axi_set_multiple_delays(LD_DLY_LANE1_IDELAY, 8, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask

    task axi_set_dq_odelay;
        input [7:0] delay;
        begin
           $display("SET DQ ODELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_LANE0_ODELAY, 8, delay);
           axi_set_multiple_delays(LD_DLY_LANE1_ODELAY, 8, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask

    task axi_set_dqs_idelay;
        input [7:0] delay;
        begin
           $display("SET DQS IDELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_LANE0_IDELAY + 8, 1, delay);
           axi_set_multiple_delays(LD_DLY_LANE1_IDELAY + 8, 1, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask

    task axi_set_dqs_odelay;
        input [7:0] delay;
        begin
           $display("SET DQS ODELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_LANE0_ODELAY + 8, 1, delay);
           axi_set_multiple_delays(LD_DLY_LANE1_ODELAY + 8, 1, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask

    task axi_set_dm_odelay;
        input [7:0] delay;
        begin
           $display("SET DQM IDELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_LANE0_ODELAY + 9, 1, delay);
           axi_set_multiple_delays(LD_DLY_LANE1_ODELAY + 9, 1, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask

    task axi_set_cmda_odelay;
        input [7:0] delay;
        begin
           $display("SET COMMAND and ADDRESS ODELAY=0x%x @ %t",delay,$time);
           axi_set_multiple_delays(LD_DLY_CMDA, 32, delay);
           write_contol_register(DLY_SET,0); // set all delays
        end
    endtask


    task axi_set_multiple_delays;
        input [29:0] reg_addr;
        input integer number;
        input [7:0]  delay;
        integer i;
        begin
           for (i=0;i<number;i=i+1) begin
                write_contol_register(reg_addr + i, {24'b0,delay}); // control regiter address
           end
        end
    endtask

    task axi_set_phase;
        input [PHASE_WIDTH-1:0] phase;
213
        reg   [PHASE_WIDTH-1:0] inverted_phase;
214
        begin
215 216 217 218 219 220 221 222 223 224
            if (CLKFBOUT_USE_FINE_PS) begin
                inverted_phase = -phase;
                $display("SET CLOCK INVERTED PHASE (0x%x) to 0x%x @ %t",phase,inverted_phase,$time);
                write_contol_register(LD_DLY_PHASE, {{(32-PHASE_WIDTH){1'b0}},inverted_phase}); // control regiter address
                target_phase <= inverted_phase;
            end else begin
                $display("SET CLOCK PHASE to 0x%x @ %t",phase,$time);
                write_contol_register(LD_DLY_PHASE, {{(32-PHASE_WIDTH){1'b0}},phase}); // control regiter address
                target_phase <= phase;
            end
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
            write_contol_register(DLY_SET,0);
        end
    endtask
 
     task axi_set_wbuf_delay;
        input [3:0] delay;
        begin
            $display("SET WBUF DELAY to 0x%x @ %t",delay,$time);
            write_contol_register(MCONTR_PHY_16BIT_ADDR+MCONTR_PHY_16BIT_WBUF_DELAY, {28'h0, delay});
        end
    endtask
 
 
// set dq /dqs tristate on/off patterns
    task axi_set_tristate_patterns;
        begin
            $display("SET TRISTATE PATTERNS @ %t",$time);    
            write_contol_register(MCONTR_PHY_16BIT_ADDR +MCONTR_PHY_16BIT_PATTERNS_TRI,
                {16'h0, DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
        end
    endtask

 task axi_set_dqs_dqm_patterns;
        begin
            $display("SET DQS+DQM PATTERNS @ %t",$time);    
 // set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)        
            write_contol_register(MCONTR_PHY_16BIT_ADDR + MCONTR_PHY_16BIT_PATTERNS,
                32'h0055);
        end
 endtask