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

Subversion Repositories nysa_sata

[/] [nysa_sata/] [trunk/] [rtl/] [phy/] [oob_controller.v] - Diff between revs 2 and 3

Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 29... Line 29...
 
 
input               rst,              //reset
input               rst,              //reset
input               clk,
input               clk,
 
 
input               platform_ready,   //the underlying physical platform is
input               platform_ready,   //the underlying physical platform is
 
output  reg         platform_error,   //Underlyaing physal platform received an error, this should probably be a reset
output  reg         linkup,           //link is finished
output  reg         linkup,           //link is finished
 
 
output  reg         tx_comm_reset,     //send a init OOB signal
output  reg         tx_comm_reset,     //send a init OOB signal
output  reg         tx_comm_wake,     //send a wake OOB signal
output  reg         tx_comm_wake,     //send a wake OOB signal
 
input               tx_oob_complete,  //Phy has said we are finished with this OOB transaction
 
 
input               comm_init_detect, //detected an init
input               comm_init_detect, //detected an init
input               comm_wake_detect, //detected a wake on the rx lines
input               comm_wake_detect, //detected a wake on the rx lines
 
 
input       [31:0]  rx_din,
input       [31:0]  rx_din,
input       [3:0]   rx_isk,
input       [3:0]   rx_is_k,
input               rx_is_elec_idle,
input               rx_is_elec_idle,
input               rx_byte_is_aligned,
input               rx_byte_is_aligned,
 
input               phy_error,
 
 
output  reg [31:0]  tx_dout,
output  reg [31:0]  tx_dout,
output  reg         tx_isk,
output  reg         tx_is_k,
output  reg         tx_set_elec_idle,
output  reg         tx_set_elec_idle,
output      [3:0]   lax_state
output      [3:0]   lax_state
 
 
 
 
);
);
Line 63... Line 66...
parameter           WAIT_FOR_NO_INIT        = 4'h3;
parameter           WAIT_FOR_NO_INIT        = 4'h3;
parameter           WAIT_FOR_CONFIGURE_END  = 4'h4;
parameter           WAIT_FOR_CONFIGURE_END  = 4'h4;
parameter           SEND_WAKE               = 4'h5;
parameter           SEND_WAKE               = 4'h5;
parameter           WAIT_FOR_WAKE           = 4'h6;
parameter           WAIT_FOR_WAKE           = 4'h6;
parameter           WAIT_FOR_NO_WAKE        = 4'h7;
parameter           WAIT_FOR_NO_WAKE        = 4'h7;
parameter           WAIT_FOR_ALIGN          = 4'h8;
parameter           WAIT_FOR_IDLE           = 4'h8;
parameter           SEND_ALIGN              = 4'h9;
parameter           WAIT_FOR_ALIGN          = 4'h9;
parameter           DETECT_SYNC             = 4'hA;
parameter           SEND_ALIGN              = 4'hA;
parameter           READY                   = 4'hB;
parameter           DETECT_SYNC             = 4'hB;
 
parameter           READY                   = 4'hC;
 
 
//Registers/Wires
//Registers/Wires
reg         [3:0]   state;
reg         [3:0]   state;
reg         [31:0]  timer;
reg         [31:0]  timer;
reg         [1:0]   no_align_count;
reg         [1:0]   no_align_count;
 
reg         [3:0]   retries;
 
 
//timer used to send 'INITs', WAKEs' and read them
//timer used to send 'INITs', WAKEs' and read them
wire                timeout;
wire                timeout;
wire                align_detected;
wire                align_detected;
wire                sync_detected;
wire                sync_detected;
 
 
//Submodules
//Submodules
//Asynchronous Logic
//Asynchronous Logic
assign              timeout         = (timer == 0);
assign              timeout         = (timer == 0);
assign              align_detected  = ((rx_isk > 0) && (rx_din == `PRIM_ALIGN) && rx_byte_is_aligned);
//assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN) && !phy_error);
assign              sync_detected   = ((rx_isk > 0) && (rx_din == `PRIM_SYNC));
//assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN));
 
assign              align_detected  = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN) && rx_byte_is_aligned);
 
assign              sync_detected   = ((rx_is_k > 0) && (rx_din == `PRIM_SYNC));
assign              lax_state       = state;
assign              lax_state       = state;
 
 
//Synchronous Logic
//Synchronous Logic
initial begin
initial begin
  tx_set_elec_idle      <=  1;
  tx_set_elec_idle      <=  1;
Line 95... Line 102...
always @ (posedge clk) begin
always @ (posedge clk) begin
  if (rst) begin
  if (rst) begin
    state               <=  IDLE;
    state               <=  IDLE;
    linkup              <=  0;
    linkup              <=  0;
    timer               <=  0;
    timer               <=  0;
    tx_comm_reset       <=  1;
    tx_comm_reset       <=  0;
    tx_comm_wake        <=  0;
    tx_comm_wake        <=  0;
    tx_dout             <=  0;
    tx_dout             <=  0;
    tx_isk              <=  0;
    tx_is_k             <=  0;
    tx_set_elec_idle    <=  1;
    tx_set_elec_idle    <=  1;
    no_align_count      <=  0;
    no_align_count      <=  0;
 
    platform_error      <=  0;
 
    retries             <=  0;
  end
  end
  else begin
  else begin
    //to support strobes, continuously reset the following signals
    //to support strobes, continuously reset the following signals
    tx_comm_reset       <=  0;
    tx_comm_reset       <=  0;
    tx_comm_wake        <=  0;
    tx_comm_wake        <=  0;
 
 
    tx_isk              <=  0;
    tx_is_k             <=  0;
 
 
 
 
    //timer (when reache 0 timeout has occured)
    //timer (when reache 0 timeout has occured)
    if (timer > 0) begin
    if (timer > 0) begin
      timer                 <=  timer - 1;
      timer                 <=  timer - 1;
    end
    end
 
 
    //main state machine, if this reaches ready an initialization sequence has completed
    //main state machine, if this reaches ready an initialization sequence has completed
    case (state)
    case (state)
      IDLE: begin
      IDLE: begin
 
        platform_error      <=  0;
        linkup              <=  0;
        linkup              <=  0;
        tx_set_elec_idle    <=  1;
        tx_set_elec_idle    <=  1;
        if (platform_ready) begin
        if (platform_ready) begin
          $display ("oob_controller: send RESET");
          $display ("oob_controller: send RESET");
          //the platform is ready
          //the platform is ready
          //  PLL has locked onto a clock
          //  PLL has locked onto a clock
          //  DCM has generated the correct clocks
          //  DCM has generated the correct clocks
          timer             <=  32'h000000A2;
          timer             <=  32'h000000A2;
          state             <=  SEND_RESET;
          state             <=  SEND_RESET;
 
          tx_comm_reset     <=  1;
        end
        end
      end
      end
      SEND_RESET: begin
      SEND_RESET: begin
//XXX: In the groundhog COMM RESET was continuously issued for a long period of time
//XXX: In the groundhog COMM RESET was continuously issued for a long period of time
        //send the INIT sequence, this will initiate a communication with the
        //send the INIT sequence, this will initiate a communication with the
        //SATA hard drive, or reset it so that it can be initiated to state
        //SATA hard drive, or reset it so that it can be initiated to state
 
 
        //strobe the comm init so that the platform will send an INIT OOB signal
        //strobe the comm init so that the platform will send an INIT OOB signal
        tx_comm_reset       <=  1;
        if (timeout || tx_oob_complete) begin
        if (timeout) begin
          timer               <=  `INITIALIZE_TIMEOUT;
          timer               <=  32'd`INITIALIZE_TIMEOUT;
 
          state               <=  WAIT_FOR_INIT;
          state               <=  WAIT_FOR_INIT;
          $display ("oob_controller: wait for INIT");
          $display ("oob_controller: wait for INIT");
        end
        end
      end
      end
      WAIT_FOR_INIT: begin
      WAIT_FOR_INIT: begin
        //wait for a response from the SATA harddrive, if the timeout occurs
        //wait for a response from the SATA harddrive, if the timeout occurs
        //go back to the SEND_RESET state
        //go back to the SEND_RESET state
        if (comm_init_detect) begin
        if (comm_init_detect) begin
          //HD said 'sup' go to a wake
          //HD said 'sup' go to a wake
          timer             <=  0;
          //timer             <=  0;
 
          timer             <=  32'h00001000;
          state             <=  WAIT_FOR_NO_INIT;
          state             <=  WAIT_FOR_NO_INIT;
          $display ("oob_controller: wait for INIT to go low");
          $display ("oob_controller: wait for INIT to go low");
        end
        end
        if (timeout) begin
        if (timeout) begin
          $display ("oob_controller: timed out while waiting for INIT");
          $display ("oob_controller: timed out while waiting for INIT");
          state             <=  IDLE;
          state             <=  IDLE;
        end
        end
      end
      end
      WAIT_FOR_NO_INIT: begin
      WAIT_FOR_NO_INIT: begin
        //wait for the init signal to go low from the device
        //wait for the init signal to go low from the device
        if (!comm_init_detect) begin
        if (!comm_init_detect && (timeout || tx_oob_complete)) begin
          $display ("oob_controller: INIT deasserted");
          $display ("oob_controller: INIT deasserted");
          $display ("oob_controller: start configuration");
          $display ("oob_controller: start configuration");
          state             <=  WAIT_FOR_CONFIGURE_END;
          state             <=  WAIT_FOR_CONFIGURE_END;
        end
        end
      end
      end
      WAIT_FOR_CONFIGURE_END: begin
      WAIT_FOR_CONFIGURE_END: begin
          $display ("oob_controller: System is configured");
          $display ("oob_controller: System is configured");
          state             <=  SEND_WAKE;
          state             <=  SEND_WAKE;
          timer             <=  32'h0000009B;
          timer             <=  32'h0000009B;
 
          tx_comm_wake      <=  1;
        //end
        //end
      end
      end
      SEND_WAKE:  begin
      SEND_WAKE:  begin
//XXX: In the groundhog COMM WAKE was continuously send for a long period of time
//XXX: In the groundhog COMM WAKE was continuously send for a long period of time
        //Send the WAKE sequence to the hard drive to initiate a wakeup sequence
        //Send the WAKE sequence to the hard drive to initiate a wakeup sequence
        tx_comm_wake        <=  1;
 
//XXX: Is this timeout correct?
//XXX: Is this timeout correct?
        //880uS
        //880uS
        if (timeout) begin
        if (timeout || tx_oob_complete) begin
          //timer               <=  32'd`INITIALIZE_TIMEOUT;
          //timer               <=  32'd`INITIALIZE_TIMEOUT;
          timer               <=  32'h000203AD;
          timer               <=  32'h000203AD;
          state               <=  WAIT_FOR_WAKE;
          state               <=  WAIT_FOR_WAKE;
        end
        end
      end
      end
Line 204... Line 215...
//XXX: Is this timeout correct?
//XXX: Is this timeout correct?
          //880uS
          //880uS
          $display ("oob_controller: detected WAKE deasserted");
          $display ("oob_controller: detected WAKE deasserted");
          $display ("oob_controller: Send Dialtone, wait for ALIGN");
          $display ("oob_controller: Send Dialtone, wait for ALIGN");
//Going to add more timeout
//Going to add more timeout
          timer             <=  32'h203AD;
          //timer           <=  32'h0203AD;
 
          timer           <=  32'h0203AD;
          state             <=  WAIT_FOR_ALIGN;
          state             <=  WAIT_FOR_ALIGN;
 
          //state           <=  WAIT_FOR_IDLE;
 
          retries         <=  4;
        end
        end
      end
      end
 
      /*
 
      WAIT_FOR_IDLE: begin
 
        if (!rx_is_elec_idle) begin
 
          state           <=  WAIT_FOR_ALIGN;
 
          timer           <=  32'h0101D0;
 
        end
 
        else if (timeout) begin
 
          if (retries > 0) begin
 
            timer         <=  32'h0203AD;
 
            retries       <=  retries - 1;
 
          end
 
          if (retries == 0) begin
 
            state         <= IDLE;
 
          end
 
        end
 
      end
 
      */
      WAIT_FOR_ALIGN: begin
      WAIT_FOR_ALIGN: begin
        //transmit the 'dialtone' continuously
        //transmit the 'dialtone' continuously
        //since we need to start sending actual data (not OOB signals, get out
        //since we need to start sending actual data (not OOB signals, get out
        //  of tx idle)
        //  of tx idle)
        tx_set_elec_idle    <=  0;
        tx_set_elec_idle    <=  0;
        //a sequence of 0's and 1's
        //a sequence of 0's and 1's
        tx_dout             <=  `DIALTONE;
        tx_dout             <=  `DIALTONE;
        tx_isk              <=  0;
        tx_is_k             <=  0;
 
        //$display ("rx din: %h, k: %h", rx_din, rx_is_k);
        if (align_detected) begin
        if (align_detected) begin
          //we got something from the device!
          //we got something from the device!
          timer             <=  0;
          timer             <=  0;
          //now send an align from my side
          //now send an align from my side
          state             <=  SEND_ALIGN;
          state             <=  SEND_ALIGN;
Line 233... Line 265...
          state             <=  IDLE;
          state             <=  IDLE;
        end
        end
      end
      end
      SEND_ALIGN: begin
      SEND_ALIGN: begin
        tx_dout             <=  `PRIM_ALIGN;
        tx_dout             <=  `PRIM_ALIGN;
        tx_isk              <=  1;
        tx_is_k             <=  1;
        if (!align_detected) begin
        if (!align_detected) begin
          $display ("oob_controller: detected ALIGN deasserted");
          $display ("oob_controller: detected ALIGN deasserted");
//XXX: Groundhog detects the SYNC primitve before declaring linkup
//XXX: Groundhog detects the SYNC primitve before declaring linkup
          if (no_align_count == 3) begin
          if (no_align_count == 3) begin
            $display ("oob_controller: ready");
            $display ("oob_controller: ready");
            state           <=  READY;
            state           <=  READY;
          end
          end
          else begin
          else begin
            no_align_count  <=  no_align_count + 1;
            no_align_count  <=  no_align_count + 2'b01;
          end
          end
        end
        end
      end
      end
      DETECT_SYNC: begin
      DETECT_SYNC: begin
        if (sync_detected) begin
        if (sync_detected) begin
          state             <=  READY;
          state             <=  READY;
        end
        end
      end
      end
      READY:  begin
      READY:  begin
        linkup      <=  1;
        linkup      <=  1;
 
        /*
 
        if (phy_error) begin
 
          platform_error    <=  1;
 
        end
 
        */
        if (comm_init_detect) begin
        if (comm_init_detect) begin
          state             <=  IDLE;
          state             <=  IDLE;
        end
        end
      end
      end
      default: begin
      default: begin

powered by: WebSVN 2.1.0

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