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

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source/] [tx_sync_gtx.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
 
2
//-----------------------------------------------------------------------------
3
//
4
// (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
5
//
6
// This file contains confidential and proprietary information
7
// of Xilinx, Inc. and is protected under U.S. and
8
// international copyright and other intellectual property
9
// laws.
10
//
11
// DISCLAIMER
12
// This disclaimer is not a license and does not grant any
13
// rights to the materials distributed herewith. Except as
14
// otherwise provided in a valid license issued to you by
15
// Xilinx, and to the maximum extent permitted by applicable
16
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
17
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
18
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
19
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
20
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
21
// (2) Xilinx shall not be liable (whether in contract or tort,
22
// including negligence, or under any other theory of
23
// liability) for any loss or damage of any kind or nature
24
// related to, arising under or in connection with these
25
// materials, including for any direct, or any indirect,
26
// special, incidental, or consequential loss or damage
27
// (including loss of data, profits, goodwill, or any type of
28
// loss or damage suffered as a result of any action brought
29
// by a third party) even if such damage or loss was
30
// reasonably foreseeable or Xilinx had been advised of the
31
// possibility of the same.
32
//
33
// CRITICAL APPLICATIONS
34
// Xilinx products are not designed or intended to be fail-
35
// safe, or for use in any application requiring fail-safe
36
// performance, such as life-support or safety devices or
37
// systems, Class III medical devices, nuclear facilities,
38
// applications related to the deployment of airbags, or any
39
// other applications that could lead to death, personal
40
// injury, or severe property or environmental damage
41
// (individually and collectively, "Critical
42
// Applications"). Customer assumes the sole risk and
43
// liability of any use of Xilinx products in Critical
44
// Applications, subject only to applicable laws and
45
// regulations governing limitations on product liability.
46
//
47
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
48
// PART OF THIS FILE AT ALL TIMES.
49
//
50
//-----------------------------------------------------------------------------
51
// Project    : V5-Block Plus for PCI Express
52
// File       : tx_sync_gtx.v
53
//--------------------------------------------------------------------------------
54
//--------------------------------------------------------------------------------
55
///////////////////////////////////////////////////////////////////////////////
56
//   ____  ____ 
57
//  /   /\/   / 
58
// /___/  \  /    Vendor: Xilinx 
59
// \   \   \/     Version : 1.5
60
//  \   \         Application : RocketIO GTX Wizard 
61
//  /   /         Filename : tx_sync.v
62
// /___/   /\     Timestamp : 
63
// \   \  /  \ 
64
//  \___\/\___\ 
65
//
66
//
67
// Module TX_SYNC
68
// Generated by Xilinx RocketIO GTX Wizard
69
 
70
`timescale 1ns / 1ps
71
`define DLY #1
72
 
73
module TX_SYNC #(
74
  parameter         PLL_DIVSEL_OUT    =   1
75
)
76
 
77
(
78
  // User DRP Interface
79
  output  reg [16-1:0]            USER_DO,
80
  input       [16-1:0]            USER_DI,
81
  input       [7-1:0]             USER_DADDR,
82
  input                           USER_DEN,
83
  input                           USER_DWE,
84
  output  reg                     USER_DRDY,
85
 
86
  // GT DRP Interface 
87
  output      [16-1:0]            GT_DO,         // connects to DI of GTX_DUAL
88
  input       [16-1:0]            GT_DI,         // connects to DO of GTX_DUAL
89
  output  reg [7-1:0]             GT_DADDR,
90
  output  reg                     GT_DEN,
91
  output                          GT_DWE,
92
  input                           GT_DRDY,
93
 
94
  // Clocks and Reset
95
  input                           USER_CLK,
96
  input                           DCLK,
97
  input                           RESET,
98
  input                           RESETDONE,
99
 
100
  // Phase Alignment ports to GT
101
  output                          TXENPMAPHASEALIGN,
102
  output                          TXPMASETPHASE,
103
  output  reg                     TXRESET,
104
 
105
  // SYNC operations 
106
  output                          SYNC_DONE,
107
  input                           RESTART_SYNC
108
 
109
);
110
 
111
// synthesis attribute X_CORE_INFO of TX_SYNC is "gtxwizard_v1_4, Coregen v10.1_ip2";
112
 
113
parameter C_DRP_DWIDTH = 16;
114
parameter C_DRP_AWIDTH = 7;
115
 
116
//*******************************Register Declarations************************
117
// USER_CLK domain
118
 
119
reg   [1:0]             reset_usrclk_r; // reset to SYNC FSM
120
reg                     dclk_fsms_rdy_r; // trigger to move to start_drp state 
121
reg                     dclk_fsms_rdy_r2; // trigger to move to start_drp state
122
reg   [6:0]             sync_state;
123
reg   [6:0]             sync_next_state;
124
reg   [40*7:0]          sync_fsm_name;
125
reg                     revert_drp;
126
reg                     start_drp;
127
reg                     start_drp_done_r2;
128
reg                     start_drp_done_r;
129
reg                     txreset_done_r;
130
reg                     revert_drp_done_r2;
131
reg                     revert_drp_done_r;
132
reg                     phase_align_done_r;
133
reg   [15:0]            sync_counter_r;
134
reg                     en_phase_align_r;
135
reg                     set_phase_r;
136
reg   [5:0]             wait_before_sync_r;
137
reg                     restart_sync_r2;
138
reg                     restart_sync_r;
139
reg                     resetdone_r;
140
reg                     resetdone_r2;
141
 
142
 // synthesis attribute fsm_encoding of sync_state is one-hot;
143
 
144
 // synthesis attribute ASYNC_REG of dclk_fsms_rdy_r is "TRUE";
145
 // synthesis attribute ASYNC_REG of start_drp_done_r is "TRUE";
146
 // synthesis attribute ASYNC_REG of revert_drp_done_r is "TRUE";
147
 // synthesis attribute ASYNC_REG of restart_sync_r is "TRUE";
148
 // synthesis attribute ASYNC_REG of resetdone_r is "TRUE"; 
149
 
150
// DCLK domain
151
 
152
reg   [1:0]             reset_dclk_r; // reset to DRP, XD and DB FSMs
153
reg  [C_DRP_DWIDTH-1:0] user_di_r = {C_DRP_DWIDTH{1'b0}};
154
reg  [C_DRP_AWIDTH-1:0] user_daddr_r = {C_DRP_AWIDTH{1'b0}};
155
reg                     user_den_r;
156
reg                     user_req;
157
reg                     user_dwe_r;
158
reg                     xd_req = 1'b0;
159
reg                     xd_read = 1'b0;
160
reg                     xd_write = 1'b0;
161
reg                     xd_drp_done = 1'b0;
162
reg  [C_DRP_DWIDTH-1:0] xd_wr_wreg = {C_DRP_DWIDTH{1'b0}};
163
reg  [C_DRP_AWIDTH-1:0] xd_addr_r;
164
reg                     gt_drdy_r = 1'b0;
165
reg [C_DRP_DWIDTH-1:0]  gt_do_r = {C_DRP_DWIDTH{1'b0}};
166
reg   [3:0]             db_state;
167
reg   [3:0]             db_next_state;
168
reg   [5:0]             drp_state;
169
reg   [5:0]             drp_next_state;
170
reg   [15:0]            xd_state;
171
reg   [15:0]            xd_next_state;
172
reg   [40*7:0]          db_fsm_name;
173
reg   [40*7:0]          drp_fsm_name;
174
reg   [40*7:0]          xd_fsm_name;
175
reg                     revert_drp_r2;
176
reg                     revert_drp_r;
177
reg                     start_drp_r2;
178
reg                     start_drp_r;
179
 
180
 // synthesis attribute fsm_encoding of db_state is one-hot;
181
 // synthesis attribute fsm_encoding of drp_state is one-hot;
182
 // synthesis attribute fsm_encoding of xd_state is one-hot;
183
 
184
 // synthesis attribute ASYNC_REG of start_drp_r is "TRUE";
185
 // synthesis attribute ASYNC_REG of revert_drp_r is "TRUE";  
186
 
187
 
188
 
189
//*******************************Wire Declarations****************************
190
 
191
wire [C_DRP_AWIDTH-1:0] c_tx_xclk0_addr;
192
wire [C_DRP_AWIDTH-1:0] c_tx_xclk1_addr;
193
wire                    user_sel;
194
wire                    xd_sel;
195
wire                    drp_rd;
196
wire                    drp_wr;
197
wire                    db_fsm_rdy;
198
wire                    drp_fsm_rdy;
199
wire                    xd_fsm_rdy;
200
wire                    dclk_fsms_rdy;
201
wire                    revert_drp_done;
202
wire                    start_drp_done;
203
wire                    count_setphase_complete_r;
204
wire                    txreset_i;
205
 
206
 
207
//----------------------------------------------------------------------------
208
// Arbitration FSM - Blocks User DRP Access when SYNC DRP operation 
209
// is in progress
210
//----------------------------------------------------------------------------
211
parameter C_RESET           = 4'b0001;
212
parameter C_IDLE            = 4'b0010;
213
parameter C_XD_DRP_OP       = 4'b0100;
214
parameter C_USER_DRP_OP     = 4'b1000;
215
 
216
 
217
//----------------------------------------------------------------------------
218
// DRP FSM
219
//----------------------------------------------------------------------------
220
parameter C_DRP_RESET       = 6'b000001;
221
parameter C_DRP_IDLE        = 6'b000010;
222
parameter C_DRP_READ        = 6'b000100;
223
parameter C_DRP_WRITE       = 6'b001000;
224
parameter C_DRP_WAIT        = 6'b010000;
225
parameter C_DRP_COMPLETE    = 6'b100000;
226
 
227
 
228
//----------------------------------------------------------------------------
229
// XCLK_SEL DRP FSM
230
//----------------------------------------------------------------------------
231
parameter C_XD_RESET              = 16'b0000000000000001;
232
parameter C_XD_IDLE               = 16'b0000000000000010;
233
parameter C_XD_RD_XCLK0_TXUSR     = 16'b0000000000000100;
234
parameter C_XD_MD_XCLK0_TXUSR     = 16'b0000000000001000;
235
parameter C_XD_WR_XCLK0_TXUSR     = 16'b0000000000010000;
236
parameter C_XD_RD_XCLK1_TXUSR     = 16'b0000000000100000;
237
parameter C_XD_MD_XCLK1_TXUSR     = 16'b0000000001000000;
238
parameter C_XD_WR_XCLK1_TXUSR     = 16'b0000000010000000;
239
parameter C_XD_WAIT               = 16'b0000000100000000;
240
parameter C_XD_RD_XCLK0_TXOUT     = 16'b0000001000000000;
241
parameter C_XD_MD_XCLK0_TXOUT     = 16'b0000010000000000;
242
parameter C_XD_WR_XCLK0_TXOUT     = 16'b0000100000000000;
243
parameter C_XD_RD_XCLK1_TXOUT     = 16'b0001000000000000;
244
parameter C_XD_MD_XCLK1_TXOUT     = 16'b0010000000000000;
245
parameter C_XD_WR_XCLK1_TXOUT     = 16'b0100000000000000;
246
parameter C_XD_DONE               = 16'b1000000000000000;
247
 
248
//----------------------------------------------------------------------------
249
// SYNC FSM
250
//----------------------------------------------------------------------------
251
parameter C_SYNC_IDLE               = 7'b0000001;
252
parameter C_SYNC_START_DRP          = 7'b0000010;
253
parameter C_SYNC_PHASE_ALIGN        = 7'b0000100;
254
parameter C_SYNC_REVERT_DRP         = 7'b0001000;
255
parameter C_SYNC_TXRESET            = 7'b0010000;
256
parameter C_SYNC_WAIT_RESETDONE     = 7'b0100000;
257
parameter C_SYNC_DONE               = 7'b1000000;
258
 
259
//----------------------------------------------------------------------------
260
// Make Addresses for GTX0 or GTX1 at compile time
261
//----------------------------------------------------------------------------
262
parameter C_GTX0_TX_XCLK_ADDR     = 7'h3A;
263
parameter C_GTX1_TX_XCLK_ADDR     = 7'h15;
264
 
265
assign c_tx_xclk0_addr    = C_GTX0_TX_XCLK_ADDR;
266
assign c_tx_xclk1_addr    = C_GTX1_TX_XCLK_ADDR;
267
 
268
 
269
//----------------------------------------------------------------------------
270
// Sync RESET to USER_CLK and DCLK domain
271
//----------------------------------------------------------------------------
272
always @(posedge DCLK or posedge RESET)
273
  if (RESET)
274
    reset_dclk_r <= 2'b11;
275
  else
276
    reset_dclk_r <= {1'b0, reset_dclk_r[1]};
277
 
278
always @(posedge USER_CLK or posedge RESET)
279
  if (RESET)
280
    reset_usrclk_r <= 2'b11;
281
  else
282
    reset_usrclk_r <= {1'b0, reset_usrclk_r[1]};
283
 
284
 
285
//----------------------------------------------------------------------------
286
// User DRP Transaction Capture Input Registers
287
//----------------------------------------------------------------------------
288
// User Data Input
289
always @ (posedge DCLK)
290
begin
291
  if (reset_dclk_r[0])
292
    user_di_r <= 1'b0;
293
  else if (USER_DEN)
294
    user_di_r <= USER_DI;
295
end
296
 
297
// User DRP Address
298
always @ (posedge DCLK)
299
begin
300
  if (reset_dclk_r[0])
301
    user_daddr_r <= 7'b0;
302
  else if (USER_DEN)
303
    user_daddr_r <= USER_DADDR[C_DRP_AWIDTH-1:0];
304
end
305
 
306
// User Data Write Enable
307
always @ (posedge DCLK)
308
  if (reset_dclk_r[0])
309
    user_dwe_r <= 1'b0;
310
  else if (USER_DEN)
311
    user_dwe_r <= USER_DWE;
312
 
313
// Register the user_den_r when the user is granted access from the
314
// Arbitration FSM
315
always @ (posedge DCLK)
316
  if (reset_dclk_r[0] | (db_state==C_USER_DRP_OP))
317
    user_den_r <= 1'b0;
318
  else if (~user_den_r)
319
    user_den_r <= USER_DEN;
320
 
321
// Generate the user request (user_req) signal when the user is not accessing
322
// the same DRP addresses as the deskew Block or when the deskew
323
// Block is in idle or done states.
324
always @ (posedge DCLK)
325
  if (reset_dclk_r[0] | (db_state==C_USER_DRP_OP))
326
    user_req <= 1'b0;
327
  else if (
328
            ~(user_daddr_r==c_tx_xclk0_addr) &
329
            ~(user_daddr_r==c_tx_xclk1_addr))
330
    user_req <= user_den_r;
331
  else if (xd_state==C_XD_IDLE || xd_state==C_XD_DONE)
332
    user_req <= user_den_r;
333
 
334
// User Data Output
335
always @ (posedge DCLK)
336
  if ( (db_state == C_USER_DRP_OP) & GT_DRDY)
337
    USER_DO <= GT_DI;
338
 
339
// User Data Ready
340
always @ (posedge DCLK)
341
  if (reset_dclk_r[0] | USER_DRDY)
342
    USER_DRDY <= 1'b0;
343
  else if ( (db_state==C_USER_DRP_OP) )
344
    USER_DRDY <= GT_DRDY;
345
 
346
//----------------------------------------------------------------------------
347
// GT DRP Interface
348
//----------------------------------------------------------------------------
349
// GT Data Output: the data output is generated either from a XCLK_SEL DRP
350
// FSM operation, an Auto deskew FSM operation, or a user access.
351
always @(posedge DCLK)
352
  casez( {xd_sel,user_sel} )
353
    2'b1?: gt_do_r <= xd_wr_wreg;
354
    2'b01: gt_do_r <= user_di_r;
355
  endcase
356
 
357
assign GT_DO = gt_do_r;
358
 
359
// GT DRP Address: the DRP address is generated either from a XCLK_SEL DRP  
360
// FSM operation, or a user access.  DRP address ranges from 0x40 to 0x7F.
361
always @(posedge DCLK)
362
begin
363
  casez( {xd_sel, user_sel})
364
    2'b1?: GT_DADDR <= xd_addr_r;
365
    2'b01: GT_DADDR <= user_daddr_r;
366
  endcase
367
end
368
 
369
// GT Data Enable: the data enable is generated whenever there is a DRP
370
// Read or a DRP Write
371
always @(posedge DCLK)
372
  if (reset_dclk_r[0])
373
    GT_DEN <= 1'b0;
374
  else
375
    GT_DEN <= (drp_state==C_DRP_IDLE) & (drp_wr | drp_rd);
376
 
377
// GT Data Write Enable
378
assign GT_DWE = (drp_state==C_DRP_WRITE);
379
 
380
// GT Data Ready
381
always @(posedge DCLK)
382
  gt_drdy_r <= GT_DRDY;
383
 
384
 
385
 
386
 
387
//----------------------------------------------------------------------------
388
// SYNC FSM Internal Logic
389
// 1. Trigger DRP operation to change TX_XCLK_SEL to "TXUSR"
390
// 2. Perform Phase Alignment by asserting PMASETPHASE, ENPMAPHASEALIGN ports
391
// 3. Trigger DRP operation to change TX_XCLK_SEL back to "TXOUT"
392
// 4. Apply TXRESET, wait for RESETDONE to go High and assert SYNC_DONE
393
//----------------------------------------------------------------------------
394
assign dclk_fsms_rdy = db_fsm_rdy & xd_fsm_rdy & drp_fsm_rdy;
395
 
396
always @(posedge USER_CLK)
397
begin
398
  if (dclk_fsms_rdy)
399
    dclk_fsms_rdy_r <= 1'b1;
400
  else
401
    dclk_fsms_rdy_r <= 1'b0;
402
end
403
 
404
always @(posedge USER_CLK)
405
    dclk_fsms_rdy_r2 <= dclk_fsms_rdy_r;
406
 
407
// Generate a signal to trigger drp operation of changing XCLK_SEL to TXUSR
408
always @(posedge USER_CLK)
409
begin
410
  if (sync_state == C_SYNC_START_DRP)
411
    start_drp <= 1'b1;
412
  else
413
    start_drp <= 1'b0;
414
end
415
 
416
// Capture start_drp_done(DCLK) signal on USER_CLK domain
417
always @(posedge USER_CLK)
418
begin
419
  if (reset_usrclk_r[0])
420
    start_drp_done_r <= 1'b0;
421
  else if (start_drp_done)
422
    start_drp_done_r <= 1'b1;
423
  else
424
    start_drp_done_r <= 1'b0;
425
end
426
 
427
always @(posedge USER_CLK)
428
    start_drp_done_r2 <= start_drp_done_r;
429
 
430
// Perform Phase Align operations in C_SYNC_PHASE_ALIGN state
431
// Assert TXENPMAPHASEALIGN in C_SYNC_PHASE_ALIGN state
432
// Once asserted, TXENPMAPHASEALIGN is deasserted only when
433
// the state machine moves back to C_SYNC_IDLE
434
always @(posedge USER_CLK)
435
begin
436
  if ( reset_usrclk_r[0] | (sync_state == C_SYNC_IDLE) )
437
     en_phase_align_r <= 1'b0;
438
  else if (sync_state == C_SYNC_PHASE_ALIGN)
439
     en_phase_align_r <= 1'b1;
440
end
441
 
442
assign TXENPMAPHASEALIGN = en_phase_align_r;
443
 
444
// Assert set_phase_r in C_SYNC_PHASE ALIGN state after waiting for 
445
// 32 cycles. set_phase_r is deasserted after setphase count is complete
446
always @(posedge USER_CLK)
447
begin
448
  if ( reset_usrclk_r[0] | ~en_phase_align_r )
449
    wait_before_sync_r <= `DLY  6'b000000;
450
  else if( ~wait_before_sync_r[5] )
451
    wait_before_sync_r <= `DLY  wait_before_sync_r + 1'b1;
452
end
453
 
454
always @(posedge USER_CLK)
455
begin
456
  if ( ~wait_before_sync_r[5] )
457
    set_phase_r <= 1'b0;
458
  else if ( ~count_setphase_complete_r & (sync_state == C_SYNC_PHASE_ALIGN) )
459
    set_phase_r <= 1'b1;
460
  else
461
    set_phase_r <= 1'b0;
462
end
463
 
464
// Assign PMASETPHASE to set_phase_r
465
assign TXPMASETPHASE = set_phase_r;
466
 
467
// Counter for holding SYNC for SYNC_CYCLES 
468
always @(posedge USER_CLK)
469
begin
470
 if ( reset_usrclk_r[0] | ~(sync_state == C_SYNC_PHASE_ALIGN) )
471
   sync_counter_r <= `DLY  16'h0000;
472
 else if (set_phase_r)
473
   sync_counter_r <= `DLY  sync_counter_r + 1'b1;
474
end
475
 
476
generate
477
if (PLL_DIVSEL_OUT==1)
478
begin : pll_divsel_out_equals_1
479
// 8192 cycles of setphase for output divider of 1
480
  assign count_setphase_complete_r = sync_counter_r[13];
481
end
482
else if (PLL_DIVSEL_OUT==2)
483
begin :pll_divsel_out_equals_2
484
// 16384 cycles of setphase for output divider of 2
485
  assign count_setphase_complete_r = sync_counter_r[14];
486
end
487
else
488
begin :pll_divsel_out_equals_4
489
// 32768 cycles of setphase for output divider of 4
490
  assign count_setphase_complete_r = sync_counter_r[15];
491
end
492
endgenerate
493
 
494
// Assert phase_align_done_r when setphase count is complete
495
always @(posedge USER_CLK)
496
begin
497
  if (reset_usrclk_r[0])
498
    phase_align_done_r <= 1'b0;
499
  else
500
    phase_align_done_r <= set_phase_r & count_setphase_complete_r;
501
end
502
 
503
// Generate a signal to trigger drp operation to revert XCLK_SEL back to TXOUT
504
always @(posedge USER_CLK)
505
begin
506
  if (reset_usrclk_r[0])
507
    revert_drp <= 1'b0;
508
  else if (sync_state == C_SYNC_REVERT_DRP)
509
    revert_drp <= 1'b1;
510
  else
511
    revert_drp <= 1'b0;
512
end
513
 
514
// Capture revert_drp_done(DCLK) signal on USER_CLK domain
515
always @(posedge USER_CLK)
516
begin
517
  if (reset_usrclk_r[0])
518
    revert_drp_done_r <= 1'b0;
519
  else if (revert_drp_done)
520
    revert_drp_done_r <= 1'b1;
521
  else
522
    revert_drp_done_r <= 1'b0;
523
end
524
 
525
always @(posedge USER_CLK)
526
    revert_drp_done_r2 <= revert_drp_done_r;
527
 
528
// Assert txreset_i in C_SYNC_TXRESET state
529
assign txreset_i = (sync_state == C_SYNC_TXRESET);
530
 
531
// Register txreset_i on USER_CLK
532
always @(posedge USER_CLK)
533
  TXRESET <= txreset_i;
534
 
535
always @(posedge USER_CLK)
536
begin
537
  if (reset_usrclk_r[0])
538
    txreset_done_r <= 1'b0;
539
  else if ((sync_state == C_SYNC_TXRESET) & ~resetdone_r2)
540
    txreset_done_r <= 1'b1;
541
  else
542
    txreset_done_r <= 1'b0;
543
end
544
 
545
// Capture RESETDONE on USER_CLK
546
always @(posedge USER_CLK)
547
begin
548
  if (RESETDONE)
549
    resetdone_r <= 1'b1;
550
  else
551
    resetdone_r <= 1'b0;
552
end
553
 
554
always @(posedge USER_CLK)
555
  resetdone_r2 <= resetdone_r;
556
 
557
// Capture RESTART_SYNC on USER_CLK
558
always @(posedge USER_CLK)
559
begin
560
  if (RESTART_SYNC)
561
    restart_sync_r <= 1'b1;
562
  else
563
    restart_sync_r <= 1'b0;
564
end
565
 
566
always @(posedge USER_CLK)
567
  restart_sync_r2 <= restart_sync_r;
568
 
569
assign SYNC_DONE = (sync_state == C_SYNC_DONE);
570
 
571
//----------------------------------------------------------------------------
572
// SYNC FSM
573
//----------------------------------------------------------------------------
574
always @(posedge USER_CLK)
575
begin
576
  if (reset_usrclk_r[0])
577
    sync_state <= C_SYNC_IDLE;
578
  else
579
    sync_state <= sync_next_state;
580
end
581
 
582
always @*
583
begin
584
  case (sync_state)
585
    C_SYNC_IDLE: begin
586
      sync_next_state <= dclk_fsms_rdy_r2 ? C_SYNC_START_DRP : C_SYNC_IDLE;
587
      sync_fsm_name = "C_SYNC_IDLE";
588
    end
589
 
590
    C_SYNC_START_DRP: begin
591
      sync_next_state <= start_drp_done_r2 ? C_SYNC_PHASE_ALIGN : C_SYNC_START_DRP;
592
      sync_fsm_name = "C_SYNC_START_DRP";
593
    end
594
 
595
    C_SYNC_PHASE_ALIGN: begin
596
      sync_next_state <= phase_align_done_r ? C_SYNC_REVERT_DRP : C_SYNC_PHASE_ALIGN;
597
      sync_fsm_name = "C_SYNC_PHASE_ALIGN";
598
    end
599
 
600
    C_SYNC_REVERT_DRP: begin
601
      sync_next_state <= revert_drp_done_r2 ? C_SYNC_TXRESET : C_SYNC_REVERT_DRP;
602
      sync_fsm_name = "C_SYNC_REVERT_DRP";
603
    end
604
 
605
    C_SYNC_TXRESET: begin
606
      sync_next_state <= txreset_done_r ? C_SYNC_WAIT_RESETDONE : C_SYNC_TXRESET;
607
      sync_fsm_name = "C_SYNC_TXRESET";
608
    end
609
 
610
    C_SYNC_WAIT_RESETDONE: begin
611
      sync_next_state <= resetdone_r2 ? C_SYNC_DONE : C_SYNC_WAIT_RESETDONE;
612
      sync_fsm_name = "C_SYNC_WAIT_RESETDONE";
613
    end
614
 
615
    C_SYNC_DONE: begin
616
      sync_next_state <= restart_sync_r2 ? C_SYNC_IDLE : C_SYNC_DONE;
617
      sync_fsm_name = "C_SYNC_DONE";
618
    end
619
 
620
    default: begin
621
      sync_next_state <= C_SYNC_IDLE;
622
      sync_fsm_name = "default";
623
    end
624
 
625
  endcase
626
end
627
 
628
 
629
//----------------------------------------------------------------------------
630
// deskew Block Internal Logic:  The different select signals are
631
// generated for a user DRP operations as well as internal deskew Block
632
// accesses.
633
//----------------------------------------------------------------------------
634
assign xd_sel = (db_state == C_XD_DRP_OP);
635
assign user_sel = (db_state == C_USER_DRP_OP);
636
assign db_fsm_rdy = ~(db_state == C_RESET);
637
 
638
//----------------------------------------------------------------------------
639
// deskew Block (DB) FSM
640
//----------------------------------------------------------------------------
641
always @(posedge DCLK)
642
begin
643
  if (reset_dclk_r[0])
644
    db_state <= C_RESET;
645
  else
646
    db_state <= db_next_state;
647
end
648
 
649
always @*
650
begin
651
  case (db_state)
652
    C_RESET: begin
653
      db_next_state <= C_IDLE;
654
      db_fsm_name = "C_RESET";
655
    end
656
 
657
    C_IDLE: begin
658
      if (xd_req)         db_next_state <= C_XD_DRP_OP;
659
      else if (user_req)  db_next_state <= C_USER_DRP_OP;
660
      else                db_next_state <= C_IDLE;
661
      db_fsm_name = "C_IDLE";
662
    end
663
 
664
    C_XD_DRP_OP: begin
665
      db_next_state <= gt_drdy_r ? C_IDLE : C_XD_DRP_OP;
666
      db_fsm_name = "C_XD_DRP_OP";
667
    end
668
 
669
    C_USER_DRP_OP: begin
670
      db_next_state <= gt_drdy_r ? C_IDLE : C_USER_DRP_OP;
671
      db_fsm_name = "C_USER_DRP_OP";
672
    end
673
 
674
    default: begin
675
      db_next_state <= C_IDLE;
676
      db_fsm_name = "default";
677
    end
678
 
679
  endcase
680
end
681
 
682
//----------------------------------------------------------------------------
683
// XCLK_SEL DRP Block Internal Logic
684
//----------------------------------------------------------------------------
685
// Request for DRP operation
686
always @(posedge DCLK)
687
begin
688
  if ((xd_state == C_XD_IDLE) | xd_drp_done)
689
    xd_req <= 1'b0;
690
  else
691
    xd_req <= xd_read | xd_write;
692
end
693
 
694
// Indicates DRP Read
695
always @(posedge DCLK)
696
begin
697
  if ((xd_state == C_XD_IDLE) | xd_drp_done)
698
    xd_read <= 1'b0;
699
  else
700
    xd_read <=  (xd_state == C_XD_RD_XCLK0_TXUSR) |
701
                (xd_state == C_XD_RD_XCLK1_TXUSR) |
702
                (xd_state == C_XD_RD_XCLK0_TXOUT) |
703
                (xd_state == C_XD_RD_XCLK1_TXOUT);
704
end
705
 
706
// Indicates Detect DRP Write
707
always @(posedge DCLK)
708
begin
709
  if ((xd_state == C_XD_IDLE) | xd_drp_done)
710
    xd_write <= 1'b0;
711
  else
712
    xd_write <= (xd_state == C_XD_WR_XCLK0_TXUSR) |
713
                (xd_state == C_XD_WR_XCLK1_TXUSR) |
714
                (xd_state == C_XD_WR_XCLK0_TXOUT) |
715
                (xd_state == C_XD_WR_XCLK1_TXOUT);
716
end
717
 
718
// Detect DRP Write Working Register
719
//TODO: Add check for txrx_invert bits as well
720
always @(posedge DCLK)
721
begin
722
  if ((db_state == C_XD_DRP_OP) & xd_read & GT_DRDY)
723
    xd_wr_wreg <= GT_DI;
724
  else begin
725
    case (xd_state)
726
      C_XD_MD_XCLK0_TXUSR:
727
        xd_wr_wreg <= {xd_wr_wreg[15:9], 1'b1, xd_wr_wreg[7:0]};
728
      C_XD_MD_XCLK1_TXUSR:
729
        xd_wr_wreg <= {xd_wr_wreg[15:8], 1'b1, xd_wr_wreg[6:0]};
730
      C_XD_MD_XCLK0_TXOUT:
731
        xd_wr_wreg <= {xd_wr_wreg[15:9], 1'b0, xd_wr_wreg[7:0]};
732
      C_XD_MD_XCLK1_TXOUT:
733
        xd_wr_wreg <= {xd_wr_wreg[15:8], 1'b0, xd_wr_wreg[6:0]};
734
    endcase
735
  end
736
end
737
 
738
// Generate DRP Addresses 
739
always @*
740
begin
741
  case (xd_state)
742
    C_XD_RD_XCLK0_TXUSR:  xd_addr_r <= c_tx_xclk0_addr;
743
    C_XD_WR_XCLK0_TXUSR:  xd_addr_r <= c_tx_xclk0_addr;
744
    C_XD_RD_XCLK0_TXOUT:  xd_addr_r <= c_tx_xclk0_addr;
745
    C_XD_WR_XCLK0_TXOUT:  xd_addr_r <= c_tx_xclk0_addr;
746
    C_XD_RD_XCLK1_TXUSR:  xd_addr_r <= c_tx_xclk1_addr;
747
    C_XD_WR_XCLK1_TXUSR:  xd_addr_r <= c_tx_xclk1_addr;
748
    C_XD_RD_XCLK1_TXOUT:  xd_addr_r <= c_tx_xclk1_addr;
749
    C_XD_WR_XCLK1_TXOUT:  xd_addr_r <= c_tx_xclk1_addr;
750
    default:              xd_addr_r <= c_tx_xclk0_addr;
751
  endcase
752
end
753
 
754
// Assert DRP DONE when DRP Operation is Complete
755
always @(posedge DCLK)
756
  xd_drp_done <= GT_DRDY & (db_state==C_XD_DRP_OP);
757
 
758
// Assert xd_fsm_rdy when xd_state is not C_XD_RESET
759
assign xd_fsm_rdy = ~(xd_state == C_XD_RESET);
760
 
761
// Generate a start_drp_r2 on DCLK domain from start_drp(USER_CLK)
762
always @(posedge DCLK)
763
begin
764
  if (reset_dclk_r[0])
765
    start_drp_r <= 1'b0;
766
  else if (start_drp)
767
    start_drp_r <= 1'b1;
768
  else
769
    start_drp_r <= 1'b0;
770
end
771
 
772
always @(posedge DCLK)
773
    start_drp_r2 <= start_drp_r;
774
 
775
// Assert start_drp_done when xd_state is C_XD_WAIT
776
assign start_drp_done = (xd_state == C_XD_WAIT);
777
 
778
// Generate a revert_drp_r2 on DCLK domain from revert_drp(USER_CLK)
779
always @(posedge DCLK)
780
begin
781
  if (reset_dclk_r[0])
782
    revert_drp_r <= 1'b0;
783
  else if (revert_drp)
784
    revert_drp_r <= 1'b1;
785
  else
786
    revert_drp_r <= 1'b0;
787
end
788
 
789
always @(posedge DCLK)
790
    revert_drp_r2 <= revert_drp_r;
791
 
792
// Assert revert_drp_done when xd_state is C_XD_DONE
793
assign revert_drp_done = (xd_state == C_XD_DONE);
794
 
795
 
796
//----------------------------------------------------------------------------
797
// XCLK_SEL DRP FSM:  The XD FSM is triggered by the SYNC FSM
798
//----------------------------------------------------------------------------
799
always @(posedge DCLK)
800
begin
801
  if (reset_dclk_r[0])
802
    xd_state <= C_XD_RESET;
803
  else
804
    xd_state <= xd_next_state;
805
end
806
 
807
always @*
808
begin
809
  case (xd_state)
810
    C_XD_RESET: begin
811
      xd_next_state <= C_XD_IDLE;
812
      xd_fsm_name = "C_XD_RESET";
813
    end
814
 
815
    C_XD_IDLE: begin
816
      if (start_drp_r2)
817
        xd_next_state <= C_XD_RD_XCLK0_TXUSR;
818
      else
819
        xd_next_state <= C_XD_IDLE;
820
      xd_fsm_name = "C_XD_IDLE";
821
    end
822
 
823
    C_XD_RD_XCLK0_TXUSR: begin
824
      xd_next_state <= xd_drp_done ? C_XD_MD_XCLK0_TXUSR :
825
                                     C_XD_RD_XCLK0_TXUSR;
826
      xd_fsm_name = "C_XD_RD_XCLK0_TXUSR";
827
    end
828
 
829
    C_XD_MD_XCLK0_TXUSR: begin
830
      xd_next_state <= C_XD_WR_XCLK0_TXUSR;
831
      xd_fsm_name = "C_XD_MD_XCLK0_TXUSR";
832
    end
833
 
834
    C_XD_WR_XCLK0_TXUSR: begin
835
      xd_next_state <= xd_drp_done ? C_XD_RD_XCLK1_TXUSR : C_XD_WR_XCLK0_TXUSR;
836
      xd_fsm_name = "C_XD_WR_XCLK0_TXUSR";
837
    end
838
 
839
    C_XD_RD_XCLK1_TXUSR: begin
840
      xd_next_state <= xd_drp_done ? C_XD_MD_XCLK1_TXUSR : C_XD_RD_XCLK1_TXUSR;
841
      xd_fsm_name = "C_XD_RD_XCLK1_TXUSR";
842
    end
843
 
844
    C_XD_MD_XCLK1_TXUSR: begin
845
      xd_next_state <= C_XD_WR_XCLK1_TXUSR;
846
      xd_fsm_name = "C_XD_MD_XCLK1_TXUSR";
847
    end
848
 
849
    C_XD_WR_XCLK1_TXUSR: begin
850
      xd_next_state <= xd_drp_done ? C_XD_WAIT: C_XD_WR_XCLK1_TXUSR;
851
      xd_fsm_name = "C_XD_WR_XCLK1_TXUSR";
852
    end
853
 
854
    C_XD_WAIT: begin
855
      xd_next_state <= revert_drp_r2 ? C_XD_RD_XCLK0_TXOUT : C_XD_WAIT;
856
      xd_fsm_name = "C_XD_WAIT";
857
    end
858
 
859
    C_XD_RD_XCLK0_TXOUT: begin
860
      xd_next_state <= xd_drp_done ?
861
                        C_XD_MD_XCLK0_TXOUT : C_XD_RD_XCLK0_TXOUT;
862
      xd_fsm_name = "C_XD_RD_XCLK0_TXOUT";
863
    end
864
 
865
    C_XD_MD_XCLK0_TXOUT: begin
866
      xd_next_state <= C_XD_WR_XCLK0_TXOUT;
867
      xd_fsm_name = "C_XD_MD_XCLK0_TXOUT";
868
    end
869
 
870
    C_XD_WR_XCLK0_TXOUT: begin
871
      xd_next_state <= xd_drp_done ? C_XD_RD_XCLK1_TXOUT : C_XD_WR_XCLK0_TXOUT;
872
      xd_fsm_name = "C_XD_WR_XCLK0_TXOUT";
873
    end
874
 
875
    C_XD_RD_XCLK1_TXOUT: begin
876
      xd_next_state <= xd_drp_done ? C_XD_MD_XCLK1_TXOUT : C_XD_RD_XCLK1_TXOUT;
877
      xd_fsm_name = "C_XD_RD_XCLK1_TXOUT";
878
    end
879
 
880
    C_XD_MD_XCLK1_TXOUT: begin
881
      xd_next_state <= C_XD_WR_XCLK1_TXOUT;
882
      xd_fsm_name = "C_XD_MD_XCLK1_TXOUT";
883
    end
884
 
885
    C_XD_WR_XCLK1_TXOUT: begin
886
      xd_next_state <= xd_drp_done ? C_XD_DONE : C_XD_WR_XCLK1_TXOUT;
887
      xd_fsm_name = "C_XD_WR_XCLK1_TXOUT";
888
    end
889
 
890
    C_XD_DONE: begin
891
      xd_next_state <= ~revert_drp_r2 ? C_XD_IDLE : C_XD_DONE;
892
      xd_fsm_name = "C_XD_DONE";
893
    end
894
 
895
    default: begin
896
      xd_next_state <= C_XD_IDLE;
897
      xd_fsm_name = "default";
898
    end
899
 
900
  endcase
901
end
902
 
903
 
904
//----------------------------------------------------------------------------
905
// DRP Read/Write FSM
906
//----------------------------------------------------------------------------
907
// Generate a read signal for the DRP
908
assign drp_rd = ((db_state == C_XD_DRP_OP) & xd_read) |
909
                ((db_state == C_USER_DRP_OP) & ~user_dwe_r);
910
 
911
// Generate a write signal for the DRP
912
assign drp_wr = ((db_state == C_XD_DRP_OP) & xd_write) |
913
                ((db_state == C_USER_DRP_OP) & user_dwe_r);
914
 
915
 
916
assign drp_fsm_rdy = ~(drp_state == C_DRP_RESET);
917
 
918
always @(posedge DCLK)
919
begin
920
  if (reset_dclk_r[0])
921
    drp_state <= C_DRP_RESET;
922
  else
923
    drp_state <= drp_next_state;
924
end
925
 
926
always @*
927
begin
928
  case (drp_state)
929
    C_DRP_RESET: begin
930
      drp_next_state <= C_DRP_IDLE;
931
      drp_fsm_name = "C_DRP_RESET";
932
    end
933
 
934
    C_DRP_IDLE: begin
935
      drp_next_state <= drp_wr ? C_DRP_WRITE : (drp_rd?C_DRP_READ:C_DRP_IDLE);
936
      drp_fsm_name = "C_DRP_IDLE";
937
    end
938
 
939
    C_DRP_READ: begin
940
      drp_next_state <= C_DRP_WAIT;
941
      drp_fsm_name = "C_DRP_READ";
942
    end
943
 
944
    C_DRP_WRITE: begin
945
      drp_next_state <= C_DRP_WAIT;
946
      drp_fsm_name = "C_DRP_WRITE";
947
    end
948
 
949
    C_DRP_WAIT: begin
950
      drp_next_state <= gt_drdy_r ? C_DRP_COMPLETE : C_DRP_WAIT;
951
      drp_fsm_name = "C_DRP_WAIT";
952
    end
953
 
954
    C_DRP_COMPLETE: begin
955
      drp_next_state <= C_DRP_IDLE;
956
      drp_fsm_name = "C_DRP_COMPLETE";
957
    end
958
 
959
    default: begin
960
      drp_next_state <= C_DRP_IDLE;
961
      drp_fsm_name = "default";
962
    end
963
 
964
  endcase
965
end
966
 
967
endmodule
968
 

powered by: WebSVN 2.1.0

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