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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [rtl/] [transport/] [sata_transport_layer.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cospan
//sata_transport_layer.v
2
/*
3
Distributed under the MIT license.
4
Copyright (c) 2011 Dave McCoy (dave.mccoy@cospandesign.com)
5
 
6
Permission is hereby granted, free of charge, to any person obtaining a copy of
7
this software and associated documentation files (the "Software"), to deal in
8
the Software without restriction, including without limitation the rights to
9
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
of the Software, and to permit persons to whom the Software is furnished to do
11
so, subject to the following conditions:
12
 
13
The above copyright notice and this permission notice shall be included in all
14
copies or substantial portions of the Software.
15
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
SOFTWARE.
23
*/
24
 
25
`include "sata_defines.v"
26
 
27
module sata_transport_layer (
28
  input               rst,            //reset
29
  input               clk,
30
  input               phy_ready,
31
 
32
 
33
//Transport Layer Control/Status
34
  output              transport_layer_ready,
35
  input               sync_escape,
36
 
37
  output  reg         d2h_reg_stb,
38
  output  reg         dma_activate_stb,
39
  output  reg         d2h_data_stb,
40
  output  reg         dma_setup_stb,
41
  output  reg         pio_setup_stb,
42
  output  reg         set_device_bits_stb,
43
 
44
  output  reg         remote_abort,
45
  output              xmit_error,
46
  output              read_crc_error,
47
 
48
  input               send_command_stb,
49
  input               send_control_stb,
50
  input               send_data_stb,
51
 
52
//PIO
53
  output reg          pio_response,
54
  output reg          pio_direction,
55
  output reg  [15:0]  pio_transfer_count,
56
  output reg  [7:0]   pio_e_status,
57
 
58
 
59
//Host to Device Registers
60
  input       [7:0]   h2d_command,
61
  input       [15:0]  h2d_features,
62
  input       [7:0]   h2d_control,
63
  input       [3:0]   h2d_port_mult,
64
  input       [7:0]   h2d_device,
65
  input       [47:0]  h2d_lba,
66
  input       [15:0]  h2d_sector_count,
67
 
68
//Device to Host Registers
69
  output  reg         d2h_interrupt,
70
  output  reg         d2h_notification,
71
  output  reg [3:0]   d2h_port_mult,
72
  output  reg [7:0]   d2h_device,
73
  output  reg [47:0]  d2h_lba,
74
  output  reg [15:0]  d2h_sector_count,
75
  output  reg [7:0]   d2h_status,
76
  output  reg [7:0]   d2h_error,
77
 
78
//DMA Specific Control
79
 
80
//Data Control
81
  input               cl_if_ready,
82
  output reg          cl_if_activate,
83
  input       [23:0]  cl_if_size,
84
 
85
  output              cl_if_strobe,
86
  input       [31:0]  cl_if_data,
87
 
88
  input       [1:0]   cl_of_ready,
89
  output  reg [1:0]   cl_of_activate,
90
  output              cl_of_strobe,
91
  output      [31:0]  cl_of_data,
92
  input       [23:0]  cl_of_size,
93
 
94
 
95
//Link Layer Interface
96
  input               link_layer_ready,
97
  output              ll_sync_escape,
98
 
99
  output              ll_write_start,
100
  input               ll_write_strobe,
101
  input               ll_write_finished,
102
  output      [31:0]  ll_write_data,
103
  output      [31:0]  ll_write_size,
104
  output              ll_write_hold,
105
  output              ll_write_abort,
106
  input               ll_xmit_error,
107
 
108
  input               ll_read_start,
109
  output              ll_read_ready,
110
  input       [31:0]  ll_read_data,
111
  input               ll_read_strobe,
112
  input               ll_read_finished,
113
  input               ll_read_crc_ok,
114
  input               ll_remote_abort,
115
 
116
  output      [3:0]   lax_state
117
);
118
 
119
 
120
//Parameters
121
parameter           IDLE                  = 4'h0;
122
parameter           READ_FIS              = 4'h1;
123
parameter           WAIT_FOR_END          = 4'h2;
124
 
125
 
126
parameter           CHECK_FIS_TYPE        = 4'h1;
127
parameter           WRITE_H2D_REG         = 4'h2;
128
parameter           RETRY                 = 4'h3;
129
parameter           READ_D2H_REG          = 4'h4;
130
parameter           READ_PIO_SETUP        = 4'h5;
131
parameter           READ_SET_DEVICE_BITS  = 4'h6;
132
parameter           DMA_ACTIVATE          = 4'h7;
133
parameter           SEND_DATA             = 4'h8;
134
parameter           READ_DATA             = 4'h9;
135
 
136
 
137
//Registers/Wires
138
reg         [3:0]   fis_id_state;
139
reg         [3:0]   state;
140
reg                 detect_fis;
141
reg         [7:0]   current_fis;
142
wire                processing_fis;
143
 
144
//data direction
145
wire                data_direction;
146
 
147
//Detect FIS from the device
148
wire                detect_d2h_reg;
149
wire                detect_dma_activate;
150
wire                detect_dma_setup;
151
wire                detect_d2h_data;
152
wire                detect_pio_setup;
153
wire                detect_set_device_bits;
154
 
155
//control data signals
156
wire        [31:0]  register_fis          [5:0];
157
reg         [7:0]   register_fis_ptr;
158
reg                 cmd_bit;
159
 
160
reg                 reg_write_start;
161
wire        [31:0]  reg_write_data;
162
wire        [31:0]  reg_write_size;
163
reg                 reg_write_ready;
164
wire                reg_write_hold;
165
wire                reg_write_abort;
166
wire                reg_write_strobe;
167
 
168
//read register
169
wire                reg_read;
170
wire                reg_write;
171
reg         [7:0]   reg_read_count;
172
wire                reg_read_stb;
173
 
174
 
175
 
176
//data state machine signals
177
reg                 data_write_start;
178
wire                data_write_strobe;
179
wire                data_read_strobe;
180
wire        [31:0]  data_write_size;
181
wire        [31:0]  data_write_data;
182
wire                data_write_hold;
183
wire                data_write_abort;
184
 
185
reg                 data_read_ready;
186
reg                 send_data_fis_id;
187
 
188
 
189
 
190
//Asnchronous Logic
191
assign  lax_state               = state;
192
assign  transport_layer_ready   = (state == IDLE) && link_layer_ready;
193
assign  ll_sync_escape          = sync_escape;
194
assign  xmit_error              = ll_xmit_error;
195
 
196
//Attach Control/Data Signals to link layer depending on the conditions
197
 
198
//Write Control
199
assign  ll_write_start          = (reg_write)   ? reg_write_start                : data_write_start;
200
assign  ll_write_data           = (reg_write)   ? register_fis[register_fis_ptr] : data_write_data;
201
assign  ll_write_size           = (reg_write)   ? reg_write_size                 : data_write_size;
202
assign  ll_write_hold           = (reg_write)   ? 0                              : data_write_hold;
203
assign  ll_write_abort          = (reg_write)   ? 0                              : data_write_abort;
204
assign  cl_if_strobe            = (reg_write)   ? 0                              : (!send_data_fis_id && data_write_strobe);
205
 
206
//Read Control
207
assign  ll_read_ready           = (reg_read)    ? 1                              : data_read_ready;
208
assign  cl_of_strobe            = (reg_read)    ? 0                              : ((state == READ_DATA) && data_read_strobe);
209
assign  cl_of_data              = ll_read_data;
210
 
211
//Data Register Write Control Signals
212
assign  data_write_data         = (send_data_fis_id)     ? `FIS_DATA                : cl_if_data;
213
                                                      //the first DWORD is the FIS ID
214
assign  data_write_size         = (cl_if_size + 1);
215
//assign  data_write_size         = cl_if_size;
216
                                                      //Add 1 to the size so that there is room for the FIS ID
217
assign  data_write_strobe       = ll_write_strobe;
218
assign  data_read_strobe        = ll_read_strobe;
219
assign  data_write_hold         = 0;
220
                                                   //There should never be a hold on the data becuase the CL will set it up
221
assign  data_write_abort        = 0;
222
assign  read_crc_error          = !ll_read_crc_ok;
223
 
224
 
225
//H2D Register Write control signals
226
assign  reg_write_strobe        = ll_write_strobe;
227
assign  reg_write_size          = `FIS_H2D_REG_SIZE;
228
assign  reg_write_hold          = 0;
229
assign  reg_write_abort         = 0;
230
assign  reg_write               = (state == WRITE_H2D_REG)        || (send_command_stb || send_control_stb);
231
 
232
//D2H Register Read control signals
233
assign  reg_read                = (state == READ_D2H_REG)         ||  detect_d2h_reg          ||
234
                                  (state == READ_PIO_SETUP)       ||  detect_pio_setup        ||
235
                                  (state == READ_SET_DEVICE_BITS) ||  detect_set_device_bits;
236
 
237
assign  reg_read_stb            = ll_read_strobe;
238
 
239
//Data Read control signals
240
 
241
//Detect Signals
242
assign  processing_fis          = (state == READ_FIS);
243
 
244
assign  detect_d2h_reg          = detect_fis ? (ll_read_data[7:0] == `FIS_D2H_REG)       : (current_fis == `FIS_D2H_REG      );
245
assign  detect_dma_activate     = detect_fis ? (ll_read_data[7:0] == `FIS_DMA_ACT)       : (current_fis == `FIS_DMA_ACT      );
246
assign  detect_d2h_data         = detect_fis ? (ll_read_data[7:0] == `FIS_DATA)          : (current_fis == `FIS_DATA         );
247
assign  detect_dma_setup        = detect_fis ? (ll_read_data[7:0] == `FIS_DMA_SETUP)     : (current_fis == `FIS_DMA_SETUP    );
248
assign  detect_pio_setup        = detect_fis ? (ll_read_data[7:0] == `FIS_PIO_SETUP)     : (current_fis == `FIS_PIO_SETUP    );
249
assign  detect_set_device_bits  = detect_fis ? (ll_read_data[7:0] == `FIS_SET_DEV_BITS)  : (current_fis == `FIS_SET_DEV_BITS );
250
 
251
assign  register_fis[0]         = {h2d_features[7:0], h2d_command, cmd_bit, 3'b000, h2d_port_mult, `FIS_H2D_REG};
252
assign  register_fis[1]         = {h2d_device, h2d_lba[23:0]};
253
assign  register_fis[2]         = {h2d_features[15:8], h2d_lba[47:24]};
254
assign  register_fis[3]         = {h2d_control, 8'h00, h2d_sector_count};
255
assign  register_fis[4]         = {32'h00000000};
256
 
257
//Synchronous Logic
258
//FIS ID State machine
259
always @ (posedge clk) begin
260
  if (rst) begin
261
    fis_id_state            <=  IDLE;
262
    detect_fis              <=  0;
263
    current_fis             <=  0;
264
  end
265
  else begin
266
    //in order to set all the detect_* high when the actual fis is detected send this strobe
267
    if(ll_read_finished) begin
268
      current_fis           <=  0;
269
      fis_id_state          <=  IDLE;
270
    end
271
    else begin
272
      case (fis_id_state)
273
        IDLE: begin
274
          current_fis         <=  0;
275
          detect_fis          <=  0;
276
          if (ll_read_start) begin
277
            detect_fis        <=  1;
278
            fis_id_state      <=  READ_FIS;
279
          end
280
        end
281
        READ_FIS: begin
282
          if (ll_read_strobe) begin
283
            detect_fis        <=  0;
284
            current_fis         <=  ll_read_data[7:0];
285
            fis_id_state        <=  WAIT_FOR_END;
286
          end
287
        end
288
        WAIT_FOR_END: begin
289
          if (ll_read_finished) begin
290
            current_fis       <=  0;
291
            fis_id_state      <=  IDLE;
292
          end
293
        end
294
        default: begin
295
          fis_id_state        <=  IDLE;
296
        end
297
      endcase
298
    end
299
  end
300
end
301
 
302
 
303
//main DATA state machine
304
always @ (posedge clk) begin
305
  if (rst) begin
306
    state                       <=  IDLE;
307
    cl_of_activate              <=  0;
308
    cl_if_activate              <=  0;
309
    data_read_ready             <=  0;
310
 
311
    //Data Send
312
 
313
    send_data_fis_id            <=  0;
314
 
315
    //H2D Register
316
    register_fis_ptr            <=  0;
317
    reg_write_start             <=  0;
318
 
319
    //D2H Register
320
    reg_read_count              <=  0;
321
 
322
    //Device Status
323
    d2h_interrupt               <=  0;
324
    d2h_notification            <=  0;
325
    d2h_port_mult               <=  0;
326
    d2h_lba                     <=  0;
327
    d2h_sector_count            <=  0;
328
    d2h_status                  <=  0;
329
    d2h_error                   <=  0;
330
 
331
    d2h_reg_stb                 <=  0;
332
    d2h_data_stb                <=  0;
333
    pio_setup_stb               <=  0;
334
    set_device_bits_stb         <=  0;
335
    dma_activate_stb            <=  0;
336
    dma_setup_stb               <=  0;
337
 
338
    remote_abort                <=  0;
339
 
340
    cmd_bit                     <=  0;
341
 
342
    //PIO
343
    pio_transfer_count          <=  0;
344
    pio_e_status                <=  0;
345
    pio_direction               <=  0;
346
    pio_response                <=  0;
347
 
348
    data_write_start            <=  0;
349
 
350
  end
351
  else begin
352
    //Strobed signals
353
    if (phy_ready) begin
354
      //only deassert a link layer strobe when Phy is ready
355
      data_write_start          <=  0;
356
      reg_write_start           <=  0;
357
    end
358
 
359
    d2h_reg_stb                 <=  0;
360
    d2h_data_stb                <=  0;
361
    pio_setup_stb               <=  0;
362
    set_device_bits_stb         <=  0;
363
    dma_activate_stb            <=  0;
364
    dma_setup_stb               <=  0;
365
 
366
    remote_abort                <=  0;
367
 
368
 
369
 
370
    d2h_device                  <=  0;
371
    //Always attempt to get a free buffer
372
    if ((cl_of_activate == 0) && (cl_of_ready > 0)) begin
373
      if (cl_of_ready[0]) begin
374
        cl_of_activate[0]       <= 1;
375
      end
376
      else begin
377
        cl_of_activate[1]       <= 1;
378
      end
379
      data_read_ready           <= 1;
380
    end
381
    else if (cl_of_activate == 0) begin
382
//XXX: NO BUFFER AVAILABLE!!!! Can't accept new data from the Hard Drive
383
      data_read_ready           <= 0;
384
    end
385
 
386
    //Always attempt to get the incomming buffer
387
    if (cl_if_ready && !cl_if_activate) begin
388
      cl_if_activate            <=  1;
389
    end
390
 
391
    case (state)
392
      IDLE: begin
393
        register_fis_ptr        <=  0;
394
        reg_read_count          <=  0;
395
        cmd_bit                 <=  0;
396
        //Detect a FIS
397
        if(ll_read_start) begin
398
          //detect the start of a frame
399
          state                 <=  CHECK_FIS_TYPE;
400
//Clear Errors when a new transaction starts
401
        end
402
        //Send Register
403
        if (send_command_stb || send_control_stb) begin
404
//Clear Errors when a new transaction starts
405
 
406
          if (send_command_stb) begin
407
            cmd_bit               <=  1;
408
          end
409
          else if (send_control_stb) begin
410
            cmd_bit               <=  0;
411
          end
412
 
413
          reg_write_start       <=  1;
414
          state                 <=  WRITE_H2D_REG;
415
        end
416
        //Send Data
417
        else if (send_data_stb) begin
418
//Clear Errors when a new transaction starts
419
          data_write_start      <=  1;
420
          send_data_fis_id      <=  1;
421
          state                 <=  SEND_DATA;
422
        end
423
      end
424
      CHECK_FIS_TYPE: begin
425
        if (detect_dma_setup) begin
426
//XXX: Future work!
427
          reg_read_count        <=  reg_read_count + 1;
428
          state                 <=  IDLE;
429
        end
430
        else if (detect_dma_activate) begin
431
          //hard drive is ready to receive data
432
          state                 <=  DMA_ACTIVATE;
433
          reg_read_count        <=  reg_read_count + 1;
434
          //state                 <=  IDLE;
435
        end
436
        else if (detect_d2h_data) begin
437
          //incomming data, because the out FIFO is directly connected to the output during a read
438
          state                 <=  READ_DATA;
439
        end
440
        else if (detect_d2h_reg) begin
441
          //store the error, status interrupt from this read
442
          d2h_status            <=  ll_read_data[23:16];
443
          d2h_error             <=  ll_read_data[31:24];
444
          d2h_interrupt         <=  ll_read_data[14];
445
          d2h_port_mult         <=  ll_read_data[11:8];
446
 
447
          state                 <=  READ_D2H_REG;
448
          reg_read_count        <=  reg_read_count + 1;
449
        end
450
        else if (detect_pio_setup) begin
451
          //store the error, status, direction interrupt from this read
452
          pio_response          <=  1;
453
 
454
          d2h_status            <=  ll_read_data[23:16];
455
          d2h_error             <=  ll_read_data[31:24];
456
          d2h_interrupt         <=  ll_read_data[14];
457
          pio_direction         <=  ll_read_data[13];
458
          d2h_port_mult         <=  ll_read_data[11:8];
459
 
460
          state                 <=  READ_PIO_SETUP;
461
          reg_read_count        <=  reg_read_count + 1;
462
        end
463
        else if (detect_set_device_bits) begin
464
          //store the error, a subset of the status bit and the interrupt
465
          state                 <=  IDLE;
466
          d2h_status[6:4]       <=  ll_read_data[22:20];
467
          d2h_status[2:0]       <=  ll_read_data[18:16];
468
          d2h_error             <=  ll_read_data[31:24];
469
          d2h_notification      <=  ll_read_data[15];
470
          d2h_interrupt         <=  ll_read_data[14];
471
          d2h_port_mult         <=  ll_read_data[11:8];
472
 
473
          state                 <=  READ_SET_DEVICE_BITS;
474
        end
475
        else if (ll_read_finished) begin
476
          //unrecognized FIS
477
          state                 <=  IDLE;
478
        end
479
      end
480
      WRITE_H2D_REG: begin
481
        if  (register_fis_ptr < `FIS_H2D_REG_SIZE) begin
482
          if (reg_write_strobe) begin
483
            register_fis_ptr    <=  register_fis_ptr + 1;
484
          end
485
        end
486
        if (ll_write_finished) begin
487
          if (ll_xmit_error) begin
488
            state               <=  RETRY;
489
          end
490
          else begin
491
            state               <=  IDLE;
492
          end
493
        end
494
      end
495
      RETRY: begin
496
        if (link_layer_ready) begin
497
          reg_write_start       <=  1;
498
          register_fis_ptr      <=  0;
499
          state                 <=  WRITE_H2D_REG;
500
        end
501
      end
502
      READ_D2H_REG: begin
503
        case (reg_read_count)
504
          1: begin
505
            d2h_device          <=  ll_read_data[31:24];
506
            d2h_lba[23:0]       <=  ll_read_data[23:0];
507
          end
508
          2: begin
509
            d2h_lba[47:24]      <=  ll_read_data[23:0];
510
          end
511
          3: begin
512
            d2h_sector_count    <=  ll_read_data[15:0];
513
          end
514
          4: begin
515
          end
516
          default: begin
517
          end
518
        endcase
519
        if (reg_read_stb) begin
520
          reg_read_count        <=  reg_read_count + 1;
521
        end
522
        if (ll_read_finished) begin
523
          d2h_reg_stb           <=  1;
524
          state                 <=  IDLE;
525
        end
526
      end
527
      READ_PIO_SETUP: begin
528
        case (reg_read_count)
529
          1: begin
530
            d2h_device          <=  ll_read_data[31:24];
531
            d2h_lba[23:0]       <=  ll_read_data[23:0];
532
          end
533
          2: begin
534
            d2h_lba[47:24]      <=  ll_read_data[23:0];
535
          end
536
          3: begin
537
            d2h_sector_count    <=  ll_read_data[15:0];
538
            pio_e_status        <=  ll_read_data[31:24];
539
          end
540
          4: begin
541
            pio_transfer_count  <=  ll_read_data[15:0];
542
          end
543
          default: begin
544
          end
545
        endcase
546
        if (reg_read_stb) begin
547
          reg_read_count        <=  reg_read_count + 1;
548
        end
549
        if (ll_read_finished) begin
550
          pio_setup_stb         <=  1;
551
          state                 <=  IDLE;
552
        end
553
      end
554
      READ_SET_DEVICE_BITS: begin
555
        state                 <=  IDLE;
556
        set_device_bits_stb   <=  1;
557
      end
558
      DMA_ACTIVATE: begin
559
        state                 <=  IDLE;
560
        dma_activate_stb      <=  1;
561
      end
562
      SEND_DATA: begin
563
        if (ll_write_strobe && send_data_fis_id) begin
564
          send_data_fis_id      <=  0;
565
        end
566
        if (ll_write_finished) begin
567
          cl_if_activate        <=  0;
568
          state                 <=  IDLE;
569
          if (pio_response) begin
570
            //write the end status to the status pin
571
            d2h_status          <=  pio_e_status;
572
          end
573
        end
574
      end
575
      READ_DATA: begin
576
        //NOTE: the data_read_ready will automatically 'flow control' the data from the link layer
577
        //so we don't have to check it here
578
        //NOTE: We don't have to keep track of the count because the lower level will give a max of 2048 DWORDS
579
        if (ll_read_finished) begin
580
          //deactivate FIFO
581
          d2h_data_stb      <=  1;
582
          cl_of_activate    <=  0;
583
          state             <=  IDLE;
584
          if (pio_response) begin
585
            //write the end status to the status pin
586
            d2h_status        <=  pio_e_status;
587
          end
588
        end
589
      end
590
      default: begin
591
        state               <=  IDLE;
592
      end
593
    endcase
594
    if (sync_escape) begin
595
      state                 <=  IDLE;
596
    end
597
  end
598
end
599
 
600
 
601
endmodule
602
 
603
 

powered by: WebSVN 2.1.0

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