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 3

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 3 cospan
  output              tx_is_k,
53 2 cospan
 
54
  input       [31:0]  rx_din,
55 3 cospan
  input       [3:0]   rx_is_k,
56 2 cospan
 
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      [31:0]    crc_din;
95
 
96
reg       [31:0]    prev_crc;
97
reg       [31:0]    prev_data;
98
wire                data_valid;
99
reg                 first_dword;
100
 
101
 
102
 
103
//Descrambler
104
wire                descr_en;
105
wire      [31:0]    descr_din;
106
wire      [31:0]    descr_dout;
107
 
108
//SubModules
109
scrambler descr (
110
  .rst            (rst      ||  idle),
111
  .clk            (clk              ),
112 3 cospan
  .prim_scrambler (1'b0             ),
113 2 cospan
  .en             (descr_en         ),
114
  .din            (rx_din           ),
115
  .dout           (descr_dout       )
116
);
117
 
118
 
119
 
120
//Asynchronous Logic
121
assign              idle    = (state == IDLE);
122
assign              tx_dout = (send_r_rdy)  ? `PRIM_R_RDY :
123
                              (send_r_ip)   ? `PRIM_R_IP  :
124
                              (send_r_err)  ? `PRIM_R_ERR :
125
                              (send_r_ok)   ? `PRIM_R_OK  :
126
                              (send_hold)   ? `PRIM_HOLD  :
127
                              (send_sync)   ? `PRIM_SYNC  :
128
                              (send_holda)  ? `PRIM_HOLDA :
129
                              `PRIM_SYNC;
130
 
131 3 cospan
assign              tx_is_k  = ( send_r_rdy  ||
132 2 cospan
                                send_r_ip   ||
133
                                send_r_err  ||
134
                                send_r_ok   ||
135
                                send_hold   ||
136
                                send_holda  ||
137
                                send_sync);
138
 
139
assign              crc_din       = (data_scrambler_en) ? descr_dout : rx_din;
140
//assign              read_data     = (read_strobe) ? rx_din : 32'h0;
141
assign              read_finished = detect_eof;
142
assign              read_start    = detect_sof;
143
assign              data_valid    = (state == READ) &&
144 3 cospan
                                    (rx_is_k == 0)   &&
145 2 cospan
                                    (!detect_hold)  &&
146
                                    (!detect_holda) &&
147
                                    (!detect_align);
148
 
149
assign              descr_en      = (data_scrambler_en && (detect_sof || data_valid));
150
assign              descr_din     = (data_valid) ? rx_din : 32'h00000000;
151
//assign              crc_ok        = (prev_data == prev_crc);
152
 
153
assign              lax_r_state   = state;
154
 
155
//Synchronous Logic
156
always @ (posedge clk) begin
157
  if (rst) begin
158
    state             <=  IDLE;
159
    send_r_rdy        <=  0;
160
    send_r_ip         <=  0;
161
    send_r_err        <=  0;
162
    send_r_ok         <=  0;
163
    send_hold         <=  0;
164
    send_holda        <=  0;
165
    send_sync         <=  0;
166
 
167
    crc_ok            <=  0;
168
 
169
    prev_crc          <=  0;
170
    prev_data         <=  0;
171
    read_data         <=  0;
172
    read_strobe       <=  0;
173
    first_dword       <=  0;
174
 
175
    remote_abort      <=  0;
176
 
177
  end
178
  else begin
179
    read_strobe       <=  0;
180
    remote_abort      <=  0;
181
 
182
    if (phy_ready) begin
183
      send_r_rdy        <=  0;
184
      send_r_ip         <=  0;
185
      send_r_err        <=  0;
186
      send_r_ok         <=  0;
187
      send_hold         <=  0;
188
      send_sync         <=  0;
189
      send_holda        <=  0;
190
    end
191
 
192
    case (state)
193
      IDLE: begin
194
        read_data     <=  0;
195
        send_sync     <=  1;
196
        if (!detect_align) begin
197
          crc_ok            <=  0;
198
          prev_crc          <=  0;
199
          prev_data         <=  0;
200
          if (detect_x_rdy) begin
201
            if (detect_xrdy_xrdy) begin
202
              if (!is_device) begin
203
                if (read_ready || sync_escape) begin
204
                //Transport is ready
205
                  if (phy_ready) begin
206
                    send_r_rdy  <=  1;
207
                    state       <=  READ_START;
208
                  end
209
                end
210
              end
211
            end
212
            else begin
213
              if (read_ready || sync_escape) begin
214
                //Transport is ready
215
//XXX: I think this is okay because remote will continue to send X_RDY Primative
216
                if (phy_ready) begin
217
                  send_r_rdy  <=  1;
218
                  state       <=  READ_START;
219
                end
220
              end
221
            end
222
//            else begin
223
//              //Transport Read is not ready
224
//              send_sync   <=  1;
225
//            end
226
          end
227
        end
228
      end
229
      READ_START: begin
230
        //wait for a start of frame
231
        send_r_rdy            <=  1;
232
        if (detect_sync) begin
233
            remote_abort      <=  1;
234
            state             <=  IDLE;
235
        end
236
        else if (detect_sof) begin
237
          state         <=  READ;
238
          send_r_ip     <=  1;
239
          first_dword   <=  1;
240
        end
241
      end
242
      READ: begin
243
        if (sync_escape) begin
244
          send_sync           <=  1;
245
          if (detect_sync) begin
246
            state       <=  IDLE;
247
          end
248
        end
249
        else begin
250
          if (detect_eof) begin
251
            //check the CRC
252
            state         <=  READ_END;
253
            send_r_ip     <=  1;
254
            //if (prev_data == prev_crc) begin
255
            if (prev_data == prev_crc) begin
256
              crc_ok      <=  1;
257
            end
258
          end
259
          else begin
260
            if (detect_sync) begin
261
              remote_abort      <=  1;
262
              state             <=  IDLE;
263
            end
264
            else if (!read_ready || dbg_hold) begin
265
              //we should still have 20 DWORD of data to write
266
              send_hold         <=  1;
267
            end
268
            else if (detect_hold) begin
269
              send_holda        <=  1;
270
            end
271
            else begin
272
              send_r_ip         <=  1;
273
            end
274
          end
275
          if (data_valid) begin
276
            if (first_dword) begin
277
              first_dword   <=  0;
278
            end
279
            else begin
280
              read_strobe   <=  1;
281
            end
282
            read_data     <=  prev_data;
283
            if (data_scrambler_en) begin
284
              prev_data   <=  descr_dout;
285
            end
286
            else begin
287
              prev_data   <=  rx_din;
288
            end
289
            prev_crc      <=  crc_din;
290
          end
291
 
292
        end
293
 
294
        //put data into the incomming buffer
295
        //check to see if we have enough room for 20 more dwords
296
        //if not send a hold
297
      end
298
      READ_END: begin
299
        //send r ok or r err
300
//XXX: Watch out for PHY_READY
301
        //if CRC checks out OK then send an R_OK
302
        //if CRC does not check out then send an R_ERR
303
        //if (phy_ready) begin
304
          if (crc_ok) begin
305
            send_r_ok     <=  1;
306
            state         <=  SEND_STATUS;
307
          end
308
          else begin
309
            send_r_err    <=  1;
310
            state         <=  SEND_STATUS;
311
          end
312
        //end
313
      end
314
      SEND_STATUS: begin
315
        if (send_r_ok) begin
316
          send_r_ok       <=  1;
317
        end
318
        else begin
319
          send_r_err      <=  1;
320
        end
321
        if (detect_sync) begin
322
          state         <=  IDLE;
323
        end
324
      end
325
      default: begin
326
        state         <=  IDLE;
327
      end
328
    endcase
329
  end
330
end
331
endmodule

powered by: WebSVN 2.1.0

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