OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [altera_ddr_ctrl/] [altera_ddr_phy_alt_mem_phy.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
//
2
 
3
`default_nettype none
4
 
5
`ifdef ALT_MEM_PHY_DEFINES
6
`else
7
`include "alt_mem_phy_defines.v"
8
`endif
9
 
10
//
11
(* altera_attribute = "-name MESSAGE_DISABLE 14130" *) module altera_ddr_phy_alt_mem_phy (
12
                        //Clock and reset inputs:
13
                        pll_ref_clk,
14
                        global_reset_n,
15
                        soft_reset_n,
16
 
17
                        // Used to indicate PLL loss of lock for system reset management:
18
                        reset_request_n,
19
 
20
                        // Clock and reset for the controller interface:
21
                        ctl_clk,
22
                        ctl_reset_n,
23
 
24
                        // Write data interface:
25
                        ctl_dqs_burst,
26
                        ctl_wdata_valid,
27
                        ctl_wdata,
28
                        ctl_dm,
29
                        ctl_wlat,
30
 
31
                        // Address and command interface:
32
                        ctl_addr,
33
                        ctl_ba,
34
                        ctl_cas_n,
35
                        ctl_cke,
36
                        ctl_cs_n,
37
                        ctl_odt,
38
                        ctl_ras_n,
39
                        ctl_we_n,
40
                        ctl_rst_n,
41
                        ctl_mem_clk_disable,
42
 
43
                        // Read data interface:
44
                        ctl_doing_rd,
45
                        ctl_rdata,
46
                        ctl_rdata_valid,
47
                        ctl_rlat,
48
 
49
                        //re-calibration request & configuration:
50
                        ctl_cal_req,
51
                        ctl_cal_byte_lane_sel_n,
52
 
53
                        //Calibration status interface:
54
                        ctl_cal_success,
55
                        ctl_cal_fail,
56
 
57
                        //ports to memory device(s):
58
                        mem_addr,
59
                        mem_ba,
60
                        mem_cas_n,
61
                        mem_cke,
62
                        mem_cs_n,
63
                        mem_dm,
64
                        mem_odt,
65
                        mem_ras_n,
66
                        mem_we_n,
67
                        mem_clk,
68
                        mem_clk_n,
69
                        mem_reset_n,
70
 
71
                        // Bidirectional Memory interface signals:
72
                        mem_dq,
73
                        mem_dqs,
74
                        mem_dqs_n,
75
 
76
                        // Auxiliary clocks. Some systems may need these for debugging
77
                        // purposes, or for full-rate to half-rate bridge interfaces
78
                        aux_half_rate_clk,
79
                        aux_full_rate_clk,
80
 
81
                        // Debug interface:- ALTERA USE ONLY
82
                        dbg_clk,
83
                        dbg_reset_n,
84
                        dbg_addr,
85
                        dbg_wr,
86
                        dbg_rd,
87
                        dbg_cs,
88
                        dbg_wr_data,
89
                        dbg_rd_data,
90
                        dbg_waitrequest
91
 
92
                      );
93
 
94
 
95
// Default parameter values :
96
 
97
parameter FAMILY                          =     "CYCLONEIII";
98
parameter MEM_IF_MEMTYPE                  =           "DDR2";
99
parameter LEVELLING                       =                0; // RFU
100
parameter SPEED_GRADE                     =             "C6";
101
parameter DLL_DELAY_BUFFER_MODE           =           "HIGH";
102
parameter DLL_DELAY_CHAIN_LENGTH          =                8;
103
parameter DQS_DELAY_CTL_WIDTH             =                6;
104
parameter DQS_OUT_MODE                    =   "DELAY_CHAIN2";
105
parameter DQS_PHASE                       =             9000;
106
parameter DQS_PHASE_SETTING               =                2;
107
parameter DWIDTH_RATIO                    =                4;
108
parameter MEM_IF_DWIDTH                   =               64;
109
parameter MEM_IF_ADDR_WIDTH               =               13;
110
parameter MEM_IF_BANKADDR_WIDTH           =                3;
111
parameter MEM_IF_CS_WIDTH                 =                2;
112
parameter MEM_IF_DM_WIDTH                 =                8;
113
parameter MEM_IF_DM_PINS_EN               =                1;
114
parameter MEM_IF_DQ_PER_DQS               =                8;
115
parameter MEM_IF_DQS_WIDTH                =                8;
116
parameter MEM_IF_OCT_EN                   =                0;
117
parameter MEM_IF_CLK_PAIR_COUNT           =                3;
118
parameter MEM_IF_CLK_PS                   =             4000;
119
parameter MEM_IF_CLK_PS_STR               =        "4000 ps";
120
parameter MEM_IF_MR_0                     =                0;
121
parameter MEM_IF_MR_1                     =                0;
122
parameter MEM_IF_MR_2                     =                0;
123
parameter MEM_IF_MR_3                     =                0;
124
parameter MEM_IF_PRESET_RLAT              =                0;
125
parameter PLL_STEPS_PER_CYCLE             =               24;
126
parameter SCAN_CLK_DIVIDE_BY              =                4;
127
parameter REDUCE_SIM_TIME                 =                0;
128
parameter CAPABILITIES                    =                0;
129
parameter TINIT_TCK                       =            40000;
130
parameter TINIT_RST                       =           100000;
131
parameter DBG_A_WIDTH                     =               13;
132
parameter SEQ_STRING_ID                   =       "seq_name";
133
parameter MEM_IF_CS_PER_RANK              =                1;    // duplicates CS, CKE, ODT, sequencer still controls 1 rank, but it is subdivided from controller perspective.
134
parameter MEM_IF_RANKS_PER_SLOT           =                1;    // how ranks are arranged into slot - needed for odt setting in the sequencer
135
parameter MEM_IF_RDV_PER_CHIP             =                0;   // multiple chips, and which gives valid data
136
parameter GENERATE_ADDITIONAL_DBG_RTL     =                0;   // DDR2 sequencer specific
137
parameter CAPTURE_PHASE_OFFSET            =                0;
138
parameter MEM_IF_ADDR_CMD_PHASE           =                0;
139
parameter DLL_EXPORT_IMPORT               =           "NONE";
140
parameter MEM_IF_DQSN_EN                  =                1;
141
 
142
parameter RANK_HAS_ADDR_SWAP              =                0;
143
 
144
//
145
localparam phy_report_prefix              = "altera_ddr_phy_alt_mem_phy (top level) : ";
146
 
147
// function to set the USE_MEM_CLK_FOR_ADDR_CMD_CLK localparam based on MEM_IF_ADDR_CMD_PHASE
148
function integer set_mem_clk_for_ac_clk (input reg [23:0] addr_cmd_phase);
149
    integer return_value;
150
    begin
151
        return_value = 0;
152
        case (addr_cmd_phase)
153
            0, 180       : return_value = 1;
154
            90, 270      : return_value = 0;
155
            default      : begin
156
                               $display(phy_report_prefix, "Illegal value set on MEM_IF_ADDR_CMD_PHASE parameter: ", addr_cmd_phase);
157
                               $stop;
158
                           end
159
        endcase
160
        set_mem_clk_for_ac_clk = return_value;
161
    end
162
endfunction
163
 
164
// function to set the ADDR_CMD_NEGEDGE_EN localparam based on MEM_IF_ADDR_CMD_PHASE
165
function integer set_ac_negedge_en(input reg [23:0] addr_cmd_phase);
166
    integer return_value;
167
    begin
168
        return_value = 0;
169
        case (addr_cmd_phase)
170
            90, 180      : return_value = 1;
171
            0, 270       : return_value = 0;
172
            default      : begin
173
                               $display(phy_report_prefix, "Illegal value set on MEM_IF_ADDR_CMD_PHASE parameter: ", addr_cmd_phase);
174
                               $stop;
175
                           end
176
        endcase
177
        set_ac_negedge_en = return_value;
178
    end
179
endfunction
180
 
181
localparam USE_MEM_CLK_FOR_ADDR_CMD_CLK   =           set_mem_clk_for_ac_clk(MEM_IF_ADDR_CMD_PHASE);
182
localparam ADDR_CMD_NEGEDGE_EN            =           set_ac_negedge_en(MEM_IF_ADDR_CMD_PHASE);
183
 
184
localparam LOCAL_IF_DWIDTH                =           MEM_IF_DWIDTH*DWIDTH_RATIO;
185
localparam MEM_IF_POSTAMBLE_EN_WIDTH      =           MEM_IF_DWIDTH/MEM_IF_DQ_PER_DQS;
186
localparam LOCAL_IF_CLK_PS                =           MEM_IF_CLK_PS/(DWIDTH_RATIO/2);
187
localparam PLL_REF_CLK_PS                 =           LOCAL_IF_CLK_PS;
188
 
189
localparam MEM_IF_DQS_CAPTURE_EN          =                0;
190
localparam ADDR_COUNT_WIDTH               =                4;
191
localparam RDP_RESYNC_LAT_CTL_EN          =                0;
192
localparam DEDICATED_MEMORY_CLK_EN        =                0;
193
 
194
localparam ADV_LAT_WIDTH                  =                5;
195
localparam CAPTURE_MIMIC_PATH             =                0;
196
localparam DDR_MIMIC_PATH_EN              =                1;
197
localparam MIMIC_DEBUG_EN                 =                0;
198
localparam NUM_MIMIC_SAMPLE_CYCLES        =                6;
199
localparam NUM_DEBUG_SAMPLES_TO_STORE     =             4096;
200
localparam ASYNCHRONOUS_AVALON_CLOCK      =                1;
201
localparam RDV_INITIAL_LAT                =               23;
202
localparam RDP_INITIAL_LAT                =                6;
203
localparam RESYNC_PIPELINE_DEPTH          =                2;
204
localparam CLOCK_INDEX_WIDTH              =                3;
205
localparam OCT_LAT_WIDTH                  =    ADV_LAT_WIDTH;
206
 
207
 
208
// I/O Signal definitions :
209
 
210
// Clock and reset I/O :
211
input  wire                                                    pll_ref_clk;
212
input  wire                                                    global_reset_n;
213
input  wire                                                    soft_reset_n;
214
 
215
// This is the PLL locked signal :
216
output wire                                                    reset_request_n;
217
 
218
// The controller must use this phy_clk to interface to the PHY.  It is
219
// optional as to whether the remainder of the system uses it :
220
output wire                                                    ctl_clk;
221
output wire                                                    ctl_reset_n;
222
 
223
// new AFI I/Os -  write data i/f:
224
input  wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 -1 : 0]         ctl_dqs_burst;
225
input  wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 -1 : 0]         ctl_wdata_valid;
226
input  wire [MEM_IF_DWIDTH * DWIDTH_RATIO      -1 : 0]         ctl_wdata;
227
input  wire [MEM_IF_DM_WIDTH * DWIDTH_RATIO    -1 : 0]         ctl_dm;
228
output wire [4 : 0]                                            ctl_wlat;
229
 
230
// new AFI I/Os - addr/cmd i/f:
231
input  wire [MEM_IF_ADDR_WIDTH  * DWIDTH_RATIO/2 -1 : 0]       ctl_addr;
232
input  wire [MEM_IF_BANKADDR_WIDTH * DWIDTH_RATIO/2 -1 : 0]    ctl_ba;
233
input  wire [1 * DWIDTH_RATIO/2 -1 : 0]                        ctl_cas_n;
234
input  wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1:0]           ctl_cke;
235
input  wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1:0]           ctl_cs_n;
236
input  wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1:0]           ctl_odt;
237
input  wire [1 * DWIDTH_RATIO/2 -1 : 0]                        ctl_ras_n;
238
input  wire [1 * DWIDTH_RATIO/2 -1 : 0]                        ctl_we_n;
239
input  wire [DWIDTH_RATIO/2 - 1 : 0]                           ctl_rst_n;
240
input  wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                    ctl_mem_clk_disable;
241
 
242
// new AFI I/Os - read data i/f:
243
input  wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO / 2 -1 : 0]       ctl_doing_rd;
244
output wire [MEM_IF_DWIDTH * DWIDTH_RATIO      -1 : 0]         ctl_rdata;
245
output wire [DWIDTH_RATIO / 2 -1 : 0]                          ctl_rdata_valid;
246
output wire [4 : 0]                                            ctl_rlat;
247
 
248
// re-calibration request and configuration:
249
input  wire                                                    ctl_cal_req;
250
input  wire [MEM_IF_DQS_WIDTH * MEM_IF_CS_WIDTH - 1 : 0]       ctl_cal_byte_lane_sel_n;
251
 
252
// new AFI I/Os - status interface:
253
output wire                                                    ctl_cal_success;
254
output wire                                                    ctl_cal_fail;
255
 
256
 
257
//Outputs to DIMM :
258
output wire [MEM_IF_ADDR_WIDTH - 1 : 0]                        mem_addr;
259
output wire [MEM_IF_BANKADDR_WIDTH - 1 : 0]                    mem_ba;
260
output wire                                                    mem_cas_n;
261
output wire [MEM_IF_CS_WIDTH - 1 : 0]                          mem_cke;
262
output wire [MEM_IF_CS_WIDTH - 1 : 0]                          mem_cs_n;
263
wire        [MEM_IF_DWIDTH - 1 : 0]                            mem_d;
264
output wire [MEM_IF_DM_WIDTH - 1 : 0]                          mem_dm;
265
output wire [MEM_IF_CS_WIDTH - 1 : 0]                          mem_odt;
266
output wire                                                    mem_ras_n;
267
output wire                                                    mem_we_n;
268
output wire                                                    mem_reset_n;
269
 
270
//The mem_clks are outputs, but one is sometimes used for the mimic_path, so
271
//is looped back in.  Therefore defining as an inout ensures no errors in Quartus :
272
inout  wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                    mem_clk;
273
inout  wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                    mem_clk_n;
274
 
275
//Bidirectional:
276
inout  tri  [MEM_IF_DWIDTH - 1 : 0]                            mem_dq;
277
inout  tri  [MEM_IF_DWIDTH / MEM_IF_DQ_PER_DQS - 1 : 0]        mem_dqs;
278
inout  tri  [MEM_IF_DWIDTH / MEM_IF_DQ_PER_DQS - 1 : 0]        mem_dqs_n;
279
 
280
 
281
// AVALON MM Slave   -- debug IF
282
input  wire                                                    dbg_clk;
283
input  wire                                                    dbg_reset_n;
284
input  wire [DBG_A_WIDTH -1 : 0]                               dbg_addr;
285
input  wire                                                    dbg_wr;
286
input  wire                                                    dbg_rd;
287
input  wire                                                    dbg_cs;
288
input  wire [31 : 0]                                           dbg_wr_data;
289
output wire [31 : 0]                                           dbg_rd_data;
290
output wire                                                    dbg_waitrequest;
291
 
292
// Auxillary clocks. These do not have to be connected if the system
293
// doesn't require them :
294
output wire                                                    aux_half_rate_clk;
295
output wire                                                    aux_full_rate_clk;
296
 
297
// Internal signal declarations :
298
 
299
// Clocks :
300
 
301
// full-rate memory clock
302
wire                                            mem_clk_2x;
303
 
304
// half-rate memory clock
305
wire                                            mem_clk_1x;
306
 
307
// write_clk_2x is a full-rate write clock.  It is -90 degress aligned to the
308
// system clock :
309
wire                                            write_clk_2x;
310
 
311
wire                                            phy_clk_1x_src;
312
wire                                            phy_clk_1x;
313
wire                                            ac_clk_1x;
314
wire                                            ac_clk_2x;
315
wire                                            cs_n_clk_1x;
316
wire                                            cs_n_clk_2x;
317
wire                                            postamble_clk_2x;
318
wire                                            resync_clk_2x;
319
wire                                            measure_clk_1x;
320
wire                                            measure_clk_2x;
321
 
322
wire                                            half_rate_clk;
323
 
324
wire [MEM_IF_DQS_WIDTH - 1 : 0]                 resync_clk_1x;
325
 
326
wire [DQS_DELAY_CTL_WIDTH - 1 : 0 ]             dedicated_dll_delay_ctrl;
327
 
328
// resets, async assert, de-assert is sync'd to each clock domain
329
wire                                            reset_mem_clk_2x_n;
330
wire [MEM_IF_DQS_WIDTH - 1 : 0]                 reset_rdp_phy_clk_1x_n;
331
wire                                            reset_phy_clk_1x_n;
332
wire                                            reset_ac_clk_1x_n;
333
wire                                            reset_ac_clk_2x_n;
334
wire                                            reset_cs_n_clk_1x_n;
335
wire                                            reset_cs_n_clk_2x_n;
336
wire                                            reset_mimic_2x_n;
337
wire [MEM_IF_DQS_WIDTH - 1 : 0]                 reset_resync_clk_1x_n;
338
wire                                            reset_resync_clk_2x_n;
339
wire                                            reset_seq_n;
340
wire                                            reset_measure_clk_1x_n;
341
wire                                            reset_measure_clk_2x_n;
342
wire                                            reset_poa_clk_2x_n;
343
wire                                            reset_write_clk_2x_n;
344
 
345
 
346
// Misc signals :
347
wire                                            phs_shft_busy;
348
wire                                            pll_seq_reconfig_busy;
349
 
350
// Postamble signals :
351
 
352
wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO /2  - 1 : 0]             poa_postamble_en_preset;
353
wire [MEM_IF_POSTAMBLE_EN_WIDTH - 1 : 0]                       poa_postamble_en_preset_2x;
354
 
355
 
356
// Sequencer signals
357
wire                                                           seq_mmc_start;
358
wire                                                           seq_pll_inc_dec_n;
359
wire                                                           seq_pll_start_reconfig;
360
wire [CLOCK_INDEX_WIDTH - 1 : 0]                               seq_pll_select;
361
wire [MEM_IF_DQS_WIDTH -1 : 0]                                 seq_rdp_dec_read_lat_1x;
362
wire [MEM_IF_DQS_WIDTH -1 : 0]                                 seq_rdp_inc_read_lat_1x;
363
wire [MEM_IF_DQS_WIDTH -1 : 0]                                 seq_poa_lat_dec_1x;
364
wire [MEM_IF_DQS_WIDTH -1 : 0]                                 seq_poa_lat_inc_1x;
365
wire                                                           seq_poa_protection_override_1x;
366
 
367
wire                                                           seq_rdp_reset_req_n;
368
 
369
wire                                                           seq_ac_sel;
370
 
371
wire [MEM_IF_ADDR_WIDTH * DWIDTH_RATIO/2 - 1 : 0]              seq_ac_addr;
372
wire [MEM_IF_BANKADDR_WIDTH * DWIDTH_RATIO/2 - 1 : 0]          seq_ac_ba;
373
wire [DWIDTH_RATIO/2 -1 : 0]                                   seq_ac_cas_n;
374
wire [DWIDTH_RATIO/2 -1 : 0]                                   seq_ac_ras_n;
375
wire [DWIDTH_RATIO/2 -1 : 0]                                   seq_ac_we_n;
376
wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]                seq_ac_cke;
377
wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]                seq_ac_cs_n;
378
wire [MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]                seq_ac_odt;
379
 
380
wire [DWIDTH_RATIO * MEM_IF_DM_WIDTH - 1 : 0 ]                 seq_wdp_dm;
381
wire [MEM_IF_DQS_WIDTH * (DWIDTH_RATIO/2) - 1 : 0]             seq_wdp_dqs_burst;
382
wire [MEM_IF_DWIDTH * DWIDTH_RATIO - 1 : 0 ]                   seq_wdp_wdata;
383
wire [MEM_IF_DQS_WIDTH * (DWIDTH_RATIO/2) - 1 : 0]             seq_wdp_wdata_valid;
384
wire [DWIDTH_RATIO - 1 :0]                                     seq_wdp_dqs;
385
wire                                                           seq_wdp_ovride;
386
 
387
wire [MEM_IF_DQS_WIDTH * (DWIDTH_RATIO/2) - 1 : 0]             oct_rsst_sel;
388
 
389
wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]               seq_doing_rd;
390
wire                                                           seq_rdata_valid_lat_inc;
391
wire                                                           seq_rdata_valid_lat_dec;
392
 
393
wire  [DWIDTH_RATIO/2 - 1 : 0]                                 seq_rdata_valid;
394
 
395
 
396
// per group scanchain signals
397
wire [MEM_IF_DQS_WIDTH - 1 : 0]                                scan_enable_dqs_config;
398
wire [MEM_IF_DQS_WIDTH - 1 : 0]                                scan_din;
399
wire [MEM_IF_DQS_WIDTH - 1 : 0]                                scan_update;
400
 
401
 
402
// per pin scanchain signals
403
wire [MEM_IF_DQS_WIDTH - 1 : 0]                                scan_enable_dqs;
404
wire [MEM_IF_DQS_WIDTH - 1 : 0]                                scan_enable_dqsn;
405
wire [MEM_IF_DWIDTH  - 1 : 0]                                  scan_enable_dq;
406
wire [MEM_IF_DM_WIDTH - 1 : 0]                                 scan_enable_dm;
407
wire [MEM_IF_DWIDTH  - 1 : 0]                                  scan_enable_d;
408
 
409
reg  [DQS_DELAY_CTL_WIDTH - 1 : 0 ]                            dedicated_dll_delay_ctrl_r;
410
 
411
 
412
 
413
// The clk_reset block provides the sc_clk to the sequencer and DP blocks.
414
wire                                               sc_clk;
415
wire [MEM_IF_DQS_WIDTH - 1 : 0]                    sc_clk_dp;
416
 
417
// Mimic signals :
418
wire                                               mmc_seq_done;
419
wire                                               mmc_seq_value;
420
wire                                               mimic_data;
421
 
422
wire                                               mux_seq_controller_ready;
423
wire                                               mux_seq_wdata_req;
424
 
425
 
426
// Read datapath signals :
427
 
428
// Connections from the IOE to the read datapath :
429
wire [MEM_IF_DWIDTH - 1 : 0]                       dio_rdata_h_2x;
430
wire [MEM_IF_DWIDTH - 1 : 0]                       dio_rdata_l_2x;
431
 
432
 
433
// Write datapath signals :
434
 
435
 
436
 
437
// wires from the wdp to the dpio :
438
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata3_1x;
439
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata2_1x;
440
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata1_1x;
441
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata0_1x;
442
 
443
 
444
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata_h_2x;
445
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata_l_2x;
446
wire [MEM_IF_DWIDTH - 1 : 0]                 wdp_wdata_oe_2x;
447
wire  [(LOCAL_IF_DWIDTH/8) - 1 : 0]          ctl_mem_be;
448
 
449
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_wdata_oe_h_1x;
450
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_wdata_oe_l_1x;
451
 
452
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs3_1x;
453
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs2_1x;
454
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs1_1x;
455
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs0_1x;
456
 
457
wire [(MEM_IF_DQS_WIDTH) - 1 : 0]            wdp_wdqs_2x;
458
 
459
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs_oe_h_1x;
460
wire [MEM_IF_DQS_WIDTH - 1 : 0]              wdp_dqs_oe_l_1x;
461
 
462
wire [(MEM_IF_DQS_WIDTH) - 1 : 0]            wdp_wdqs_oe_2x;
463
 
464
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm3_1x;
465
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm2_1x;
466
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm1_1x;
467
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm0_1x;
468
 
469
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm_h_2x;
470
wire [MEM_IF_DM_WIDTH -1 : 0]                wdp_dm_l_2x;
471
 
472
wire [MEM_IF_DQS_WIDTH -1 : 0]               wdp_oct_h_1x;
473
wire [MEM_IF_DQS_WIDTH -1 : 0]               wdp_oct_l_1x;
474
 
475
wire [MEM_IF_DQS_WIDTH -1 : 0]               seq_dqs_add_2t_delay;
476
 
477
wire                                         ctl_add_1t_ac_lat_internal;
478
wire                                         ctl_add_1t_odt_lat_internal;
479
wire                                         ctl_add_intermediate_regs_internal;
480
wire                                         ctl_negedge_en_internal;
481
 
482
wire                                         ctl_mem_dqs_burst;
483
wire [MEM_IF_DWIDTH*DWIDTH_RATIO - 1 : 0]    ctl_mem_wdata;
484
wire                                         ctl_mem_wdata_valid;
485
 
486
// These ports are tied off for DDR,DDR2,DDR3.  Registers are used to reduce Quartus warnings :
487
(* preserve *) reg [3 : 0]                   ctl_mem_dqs = 4'b1100;
488
 
489
wire [MEM_IF_CS_WIDTH - 1 : 0]               int_rank_has_addr_swap;
490
 
491
//SIII declarations :
492
 
493
//Outputs from the dp_io block to the read_dp block :
494
wire [MEM_IF_DWIDTH - 1 : 0]                     dio_rdata3_1x;
495
wire [MEM_IF_DWIDTH - 1 : 0]                     dio_rdata2_1x;
496
wire [MEM_IF_DWIDTH - 1 : 0]                     dio_rdata1_1x;
497
wire [MEM_IF_DWIDTH - 1 : 0]                     dio_rdata0_1x;
498
 
499
reg [DWIDTH_RATIO/2 - 1 : 0]                     rdv_pipe_ip;
500
reg [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]  merged_doing_rd;
501
 
502
 
503
wire [OCT_LAT_WIDTH - 1 : 0]                     seq_oct_oct_delay; // oct_lat
504
wire [OCT_LAT_WIDTH - 1 : 0]                     seq_oct_oct_extend; //oct_extend_duration
505
wire seq_oct_val;
506
 
507
wire seq_mem_clk_disable;
508
 
509
 
510
wire [DWIDTH_RATIO/2 - 1 : 0]                    seq_ac_rst_n;
511
 
512
wire                                             dqs_delay_update_en;
513
wire [DQS_DELAY_CTL_WIDTH - 1 : 0 ]              dlloffset_offsetctrl_out;
514
 
515
// Generate auxillary clocks:
516
generate
517
 
518
    // Half-rate mode :
519
    if (DWIDTH_RATIO == 4)
520
    begin
521
        assign aux_half_rate_clk = phy_clk_1x;
522
        assign aux_full_rate_clk = mem_clk_2x;
523
    end
524
 
525
    // Full-rate mode :
526
    else
527
    begin
528
        assign aux_half_rate_clk = half_rate_clk;
529
        assign aux_full_rate_clk = phy_clk_1x;
530
    end
531
 
532
endgenerate
533
 
534
// The top level I/O should not have the "Nx" clock domain suffices, so this is
535
// assigned here.  Also note that to avoid delta delay issues both the external and
536
// internal phy_clks are assigned to a common 'src' clock :
537
assign ctl_clk         = phy_clk_1x_src;
538
assign phy_clk_1x      = phy_clk_1x_src;
539
 
540
assign ctl_reset_n     = reset_phy_clk_1x_n;
541
 
542
// Instance I/O modules :
543
 
544
 
545
//
546
altera_ddr_phy_alt_mem_phy_dp_io #(
547
    .MEM_IF_CLK_PS              (MEM_IF_CLK_PS),
548
    .MEM_IF_BANKADDR_WIDTH      (MEM_IF_BANKADDR_WIDTH),
549
    .MEM_IF_CS_WIDTH            (MEM_IF_CS_WIDTH),
550
    .MEM_IF_DWIDTH              (MEM_IF_DWIDTH),
551
    .MEM_IF_DM_WIDTH            (MEM_IF_DM_WIDTH),
552
    .MEM_IF_DM_PINS_EN          (MEM_IF_DM_PINS_EN),
553
    .MEM_IF_DQ_PER_DQS          (MEM_IF_DQ_PER_DQS),
554
    .MEM_IF_DQS_CAPTURE_EN      (MEM_IF_DQS_CAPTURE_EN),
555
    .MEM_IF_DQS_WIDTH           (MEM_IF_DQS_WIDTH),
556
    .MEM_IF_POSTAMBLE_EN_WIDTH  (MEM_IF_POSTAMBLE_EN_WIDTH),
557
    .MEM_IF_ROWADDR_WIDTH       (MEM_IF_ADDR_WIDTH),
558
    .DLL_DELAY_BUFFER_MODE      (DLL_DELAY_BUFFER_MODE),
559
    .DQS_OUT_MODE               (DQS_OUT_MODE),
560
    .DQS_PHASE                  (DQS_PHASE)
561
) dpio (
562
    .reset_resync_clk_2x_n      (reset_resync_clk_2x_n),
563
    .resync_clk_2x              (resync_clk_2x),
564
    .mem_clk_2x                 (mem_clk_2x),
565
    .write_clk_2x               (write_clk_2x),
566
    .mem_dm                     (mem_dm),
567
    .mem_dq                     (mem_dq),
568
    .mem_dqs                    (mem_dqs),
569
    .dio_rdata_h_2x             (dio_rdata_h_2x),
570
    .dio_rdata_l_2x             (dio_rdata_l_2x),
571
    .poa_postamble_en_preset_2x (poa_postamble_en_preset_2x),
572
    .wdp_dm_h_2x                (wdp_dm_h_2x),
573
    .wdp_dm_l_2x                (wdp_dm_l_2x),
574
    .wdp_wdata_h_2x             (wdp_wdata_h_2x),
575
    .wdp_wdata_l_2x             (wdp_wdata_l_2x),
576
    .wdp_wdata_oe_2x            (wdp_wdata_oe_2x),
577
    .wdp_wdqs_2x                (wdp_wdqs_2x),
578
    .wdp_wdqs_oe_2x             (wdp_wdqs_oe_2x)
579
);
580
 
581
// Instance the read datapath :
582
 
583
//
584
altera_ddr_phy_alt_mem_phy_read_dp #(
585
    .ADDR_COUNT_WIDTH          (ADDR_COUNT_WIDTH),
586
    .BIDIR_DPINS               (1),
587
    .DWIDTH_RATIO              (DWIDTH_RATIO),
588
    .MEM_IF_CLK_PS             (MEM_IF_CLK_PS),
589
    .FAMILY                    (FAMILY),
590
    .LOCAL_IF_DWIDTH           (LOCAL_IF_DWIDTH),
591
    .MEM_IF_DQ_PER_DQS         (MEM_IF_DQ_PER_DQS),
592
    .MEM_IF_DQS_WIDTH          (MEM_IF_DQS_WIDTH),
593
    .MEM_IF_DWIDTH             (MEM_IF_DWIDTH),
594
    .RDP_INITIAL_LAT           (RDP_INITIAL_LAT),
595
    .RDP_RESYNC_LAT_CTL_EN     (RDP_RESYNC_LAT_CTL_EN),
596
    .RESYNC_PIPELINE_DEPTH     (RESYNC_PIPELINE_DEPTH)
597
) rdp (
598
    .phy_clk_1x                (phy_clk_1x),
599
    .resync_clk_2x             (resync_clk_2x),
600
    .reset_phy_clk_1x_n        (reset_phy_clk_1x_n),
601
    .reset_resync_clk_2x_n     (reset_resync_clk_2x_n),
602
    .seq_rdp_dec_read_lat_1x   (seq_rdp_dec_read_lat_1x[0]),
603
    .seq_rdp_dmx_swap          (1'b0),
604
    .seq_rdp_inc_read_lat_1x   (seq_rdp_inc_read_lat_1x[0]),
605
    .dio_rdata_h_2x            (dio_rdata_h_2x),
606
    .dio_rdata_l_2x            (dio_rdata_l_2x),
607
    .ctl_mem_rdata             (ctl_rdata)
608
);
609
//          enhancements a different delay per dqs group may be implemented using the
610
//          full vector
611
 
612
 
613
// Instance the write datapath :
614
 
615
generate
616
 
617
    // Half-rate Write datapath :
618
    if (DWIDTH_RATIO == 4)
619
    begin : half_rate_wdp_gen
620
 
621
        //
622
        altera_ddr_phy_alt_mem_phy_write_dp #(
623
                    .BIDIR_DPINS           (1),
624
            .LOCAL_IF_DRATE        ("HALF"),
625
            .LOCAL_IF_DWIDTH       (LOCAL_IF_DWIDTH),
626
            .MEM_IF_DM_WIDTH       (MEM_IF_DM_WIDTH),
627
            .MEM_IF_DQ_PER_DQS     (MEM_IF_DQ_PER_DQS),
628
            .MEM_IF_DQS_WIDTH      (MEM_IF_DQS_WIDTH),
629
            .GENERATE_WRITE_DQS    (1),
630
            .MEM_IF_DWIDTH         (MEM_IF_DWIDTH),
631
            .DWIDTH_RATIO          (DWIDTH_RATIO)
632
        ) wdp (
633
            .phy_clk_1x            (phy_clk_1x),
634
            .mem_clk_2x            (mem_clk_2x),
635
            .write_clk_2x          (write_clk_2x),
636
            .reset_phy_clk_1x_n    (reset_phy_clk_1x_n),
637
            .reset_mem_clk_2x_n    (reset_mem_clk_2x_n),
638
            .reset_write_clk_2x_n  (reset_write_clk_2x_n),
639
            .ctl_mem_be            (ctl_dm),
640
            .ctl_mem_dqs_burst     (ctl_dqs_burst),
641
            .ctl_mem_wdata         (ctl_wdata),
642
            .ctl_mem_wdata_valid   (ctl_wdata_valid),
643
            .seq_be                (seq_wdp_dm),
644
            .seq_dqs_burst         (seq_wdp_dqs_burst),
645
            .seq_wdata             (seq_wdp_wdata),
646
            .seq_wdata_valid       (seq_wdp_wdata_valid),
647
            .seq_ctl_sel           (seq_wdp_ovride),
648
            .wdp_wdata_h_2x        (wdp_wdata_h_2x),
649
            .wdp_wdata_l_2x        (wdp_wdata_l_2x),
650
            .wdp_wdata_oe_2x       (wdp_wdata_oe_2x),
651
            .wdp_wdqs_2x           (wdp_wdqs_2x),
652
            .wdp_wdqs_oe_2x        (wdp_wdqs_oe_2x),
653
            .wdp_dm_h_2x           (wdp_dm_h_2x),
654
            .wdp_dm_l_2x           (wdp_dm_l_2x)
655
        );
656
 
657
    end
658
 
659
    // Full-rate :
660
    else
661
    begin : full_rate_wdp_gen
662
 
663
        //
664
        altera_ddr_phy_alt_mem_phy_write_dp_fr #(
665
                    .BIDIR_DPINS           (1),
666
            .LOCAL_IF_DRATE        ("FULL"),
667
            .LOCAL_IF_DWIDTH       (LOCAL_IF_DWIDTH),
668
            .MEM_IF_DM_WIDTH       (MEM_IF_DM_WIDTH),
669
            .MEM_IF_DQ_PER_DQS     (MEM_IF_DQ_PER_DQS),
670
            .MEM_IF_DQS_WIDTH      (MEM_IF_DQS_WIDTH),
671
            .GENERATE_WRITE_DQS    (1),
672
            .MEM_IF_DWIDTH         (MEM_IF_DWIDTH),
673
            .DWIDTH_RATIO          (DWIDTH_RATIO)
674
        ) wdp (
675
            .phy_clk_1x            (phy_clk_1x),
676
            .mem_clk_2x            (mem_clk_2x),
677
            .write_clk_2x          (write_clk_2x),
678
            .reset_phy_clk_1x_n    (reset_phy_clk_1x_n),
679
            .reset_mem_clk_2x_n    (reset_mem_clk_2x_n),
680
            .reset_write_clk_2x_n  (reset_write_clk_2x_n),
681
            .ctl_mem_be            (ctl_dm),
682
            .ctl_mem_dqs_burst     (ctl_dqs_burst),
683
            .ctl_mem_wdata         (ctl_wdata),
684
            .ctl_mem_wdata_valid   (ctl_wdata_valid),
685
            .seq_be                (seq_wdp_dm),
686
            .seq_dqs_burst         (seq_wdp_dqs_burst),
687
            .seq_wdata             (seq_wdp_wdata),
688
            .seq_wdata_valid       (seq_wdp_wdata_valid),
689
            .seq_ctl_sel            (seq_wdp_ovride),
690
            .wdp_wdata_h_2x        (wdp_wdata_h_2x),
691
            .wdp_wdata_l_2x        (wdp_wdata_l_2x),
692
            .wdp_wdata_oe_2x       (wdp_wdata_oe_2x),
693
            .wdp_wdqs_2x           (wdp_wdqs_2x),
694
            .wdp_wdqs_oe_2x        (wdp_wdqs_oe_2x),
695
            .wdp_dm_h_2x           (wdp_dm_h_2x),
696
            .wdp_dm_l_2x           (wdp_dm_l_2x)
697
        );
698
 
699
    end
700
 
701
endgenerate
702
 
703
 
704
// Instance the address and command :
705
 
706
generate
707
 
708
    // Half-rate address and command :
709
    if (DWIDTH_RATIO == 4)
710
    begin : half_rate_adc_gen
711
 
712
        //
713
        altera_ddr_phy_alt_mem_phy_addr_cmd #(
714
                     .DWIDTH_RATIO                 (DWIDTH_RATIO),
715
             .MEM_ADDR_CMD_BUS_COUNT       (1),
716
             .MEM_IF_BANKADDR_WIDTH        (MEM_IF_BANKADDR_WIDTH),
717
             .MEM_IF_CS_WIDTH              (MEM_IF_CS_WIDTH),
718
             .MEM_IF_MEMTYPE               (MEM_IF_MEMTYPE),
719
             .MEM_IF_ROWADDR_WIDTH         (MEM_IF_ADDR_WIDTH)
720
        ) adc (
721
             .ac_clk_1x                    (ac_clk_1x),
722
             .ac_clk_2x                    (ac_clk_2x),
723
             .cs_n_clk_1x                  (cs_n_clk_1x),
724
             .cs_n_clk_2x                  (cs_n_clk_2x),
725
             .phy_clk_1x                   (phy_clk_1x),
726
             .reset_ac_clk_1x_n            (reset_ac_clk_1x_n),
727
             .reset_ac_clk_2x_n            (reset_ac_clk_2x_n),
728
             .reset_cs_n_clk_1x_n          (reset_cs_n_clk_1x_n),
729
             .reset_cs_n_clk_2x_n          (reset_cs_n_clk_2x_n),
730
             .ctl_add_1t_ac_lat            (ctl_add_1t_ac_lat_internal),
731
             .ctl_add_1t_odt_lat           (ctl_add_1t_odt_lat_internal),
732
             .ctl_add_intermediate_regs    (ctl_add_intermediate_regs_internal),
733
        //     .ctl_negedge_en               (ctl_negedge_en_internal),
734
             .ctl_negedge_en               (ADDR_CMD_NEGEDGE_EN[0 : 0]),
735
             .ctl_mem_addr_h               (ctl_addr[MEM_IF_ADDR_WIDTH -1 : 0]),
736
             .ctl_mem_addr_l               (ctl_addr[(MEM_IF_ADDR_WIDTH  * DWIDTH_RATIO/2) -1 : MEM_IF_ADDR_WIDTH]),
737
             .ctl_mem_ba_h                 (ctl_ba[MEM_IF_BANKADDR_WIDTH -1 : 0]),
738
             .ctl_mem_ba_l                 (ctl_ba[MEM_IF_BANKADDR_WIDTH * DWIDTH_RATIO/2 -1 : MEM_IF_BANKADDR_WIDTH]),
739
             .ctl_mem_cas_n_h              (ctl_cas_n[0]),
740
             .ctl_mem_cas_n_l              (ctl_cas_n[1]),
741
             .ctl_mem_cke_h                (ctl_cke[MEM_IF_CS_WIDTH - 1 : 0]),
742
             .ctl_mem_cke_l                (ctl_cke[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
743
             .ctl_mem_cs_n_h               (ctl_cs_n[MEM_IF_CS_WIDTH - 1 : 0]),
744
             .ctl_mem_cs_n_l               (ctl_cs_n[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
745
             .ctl_mem_odt_h                (ctl_odt[MEM_IF_CS_WIDTH - 1 : 0]),
746
             .ctl_mem_odt_l                (ctl_odt[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
747
             .ctl_mem_ras_n_h              (ctl_ras_n[0]),
748
             .ctl_mem_ras_n_l              (ctl_ras_n[1]),
749
             .ctl_mem_we_n_h               (ctl_we_n[0]),
750
             .ctl_mem_we_n_l               (ctl_we_n[1]),
751
             .seq_addr_h                   (seq_ac_addr[MEM_IF_ADDR_WIDTH -1 : 0]),
752
             .seq_addr_l                   (seq_ac_addr[MEM_IF_ADDR_WIDTH  * DWIDTH_RATIO/2 -1 : MEM_IF_ADDR_WIDTH]),
753
             .seq_ba_h                     (seq_ac_ba[MEM_IF_BANKADDR_WIDTH -1 : 0]),
754
             .seq_ba_l                     (seq_ac_ba[MEM_IF_BANKADDR_WIDTH * DWIDTH_RATIO/2 -1 : MEM_IF_BANKADDR_WIDTH]),
755
             .seq_cas_n_h                  (seq_ac_cas_n[0]),
756
             .seq_cas_n_l                  (seq_ac_cas_n[1]),
757
             .seq_cke_h                    (seq_ac_cke[MEM_IF_CS_WIDTH - 1 : 0]),
758
             .seq_cke_l                    (seq_ac_cke[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
759
             .seq_cs_n_h                   (seq_ac_cs_n[MEM_IF_CS_WIDTH - 1 : 0]),
760
             .seq_cs_n_l                   (seq_ac_cs_n[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
761
             .seq_odt_h                    (seq_ac_odt[MEM_IF_CS_WIDTH - 1 : 0]),
762
             .seq_odt_l                    (seq_ac_odt[MEM_IF_CS_WIDTH * DWIDTH_RATIO/2 - 1 : MEM_IF_CS_WIDTH]),
763
             .seq_ras_n_h                  (seq_ac_ras_n[0]),
764
             .seq_ras_n_l                  (seq_ac_ras_n[1]),
765
             .seq_we_n_h                   (seq_ac_we_n[0]),
766
             .seq_we_n_l                   (seq_ac_we_n[1]),
767
             .seq_ac_sel                   (seq_ac_sel),
768
             .mem_addr                     (mem_addr),
769
             .mem_ba                       (mem_ba),
770
             .mem_cas_n                    (mem_cas_n),
771
             .mem_cke                      (mem_cke),
772
             .mem_cs_n                     (mem_cs_n),
773
             .mem_odt                      (mem_odt),
774
             .mem_ras_n                    (mem_ras_n),
775
             .mem_we_n                     (mem_we_n)
776
        );
777
    end
778
 
779
    // Full-rate :
780
    else
781
    begin : full_rate_adc_gen
782
 
783
        //
784
        altera_ddr_phy_alt_mem_phy_addr_cmd #(
785
                     .DWIDTH_RATIO                 (DWIDTH_RATIO),
786
             .MEM_ADDR_CMD_BUS_COUNT       (1),
787
             .MEM_IF_BANKADDR_WIDTH        (MEM_IF_BANKADDR_WIDTH),
788
             .MEM_IF_CS_WIDTH              (MEM_IF_CS_WIDTH),
789
             .MEM_IF_MEMTYPE               (MEM_IF_MEMTYPE),
790
             .MEM_IF_ROWADDR_WIDTH         (MEM_IF_ADDR_WIDTH)
791
        ) adc (
792
             .ac_clk_1x                    (ac_clk_1x),
793
             .ac_clk_2x                    (ac_clk_2x),
794
             .cs_n_clk_1x                  (cs_n_clk_1x),
795
             .cs_n_clk_2x                  (cs_n_clk_2x),
796
             .phy_clk_1x                   (phy_clk_1x),
797
             .reset_ac_clk_1x_n            (reset_ac_clk_1x_n),
798
             .reset_ac_clk_2x_n            (reset_ac_clk_2x_n),
799
             .reset_cs_n_clk_1x_n          (reset_cs_n_clk_1x_n),
800
             .reset_cs_n_clk_2x_n          (reset_cs_n_clk_2x_n),
801
             .ctl_add_1t_ac_lat            (ctl_add_1t_ac_lat_internal),
802
             .ctl_add_1t_odt_lat           (ctl_add_1t_odt_lat_internal),
803
             .ctl_add_intermediate_regs    (ctl_add_intermediate_regs_internal),
804
        //     .ctl_negedge_en               (ctl_negedge_en_internal),
805
             .ctl_negedge_en               (ADDR_CMD_NEGEDGE_EN[0 : 0]),
806
             .ctl_mem_addr_h               (),
807
             .ctl_mem_addr_l               (ctl_addr[MEM_IF_ADDR_WIDTH  -1 : 0]),
808
             .ctl_mem_ba_h                 (),
809
             .ctl_mem_ba_l                 (ctl_ba[MEM_IF_BANKADDR_WIDTH -1 : 0]),
810
             .ctl_mem_cas_n_h              (),
811
             .ctl_mem_cas_n_l              (ctl_cas_n[0]),
812
             .ctl_mem_cke_h                (),
813
             .ctl_mem_cke_l                (ctl_cke[MEM_IF_CS_WIDTH - 1 : 0]),
814
             .ctl_mem_cs_n_h               (),
815
             .ctl_mem_cs_n_l               (ctl_cs_n[MEM_IF_CS_WIDTH - 1 : 0]),
816
             .ctl_mem_odt_h                (),
817
             .ctl_mem_odt_l                (ctl_odt[MEM_IF_CS_WIDTH - 1 : 0]),
818
             .ctl_mem_ras_n_h              (),
819
             .ctl_mem_ras_n_l              (ctl_ras_n[0]),
820
             .ctl_mem_we_n_h               (),
821
             .ctl_mem_we_n_l               (ctl_we_n[0]),
822
             .seq_addr_h                   (),
823
             .seq_addr_l                   (seq_ac_addr[MEM_IF_ADDR_WIDTH -1 : 0]),
824
             .seq_ba_h                     (),
825
             .seq_ba_l                     (seq_ac_ba[MEM_IF_BANKADDR_WIDTH -1 : 0]),
826
             .seq_cas_n_h                  (),
827
             .seq_cas_n_l                  (seq_ac_cas_n[0]),
828
             .seq_cke_h                    (),
829
             .seq_cke_l                    (seq_ac_cke[MEM_IF_CS_WIDTH - 1 : 0]),
830
             .seq_cs_n_h                   (),
831
             .seq_cs_n_l                   (seq_ac_cs_n[MEM_IF_CS_WIDTH - 1 : 0]),
832
             .seq_odt_h                    (),
833
             .seq_odt_l                    (seq_ac_odt[MEM_IF_CS_WIDTH - 1 : 0]),
834
             .seq_ras_n_h                  (),
835
             .seq_ras_n_l                  (seq_ac_ras_n[0]),
836
             .seq_we_n_h                   (),
837
             .seq_we_n_l                   (seq_ac_we_n[0]),
838
             .seq_ac_sel                   (seq_ac_sel),
839
             .mem_addr                     (mem_addr),
840
             .mem_ba                       (mem_ba),
841
             .mem_cas_n                    (mem_cas_n),
842
             .mem_cke                      (mem_cke),
843
             .mem_cs_n                     (mem_cs_n),
844
             .mem_odt                      (mem_odt),
845
             .mem_ras_n                    (mem_ras_n),
846
             .mem_we_n                     (mem_we_n)
847
        );
848
 
849
    end
850
endgenerate
851
 
852
 assign int_rank_has_addr_swap = RANK_HAS_ADDR_SWAP[MEM_IF_CS_WIDTH - 1 : 0];
853
 
854
   //
855
  altera_ddr_phy_alt_mem_phy_seq_wrapper
856
      //
857
    seq_wrapper (
858
        .phy_clk_1x                         (phy_clk_1x),
859
        .reset_phy_clk_1x_n                 (reset_phy_clk_1x_n),
860
        .ctl_cal_success                    (ctl_cal_success),
861
        .ctl_cal_fail                       (ctl_cal_fail),
862
        .ctl_cal_req                        (ctl_cal_req),
863
        .int_RANK_HAS_ADDR_SWAP             (int_rank_has_addr_swap),
864
        .ctl_cal_byte_lane_sel_n            (ctl_cal_byte_lane_sel_n),
865
        .seq_pll_inc_dec_n                  (seq_pll_inc_dec_n),
866
        .seq_pll_start_reconfig             (seq_pll_start_reconfig),
867
        .seq_pll_select                     (seq_pll_select),
868
        .phs_shft_busy                      (phs_shft_busy),
869
        .pll_resync_clk_index               (5),
870
        .pll_measure_clk_index              (4),
871
        .sc_clk_dp                          (sc_clk_dp),
872
        .scan_enable_dqs_config             (scan_enable_dqs_config),
873
        .scan_update                        (scan_update),
874
        .scan_din                           (scan_din),
875
        .scan_enable_dqs                    (scan_enable_dqs),
876
        .scan_enable_dqsn                   (scan_enable_dqsn),
877
        .scan_enable_dq                     (scan_enable_dq),
878
        .scan_enable_dm                     (scan_enable_dm),
879
        .scan_enable_d                      (scan_enable_d),
880
        .hr_rsc_clk                         (resync_clk_1x[0]),
881
        .seq_ac_addr                        (seq_ac_addr),
882
        .seq_ac_ba                          (seq_ac_ba),
883
        .seq_ac_cas_n                       (seq_ac_cas_n),
884
        .seq_ac_ras_n                       (seq_ac_ras_n),
885
        .seq_ac_we_n                        (seq_ac_we_n),
886
        .seq_ac_cke                         (seq_ac_cke),
887
        .seq_ac_cs_n                        (seq_ac_cs_n),
888
        .seq_ac_odt                         (seq_ac_odt),
889
        .seq_ac_rst_n                       (seq_ac_rst_n),
890
        .seq_ac_sel                         (seq_ac_sel),
891
        .seq_mem_clk_disable                (seq_mem_clk_disable),
892
        .ctl_add_1t_ac_lat_internal         (ctl_add_1t_ac_lat_internal),
893
        .ctl_add_1t_odt_lat_internal        (ctl_add_1t_odt_lat_internal),
894
        .ctl_add_intermediate_regs_internal (ctl_add_intermediate_regs_internal),
895
        .seq_rdv_doing_rd                   (seq_doing_rd),
896
        .seq_rdp_reset_req_n                (seq_rdp_reset_req_n),
897
        .seq_rdp_inc_read_lat_1x            (seq_rdp_inc_read_lat_1x),
898
        .seq_rdp_dec_read_lat_1x            (seq_rdp_dec_read_lat_1x),
899
        .ctl_rdata                          (ctl_rdata),
900
        .int_rdata_valid_1t                 (seq_rdata_valid),
901
        .seq_rdata_valid_lat_inc            (seq_rdata_valid_lat_inc),
902
        .seq_rdata_valid_lat_dec            (seq_rdata_valid_lat_dec),
903
        .ctl_rlat                           (ctl_rlat),
904
        .seq_poa_lat_dec_1x                 (seq_poa_lat_dec_1x),
905
        .seq_poa_lat_inc_1x                 (seq_poa_lat_inc_1x),
906
        .seq_poa_protection_override_1x     (seq_poa_protection_override_1x),
907
        .seq_oct_oct_delay                  (seq_oct_oct_delay),
908
        .seq_oct_oct_extend                 (seq_oct_oct_extend),
909
        .seq_oct_val                        (seq_oct_val),
910
        .seq_wdp_dqs_burst                  (seq_wdp_dqs_burst),
911
        .seq_wdp_wdata_valid                (seq_wdp_wdata_valid),
912
        .seq_wdp_wdata                      (seq_wdp_wdata),
913
        .seq_wdp_dm                         (seq_wdp_dm),
914
        .seq_wdp_dqs                        (seq_wdp_dqs),
915
        .seq_wdp_ovride                     (seq_wdp_ovride),
916
        .seq_dqs_add_2t_delay               (seq_dqs_add_2t_delay),
917
        .ctl_wlat                           (ctl_wlat),
918
        .ctl_addr                           (ctl_addr),
919
        .ctl_ba                             (ctl_ba),
920
        .ctl_cke                            (ctl_cke),
921
        .ctl_cs_n                           (ctl_cs_n),
922
        .ctl_cas_n                          (ctl_cas_n),
923
        .ctl_ras_n                          (ctl_ras_n),
924
        .ctl_we_n                           (ctl_we_n),
925
        .ctl_rst_n                          ({(DWIDTH_RATIO/2){1'b0}}),
926
        .seq_mmc_start                      (seq_mmc_start),
927
        .mmc_seq_done                       (mmc_seq_done),
928
        .mmc_seq_value                      (mmc_seq_value),
929
        .dbg_clk                            (dbg_clk),
930
        .dbg_reset_n                        (dbg_reset_n),
931
        .dbg_addr                           (dbg_addr),
932
        .dbg_wr                             (dbg_wr),
933
        .dbg_rd                             (dbg_rd),
934
        .dbg_cs                             (dbg_cs),
935
        .dbg_wr_data                        (dbg_wr_data),
936
        .dbg_rd_data                        (dbg_rd_data),
937
        .dbg_waitrequest                    (dbg_waitrequest)
938
    );
939
 
940
// Generate rdata_valid for sequencer and control blocks
941
//
942
altera_ddr_phy_alt_mem_phy_rdata_valid #(
943
     .FAMILY                    (FAMILY),
944
     .MEM_IF_DQS_WIDTH          (MEM_IF_DQS_WIDTH),
945
     .RDATA_VALID_AWIDTH        (5),
946
     .RDATA_VALID_INITIAL_LAT   (RDV_INITIAL_LAT),
947
     .DWIDTH_RATIO              (DWIDTH_RATIO)
948
) rdv_pipe (
949
     .phy_clk_1x                (phy_clk_1x),
950
     .reset_phy_clk_1x_n        (reset_phy_clk_1x_n),
951
     .seq_rdata_valid_lat_dec   (seq_rdata_valid_lat_dec),
952
     .seq_rdata_valid_lat_inc   (seq_rdata_valid_lat_inc),
953
     .seq_doing_rd              (seq_doing_rd),
954
     .ctl_doing_rd              (ctl_doing_rd),
955
     .ctl_cal_success           (ctl_cal_success),
956
     .ctl_rdata_valid           (ctl_rdata_valid),
957
     .seq_rdata_valid           (seq_rdata_valid)
958
);
959
 
960
// Instance the CIII clock and reset :
961
 
962
//
963
altera_ddr_phy_alt_mem_phy_clk_reset #(
964
    .AC_PHASE                             (MEM_IF_ADDR_CMD_PHASE),
965
    .CLOCK_INDEX_WIDTH                    (CLOCK_INDEX_WIDTH),
966
    .CAPTURE_MIMIC_PATH                   (CAPTURE_MIMIC_PATH),
967
    .DDR_MIMIC_PATH_EN                    (DDR_MIMIC_PATH_EN),
968
    .DEDICATED_MEMORY_CLK_EN              (DEDICATED_MEMORY_CLK_EN),
969
    .DLL_EXPORT_IMPORT                    (DLL_EXPORT_IMPORT),
970
    .DWIDTH_RATIO                         (DWIDTH_RATIO),
971
    .LOCAL_IF_CLK_PS                      (LOCAL_IF_CLK_PS),
972
    .MEM_IF_CLK_PAIR_COUNT                (MEM_IF_CLK_PAIR_COUNT),
973
    .MEM_IF_CLK_PS                        (MEM_IF_CLK_PS),
974
    .MEM_IF_CS_WIDTH                      (MEM_IF_CS_WIDTH),
975
    .MEM_IF_DQ_PER_DQS                    (MEM_IF_DQ_PER_DQS),
976
    .MEM_IF_DQS_WIDTH                     (MEM_IF_DQS_WIDTH),
977
    .MEM_IF_DWIDTH                        (MEM_IF_DWIDTH),
978
    .MIF_FILENAME                         ("PLL.MIF"),
979
    .PLL_EXPORT_IMPORT                    ("NONE"),
980
    .PLL_REF_CLK_PS                       (PLL_REF_CLK_PS),
981
    .PLL_TYPE                             ("ENHANCED"),
982
    .SPEED_GRADE                          ("C6"),
983
    .DLL_DELAY_BUFFER_MODE                (DLL_DELAY_BUFFER_MODE),
984
    .DLL_DELAY_CHAIN_LENGTH               (DLL_DELAY_CHAIN_LENGTH),
985
    .DQS_OUT_MODE                         (DQS_OUT_MODE),
986
    .DQS_PHASE                            (DQS_PHASE),
987
    .SCAN_CLK_DIVIDE_BY                   (SCAN_CLK_DIVIDE_BY),
988
    .USE_MEM_CLK_FOR_ADDR_CMD_CLK         (USE_MEM_CLK_FOR_ADDR_CMD_CLK)
989
) clk (
990
    .pll_ref_clk                          (pll_ref_clk),
991
    .global_reset_n                       (global_reset_n),
992
    .soft_reset_n                         (soft_reset_n),
993
    .resync_clk_1x                        (resync_clk_1x),
994
    .ac_clk_1x                            (ac_clk_1x),
995
    .ac_clk_2x                            (ac_clk_2x),
996
    .measure_clk_2x                       (measure_clk_2x),
997
    .measure_clk_1x                       (),
998
    .mem_clk_2x                           (mem_clk_2x),
999
    .mem_clk                              (mem_clk),
1000
    .mem_clk_n                            (mem_clk_n),
1001
    .phy_clk_1x                           (phy_clk_1x_src),
1002
    .postamble_clk_2x                     (postamble_clk_2x),
1003
    .resync_clk_2x                        (resync_clk_2x),
1004
    .cs_n_clk_1x                          (cs_n_clk_1x),
1005
    .cs_n_clk_2x                          (cs_n_clk_2x),
1006
    .write_clk_2x                         (write_clk_2x),
1007
    .half_rate_clk                        (half_rate_clk),
1008
    .reset_ac_clk_1x_n                    (),
1009
    .reset_ac_clk_2x_n                    (reset_ac_clk_2x_n),
1010
    .reset_measure_clk_2x_n               (reset_measure_clk_2x_n),
1011
    .reset_measure_clk_1x_n               (),
1012
    .reset_mem_clk_2x_n                   (reset_mem_clk_2x_n),
1013
    .reset_phy_clk_1x_n                   (reset_phy_clk_1x_n),
1014
    .reset_poa_clk_2x_n                   (reset_poa_clk_2x_n),
1015
    .reset_resync_clk_2x_n                (reset_resync_clk_2x_n),
1016
    .reset_resync_clk_1x_n                (),
1017
    .reset_write_clk_2x_n                 (reset_write_clk_2x_n),
1018
    .reset_cs_n_clk_1x_n                  (),
1019
    .reset_cs_n_clk_2x_n                  (reset_cs_n_clk_2x_n),
1020
    .mem_reset_n                          (mem_reset_n),
1021
    .reset_request_n                      (reset_request_n),
1022
    .phs_shft_busy                        (phs_shft_busy),
1023
    .seq_pll_inc_dec_n                    (seq_pll_inc_dec_n),
1024
    .seq_pll_select                       (seq_pll_select),
1025
    .seq_pll_start_reconfig               (seq_pll_start_reconfig),
1026
    .mimic_data_1x                        (),
1027
    .mimic_data_2x                        (mimic_data),
1028
    .seq_clk_disable                      (seq_mem_clk_disable),
1029
    .ctrl_clk_disable                     (ctl_mem_clk_disable)
1030
);
1031
 
1032
// Instance the mimic block :
1033
 
1034
//
1035
altera_ddr_phy_alt_mem_phy_mimic #(
1036
    .NUM_MIMIC_SAMPLE_CYCLES (NUM_MIMIC_SAMPLE_CYCLES)
1037
) mmc (
1038
    .measure_clk             (measure_clk_2x),
1039
    .reset_measure_clk_n     (reset_measure_clk_2x_n),
1040
    .mimic_data_in           (mimic_data),
1041
    .seq_mmc_start           (seq_mmc_start),
1042
    .mmc_seq_done            (mmc_seq_done),
1043
    .mmc_seq_value           (mmc_seq_value)
1044
);
1045
 
1046
// If required, instance the Mimic debug block.  If the debug block is used, a top level input
1047
// for mimic_recapture_debug_data should be created.
1048
generate
1049
 
1050
    if (MIMIC_DEBUG_EN == 1)
1051
    begin : create_mimic_debug_ram
1052
 
1053
        //
1054
        altera_ddr_phy_alt_mem_phy_mimic_debug #(
1055
                    .NUM_DEBUG_SAMPLES_TO_STORE (NUM_DEBUG_SAMPLES_TO_STORE),
1056
            .PLL_STEPS_PER_CYCLE        (PLL_STEPS_PER_CYCLE)
1057
        ) mmc_debug (
1058
            .measure_clk                (measure_clk_1x),
1059
            .reset_measure_clk_n        (reset_measure_clk_1x_n),
1060
            .mmc_seq_done               (mmc_seq_done),
1061
            .mmc_seq_value              (mmc_seq_value),
1062
            .mimic_recapture_debug_data (1'b0)
1063
        );
1064
 
1065
    end
1066
 
1067
endgenerate
1068
 
1069
endmodule
1070
 
1071
`default_nettype wire
1072
 
1073
 
1074
//
1075
 
1076
`ifdef ALT_MEM_PHY_DEFINES
1077
`else
1078
`include "alt_mem_phy_defines.v"
1079
`endif
1080
 
1081
//
1082
module altera_ddr_phy_alt_mem_phy_clk_reset (
1083
                               pll_ref_clk,
1084
                               global_reset_n,
1085
                               soft_reset_n,
1086
 
1087
                               resync_clk_1x,
1088
 
1089
                               ac_clk_1x,
1090
                               ac_clk_2x,
1091
                               measure_clk_2x,
1092
                               measure_clk_1x,
1093
                               mem_clk_2x,
1094
                               mem_clk,
1095
                               mem_clk_n,
1096
                               phy_clk_1x,
1097
                               postamble_clk_2x,
1098
                               resync_clk_2x,
1099
                               cs_n_clk_1x,
1100
                               cs_n_clk_2x,
1101
                               write_clk_2x,
1102
                               half_rate_clk,
1103
 
1104
                               reset_ac_clk_1x_n,
1105
                               reset_ac_clk_2x_n,
1106
                               reset_measure_clk_2x_n,
1107
                               reset_measure_clk_1x_n,
1108
                               reset_mem_clk_2x_n,
1109
                               reset_phy_clk_1x_n,
1110
                               reset_poa_clk_2x_n,
1111
                               reset_resync_clk_2x_n,
1112
                               reset_resync_clk_1x_n,
1113
                               reset_write_clk_2x_n,
1114
                               reset_cs_n_clk_1x_n,
1115
                               reset_cs_n_clk_2x_n,
1116
                               mem_reset_n,
1117
 
1118
                               reset_request_n, // new output
1119
 
1120
                               phs_shft_busy,
1121
 
1122
                               seq_pll_inc_dec_n,
1123
                               seq_pll_select,
1124
                               seq_pll_start_reconfig,
1125
 
1126
                               mimic_data_1x,
1127
                               mimic_data_2x,
1128
 
1129
                               seq_clk_disable,
1130
                               ctrl_clk_disable
1131
 
1132
                              ) /* synthesis altera_attribute="disable_da_rule=\"R101,C104\"" */;
1133
 
1134
// Note the peculiar ranging below is necessary to use a generated CASE statement
1135
// later in the code :
1136
parameter       AC_PHASE                     =      "MEM_CLK";
1137
parameter       CLOCK_INDEX_WIDTH            =              3;
1138
parameter [0:0] CAPTURE_MIMIC_PATH           =              0;
1139
parameter [0:0] DDR_MIMIC_PATH_EN            =              1;
1140
parameter [0:0] DEDICATED_MEMORY_CLK_EN      =              0;
1141
parameter       DLL_EXPORT_IMPORT            =         "NONE";
1142
parameter       DWIDTH_RATIO                 =              4;
1143
parameter       LOCAL_IF_CLK_PS              =           4000;
1144
parameter       MEM_IF_CLK_PAIR_COUNT        =              3;
1145
parameter       MEM_IF_CLK_PS                =           4000;
1146
parameter       MEM_IF_CS_WIDTH              =              2;
1147
parameter       MEM_IF_DQ_PER_DQS            =              8;
1148
parameter       MEM_IF_DQS_WIDTH             =              8;
1149
parameter       MEM_IF_DWIDTH                =             64;
1150
parameter       MIF_FILENAME                 =      "PLL.MIF";
1151
parameter       PLL_EXPORT_IMPORT            =         "NONE";
1152
parameter       PLL_REF_CLK_PS               =           4000;
1153
parameter       PLL_TYPE                     =     "ENHANCED";
1154
parameter       SPEED_GRADE                  =           "C3";
1155
parameter       DLL_DELAY_BUFFER_MODE        =         "HIGH";
1156
parameter       DLL_DELAY_CHAIN_LENGTH       =             10;
1157
parameter       DQS_OUT_MODE                 = "DELAY_CHAIN2";
1158
parameter       DQS_PHASE                    =             72;
1159
parameter       SCAN_CLK_DIVIDE_BY           =              2;
1160
parameter       USE_MEM_CLK_FOR_ADDR_CMD_CLK =              1;
1161
 
1162
// Clock/reset inputs :
1163
input  wire                                                               global_reset_n;
1164
input  wire                                                               pll_ref_clk;
1165
 
1166
input  wire                                                               soft_reset_n;
1167
 
1168
input  wire [MEM_IF_DQS_WIDTH - 1 : 0]                                    resync_clk_1x;
1169
 
1170
// Clock/reset outputs :
1171
output wire                                                               ac_clk_1x;
1172
(* altera_attribute = "-name global_signal   global_clock" *) output wire ac_clk_2x;
1173
(* altera_attribute = "-name global_signal regional_clock" *) output wire measure_clk_2x;
1174
output wire                                                               measure_clk_1x;
1175
(* altera_attribute = "-name global_signal   global_clock" *) output wire mem_clk_2x;
1176
inout wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                                mem_clk;
1177
inout wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                                mem_clk_n;
1178
(* altera_attribute = "-name global_signal   global_clock" *) output wire phy_clk_1x;
1179
(* altera_attribute = "-name global_signal regional_clock" *) output wire postamble_clk_2x;
1180
(* altera_attribute = "-name global_signal regional_clock" *) output wire resync_clk_2x;
1181
output wire                                                               cs_n_clk_1x;
1182
(* altera_attribute = "-name global_signal   global_clock" *) output wire cs_n_clk_2x;
1183
(* altera_attribute = "-name global_signal   global_clock" *) output wire write_clk_2x;
1184
output wire                                                               half_rate_clk;
1185
 
1186
output wire                                                               reset_ac_clk_1x_n;
1187
output wire                                                               reset_ac_clk_2x_n;
1188
output wire                                                               reset_measure_clk_2x_n;
1189
output wire                                                               reset_measure_clk_1x_n;
1190
output wire                                                               reset_mem_clk_2x_n;
1191
output  reg                                                               reset_phy_clk_1x_n;
1192
output wire                                                               reset_poa_clk_2x_n;
1193
output wire                                                               reset_resync_clk_2x_n;
1194
output wire                                                               reset_resync_clk_1x_n;
1195
output wire                                                               reset_write_clk_2x_n;
1196
output wire                                                               reset_cs_n_clk_1x_n;
1197
output wire                                                               reset_cs_n_clk_2x_n;
1198
output wire                                                               mem_reset_n;
1199
 
1200
// This is the PLL locked signal :
1201
output wire                                                               reset_request_n;
1202
 
1203
// Misc I/O :
1204
output reg                                                                phs_shft_busy;
1205
 
1206
input  wire                                                               seq_pll_inc_dec_n;
1207
input  wire [CLOCK_INDEX_WIDTH - 1 : 0 ]                                  seq_pll_select;
1208
input  wire                                                               seq_pll_start_reconfig;
1209
 
1210
output wire                                                               mimic_data_1x;
1211
output wire                                                               mimic_data_2x;
1212
 
1213
input wire                                                                seq_clk_disable;
1214
input wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                                ctrl_clk_disable;
1215
 
1216
 
1217
 
1218
(*preserve*) reg                                                          seq_pll_start_reconfig_ams;
1219
(*preserve*) reg                                                          seq_pll_start_reconfig_r;
1220
(*preserve*) reg                                                          seq_pll_start_reconfig_2r;
1221
(*preserve*) reg                                                          seq_pll_start_reconfig_3r;
1222
 
1223
wire                                                                      pll_scanclk;
1224
wire                                                                      pll_scanread;
1225
wire                                                                      pll_scanwrite;
1226
wire                                                                      pll_scandata;
1227
wire                                                                      pll_scandone;
1228
wire                                                                      pll_scandataout;
1229
 
1230
reg                                                                       pll_new_dir;
1231
reg [2:0]                                                                 pll_new_phase;
1232
wire                                                                      pll_phase_auto_calibrate_pulse;
1233
 
1234
reg [`CLK_PLL_RECONFIG_FSM_WIDTH-1:0]                                     pll_reconfig_state;
1235
 
1236
reg                                                                       pll_reconfig_initialised;
1237
reg [CLOCK_INDEX_WIDTH - 1 : 0 ]                                          pll_current_phase;
1238
reg                                                                       pll_current_dir;
1239
 
1240
reg [`CLK_PLL_RECONFIG_FSM_WIDTH-1:0]                                     next_pll_reconfig_state;
1241
 
1242
reg                                                                       next_pll_reconfig_initialised;
1243
reg [CLOCK_INDEX_WIDTH - 1 : 0 ]                                          next_pll_current_phase;
1244
reg                                                                       next_pll_current_dir;
1245
 
1246
(*preserve*) reg                                                          pll_reprogram_request_pulse;   // 1 scan clk cycle long
1247
(*preserve*) reg                                                          pll_reprogram_request_pulse_r;
1248
(*preserve*) reg                                                          pll_reprogram_request_pulse_2r;
1249
wire                                                                      pll_reprogram_request_long_pulse; // 3 scan clk cycles long
1250
(*preserve*) reg                                                          pll_reprogram_request;
1251
 
1252
wire                                                                      pll_reconfig_busy;
1253
reg                                                                       pll_reconfig;
1254
reg                                                                       pll_reconfig_write_param;
1255
reg [3:0]                                                                 pll_reconfig_counter_type;
1256
reg [8:0]                                                                 pll_reconfig_data_in;
1257
 
1258
wire                                                                      pll_locked;
1259
 
1260
 
1261
wire                                                                      phy_internal_reset_n;
1262
wire                                                                      pll_reset;
1263
 
1264
(*preserve*) reg                                                          global_pre_clear;
1265
wire                                                                      global_or_soft_reset_n;
1266
 
1267
(*preserve*) reg                                                          clk_div_reset_ams_n   = 1'b0;
1268
(*preserve*) reg                                                          clk_div_reset_ams_n_r = 1'b0;
1269
 
1270
(*preserve*) reg                                                          pll_reconfig_reset_ams_n   = 1'b0;
1271
(*preserve*) reg                                                          pll_reconfig_reset_ams_n_r = 1'b0;
1272
 
1273
(*preserve*) reg                                                          reset_master_ams;
1274
 
1275
wire [MEM_IF_CLK_PAIR_COUNT - 1 : 0]                                      mimic_data_2x_internal;
1276
 
1277
// Create the scan clock.  This is a divided-down version of the PLL reference clock.
1278
// The scan chain will have an Fmax of around 100MHz, and so initially the scan clock is
1279
// created by a divide-by 4 circuit to allow plenty of margin with the expected reference
1280
// clock frequency of 100MHz.  This may be changed via the parameter.
1281
 
1282
reg [2:0]                                                                 divider  = 3'h0;
1283
(*preserve*) reg                                                          scan_clk = 1'b0;
1284
 
1285
 
1286
(*preserve*) reg                                                          global_reset_ams_n   = 1'b0;
1287
(*preserve*) reg                                                          global_reset_ams_n_r = 1'b0;
1288
 
1289
 
1290
wire                                                                      pll_phase_done;
1291
 
1292
(*preserve*) reg [2:0]                                                    seq_pll_start_reconfig_ccd_pipe;
1293
 
1294
(*preserve*) reg                                                          seq_pll_inc_dec_ccd;
1295
(*preserve*) reg [CLOCK_INDEX_WIDTH - 1 : 0]                              seq_pll_select_ccd ;
1296
 
1297
wire                                                                      pll_reconfig_reset_n;
1298
 
1299
wire                                                                      clk_divider_reset_n;
1300
 
1301
 
1302
// Output the PLL locked signal to be used as a reset_request_n - IE. reset when the PLL loses
1303
// lock :
1304
assign reset_request_n = pll_locked;
1305
 
1306
 
1307
 
1308
// Reset the scanclk clock divider if we either have a global_reset or the PLL loses lock
1309
assign pll_reconfig_reset_n = global_reset_n && pll_locked;
1310
 
1311
 
1312
// Clock divider circuit reset generation.
1313
always @(posedge phy_clk_1x or negedge pll_reconfig_reset_n)
1314
begin
1315
 
1316
    if (pll_reconfig_reset_n == 1'b0)
1317
    begin
1318
        clk_div_reset_ams_n   <= 1'b0;
1319
        clk_div_reset_ams_n_r <= 1'b0;
1320
    end
1321
 
1322
    else
1323
    begin
1324
        clk_div_reset_ams_n   <= 1'b1;
1325
        clk_div_reset_ams_n_r <= clk_div_reset_ams_n;
1326
    end
1327
 
1328
end
1329
 
1330
// PLL reconfig and synchronisation circuit reset generation.
1331
always @(posedge scan_clk or negedge pll_reconfig_reset_n)
1332
begin
1333
 
1334
    if (pll_reconfig_reset_n == 1'b0)
1335
    begin
1336
        pll_reconfig_reset_ams_n   <= 1'b0;
1337
        pll_reconfig_reset_ams_n_r <= 1'b0;
1338
    end
1339
 
1340
    else
1341
    begin
1342
        pll_reconfig_reset_ams_n   <= 1'b1;
1343
        pll_reconfig_reset_ams_n_r <= pll_reconfig_reset_ams_n;
1344
    end
1345
 
1346
end
1347
 
1348
// Create the scan clock.  Used for PLL reconfiguring in this block.
1349
 
1350
// Clock divider reset is the direct output of the AMS flops :
1351
assign clk_divider_reset_n = clk_div_reset_ams_n_r;
1352
 
1353
generate
1354
 
1355
    if (SCAN_CLK_DIVIDE_BY == 1)
1356
    begin : no_scan_clk_divider
1357
 
1358
        always @(phy_clk_1x)
1359
        begin
1360
            scan_clk = phy_clk_1x;
1361
        end
1362
 
1363
    end
1364
 
1365
    else
1366
    begin : gen_scan_clk
1367
 
1368
        always @(posedge phy_clk_1x or negedge clk_divider_reset_n)
1369
        begin
1370
 
1371
            if (clk_divider_reset_n == 1'b0)
1372
            begin
1373
                scan_clk  <= 1'b0;
1374
                divider   <= 3'h0;
1375
            end
1376
 
1377
            else
1378
            begin
1379
 
1380
                // This method of clock division does not require "divider" to be used
1381
                // as an intermediate clock:
1382
                if (divider == (SCAN_CLK_DIVIDE_BY / 2 - 1))
1383
                begin
1384
                    scan_clk <= ~scan_clk; // Toggle
1385
                    divider  <= 3'h0;
1386
                end
1387
 
1388
                else
1389
                begin
1390
                    scan_clk <= scan_clk; // Do not toggle
1391
                    divider  <= divider + 3'h1;
1392
                end
1393
 
1394
            end
1395
 
1396
        end
1397
 
1398
    end
1399
 
1400
endgenerate
1401
 
1402
 
1403
 
1404
 
1405
// NB. This lookup table shall be different for CIII/SIII
1406
// The PLL phasecounterselect is 3 bits wide, therefore hardcode the output to 3 bits :
1407
function [2:0] lookup;
1408
 
1409
input [CLOCK_INDEX_WIDTH-1:0] seq_num;
1410
begin
1411
    casez (seq_num)
1412
    3'b000  : lookup = 3'b010; // legal code
1413
    3'b001  : lookup = 3'b011; // legal code
1414
    3'b010  : lookup = 3'b111; // illegal - return code 3'b111
1415
    3'b011  : lookup = 3'b100; // legal code
1416
    3'b100  : lookup = 3'b110; // legal code
1417
    3'b101  : lookup = 3'b101; // legal code
1418
    3'b110  : lookup = 3'b111; // illegal - return code 3'b111
1419
    3'b111  : lookup = 3'b111; // illegal - return code 3'b111
1420
    default : lookup = 3'bxxx; // X propagation
1421
    endcase
1422
end
1423
 
1424
endfunction
1425
 
1426
 
1427
 
1428
// Metastable-harden seq_pll_start_reconfig signal (from the phy clock domain). NB:
1429
// by double-clocking this signal, it is not necessary to double-clock the
1430
// seq_pll_inc_dec_n and seq_pll_select signals - since they will only get
1431
// used on a positive edge of the metastable-hardened seq_pll_start_reconfig signal (so
1432
// should be stable by that point).
1433
 
1434
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
1435
begin
1436
 
1437
    if (reset_phy_clk_1x_n == 1'b0)
1438
    begin
1439
        seq_pll_inc_dec_ccd             <= 1'b0;
1440
        seq_pll_select_ccd              <= {CLOCK_INDEX_WIDTH{1'b0}};
1441
        seq_pll_start_reconfig_ccd_pipe <= 3'b000;
1442
    end
1443
 
1444
    // Generate 'ccd' Cross Clock Domain signals :
1445
    else
1446
    begin
1447
 
1448
        seq_pll_start_reconfig_ccd_pipe <= {seq_pll_start_reconfig_ccd_pipe[1:0], seq_pll_start_reconfig};
1449
 
1450
        if (seq_pll_start_reconfig == 1'b1 && seq_pll_start_reconfig_ccd_pipe[0] == 1'b0)
1451
        begin
1452
            seq_pll_inc_dec_ccd <= seq_pll_inc_dec_n;
1453
            seq_pll_select_ccd  <= seq_pll_select;
1454
        end
1455
 
1456
    end
1457
 
1458
end
1459
 
1460
 
1461
always @(posedge scan_clk or negedge pll_reconfig_reset_ams_n_r)
1462
begin
1463
 
1464
    if (pll_reconfig_reset_ams_n_r == 1'b0)
1465
    begin
1466
        seq_pll_start_reconfig_ams     <= 1'b0;
1467
        seq_pll_start_reconfig_r       <= 1'b0;
1468
        seq_pll_start_reconfig_2r      <= 1'b0;
1469
        seq_pll_start_reconfig_3r      <= 1'b0;
1470
 
1471
        pll_reprogram_request_pulse    <= 1'b0;
1472
        pll_reprogram_request_pulse_r  <= 1'b0;
1473
        pll_reprogram_request_pulse_2r <= 1'b0;
1474
        pll_reprogram_request          <= 1'b0;
1475
    end
1476
 
1477
    else
1478
    begin
1479
        seq_pll_start_reconfig_ams     <= seq_pll_start_reconfig_ccd_pipe[2];
1480
        seq_pll_start_reconfig_r       <= seq_pll_start_reconfig_ams;
1481
        seq_pll_start_reconfig_2r      <= seq_pll_start_reconfig_r;
1482
        seq_pll_start_reconfig_3r      <= seq_pll_start_reconfig_2r;
1483
 
1484
        pll_reprogram_request_pulse    <= pll_phase_auto_calibrate_pulse;
1485
        pll_reprogram_request_pulse_r  <= pll_reprogram_request_pulse;
1486
        pll_reprogram_request_pulse_2r <= pll_reprogram_request_pulse_r;
1487
        pll_reprogram_request          <= pll_reprogram_request_long_pulse;
1488
 
1489
    end
1490
 
1491
end
1492
 
1493
 
1494
 
1495
// Rising-edge detect to generate a single phase shift step
1496
assign pll_phase_auto_calibrate_pulse = ~seq_pll_start_reconfig_3r && seq_pll_start_reconfig_2r;
1497
 
1498
// extend the phase shift request pulse to be 3 scan clk cycles long.
1499
assign pll_reprogram_request_long_pulse = pll_reprogram_request_pulse || pll_reprogram_request_pulse_r || pll_reprogram_request_pulse_2r;
1500
 
1501
 
1502
 
1503
// Register the Phase step settings
1504
always @(posedge scan_clk or negedge pll_reconfig_reset_ams_n_r)
1505
begin
1506
    if (pll_reconfig_reset_ams_n_r == 1'b0)
1507
    begin
1508
        pll_new_dir   <= 1'b0;
1509
        pll_new_phase <= 3'h0; // CIII PLL has 3bit phase select
1510
    end
1511
 
1512
    else
1513
    begin
1514
 
1515
        if (pll_phase_auto_calibrate_pulse)
1516
        begin
1517
            pll_new_dir   <= seq_pll_inc_dec_ccd;
1518
            pll_new_phase <= lookup(seq_pll_select_ccd);
1519
        end
1520
 
1521
    end
1522
end
1523
 
1524
 
1525
 
1526
// generate the busy signal - just the inverse of the done o/p from the pll OR'd with the reprogram request (in case the done o/p is missed).
1527
always @(posedge scan_clk or negedge pll_reconfig_reset_ams_n_r)
1528
begin
1529
 
1530
    if (pll_reconfig_reset_ams_n_r == 1'b0)
1531
        phs_shft_busy <= 1'b0;
1532
 
1533
    else
1534
        phs_shft_busy <= pll_reprogram_request || ~pll_phase_done;
1535
 
1536
end
1537
 
1538
 
1539
 
1540
 
1541
// Gate the soft reset input (from SOPC builder for example) with the PLL
1542
// locked signal :
1543
assign global_or_soft_reset_n  = soft_reset_n && global_reset_n;
1544
 
1545
// Create the PHY internal reset signal :
1546
assign phy_internal_reset_n = pll_locked && global_or_soft_reset_n;
1547
 
1548
// The PLL resets only on a global reset :
1549
assign pll_reset = !global_reset_n;
1550
 
1551
 
1552
generate
1553
 
1554
    // Half-rate mode :
1555
    if (DWIDTH_RATIO == 4)
1556
    begin
1557
 
1558
 
1559
        //
1560
        altera_ddr_phy_alt_mem_phy_pll pll(
1561
                    .areset(pll_reset),
1562
            .inclk0(pll_ref_clk),
1563
            .phasecounterselect(pll_new_phase),
1564
            .phasestep(pll_reprogram_request),
1565
            .phaseupdown(pll_new_dir),
1566
            .scanclk(scan_clk),
1567
            .c0(phy_clk_1x),
1568
            .c1(mem_clk_2x),
1569
            .c2(write_clk_2x),
1570
            .c3(resync_clk_2x),
1571
            .c4(measure_clk_2x),
1572
            .locked(pll_locked),
1573
            .phasedone(pll_phase_done)
1574
        );
1575
 
1576
        assign half_rate_clk = phy_clk_1x;
1577
 
1578
    end
1579
 
1580
    // Full-rate mode :
1581
    else
1582
    begin
1583
 
1584
 
1585
        //
1586
        altera_ddr_phy_alt_mem_phy_pll pll(
1587
                    .areset(pll_reset),
1588
            .inclk0(pll_ref_clk),
1589
            .phasecounterselect(pll_new_phase),
1590
            .phasestep(pll_reprogram_request),
1591
            .phaseupdown(pll_new_dir),
1592
            .scanclk(scan_clk),
1593
            .c0(half_rate_clk),
1594
            .c1(mem_clk_2x),
1595
            .c2(write_clk_2x),
1596
            .c3(resync_clk_2x),
1597
            .c4(measure_clk_2x),
1598
            .locked(pll_locked),
1599
            .phasedone(pll_phase_done)
1600
        );
1601
 
1602
        // NB. phy_clk_1x is now full-rate, despite the "1x" naming convention :
1603
        assign phy_clk_1x = mem_clk_2x;
1604
 
1605
    end
1606
 
1607
endgenerate
1608
 
1609
 
1610
// The postamble clock is the inverse of the resync clock
1611
assign postamble_clk_2x = ~resync_clk_2x;
1612
 
1613
 
1614
generate
1615
 
1616
    if (USE_MEM_CLK_FOR_ADDR_CMD_CLK == 1)
1617
    begin
1618
 
1619
        assign ac_clk_2x   = mem_clk_2x;
1620
        assign cs_n_clk_2x = mem_clk_2x;
1621
 
1622
    end
1623
 
1624
    else
1625
    begin
1626
 
1627
        assign ac_clk_2x   = write_clk_2x;
1628
        assign cs_n_clk_2x = write_clk_2x;
1629
 
1630
    end
1631
 
1632
endgenerate
1633
 
1634
//These clocks are only required for half-rate IO cells, IE. SIII :
1635
assign ac_clk_1x   = 1'b0;
1636
assign cs_n_clk_1x = 1'b0;
1637
 
1638
 
1639
//NB. cannot use altddio_out instantiations, as need the combout and regout outputs for mimic path.
1640
generate
1641
genvar clk_pair;
1642
 
1643
    case ({DDR_MIMIC_PATH_EN, CAPTURE_MIMIC_PATH, DEDICATED_MEMORY_CLK_EN})
1644
 
1645
    // Mimic path option 1 - this is the default configuration
1646
    default :
1647
    begin
1648
 
1649
    for (clk_pair = 0 ; clk_pair < MEM_IF_CLK_PAIR_COUNT; clk_pair = clk_pair + 1)
1650
    begin : DDR_CLK_OUT
1651
 
1652
        // Instance "mem_clk" output pad, with appropriate mimic path connections :
1653
        altddio_bidir   #(
1654
            .extend_oe_disable ("UNUSED"),
1655
            .implement_input_in_lcell ("UNUSED"),
1656
            .intended_device_family ("Cyclone III"),
1657
            .invert_output ("OFF"),
1658
            .lpm_type ("altddio_bidir"),
1659
            .oe_reg ("UNUSED"),
1660
            .power_up_high ("OFF"),
1661
            .width (1)
1662
 
1663
        )ddr_clk_out_p (
1664
            .padio (mem_clk[clk_pair]),
1665
            .outclock (~mem_clk_2x),
1666
            .inclock (measure_clk_2x),
1667
            .oe (1'b1),
1668
            .datain_h (1'b0),
1669
            .datain_l (1'b1),
1670
            .dataout_h (mimic_data_2x_internal[clk_pair]),
1671
            .dataout_l (),
1672
            .aclr (seq_clk_disable || ctrl_clk_disable[clk_pair]),
1673
            .aset (),
1674
            .combout (),
1675
            .dqsundelayedout (),
1676
            .inclocken (),
1677
            .oe_out (),
1678
            .outclocken (1'b1),
1679
            .sclr (1'b0),
1680
            .sset (1'b0)
1681
        );
1682
 
1683
        // Instance "mem_clk_n" output pad, no mimic connections made as these are on the
1684
        // 'mem_clk' :
1685
        altddio_bidir   #(
1686
            .extend_oe_disable ("UNUSED"),
1687
            .implement_input_in_lcell ("UNUSED"),
1688
            .intended_device_family ("Cyclone III"),
1689
            .invert_output ("OFF"),
1690
            .lpm_type ("altddio_bidir"),
1691
            .oe_reg ("UNUSED"),
1692
            .power_up_high ("OFF"),
1693
            .width (1)
1694
        )ddr_clk_out_n (
1695
            .padio (mem_clk_n[clk_pair]),
1696
            .outclock (mem_clk_2x),
1697
            .inclock (),
1698
            .oe (1'b1),
1699
            .datain_h (1'b0),
1700
            .datain_l (1'b1),
1701
            .dataout_h (),
1702
            .dataout_l (),
1703
            .aclr (seq_clk_disable || ctrl_clk_disable[clk_pair]),
1704
            .aset (),
1705
            .combout (),
1706
            .dqsundelayedout (),
1707
            .inclocken (),
1708
            .oe_out (),
1709
            .outclocken (1'b1),
1710
            .sclr (1'b0),
1711
            .sset (1'b0)
1712
        );
1713
 
1714
 
1715
    end //for
1716
 
1717
    // Pick off the mimic data from the first internal mimic_data signal :
1718
    assign mimic_data_2x = mimic_data_2x_internal[0];
1719
 
1720
    end // caseitem
1721
 
1722
    endcase
1723
 
1724
endgenerate
1725
 
1726
 
1727
 
1728
 
1729
 
1730
// Master reset generation :
1731
always @(posedge phy_clk_1x or negedge phy_internal_reset_n)
1732
begin
1733
 
1734
    if (phy_internal_reset_n == 1'b0)
1735
    begin
1736
        reset_master_ams   <= 1'b0;
1737
        global_pre_clear    <= 1'b0;
1738
    end
1739
 
1740
    else
1741
    begin
1742
        reset_master_ams   <= 1'b1;
1743
        global_pre_clear    <= reset_master_ams;
1744
    end
1745
 
1746
end
1747
 
1748
 
1749
// phy_clk reset generation :
1750
always @(posedge phy_clk_1x or negedge global_pre_clear)
1751
begin
1752
 
1753
    if (global_pre_clear == 1'b0)
1754
    begin
1755
        reset_phy_clk_1x_n <= 1'b0;
1756
    end
1757
 
1758
    else
1759
    begin
1760
        reset_phy_clk_1x_n <= global_pre_clear;
1761
    end
1762
 
1763
end
1764
 
1765
 
1766
 
1767
 
1768
 
1769
// NB. phy_clk reset is generated above.
1770
 
1771
// Tie-off SIII-only outputs :
1772
assign reset_ac_clk_1x_n      = 1'b0;
1773
assign reset_cs_n_clk_1x_n    = 1'b0;
1774
assign reset_resync_clk_1x_n  = 1'b0;
1775
assign reset_measure_clk_1x_n = 1'b0;
1776
assign measure_clk_1x         = 1'b0;
1777
assign mimic_data_1x          = 1'b0;
1778
 
1779
// mem_clk reset generation :
1780
 
1781
//
1782
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (2) )         mem_pipe(
1783
                                                              .clock     (mem_clk_2x),
1784
                                                              .pre_clear (global_pre_clear),
1785
                                                              .reset_out (mem_reset_n)
1786
                                                            );
1787
 
1788
// ac_clk_2x reset generation :
1789
//
1790
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (2) )   ac_clk_pipe_2x(
1791
                                                              .clock     (ac_clk_2x),
1792
                                                              .pre_clear (global_pre_clear),
1793
                                                              .reset_out (reset_ac_clk_2x_n)
1794
                                                            );
1795
 
1796
// measure_clk_2x reset generation :
1797
//
1798
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (2) ) measure_clk_pipe(
1799
                                                              .clock     (measure_clk_2x),
1800
                                                              .pre_clear (global_pre_clear),
1801
                                                              .reset_out (reset_measure_clk_2x_n)
1802
                                                            );
1803
 
1804
// mem_clk_2x reset generation :
1805
//
1806
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (4) )     mem_clk_pipe(
1807
                                                              .clock     (mem_clk_2x),
1808
                                                              .pre_clear (global_pre_clear),
1809
                                                              .reset_out (reset_mem_clk_2x_n)
1810
                                                            );
1811
 
1812
// poa_clk_2x reset generation :
1813
//
1814
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (2) )     poa_clk_pipe(
1815
                                                              .clock     (postamble_clk_2x),
1816
                                                              .pre_clear (global_pre_clear),
1817
                                                              .reset_out (reset_poa_clk_2x_n)
1818
                                                            );
1819
 
1820
// resync_clk_2x reset generation :
1821
//
1822
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (2) )  resync_clk_pipe(
1823
                                                              .clock     (resync_clk_2x),
1824
                                                              .pre_clear (global_pre_clear),
1825
                                                              .reset_out (reset_resync_clk_2x_n)
1826
                                                            );
1827
 
1828
 
1829
// write_clk_2x reset generation :
1830
//
1831
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (4) )   write_clk_pipe(
1832
                                                              .clock     (write_clk_2x),
1833
                                                              .pre_clear (global_pre_clear),
1834
                                                              .reset_out (reset_write_clk_2x_n)
1835
                                                            );
1836
 
1837
 
1838
// cs_clk_2x reset generation :
1839
//
1840
altera_ddr_phy_alt_mem_phy_reset_pipe # (.PIPE_DEPTH (4) ) cs_n_clk_pipe_2x(
1841
                                                              .clock     (cs_n_clk_2x),
1842
                                                              .pre_clear (global_pre_clear),
1843
                                                              .reset_out (reset_cs_n_clk_2x_n)
1844
                                                            );
1845
 
1846
 
1847
endmodule
1848
 
1849
//
1850
 
1851
`default_nettype none
1852
 
1853
`ifdef ALT_MEM_PHY_DEFINES
1854
`else
1855
`include "alt_mem_phy_defines.v"
1856
`endif
1857
 
1858
//
1859
module altera_ddr_phy_alt_mem_phy_ac (
1860
                            clk_2x,
1861
                            reset_2x_n,
1862
                            phy_clk_1x,
1863
                            ctl_add_1t_ac_lat,
1864
                            ctl_negedge_en,
1865
                            ctl_add_intermediate_regs,
1866
                            period_sel,
1867
                            seq_ac_sel,
1868
                            ctl_ac_h,
1869
                            ctl_ac_l,
1870
                            seq_ac_h,
1871
                            seq_ac_l,
1872
                            mem_ac );
1873
parameter POWER_UP_HIGH = 1;
1874
parameter DWIDTH_RATIO  = 4;
1875
 
1876
// NB. clk_2x could be either ac_clk_2x or cs_n_clk_2x :
1877
input wire   clk_2x;
1878
input wire   reset_2x_n;
1879
input wire   phy_clk_1x;
1880
 
1881
input wire   ctl_add_1t_ac_lat;
1882
input wire   ctl_negedge_en;
1883
input wire   ctl_add_intermediate_regs;
1884
input wire   period_sel;
1885
input wire   seq_ac_sel;
1886
 
1887
input wire   ctl_ac_h;
1888
input wire   ctl_ac_l;
1889
 
1890
input wire   seq_ac_h;
1891
input wire   seq_ac_l;
1892
 
1893
output wire  mem_ac;
1894
 
1895
(* preserve *) reg  ac_h_r     = POWER_UP_HIGH[0];
1896
(* preserve *) reg  ac_l_r     = POWER_UP_HIGH[0];
1897
(* preserve *) reg  ac_h_2r    = POWER_UP_HIGH[0];
1898
(* preserve *) reg  ac_l_2r    = POWER_UP_HIGH[0];
1899
(* preserve *) reg  ac_1t      = POWER_UP_HIGH[0];
1900
(* preserve *) reg  ac_2x      = POWER_UP_HIGH[0];
1901
(* preserve *) reg  ac_2x_r    = POWER_UP_HIGH[0];
1902
(* preserve *) reg  ac_2x_2r   = POWER_UP_HIGH[0];
1903
(* preserve *) reg  ac_2x_mux  = POWER_UP_HIGH[0];
1904
 
1905
reg ac_2x_retime     = POWER_UP_HIGH[0];
1906
reg ac_2x_retime_r   = POWER_UP_HIGH[0];
1907
reg ac_2x_deg_choice = POWER_UP_HIGH[0];
1908
 
1909
reg ac_h;
1910
reg ac_l;
1911
 
1912
wire reset_2x ;
1913
assign reset_2x         = ~reset_2x_n;
1914
 
1915
generate
1916
 
1917
    if (DWIDTH_RATIO == 4) //HR
1918
    begin : hr_mux_gen
1919
 
1920
        // Half Rate DDR memory types require an extra cycle of latency :
1921
        always @(posedge phy_clk_1x)
1922
        begin
1923
 
1924
            casez(seq_ac_sel)
1925
 
1926
            1'b0 :
1927
            begin
1928
                ac_l <= ctl_ac_l;
1929
                ac_h <= ctl_ac_h;
1930
            end
1931
 
1932
            1'b1 :
1933
            begin
1934
                ac_l <= seq_ac_l;
1935
                ac_h <= seq_ac_h;
1936
            end
1937
 
1938
            endcase
1939
 
1940
        end //always   
1941
 
1942
    end
1943
 
1944
    else // FR
1945
    begin : fr_passthru_gen
1946
 
1947
        // Note that "_h" is unused in full-rate and no latency
1948
        // is required :
1949
        always @*
1950
        begin
1951
 
1952
            casez(seq_ac_sel)
1953
 
1954
            1'b0 :
1955
            begin
1956
                ac_l <= ctl_ac_l;
1957
            end
1958
 
1959
            1'b1 :
1960
            begin
1961
                ac_l <= seq_ac_l;
1962
            end
1963
 
1964
            endcase
1965
 
1966
        end
1967
    end
1968
 
1969
endgenerate
1970
 
1971
generate
1972
 
1973
    if (DWIDTH_RATIO == 4)
1974
    begin : half_rate
1975
 
1976
        // Initial registering of inputs :
1977
        always @(posedge phy_clk_1x)
1978
        begin
1979
            ac_h_r  <= ac_h;
1980
            ac_l_r  <= ac_l;
1981
        end
1982
 
1983
 
1984
        // Select high and low phases periodically to create the _2x signal :
1985
        always @*
1986
        begin
1987
 
1988
            casez(period_sel)
1989
 
1990
            1'b0     : ac_2x = ac_l_2r;
1991
            1'b1     : ac_2x = ac_h_2r;
1992
            default  : ac_2x = 1'bx; // X propagaton
1993
 
1994
            endcase
1995
 
1996
        end
1997
 
1998
        always @(posedge clk_2x)
1999
        begin
2000
 
2001
            // Second stage of registering - on clk_2x
2002
            ac_h_2r <= ac_h_r;
2003
            ac_l_2r <= ac_l_r;
2004
 
2005
            // 1t registering - used if ctl_add_1t_ac_lat is true
2006
            ac_1t   <= ac_2x;
2007
 
2008
            // AC_PHASE==270 requires an extra cycle of delay :
2009
            ac_2x_deg_choice <= ac_1t;
2010
 
2011
            // If not at AC_PHASE==270, ctl_add_intermediate_regs shall be zero :
2012
            if (ctl_add_intermediate_regs == 1'b0)
2013
            begin
2014
 
2015
                if (ctl_add_1t_ac_lat == 1'b1)
2016
                begin
2017
                    ac_2x_r <= ac_1t;
2018
                end
2019
 
2020
                else
2021
                begin
2022
                    ac_2x_r <= ac_2x;
2023
                end
2024
 
2025
            end
2026
 
2027
            // If at AC_PHASE==270, ctl_add_intermediate_regs shall be one
2028
            // and an extra cycle delay is required :
2029
            else
2030
            begin
2031
 
2032
                if (ctl_add_1t_ac_lat == 1'b1)
2033
                begin
2034
                    ac_2x_r <= ac_2x_deg_choice;
2035
                end
2036
 
2037
                else
2038
                begin
2039
                    ac_2x_r <= ac_1t;
2040
                end
2041
 
2042
            end
2043
 
2044
            // Register the above output for use when ctl_negedge_en is set :
2045
            ac_2x_2r <= ac_2x_r;
2046
 
2047
        end
2048
 
2049
 
2050
        // Determine whether to select the "_r" or "_2r" variant :
2051
        always @*
2052
        begin
2053
 
2054
            casez(ctl_negedge_en)
2055
 
2056
            1'b0     : ac_2x_mux = ac_2x_r;
2057
            1'b1     : ac_2x_mux = ac_2x_2r;
2058
            default  : ac_2x_mux = 1'bx; // X propagaton
2059
 
2060
            endcase
2061
 
2062
        end
2063
 
2064
        if (POWER_UP_HIGH == 1)
2065
        begin
2066
 
2067
            altddio_out #(
2068
                .extend_oe_disable      ("UNUSED"),
2069
                .intended_device_family ("Cyclone III"),
2070
                .lpm_hint               ("UNUSED"),
2071
                .lpm_type               ("altddio_out"),
2072
                .oe_reg                 ("UNUSED"),
2073
                .power_up_high          ("ON"),
2074
                .width                  (1)
2075
            ) addr_pin (
2076
                .aset                   (reset_2x),
2077
                .datain_h               (ac_2x_mux),
2078
                .datain_l               (ac_2x_r),
2079
                .dataout                (mem_ac),
2080
                .oe                     (1'b1),
2081
                .outclock               (clk_2x),
2082
                .outclocken             (1'b1),
2083
                .aclr                   (),
2084
                .sset                   (),
2085
                .sclr                   (),
2086
                .oe_out                 ()
2087
            );
2088
 
2089
        end
2090
 
2091
        else
2092
        begin
2093
 
2094
            altddio_out #(
2095
                .extend_oe_disable      ("UNUSED"),
2096
                .intended_device_family ("Cyclone III"),
2097
                .lpm_hint               ("UNUSED"),
2098
                .lpm_type               ("altddio_out"),
2099
                .oe_reg                 ("UNUSED"),
2100
                .power_up_high          ("OFF"),
2101
                .width                  (1)
2102
            ) addr_pin (
2103
                .aclr                   (reset_2x),
2104
                .aset                   (),
2105
                .datain_h               (ac_2x_mux),
2106
                .datain_l               (ac_2x_r),
2107
                .dataout                (mem_ac),
2108
                .oe                     (1'b1),
2109
                .outclock               (clk_2x),
2110
                .outclocken             (1'b1),
2111
                .sset                   (),
2112
                .sclr                   (),
2113
                .oe_out                 ()
2114
 
2115
            );
2116
 
2117
        end
2118
 
2119
    end // Half-rate
2120
 
2121
    // full-rate
2122
    else
2123
    begin : full_rate
2124
 
2125
        always @(posedge phy_clk_1x)
2126
        begin
2127
 
2128
            // 1t registering - only used if ctl_add_1t_ac_lat is true
2129
            ac_1t <= ac_l;
2130
 
2131
            // add 1 addr_clock delay if "Add 1T" is set:
2132
           if (ctl_add_1t_ac_lat == 1'b1)
2133
               ac_2x <= ac_1t;
2134
           else
2135
               ac_2x <= ac_l;
2136
 
2137
        end
2138
 
2139
        always @(posedge clk_2x)
2140
        begin
2141
            ac_2x_deg_choice <= ac_2x;
2142
        end
2143
 
2144
        // Note this is for 270 degree operation to align it to the correct clock phase.
2145
        always @*
2146
        begin
2147
            casez(ctl_add_intermediate_regs)
2148
                1'b0     : ac_2x_r = ac_2x;
2149
                1'b1     : ac_2x_r = ac_2x_deg_choice;
2150
                default  : ac_2x_r = 1'bx; // X propagaton
2151
            endcase
2152
        end
2153
 
2154
        always @(posedge clk_2x)
2155
        begin
2156
            ac_2x_2r <= ac_2x_r;
2157
        end
2158
 
2159
        // Determine whether to select the "_r" or "_2r" variant :
2160
        always @*
2161
        begin
2162
            casez(ctl_negedge_en)
2163
                1'b0     : ac_2x_mux = ac_2x_r;
2164
                1'b1     : ac_2x_mux = ac_2x_2r;
2165
                default  : ac_2x_mux = 1'bx; // X propagaton
2166
            endcase
2167
        end
2168
 
2169
        if (POWER_UP_HIGH == 1)
2170
        begin
2171
 
2172
            altddio_out #(
2173
                .extend_oe_disable      ("UNUSED"),
2174
                .intended_device_family ("Cyclone III"),
2175
                .lpm_hint               ("UNUSED"),
2176
                .lpm_type               ("altddio_out"),
2177
                .oe_reg                 ("UNUSED"),
2178
                .power_up_high          ("ON"),
2179
                .width                  (1)
2180
            ) addr_pin (
2181
                .aset                   (reset_2x),
2182
                .datain_h               (ac_2x_mux),
2183
                .datain_l               (ac_2x_r),
2184
                .dataout                (mem_ac),
2185
                .oe                     (1'b1),
2186
                .outclock               (clk_2x),
2187
                .outclocken             (1'b1),
2188
                .aclr                   (),
2189
                .sclr                   (),
2190
                .sset                   (),
2191
                .oe_out                 ()
2192
            );
2193
 
2194
        end
2195
 
2196
        else
2197
        begin
2198
 
2199
            altddio_out #(
2200
                .extend_oe_disable      ("UNUSED"),
2201
                .intended_device_family ("Cyclone III"),
2202
                .lpm_hint               ("UNUSED"),
2203
                .lpm_type               ("altddio_out"),
2204
                .oe_reg                 ("UNUSED"),
2205
                .power_up_high          ("OFF"),
2206
                .width                  (1)
2207
            ) addr_pin (
2208
                .aclr                   (reset_2x),
2209
                .datain_h               (ac_2x_mux),
2210
                .datain_l               (ac_2x_r),
2211
                .dataout                (mem_ac),
2212
                .oe                     (1'b1),
2213
                .outclock               (clk_2x),
2214
                .outclocken             (1'b1),
2215
                .aset                   (),
2216
                .sclr                   (),
2217
                .sset                   (),
2218
                .oe_out                 ()
2219
            );
2220
 
2221
        end // else: !if(POWER_UP_HIGH == 1) 
2222
 
2223
    end // block: full_rate
2224
 
2225
endgenerate
2226
 
2227
endmodule
2228
 
2229
`default_nettype wire
2230
 
2231
//
2232
 
2233
`default_nettype none
2234
 
2235
`ifdef ALT_MEM_PHY_DEFINES
2236
`else
2237
`include "alt_mem_phy_defines.v"
2238
`endif
2239
 
2240
//
2241
module altera_ddr_phy_alt_mem_phy_addr_cmd ( ac_clk_1x,
2242
                                  ac_clk_2x,
2243
                                  cs_n_clk_1x,
2244
                                  cs_n_clk_2x,
2245
                                  phy_clk_1x,
2246
                                  reset_ac_clk_1x_n,
2247
                                  reset_ac_clk_2x_n,
2248
                                  reset_cs_n_clk_1x_n,
2249
                                  reset_cs_n_clk_2x_n,
2250
 
2251
                                  // Addr/cmd interface from controller
2252
                                  ctl_add_1t_ac_lat,
2253
                                  ctl_add_1t_odt_lat,
2254
                                  ctl_add_intermediate_regs,
2255
 
2256
                                  ctl_negedge_en,
2257
                                                  ctl_mem_addr_h,
2258
                                  ctl_mem_addr_l,
2259
                                  ctl_mem_ba_h,
2260
                                  ctl_mem_ba_l,
2261
                                  ctl_mem_cas_n_h,
2262
                                  ctl_mem_cas_n_l,
2263
                                  ctl_mem_cke_h,
2264
                                  ctl_mem_cke_l,
2265
                                  ctl_mem_cs_n_h,
2266
                                  ctl_mem_cs_n_l,
2267
                                  ctl_mem_odt_h,
2268
                                  ctl_mem_odt_l,
2269
                                  ctl_mem_ras_n_h,
2270
                                  ctl_mem_ras_n_l,
2271
                                  ctl_mem_we_n_h,
2272
                                  ctl_mem_we_n_l,
2273
 
2274
                                  // Interface from Sequencer, used for calibration
2275
                                  // as the MRS registers need to be controlled :
2276
                                  seq_addr_h,
2277
                                  seq_addr_l,
2278
                                  seq_ba_h,
2279
                                  seq_ba_l,
2280
                                  seq_cas_n_h,
2281
                                  seq_cas_n_l,
2282
                                  seq_cke_h,
2283
                                  seq_cke_l,
2284
                                  seq_cs_n_h,
2285
                                  seq_cs_n_l,
2286
                                  seq_odt_h,
2287
                                  seq_odt_l,
2288
                                  seq_ras_n_h,
2289
                                  seq_ras_n_l,
2290
                                  seq_we_n_h,
2291
                                  seq_we_n_l,
2292
 
2293
                                  seq_ac_sel,
2294
 
2295
                                  mem_addr,
2296
                                  mem_ba,
2297
                                  mem_cas_n,
2298
                                  mem_cke,
2299
                                  mem_cs_n,
2300
                                  mem_odt,
2301
                                  mem_ras_n,
2302
                                  mem_we_n );
2303
 
2304
 
2305
parameter DWIDTH_RATIO            =           4;
2306
parameter MEM_ADDR_CMD_BUS_COUNT  =           1;
2307
parameter MEM_IF_BANKADDR_WIDTH   =           3;
2308
parameter MEM_IF_CS_WIDTH         =           2;
2309
parameter MEM_IF_MEMTYPE          =       "DDR";
2310
parameter MEM_IF_ROWADDR_WIDTH    =          13;
2311
 
2312
input wire                                  cs_n_clk_1x;
2313
input wire                                  cs_n_clk_2x;
2314
input wire                                  ac_clk_1x;
2315
input wire                                  ac_clk_2x;
2316
input wire                                  phy_clk_1x;
2317
 
2318
input wire                                  reset_ac_clk_1x_n;
2319
input wire                                  reset_ac_clk_2x_n;
2320
input wire                                  reset_cs_n_clk_1x_n;
2321
input wire                                  reset_cs_n_clk_2x_n;
2322
 
2323
input wire [MEM_IF_ROWADDR_WIDTH -1:0]      ctl_mem_addr_h;
2324
input wire [MEM_IF_ROWADDR_WIDTH -1:0]      ctl_mem_addr_l;
2325
input wire                                  ctl_add_1t_ac_lat;
2326
input wire                                  ctl_add_1t_odt_lat;
2327
input wire                                  ctl_negedge_en;
2328
input wire                                  ctl_add_intermediate_regs;
2329
input wire [MEM_IF_BANKADDR_WIDTH - 1:0]    ctl_mem_ba_h;
2330
input wire [MEM_IF_BANKADDR_WIDTH - 1:0]    ctl_mem_ba_l;
2331
input wire                                  ctl_mem_cas_n_h;
2332
input wire                                  ctl_mem_cas_n_l;
2333
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_cke_h;
2334
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_cke_l;
2335
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_cs_n_h;
2336
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_cs_n_l;
2337
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_odt_h;
2338
input wire [MEM_IF_CS_WIDTH - 1:0]          ctl_mem_odt_l;
2339
input wire                                  ctl_mem_ras_n_h;
2340
input wire                                  ctl_mem_ras_n_l;
2341
input wire                                  ctl_mem_we_n_h;
2342
input wire                                  ctl_mem_we_n_l;
2343
 
2344
input wire [MEM_IF_ROWADDR_WIDTH -1:0]      seq_addr_h;
2345
input wire [MEM_IF_ROWADDR_WIDTH -1:0]      seq_addr_l;
2346
input wire [MEM_IF_BANKADDR_WIDTH - 1:0]    seq_ba_h;
2347
input wire [MEM_IF_BANKADDR_WIDTH - 1:0]    seq_ba_l;
2348
input wire                                  seq_cas_n_h;
2349
input wire                                  seq_cas_n_l;
2350
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_cke_h;
2351
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_cke_l;
2352
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_cs_n_h;
2353
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_cs_n_l;
2354
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_odt_h;
2355
input wire [MEM_IF_CS_WIDTH - 1:0]          seq_odt_l;
2356
input wire                                  seq_ras_n_h;
2357
input wire                                  seq_ras_n_l;
2358
input wire                                  seq_we_n_h;
2359
input wire                                  seq_we_n_l;
2360
 
2361
input wire                                  seq_ac_sel;
2362
 
2363
output wire [MEM_IF_ROWADDR_WIDTH - 1 : 0]  mem_addr;
2364
output wire [MEM_IF_BANKADDR_WIDTH - 1 : 0] mem_ba;
2365
output wire                                 mem_cas_n;
2366
output wire [MEM_IF_CS_WIDTH - 1 : 0]       mem_cke;
2367
output wire [MEM_IF_CS_WIDTH - 1 : 0]       mem_cs_n;
2368
output wire [MEM_IF_CS_WIDTH - 1 : 0]       mem_odt;
2369
output wire                                 mem_ras_n;
2370
output wire                                 mem_we_n;
2371
 
2372
 
2373
// Periodical select registers - per group of pins
2374
reg  [`ADC_NUM_PIN_GROUPS-1:0]              count_addr = `ADC_NUM_PIN_GROUPS'b0;
2375
reg  [`ADC_NUM_PIN_GROUPS-1:0]              count_addr_2x = `ADC_NUM_PIN_GROUPS'b0;
2376
reg  [`ADC_NUM_PIN_GROUPS-1:0]              count_addr_2x_r = `ADC_NUM_PIN_GROUPS'b0;
2377
reg  [`ADC_NUM_PIN_GROUPS-1:0]              period_sel_addr = `ADC_NUM_PIN_GROUPS'b0;
2378
 
2379
 
2380
 
2381
generate
2382
genvar ia;
2383
 
2384
for (ia=0; ia<`ADC_NUM_PIN_GROUPS - 1; ia=ia+1)
2385
begin : SELECTS
2386
 
2387
    always @(posedge phy_clk_1x)
2388
    begin
2389
        count_addr[ia] <= ~count_addr[ia];
2390
    end
2391
 
2392
    always @(posedge ac_clk_2x)
2393
    begin
2394
        count_addr_2x[ia]   <= count_addr[ia];
2395
        count_addr_2x_r[ia] <= count_addr_2x[ia];
2396
        period_sel_addr[ia] <= ~(count_addr_2x_r[ia] ^ count_addr_2x[ia]);
2397
    end
2398
 
2399
end
2400
 
2401
endgenerate
2402
 
2403
 
2404
//now generate cs_n period sel, off the dedicated cs_n clock :
2405
always @(posedge phy_clk_1x)
2406
begin
2407
    count_addr[`ADC_CS_N_PERIOD_SEL] <= ~count_addr[`ADC_CS_N_PERIOD_SEL];
2408
end
2409
 
2410
always @(posedge cs_n_clk_2x)
2411
begin
2412
    count_addr_2x  [`ADC_CS_N_PERIOD_SEL] <= count_addr   [`ADC_CS_N_PERIOD_SEL];
2413
    count_addr_2x_r[`ADC_CS_N_PERIOD_SEL] <= count_addr_2x[`ADC_CS_N_PERIOD_SEL];
2414
    period_sel_addr[`ADC_CS_N_PERIOD_SEL] <= ~(count_addr_2x_r[`ADC_CS_N_PERIOD_SEL] ^ count_addr_2x[`ADC_CS_N_PERIOD_SEL]);
2415
end
2416
 
2417
 
2418
// Create the ADDR I/O structure :
2419
 
2420
generate
2421
genvar ib;
2422
 
2423
    for (ib=0; ib<MEM_IF_ROWADDR_WIDTH; ib=ib+1)
2424
    begin : addr
2425
 
2426
        //
2427
        altera_ddr_phy_alt_mem_phy_ac # (
2428
                    .POWER_UP_HIGH (1),
2429
            .DWIDTH_RATIO (DWIDTH_RATIO)
2430
        ) addr_struct (
2431
            .clk_2x                    (ac_clk_2x),
2432
            .reset_2x_n                (1'b1),
2433
            .phy_clk_1x                (phy_clk_1x),
2434
            .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2435
            .ctl_negedge_en            (ctl_negedge_en),
2436
            .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2437
            .period_sel                (period_sel_addr[`ADC_ADDR_PERIOD_SEL]),
2438
            .seq_ac_sel                (seq_ac_sel),
2439
            .ctl_ac_h                  (ctl_mem_addr_h[ib]),
2440
            .ctl_ac_l                  (ctl_mem_addr_l[ib]),
2441
            .seq_ac_h                  (seq_addr_h[ib]),
2442
            .seq_ac_l                  (seq_addr_l[ib]),
2443
            .mem_ac                    (mem_addr[ib])
2444
        );
2445
 
2446
    end
2447
 
2448
endgenerate
2449
 
2450
// Create the BANK_ADDR I/O structure :
2451
generate
2452
genvar ic;
2453
 
2454
    for (ic=0; ic<MEM_IF_BANKADDR_WIDTH; ic=ic+1)
2455
    begin : ba
2456
 
2457
        //
2458
        altera_ddr_phy_alt_mem_phy_ac #(
2459
                    .POWER_UP_HIGH (0),
2460
            .DWIDTH_RATIO (DWIDTH_RATIO)
2461
        ) ba_struct  (
2462
            .clk_2x                    (ac_clk_2x),
2463
            .reset_2x_n                (1'b1),
2464
            .phy_clk_1x                (phy_clk_1x),
2465
            .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2466
            .ctl_negedge_en            (ctl_negedge_en),
2467
            .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2468
            .period_sel                (period_sel_addr[`ADC_BA_PERIOD_SEL]),
2469
            .seq_ac_sel                (seq_ac_sel),
2470
            .ctl_ac_h                  (ctl_mem_ba_h[ic]),
2471
            .ctl_ac_l                  (ctl_mem_ba_l[ic]),
2472
            .seq_ac_h                  (seq_ba_h[ic]),
2473
            .seq_ac_l                  (seq_ba_l[ic]),
2474
            .mem_ac                    (mem_ba[ic])
2475
        );
2476
 
2477
    end
2478
 
2479
endgenerate
2480
 
2481
// Create the CAS_N I/O structure :
2482
//
2483
altera_ddr_phy_alt_mem_phy_ac #(
2484
    .POWER_UP_HIGH (1),
2485
    .DWIDTH_RATIO (DWIDTH_RATIO)
2486
 
2487
) cas_n_struct (
2488
    .clk_2x                    (ac_clk_2x),
2489
    .reset_2x_n                (1'b1),
2490
    .phy_clk_1x                (phy_clk_1x),
2491
    .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2492
    .ctl_negedge_en            (ctl_negedge_en),
2493
    .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2494
    .period_sel                (period_sel_addr[`ADC_CAS_N_PERIOD_SEL]),
2495
    .seq_ac_sel                (seq_ac_sel),
2496
    .ctl_ac_h                  (ctl_mem_cas_n_h),
2497
    .ctl_ac_l                  (ctl_mem_cas_n_l),
2498
    .seq_ac_h                  (seq_cas_n_h),
2499
    .seq_ac_l                  (seq_cas_n_l),
2500
    .mem_ac                    (mem_cas_n)
2501
);
2502
 
2503
 
2504
// Create the CKE I/O structure :
2505
generate
2506
genvar id;
2507
 
2508
    for (id=0; id<MEM_IF_CS_WIDTH; id=id+1)
2509
    begin : cke
2510
 
2511
        //
2512
        altera_ddr_phy_alt_mem_phy_ac # (
2513
                    .POWER_UP_HIGH (0),
2514
            .DWIDTH_RATIO (DWIDTH_RATIO)
2515
        ) cke_struct  (
2516
            .clk_2x                    (ac_clk_2x),
2517
            .reset_2x_n                (reset_ac_clk_2x_n),
2518
            .phy_clk_1x                (phy_clk_1x),
2519
            .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2520
            .ctl_negedge_en            (ctl_negedge_en),
2521
            .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2522
            .period_sel                (period_sel_addr[`ADC_CKE_PERIOD_SEL]),
2523
            .seq_ac_sel                (seq_ac_sel),
2524
            .ctl_ac_h                  (ctl_mem_cke_h[id]),
2525
            .ctl_ac_l                  (ctl_mem_cke_l[id]),
2526
            .seq_ac_h                  (seq_cke_h[id]),
2527
            .seq_ac_l                  (seq_cke_l[id]),
2528
            .mem_ac                    (mem_cke[id])
2529
        );
2530
 
2531
    end
2532
 
2533
endgenerate
2534
 
2535
 
2536
// Create the CS_N I/O structure.  Note that the 2x clock is different.
2537
generate
2538
genvar ie;
2539
 
2540
    for (ie=0; ie<MEM_IF_CS_WIDTH; ie=ie+1)
2541
    begin : cs_n
2542
 
2543
        //
2544
        altera_ddr_phy_alt_mem_phy_ac # (
2545
                    .POWER_UP_HIGH (1),
2546
            .DWIDTH_RATIO (DWIDTH_RATIO)
2547
        ) cs_n_struct (
2548
            .clk_2x                    (cs_n_clk_2x),
2549
            .reset_2x_n                (reset_ac_clk_2x_n),
2550
            .phy_clk_1x                (phy_clk_1x),
2551
            .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2552
            .ctl_negedge_en            (ctl_negedge_en),
2553
            .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2554
            .period_sel                (period_sel_addr[`ADC_CS_N_PERIOD_SEL]),
2555
            .seq_ac_sel                (seq_ac_sel),
2556
            .ctl_ac_h                  (ctl_mem_cs_n_h[ie]),
2557
            .ctl_ac_l                  (ctl_mem_cs_n_l[ie]),
2558
            .seq_ac_h                  (seq_cs_n_h[ie]),
2559
            .seq_ac_l                  (seq_cs_n_l[ie]),
2560
            .mem_ac                    (mem_cs_n[ie])
2561
        );
2562
 
2563
    end
2564
 
2565
endgenerate
2566
 
2567
 
2568
// Create the ODT I/O structure :
2569
 
2570
generate
2571
genvar ig;
2572
 
2573
    if (MEM_IF_MEMTYPE != "DDR")
2574
    begin : gen_odt
2575
 
2576
        for (ig=0; ig<MEM_IF_CS_WIDTH; ig=ig+1)
2577
        begin : odt
2578
 
2579
            //
2580
            altera_ddr_phy_alt_mem_phy_ac #(
2581
                        .POWER_UP_HIGH (0),
2582
                .DWIDTH_RATIO (DWIDTH_RATIO)
2583
            ) odt_struct  (
2584
                .clk_2x                            (ac_clk_2x),
2585
                .reset_2x_n                        (1'b1),
2586
                .phy_clk_1x                        (phy_clk_1x),
2587
                .ctl_add_1t_ac_lat             (ctl_add_1t_odt_lat),
2588
                .ctl_negedge_en                (ctl_negedge_en),
2589
                .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2590
                .period_sel                        (period_sel_addr[`ADC_ODT_PERIOD_SEL]),
2591
                .seq_ac_sel                (seq_ac_sel),
2592
            .ctl_ac_h                      (ctl_mem_odt_h[ig]),
2593
            .ctl_ac_l                      (ctl_mem_odt_l[ig]),
2594
            .seq_ac_h                      (seq_odt_h[ig]),
2595
            .seq_ac_l                      (seq_odt_l[ig]),
2596
            .mem_ac                        (mem_odt[ig])
2597
            );
2598
 
2599
        end
2600
 
2601
    end
2602
 
2603
endgenerate
2604
 
2605
 
2606
// Create the RAS_N I/O structure :
2607
//
2608
altera_ddr_phy_alt_mem_phy_ac # (
2609
    .POWER_UP_HIGH (1),
2610
    .DWIDTH_RATIO (DWIDTH_RATIO)
2611
) ras_n_struct  (
2612
    .clk_2x                    (ac_clk_2x),
2613
    .reset_2x_n                (1'b1),
2614
    .phy_clk_1x                (phy_clk_1x),
2615
    .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2616
    .ctl_negedge_en            (ctl_negedge_en),
2617
    .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2618
    .period_sel                (period_sel_addr[`ADC_RAS_N_PERIOD_SEL]),
2619
    .seq_ac_sel                (seq_ac_sel),
2620
    .ctl_ac_h                  (ctl_mem_ras_n_h),
2621
    .ctl_ac_l                  (ctl_mem_ras_n_l),
2622
    .seq_ac_h                  (seq_ras_n_h),
2623
    .seq_ac_l                  (seq_ras_n_l),
2624
    .mem_ac                    (mem_ras_n)
2625
);
2626
 
2627
 
2628
// Create the WE_N I/O structure :
2629
//
2630
altera_ddr_phy_alt_mem_phy_ac # (
2631
    .POWER_UP_HIGH (1),
2632
    .DWIDTH_RATIO (DWIDTH_RATIO)
2633
) we_n_struct  (
2634
    .clk_2x                    (ac_clk_2x),
2635
    .reset_2x_n                (1'b1),
2636
    .phy_clk_1x                (phy_clk_1x),
2637
    .ctl_add_1t_ac_lat         (ctl_add_1t_ac_lat),
2638
    .ctl_negedge_en            (ctl_negedge_en),
2639
    .ctl_add_intermediate_regs (ctl_add_intermediate_regs),
2640
    .period_sel                (period_sel_addr[`ADC_WE_N_PERIOD_SEL]),
2641
    .seq_ac_sel                (seq_ac_sel),
2642
    .ctl_ac_h                  (ctl_mem_we_n_h),
2643
    .ctl_ac_l                  (ctl_mem_we_n_l),
2644
    .seq_ac_h                  (seq_we_n_h),
2645
    .seq_ac_l                  (seq_we_n_l),
2646
    .mem_ac                    (mem_we_n)
2647
);
2648
 
2649
endmodule
2650
 
2651
`default_nettype wire
2652
 
2653
/* Legal Notice: (C)2006 Altera Corporation. All rights reserved.  Your
2654
   use of Altera Corporation's design tools, logic functions and other
2655
   software and tools, and its AMPP partner logic functions, and any
2656
   output files any of the foregoing (including device programming or
2657
   simulation files), and any associated documentation or information are
2658
   expressly subject to the terms and conditions of the Altera Program
2659
   License Subscription Agreement or other applicable license agreement,
2660
   including, without limitation, that your use is for the sole purpose
2661
   of programming logic devices manufactured by Altera and sold by Altera
2662
   or its authorized distributors.  Please refer to the applicable
2663
   agreement for further details. */
2664
 
2665
 
2666
/*////////////////////////////////////////////////////////////////////////////-
2667
  Title           : Datapath IO elements
2668
 
2669
  File:  $RCSfile : alt_mem_phy_dp_io.v,v $
2670
 
2671
  Last Modified   : $Date: 2009/04/01 $
2672
 
2673
  Revision        : $Revision: #1 $
2674
 
2675
  Abstract        : NewPhy Datapath IO atoms.  This block shall connect to both
2676
                    the read and write datapath blocks, abstracting the I/O
2677
                    elements from the remainder of the circuit.  This file
2678
                    instances atoms specific to Cyclone III.
2679
////////////////////////////////////////////////////////////////////////////-*/
2680
 
2681
`include "alt_mem_phy_defines.v"
2682
 
2683
//DQS pin assignments
2684
(* altera_attribute = " -name DQS_FREQUENCY 150.0MHz -to dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[0].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[1].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[2].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[3].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[4].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[5].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[6].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[0].dq[7].dq_ibuf -from dqs[0].dqs_obuf; -name DQ_GROUP 9 -to dm[0].dm_obuf -from dqs[0].dqs_obuf; -name DQS_FREQUENCY 150.0MHz -to dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[0].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[1].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[2].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[3].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[4].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[5].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[6].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dqs_group[1].dq[7].dq_ibuf -from dqs[1].dqs_obuf; -name DQ_GROUP 9 -to dm[1].dm_obuf -from dqs[1].dqs_obuf" *)
2685
 
2686
//
2687
module altera_ddr_phy_alt_mem_phy_dp_io (
2688
                                reset_resync_clk_2x_n,
2689
                                resync_clk_2x,
2690
                                mem_clk_2x,
2691
                                write_clk_2x,
2692
                                mem_dm,
2693
                                mem_dq,
2694
                                mem_dqs,
2695
                                dio_rdata_h_2x,
2696
                                dio_rdata_l_2x,
2697
                                poa_postamble_en_preset_2x,
2698
                                wdp_dm_h_2x,
2699
                                wdp_dm_l_2x,
2700
                                wdp_wdata_h_2x,
2701
                                wdp_wdata_l_2x,
2702
                                wdp_wdata_oe_2x,
2703
                                wdp_wdqs_2x,
2704
                                wdp_wdqs_oe_2x
2705
                              );
2706
 
2707
parameter MEM_IF_CLK_PS             =           4000;
2708
parameter MEM_IF_BANKADDR_WIDTH     =              3;
2709
parameter MEM_IF_CS_WIDTH           =              2;
2710
parameter MEM_IF_DWIDTH             =             64;
2711
parameter MEM_IF_DM_PINS_EN         =              1;
2712
parameter MEM_IF_DM_WIDTH           =              8;
2713
parameter MEM_IF_DQ_PER_DQS         =              8;
2714
parameter MEM_IF_DQS_CAPTURE_EN     =              0;
2715
parameter MEM_IF_DQS_WIDTH          =              8;
2716
parameter MEM_IF_POSTAMBLE_EN_WIDTH =              8;
2717
parameter MEM_IF_ROWADDR_WIDTH      =             13;
2718
parameter DLL_DELAY_BUFFER_MODE     =         "HIGH";
2719
parameter DQS_OUT_MODE              = "DELAY_CHAIN2";
2720
parameter DQS_PHASE                 =             72;
2721
 
2722
 
2723
input  wire                                             reset_resync_clk_2x_n;
2724
input  wire                                             resync_clk_2x;
2725
input  wire                                             mem_clk_2x;
2726
input  wire                                             write_clk_2x;
2727
output wire [MEM_IF_DM_WIDTH - 1 : 0]                   mem_dm;
2728
inout  wire [MEM_IF_DWIDTH - 1 : 0]                     mem_dq;
2729
inout  wire [MEM_IF_DWIDTH / MEM_IF_DQ_PER_DQS - 1 : 0] mem_dqs;
2730
(* preserve *) output reg [MEM_IF_DWIDTH - 1 : 0]       dio_rdata_h_2x;
2731
(* preserve *) output reg [MEM_IF_DWIDTH - 1 : 0]       dio_rdata_l_2x;
2732
input  wire [MEM_IF_POSTAMBLE_EN_WIDTH - 1 : 0]         poa_postamble_en_preset_2x;
2733
input  wire [MEM_IF_DM_WIDTH -1 : 0]                    wdp_dm_h_2x;
2734
input  wire [MEM_IF_DM_WIDTH -1 : 0]                    wdp_dm_l_2x;
2735
input  wire [MEM_IF_DWIDTH - 1 : 0]                     wdp_wdata_h_2x;
2736
input  wire [MEM_IF_DWIDTH - 1 : 0]                     wdp_wdata_l_2x;
2737
input  wire [MEM_IF_DWIDTH - 1 : 0]                     wdp_wdata_oe_2x;
2738
input  wire [(MEM_IF_DQS_WIDTH) - 1 : 0]                wdp_wdqs_2x;
2739
input  wire [(MEM_IF_DQS_WIDTH) - 1 : 0]                wdp_wdqs_oe_2x;
2740
 
2741
(* altera_attribute=" -name FAST_OUTPUT_ENABLE_REGISTER ON" *) reg [MEM_IF_DWIDTH - 1 : 0] wdp_wdata_oe_2x_r;
2742
 
2743
wire [MEM_IF_DWIDTH - 1 : 0]                            rdata_n_captured;
2744
wire [MEM_IF_DWIDTH - 1 : 0]                            rdata_p_captured;
2745
 
2746
(* preserve *) wire [(MEM_IF_DQS_WIDTH) - 1 : 0]        wdp_wdqs_oe_2x_r;
2747
 
2748
(* preserve *) reg  [MEM_IF_DWIDTH - 1 : 0]             rdata_n_ams;
2749
(* preserve *) reg  [MEM_IF_DWIDTH - 1 : 0]             rdata_p_ams;
2750
 
2751
// Use DQS clock to register DQ read data
2752
wire [(MEM_IF_DQS_WIDTH) - 1 : 0]                       dqs_clk;
2753
wire [(MEM_IF_DQS_WIDTH) - 1 : 0]                       dq_capture_clk;
2754
 
2755
wire                                                    reset_resync_clk_2x;
2756
 
2757
 
2758
wire [MEM_IF_DWIDTH - 1 : 0]                            dq_ddio_dataout;
2759
wire [MEM_IF_DWIDTH - 1 : 0]                            dq_datain;
2760
wire [MEM_IF_DWIDTH - 1 : 0]                            dm_ddio_dataout;
2761
wire [MEM_IF_DWIDTH / MEM_IF_DQ_PER_DQS - 1 : 0]        dqs_ddio_dataout;
2762
 
2763
 
2764
genvar i,j;
2765
 
2766
 
2767
// Create non-inverted reset for pads :
2768
assign reset_resync_clk_2x = ~reset_resync_clk_2x_n;
2769
 
2770
// Read datapath functionality :
2771
 
2772
 
2773
// synchronise to the resync_clk_2x_domain
2774
 
2775
always @(posedge resync_clk_2x)
2776
begin
2777
 
2778
    // Resynchronise :
2779
 
2780
    // The comparison to 'X' is performed to prevent X's being captured in non-DQS mode
2781
    // and propagating into the sequencer's control logic.  This can only occur when a Verilog SIMGEN
2782
    // model of the sequencer is being used :
2783
    if (|rdata_p_captured === 1'bX)
2784
        rdata_p_ams <= {MEM_IF_DWIDTH{1'b0}};
2785
    else
2786
        rdata_p_ams <= rdata_p_captured; // 'captured' is from the IOEs
2787
 
2788
     if (|rdata_n_captured === 1'bX)
2789
        rdata_n_ams <= {MEM_IF_DWIDTH{1'b0}};
2790
    else
2791
        rdata_n_ams <= rdata_n_captured; // 'captured' is from the IOEs
2792
 
2793
    // Output registers :
2794
    dio_rdata_h_2x <= rdata_p_ams;
2795
    dio_rdata_l_2x <= rdata_n_ams;
2796
 
2797
end
2798
 
2799
 
2800
// Either use the DQS clock to capture, or the resync clock:
2801
 
2802
generate
2803
 
2804
    if (MEM_IF_DQS_CAPTURE_EN == 1)
2805
        assign dq_capture_clk = ~dqs_clk;
2806
    else
2807
        assign dq_capture_clk = {MEM_IF_DQS_WIDTH{resync_clk_2x}};
2808
 
2809
endgenerate
2810
 
2811
 
2812
// DQ pins and their logic
2813
 
2814
generate
2815
 
2816
// First generate each DQS group :
2817
for (i=0; i<MEM_IF_DQS_WIDTH ; i=i+1)
2818
begin : dqs_group
2819
 
2820
    // Then generate DQ pins for each group :
2821
    for (j=0; j<MEM_IF_DQ_PER_DQS ; j=j+1)
2822
    begin : dq
2823
 
2824
        // DDIO out :
2825
        cycloneiii_ddio_out # (
2826
            .power_up("low"),
2827
            .async_mode("none"),
2828
            .sync_mode("none"),
2829
            .lpm_type("cycloneiii_ddio_out"),
2830
            .use_new_clocking_model("true")
2831
        ) dq_ddio_out (
2832
            .datainlo(wdp_wdata_l_2x[j+(i*MEM_IF_DQ_PER_DQS)]),
2833
            .datainhi(wdp_wdata_h_2x[j+(i*MEM_IF_DQ_PER_DQS)]),
2834
            .clkhi(write_clk_2x),
2835
            .clklo(write_clk_2x),
2836
            .clk(),
2837
            .muxsel(write_clk_2x),
2838
            .ena(1'b1),
2839
            .areset(),
2840
            .sreset(),
2841
            .dataout(dq_ddio_dataout[j+(i*MEM_IF_DQ_PER_DQS)]),
2842
            .dfflo(),
2843
            .dffhi(),
2844
            .devpor(),
2845
            .devclrn()
2846
        );
2847
 
2848
        // Need to register OE :
2849
        always @(posedge write_clk_2x)
2850
        begin
2851
            wdp_wdata_oe_2x_r[j+(i*MEM_IF_DQ_PER_DQS)] <= wdp_wdata_oe_2x[j+(i*MEM_IF_DQ_PER_DQS)];
2852
        end
2853
 
2854
        //The buffer itself (output side) :
2855
        cycloneiii_io_obuf dq_obuf (
2856
            .i(dq_ddio_dataout[j+(i*MEM_IF_DQ_PER_DQS)]),
2857
            .oe(wdp_wdata_oe_2x_r[j+(i*MEM_IF_DQ_PER_DQS)]),
2858
            .seriesterminationcontrol(),
2859
            .devoe(),
2860
            .o(mem_dq[j+(i*MEM_IF_DQ_PER_DQS)]), //pad
2861
            .obar()
2862
        );
2863
 
2864
        //The buffer itself (input side) :
2865
 
2866
        cycloneiii_io_ibuf # (
2867
            .simulate_z_as("gnd")
2868
        ) dq_ibuf (
2869
            .i(mem_dq[j+(i*MEM_IF_DQ_PER_DQS)]),//pad
2870
            .ibar(),
2871
            .o(dq_datain[j+(i*MEM_IF_DQ_PER_DQS)])
2872
        );
2873
 
2874
        // Read data input DDIO path :
2875
        altddio_in #( .intended_device_family ("Cyclone III"),
2876
            .lpm_hint      ("UNUSED"),
2877
            .lpm_type      ("altddio_in"),
2878
            .power_up_high ("OFF"),
2879
            .width         (1)
2880
        ) dqi (
2881
            .aclr          (reset_resync_clk_2x),
2882
            .aset          (),
2883
            .sset          (),
2884
            .sclr          (),
2885
            .datain        (dq_datain[j+(i*MEM_IF_DQ_PER_DQS)]),
2886
            .dataout_h     (rdata_n_captured[j+(i*MEM_IF_DQ_PER_DQS)]),
2887
            .dataout_l     (rdata_p_captured[j+(i*MEM_IF_DQ_PER_DQS)]),
2888
            .inclock       (dq_capture_clk[i]),
2889
            .inclocken     (1'b1)
2890
        );
2891
 
2892
    end
2893
 
2894
end
2895
 
2896
endgenerate
2897
 
2898
 
2899
 
2900
//////////////////////////////////////////////////////////////////////////////-
2901
// DM Pin and its logic
2902
//////////////////////////////////////////////////////////////////////////////-
2903
 
2904
 
2905
generate
2906
 
2907
for (i=0; i<MEM_IF_DM_WIDTH; i=i+1)
2908
begin : dm
2909
 
2910
    cycloneiii_ddio_out # (
2911
        .power_up("low"),
2912
        .async_mode("none"),
2913
        .sync_mode("none"),
2914
        .lpm_type("cycloneiii_ddio_out"),
2915
        .use_new_clocking_model("true")
2916
    ) dm_ddio_out (
2917
        .datainlo(wdp_dm_l_2x[i]),
2918
        .datainhi(wdp_dm_h_2x[i]),
2919
        .clkhi(write_clk_2x),
2920
        .clklo(write_clk_2x),
2921
        .clk(),
2922
        .muxsel(write_clk_2x),
2923
        .ena(1'b1),
2924
        .areset(),
2925
        .sreset(),
2926
        .dataout(dm_ddio_dataout[i]),
2927
        .dfflo(),
2928
        .dffhi(),
2929
        .devpor(),
2930
        .devclrn()
2931
    );
2932
 
2933
    cycloneiii_io_obuf dm_obuf (
2934
        .i(dm_ddio_dataout[i]),
2935
        .oe(1'b1),
2936
        .seriesterminationcontrol(),
2937
        .devoe(),
2938
        .o(mem_dm[i]), //pad
2939
        .obar()
2940
    );
2941
 
2942
end
2943
 
2944
endgenerate
2945
 
2946
 
2947
 
2948
// Note that for CIII DQS-capture mode is unsupported, and so DQS is only used
2949
// as an output :
2950
generate
2951
 
2952
for (i=0; i<(MEM_IF_DQS_WIDTH); i=i+1)
2953
begin : dqs
2954
 
2955
    cycloneiii_ddio_out # (
2956
         .power_up("low"),
2957
         .async_mode("none"),
2958
         .sync_mode("none"),
2959
         .lpm_type("cycloneiii_ddio_out"),
2960
         .use_new_clocking_model("true")
2961
     ) dqs_ddio_out (
2962
         .datainlo(1'b0),
2963
         .datainhi(wdp_wdqs_2x[i]),
2964
         .clkhi(mem_clk_2x),
2965
         .clklo(mem_clk_2x),
2966
         .clk(),
2967
         .muxsel(mem_clk_2x),
2968
         .ena(1'b1),
2969
         .areset(),
2970
         .sreset(),
2971
         .dataout(dqs_ddio_dataout[i]),
2972
         .dfflo(),
2973
         .dffhi(),
2974
         .devpor(),
2975
         .devclrn()
2976
     );
2977
 
2978
    // NB. Invert the OE input, as Quartus requires us to invert
2979
    // the OE input on the OBUF :
2980
    cycloneiii_ddio_oe # (
2981
         .power_up("low"),
2982
         .async_mode("none"),
2983
         .sync_mode("none"),
2984
         .lpm_type("cycloneiii_ddio_oe")
2985
     ) dqsoe_ddio_oe (
2986
         .oe(~wdp_wdqs_oe_2x[i]),
2987
         .clk(mem_clk_2x),
2988
         .ena(1'b1),
2989
         .areset(),
2990
         .sreset(),
2991
         .dataout(wdp_wdqs_oe_2x_r[i]),
2992
         .dfflo(),
2993
         .dffhi(),
2994
         .devpor(),
2995
         .devclrn()
2996
     );
2997
 
2998
     // Output buffer itself :
2999
     // OE input is active HIGH
3000
     cycloneiii_io_obuf dqs_obuf (
3001
         .i(dqs_ddio_dataout[i]),
3002
         .oe(~wdp_wdqs_oe_2x_r[i]),
3003
         .seriesterminationcontrol(),
3004
         .devoe(),
3005
         .o(mem_dqs[i]),
3006
         .obar()
3007
     );
3008
 
3009
end
3010
 
3011
endgenerate
3012
 
3013
 
3014
endmodule
3015
 
3016
//
3017
 
3018
`ifdef ALT_MEM_PHY_DEFINES
3019
`else
3020
`include "alt_mem_phy_defines.v"
3021
`endif
3022
 
3023
//
3024
module altera_ddr_phy_alt_mem_phy_read_dp ( phy_clk_1x,
3025
                             resync_clk_2x,
3026
                             reset_phy_clk_1x_n,
3027
                             reset_resync_clk_2x_n,
3028
                             seq_rdp_dec_read_lat_1x,
3029
                             seq_rdp_dmx_swap,
3030
                             seq_rdp_inc_read_lat_1x,
3031
                             dio_rdata_h_2x,
3032
                             dio_rdata_l_2x,
3033
                             ctl_mem_rdata
3034
                            );
3035
 
3036
parameter ADDR_COUNT_WIDTH         =               4;
3037
parameter BIDIR_DPINS              =               1; // 0 for QDR only.
3038
parameter DWIDTH_RATIO             =               4;
3039
parameter MEM_IF_CLK_PS            =            4000;
3040
parameter FAMILY                   =    "Stratix II";
3041
parameter LOCAL_IF_DWIDTH          =             256;
3042
parameter MEM_IF_DQ_PER_DQS        =               8;
3043
parameter MEM_IF_DQS_WIDTH         =               8;
3044
parameter MEM_IF_DWIDTH            =              64;
3045
parameter MEM_IF_PHY_NAME          = "STRATIXII_DQS";
3046
parameter RDP_INITIAL_LAT          =               6;
3047
parameter RDP_RESYNC_LAT_CTL_EN    =               0;
3048
parameter RESYNC_PIPELINE_DEPTH    =               1;
3049
 
3050
localparam NUM_DQS_PINS            = MEM_IF_DQS_WIDTH;
3051
 
3052
input  wire                         phy_clk_1x;
3053
input  wire                         resync_clk_2x;
3054
input  wire                         reset_phy_clk_1x_n;
3055
input  wire                         reset_resync_clk_2x_n;
3056
input  wire                         seq_rdp_dec_read_lat_1x;
3057
input  wire                         seq_rdp_dmx_swap;
3058
input  wire                         seq_rdp_inc_read_lat_1x;
3059
input  wire [MEM_IF_DWIDTH-1 : 0]   dio_rdata_h_2x;
3060
input  wire [MEM_IF_DWIDTH-1 : 0]   dio_rdata_l_2x;
3061
output wire [LOCAL_IF_DWIDTH-1 : 0] ctl_mem_rdata;
3062
 
3063
// concatonated read data :
3064
wire [(2*MEM_IF_DWIDTH)-1 : 0]      dio_rdata_2x;
3065
reg  [ADDR_COUNT_WIDTH - DWIDTH_RATIO/2 : 0]     rd_ram_rd_addr;
3066
reg  [ADDR_COUNT_WIDTH - 1 : 0]     rd_ram_wr_addr;
3067
wire [(2*MEM_IF_DWIDTH)-1 : 0]      rd_data_piped_2x;
3068
 
3069
 
3070
 
3071
reg                                 inc_read_lat_sync_r;
3072
reg                                 dec_read_lat_sync_r;
3073
 
3074
// Optional AMS registers :
3075
reg                                 inc_read_lat_ams;
3076
reg                                 inc_read_lat_sync;
3077
 
3078
reg                                 dec_read_lat_ams;
3079
reg                                 dec_read_lat_sync;
3080
 
3081
reg                                 state;
3082
reg                                 dmx_swap_ams;
3083
reg                                 dmx_swap_sync;
3084
reg                                 dmx_swap_sync_r;
3085
 
3086
wire                                wr_addr_toggle_detect;
3087
wire                                wr_addr_stall;
3088
wire                                wr_addr_double_inc;
3089
 
3090
wire                                rd_addr_stall;
3091
wire                                rd_addr_double_inc;
3092
 
3093
// Read data from ram, prior to mapping/re-ordering :
3094
wire [LOCAL_IF_DWIDTH-1 : 0]        ram_rdata_1x;
3095
 
3096
////////////////////////////////////////////////////////////////////////////////
3097
//                          Write Address block
3098
////////////////////////////////////////////////////////////////////////////////
3099
 
3100
 
3101
// 'toggle detect' logic :
3102
assign wr_addr_toggle_detect = !dmx_swap_sync_r && dmx_swap_sync;
3103
 
3104
// 'stall' logic :
3105
assign wr_addr_stall      = !(~state && wr_addr_toggle_detect);
3106
 
3107
// 'double_inc' logic :
3108
assign wr_addr_double_inc = state && wr_addr_toggle_detect;
3109
 
3110
// Write address generation
3111
// When no demux toggle - increment every clock cycle
3112
// When demux toggle is detected,invert addr_stall
3113
// if addr_stall is 1 then do nothing to address, else double increment this cycle.
3114
always@ (posedge resync_clk_2x or negedge reset_resync_clk_2x_n)
3115
begin
3116
 
3117
   if (reset_resync_clk_2x_n == 0)
3118
   begin
3119
       rd_ram_wr_addr  <= RDP_INITIAL_LAT[3:0];
3120
       state           <= 1'b0;
3121
       dmx_swap_ams    <= 1'b0;
3122
       dmx_swap_sync   <= 1'b0;
3123
       dmx_swap_sync_r <= 1'b0;
3124
   end
3125
 
3126
   else
3127
   begin
3128
 
3129
       // Synchronise dmx_swap :
3130
       dmx_swap_ams    <= seq_rdp_dmx_swap;
3131
       dmx_swap_sync   <= dmx_swap_ams;
3132
       dmx_swap_sync_r <= dmx_swap_sync;
3133
 
3134
       // RAM write address :
3135
       if (wr_addr_stall == 1'b1)
3136
       begin
3137
           rd_ram_wr_addr <= rd_ram_wr_addr + 1'b1 + wr_addr_double_inc;
3138
       end
3139
 
3140
       // Maintain single bit state :
3141
       if (wr_addr_toggle_detect == 1'b1)
3142
       begin
3143
           state <= ~state;
3144
       end
3145
 
3146
   end
3147
 
3148
end
3149
 
3150
 
3151
 
3152
////////////////////////////////////////////////////////////////////////////////
3153
//                          Pipeline registers
3154
////////////////////////////////////////////////////////////////////////////////
3155
 
3156
 
3157
// Concatenate the input read data taking note of ram input datawidths
3158
// This is concatenating rdata_p and rdata_n from a DQS group together so that the rest
3159
// of the pipeline can use a single vector:
3160
generate
3161
 
3162
genvar dqs_group_num;
3163
 
3164
    for (dqs_group_num = 0; dqs_group_num < NUM_DQS_PINS ; dqs_group_num  = dqs_group_num + 1)
3165
    begin : ddio_remap
3166
 
3167
        assign dio_rdata_2x[2*MEM_IF_DQ_PER_DQS*dqs_group_num + 2*MEM_IF_DQ_PER_DQS-1: 2*MEM_IF_DQ_PER_DQS*dqs_group_num]
3168
 
3169
         = {  dio_rdata_l_2x[MEM_IF_DQ_PER_DQS*dqs_group_num + MEM_IF_DQ_PER_DQS-1: MEM_IF_DQ_PER_DQS*dqs_group_num],
3170
              dio_rdata_h_2x[MEM_IF_DQ_PER_DQS*dqs_group_num + MEM_IF_DQ_PER_DQS-1: MEM_IF_DQ_PER_DQS*dqs_group_num]
3171
            };
3172
    end
3173
 
3174
endgenerate
3175
 
3176
 
3177
// Generate appropriate pipeline depth
3178
 
3179
generate
3180
genvar i;
3181
 
3182
    if (RESYNC_PIPELINE_DEPTH > 0)
3183
    begin : resync_pipeline_gen
3184
 
3185
    // Declare pipeline registers
3186
    reg  [(2*MEM_IF_DWIDTH)-1 : 0 ] pipeline_delay [0 : RESYNC_PIPELINE_DEPTH - 1] ;
3187
 
3188
        for (i=0; i< RESYNC_PIPELINE_DEPTH; i = i + 1)
3189
        begin : PIPELINE
3190
 
3191
            always @(posedge resync_clk_2x)
3192
            begin
3193
 
3194
                if (i==0)
3195
                    pipeline_delay[i] <= dio_rdata_2x;
3196
                else
3197
                    pipeline_delay[i] <= pipeline_delay[i-1];
3198
 
3199
            end //always
3200
 
3201
        end //for
3202
 
3203
        assign rd_data_piped_2x = pipeline_delay[RESYNC_PIPELINE_DEPTH-1];
3204
 
3205
    end
3206
 
3207
    // If pipeline registers are not configured, pass-thru :
3208
    else
3209
    begin : no_resync_pipe_gen
3210
 
3211
        assign rd_data_piped_2x = dio_rdata_2x;
3212
 
3213
    end
3214
 
3215
endgenerate
3216
 
3217
 
3218
 
3219
 
3220
 
3221
////////////////////////////////////////////////////////////////////////////////
3222
//         Instantiate the read_dp dpram
3223
////////////////////////////////////////////////////////////////////////////////
3224
 
3225
generate
3226
 
3227
    if (DWIDTH_RATIO == 4)
3228
    begin : half_rate_ram_gen
3229
 
3230
        altsyncram #(
3231
             .address_reg_b             ("CLOCK1"),
3232
             .clock_enable_input_a      ("BYPASS"),
3233
             .clock_enable_input_b      ("BYPASS"),
3234
             .clock_enable_output_b     ("BYPASS"),
3235
             .intended_device_family    (FAMILY),
3236
             .lpm_type                  ("altsyncram"),
3237
             .numwords_a                ((2**ADDR_COUNT_WIDTH )),
3238
             .numwords_b                ((2**ADDR_COUNT_WIDTH )/2),
3239
             .operation_mode            ("DUAL_PORT"),
3240
             .outdata_aclr_b            ("NONE"),
3241
             .outdata_reg_b             ("CLOCK1"),
3242
             .power_up_uninitialized    ("FALSE"),
3243
             .widthad_a                 (ADDR_COUNT_WIDTH),
3244
             .widthad_b                 (ADDR_COUNT_WIDTH - 1),
3245
             .width_a                   (MEM_IF_DWIDTH*2),
3246
             .width_b                   (MEM_IF_DWIDTH*4),
3247
             .width_byteena_a           (1)
3248
        ) altsyncram_component (
3249
             .wren_a            (1'b1),
3250
             .clock0            (resync_clk_2x),
3251
             .clock1            (phy_clk_1x),
3252
             .address_a         (rd_ram_wr_addr),
3253
             .address_b         (rd_ram_rd_addr),
3254
             .data_a            (rd_data_piped_2x),
3255
             .q_b               (ram_rdata_1x),
3256
             .aclr0             (1'b0),
3257
             .aclr1             (1'b0),
3258
             .addressstall_a    (1'b0),
3259
             .addressstall_b    (1'b0),
3260
             .byteena_a         (1'b1),
3261
             .byteena_b         (1'b1),
3262
             .clocken0          (1'b1),
3263
             .clocken1          (1'b1),
3264
             .clocken2          (),
3265
             .clocken3          (),
3266
             .data_b            ({(MEM_IF_DWIDTH*4){1'b1}}),
3267
             .q_a               (),
3268
             .rden_b            (1'b1),
3269
             .rden_a            (),
3270
             .wren_b            (1'b0),
3271
             .eccstatus         ()
3272
        );
3273
 
3274
        // Read data mapping :
3275
        genvar dqs_group_num_b;
3276
 
3277
        for (dqs_group_num_b = 0; dqs_group_num_b < NUM_DQS_PINS ; dqs_group_num_b  = dqs_group_num_b + 1)
3278
        begin : remap_logic
3279
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 0 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 0 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS +     MEM_IF_DQ_PER_DQS - 1 :                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS                     ];
3280
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 1 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 1 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + 2 * MEM_IF_DQ_PER_DQS - 1 :                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS ];
3281
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 2 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 2 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [ MEM_IF_DWIDTH * 2 + dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS +     MEM_IF_DQ_PER_DQS - 1 : MEM_IF_DWIDTH * 2 + dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS                     ];
3282
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 3 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 3 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [ MEM_IF_DWIDTH * 2 + dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + 2 * MEM_IF_DQ_PER_DQS - 1 : MEM_IF_DWIDTH * 2 + dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS ];
3283
        end
3284
 
3285
     end // block: half_rate_dp
3286
 
3287
endgenerate
3288
 
3289
// full-rate
3290
 
3291
generate
3292
 
3293
    if (DWIDTH_RATIO == 2)
3294
    begin : full_rate_ram_gen
3295
 
3296
        altsyncram #(
3297
             .address_reg_b             ("CLOCK1"),
3298
             .clock_enable_input_a      ("BYPASS"),
3299
             .clock_enable_input_b      ("BYPASS"),
3300
             .clock_enable_output_b     ("BYPASS"),
3301
             .intended_device_family    (FAMILY),
3302
             .lpm_type                  ("altsyncram"),
3303
             .numwords_a                ((2**ADDR_COUNT_WIDTH )),
3304
             .numwords_b                ((2**ADDR_COUNT_WIDTH )),
3305
             .operation_mode            ("DUAL_PORT"),
3306
             .outdata_aclr_b            ("NONE"),
3307
             .outdata_reg_b             ("CLOCK1"),
3308
             .power_up_uninitialized    ("FALSE"),
3309
             .widthad_a                 (ADDR_COUNT_WIDTH),
3310
             .widthad_b                 (ADDR_COUNT_WIDTH),
3311
             .width_a                   (MEM_IF_DWIDTH*2),
3312
             .width_b                   (MEM_IF_DWIDTH*2),
3313
             .width_byteena_a           (1)
3314
        ) altsyncram_component(
3315
             .wren_a            (1'b1),
3316
             .clock0            (resync_clk_2x),
3317
             .clock1            (phy_clk_1x),
3318
             .address_a         (rd_ram_wr_addr),
3319
             .address_b         (rd_ram_rd_addr),
3320
             .data_a            (rd_data_piped_2x),
3321
             .q_b               (ram_rdata_1x),
3322
             .aclr0             (1'b0),
3323
             .aclr1             (1'b0),
3324
             .addressstall_a    (1'b0),
3325
             .addressstall_b    (1'b0),
3326
             .byteena_a         (1'b1),
3327
             .byteena_b         (1'b1),
3328
             .clocken0          (1'b1),
3329
             .clocken1          (1'b1),
3330
             .clocken2          (),
3331
             .clocken3          (),
3332
             .data_b            ({(MEM_IF_DWIDTH*2){1'b1}}),
3333
             .q_a               (),
3334
             .rden_b            (1'b1),
3335
             .rden_a            (),
3336
             .wren_b            (1'b0),
3337
             .eccstatus         ()
3338
        );
3339
 
3340
        // Read data mapping :
3341
        genvar dqs_group_num_b;
3342
 
3343
        for (dqs_group_num_b = 0; dqs_group_num_b < NUM_DQS_PINS ; dqs_group_num_b  = dqs_group_num_b + 1)
3344
        begin : remap_logic
3345
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 0 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 0 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS +     MEM_IF_DQ_PER_DQS - 1 :                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS                     ];
3346
            assign ctl_mem_rdata [MEM_IF_DWIDTH * 1 + dqs_group_num_b * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS -1 : MEM_IF_DWIDTH * 1 + dqs_group_num_b * MEM_IF_DQ_PER_DQS ] = ram_rdata_1x [                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + 2 * MEM_IF_DQ_PER_DQS - 1 :                     dqs_group_num_b * 2 * MEM_IF_DQ_PER_DQS + MEM_IF_DQ_PER_DQS ];
3347
 
3348
        end
3349
 
3350
     end // block: half_rate_dp
3351
 
3352
endgenerate
3353
 
3354
 
3355
 
3356
////////////////////////////////////////////////////////////////////////////////
3357
//                          Read Address block
3358
////////////////////////////////////////////////////////////////////////////////
3359
 
3360
 
3361
// Optional Anti-metastability flops :
3362
generate
3363
 
3364
    if (RDP_RESYNC_LAT_CTL_EN == 1)
3365
 
3366
    always@ (posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3367
    begin : rd_addr_ams
3368
 
3369
        if (reset_phy_clk_1x_n == 1'b0)
3370
        begin
3371
 
3372
            inc_read_lat_ams    <= 1'b0;
3373
            inc_read_lat_sync   <= 1'b0;
3374
            inc_read_lat_sync_r <= 1'b0;
3375
 
3376
            // Synchronise rd_lat_inc_1x :
3377
            dec_read_lat_ams    <= 1'b0;
3378
            dec_read_lat_sync   <= 1'b0;
3379
            dec_read_lat_sync_r <= 1'b0;
3380
 
3381
        end
3382
 
3383
        else
3384
        begin
3385
 
3386
            // Synchronise rd_lat_inc_1x :
3387
            inc_read_lat_ams    <= seq_rdp_inc_read_lat_1x;
3388
            inc_read_lat_sync   <= inc_read_lat_ams;
3389
            inc_read_lat_sync_r <= inc_read_lat_sync;
3390
 
3391
            // Synchronise rd_lat_inc_1x :
3392
            dec_read_lat_ams    <= seq_rdp_dec_read_lat_1x;
3393
            dec_read_lat_sync   <= dec_read_lat_ams;
3394
            dec_read_lat_sync_r <= dec_read_lat_sync;
3395
 
3396
        end
3397
 
3398
    end // always
3399
 
3400
    // No anti-metastability protection required :
3401
    else
3402
 
3403
    always@ (posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3404
    begin
3405
 
3406
        if (reset_phy_clk_1x_n == 1'b0)
3407
        begin
3408
            inc_read_lat_sync_r    <= 1'b0;
3409
            dec_read_lat_sync_r   <= 1'b0;
3410
        end
3411
 
3412
        else
3413
        begin
3414
            // No need to re-synchronise, just register for edge detect :
3415
            inc_read_lat_sync_r <= seq_rdp_inc_read_lat_1x;
3416
            dec_read_lat_sync_r <= seq_rdp_dec_read_lat_1x;
3417
        end
3418
 
3419
    end
3420
 
3421
endgenerate
3422
 
3423
 
3424
 
3425
 
3426
generate
3427
 
3428
    if (RDP_RESYNC_LAT_CTL_EN == 1)
3429
    begin : lat_ctl_en_gen
3430
 
3431
        // 'toggle detect' logic :
3432
        //assign rd_addr_double_inc =    !inc_read_lat_sync_r && inc_read_lat_sync;
3433
        assign rd_addr_double_inc =    ( !dec_read_lat_sync_r && dec_read_lat_sync );
3434
        // 'stall' logic :
3435
       // assign rd_addr_stall      = !( !dec_read_lat_sync_r && dec_read_lat_sync );
3436
        assign rd_addr_stall      =  !inc_read_lat_sync_r && inc_read_lat_sync;
3437
    end
3438
 
3439
    else
3440
    begin : no_lat_ctl_en_gen
3441
        // 'toggle detect' logic :
3442
        //assign rd_addr_double_inc =    !inc_read_lat_sync_r && seq_rdp_inc_read_lat_1x;
3443
        assign rd_addr_double_inc =   ( !dec_read_lat_sync_r && seq_rdp_dec_read_lat_1x );
3444
        // 'stall' logic :
3445
        //assign rd_addr_stall      = !( !dec_read_lat_sync_r && seq_rdp_dec_read_lat_1x );
3446
        assign rd_addr_stall      = !inc_read_lat_sync_r && seq_rdp_inc_read_lat_1x;
3447
    end
3448
 
3449
endgenerate
3450
 
3451
 
3452
 
3453
always@ (posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3454
begin
3455
 
3456
   if (reset_phy_clk_1x_n == 0)
3457
   begin
3458
       rd_ram_rd_addr  <= { ADDR_COUNT_WIDTH - DWIDTH_RATIO/2 {1'b0} };
3459
   end
3460
 
3461
   else
3462
   begin
3463
 
3464
       // RAM read address :
3465
       if (rd_addr_stall == 1'b0)
3466
       begin
3467
           rd_ram_rd_addr <= rd_ram_rd_addr + 1'b1 + rd_addr_double_inc;
3468
       end
3469
 
3470
   end
3471
 
3472
end
3473
 
3474
 
3475
 
3476
 
3477
 
3478
endmodule
3479
 
3480
//
3481
 
3482
// Note, this write datapath logic matches both the spec, and what was done in
3483
// the beta project.
3484
 
3485
`ifdef ALT_MEM_PHY_DEFINES
3486
`else
3487
`include "alt_mem_phy_defines.v"
3488
`endif
3489
 
3490
//
3491
module altera_ddr_phy_alt_mem_phy_write_dp_fr(
3492
                                // clocks
3493
                                phy_clk_1x,            // full-rate clock
3494
                                mem_clk_2x,            // full-rate clock
3495
                                write_clk_2x,          // full-rate clock
3496
 
3497
                                // active-low resets, sync'd to clock domain
3498
                                reset_phy_clk_1x_n,
3499
                                reset_mem_clk_2x_n,
3500
                                reset_write_clk_2x_n,
3501
 
3502
                                // control i/f inputs
3503
                                ctl_mem_be,
3504
                                ctl_mem_dqs_burst,
3505
                                ctl_mem_wdata,
3506
                                ctl_mem_wdata_valid,
3507
 
3508
                                // seq i/f inputs :
3509
                                seq_be,
3510
                                seq_dqs_burst,
3511
                                seq_wdata,
3512
                                seq_wdata_valid,
3513
 
3514
                                seq_ctl_sel,
3515
 
3516
                                // outputs to IOEs
3517
                                wdp_wdata_h_2x,
3518
                                wdp_wdata_l_2x,
3519
                                wdp_wdata_oe_2x,
3520
                                wdp_wdqs_2x,
3521
                                wdp_wdqs_oe_2x,
3522
                                wdp_dm_h_2x,
3523
                                wdp_dm_l_2x
3524
                                );
3525
 
3526
// parameter declarations
3527
parameter BIDIR_DPINS        = 1;
3528
parameter LOCAL_IF_DRATE     = "FULL";
3529
parameter LOCAL_IF_DWIDTH    = 256;
3530
parameter MEM_IF_DM_WIDTH    = 8;
3531
parameter MEM_IF_DQ_PER_DQS  = 8;
3532
parameter MEM_IF_DQS_WIDTH   = 8;
3533
parameter GENERATE_WRITE_DQS = 1;
3534
parameter MEM_IF_DWIDTH      = 64;
3535
parameter DWIDTH_RATIO       = 2;
3536
parameter MEM_IF_DM_PINS_EN  = 1;
3537
 
3538
 
3539
// "internal" parameter, not to get propagated from higher levels...
3540
parameter NUM_DUPLICATE_REGS = 4;             // 1 per nibble to save registers
3541
 
3542
 
3543
// clocks
3544
input wire                                                   phy_clk_1x;          // half-rate system clock
3545
input wire                                                   mem_clk_2x;          // full-rate memory clock
3546
input wire                                                   write_clk_2x;        // full-rate write clock
3547
 
3548
// resets, async assert, de-assert is sync'd to each clock domain
3549
input wire                                                   reset_phy_clk_1x_n;
3550
input wire                                                   reset_mem_clk_2x_n;
3551
input wire                                                   reset_write_clk_2x_n;
3552
 
3553
// control i/f inputs
3554
input wire [MEM_IF_DM_WIDTH  * DWIDTH_RATIO - 1 : 0]         ctl_mem_be;           // byte enable == ~data mask
3555
input wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]       ctl_mem_dqs_burst;    // dqs burst indication
3556
input wire [MEM_IF_DWIDTH*DWIDTH_RATIO - 1 : 0]              ctl_mem_wdata;        // write data
3557
input wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]       ctl_mem_wdata_valid;  // write data valid indication
3558
 
3559
// seq i/f inputs
3560
input wire [MEM_IF_DM_WIDTH  * DWIDTH_RATIO   - 1 : 0]       seq_be;
3561
input wire [MEM_IF_DWIDTH    * DWIDTH_RATIO   - 1 : 0]       seq_wdata;
3562
input wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]       seq_dqs_burst;
3563
input wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]       seq_wdata_valid;
3564
 
3565
input wire                                                   seq_ctl_sel;
3566
 
3567
(*preserve*) output reg  [MEM_IF_DWIDTH - 1 : 0]             wdp_wdata_h_2x;      // wdata_h to IOE
3568
(*preserve*) output reg  [MEM_IF_DWIDTH - 1 : 0]             wdp_wdata_l_2x;      // wdata_l to IOE
3569
output wire [MEM_IF_DWIDTH - 1 : 0]                          wdp_wdata_oe_2x;     // OE to DQ pin
3570
output reg  [(MEM_IF_DQS_WIDTH) - 1 : 0]                     wdp_wdqs_2x;         // DQS to IOE
3571
output reg  [(MEM_IF_DQS_WIDTH) - 1 : 0]                     wdp_wdqs_oe_2x;      // OE to DQS pin
3572
 
3573
(*preserve*) output reg [MEM_IF_DM_WIDTH -1 : 0]                 wdp_dm_h_2x;         // dm_h to IOE
3574
(*preserve*) output reg [MEM_IF_DM_WIDTH -1 : 0]                 wdp_dm_l_2x;         // dm_l to IOE
3575
 
3576
// internal reg declarations
3577
 
3578
// registers (on a per- DQS group basis) which sync the dqs_burst_1x to phy_clk or mem_clk_2x.
3579
// They are used to generate the DQS signal and its OE.
3580
(*preserve*) reg [MEM_IF_DQS_WIDTH -1 : 0]                   dqs_burst_1x_r;
3581
(*preserve*) reg [MEM_IF_DQS_WIDTH -1 : 0]                   dqs_burst_2x_r1;
3582
(*preserve*) reg [MEM_IF_DQS_WIDTH -1 : 0]                   dqs_burst_2x_r2;
3583
(*preserve*) reg [MEM_IF_DQS_WIDTH -1 : 0]                   dqs_burst_2x_r3;
3584
 
3585
// registers to generate the dq_oe, on a per nibble basis, to save registers.
3586
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_valid_1x_r1;   // wdata_valid_1x, retimed in phy_clk_1x
3587
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_valid_1x_r2;   // wdata_valid_1x_r1, retimed in phy_clk_1x
3588
 
3589
(* preserve, altera_attribute = "-name ADV_NETLIST_OPT_ALLOWED \"NEVER ALLOW\"" *) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] dq_oe_2x;            // 1 per nibble, to save registers
3590
 
3591
             reg [MEM_IF_DWIDTH - 1 : 0]                    wdp_wdata_oe_2x_int; // intermediate output, gets assigned to o/p signal
3592
 
3593
             reg [LOCAL_IF_DWIDTH -1 : 0]                   mem_wdata_r1;     // mem_wdata, retimed in phy_clk_1x
3594
             reg [LOCAL_IF_DWIDTH -1 : 0]                   mem_wdata_r2;     // mem_wdata_r1, retimed in phy_clk_1x
3595
 
3596
// registers used to generate the mux select signal for wdata.
3597
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_valid_1x_r;    // 1 per nibble, to save registers
3598
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_valid_2x_r1;   // 1 per nibble, to save registers
3599
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_valid_2x_r2;   // 1 per nibble, to save registers
3600
(*preserve*) reg [MEM_IF_DWIDTH/NUM_DUPLICATE_REGS -1 : 0 ] wdata_sel;           // 1 per nibble, to save registers
3601
 
3602
// registers used to generate the dm mux select and dm signals
3603
             reg [MEM_IF_DM_WIDTH*DWIDTH_RATIO - 1 : 0]     mem_dm_r1;
3604
             reg [MEM_IF_DM_WIDTH*DWIDTH_RATIO - 1 : 0]     mem_dm_r2;
3605
(*preserve*) reg                                            wdata_dm_1x_r;       // preserved, to stop merge with wdata_valid_1x_r
3606
(*preserve*) reg                                            wdata_dm_2x_r1;      // preserved, to stop merge with wdata_valid_2x_r1
3607
(*preserve*) reg                                            wdata_dm_2x_r2;      // preserved, to stop merge with wdata_valid_2x_r2
3608
(*preserve*) reg                                            dm_sel;              // preserved, to stop merge with wdata_sel
3609
 
3610
// MUX outputs....
3611
reg [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0] mem_dqs_burst  ;
3612
reg [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0] mem_wdata_valid;
3613
reg [MEM_IF_DM_WIDTH  * DWIDTH_RATIO   - 1 : 0] mem_be         ;
3614
reg [MEM_IF_DWIDTH    * DWIDTH_RATIO   - 1 : 0] mem_wdata      ;
3615
 
3616
wire [MEM_IF_DQS_WIDTH - 1 : 0]                             wdp_wdqs_oe_2x_int;
3617
 
3618
 
3619
always @*
3620
begin
3621
 
3622
    // Select controller or sequencer according to the select signal :
3623
    if (seq_ctl_sel)
3624
    begin
3625
        mem_be            = seq_be;
3626
        mem_wdata         = seq_wdata;
3627
        mem_wdata_valid   = seq_wdata_valid;
3628
        mem_dqs_burst     = seq_dqs_burst;
3629
    end
3630
 
3631
 
3632
    else
3633
    begin
3634
        mem_be            = ctl_mem_be;
3635
        mem_wdata         = ctl_mem_wdata;
3636
        mem_wdata_valid   = ctl_mem_wdata_valid;
3637
        mem_dqs_burst     = ctl_mem_dqs_burst;
3638
    end
3639
 
3640
end
3641
 
3642
genvar  a, b, c, d; // variable for generate statement
3643
integer j;          // variable for loop counters
3644
 
3645
/////////////////////////////////////////////////////////////////////////
3646
// generate the following write DQS logic on a per DQS group basis.
3647
// wdp_wdqs_2x and wdp_wdqs_oe_2x get output to the IOEs.
3648
////////////////////////////////////////////////////////////////////////
3649
 
3650
generate
3651
if (GENERATE_WRITE_DQS == 1)
3652
begin
3653
 
3654
    for (a=0; a<MEM_IF_DQS_WIDTH; a = a+1)
3655
    begin : gen_loop_dqs
3656
 
3657
        always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3658
        begin
3659
            if (reset_phy_clk_1x_n == 1'b0)
3660
            begin
3661
                wdp_wdqs_2x[a]     <= 0;
3662
                wdp_wdqs_oe_2x[a]  <= 0;
3663
            end
3664
            else
3665
            begin
3666
                wdp_wdqs_2x[a]     <= wdp_wdqs_oe_2x[a];
3667
                wdp_wdqs_oe_2x[a]  <= mem_dqs_burst;
3668
            end
3669
        end
3670
    end
3671
end
3672
endgenerate
3673
 
3674
///////////////////////////////////////////////////////////////////
3675
// Generate the write DQ logic.
3676
// These are internal registers which will be used to assign to:
3677
// wdp_wdata_h_2x, wdp_wdata_l_2x, wdp_wdata_oe_2x
3678
// (these get output to the IOEs).
3679
//////////////////////////////////////////////////////////////////
3680
 
3681
// number of times to replicate mem_wdata_valid bits
3682
parameter DQ_OE_REPS = MEM_IF_DQ_PER_DQS/NUM_DUPLICATE_REGS;
3683
 
3684
generate
3685
for (a=0; a<MEM_IF_DWIDTH/MEM_IF_DQ_PER_DQS; a=a+1)
3686
begin : gen_dq_oe_2x
3687
    always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3688
    begin
3689
 
3690
        if (reset_phy_clk_1x_n == 1'b0)
3691
        begin
3692
            dq_oe_2x[DQ_OE_REPS*(a+1)-1:DQ_OE_REPS*a] <= {(DQ_OE_REPS){1'b0}};
3693
        end
3694
        else
3695
 
3696
        begin
3697
            dq_oe_2x[DQ_OE_REPS*(a+1)-1:DQ_OE_REPS*a] <= {(DQ_OE_REPS){mem_wdata_valid[a]}};
3698
        end
3699
 
3700
    end
3701
end
3702
endgenerate
3703
 
3704
////////////////////////////////////////////////////////////////////////////////
3705
// fanout the dq_oe_2x, which has one register per NUM_DUPLICATE_REGS
3706
// (to save registers), to each bit of wdp_wdata_oe_2x_int and then
3707
// assign to the output wire wdp_wdata_oe_2x( ie one oe for each DQ "pin").
3708
////////////////////////////////////////////////////////////////////////////////
3709
 
3710
always @(dq_oe_2x)
3711
begin
3712
 
3713
    for (j=0; j<MEM_IF_DWIDTH; j=j+1)
3714
    begin
3715
        wdp_wdata_oe_2x_int[j] = dq_oe_2x[(j/NUM_DUPLICATE_REGS)];
3716
    end
3717
 
3718
end
3719
 
3720
assign wdp_wdata_oe_2x = wdp_wdata_oe_2x_int;
3721
 
3722
 
3723
//////////////////////////////////////////////////////////////////////
3724
// Write DQ mapping from mem_wdata to wdata_l_2x, wdata_h_2x
3725
//////////////////////////////////////////////////////////////////////
3726
 
3727
generate
3728
for (c=0; c<MEM_IF_DWIDTH; c=c+1)
3729
begin : gen_wdata
3730
 
3731
    always @(posedge phy_clk_1x)
3732
    begin
3733
            wdp_wdata_l_2x[c] <= mem_wdata[c +   MEM_IF_DWIDTH];
3734
            wdp_wdata_h_2x[c] <= mem_wdata[c                  ];
3735
 
3736
    end
3737
end
3738
endgenerate
3739
 
3740
 
3741
 
3742
///////////////////////////////////////////////////////
3743
// Conditional generation of DM logic, based on generic
3744
///////////////////////////////////////////////////////
3745
 
3746
generate
3747
if (MEM_IF_DM_PINS_EN == 1'b1)
3748
begin : dm_logic_enabled
3749
 
3750
 
3751
    ///////////////////////////////////////////////////////////////////
3752
    // Write DM logic: assignment to wdp_dm_h_2x, wdp_dm_l_2x
3753
    ///////////////////////////////////////////////////////////////////
3754
 
3755
 
3756
 
3757
    // for loop inside a generate statement, but outside a procedural block
3758
    // is treated as a nested generate
3759
 
3760
    for (d=0; d<MEM_IF_DM_WIDTH; d=d+1)
3761
    begin : gen_dm
3762
 
3763
        always @(posedge phy_clk_1x)
3764
        begin
3765
 
3766
            if (mem_wdata_valid[d] == 1'b1) // nb might need to duplicate to meet timing
3767
            begin
3768
                wdp_dm_l_2x[d] <= mem_be[d+MEM_IF_DM_WIDTH];
3769
                wdp_dm_h_2x[d] <= mem_be[d];
3770
            end
3771
 
3772
            // To support writes of less than the burst length, mask data when invalid :
3773
            else
3774
            begin
3775
                wdp_dm_l_2x[d] <= 1'b1;
3776
                wdp_dm_h_2x[d] <= 1'b1;
3777
            end
3778
 
3779
 
3780
 
3781
 
3782
        end
3783
    end // block: gen_dm
3784
 
3785
 
3786
end // block: dm_logic_enabled
3787
 
3788
 
3789
endgenerate
3790
 
3791
 
3792
endmodule
3793
 
3794
 
3795
 
3796
//
3797
 
3798
`ifdef ALT_MEM_PHY_DEFINES
3799
`else
3800
`include "alt_mem_phy_defines.v"
3801
`endif
3802
 
3803
`default_nettype none
3804
 
3805
//
3806
module altera_ddr_phy_alt_mem_phy_rdata_valid ( // inputs
3807
                               phy_clk_1x,
3808
                               reset_phy_clk_1x_n,
3809
                               seq_rdata_valid_lat_dec,
3810
                               seq_rdata_valid_lat_inc,
3811
                               seq_doing_rd,
3812
                               ctl_doing_rd,
3813
                               ctl_cal_success,
3814
 
3815
                               // outputs
3816
                               ctl_rdata_valid,
3817
                               seq_rdata_valid
3818
                              );
3819
 
3820
parameter FAMILY                       = "CYCLONEIII";
3821
parameter MEM_IF_DQS_WIDTH             = 8;
3822
parameter RDATA_VALID_AWIDTH           = 5;
3823
parameter RDATA_VALID_INITIAL_LAT      = 16;
3824
parameter DWIDTH_RATIO                 = 2;
3825
 
3826
localparam MAX_RDATA_VALID_DELAY       = 2 ** RDATA_VALID_AWIDTH;
3827
localparam RDV_DELAY_SHR_LEN           = MAX_RDATA_VALID_DELAY*(DWIDTH_RATIO/2);
3828
 
3829
// clocks
3830
input  wire                                              phy_clk_1x;
3831
 
3832
// resets
3833
input  wire                                              reset_phy_clk_1x_n;
3834
 
3835
// control signals from sequencer
3836
input  wire                                              seq_rdata_valid_lat_dec;
3837
input  wire                                              seq_rdata_valid_lat_inc;
3838
input  wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO / 2 -1 : 0] seq_doing_rd;
3839
input  wire [MEM_IF_DQS_WIDTH * DWIDTH_RATIO / 2 -1 : 0] ctl_doing_rd;
3840
input  wire                                              ctl_cal_success;
3841
 
3842
// output to IOE
3843
output reg [DWIDTH_RATIO / 2 -1 : 0]                     ctl_rdata_valid;
3844
output reg [DWIDTH_RATIO / 2 -1 : 0]                     seq_rdata_valid;
3845
 
3846
// Internal Signals / Variables
3847
reg  [RDATA_VALID_AWIDTH - 1 : 0]                         rd_addr;
3848
reg  [RDATA_VALID_AWIDTH - 1 : 0]                         wr_addr;
3849
reg  [RDATA_VALID_AWIDTH - 1 : 0]                         next_wr_addr;
3850
reg  [DWIDTH_RATIO/2 - 1 : 0]                             wr_data;
3851
 
3852
wire [DWIDTH_RATIO / 2 -1 : 0]                            int_rdata_valid;
3853
reg  [DWIDTH_RATIO/2 - 1 : 0]                             rdv_pipe_ip;
3854
reg                                                       rdv_pipe_ip_beat2_r;
3855
reg  [MEM_IF_DQS_WIDTH * DWIDTH_RATIO/2 - 1 : 0]          merged_doing_rd;
3856
reg                                                       seq_rdata_valid_lat_dec_1t;
3857
reg                                                       seq_rdata_valid_lat_inc_1t;
3858
reg                                                       bit_order_1x;
3859
 
3860
// Generate the input to the RDV delay.
3861
// Also determine the data for the OCT control & postamble paths (merged_doing_rd)
3862
generate
3863
    if (DWIDTH_RATIO == 4)
3864
    begin : merging_doing_rd_halfrate
3865
        always @*
3866
        begin
3867
            merged_doing_rd = seq_doing_rd | (ctl_doing_rd & {(2 * MEM_IF_DQS_WIDTH) {ctl_cal_success}});
3868
            rdv_pipe_ip[0]  = | merged_doing_rd[    MEM_IF_DQS_WIDTH - 1 : 0];
3869
            rdv_pipe_ip[1]  = | merged_doing_rd[2 * MEM_IF_DQS_WIDTH - 1 : MEM_IF_DQS_WIDTH];
3870
        end
3871
    end
3872
    else  // DWIDTH_RATIO == 2
3873
    begin : merging_doing_rd_fullrate
3874
        always @*
3875
        begin
3876
            merged_doing_rd = seq_doing_rd | (ctl_doing_rd & { MEM_IF_DQS_WIDTH {ctl_cal_success}});
3877
            rdv_pipe_ip[0]  = | merged_doing_rd[MEM_IF_DQS_WIDTH - 1 : 0];
3878
        end
3879
    end // else: !if(DWIDTH_RATIO == 4)
3880
endgenerate
3881
 
3882
 
3883
// Register inc/dec rdata_valid signals and generate bit_order_1x
3884
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3885
begin
3886
    if (reset_phy_clk_1x_n == 1'b0)
3887
        begin
3888
            seq_rdata_valid_lat_dec_1t <= 1'b0;
3889
            seq_rdata_valid_lat_inc_1t <= 1'b0;
3890
            bit_order_1x               <= 1'b1;
3891
 
3892
        end
3893
    else
3894
        begin
3895
            rdv_pipe_ip_beat2_r <= rdv_pipe_ip[DWIDTH_RATIO/2 - 1];
3896
            seq_rdata_valid_lat_dec_1t <= seq_rdata_valid_lat_dec;
3897
            seq_rdata_valid_lat_inc_1t <= seq_rdata_valid_lat_inc;
3898
 
3899
            if (DWIDTH_RATIO == 2)
3900
                bit_order_1x <= 1'b0;
3901
            else if (seq_rdata_valid_lat_dec == 1'b1 && seq_rdata_valid_lat_dec_1t == 1'b0)
3902
            begin
3903
                bit_order_1x <=  ~bit_order_1x;
3904
            end
3905
 
3906
            else if (seq_rdata_valid_lat_inc == 1'b1 && seq_rdata_valid_lat_inc_1t == 1'b0)
3907
            begin
3908
                bit_order_1x <= ~bit_order_1x;
3909
            end
3910
        end
3911
end
3912
 
3913
// write data
3914
generate // based on DWIDTH RATIO
3915
  if (DWIDTH_RATIO == 4) // Half Rate
3916
  begin : halfrate_wdata_gen
3917
      always @* // combinational logic sensitivity
3918
      begin
3919
 
3920
        if (bit_order_1x == 1'b0)
3921
        begin
3922
            wr_data  = {rdv_pipe_ip[1], rdv_pipe_ip[0]};
3923
        end
3924
 
3925
        else
3926
        begin
3927
            wr_data  = {rdv_pipe_ip[0], rdv_pipe_ip_beat2_r};
3928
        end
3929
      end
3930
  end
3931
else // Full-rate
3932
 begin : fullrate_wdata_gen
3933
 
3934
  always @* // combinational logic sensitivity
3935
    begin
3936
        wr_data = rdv_pipe_ip;
3937
    end
3938
  end
3939
endgenerate
3940
 
3941
// write address
3942
always @*
3943
begin
3944
 
3945
    next_wr_addr = wr_addr + 1'b1;
3946
 
3947
    if (seq_rdata_valid_lat_dec == 1'b1 && seq_rdata_valid_lat_dec_1t == 1'b0)
3948
    begin
3949
 
3950
        if ((bit_order_1x == 1'b0) || (DWIDTH_RATIO == 2))
3951
        begin
3952
            next_wr_addr = wr_addr;
3953
        end
3954
 
3955
    end
3956
 
3957
    else if (seq_rdata_valid_lat_inc == 1'b1 && seq_rdata_valid_lat_inc_1t == 1'b0)
3958
    begin
3959
 
3960
        if ((bit_order_1x == 1'b1) || (DWIDTH_RATIO ==2))
3961
        begin
3962
            next_wr_addr = wr_addr + 2'h2;
3963
        end
3964
 
3965
    end
3966
 
3967
end
3968
 
3969
 
3970
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3971
begin
3972
 
3973
    if (reset_phy_clk_1x_n == 1'b0)
3974
    begin
3975
        wr_addr <= RDATA_VALID_INITIAL_LAT[RDATA_VALID_AWIDTH - 1 : 0];
3976
    end
3977
 
3978
    else
3979
    begin
3980
        wr_addr <= next_wr_addr;
3981
    end
3982
 
3983
end
3984
 
3985
//     read address generator : just a free running counter.
3986
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
3987
begin
3988
 
3989
    if (reset_phy_clk_1x_n == 1'b0)
3990
    begin
3991
        rd_addr <= {RDATA_VALID_AWIDTH{1'b0}};
3992
    end
3993
 
3994
    else
3995
    begin
3996
        rd_addr <= rd_addr + 1'b1;     //inc address, can wrap
3997
    end
3998
 
3999
end
4000
 
4001
// altsyncram instance
4002
altsyncram #(.
4003
    address_aclr_b            ("NONE"),
4004
        .address_reg_b            ("CLOCK0"),
4005
        .clock_enable_input_a     ("BYPASS"),
4006
        .clock_enable_input_b     ("BYPASS"),
4007
        .clock_enable_output_b    ("BYPASS"),
4008
        .intended_device_family   (FAMILY),
4009
        .lpm_type                 ("altsyncram"),
4010
        .numwords_a               (2**RDATA_VALID_AWIDTH),
4011
        .numwords_b               (2**RDATA_VALID_AWIDTH),
4012
        .operation_mode           ("DUAL_PORT"),
4013
        .outdata_aclr_b           ("NONE"),
4014
        .outdata_reg_b            ("CLOCK0"),
4015
        .power_up_uninitialized   ("FALSE"),
4016
        .widthad_a                (RDATA_VALID_AWIDTH),
4017
        .widthad_b                (RDATA_VALID_AWIDTH),
4018
        .width_a                  (DWIDTH_RATIO/2),
4019
        .width_b                  (DWIDTH_RATIO/2),
4020
        .width_byteena_a          (1)
4021
) altsyncram_component (
4022
        .wren_a                   (1'b1),
4023
        .clock0                   (phy_clk_1x),
4024
        .address_a                (wr_addr),
4025
        .address_b                (rd_addr),
4026
        .data_a                   (wr_data),
4027
        .q_b                      (int_rdata_valid),
4028
        .aclr0                    (1'b0),
4029
        .aclr1                    (1'b0),
4030
        .addressstall_a           (1'b0),
4031
        .addressstall_b           (1'b0),
4032
        .byteena_a                (1'b1),
4033
        .byteena_b                (1'b1),
4034
        .clock1                   (1'b1),
4035
        .clocken0                 (1'b1),
4036
        .clocken1                 (1'b1),
4037
        .clocken2                 (1'b1),
4038
        .clocken3                 (1'b1),
4039
        .data_b                   ({(DWIDTH_RATIO/2){1'b1}}),
4040
        .eccstatus                (),
4041
        .q_a                      (),
4042
        .rden_a                   (1'b1),
4043
        .rden_b                   (1'b1),
4044
        .wren_b                   (1'b0)
4045
);
4046
 
4047
// Generate read data valid enable signals for controller and seqencer
4048
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
4049
begin
4050
    if (reset_phy_clk_1x_n == 1'b0)
4051
        begin
4052
            ctl_rdata_valid <= {(DWIDTH_RATIO/2){1'b0}};
4053
            seq_rdata_valid <= {(DWIDTH_RATIO/2){1'b0}};
4054
        end
4055
    else
4056
        begin
4057
            // shift the shift register by DWIDTH_RATIO locations
4058
            // rdv_delay_index plus (DWIDTH_RATIO/2)-1 bits counting down
4059
            ctl_rdata_valid <= int_rdata_valid & {(DWIDTH_RATIO/2){ctl_cal_success}};
4060
            seq_rdata_valid <= int_rdata_valid;
4061
        end
4062
end
4063
 
4064
 
4065
endmodule
4066
 
4067
`default_nettype wire
4068
 
4069
//
4070
 
4071
`ifdef ALT_MEM_PHY_DEFINES
4072
`else
4073
`include "alt_mem_phy_defines.v"
4074
`endif
4075
 
4076
//
4077
module altera_ddr_phy_alt_mem_phy_mux (
4078
                         phy_clk_1x,
4079
                         reset_phy_clk_1x_n,
4080
 
4081
// MUX Outputs to controller :
4082
                         ctl_address,
4083
                         ctl_read_req,
4084
                         ctl_wdata,
4085
                         ctl_write_req,
4086
                         ctl_size,
4087
                         ctl_be,
4088
                         ctl_refresh_req,
4089
                         ctl_burstbegin,
4090
 
4091
// Controller inputs to the MUX :
4092
                         ctl_ready,
4093
                         ctl_wdata_req,
4094
                         ctl_rdata,
4095
                         ctl_rdata_valid,
4096
                         ctl_refresh_ack,
4097
                         ctl_init_done,
4098
 
4099
// MUX Select line :
4100
                         ctl_usr_mode_rdy,
4101
 
4102
// MUX inputs from local interface :
4103
                         local_address,
4104
                         local_read_req,
4105
                         local_wdata,
4106
                         local_write_req,
4107
                         local_size,
4108
                         local_be,
4109
                         local_refresh_req,
4110
                         local_burstbegin,
4111
 
4112
// MUX outputs to sequencer :
4113
                         mux_seq_controller_ready,
4114
                         mux_seq_wdata_req,
4115
 
4116
// MUX inputs from sequencer :
4117
                         seq_mux_address,
4118
                         seq_mux_read_req,
4119
                         seq_mux_wdata,
4120
                         seq_mux_write_req,
4121
                         seq_mux_size,
4122
                         seq_mux_be,
4123
                         seq_mux_refresh_req,
4124
                         seq_mux_burstbegin,
4125
 
4126
// Changes made to accomodate new ports for self refresh/power-down & Auto precharge in HP Controller (User to PHY)
4127
                         local_autopch_req,
4128
                         local_powerdn_req,
4129
                         local_self_rfsh_req,
4130
                         local_powerdn_ack,
4131
                         local_self_rfsh_ack,
4132
 
4133
// Changes made to accomodate new ports for self refresh/power-down & Auto precharge in HP Controller (PHY to Controller)
4134
                         ctl_autopch_req,
4135
                         ctl_powerdn_req,
4136
                         ctl_self_rfsh_req,
4137
                         ctl_powerdn_ack,
4138
                         ctl_self_rfsh_ack,
4139
 
4140
// Also MUX some signals from the controller to the local interface :
4141
                         local_ready,
4142
                         local_wdata_req,
4143
                         local_init_done,
4144
                         local_rdata,
4145
                         local_rdata_valid,
4146
                         local_refresh_ack
4147
 
4148
                       );
4149
 
4150
 
4151
parameter LOCAL_IF_AWIDTH       =  26;
4152
parameter LOCAL_IF_DWIDTH       = 256;
4153
parameter LOCAL_BURST_LEN_BITS  =   1;
4154
parameter MEM_IF_DQ_PER_DQS     =   8;
4155
parameter MEM_IF_DWIDTH         =  64;
4156
 
4157
input wire                                           phy_clk_1x;
4158
input wire                                           reset_phy_clk_1x_n;
4159
 
4160
// MUX Select line :
4161
input wire                                           ctl_usr_mode_rdy;
4162
 
4163
// MUX inputs from local interface :
4164
input wire [LOCAL_IF_AWIDTH - 1 : 0]                 local_address;
4165
input wire                                           local_read_req;
4166
input wire [LOCAL_IF_DWIDTH - 1 : 0]                 local_wdata;
4167
input wire                                           local_write_req;
4168
input wire [LOCAL_BURST_LEN_BITS - 1 : 0]            local_size;
4169
input wire [(LOCAL_IF_DWIDTH/8) - 1 : 0]             local_be;
4170
input wire                                           local_refresh_req;
4171
input wire                                           local_burstbegin;
4172
 
4173
// MUX inputs from sequencer :
4174
input wire [LOCAL_IF_AWIDTH - 1 : 0]                 seq_mux_address;
4175
input wire                                           seq_mux_read_req;
4176
input wire [LOCAL_IF_DWIDTH - 1 : 0]                 seq_mux_wdata;
4177
input wire                                           seq_mux_write_req;
4178
input wire [LOCAL_BURST_LEN_BITS - 1 : 0]            seq_mux_size;
4179
input wire [(LOCAL_IF_DWIDTH/8) - 1:0]               seq_mux_be;
4180
input wire                                           seq_mux_refresh_req;
4181
input wire                                           seq_mux_burstbegin;
4182
 
4183
// MUX Outputs to controller :
4184
output reg [LOCAL_IF_AWIDTH - 1 : 0]                 ctl_address;
4185
output reg                                           ctl_read_req;
4186
output reg [LOCAL_IF_DWIDTH - 1 : 0]                 ctl_wdata;
4187
output reg                                           ctl_write_req;
4188
output reg [LOCAL_BURST_LEN_BITS - 1 : 0]            ctl_size;
4189
output reg [(LOCAL_IF_DWIDTH/8) - 1:0]               ctl_be;
4190
output reg                                           ctl_refresh_req;
4191
output reg                                           ctl_burstbegin;
4192
 
4193
 
4194
// The "ready" input from the controller shall be passed to either the
4195
// local interface if in user mode, or the sequencer :
4196
input wire                                           ctl_ready;
4197
output reg                                           local_ready;
4198
output reg                                           mux_seq_controller_ready;
4199
 
4200
// The controller's "wdata req" output is similarly passed to either
4201
// the local interface if in user mode, or the sequencer :
4202
input wire                                           ctl_wdata_req;
4203
output reg                                           local_wdata_req;
4204
output reg                                           mux_seq_wdata_req;
4205
 
4206
input wire                                           ctl_init_done;
4207
output reg                                           local_init_done;
4208
 
4209
input wire [LOCAL_IF_DWIDTH - 1 : 0]                 ctl_rdata;
4210
output reg  [LOCAL_IF_DWIDTH - 1 : 0]                local_rdata;
4211
 
4212
input wire                                           ctl_rdata_valid;
4213
output reg                                           local_rdata_valid;
4214
 
4215
input wire                                           ctl_refresh_ack;
4216
output reg                                           local_refresh_ack;
4217
 
4218
//-> Changes made to accomodate new ports for self refresh/power-down & Auto precharge in HP Controller (User to PHY)
4219
input  wire                                          local_autopch_req;
4220
input  wire                                          local_powerdn_req;
4221
input  wire                                          local_self_rfsh_req;
4222
output reg                                           local_powerdn_ack;
4223
output reg                                           local_self_rfsh_ack;
4224
 
4225
// --> Changes made to accomodate new ports for self refresh/power-down & Auto precharge in HP Controller (PHY to Controller)
4226
output reg                                           ctl_autopch_req;
4227
output reg                                           ctl_powerdn_req;
4228
output reg                                           ctl_self_rfsh_req;
4229
input  wire                                          ctl_powerdn_ack;
4230
input  wire                                          ctl_self_rfsh_ack;
4231
 
4232
 
4233
wire                                                 local_burstbegin_held;
4234
reg                                                  burstbegin_hold;
4235
 
4236
always @(posedge phy_clk_1x or negedge reset_phy_clk_1x_n)
4237
begin
4238
 
4239
    if (reset_phy_clk_1x_n == 1'b0)
4240
        burstbegin_hold <= 1'b0;
4241
 
4242
    else
4243
    begin
4244
 
4245
        if (local_ready == 1'b0 && (local_write_req == 1'b1 || local_read_req == 1'b1) && local_burstbegin == 1'b1)
4246
            burstbegin_hold <= 1'b1;
4247
        else if (local_ready == 1'b1 && (local_write_req == 1'b1 || local_read_req == 1'b1))
4248
            burstbegin_hold <= 1'b0;
4249
 
4250
    end
4251
end
4252
 
4253
// Gate the local burstbegin signal with the held version :
4254
assign local_burstbegin_held = burstbegin_hold || local_burstbegin;
4255
 
4256
always @*
4257
begin
4258
 
4259
    if (ctl_usr_mode_rdy == 1'b1)
4260
    begin
4261
 
4262
        // Pass local interface signals to the controller if ready :
4263
        ctl_address            = local_address;
4264
        ctl_read_req           = local_read_req;
4265
        ctl_wdata              = local_wdata;
4266
        ctl_write_req          = local_write_req;
4267
        ctl_size               = local_size;
4268
        ctl_be                 = local_be;
4269
        ctl_refresh_req        = local_refresh_req;
4270
        ctl_burstbegin         = local_burstbegin_held;
4271
 
4272
        // If in user mode,  pass on the controller's ready
4273
        // and wdata request signals to the local interface :
4274
        local_ready         = ctl_ready;
4275
        local_wdata_req     = ctl_wdata_req;
4276
        local_init_done     = ctl_init_done;
4277
        local_rdata         = ctl_rdata;
4278
        local_rdata_valid   = ctl_rdata_valid;
4279
        local_refresh_ack   = ctl_refresh_ack;
4280
 
4281
        // Whilst indicate to the sequencer that the controller is busy :
4282
        mux_seq_controller_ready = 1'b0;
4283
        mux_seq_wdata_req        = 1'b0;
4284
 
4285
        // Autopch_req & Local_power_req changes
4286
        ctl_autopch_req     = local_autopch_req;
4287
        ctl_powerdn_req     = local_powerdn_req;
4288
        ctl_self_rfsh_req   = local_self_rfsh_req;
4289
        local_powerdn_ack   = ctl_powerdn_ack;
4290
        local_self_rfsh_ack = ctl_self_rfsh_ack;
4291
 
4292
 
4293
    end
4294
 
4295
    else
4296
    begin
4297
 
4298
        // Pass local interface signals to the sequencer if not in user mode :
4299
 
4300
        // NB. The controller will have more address bits than the sequencer, so
4301
        // these are zero padded :
4302
        ctl_address            = seq_mux_address;
4303
        ctl_read_req           = seq_mux_read_req;
4304
        ctl_wdata              = seq_mux_wdata;
4305
        ctl_write_req          = seq_mux_write_req;
4306
        ctl_size               = seq_mux_size;        // NB. Should be tied-off when the mux is instanced
4307
        ctl_be                 = seq_mux_be;          // NB. Should be tied-off when the mux is instanced
4308
        ctl_refresh_req        = local_refresh_req; // NB. Should be tied-off when the mux is instanced
4309
        ctl_burstbegin         = seq_mux_burstbegin; // NB. Should be tied-off when the mux is instanced
4310
 
4311
        // Indicate to the local IF that the controller is busy :
4312
        local_ready         = 1'b0;
4313
        local_wdata_req     = 1'b0;
4314
        local_init_done     = 1'b0;
4315
        local_rdata         = {LOCAL_IF_DWIDTH{1'b0}};
4316
        local_rdata_valid   = 1'b0;
4317
        local_refresh_ack   = ctl_refresh_ack;
4318
 
4319
        // If not in user mode,  pass on the controller's ready
4320
        // and wdata request signals to the sequencer :
4321
        mux_seq_controller_ready   = ctl_ready;
4322
        mux_seq_wdata_req   = ctl_wdata_req;
4323
 
4324
       // Autopch_req & Local_power_req changes
4325
        ctl_autopch_req     = 1'b0;
4326
        ctl_powerdn_req     = 1'b0;
4327
        ctl_self_rfsh_req   = local_self_rfsh_req;
4328
        local_powerdn_ack   = 1'b0;
4329
        local_self_rfsh_ack = ctl_self_rfsh_ack;
4330
 
4331
    end
4332
 
4333
end
4334
 
4335
 
4336
 
4337
 
4338
endmodule
4339
 
4340
//
4341
 
4342
`default_nettype none
4343
 
4344
`ifdef ALT_MEM_PHY_DEFINES
4345
`else
4346
`include "alt_mem_phy_defines.v"
4347
`endif
4348
 
4349
/* -----------------------------------------------------------------------------
4350
// module description
4351
---------------------------------------------------------------------------- */
4352
//
4353
module altera_ddr_phy_alt_mem_phy_mimic(
4354
                         //Inputs 
4355
 
4356
                         //Clocks 
4357
                         measure_clk,         // full rate clock from PLL
4358
                         mimic_data_in,       // Input against which the VT variations 
4359
                                              // are tracked (e.g. memory clock)        
4360
 
4361
                         // Active low reset                            
4362
                         reset_measure_clk_n,
4363
 
4364
                         //Indicates that the mimic calibration sequence can start
4365
                         seq_mmc_start,       // from sequencer
4366
 
4367
 
4368
                         //Outputs      
4369
                         mmc_seq_done,        // mimic calibration finished for the current PLL phase       
4370
                         mmc_seq_value        // result value of the mimic calibration
4371
 
4372
        );
4373
 
4374
   input  wire measure_clk;
4375
   input  wire mimic_data_in;
4376
   input  wire reset_measure_clk_n;
4377
   input  wire seq_mmc_start;
4378
   output wire mmc_seq_done;
4379
   output wire mmc_seq_value;
4380
 
4381
   function integer clogb2;
4382
      input [31:0] value;
4383
      for (clogb2=0; value>0; clogb2=clogb2+1)
4384
          value = value >> 1;
4385
   endfunction // clogb2
4386
 
4387
 
4388
 
4389
 
4390
   // Parameters        
4391
   parameter NUM_MIMIC_SAMPLE_CYCLES = 6;
4392
 
4393
   parameter SHIFT_REG_COUNTER_WIDTH = clogb2(NUM_MIMIC_SAMPLE_CYCLES);
4394
 
4395
 
4396
   reg [`MIMIC_FSM_WIDTH-1:0]           mimic_state;
4397
 
4398
 
4399
   reg [2:0]                            seq_mmc_start_metastable;
4400
   wire                                 start_edge_detected;
4401
 
4402
   (* altera_attribute=" -name fast_input_register OFF"*) reg [1:0] mimic_data_in_metastable;
4403
 
4404
 
4405
   wire                                 mimic_data_in_sample;
4406
 
4407
   wire                                 shift_reg_data_out_all_ones;
4408
   reg                                  mimic_done_out;
4409
   reg                                  mimic_value_captured;
4410
 
4411
 
4412
   reg [SHIFT_REG_COUNTER_WIDTH : 0]    shift_reg_counter;
4413
   reg                                  shift_reg_enable;
4414
 
4415
   wire                                 shift_reg_data_in;
4416
   reg                                  shift_reg_s_clr;
4417
   wire                                 shift_reg_a_clr;
4418
 
4419
   reg [NUM_MIMIC_SAMPLE_CYCLES -1 : 0] shift_reg_data_out;
4420
 
4421
   // shift register which contains the sampled data
4422
   always @(posedge measure_clk or posedge shift_reg_a_clr)
4423
   begin
4424
      if (shift_reg_a_clr == 1'b1)
4425
      begin
4426
          shift_reg_data_out    <= {NUM_MIMIC_SAMPLE_CYCLES{1'b0}};
4427
      end
4428
 
4429
      else
4430
      begin
4431
         if (shift_reg_s_clr == 1'b1)
4432
         begin
4433
             shift_reg_data_out <= {NUM_MIMIC_SAMPLE_CYCLES{1'b0}};
4434
         end
4435
 
4436
         else if (shift_reg_enable == 1'b1)
4437
         begin
4438
             shift_reg_data_out <= {(shift_reg_data_out[NUM_MIMIC_SAMPLE_CYCLES -2 : 0]), shift_reg_data_in};
4439
         end
4440
      end
4441
   end
4442
 
4443
 
4444
  // Metastable-harden mimic_start : 
4445
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4446
  begin
4447
 
4448
    if (reset_measure_clk_n == 1'b0)
4449
    begin
4450
        seq_mmc_start_metastable    <= 0;
4451
    end
4452
    else
4453
 
4454
    begin
4455
        seq_mmc_start_metastable[0] <= seq_mmc_start;
4456
        seq_mmc_start_metastable[1] <= seq_mmc_start_metastable[0];
4457
        seq_mmc_start_metastable[2] <= seq_mmc_start_metastable[1];
4458
    end
4459
 
4460
  end
4461
 
4462
  assign start_edge_detected =  seq_mmc_start_metastable[1]
4463
                             && !seq_mmc_start_metastable[2];
4464
 
4465
  // Metastable-harden mimic_data_in : 
4466
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4467
  begin
4468
 
4469
    if (reset_measure_clk_n == 1'b0)
4470
    begin
4471
        mimic_data_in_metastable    <= 0;
4472
    end
4473
      //some mimic paths configurations have another flop inside the wysiwyg ioe 
4474
    else
4475
 
4476
    begin
4477
        mimic_data_in_metastable[0] <= mimic_data_in;
4478
        mimic_data_in_metastable[1] <= mimic_data_in_metastable[0];
4479
    end
4480
 
4481
  end
4482
 
4483
  assign mimic_data_in_sample =  mimic_data_in_metastable[1];
4484
 
4485
  // Main FSM : 
4486
  always @(posedge measure_clk or negedge reset_measure_clk_n )
4487
  begin
4488
 
4489
     if (reset_measure_clk_n == 1'b0)
4490
     begin
4491
 
4492
         mimic_state           <= `MIMIC_IDLE;
4493
 
4494
         mimic_done_out        <= 1'b0;
4495
         mimic_value_captured  <= 1'b0;
4496
 
4497
         shift_reg_counter     <= 0;
4498
         shift_reg_enable      <= 1'b0;
4499
         shift_reg_s_clr       <= 1'b0;
4500
 
4501
     end
4502
 
4503
     else
4504
     begin
4505
 
4506
         case (mimic_state)
4507
 
4508
         `MIMIC_IDLE : begin
4509
 
4510
                           shift_reg_counter     <= 0;
4511
                           mimic_done_out        <= 1'b0;
4512
                           shift_reg_s_clr       <= 1'b1;
4513
                           shift_reg_enable      <= 1'b1;
4514
 
4515
                           if (start_edge_detected == 1'b1)
4516
                           begin
4517
                               mimic_state       <= `MIMIC_SAMPLE;
4518
                               shift_reg_counter <= shift_reg_counter + 1'b1;
4519
                               shift_reg_s_clr   <= 1'b0;
4520
                           end
4521
                           else
4522
 
4523
                           begin
4524
                               mimic_state <= `MIMIC_IDLE;
4525
                           end
4526
         end // case: MIMIC_IDLE
4527
 
4528
           `MIMIC_SAMPLE : begin
4529
 
4530
                               shift_reg_counter        <= shift_reg_counter + 1'b1;
4531
 
4532
                               if (shift_reg_counter == NUM_MIMIC_SAMPLE_CYCLES + 1)
4533
 
4534
                               begin
4535
                                   mimic_done_out       <= 1'b1;
4536
                                   mimic_value_captured <= shift_reg_data_out_all_ones; //captured only here
4537
                                   shift_reg_enable     <= 1'b0;
4538
                                   shift_reg_counter    <= shift_reg_counter;
4539
                                   mimic_state          <= `MIMIC_SEND;
4540
                               end
4541
           end // case: MIMIC_SAMPLE
4542
 
4543
           `MIMIC_SEND : begin
4544
 
4545
                             mimic_done_out  <= 1'b1; //redundant statement, here just for readibility 
4546
                             mimic_state     <= `MIMIC_SEND1;
4547
 
4548
            /* mimic_value_captured will not change during MIMIC_SEND
4549
               it will change next time mimic_done_out is asserted
4550
               mimic_done_out will be reset during MIMIC_IDLE
4551
               the purpose of the current state is to add one clock cycle
4552
               mimic_done_out will be active for 2 measure_clk clock cycles, i.e
4553
               the pulses duration will be just one sequencer clock cycle
4554
               (which is half rate) */
4555
           end // case: MIMIC_SEND
4556
 
4557
           // MIMIC_SEND1 and MIMIC_SEND2 extend the mimic_done_out signal by another 2 measure_clk_2x cycles
4558
           // so it is a total of 4 measure clocks long (ie 2 half-rate clock cycles long in total)
4559
           `MIMIC_SEND1 : begin
4560
 
4561
                              mimic_done_out  <= 1'b1; //redundant statement, here just for readibility 
4562
                              mimic_state     <= `MIMIC_SEND2;
4563
 
4564
           end
4565
 
4566
           `MIMIC_SEND2 : begin
4567
 
4568
                              mimic_done_out  <= 1'b1; //redundant statement, here just for readibility 
4569
                              mimic_state     <= `MIMIC_IDLE;
4570
 
4571
           end
4572
 
4573
 
4574
           default : begin
4575
                         mimic_state <= `MIMIC_IDLE;
4576
           end
4577
 
4578
 
4579
         endcase
4580
 
4581
     end
4582
 
4583
  end
4584
 
4585
  assign shift_reg_data_out_all_ones   = (( & shift_reg_data_out) == 1'b1) ? 1'b1
4586
                                                                           : 1'b0;
4587
 
4588
  // Shift Register assignments
4589
  assign shift_reg_data_in  =  mimic_data_in_sample;
4590
  assign shift_reg_a_clr    =  !reset_measure_clk_n;
4591
 
4592
  // Output assignments  
4593
  assign mmc_seq_done    = mimic_done_out;
4594
  assign mmc_seq_value   = mimic_value_captured;
4595
 
4596
 
4597
endmodule
4598
 
4599
`default_nettype wire
4600
 
4601
//
4602
 
4603
 
4604
/* -----------------------------------------------------------------------------
4605
// module description
4606
----------------------------------------------------------------------------- */
4607
//
4608
module altera_ddr_phy_alt_mem_phy_mimic_debug(
4609
        // Inputs
4610
 
4611
        // Clocks 
4612
        measure_clk,    // full rate clock from PLL
4613
 
4614
        // Active low reset                             
4615
        reset_measure_clk_n,
4616
 
4617
        mimic_recapture_debug_data, // from user board button
4618
 
4619
        mmc_seq_done,   // mimic calibration finished for the current PLL phase
4620
        mmc_seq_value   // result value of the mimic calibration        
4621
 
4622
        );
4623
 
4624
 
4625
   // Parameters 
4626
 
4627
   parameter NUM_DEBUG_SAMPLES_TO_STORE = 4096;   // can range from 4096 to 524288
4628
   parameter PLL_STEPS_PER_CYCLE        = 24;     // can  range from 16 to 48  
4629
 
4630
   input wire measure_clk;
4631
   input wire reset_measure_clk_n;
4632
 
4633
   input wire mimic_recapture_debug_data;
4634
 
4635
   input wire mmc_seq_done;
4636
   input wire mmc_seq_value;
4637
 
4638
 
4639
   function integer clogb2;
4640
      input [31:0] value;
4641
      for (clogb2=0; value>0; clogb2=clogb2+1)
4642
          value = value >> 1;
4643
   endfunction // clogb2
4644
 
4645
 
4646
   parameter RAM_WR_ADDRESS_WIDTH = clogb2(NUM_DEBUG_SAMPLES_TO_STORE - 1); // can range from 12 to 19 
4647
 
4648
 
4649
   reg                                       s_clr_ram_wr_address_count;
4650
 
4651
   reg [(clogb2(PLL_STEPS_PER_CYCLE)-1) : 0] mimic_sample_count;
4652
 
4653
   reg [RAM_WR_ADDRESS_WIDTH-1 : 0 ]         ram_write_address;
4654
   wire                                      ram_wr_enable;
4655
   wire [0:0]                                debug_ram_data;
4656
   reg                                       clear_ram_wr_enable;
4657
 
4658
   reg [1:0]                                 mimic_recapture_debug_data_metastable;
4659
 
4660
   wire                                      mimic_done_in_dbg; // for internal use, just 1 measure_clk cycles long
4661
   reg                                       mmc_seq_done_r;
4662
 
4663
 
4664
   // generate mimic_done_in_debug : a single clock wide pulse based on the rising edge of mmc_seq_done:
4665
 
4666
   always @ (posedge measure_clk or negedge reset_measure_clk_n)
4667
   begin
4668
     if (reset_measure_clk_n == 1'b0)      // asynchronous reset (active low)
4669
     begin
4670
         mmc_seq_done_r <= 1'b0;
4671
     end
4672
     else
4673
 
4674
     begin
4675
         mmc_seq_done_r <= mmc_seq_done;
4676
     end
4677
 
4678
   end
4679
 
4680
 
4681
   assign mimic_done_in_dbg   = mmc_seq_done && !mmc_seq_done_r;
4682
 
4683
   assign ram_wr_enable       = mimic_done_in_dbg && !clear_ram_wr_enable;
4684
   assign debug_ram_data[0]   = mmc_seq_value;
4685
 
4686
 
4687
 
4688
  altsyncram #(
4689
 
4690
                .clock_enable_input_a   ( "BYPASS"),
4691
                .clock_enable_output_a  ( "BYPASS"),
4692
                .intended_device_family ( "Stratix II"),
4693
                .lpm_hint               ( "ENABLE_RUNTIME_MOD=YES, INSTANCE_NAME=MRAM"),
4694
                .lpm_type               ( "altsyncram"),
4695
                .maximum_depth          ( 4096),
4696
                .numwords_a             ( 4096),
4697
                .operation_mode         ( "SINGLE_PORT"),
4698
                .outdata_aclr_a         ( "NONE"),
4699
                .outdata_reg_a          ( "UNREGISTERED"),
4700
                .power_up_uninitialized ( "FALSE"),
4701
                .widthad_a              ( 12),
4702
                .width_a                ( 1),
4703
                .width_byteena_a        ( 1)
4704
        )
4705
         altsyncram_component (
4706
                .wren_a                 ( ram_wr_enable),
4707
                .clock0                 ( measure_clk),
4708
                .address_a              ( ram_write_address),
4709
                .data_a                 ( debug_ram_data),
4710
                .q_a                    ( )
4711
        );
4712
 
4713
 
4714
 
4715
 
4716
  //  Metastability_mimic_recapture_debug_data : 
4717
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4718
  begin
4719
 
4720
    if (reset_measure_clk_n == 1'b0)
4721
    begin
4722
        mimic_recapture_debug_data_metastable    <=  2'b0;
4723
    end
4724
    else
4725
 
4726
    begin
4727
        mimic_recapture_debug_data_metastable[0] <= mimic_recapture_debug_data;
4728
        mimic_recapture_debug_data_metastable[1] <= mimic_recapture_debug_data_metastable[0];
4729
    end
4730
 
4731
  end
4732
 
4733
 
4734
 
4735
  //mimic_sample_counter : 
4736
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4737
  begin
4738
 
4739
    if (reset_measure_clk_n == 1'b0)
4740
    begin
4741
        mimic_sample_count <= 0;        // (others => '0'); 
4742
    end
4743
    else
4744
 
4745
    begin
4746
      if (mimic_done_in_dbg == 1'b1)
4747
      begin
4748
          mimic_sample_count <= mimic_sample_count + 1'b1;
4749
 
4750
          if (mimic_sample_count == PLL_STEPS_PER_CYCLE-1)
4751
          begin
4752
              mimic_sample_count <= 0; //(others => '0');
4753
          end
4754
 
4755
      end
4756
 
4757
    end
4758
 
4759
  end
4760
 
4761
 
4762
 
4763
  //RAMWrAddressCounter : 
4764
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4765
  begin
4766
 
4767
      if (reset_measure_clk_n == 1'b0)
4768
      begin
4769
          ram_write_address <= 0;      //(others => '0');   
4770
          clear_ram_wr_enable <= 1'b0;
4771
      end
4772
      else
4773
 
4774
      begin
4775
 
4776
          if (s_clr_ram_wr_address_count == 1'b1) // then --Active high synchronous reset
4777
          begin
4778
              ram_write_address <= 0;      //(others => '0');
4779
              clear_ram_wr_enable <= 1'b1;
4780
          end
4781
 
4782
          else
4783
          begin
4784
              clear_ram_wr_enable <= 1'b0;
4785
 
4786
              if (mimic_done_in_dbg == 1'b1)
4787
              begin
4788
                  if (ram_write_address != NUM_DEBUG_SAMPLES_TO_STORE-1)
4789
                  begin
4790
                      ram_write_address <= ram_write_address + 1'b1;
4791
                  end
4792
 
4793
                  else
4794
                  begin
4795
                      clear_ram_wr_enable <= 1'b1;
4796
                  end
4797
              end
4798
 
4799
          end
4800
 
4801
      end
4802
 
4803
  end
4804
 
4805
  //ClearRAMWrAddressCounter : 
4806
  always @(posedge measure_clk or negedge reset_measure_clk_n)
4807
  begin
4808
 
4809
      if (reset_measure_clk_n == 1'b0)
4810
      begin
4811
          s_clr_ram_wr_address_count <= 1'b0;
4812
      end
4813
 
4814
      else
4815
      begin
4816
          if (mimic_recapture_debug_data_metastable[1] == 1'b1)
4817
          begin
4818
              s_clr_ram_wr_address_count <= 1'b1;
4819
          end
4820
 
4821
          else if (mimic_sample_count == 0)
4822
          begin
4823
              s_clr_ram_wr_address_count <= 1'b0;
4824
          end
4825
 
4826
      end
4827
 
4828
  end
4829
 
4830
  endmodule
4831
 
4832
//
4833
 
4834
`ifdef ALT_MEM_PHY_DEFINES
4835
`else
4836
`include "alt_mem_phy_defines.v"
4837
`endif
4838
 
4839
//
4840
module altera_ddr_phy_alt_mem_phy_reset_pipe (
4841
                                input  wire clock,
4842
                                input  wire pre_clear,
4843
                                output wire reset_out
4844
                              );
4845
 
4846
parameter PIPE_DEPTH = 4;
4847
 
4848
    // Declare pipeline registers.
4849
    reg [PIPE_DEPTH - 1 : 0]  ams_pipe;
4850
    integer                   i;
4851
 
4852
//    begin : RESET_PIPE
4853
        always @(posedge clock or negedge pre_clear)
4854
        begin
4855
 
4856
            if (pre_clear == 1'b0)
4857
            begin
4858
                ams_pipe <= 0;
4859
            end
4860
 
4861
            else
4862
            begin
4863
               for (i=0; i< PIPE_DEPTH; i = i + 1)
4864
               begin
4865
                   if (i==0)
4866
                       ams_pipe[i] <= 1'b1;
4867
                   else
4868
                       ams_pipe[i] <= ams_pipe[i-1];
4869
               end
4870
            end // if-else
4871
 
4872
        end // always
4873
//    end
4874
 
4875
    assign reset_out = ams_pipe[PIPE_DEPTH-1];
4876
 
4877
 
4878
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.