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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [rtl/] [phy/] [oob_controller.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cospan
//oob_controller.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 oob_controller (
29
 
30
input               rst,              //reset
31
input               clk,
32
 
33
input               platform_ready,   //the underlying physical platform is
34 3 cospan
output  reg         platform_error,   //Underlyaing physal platform received an error, this should probably be a reset
35 2 cospan
output  reg         linkup,           //link is finished
36
 
37
output  reg         tx_comm_reset,     //send a init OOB signal
38
output  reg         tx_comm_wake,     //send a wake OOB signal
39 3 cospan
input               tx_oob_complete,  //Phy has said we are finished with this OOB transaction
40 2 cospan
 
41
input               comm_init_detect, //detected an init
42
input               comm_wake_detect, //detected a wake on the rx lines
43
 
44
input       [31:0]  rx_din,
45 3 cospan
input       [3:0]   rx_is_k,
46 2 cospan
input               rx_is_elec_idle,
47
input               rx_byte_is_aligned,
48 3 cospan
input               phy_error,
49 2 cospan
 
50
output  reg [31:0]  tx_dout,
51 3 cospan
output  reg         tx_is_k,
52 2 cospan
output  reg         tx_set_elec_idle,
53
output      [3:0]   lax_state
54
 
55
 
56
);
57
 
58
//platform signals
59
 
60
//Parameters
61
 
62
//States
63
parameter           IDLE                    = 4'h0;
64
parameter           SEND_RESET              = 4'h1;
65
parameter           WAIT_FOR_INIT           = 4'h2;
66
parameter           WAIT_FOR_NO_INIT        = 4'h3;
67
parameter           WAIT_FOR_CONFIGURE_END  = 4'h4;
68
parameter           SEND_WAKE               = 4'h5;
69
parameter           WAIT_FOR_WAKE           = 4'h6;
70
parameter           WAIT_FOR_NO_WAKE        = 4'h7;
71 3 cospan
parameter           WAIT_FOR_IDLE           = 4'h8;
72
parameter           WAIT_FOR_ALIGN          = 4'h9;
73
parameter           SEND_ALIGN              = 4'hA;
74
parameter           DETECT_SYNC             = 4'hB;
75
parameter           READY                   = 4'hC;
76 2 cospan
 
77
//Registers/Wires
78
reg         [3:0]   state;
79
reg         [31:0]  timer;
80
reg         [1:0]   no_align_count;
81 3 cospan
reg         [3:0]   retries;
82 2 cospan
 
83
//timer used to send 'INITs', WAKEs' and read them
84
wire                timeout;
85
wire                align_detected;
86
wire                sync_detected;
87
 
88
//Submodules
89
//Asynchronous Logic
90
assign              timeout         = (timer == 0);
91 3 cospan
//assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN) && !phy_error);
92
//assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN));
93
assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN) && rx_byte_is_aligned);
94
assign              sync_detected   = ((rx_is_k > 0) && (rx_din == `PRIM_SYNC));
95 2 cospan
assign              lax_state       = state;
96
 
97
//Synchronous Logic
98
initial begin
99
  tx_set_elec_idle      <=  1;
100
end
101
 
102
always @ (posedge clk) begin
103
  if (rst) begin
104
    state               <=  IDLE;
105
    linkup              <=  0;
106
    timer               <=  0;
107 3 cospan
    tx_comm_reset       <=  0;
108 2 cospan
    tx_comm_wake        <=  0;
109
    tx_dout             <=  0;
110 3 cospan
    tx_is_k             <=  0;
111 2 cospan
    tx_set_elec_idle    <=  1;
112
    no_align_count      <=  0;
113 3 cospan
    platform_error      <=  0;
114
    retries             <=  0;
115 2 cospan
  end
116
  else begin
117
    //to support strobes, continuously reset the following signals
118
    tx_comm_reset       <=  0;
119
    tx_comm_wake        <=  0;
120
 
121 3 cospan
    tx_is_k             <=  0;
122 2 cospan
 
123
 
124
    //timer (when reache 0 timeout has occured)
125
    if (timer > 0) begin
126
      timer                 <=  timer - 1;
127
    end
128
 
129
    //main state machine, if this reaches ready an initialization sequence has completed
130
    case (state)
131
      IDLE: begin
132 3 cospan
        platform_error      <=  0;
133 2 cospan
        linkup              <=  0;
134
        tx_set_elec_idle    <=  1;
135
        if (platform_ready) begin
136
          $display ("oob_controller: send RESET");
137
          //the platform is ready
138
          //  PLL has locked onto a clock
139
          //  DCM has generated the correct clocks
140
          timer             <=  32'h000000A2;
141
          state             <=  SEND_RESET;
142 3 cospan
          tx_comm_reset     <=  1;
143 2 cospan
        end
144
      end
145
      SEND_RESET: begin
146
//XXX: In the groundhog COMM RESET was continuously issued for a long period of time
147
        //send the INIT sequence, this will initiate a communication with the
148
        //SATA hard drive, or reset it so that it can be initiated to state
149
 
150
        //strobe the comm init so that the platform will send an INIT OOB signal
151 3 cospan
        if (timeout || tx_oob_complete) begin
152
          timer               <=  `INITIALIZE_TIMEOUT;
153 2 cospan
          state               <=  WAIT_FOR_INIT;
154
          $display ("oob_controller: wait for INIT");
155
        end
156
      end
157
      WAIT_FOR_INIT: begin
158
        //wait for a response from the SATA harddrive, if the timeout occurs
159
        //go back to the SEND_RESET state
160
        if (comm_init_detect) begin
161
          //HD said 'sup' go to a wake
162 3 cospan
          //timer             <=  0;
163
          timer             <=  32'h00001000;
164 2 cospan
          state             <=  WAIT_FOR_NO_INIT;
165
          $display ("oob_controller: wait for INIT to go low");
166
        end
167
        if (timeout) begin
168
          $display ("oob_controller: timed out while waiting for INIT");
169
          state             <=  IDLE;
170
        end
171
      end
172
      WAIT_FOR_NO_INIT: begin
173
        //wait for the init signal to go low from the device
174 3 cospan
        if (!comm_init_detect && (timeout || tx_oob_complete)) begin
175 2 cospan
          $display ("oob_controller: INIT deasserted");
176
          $display ("oob_controller: start configuration");
177
          state             <=  WAIT_FOR_CONFIGURE_END;
178
        end
179
      end
180
      WAIT_FOR_CONFIGURE_END: begin
181
          $display ("oob_controller: System is configured");
182
          state             <=  SEND_WAKE;
183
          timer             <=  32'h0000009B;
184 3 cospan
          tx_comm_wake      <=  1;
185 2 cospan
        //end
186
      end
187
      SEND_WAKE:  begin
188
//XXX: In the groundhog COMM WAKE was continuously send for a long period of time
189
        //Send the WAKE sequence to the hard drive to initiate a wakeup sequence
190
//XXX: Is this timeout correct?
191
        //880uS
192 3 cospan
        if (timeout || tx_oob_complete) begin
193 2 cospan
          //timer               <=  32'd`INITIALIZE_TIMEOUT;
194
          timer               <=  32'h000203AD;
195
          state               <=  WAIT_FOR_WAKE;
196
        end
197
      end
198
      WAIT_FOR_WAKE:  begin
199
        //Wait for the device to send a COMM Wake
200
        if (comm_wake_detect) begin
201
          //Found a comm wake, now wait for the device to stop sending WAKE
202
          timer             <=  0;
203
          state             <=  WAIT_FOR_NO_WAKE;
204
          $display ("oob_controller: WAKE detected");
205
        end
206
        if (timeout) begin
207
          //Timeout occured before reading WAKE
208
          state             <=  IDLE;
209
          $display ("oob_controller: timed out while waiting for WAKE to be asserted");
210
        end
211
      end
212
      WAIT_FOR_NO_WAKE: begin
213
        if (!comm_wake_detect) begin
214
          //The device stopped sending comm wake
215
//XXX: Is this timeout correct?
216
          //880uS
217
          $display ("oob_controller: detected WAKE deasserted");
218
          $display ("oob_controller: Send Dialtone, wait for ALIGN");
219
//Going to add more timeout
220 3 cospan
          //timer           <=  32'h0203AD;
221
          timer           <=  32'h0203AD;
222
          state           <=  WAIT_FOR_ALIGN;
223
          //state           <=  WAIT_FOR_IDLE;
224
          retries         <=  4;
225 2 cospan
        end
226
      end
227 3 cospan
      /*
228
      WAIT_FOR_IDLE: begin
229
        if (!rx_is_elec_idle) begin
230
          state           <=  WAIT_FOR_ALIGN;
231
          timer           <=  32'h0101D0;
232
        end
233
        else if (timeout) begin
234
          if (retries > 0) begin
235
            timer         <=  32'h0203AD;
236
            retries       <=  retries - 1;
237
          end
238
          if (retries == 0) begin
239
            state         <= IDLE;
240
          end
241
        end
242
      end
243
      */
244 2 cospan
      WAIT_FOR_ALIGN: begin
245
        //transmit the 'dialtone' continuously
246
        //since we need to start sending actual data (not OOB signals, get out
247
        //  of tx idle)
248
        tx_set_elec_idle    <=  0;
249
        //a sequence of 0's and 1's
250
        tx_dout             <=  `DIALTONE;
251 3 cospan
        tx_is_k             <=  0;
252
        //$display ("rx din: %h, k: %h", rx_din, rx_is_k);
253 2 cospan
        if (align_detected) begin
254
          //we got something from the device!
255
          timer             <=  0;
256
          //now send an align from my side
257
          state             <=  SEND_ALIGN;
258
          no_align_count    <=  0;
259
          $display ("oob_controller: ALIGN detected");
260
          $display ("oob_controller: Send out my ALIGNs");
261
        end
262
        if (timeout) begin
263
          //didn't read an align in time :( reset
264
          $display ("oob_controller: timed out while waiting for AIGN");
265
          state             <=  IDLE;
266
        end
267
      end
268
      SEND_ALIGN: begin
269
        tx_dout             <=  `PRIM_ALIGN;
270 3 cospan
        tx_is_k             <=  1;
271 2 cospan
        if (!align_detected) begin
272
          $display ("oob_controller: detected ALIGN deasserted");
273
//XXX: Groundhog detects the SYNC primitve before declaring linkup
274
          if (no_align_count == 3) begin
275
            $display ("oob_controller: ready");
276
            state           <=  READY;
277
          end
278
          else begin
279 3 cospan
            no_align_count  <=  no_align_count + 2'b01;
280 2 cospan
          end
281
        end
282
      end
283
      DETECT_SYNC: begin
284
        if (sync_detected) begin
285
          state             <=  READY;
286
        end
287
      end
288
      READY:  begin
289 3 cospan
        linkup              <=  1;
290
        /*
291
        if (phy_error) begin
292
          platform_error    <=  1;
293
        end
294
        */
295 2 cospan
        if (comm_init_detect) begin
296
          state             <=  IDLE;
297
        end
298
      end
299
      default: begin
300 3 cospan
        state               <=  IDLE;
301 2 cospan
      end
302
    endcase
303
 
304
  end
305
end
306
 
307
endmodule
308
 

powered by: WebSVN 2.1.0

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