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 2

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

powered by: WebSVN 2.1.0

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