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

Subversion Repositories sata_controller_core

[/] [sata_controller_core/] [trunk/] [sata2_bus_v1_00_a/] [base_system/] [pcores/] [sata_core_v1_00_a/] [hdl/] [verilog/] [oob_control.v] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 ashwin_men
//*****************************************************************************/
2
// Module :     OOB_control 
3
// Version:     1.0
4
// Author:      Ashwin Mendon 
5
// Description: This module handles the Out-Of-Band (OOB) sinaling requirements
6
//               for link initialization and synchronization 
7
//              It has been modified from Xilinx XAPP870 to support Virtex 6 GTX
8
//              transceivers 
9
//*****************************************************************************/
10
 
11
module OOB_control (
12
 
13
 clk,   // Clock
14
 reset, // reset        
15
 oob_control_ila_control,
16
 
17
 /**** GTX ****/
18
 rxreset,       // GTX PCS reset
19
 rx_locked,     // GTX PLL is locked
20
 gen2,          // Generation 2 speed
21
 txcominit,     // TX OOB issue  RESET/INIT
22
 txcomwake,     // TX OOB issue  WAKE
23
 cominitdet,    // RX OOB detect INIT 
24
 comwakedet,    // RX OOB detect WAKE 
25
 rxelecidle,    // RX electrical idle
26
 txelecidle_out,// TX electircal idel
27
 rxbyteisaligned,// RX byte alignment completed
28
 
29
 tx_dataout,    // Outgoing TX data to GTX
30
 tx_charisk_out,// TX byted is K character
31
 
32
 rx_datain,    // Data from GTX            
33
 rx_charisk_in,   // K character from GTX                        
34
 /**** GTX ****/
35
 
36
 /**** LINK LAYER ****/
37
 // INPUT 
38
 tx_datain,     // Incoming TX data from SATA Link Layer 
39
 tx_charisk_in, // K character indicator                          
40
 // OUTPUT 
41
 rx_dataout,   // Data to SATA Link Layer
42
 rx_charisk_out,
43
 
44
 linkup,        // SATA link is established
45
 linkup_led_out, // LINKUP LED output
46
 align_en_out,
47
 CurrentState_out // Current state for Chipscope
48
 /**** LINK LAYER ****/
49
 
50
);
51
 
52
        parameter       CHIPSCOPE  = "TRUE";
53
        input           clk;
54
        input           reset;
55
        input   [35:0]  oob_control_ila_control;
56
        input           rx_locked;
57
        input           gen2;
58
        // Added for GTX        
59
        input           cominitdet;
60
        input           comwakedet;
61
        // Added for GTX        
62
        input           rxelecidle;
63
        input           rxbyteisaligned;
64
        input   [31:0]  tx_datain;
65
        input           tx_charisk_in;
66
        input   [3:0]   rx_charisk_in;
67
        input   [31:0]  rx_datain;      //changed for GTX 
68
 
69
        output          rxreset;
70
        // Added for GTX        
71
        output          txcominit;
72
        output          txcomwake;
73
        // Added for GTX        
74
        output          txelecidle_out;
75
        output  [31:0]  tx_dataout;     //changed for GTX 
76
        output          tx_charisk_out;
77
 
78
        output  [31:0]  rx_dataout;
79
        output  [3:0]   rx_charisk_out;
80
        output          linkup;
81
        output          linkup_led_out;
82
        output          align_en_out;
83
        output  [7:0]   CurrentState_out;
84
 
85
        parameter [3:0]
86
        host_comreset           = 8'h00,
87
        wait_dev_cominit        = 8'h01,
88
        host_comwake            = 8'h02,
89
        wait_dev_comwake        = 8'h03,
90
        wait_after_comwake      = 8'h04,
91
        wait_after_comwake1     = 8'h05,
92
        host_d10_2              = 8'h06,
93
        host_send_align         = 8'h07,
94
        link_ready              = 8'h08,
95
        link_idle               = 8'h09;
96
 
97
        // Primitves
98
        parameter ALIGN      = 4'b00;
99
        parameter SYNC       = 4'b01;
100
        parameter DIAL       = 4'b10;
101
        //parameter R_RDY      = 4'b11;
102
        parameter LINK_LAYER = 4'b11;
103
 
104
        reg     [7:0]    CurrentState, NextState;
105
        reg     [17:0]   count;
106
        reg     [3:0]    align_char_cnt_reg;
107
        reg             align_char_cnt_rst, align_char_cnt_inc;
108
        reg             count_en;
109
        reg             tx_charisk, tx_charisk_next;
110
        reg             txelecidle, txelecidle_next;
111
        reg             linkup_r, linkup_r_next;
112
        reg             rxreset;
113
        reg     [31:0]  tx_datain_r;
114
        wire    [31:0]  tx_dataout_i;
115
        reg     [31:0]  rx_dataout_i;
116
        wire    [31:0]  tx_align, tx_sync, tx_dial, tx_r_rdy;
117
        reg     [3:0]   rx_charisk_r;
118
        reg             txcominit_r, txcomwake_r;
119
        wire    [1:0]   align_count_mux_out;
120
        reg     [8:0]   align_count;
121
        reg     [1:0]   prim_type, prim_type_next;
122
 
123
        wire            align_det, sync_det, cont_det, sof_det, eof_det, x_rdy_det, r_err_det, r_ok_det;
124
        reg             align_en, align_en_r;
125
        reg             rxelecidle_r;
126
        reg     [31:0]  rx_datain_r;
127
        reg     [3:0]   rx_charisk_in_r;
128
        reg             rxbyteisaligned_r;
129
        reg             comwakedet_r, cominitdet_r;
130
 
131
// OOB FSM Logic Process
132
 
133
always @ ( CurrentState or count or rxelecidle_r or rx_locked or rx_datain_r or
134
           cominitdet_r or comwakedet_r or
135
           align_det or sync_det or cont_det or
136
           tx_charisk_in )
137
begin : Comb_FSM
138
 
139
        count_en = 1'b0;
140
        NextState = host_comreset;
141
        linkup_r_next = linkup_r;
142
        txcominit_r =1'b0;
143
        txcomwake_r = 1'b0;
144
        rxreset = 1'b0;
145
        txelecidle_next = txelecidle;
146
        prim_type_next = prim_type;
147
        tx_charisk_next = tx_charisk;
148
        rx_dataout_i  = 32'b0;
149
        rx_charisk_r = 4'b0;
150
 
151
       case (CurrentState)
152
                host_comreset :
153
                        begin
154
                                txelecidle_next = 1'b1;
155
                                prim_type_next = ALIGN;
156
                                if (rx_locked)
157
                                        begin
158
                                                if ((~gen2 && count == 18'h00051) || (gen2 && count == 18'h000A2))
159
                                                begin
160
                                                        txcominit_r =1'b0;
161
                                                        NextState = wait_dev_cominit;
162
                                                end
163
                                                else  //Issue COMRESET  
164
                                                begin
165
                                                        txcominit_r =1'b1;
166
                                                        count_en = 1'b1;
167
                                                        NextState = host_comreset;
168
                                                end
169
                                        end
170
                                else
171
                                        begin
172
                                                txcominit_r =1'b0;
173
                                                NextState = host_comreset;
174
                                        end
175
                        end
176
 
177
                wait_dev_cominit : //1
178
                        begin
179
                                if (cominitdet_r == 1'b1) //device cominit detected                             
180
                                begin
181
                                        NextState = host_comwake;
182
                                end
183
                                else
184
                                begin
185
                                        `ifdef SIM
186
                                        if(count == 18'h001ff)
187
                                        `else
188
                                        if(count == 18'h203AD) //restart comreset after no cominit for at least 880us
189
                                        `endif
190
                                        begin
191
                                                count_en = 1'b0;
192
                                                NextState = host_comreset;
193
                                        end
194
                                        else
195
                                        begin
196
                                                count_en = 1'b1;
197
                                                NextState = wait_dev_cominit;
198
                                        end
199
                                end
200
                        end
201
 
202
                host_comwake : //2
203
                        begin
204
                                if ((~gen2 && count == 18'h0004E) || (gen2 && count == 18'h0009B))
205
                                begin
206
                                        txcomwake_r =1'b0;
207
                                        NextState = wait_dev_comwake;
208
                                end
209
                                else
210
                                begin
211
                                        txcomwake_r =1'b1;
212
                                        count_en = 1'b1;
213
                                        NextState = host_comwake;
214
                                end
215
 
216
                        end
217
 
218
                wait_dev_comwake : //3 
219
                        begin
220
                                if (comwakedet_r == 1'b1) //device comwake detected                             
221
                                begin
222
                                        NextState = wait_after_comwake;
223
                                end
224
                                else
225
                                begin
226
                                        if(count == 18'h203AD) //restart comreset after no cominit for 880us
227
                                        begin
228
                                                count_en = 1'b0;
229
                                                NextState = host_comreset;
230
                                        end
231
                                        else
232
                                        begin
233
                                                count_en = 1'b1;
234
                                                NextState = wait_dev_comwake;
235
                                        end
236
                                end
237
                        end
238
 
239
 
240
                wait_after_comwake : // 4
241
                        begin
242
                                if (count == 6'h3F)
243
                                begin
244
                                        NextState = wait_after_comwake1;
245
                                end
246
                                else
247
                                begin
248
                                        count_en = 1'b1;
249
 
250
                                        NextState = wait_after_comwake;
251
                                end
252
                        end
253
 
254
 
255
                wait_after_comwake1 : //5
256
                        begin
257
                                if (rxelecidle_r == 1'b0)
258
                                begin
259
                                        rxreset = 1'b1;
260
                                        NextState = host_d10_2;
261
                                end
262
                                else
263
                                        NextState = wait_after_comwake1;
264
                        end
265
 
266
                host_d10_2 : //6
267
                begin
268
                        txelecidle_next = 1'b0;
269
 
270
                        // D10.2-D10.2 "dial tone"
271
                        rx_dataout_i  = rx_datain_r;
272
                        prim_type_next = DIAL;
273
                        tx_charisk_next = 1'b0;
274
 
275
                        if (align_det)
276
                        begin
277
                                NextState = host_send_align;
278
                        end
279
                        else
280
                        begin
281
                                if(count == 18'h203AD) // restart comreset after 880us
282
                                begin
283
                                        count_en = 1'b0;
284
                                        NextState = host_comreset;
285
                                end
286
                                else
287
                                begin
288
                                        count_en = 1'b1;
289
                                        NextState = host_d10_2;
290
                                end
291
                        end
292
                end
293
 
294
                host_send_align : //7
295
                begin
296
                        rx_dataout_i  = rx_datain_r;
297
 
298
                        // Send Align primitives. Align is 
299
                        // K28.5, D10.2, D10.2, D27.3
300
                        prim_type_next = ALIGN;
301
                        tx_charisk_next = 1'b1;
302
 
303
                        if (sync_det) // SYNC detected
304
                        begin
305
                                linkup_r_next = 1'b1;
306
                                NextState = link_ready;
307
                        end
308
                        else
309
                                NextState = host_send_align;
310
                end
311
 
312
 
313
                link_ready : // 8
314
                begin
315
                        if (rxelecidle_r == 1'b1)
316
                        begin
317
                                NextState = link_ready;
318
                                linkup_r_next = 1'b0;
319
                        end
320
                        else
321
                        begin
322
                                NextState = link_ready;
323
                                linkup_r_next = 1'b1;
324
                                rx_charisk_r = rx_charisk_in_r;
325
                                rx_dataout_i = rx_datain_r;
326
                                // Send LINK_LAYER DATA
327
                                prim_type_next = LINK_LAYER;
328
                                if (align_en)
329
                                   tx_charisk_next = 1'b1;
330
                                else
331
                                   tx_charisk_next = tx_charisk_in;
332
                        end
333
                end
334
 
335
 
336
                default : NextState = host_comreset;
337
        endcase
338
end
339
 
340
 
341
// OOB FSM Synchronous Process
342
 
343
always@(posedge clk or posedge reset)
344
begin : Seq_FSM
345
        if (reset)
346
        begin
347
                CurrentState       <= host_comreset;
348
                prim_type          <= ALIGN;
349
                tx_charisk         <= 1'b0;
350
                txelecidle         <= 1'b1;
351
                linkup_r           <= 1'b0;
352
                align_en_r         <= 1'b0;
353
                rxelecidle_r       <= 1'b0;
354
                rx_datain_r        <= 32'b0;
355
                rx_charisk_in_r    <= 4'b0;
356
                rxbyteisaligned_r  <= 1'b0;
357
                cominitdet_r       <= 1'b0;
358
                comwakedet_r       <= 1'b0;
359
        end
360
        else
361
        begin
362
                CurrentState      <= NextState;
363
                prim_type         <= prim_type_next;
364
                tx_charisk        <= tx_charisk_next;
365
                txelecidle        <= txelecidle_next;
366
                linkup_r          <= linkup_r_next;
367
                align_en_r        <= align_en;
368
                rxelecidle_r      <= rxelecidle;
369
                rx_datain_r       <= rx_datain;
370
                rx_charisk_in_r   <= rx_charisk_in;
371
                rxbyteisaligned_r <= rxbyteisaligned;
372
                cominitdet_r      <= cominitdet;
373
                comwakedet_r      <= comwakedet;
374
        end
375
end
376
 
377
 
378
always@(posedge clk or posedge reset)
379
begin : freecount
380
        if (reset)
381
        begin
382
                count <= 18'b0;
383
        end
384
        else if (count_en)
385
        begin
386
                count <= count + 1;
387
        end
388
        else
389
        begin
390
                count <= 18'b0;
391
 
392
        end
393
end
394
 
395
 
396
 
397
assign txcominit = txcominit_r;
398
assign txcomwake = txcomwake_r;
399
assign txelecidle_out = txelecidle;
400
//Primitive detection
401
// Changed for 32-bit GTX
402
assign align_det = (rx_datain_r == 32'h7B4A4ABC) && (rxbyteisaligned_r == 1'b1); //prevent invalid align at wrong speed
403
assign sync_det  = (rx_datain_r == 32'hB5B5957C);
404
assign cont_det  = (rx_datain_r == 32'h9999AA7C);
405
assign sof_det   = (rx_datain_r == 32'h3737B57C);
406
assign eof_det   = (rx_datain_r == 32'hD5D5B57C);
407
assign x_rdy_det = (rx_datain_r == 32'h5757B57C);
408
assign r_err_det = (rx_datain_r == 32'h5656B57C);
409
assign r_ok_det  = (rx_datain_r == 32'h3535B57C);
410
 
411
assign linkup = linkup_r;
412
assign linkup_led_out = ((CurrentState == link_ready) && (rxelecidle_r == 1'b0)) ? 1'b1 : 1'b0;
413
assign CurrentState_out = CurrentState;
414
assign rx_charisk_out = rx_charisk_r;
415
assign tx_charisk_out = tx_charisk;
416
assign rx_dataout  = rx_dataout_i;
417
 
418
// SATA Primitives 
419
 
420
// ALIGN
421
assign tx_align  = 32'h7B4A4ABC;
422
 
423
// SYNC
424
assign tx_sync   = 32'hB5B5957C;
425
 
426
// Dial Tone
427
assign tx_dial   = 32'h4A4A4A4A;
428
 
429
// R_RDY
430
assign tx_r_rdy  = 32'h4A4A957C;
431
 
432
// Mux to switch between ALIGN and other primitives/data
433
mux_21 i_align_count
434
  (
435
   .a   (prim_type),
436
   .b   (ALIGN),
437
   .sel (align_en_r),
438
   .o   (align_count_mux_out)
439
  );
440
 // Output to Link Layer to Pause writing data frame
441
 assign align_en_out = align_en;
442
 
443
//ALIGN Primitives transmitted every 256 DWORDS for speed alignment
444
always@(posedge clk or posedge reset)
445
begin : align_cnt
446
        if (reset)
447
        begin
448
           align_count <= 9'b0;
449
        end
450
        else if (align_count < 9'h0FF) //255
451
        begin
452
           if (align_count == 9'h001) //de-assert after 2 ALIGN primitives
453
           begin
454
                align_en <= 1'b0;
455
           end
456
           align_count <= align_count + 1;
457
        end
458
        else
459
        begin
460
           align_count <= 9'b0;
461
           align_en <= 1'b1;
462
        end
463
end
464
 
465
 
466
//OUTPUT MUX
467
mux_41 i_tx_out
468
  (
469
    .a    (tx_align),
470
    .b    (tx_sync),
471
    .c    (tx_dial),
472
    //.d    (tx_r_rdy),
473
    .d    (tx_datain),
474
    .sel  (align_count_mux_out),
475
    .o    (tx_dataout_i)
476
  );
477
 
478
assign tx_dataout = tx_dataout_i;
479
 
480
 
481
// OOB ILA
482
wire [15:0] trig0;
483
wire [15:0] trig1;
484
wire [15:0] trig2;
485
wire [15:0] trig3;
486
wire [31:0] trig4;
487
wire [3:0]  trig5;
488
wire [31:0] trig6;
489
wire [31:0] trig7;
490
wire [35:0] control;
491
 
492
if (CHIPSCOPE == "TRUE") begin
493
 oob_control_ila  i_oob_control_ila
494
    (
495
      .control(oob_control_ila_control),
496
      .clk(clk),
497
      .trig0(trig0),
498
      .trig1(trig1),
499
      .trig2(trig2),
500
      .trig3(trig3),
501
      .trig4(trig4),
502
      .trig5(trig5),
503
      .trig6(trig6),
504
      .trig7(trig7)
505
    );
506
end
507
 
508
assign trig0[0] = txcomwake_r;
509
assign trig0[1] = tx_charisk;
510
assign trig0[2] = rxbyteisaligned_r;
511
assign trig0[3] = count_en;
512
assign trig0[4] = tx_charisk_in;
513
assign trig0[5] = txelecidle;
514
assign trig0[6] = rx_locked;
515
assign trig0[7] = gen2;
516
assign trig0[11:8] = rx_charisk_in_r;
517
assign trig0[15:12] = 4'b0;
518
assign trig1[15:12] =  prim_type;
519
assign trig1[11:10] = 2'b0;
520
assign trig1[9] = align_en_r;
521
assign trig1[8]  = rxelecidle_r;
522
assign trig1[7:0] = CurrentState_out;
523
assign trig2[15:7] = align_count;
524
assign trig2[6:5] = 2'b0;
525
assign trig2[4] = cominitdet_r;
526
assign trig2[3] = comwakedet_r;
527
assign trig2[2] = align_det;
528
assign trig2[1] = sync_det;
529
assign trig2[0] = cont_det;
530
assign trig3[0] = sof_det;
531
assign trig3[1] = eof_det;
532
assign trig3[2] = x_rdy_det;
533
assign trig3[3] = r_err_det;
534
assign trig3[4] = r_ok_det;
535
assign trig3[15:5] =  11'b0;
536
assign trig4 =  rx_datain_r;
537
assign trig5[0] = txcominit_r;
538
assign trig5[1] = linkup_r;
539
assign trig5[2] = align_en;
540
assign trig5[3] = 1'b0;
541
assign trig6 =  tx_datain;
542
assign trig7  = tx_dataout_i;
543
 
544
endmodule
545
 
546
module oob_control_ila
547
  (
548
    control,
549
    clk,
550
    trig0,
551
    trig1,
552
    trig2,
553
    trig3,
554
    trig4,
555
    trig5,
556
    trig6,
557
    trig7
558
  );
559
  input [35:0] control;
560
  input clk;
561
  input [15:0] trig0;
562
  input [15:0] trig1;
563
  input [15:0] trig2;
564
  input [15:0] trig3;
565
  input [31:0] trig4;
566
  input [3:0]  trig5;
567
  input [31:0] trig6;
568
  input [31:0] trig7;
569
 
570
endmodule

powered by: WebSVN 2.1.0

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