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

Subversion Repositories sata_phy

[/] [sata_phy/] [trunk/] [hdl/] [sata_phy_host_ctrl_x6series.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 beandigita
////////////////////////////////////////////////////////////
2
//
3
// This confidential and proprietary software may be used
4
// only as authorized by a licensing agreement from
5
// Bean Digital Ltd
6
// In the event of publication, the following notice is
7
// applicable:
8
//
9
// (C)COPYRIGHT 2012 BEAN DIGITAL LTD.
10
// ALL RIGHTS RESERVED
11
//
12
// The entire notice above must be reproduced on all
13
// authorized copies.
14
//
15
// File        : sata_phy_host_ctrl_x6series.v
16
// Author      : J.Bean
17
// Date        : Mar 2012
18
// Description : SATA PHY Layer Host Control Xilinx 6 Series
19
////////////////////////////////////////////////////////////
20
 
21
`resetall
22
`timescale 1ns/10ps
23
 
24
`include "sata_constants.v"
25
 
26
module sata_phy_host_ctrl_x6series
27
  #(parameter SATA_REV = 1)(              // SATA Revision (1, 2, 3)
28
  input  wire          clk_phy,           // Clock PHY
29
  input  wire          rst_n,               // Reset
30
  output reg           link_up_o,         // Link Up
31
  // Transceiver
32
  input  wire          gt_rst_done_i,     // GT Reset Done
33
  output reg  [31:0]   gt_tx_data_o,          // GT Transmit Data
34
  output reg  [3:0]    gt_tx_charisk_o,    // GT Transmit K/D
35
  output reg           gt_tx_com_strt_o,  // GT Transmit        COM Start
36
  output reg           gt_tx_com_type_o,         // GT Transmit COM Type
37
  output reg           gt_tx_elec_idle_o, // GT Transmit Electrical Idle
38
  input  wire [31:0]   gt_rx_data_i,      // GT Receive Data   
39
  input  wire [2:0]    gt_rx_status_i,      // GT Receive Status
40
  input  wire          gt_rx_elec_idle_i        // GT Receive Electrical Idle   
41
);
42
 
43
////////////////////////////////////////////////////////////
44
// Parameters
45
//////////////////////////////////////////////////////////// 
46
 
47
// Time delays
48
parameter SATA1_10MS            = 750000;   // 75MHz * 750000
49
parameter SATA2_10MS            = 1500000;  // 150MHz * 1500000
50
parameter SATA3_10MS            = 3000000;  // 300MHz * 3000000
51
parameter SATA1_873US           = 65535;    // 75MHz * 65535
52
parameter SATA2_873US           = 131070;   // 150MHz * 131070
53
parameter SATA3_873US           = 262140;   // 300MHz * 262140
54
 
55
// State machine states
56
parameter HP1_RESET             = 0;
57
parameter HP2_AWAIT_COMINIT     = 1;
58
parameter HP2B_AWAIT_NO_COMINIT = 2;
59
parameter HP3_CALIBRATE         = 3;
60
parameter HP4_COMWAKE           = 4;
61
parameter HP5_AWAIT_COMWAKE     = 5;
62
parameter HP5B_AWAIT_NO_COMWAKE = 6;
63
parameter HP6_AWAIT_ALIGN       = 7;
64
parameter HP7_SEND_ALIGN        = 8;
65
parameter HP8_READY             = 9;
66
 
67
////////////////////////////////////////////////////////////
68
// Signals
69
//////////////////////////////////////////////////////////// 
70
 
71
reg  [3:0]   state_cs;            // Current state
72
reg  [3:0]   state_ns;            // Next state  
73
reg  [199:0] state_ascii;         // ASCII state
74
wire         phy_ctrl_strt;       // PHY Control Start
75
reg      [31:0]   align_timeout_cnt;   // ALIGN Timeout Count
76
reg  [31:0]  retry_cnt;           // Retry Count 
77
wire         cominit_detect;      // COMINIT Detect
78
wire         comwake_detect;      // COMWAKE Detect
79
wire         align_detect;        // ALIGN Detected
80
wire         align_timeout;       // ALIGN Timeout
81
reg  [1:0]   non_align_cnt;       // Non ALIGN Count
82
reg          tx_com_strt;         // Transmit COM Start
83
wire         tx_com_strt_pedge;   // Transmit COM Start Positive Edge
84
reg          tx_com_done;         // Transmit COM Done
85
 
86
////////////////////////////////////////////////////////////
87
// Instance    : Transmit Com Start Pos Edge
88
// Description : Detect positive edge on com start signal.
89
////////////////////////////////////////////////////////////
90
 
91
det_pos_edge U_tx_com_strt_pedge(
92
  .clk   (clk_phy),
93
  .rst_n (rst_n),
94
  .d     (tx_com_strt),
95
  .q     (tx_com_strt_pedge));
96
 
97
////////////////////////////////////////////////////////////
98
// Comb Assign : PHY Control Start
99
// Description : Starts the control.
100
////////////////////////////////////////////////////////////
101
 
102
assign phy_ctrl_strt = gt_rst_done_i;
103
 
104
////////////////////////////////////////////////////////////
105
// Comb Assign : COMWAKE Detect
106
// Description : 
107
////////////////////////////////////////////////////////////
108
 
109
assign comwake_detect = gt_rx_status_i[1];
110
 
111
////////////////////////////////////////////////////////////
112
// Comb Assign : COMINIT Detect
113
// Description : 
114
////////////////////////////////////////////////////////////
115
 
116
assign cominit_detect = gt_rx_status_i[2];
117
 
118
////////////////////////////////////////////////////////////
119
// Comb Assign : ALIGN Timeout
120
// Description : 
121
////////////////////////////////////////////////////////////
122
 
123
assign align_timeout = (align_timeout_cnt == 0);
124
 
125
////////////////////////////////////////////////////////////
126
// Comb Assign : ALIGN primitive detect
127
// Description : 
128
////////////////////////////////////////////////////////////
129
 
130
assign align_detect = (gt_rx_data_i == 32'h7B4A4ABC);
131
 
132
////////////////////////////////////////////////////////////
133
// Seq Block   : State machine seq logic
134
// Description : Sets the current state to the next state.
135
////////////////////////////////////////////////////////////
136
 
137
always @(negedge rst_n or posedge clk_phy)
138
begin
139
  if (rst_n == 0) begin
140
    state_cs <= HP1_RESET;
141
  end else begin
142
    state_cs <= state_ns;
143
  end
144
end
145
 
146
////////////////////////////////////////////////////////////
147
// Comb Block  : State machine ascii 
148
// Description : Converts the state to ascii for debug.
149
////////////////////////////////////////////////////////////
150
 
151
always @(*)
152
begin
153
  case (state_cs)
154
    HP1_RESET:             state_ascii = "HP1_RESET";
155
    HP2_AWAIT_COMINIT:     state_ascii = "HP2_AWAIT_COMINIT";
156
    HP2B_AWAIT_NO_COMINIT: state_ascii = "HP2B_AWAIT_NO_COMINIT";
157
    HP3_CALIBRATE:         state_ascii = "HP3_CALIBRATE";
158
    HP4_COMWAKE:           state_ascii = "HP4_COMWAKE";
159
    HP5_AWAIT_COMWAKE:     state_ascii = "HP5_AWAIT_COMWAKE";
160
    HP5B_AWAIT_NO_COMWAKE: state_ascii = "HP5B_AWAIT_NO_COMWAKE";
161
    HP6_AWAIT_ALIGN:       state_ascii = "HP6_AWAIT_ALIGN";
162
    HP7_SEND_ALIGN:        state_ascii = "HP7_SEND_ALIGN";
163
    HP8_READY:             state_ascii = "HP8_READY";
164
  endcase
165
end
166
 
167
////////////////////////////////////////////////////////////
168
// Comb Block  : State machine comb logic
169
// Description : Assigns the next state.
170
////////////////////////////////////////////////////////////
171
 
172
always @(*)
173
begin
174
  state_ns = state_cs;
175
 
176
  case (state_cs)
177
    // HP1_RESET - Interface quiescent
178
    HP1_RESET: begin
179
      if ((phy_ctrl_strt == 1) && (tx_com_done == 1) && (cominit_detect == 0)) begin
180
        state_ns = HP2_AWAIT_COMINIT;
181
      end
182
    end
183
 
184
    // HP2_AWAIT_COMINIT - Wait for COMINIT to be detected
185
    HP2_AWAIT_COMINIT: begin
186
      if (cominit_detect == 1) begin
187
        state_ns = HP2B_AWAIT_NO_COMINIT;
188
      end else begin
189
        // Test if need to send COMRESET again
190
        if (retry_cnt == 0) begin
191
          state_ns = HP1_RESET;
192
        end
193
      end
194
    end
195
 
196
    // HP2B_AWAIT_NO_COMINIT - Wait for COMINIT to finish
197
    HP2B_AWAIT_NO_COMINIT: begin
198
      if (cominit_detect == 0) begin
199
        state_ns = HP3_CALIBRATE;
200
      end
201
    end
202
 
203
    // HP3_CALIBRATE
204
    HP3_CALIBRATE: begin
205
      state_ns = HP4_COMWAKE;
206
    end
207
 
208
    // HP4_COMWAKE - Send COMWAKE
209
    HP4_COMWAKE: begin
210
      if (tx_com_done == 1) begin
211
        state_ns = HP5_AWAIT_COMWAKE;
212
      end
213
    end
214
 
215
    // HP5_AWAIT_COMWAKE - Wait for COMWAKE to be detected
216
    HP5_AWAIT_COMWAKE: begin
217
      if (comwake_detect == 1) begin
218
        state_ns = HP5B_AWAIT_NO_COMWAKE;
219
      end else begin
220
        // Test if need to send COMRESET again
221
        if (retry_cnt == 0) begin
222
          state_ns = HP1_RESET;
223
        end
224
      end
225
    end
226
 
227
    // HP5B_AWAIT_NO_COMWAKE - Wait for COMWAKE to finish
228
    HP5B_AWAIT_NO_COMWAKE: begin
229
      if (comwake_detect == 0) begin
230
        state_ns = HP6_AWAIT_ALIGN;
231
      end
232
    end
233
 
234
    // HP6_AWAIT_ALIGN - Wait for ALIGN to be detected
235
    HP6_AWAIT_ALIGN: begin
236
      casez({align_detect, align_timeout})
237
        2'b10:   state_ns = HP7_SEND_ALIGN;
238
        2'b01:   state_ns = HP1_RESET;
239
        default: state_ns = HP6_AWAIT_ALIGN;
240
      endcase
241
    end
242
 
243
    // HP7_SEND_ALIGN - Send ALIGN
244
    HP7_SEND_ALIGN: begin
245
      if (non_align_cnt == 3) begin
246
        state_ns = HP8_READY;
247
      end
248
    end
249
 
250
    // HP8_READY - Link ready
251
    HP8_READY: begin
252
      if (gt_rx_elec_idle_i == 1) begin
253
        state_ns = HP1_RESET;
254
      end
255
    end
256
 
257
    default: begin
258
      state_ns = 'bx;
259
    end
260
  endcase
261
end
262
 
263
////////////////////////////////////////////////////////////
264
// Seq Block   : Link Up
265
// Description : Set when communication has been established
266
////////////////////////////////////////////////////////////
267
 
268
always @(negedge rst_n or posedge clk_phy)
269
begin
270
  if (rst_n == 0) begin
271
    link_up_o <= 0;
272
  end   else begin
273
    case (state_cs)
274
      // HP8_READY - Link ready
275
      HP8_READY: begin
276
        link_up_o <= 1;
277
      end
278
 
279
      default: begin
280
        link_up_o <= 0;
281
      end
282
    endcase
283
  end
284
end
285
 
286
////////////////////////////////////////////////////////////
287
// Seq Block   : GT Transmit COM Start
288
// Description : Transmits the selected COM signal.
289
////////////////////////////////////////////////////////////
290
 
291
always @(negedge rst_n or posedge clk_phy)
292
begin
293
  if (rst_n == 0) begin
294
    gt_tx_com_strt_o <= 0;
295
  end   else begin
296
    gt_tx_com_strt_o <= tx_com_strt_pedge;
297
  end
298
end
299
 
300
////////////////////////////////////////////////////////////
301
// Seq Block   : GT Transmit COM Type
302
// Description : 0 = COMRESET/COMINIT, 1 = COMWAKE
303
////////////////////////////////////////////////////////////
304
 
305
always @(negedge rst_n or posedge clk_phy)
306
begin
307
  if (rst_n == 0) begin
308
    gt_tx_com_type_o <= 0;
309
  end   else begin
310
    case (state_cs)
311
      // HP1_RESET - Interface quiescent
312
      HP1_RESET: begin
313
        if (phy_ctrl_strt == 1) begin
314
          gt_tx_com_type_o <= 0;
315
        end
316
      end
317
 
318
      // HP4_COMWAKE - Send COMWAKE
319
      HP4_COMWAKE: begin
320
        gt_tx_com_type_o <= 1;
321
      end
322
    endcase
323
  end
324
end
325
 
326
////////////////////////////////////////////////////////////
327
// Seq Block   : GT Transmit Electrical Idle
328
// Description : 
329
////////////////////////////////////////////////////////////
330
 
331
always @(negedge rst_n or posedge clk_phy)
332
begin
333
  if (rst_n == 0) begin
334
    gt_tx_elec_idle_o <= 0;
335
  end   else begin
336
    case (state_cs)
337
      // HP5B_AWAIT_NO_COMWAKE - Wait for COMWAKE to finish
338
      HP5B_AWAIT_NO_COMWAKE: begin
339
        if (comwake_detect == 0) begin
340
          gt_tx_elec_idle_o <= 0;
341
        end
342
      end
343
 
344
      // HP6_AWAIT_ALIGN - Wait for ALIGN to be detected
345
      HP6_AWAIT_ALIGN: begin
346
        gt_tx_elec_idle_o <= 0;
347
      end
348
 
349
      // HP7_SEND_ALIGN - Send ALIGN
350
      HP7_SEND_ALIGN: begin
351
        gt_tx_elec_idle_o <= 0;
352
      end
353
 
354
      // HP8_READY - Link ready
355
      HP8_READY: begin
356
        gt_tx_elec_idle_o <= 0;
357
      end
358
 
359
      default: begin
360
        gt_tx_elec_idle_o <= 1;
361
      end
362
    endcase
363
  end
364
end
365
 
366
////////////////////////////////////////////////////////////
367
// Seq Block   : GT Transmit Data
368
// Description : 
369
////////////////////////////////////////////////////////////
370
 
371
always @(negedge rst_n or posedge clk_phy)
372
begin
373
  if (rst_n == 0) begin
374
    gt_tx_data_o <= 0;
375
  end   else begin
376
    case (state_cs)
377
      // HP6_AWAIT_ALIGN - Wait for ALIGN to be detected
378
      HP6_AWAIT_ALIGN: begin
379
        gt_tx_data_o <= 32'h4A4A4A4A; // D10.2     
380
      end
381
 
382
      // HP7_SEND_ALIGN - Send ALIGN
383
      HP7_SEND_ALIGN: begin
384
        gt_tx_data_o <= `ALIGN_VAL;   // ALIGN; 
385
      end
386
 
387
      // HP8_READY - Link ready
388
      HP8_READY: begin
389
        gt_tx_data_o <= `SYNC_VAL;    // SYNC;  
390
      end
391
 
392
      default: begin
393
        gt_tx_data_o <= 0;
394
      end
395
    endcase
396
  end
397
end
398
 
399
////////////////////////////////////////////////////////////
400
// Seq Block   : GT Transmit K/D
401
// Description : 
402
////////////////////////////////////////////////////////////
403
 
404
always @(negedge rst_n or posedge clk_phy)
405
begin
406
  if (rst_n == 0) begin
407
    gt_tx_charisk_o <= 0;
408
  end   else begin
409
    case (state_cs)
410
      // HP6_AWAIT_ALIGN - Wait for ALIGN to be detected
411
      HP6_AWAIT_ALIGN: begin
412
        gt_tx_charisk_o <= 4'b0000; // D10.2     
413
      end
414
 
415
      // HP7_SEND_ALIGN - Send ALIGN
416
      HP7_SEND_ALIGN: begin
417
        gt_tx_charisk_o <= 4'b0001; // ALIGN; 
418
      end
419
 
420
      // HP8_READY - Link ready
421
      HP8_READY: begin
422
        gt_tx_charisk_o <= 4'b0001; // SYNC;  
423
      end
424
 
425
      default: begin
426
        gt_tx_charisk_o <= 0;
427
      end
428
    endcase
429
  end
430
end
431
 
432
////////////////////////////////////////////////////////////
433
// Seq Block   : Transmit COM Start
434
// Description : Starts transmission of a COM sequence.
435
////////////////////////////////////////////////////////////
436
 
437
always @(negedge rst_n or posedge clk_phy)
438
begin
439
  if (rst_n == 0) begin
440
    tx_com_strt <= 0;
441
  end   else begin
442
    case (state_cs)
443
      // HP1_RESET - Interface quiescent
444
      HP1_RESET: begin
445
        if (phy_ctrl_strt == 1) begin
446
          tx_com_strt <= 1;
447
        end     else begin
448
          tx_com_strt <= 0;
449
        end
450
      end
451
 
452
      // HP4_COMWAKE - Send COMWAKE
453
      HP4_COMWAKE: begin
454
        tx_com_strt <= 1;
455
      end
456
 
457
      default: begin
458
        tx_com_strt <= 0;
459
      end
460
    endcase
461
  end
462
end
463
 
464
////////////////////////////////////////////////////////////
465
// Seq Block   : Transmit COM Done
466
// Description : Detects when COM signal has been sent.
467
////////////////////////////////////////////////////////////
468
 
469
always @(negedge rst_n or posedge clk_phy)
470
begin
471
  if (rst_n == 0) begin
472
    tx_com_done <= 0;
473
  end   else begin
474
    case (state_cs)
475
      // HP1_RESET - Interface quiescent
476
      HP1_RESET: begin
477
        if ((phy_ctrl_strt == 1) && (tx_com_done == 1) && (cominit_detect == 0)) begin
478
          tx_com_done <= 0;
479
        end else begin
480
          if (gt_rx_status_i[0] == 1) begin
481
            tx_com_done <= 1;
482
          end
483
        end
484
      end
485
 
486
      // HP4_COMWAKE - Send COMWAKE
487
      HP4_COMWAKE: begin
488
        if (tx_com_done == 1) begin
489
          tx_com_done <= 0;
490
        end else begin
491
          if (gt_rx_status_i[0] == 1) begin
492
            tx_com_done <= 1;
493
          end
494
        end
495
      end
496
    endcase
497
  end
498
end
499
 
500
////////////////////////////////////////////////////////////
501
// Seq Block   : ALIGN Timeout Count
502
// Description : Used to send COMRESET if ALIGN primitives
503
//               are not detected within 873.8us.
504
////////////////////////////////////////////////////////////
505
 
506
always @(negedge rst_n or posedge clk_phy)
507
begin
508
  if (rst_n == 0) begin
509
                align_timeout_cnt <= 0;
510
        end     else begin
511
          case (state_cs)
512
      // HP1_RESET - Interface quiescent
513
      HP1_RESET: begin
514
        case (SATA_REV)
515
          1:       align_timeout_cnt <= SATA1_873US;
516
          2:       align_timeout_cnt <= SATA2_873US;
517
          3:       align_timeout_cnt <= SATA3_873US;
518
          default: align_timeout_cnt <= SATA1_873US;
519
        endcase
520
      end
521
 
522
      // HP6_AWAIT_ALIGN - Wait for ALIGN to be detected
523
      HP6_AWAIT_ALIGN: begin
524
        align_timeout_cnt <= align_timeout_cnt - 1;
525
      end
526
          endcase
527
        end
528
end
529
 
530
////////////////////////////////////////////////////////////
531
// Seq Block   : Retry Count
532
// Description : Used to for async signal recovery (10 ms)
533
////////////////////////////////////////////////////////////
534
 
535
always @(negedge rst_n or posedge clk_phy)
536
begin
537
  if (rst_n == 0) begin
538
                retry_cnt <= 0;
539
        end     else begin
540
          case (state_cs)
541
      // HP1_RESET - Interface quiescent
542
      HP1_RESET: begin
543
        case (SATA_REV)
544
          1:       retry_cnt <= SATA1_10MS;
545
          2:       retry_cnt <= SATA2_10MS;
546
          3:       retry_cnt <= SATA3_10MS;
547
          default: retry_cnt <= SATA1_10MS;
548
        endcase
549
      end
550
 
551
      // HP2_AWAIT_COMINIT - Wait for COMINIT to be detected
552
      HP2_AWAIT_COMINIT: begin
553
        retry_cnt <= retry_cnt - 1;
554
      end
555
 
556
      // HP2B_AWAIT_NO_COMINIT - Wait for COMINIT to finish
557
      HP2B_AWAIT_NO_COMINIT: begin
558
        case (SATA_REV)
559
          1:       retry_cnt <= SATA1_10MS;
560
          2:       retry_cnt <= SATA2_10MS;
561
          3:       retry_cnt <= SATA3_10MS;
562
          default: retry_cnt <= SATA1_10MS;
563
        endcase
564
      end
565
 
566
      // HP5_AWAIT_COMWAKE - Wait for COMWAKE to be detected
567
      HP5_AWAIT_COMWAKE: begin
568
        retry_cnt <= retry_cnt - 1;
569
      end
570
          endcase
571
        end
572
end
573
 
574
////////////////////////////////////////////////////////////
575
// Seq Block   : Non ALIGN Count
576
// Description : Counts 3 non ALIGN primitives. 
577
////////////////////////////////////////////////////////////
578
 
579
always @(negedge rst_n or posedge clk_phy)
580
begin
581
  if (rst_n == 0) begin
582
                non_align_cnt <= 0;
583
        end     else begin
584
          case (state_cs)
585
      // HP7_SEND_ALIGN - Send ALIGN
586
      HP7_SEND_ALIGN: begin
587
            // Look for K28.3
588
        if (gt_rx_data_i[7:0] == 8'hbc) begin
589
                        non_align_cnt <= non_align_cnt + 1;
590
        end else begin
591
                      non_align_cnt <= 0;
592
        end
593
      end
594
 
595
      default: begin
596
        non_align_cnt <= 0;
597
      end
598
          endcase
599
        end
600
end
601
 
602
endmodule

powered by: WebSVN 2.1.0

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