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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [rtl/] [link/] [sata_link_layer_read.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_link_layer_read.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
 
26
`include "sata_defines.v"
27
 
28
module sata_link_layer_read (
29
 
30
  input               rst,            //reset
31
  input               clk,
32
 
33
  input               phy_ready,
34
  input               en,
35
  output              idle,
36
 
37
  input               sync_escape,
38
  input               dbg_hold,
39
 
40
  input               detect_align,
41
  input               detect_sync,
42
  input               detect_x_rdy,
43
  input               detect_sof,
44
  input               detect_eof,
45
  input               detect_wtrm,
46
  input               detect_holda,
47
  input               detect_hold,
48
  input               detect_cont,
49
  input               detect_xrdy_xrdy,
50
 
51
  output      [31:0]  tx_dout,
52
  output              tx_isk,
53
 
54
  input       [31:0]  rx_din,
55
  input       [3:0]   rx_isk,
56
 
57
  output  reg         read_strobe,
58
  output  reg  [31:0] read_data,
59
  input               read_ready,
60
  output              read_start,
61
  output              read_finished,
62
  output  reg         remote_abort,
63
 
64
  output  reg         crc_ok,
65
//  output  wire        crc_ok,
66
 
67
  input               data_scrambler_en,
68
  input               is_device,
69
  output      [3:0]   lax_r_state
70
 
71
 
72
 
73
);
74
//Primatives
75
parameter           IDLE        = 4'h0;
76
parameter           READ_START  = 4'h1;
77
parameter           READ        = 4'h2;
78
parameter           READ_END    = 4'h3;
79
parameter           SEND_STATUS = 4'h4;
80
 
81
//Registers/Wires
82
reg         [3:0]   state;
83
 
84
reg                 send_r_rdy;
85
reg                 send_r_ip;
86
reg                 send_r_err;
87
reg                 send_r_ok;
88
reg                 send_hold;
89
reg                 send_holda;
90
reg                 send_sync;
91
 
92
//CRC
93
//XXX: Tie the CRC_EN to an incomming data dword
94
wire                crc_en;
95
wire      [31:0]    crc_din;
96
wire      [31:0]    crc_dout;
97
reg                 crc_data;
98
reg                 crc_check;
99
 
100
reg       [31:0]    prev_crc;
101
reg       [31:0]    prev_data;
102
wire                data_valid;
103
reg                 first_dword;
104
 
105
 
106
 
107
//Descrambler
108
wire                descr_en;
109
wire      [31:0]    descr_din;
110
wire      [31:0]    descr_dout;
111
 
112
//SubModules
113
crc c (
114
  .rst            (rst      || idle ),
115
  .clk            (clk              ),
116
  .en             (crc_en           ),
117
  .din            (crc_din          ),
118
  .dout           (crc_dout         )
119
);
120
 
121
scrambler descr (
122
  .rst            (rst      ||  idle),
123
  .clk            (clk              ),
124
  .prim_scrambler (0                ),
125
  .en             (descr_en         ),
126
  .din            (rx_din           ),
127
  .dout           (descr_dout       )
128
);
129
 
130
 
131
 
132
//Asynchronous Logic
133
assign              idle    = (state == IDLE);
134
assign              tx_dout = (send_r_rdy)  ? `PRIM_R_RDY :
135
                              (send_r_ip)   ? `PRIM_R_IP  :
136
                              (send_r_err)  ? `PRIM_R_ERR :
137
                              (send_r_ok)   ? `PRIM_R_OK  :
138
                              (send_hold)   ? `PRIM_HOLD  :
139
                              (send_sync)   ? `PRIM_SYNC  :
140
                              (send_holda)  ? `PRIM_HOLDA :
141
                              `PRIM_SYNC;
142
 
143
assign              tx_isk  = ( send_r_rdy  ||
144
                                send_r_ip   ||
145
                                send_r_err  ||
146
                                send_r_ok   ||
147
                                send_hold   ||
148
                                send_holda  ||
149
                                send_sync);
150
 
151
assign              crc_din       = (data_scrambler_en) ? descr_dout : rx_din;
152
//assign              read_data     = (read_strobe) ? rx_din : 32'h0;
153
assign              read_finished = detect_eof;
154
assign              read_start    = detect_sof;
155
assign              data_valid    = (state == READ) &&
156
                                    (rx_isk == 0)   &&
157
                                    (!detect_hold)  &&
158
                                    (!detect_holda) &&
159
                                    (!detect_align);
160
 
161
assign              crc_en        = data_valid;
162
assign              descr_en      = (data_scrambler_en && (detect_sof || data_valid));
163
assign              descr_din     = (data_valid) ? rx_din : 32'h00000000;
164
//assign              crc_ok        = (prev_data == prev_crc);
165
 
166
assign              lax_r_state   = state;
167
 
168
//Synchronous Logic
169
always @ (posedge clk) begin
170
  if (rst) begin
171
    state             <=  IDLE;
172
    send_r_rdy        <=  0;
173
    send_r_ip         <=  0;
174
    send_r_err        <=  0;
175
    send_r_ok         <=  0;
176
    send_hold         <=  0;
177
    send_holda        <=  0;
178
    send_sync         <=  0;
179
 
180
    crc_ok            <=  0;
181
 
182
    prev_crc          <=  0;
183
    prev_data         <=  0;
184
    read_data         <=  0;
185
    read_strobe       <=  0;
186
    first_dword       <=  0;
187
 
188
    remote_abort      <=  0;
189
 
190
  end
191
  else begin
192
    read_strobe       <=  0;
193
    remote_abort      <=  0;
194
 
195
    if (phy_ready) begin
196
      send_r_rdy        <=  0;
197
      send_r_ip         <=  0;
198
      send_r_err        <=  0;
199
      send_r_ok         <=  0;
200
      send_hold         <=  0;
201
      send_sync         <=  0;
202
      send_holda        <=  0;
203
    end
204
 
205
    case (state)
206
      IDLE: begin
207
        read_data     <=  0;
208
        send_sync     <=  1;
209
        if (!detect_align) begin
210
          crc_ok            <=  0;
211
          prev_crc          <=  0;
212
          prev_data         <=  0;
213
          if (detect_x_rdy) begin
214
            if (detect_xrdy_xrdy) begin
215
              if (!is_device) begin
216
                if (read_ready || sync_escape) begin
217
                //Transport is ready
218
                  if (phy_ready) begin
219
                    send_r_rdy  <=  1;
220
                    state       <=  READ_START;
221
                  end
222
                end
223
              end
224
            end
225
            else begin
226
              if (read_ready || sync_escape) begin
227
                //Transport is ready
228
//XXX: I think this is okay because remote will continue to send X_RDY Primative
229
                if (phy_ready) begin
230
                  send_r_rdy  <=  1;
231
                  state       <=  READ_START;
232
                end
233
              end
234
            end
235
//            else begin
236
//              //Transport Read is not ready
237
//              send_sync   <=  1;
238
//            end
239
          end
240
        end
241
      end
242
      READ_START: begin
243
        //wait for a start of frame
244
        send_r_rdy            <=  1;
245
        if (detect_sync) begin
246
            remote_abort      <=  1;
247
            state             <=  IDLE;
248
        end
249
        else if (detect_sof) begin
250
          state         <=  READ;
251
          send_r_ip     <=  1;
252
          first_dword   <=  1;
253
        end
254
      end
255
      READ: begin
256
        if (sync_escape) begin
257
          send_sync           <=  1;
258
          if (detect_sync) begin
259
            state       <=  IDLE;
260
          end
261
        end
262
        else begin
263
          if (detect_eof) begin
264
            //check the CRC
265
            state         <=  READ_END;
266
            send_r_ip     <=  1;
267
            //if (prev_data == prev_crc) begin
268
            if (prev_data == prev_crc) begin
269
              crc_ok      <=  1;
270
            end
271
          end
272
          else begin
273
            if (detect_sync) begin
274
              remote_abort      <=  1;
275
              state             <=  IDLE;
276
            end
277
            else if (!read_ready || dbg_hold) begin
278
              //we should still have 20 DWORD of data to write
279
              send_hold         <=  1;
280
            end
281
            else if (detect_hold) begin
282
              send_holda        <=  1;
283
            end
284
            else begin
285
              send_r_ip         <=  1;
286
            end
287
          end
288
          if (data_valid) begin
289
            if (first_dword) begin
290
              first_dword   <=  0;
291
            end
292
            else begin
293
              read_strobe   <=  1;
294
            end
295
            read_data     <=  prev_data;
296
            if (data_scrambler_en) begin
297
              prev_data   <=  descr_dout;
298
            end
299
            else begin
300
              prev_data   <=  rx_din;
301
            end
302
            prev_crc      <=  crc_din;
303
          end
304
 
305
        end
306
 
307
        //put data into the incomming buffer
308
        //check to see if we have enough room for 20 more dwords
309
        //if not send a hold
310
      end
311
      READ_END: begin
312
        //send r ok or r err
313
//XXX: Watch out for PHY_READY
314
        //if CRC checks out OK then send an R_OK
315
        //if CRC does not check out then send an R_ERR
316
        //if (phy_ready) begin
317
          if (crc_ok) begin
318
            send_r_ok     <=  1;
319
            state         <=  SEND_STATUS;
320
          end
321
          else begin
322
            send_r_err    <=  1;
323
            state         <=  SEND_STATUS;
324
          end
325
        //end
326
      end
327
      SEND_STATUS: begin
328
        if (send_r_ok) begin
329
          send_r_ok       <=  1;
330
        end
331
        else begin
332
          send_r_err      <=  1;
333
        end
334
        if (detect_sync) begin
335
          state         <=  IDLE;
336
        end
337
      end
338
      default: begin
339
        state         <=  IDLE;
340
      end
341
    endcase
342
  end
343
end
344
endmodule

powered by: WebSVN 2.1.0

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