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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [sim/] [faux_sata_hd_transport.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cospan
//faux_sata_hd_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 faux_sata_hd_transport (
28
 
29
input               rst,            //reset
30
input               clk,
31
 
32
//Trasport Layer Control/Status
33
output              transport_layer_ready,
34
input               send_reg_stb,
35
input               send_dma_act_stb,
36
input               send_data_stb,
37
input               send_pio_stb,
38
input               send_dev_bits_stb,
39
 
40
 
41
output  reg         remote_abort,
42
output  reg         xmit_error,
43
output  reg         read_crc_fail,
44
 
45
output  reg         h2d_reg_stb,
46
output  reg         h2d_data_stb,
47
 
48
output              pio_request,
49
input       [15:0]  pio_transfer_count,
50
input               pio_direction,
51
input       [7:0]   pio_e_status,
52
 
53
 
54
//Host to Device Registers
55
output  reg [7:0]   h2d_command,
56
output  reg [15:0]  h2d_features,
57
output  reg         h2d_cmd_bit,
58
output  reg [7:0]   h2d_control,
59
output  reg [3:0]   h2d_port_mult,
60
output  reg [7:0]   h2d_device,
61
output  reg [47:0]  h2d_lba,
62
output  reg [15:0]  h2d_sector_count,
63
 
64
//Device to Host Registers
65
input               d2h_interrupt,
66
input               d2h_notification,
67
input       [3:0]   d2h_port_mult,
68
input       [7:0]   d2h_device,
69
input       [47:0]  d2h_lba,
70
input       [15:0]  d2h_sector_count,
71
input       [7:0]   d2h_status,
72
input       [7:0]   d2h_error,
73
 
74
//DMA Specific Control
75
 
76
//Data Control
77
input               cl_if_ready,
78
output reg          cl_if_activate,
79
input       [23:0]  cl_if_size,
80
 
81
output              cl_if_strobe,
82
input       [31:0]  cl_if_data,
83
 
84
input       [1:0]   cl_of_ready,
85
output  reg [1:0]   cl_of_activate,
86
output              cl_of_strobe,
87
output      [31:0]  cl_of_data,
88
input       [23:0]  cl_of_size,
89
 
90
 
91
//Link Layer Interface
92
input               link_layer_ready,
93
 
94
output  reg         ll_write_start,
95
input               ll_write_strobe,
96
input               ll_write_finished,
97
output      [31:0]  ll_write_data,
98
output      [31:0]  ll_write_size,
99
output              ll_write_hold,
100
output              ll_write_abort,
101
input               ll_xmit_error,
102
 
103
input               ll_read_start,
104
output              ll_read_ready,
105
input       [31:0]  ll_read_data,
106
input               ll_read_strobe,
107
input               ll_read_finished,
108
input               ll_read_crc_ok,
109
input               ll_remote_abort
110
 
111
 
112
);
113
 
114
 
115
//Parameters
116
parameter           IDLE                  = 4'h0;
117
parameter           READ_FIS              = 4'h1;
118
parameter           WAIT_FOR_END          = 4'h2;
119
 
120
parameter           CHECK_FIS_TYPE        = 4'h1;
121
parameter           READ_H2D_REG          = 4'h2;
122
parameter           READ_DATA             = 4'h3;
123
 
124
parameter           WRITE_D2H_REG         = 4'h4;
125
parameter           WRITE_DEV_BITS        = 4'h5;
126
parameter           WRITE_PIO_SETUP       = 4'h6;
127
parameter           WRITE_DMA_ACTIVATE    = 4'h7;
128
parameter           WRITE_DMA_SETUP       = 4'h8;
129
parameter           SEND_DATA             = 4'h9;
130
parameter           RETRY                 = 4'hA;
131
 
132
//Registers/Wires
133
reg         [3:0]   state;
134
reg         [3:0]   next_state;
135
reg         [3:0]   fis_id_state;
136
 
137
reg         [3:0]   reg_read_count;
138
//Detect Wires
139
wire                detect_h2d_reg;
140
wire                detect_h2d_data;
141
reg                 send_data_fis_id;
142
 
143
 
144
reg                 detect_fis;
145
reg         [7:0]   current_fis;
146
 
147
//Control buffer
148
reg         [7:0]   d2h_write_ptr;
149
 
150
wire        [31:0]  d2h_reg_buffer  [5:0];
151
wire        [31:0]  d2h_pio_setup   [5:0];
152
wire        [31:0]  d2h_dev_bits    [2:0];
153
wire        [31:0]  d2h_dma_act;
154
wire        [31:0]  d2h_data_fis_id;
155
 
156
//Submodules
157
//Asychronous Logic
158
assign  transport_layer_ready       = (state == IDLE)   &&  link_layer_ready;
159
assign  detect_h2d_reg  = detect_fis  ? (ll_read_data[7:0]  ==  `FIS_H2D_REG)       : (current_fis == `FIS_H2D_REG    );
160
assign  detect_h2d_data = detect_fis  ? (ll_read_data[7:0]  ==  `FIS_DATA)          : (current_fis == `FIS_DATA       );
161
 
162
//Device to host structural packets
163
assign  d2h_reg_buffer[0] = {d2h_error, d2h_status, 1'b0, d2h_interrupt, 2'b00, d2h_port_mult, `FIS_D2H_REG};
164
assign  d2h_reg_buffer[1] = {d2h_device, d2h_lba[23:0]};
165
assign  d2h_reg_buffer[2] = {8'h00, d2h_lba[47:24]};
166
assign  d2h_reg_buffer[3] = {16'h0000, d2h_sector_count};
167
assign  d2h_reg_buffer[4] = 32'h0;
168
 
169
assign  d2h_pio_setup[0]  = {d2h_error, d2h_status, 1'b0, d2h_interrupt, pio_direction, 1'b0, d2h_port_mult, `FIS_PIO_SETUP};
170
assign  d2h_pio_setup[1]  = {d2h_device, d2h_lba[23:0]};
171
assign  d2h_pio_setup[2]  = {8'h00, d2h_lba[47:24]};
172
assign  d2h_pio_setup[3]  = {pio_e_status, 8'h00, d2h_sector_count};
173
assign  d2h_pio_setup[4]  = {16'h0000, pio_transfer_count};
174
 
175
 
176
assign  d2h_dev_bits[0]   = { d2h_error,
177
                              1'b0, d2h_status[6:4], 1'b0, d2h_status[2:0],
178
                              d2h_notification, d2h_interrupt, 2'b00, d2h_port_mult,
179
                              `FIS_SET_DEV_BITS};
180
 
181
assign  d2h_dev_bits[1]   = 32'h00000000;
182
 
183
assign  d2h_dma_act       = {8'h00, 8'h00, 4'h0, d2h_port_mult, `FIS_DMA_ACT};
184
 
185
assign  d2h_data_fis_id   = {8'h00, 8'h00, 4'h0, d2h_port_mult, `FIS_DATA};
186
 
187
 
188
 
189
//Link Layer Signals
190
 
191
//Write
192
assign  ll_write_data     = (send_data_fis_id)              ? d2h_data_fis_id                                       :
193
                            (state == SEND_DATA)            ? cl_if_data                                            :
194
                            ((state == WRITE_D2H_REG)     || send_reg_stb       )   ? d2h_reg_buffer[d2h_write_ptr] :
195
                            ((state == WRITE_DEV_BITS)    || send_dev_bits_stb  )   ? d2h_dev_bits[d2h_write_ptr]   :
196
                            ((state == WRITE_DMA_ACTIVATE)|| send_dma_act_stb   )   ? d2h_dma_act                   :
197
                            ((state == WRITE_PIO_SETUP)   || send_pio_stb       )   ? d2h_pio_setup[d2h_write_ptr]  :
198
                            32'h00000000;
199
assign  ll_write_size     = (send_data_stb)                 ? cl_if_size + 1                                        :
200
                            (state == SEND_DATA)            ? cl_if_size + 1                                        :
201
                            ((state == WRITE_D2H_REG)       || send_reg_stb       ) ? `FIS_D2H_REG_SIZE             :
202
                            ((state == WRITE_DEV_BITS)      || send_dev_bits_stb  ) ? `FIS_SET_DEV_BITS_SIZE        :
203
                            ((state == WRITE_DMA_ACTIVATE)  || send_dma_act_stb   ) ? `FIS_DMA_ACT_SIZE             :
204
                            ((state == WRITE_PIO_SETUP)     || send_pio_stb       ) ? `FIS_PIO_SETUP_SIZE           :
205
                            24'h000000;
206
assign  ll_write_hold     = (state == SEND_DATA)            ? !cl_of_activate               :
207
                            1'b0;
208
assign  ll_write_abort    = 1'b0;
209
assign  cl_if_strobe      = (state == SEND_DATA)            ? ll_write_strobe               : 0;
210
 
211
//Read
212
assign  ll_read_ready     = (state == READ_DATA)            ? cl_of_activate                :
213
                            1'b1;
214
 
215
assign  cl_of_data        = (state == READ_DATA)            ? ll_read_data                  :
216
                            32'h00000000;
217
assign  cl_of_strobe      = (state == READ_DATA)            ? ll_read_strobe                :
218
                            1'b0;
219
 
220
//Synchronous Logic
221
 
222
//FIS ID State machine
223
always @ (posedge clk) begin
224
  if (rst) begin
225
    fis_id_state            <=  IDLE;
226
    detect_fis              <=  0;
227
    current_fis             <=  0;
228
  end
229
  else begin
230
    //in order to set all the detect_* high when the actual fis is detected send this strobe
231
    case (fis_id_state)
232
      IDLE: begin
233
        current_fis         <=  0;
234
        detect_fis          <=  0;
235
        if (ll_read_start) begin
236
          detect_fis        <=  1;
237
          fis_id_state      <=  READ_FIS;
238
        end
239
      end
240
      READ_FIS: begin
241
        if (ll_read_strobe) begin
242
          detect_fis        <=  0;
243
          current_fis         <=  ll_read_data[7:0];
244
          fis_id_state        <=  WAIT_FOR_END;
245
        end
246
      end
247
      WAIT_FOR_END: begin
248
        if (ll_read_finished) begin
249
          current_fis       <=  0;
250
          fis_id_state      <=  IDLE;
251
        end
252
      end
253
      default: begin
254
        fis_id_state        <=  IDLE;
255
      end
256
    endcase
257
  end
258
end
259
 
260
//Main State machine
261
always @ (posedge clk) begin
262
  if (rst) begin
263
    state                       <=  IDLE;
264
    next_state                  <=  IDLE;
265
    d2h_write_ptr               <=  0;
266
    reg_read_count              <=  0;
267
 
268
    h2d_reg_stb                 <=  0;
269
    h2d_data_stb                <=  0;
270
    h2d_command                 <=  0;
271
 
272
    cl_of_activate              <=  0;
273
 
274
    //Link Layer Interface
275
    ll_write_start              <=  0;
276
    send_data_fis_id            <=  0;
277
 
278
    h2d_command                 <=  0;
279
    h2d_features                <=  0;
280
    h2d_cmd_bit                 <=  0;
281
    h2d_control                 <=  0;
282
    h2d_port_mult               <=  0;
283
    h2d_device                  <=  0;
284
    h2d_lba                     <=  0;
285
    h2d_sector_count            <=  0;
286
 
287
    cl_if_activate              <=  0;
288
 
289
  end
290
  else begin
291
    //Strobes
292
    h2d_reg_stb                 <=  0;
293
    h2d_data_stb                <=  0;
294
    ll_write_start              <=  0;
295
    xmit_error                  <=  0;
296
    read_crc_fail               <=  0;
297
 
298
    //if there is any outptu buffers available
299
    if ((cl_of_ready > 0) && (cl_of_activate == 0)) begin
300
      if (cl_of_ready[0]) begin
301
        cl_of_activate[0]       <=  1;
302
      end
303
      else begin
304
        cl_of_activate[1]       <=  1;
305
      end
306
    end
307
 
308
    //if there is any cl incomming buffers available grab it
309
    if (cl_if_ready && !cl_if_activate) begin
310
      cl_if_activate            <=  1;
311
    end
312
 
313
 
314
    //Remote Abortion
315
    if (ll_remote_abort) begin
316
      state                     <=  IDLE;
317
      remote_abort              <=  0;
318
    end
319
    if (ll_xmit_error) begin
320
      xmit_error                <=  1;
321
    end
322
    if (!ll_read_crc_ok) begin
323
      read_crc_fail             <=  1;
324
    end
325
 
326
    case (state)
327
      IDLE: begin
328
        d2h_write_ptr           <=  0;
329
        reg_read_count          <=  0;
330
        send_data_fis_id        <=  0;
331
        next_state              <=  IDLE;
332
 
333
        //detect an incomming FIS
334
        if (ll_read_start) begin
335
          state                 <=  CHECK_FIS_TYPE;
336
        end
337
        //Command Layer Initiated a transaction
338
        if (link_layer_ready) begin
339
          if (send_reg_stb) begin
340
            ll_write_start        <=  1;
341
            state                 <=  WRITE_D2H_REG;
342
          end
343
          else if (send_dev_bits_stb) begin
344
            ll_write_start        <=  1;
345
            state                 <=  WRITE_DEV_BITS;
346
          end
347
          else if (send_dma_act_stb) begin
348
            ll_write_start        <=  1;
349
            state                 <=  WRITE_DMA_ACTIVATE;
350
          end
351
          else if (send_pio_stb) begin
352
            ll_write_start        <=  1;
353
            state                 <=  WRITE_PIO_SETUP;
354
          end
355
          else if (send_data_stb) begin
356
            ll_write_start        <=  1;
357
            send_data_fis_id      <=  1;
358
            state                 <=  SEND_DATA;
359
          end
360
        end
361
      end
362
      CHECK_FIS_TYPE: begin
363
        if (detect_h2d_reg) begin
364
          h2d_features[7:0]     <=  ll_read_data[31:24];
365
          h2d_command           <=  ll_read_data[23:16];
366
          h2d_cmd_bit           <=  ll_read_data[15];
367
          h2d_port_mult         <=  ll_read_data[11:8];
368
 
369
          state                 <=  READ_H2D_REG;
370
          reg_read_count        <=  reg_read_count + 1;
371
        end
372
        else if (detect_h2d_data) begin
373
          state                 <=  READ_DATA;
374
        end
375
        if (ll_read_finished) begin
376
          //unrecognized FIS
377
          state                 <=  IDLE;
378
        end
379
 
380
      end
381
      READ_H2D_REG: begin
382
        case (reg_read_count)
383
          1:  begin
384
            h2d_device          <=  ll_read_data[31:24];
385
            h2d_lba[23:0]       <=  ll_read_data[23:0];
386
          end
387
          2:  begin
388
            h2d_features[15:8]  <=  ll_read_data[31:24];
389
            h2d_lba[47:24]      <=  ll_read_data[23:0];
390
          end
391
          3:  begin
392
            h2d_control         <=  ll_read_data[31:24];
393
            h2d_sector_count    <=  ll_read_data[15:0];
394
          end
395
          4:  begin
396
          end
397
          default: begin
398
          end
399
        endcase
400
        if (ll_read_strobe) begin
401
          reg_read_count        <=  reg_read_count + 1;
402
        end
403
        if (ll_read_finished) begin
404
          h2d_reg_stb           <=  1;
405
          state                 <=  IDLE;
406
        end
407
      end
408
      READ_DATA: begin
409
        //NOTE: the data_read_ready will automatically 'flow control' the data from the link layer
410
        //so we don't have to check it here
411
        //NOTE: We don't have to keep track of the count because the lower level will give a max of 2048 DWORDS
412
 
413
        if (ll_read_finished) begin
414
          h2d_data_stb          <=  1;
415
          cl_of_activate        <=  0;
416
          state                 <=  IDLE;
417
        end
418
      end
419
      WRITE_D2H_REG: begin
420
        if (ll_write_strobe) begin
421
          d2h_write_ptr         <=  d2h_write_ptr + 1;
422
        end
423
        if (ll_write_finished) begin
424
          if (ll_xmit_error) begin
425
            next_state            <=  state;
426
            state                 <=  RETRY;
427
          end
428
          else begin
429
            state                 <=  IDLE;
430
          end
431
        end
432
      end
433
      WRITE_DEV_BITS: begin
434
        if (ll_write_strobe) begin
435
          d2h_write_ptr         <=  d2h_write_ptr + 1;
436
        end
437
        if (ll_write_finished) begin
438
          if (ll_xmit_error) begin
439
            next_state            <=  state;
440
            state                 <=  RETRY;
441
          end
442
          else begin
443
            state                 <=  IDLE;
444
          end
445
        end
446
      end
447
      WRITE_PIO_SETUP: begin
448
        if (ll_write_strobe) begin
449
          d2h_write_ptr         <=  d2h_write_ptr + 1;
450
        end
451
        if (ll_write_finished) begin
452
          if (ll_xmit_error) begin
453
            next_state            <=  state;
454
            state                 <=  RETRY;
455
          end
456
          else begin
457
            state                 <=  IDLE;
458
          end
459
        end
460
      end
461
      WRITE_DMA_ACTIVATE: begin
462
        if (ll_write_strobe) begin
463
          d2h_write_ptr         <=  d2h_write_ptr + 1;
464
        end
465
        if (ll_write_finished) begin
466
          if (ll_xmit_error) begin
467
            next_state            <=  state;
468
            state                 <=  RETRY;
469
          end
470
          else begin
471
            state                 <=  IDLE;
472
          end
473
        end
474
      end
475
      WRITE_DMA_SETUP: begin
476
//XXX:  not implemented yet
477
        state                   <=  IDLE;
478
      end
479
      SEND_DATA: begin
480
        if (ll_write_strobe && send_data_fis_id) begin
481
          send_data_fis_id      <=  0;
482
        end
483
        if (ll_write_finished) begin
484
          cl_if_activate        <=  0;
485
          state                 <=  IDLE;
486
        end
487
      end
488
      RETRY: begin
489
        d2h_write_ptr           <=  0;
490
        reg_read_count          <=  0;
491
        if (link_layer_ready) begin
492
          ll_write_start        <=  1;
493
          state                 <=  next_state;
494
          next_state            <=  IDLE;
495
        end
496
      end
497
      default: begin
498
        state                   <=  IDLE;
499
      end
500
    endcase
501
  end
502
end
503
 
504
 
505
endmodule

powered by: WebSVN 2.1.0

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