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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [rtl/] [command/] [sata_command_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_command_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
`define RESET_TIMEOUT 32'h00000002
28
 
29
module sata_command_layer (
30
 
31
  input               rst,            //reset
32
  input               linkup,
33
  input               clk,
34
  input               data_in_clk,
35
  input               data_in_clk_valid,
36
  input               data_out_clk,
37
  input               data_out_clk_valid,
38
 
39
//User Interface
40
  output              sata_init,
41
  output              command_layer_ready,
42
  output  reg         busy,
43
  input               send_sync_escape,
44
  input       [15:0]  user_features,
45
 
46
//XXX: New Stb
47
  input               write_data_en,
48
  input               single_rdwr,
49
  input               read_data_en,
50
  output              dev_error,
51
 
52
  input               send_user_command_stb,
53
  input               soft_reset_en,
54
 
55
  output  reg         pio_data_ready,
56
  input       [7:0]   command,
57
 
58
  input       [15:0]  sector_count,
59
  input       [47:0]  sector_address,
60
 
61
  input       [31:0]  user_din,
62
  input               user_din_stb,
63
  output      [1:0]   user_din_ready,
64
  input       [1:0]   user_din_activate,
65
  output      [23:0]  user_din_size,
66
 
67
  output      [31:0]  user_dout,
68
  output              user_dout_ready,
69
  input               user_dout_activate,
70
  input               user_dout_stb,
71
  output      [23:0]  user_dout_size,
72
 
73
 
74
 //Transfer Layer Interface
75
  input               transport_layer_ready,
76
  output  reg         sync_escape,
77
 
78
  output              t_send_command_stb,
79
  output  reg         t_send_control_stb,
80
  output              t_send_data_stb,
81
 
82
  input               t_dma_activate_stb,
83
  input               t_d2h_reg_stb,
84
  input               t_pio_setup_stb,
85
  input               t_d2h_data_stb,
86
  input               t_dma_setup_stb,
87
  input               t_set_device_bits_stb,
88
 
89
  input               t_remote_abort,
90
  input               t_xmit_error,
91
  input               t_read_crc_error,
92
 
93
 
94
//PIO
95
  input               t_pio_response,
96
  input               t_pio_direction,
97
  input       [15:0]  t_pio_transfer_count,
98
  input       [7:0]   t_pio_e_status,
99
 
100
//Host to Device Register Values
101
  output      [7:0]   h2d_command,
102
  output  reg [15:0]  h2d_features,
103
  output      [7:0]   h2d_control,
104
  output      [3:0]   h2d_port_mult,
105
  output      [7:0]   h2d_device,
106
  output      [47:0]  h2d_lba,
107
  output      [15:0]  h2d_sector_count,
108
 
109
//Device to Host Register Values
110
  input               d2h_interrupt,
111
  input               d2h_notification,
112
  input       [3:0]   d2h_port_mult,
113
  input       [7:0]   d2h_device,
114
  input       [47:0]  d2h_lba,
115
  input       [15:0]  d2h_sector_count,
116
  input       [7:0]   d2h_status,
117
  input       [7:0]   d2h_error,
118
 
119
 
120
 
121
//command layer data interface
122
  input               t_if_strobe,
123
  output      [31:0]  t_if_data,
124
  output              t_if_ready,
125
  input               t_if_activate,
126
  output      [23:0]  t_if_size,
127
 
128
  input               t_of_strobe,
129
  input       [31:0]  t_of_data,
130
  output      [1:0]   t_of_ready,
131
  input       [1:0]   t_of_activate,
132
  output      [23:0]  t_of_size,
133
 
134
 
135
//Debug
136
  output      [3:0]   cl_c_state,
137
  output      [3:0]   cl_w_state,
138
  output      [3:0]   cl_r_state
139
 
140
);
141
 
142
 
143
//Parameters
144
parameter IDLE                = 4'h0;
145
parameter PIO_WAIT_FOR_DATA   = 4'h1;
146
parameter PIO_WRITE_DATA      = 4'h2;
147
 
148
parameter WAIT_FOR_DATA       = 4'h1;
149
 
150
parameter WAIT_FOR_DMA_ACT    = 4'h1;
151
parameter WAIT_FOR_WRITE_DATA = 4'h2;
152
parameter SEND_DATA           = 4'h3;
153
parameter WAIT_FOR_STATUS     = 4'h4;
154
 
155
//Registers/Wires
156
reg         [3:0]   cntrl_state;
157
reg                 srst;
158
reg         [7:0]   status;
159
wire                idle;
160
reg                 cntrl_send_data_stb;
161
reg                 send_command_stb;
162
reg                 prev_send_command;
163
 
164
wire                dev_busy;
165
wire                dev_data_req;
166
 
167
reg         [31:0]  reset_count;
168
wire                reset_timeout;
169
 
170
//Read State Machine
171
reg         [3:0]   read_state;
172
reg                 read_data_stb;
173
reg                 single_read_prev;
174
 
175
//Write State Machine
176
reg         [3:0]   write_state;
177
reg                 write_data_stb;
178
reg                 single_write_prev;
179
 
180
reg                 dma_send_data_stb;
181
reg                 dma_act_detected;
182
 
183
wire                write_data_available;
184
reg                 first_write;
185
reg                 first_read;
186
 
187
reg                 enable_tl_data_ready;
188
 
189
//Ping Pong FIFOs
190
wire        [1:0]   if_write_ready;
191
wire        [1:0]   if_write_activate;
192
wire        [23:0]  if_write_size;
193
wire                if_write_strobe;
194
wire                if_starved;
195
wire        [31:0]  if_write_data;
196
 
197
wire                if_read_strobe;
198
wire                if_read_ready;
199
wire                if_read_activate;
200
wire        [23:0]  if_read_size;
201
wire        [31:0]  if_read_data;
202
 
203
wire                if_reset;
204
 
205
wire        [31:0]  of_write_data;
206
wire        [1:0]   of_write_ready;
207
wire        [1:0]   of_write_activate;
208
wire        [23:0]  of_read_size;
209
wire                of_write_strobe;
210
wire                out_fifo_starved;
211
 
212
wire                of_read_ready;
213
wire        [31:0]  of_read_data;
214
wire                of_read_activate;
215
wire        [23:0]  of_write_size;
216
wire                of_read_strobe;
217
 
218
wire                of_reset;
219
 
220
//ping pong FIFO
221
//Input FIFO
222
ppfifo # (
223
  .DATA_WIDTH           (`DATA_SIZE               ),
224
  .ADDRESS_WIDTH        (`FIFO_ADDRESS_WIDTH      )
225
) fifo_in (
226
  .reset                (if_reset                 ),  //XXX: Veify that new PPFIFO doesn't need an external reset
227
 
228
  //write side
229
//XXX: This can be different clocks
230
  .write_clock          (data_in_clk              ),
231
  .write_data           (if_write_data            ),
232
  .write_ready          (if_write_ready           ),
233
  .write_activate       (if_write_activate        ),
234
  .write_fifo_size      (if_write_size            ),
235
  .write_strobe         (if_write_strobe          ),
236
  .starved              (if_starved               ),
237
 
238
  //read side
239
//XXX: This can be different clocks
240
  .read_clock           (clk                      ),
241
  .read_strobe          (if_read_strobe           ),
242
  .read_ready           (if_read_ready            ),
243
  .read_activate        (if_read_activate         ),
244
  .read_count           (if_read_size             ),
245
  .read_data            (if_read_data             )
246
);
247
 
248
 
249
//Output FIFO
250
ppfifo # (
251
  .DATA_WIDTH           (`DATA_SIZE               ),
252
  .ADDRESS_WIDTH        (`FIFO_ADDRESS_WIDTH      )
253
) fifo_out (
254
  .reset                (of_reset                 ),
255
  //.reset                (0),
256
 
257
  //write side
258
//XXX: This can be different clocks
259
  .write_clock          (clk                      ),
260
  .write_data           (of_write_data            ),
261
  .write_ready          (of_write_ready           ),
262
  .write_activate       (of_write_activate        ),
263
  .write_fifo_size      (of_write_size            ),
264
  .write_strobe         (of_write_strobe          ),
265
  .starved              (out_fifo_starved         ),
266
 
267
  //read side
268
//XXX: This can be different clocks
269
  .read_clock           (data_out_clk             ),
270
  .read_strobe          (of_read_strobe           ),
271
  .read_ready           (of_read_ready            ),
272
  .read_activate        (of_read_activate         ),
273
  .read_count           (of_read_size             ),
274
  .read_data            (of_read_data             )
275
);
276
 
277
 
278
//Asynchronous Logic
279
//Attach output of Input FIFO to TL
280
assign  t_if_ready            = if_read_ready && enable_tl_data_ready;
281
assign  t_if_size             = if_read_size;
282
assign  t_if_data             = if_read_data;
283
 
284
assign  if_read_activate      = t_if_activate;
285
assign  if_read_strobe        = t_if_strobe;
286
 
287
//Attach input of output FIFO to TL
288
assign  t_of_ready            = of_write_ready;
289
//assign  t_of_size             = of_write_size;
290
assign  t_of_size             = 24'h00800;
291
assign  of_write_data         = t_of_data;
292
 
293
assign  of_write_activate     = t_of_activate;
294
assign  of_write_strobe       = t_of_strobe;
295
 
296
assign  of_reset              = (rst && data_out_clk_valid);
297
assign  if_reset              = (rst && data_in_clk_valid);
298
 
299
 
300
 
301
assign  if_write_data         = user_din;
302
assign  if_write_strobe       = user_din_stb;
303
assign  user_din_ready        = if_write_ready;
304
assign  if_write_activate     = user_din_activate;
305
//assign  user_din_size         = if_write_size;
306
assign  user_din_size         = 24'h00800;
307
//assign  user_din_size         = 24'h00400;
308
//assign  user_din_size         = 24'h00200;
309
 
310
assign  user_dout             = of_read_data;
311
assign  user_dout_ready       = of_read_ready;
312
assign  of_read_activate      = user_dout_activate;
313
assign  user_dout_size        = of_read_size;
314
assign  of_read_strobe        = user_dout_stb;
315
 
316
 
317
assign  write_data_available  = (if_read_ready || if_read_activate) ||  (if_write_ready != 2'b11);
318
 
319
 
320
//Strobes
321
assign  t_send_command_stb    = read_data_stb ||  write_data_stb  || send_command_stb;
322
assign  t_send_data_stb       = dma_send_data_stb ||cntrl_send_data_stb;
323
 
324
//IDLE
325
assign  idle                  = (cntrl_state  == IDLE) &&
326
                                (read_state   == IDLE) &&
327
                                (write_state  == IDLE) &&
328
                                transport_layer_ready;
329
 
330
assign  command_layer_ready   = idle;
331
assign  sata_init             = reset_timeout;
332
 
333
assign  h2d_command           = (write_data_en)   ?        `COMMAND_DMA_WRITE_EX    :
334
                                (read_data_en)    ?        `COMMAND_DMA_READ_EX     :
335
                                (send_user_command_stb) ? command                   :
336
                                h2d_command;
337
 
338
assign  h2d_sector_count      = sector_count;
339
assign  h2d_lba               = (write_data_en) ? (!single_rdwr && !first_write)  ?   d2h_lba + 1 : sector_address :
340
                                (read_data_en)  ? (!single_rdwr && !first_read)   ?   d2h_lba + 1 : sector_address :
341
                                sector_address;
342
 
343
//XXX: The individual bits should be controlled directly
344
assign  h2d_control           = {5'h00, srst, 2'b00};
345
//XXX: This should be controlled from a higher level
346
assign  h2d_port_mult         = 4'h0;
347
//XXX: This should be controlled from a higher level
348
assign  h2d_device            = `D2H_REG_DEVICE;
349
 
350
assign  dev_busy              = status[`STATUS_BUSY_BIT];
351
assign  dev_data_req          = status[`STATUS_DRQ_BIT];
352
assign  dev_error             = status[`STATUS_ERR_BIT];
353
 
354
assign  cl_c_state           = cntrl_state;
355
assign  cl_r_state           = read_state;
356
assign  cl_w_state           = write_state;
357
 
358
assign  reset_timeout         = (reset_count >=  `RESET_TIMEOUT);
359
 
360
//Synchronous Logic
361
 
362
//Control State Machine
363
always @ (posedge clk) begin
364
  if (rst || (!linkup)) begin
365
    cntrl_state                   <=  IDLE;
366
 
367
    h2d_features                  <=  `D2H_REG_FEATURES;
368
    srst                          <=  0;
369
 
370
    //Strobes
371
    t_send_control_stb            <=  0;
372
    cntrl_send_data_stb           <=  0;
373
    pio_data_ready                <=  0;
374
    status                        <=  0;
375
 
376
    prev_send_command             <=  0;
377
    send_command_stb              <=  0;
378
 
379
    reset_count                   <=  0;
380
    busy                          <=  1;
381
  end
382
  else begin
383
    t_send_control_stb            <=  0;
384
    cntrl_send_data_stb           <=  0;
385
    pio_data_ready                <=  0;
386
    send_command_stb              <=  0;
387
 
388
    //Reset Count
389
    if (reset_count < `RESET_TIMEOUT) begin
390
      reset_count                 <=  reset_count + 1;
391
    end
392
    if (!reset_timeout) begin
393
      cntrl_state                 <=  IDLE;
394
    end
395
 
396
    //detected the first a user attempting to send a command
397
    if (send_user_command_stb && !prev_send_command) begin
398
      prev_send_command           <=  1;
399
      send_command_stb            <=  1;
400
    end
401
    if (!send_user_command_stb) begin
402
      prev_send_command           <=  0;
403
    end
404
 
405
    if (t_d2h_reg_stb) begin
406
      busy                        <=  0;
407
      h2d_features                <=  `D2H_REG_FEATURES;
408
    end
409
    if (t_send_command_stb || t_send_control_stb || send_user_command_stb) begin
410
      busy                        <=  1;
411
      if (send_user_command_stb) begin
412
        h2d_features              <=  user_features;
413
      end
414
    end
415
 
416
    case (cntrl_state)
417
      IDLE: begin
418
 
419
        //Soft Reset will break out of any flow
420
        if ((soft_reset_en) && !srst) begin
421
          srst                  <=  1;
422
          t_send_control_stb    <=  1;
423
          reset_count           <=  0;
424
        end
425
 
426
        if (idle) begin
427
          //The only way to transition to another state is if CL is IDLE
428
 
429
          //User Initiated commands
430
          if (!soft_reset_en && srst && reset_timeout) begin
431
            srst                  <=  0;
432
            t_send_control_stb    <=  1;
433
          end
434
       end
435
 
436
        //Device Initiated Transfers
437
        if(t_pio_setup_stb) begin
438
          if (t_pio_direction) begin
439
            //Read from device
440
            cntrl_state           <=  PIO_WAIT_FOR_DATA;
441
          end
442
          else begin
443
            //Write to device
444
            cntrl_state           <=  PIO_WRITE_DATA;
445
          end
446
        end
447
        if (t_set_device_bits_stb) begin
448
          status                  <=  d2h_status;
449
          //status register was updated
450
        end
451
        if (t_d2h_reg_stb) begin
452
          status                  <=  d2h_status;
453
        end
454
      end
455
      PIO_WAIT_FOR_DATA: begin
456
        if (t_d2h_data_stb) begin
457
          //the next peice of data is related to the PIO
458
          pio_data_ready          <=  1;
459
          cntrl_state             <=  IDLE;
460
          status                  <=  t_pio_e_status;
461
        end
462
      end
463
      PIO_WRITE_DATA: begin
464
        if (if_read_activate) begin
465
          cntrl_send_data_stb     <=  0;
466
          cntrl_state             <=  IDLE;
467
          status                  <=  t_pio_e_status;
468
        end
469
      end
470
 
471
      default: begin
472
        cntrl_state               <=  IDLE;
473
      end
474
    endcase
475
 
476
    if (send_sync_escape) begin
477
      cntrl_state                 <=  IDLE;
478
      busy                        <=  0;
479
    end
480
  end
481
end
482
 
483
//Read State Machine
484
always @ (posedge clk) begin
485
  if (rst || (!linkup)) begin
486
    read_state                    <=  IDLE;
487
    sync_escape                   <=  0;
488
    read_data_stb                 <=  0;
489
    single_read_prev              <=  0;
490
    first_read                    <=  1;
491
  end
492
  else begin
493
    read_data_stb                 <=  0;
494
    sync_escape                   <=  0;
495
 
496
    if (!read_data_en) begin
497
      single_read_prev            <=  0;
498
    end
499
 
500
    case (read_state)
501
      IDLE: begin
502
        if (idle) begin
503
          sync_escape             <=  0;
504
          //The only way to transition to another state is if CL is IDLE
505
          if (read_data_en) begin
506
            if (single_rdwr) begin
507
              if (!single_read_prev) begin
508
                single_read_prev  <=  1;
509
                read_data_stb     <=  1;
510
                read_state        <=  WAIT_FOR_DATA;
511
              end
512
            end
513
            else begin
514
              //send a request to read data
515
              read_data_stb       <=  1;
516
              read_state          <=  WAIT_FOR_DATA;
517
            end
518
          end
519
          else begin
520
            first_read            <=  1;
521
          end
522
        end
523
      end
524
      WAIT_FOR_DATA: begin
525
        //This state seems useless because it only sets a value but the state is used to indicate the system is idle or not
526
        if (t_d2h_data_stb) begin
527
          first_read          <=  0;
528
        end
529
        /*
530
        if (soft_reset_en) begin
531
//XXX: Issue a SYNC ESCAPE to cancel a large read request otherwise let it play out
532
          //sync_escape         <=  1;
533
        end
534
      */
535
      end
536
      default: begin
537
        read_state                <=  IDLE;
538
      end
539
    endcase
540
 
541
    if (soft_reset_en || !reset_timeout || send_sync_escape) begin
542
      if (read_state  != IDLE) begin
543
        sync_escape               <=  1;
544
      end
545
      if (send_sync_escape) begin
546
        sync_escape               <=  1;
547
      end
548
      read_state                  <=  IDLE;
549
    end
550
 
551
    //If this is received go back to IDLE
552
    if (t_d2h_reg_stb) begin
553
      read_state                  <=  IDLE;
554
    end
555
  end
556
end
557
 
558
//Write State Machine
559
always @ (posedge clk) begin
560
  if (rst || (!linkup)) begin
561
    write_state                   <=  IDLE;
562
 
563
    dma_send_data_stb             <=  0;
564
 
565
    write_data_stb                <=  0;
566
    single_write_prev             <=  0;
567
    first_write                   <=  1;
568
    enable_tl_data_ready          <=  0;
569
 
570
    dma_act_detected              <=  0;
571
  end
572
  else begin
573
    dma_send_data_stb             <=  0;
574
    write_data_stb                <=  0;
575
 
576
    if (enable_tl_data_ready && if_read_activate) begin
577
      //Closes the loop on the data write feedback
578
      enable_tl_data_ready        <=  0;
579
    end
580
 
581
    if (!write_data_en) begin
582
      single_write_prev           <=  0;
583
    end
584
 
585
    if (t_dma_activate_stb) begin
586
      //Set an enable signal instead of a strobe so that there is no chance of missing this signal
587
      dma_act_detected            <=  1;
588
    end
589
 
590
    case (write_state)
591
      IDLE: begin
592
        if (idle) begin
593
          //The only way to transition to another state is if CL is IDLE
594
          if (write_data_en) begin
595
            if (single_rdwr) begin
596
              if (!single_write_prev) begin
597
                single_write_prev   <=  1;
598
                write_state         <=  WAIT_FOR_DMA_ACT;
599
                write_data_stb      <=  1;
600
              end
601
            end
602
            else begin
603
              //send a request to write data
604
              write_state           <=  WAIT_FOR_DMA_ACT;
605
              write_data_stb        <=  1;
606
            end
607
          end
608
          else begin
609
            //reset the the first write when the user deassertes the write_data_en
610
            first_write             <=  1;
611
          end
612
        end
613
      end
614
      WAIT_FOR_DMA_ACT: begin
615
        if (dma_act_detected) begin
616
          dma_act_detected        <=  0;
617
          first_write             <=  0;
618
          enable_tl_data_ready    <=  1;
619
          write_state             <=  WAIT_FOR_WRITE_DATA;
620
        end
621
      end
622
      WAIT_FOR_WRITE_DATA: begin
623
        if (if_read_activate) begin
624
          write_state             <=  SEND_DATA;
625
        end
626
      end
627
      SEND_DATA: begin
628
        if (transport_layer_ready) begin
629
          //Send the Data FIS
630
          dma_send_data_stb       <=  1;
631
          write_state             <=  WAIT_FOR_DMA_ACT;
632
        end
633
      end
634
      WAIT_FOR_STATUS: begin
635
        if (t_d2h_reg_stb) begin
636
          write_state             <=  IDLE;
637
        end
638
      end
639
      default: begin
640
        write_state               <=  IDLE;
641
      end
642
    endcase
643
 
644
 
645
    if (soft_reset_en || !reset_timeout) begin
646
      //Break out of the normal flow and return to IDLE
647
      write_state                 <=  IDLE;
648
    end
649
    if (t_d2h_reg_stb) begin
650
      //Whenever I read a register transfer from the device I need to go back to IDLE
651
      write_state                 <=  IDLE;
652
    end
653
    if (send_sync_escape) begin
654
      write_state                 <=  IDLE;
655
    end
656
  end
657
end
658
 
659
 
660
 
661
endmodule
662
 
663
 

powered by: WebSVN 2.1.0

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