40   For now both device and host shall be set up to SATA2 speeds.    41   Need to think how to change speed grades on fly (either to broaden     42   data iface width or to change RXRATE/TXRATE)    44 // All references to doc = to SerialATA_Revision_2_6_Gold.pdf    68     // output data stream to gtx    71     // input data from gtx    99 assign  align = {
8'b01111011, 
8'b01001010, 
8'b01001010, 
8'b10111100}; 
// {D27.3, D10.2, D10.2, K28.5}   100 assign  sync  = {
8'b10110101, 
8'b10110101, 
8'b10010101, 
8'b01111100}; 
// {D21.5, D21.5, D21.4, K28.3}   125 // buf inputs from gtx   144 assign  aligndet = ~|(
rxdata ^ {
8'b01111011, 
8'b01001010, 
8'b01001010, 
8'b10111100}) & ~|(
rxcharisk ^ 
4'h1); 
// {D27.3, D10.2, D10.2, K28.5}   145 assign  syncdet  = ~|(
rxdata ^ {
8'b10110101, 
8'b10110101, 
8'b10010101, 
8'b01111100}) & ~|(
rxcharisk ^ 
4'h1); 
// {D21.5, D21.5, D21.4, K28.3}   208             // txcomwake period = 213.333 ns times let's say 10 pulses => 2133.333 ns = 160 cycles of 75Mhz   347 // 873.8 us error timer   348 // = 2621400 SATA2 serial ticks (period = 0.000333 us)   349 // = 131070 ticks @ 150Mhz   350 // = 65535  ticks @ 75Mhz    351 localparam  [19:0]  CLK_TO_TIMER_CONTRIB = CLK_SPEED_GRADE == 1 ? 20'h4 :   352                                            CLK_SPEED_GRADE == 2 ? 20'h2 :   353                                            CLK_SPEED_GRADE == 4 ? 20'h1 : 20'h1;   355 localparam  [19:0]  TIMER_LIMIT = 19'd200;   357 localparam  [19:0]  TIMER_LIMIT = 19'd262140;   363 // latching inputs from gtx   367 reg     [DATA_BYTE_WIDTH*8 - 1:0] rxdata;   368 reg     [DATA_BYTE_WIDTH - 1:0]   rxcharisk;   370 // primitives detection   371 wire    detected_alignp;   376 reg     state_wait_cominit;   377 reg     state_wait_comwake;   378 reg     state_wait_align;   380 reg     state_wait_linkup;   383 wire    set_wait_cominit;   384 wire    set_wait_comwake;   387 wire    set_wait_linkup;   389 wire    clr_wait_cominit;   390 wire    clr_wait_comwake;   393 wire    clr_wait_linkup;   396 assign  state_idle = ~state_wait_cominit & ~state_wait_comwake & ~state_wait_align & ~state_wait_synp & ~state_wait_linkup & ~state_error;   397 always @ (posedge clk)   399     state_wait_cominit  <= (state_wait_cominit | set_wait_cominit) & ~clr_wait_cominit & ~rst;   400     state_wait_comwake  <= (state_wait_comwake | set_wait_comwake) & ~clr_wait_comwake & ~rst;   401     state_wait_align    <= (state_wait_align   | set_wait_align  ) & ~clr_wait_align   & ~rst;   402     state_wait_synp     <= (state_wait_synp    | set_wait_synp   ) & ~clr_wait_synp    & ~rst;   403     state_wait_linkup   <= (state_wait_linkup  | set_wait_linkup ) & ~clr_wait_linkup  & ~rst;   404     state_error         <= (state_error        | set_error       ) & ~clr_error        & ~rst;   407 assign  set_wait_cominit = state_idle & oob_start & ~cominit_req;   408 assign  set_wait_comwake = state_idle & cominit_req & cominit_allow | state_wait_cominit & rxcominitdet;   409 assign  set_wait_align   = state_wait_comwake & rxcomwakedet;   410 assign  set_wait_synp    = state_wait_align & detected_alignp;   411 assign  set_wait_linkup  = state_wait_synp & detected_syncp;   412 assign  set_error        = timer_fin & (state_wait_cominit | state_wait_comwake | state_wait_align | state_wait_synp);   413 assign  clr_wait_cominit = set_wait_comwake | set_error;   414 assign  clr_wait_comwake = set_wait_align | set_error;   415 assign  clr_wait_align   = set_wait_synp | set_error;   416 assign  clr_wait_synp    = set_wait_linkup | set_error;   417 assign  clr_wait_linkup  = state_wait_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives   418 assign  clr_error        = state_error;   420 // waiting timeout timer   421 assign  timer_fin = timer == TIMER_LIMIT;   422 assign  timer_clr = set_error | state_error | state_idle;   423 always @ (posedge clk)   424     timer <= rst | timer_clr ? 20'h0 : timer + CLK_TO_TIMER_CONTRIB;   426 // something is wrong with speed grades if the host cannot lock to device's alignp stream   427 assign  oob_incompatible = state_wait_align & set_error;   429 // oob sequence is done, everything is okay   430 assign  oob_done = set_wait_linkup;   432 // noone responds to cominits   433 assign  oob_silence = set_error & state_wait_cominit;   436 assign  oob_error = set_error & ~oob_silence & ~oob_incompatible;   439 assign  oob_busy = ~state_idle;   443 always @ (posedge clk)   444     txelecidle_r <= rst ? 1'b1 : clr_wait_cominit ? 1'b0 : set_wait_cominit ? 1'b1 : txelecidle_r;   446 assign  txcominit  = set_wait_cominit;   447 assign  txcomwake  = set_wait_comwake;   448 assign  txelecidle = set_wait_cominit | txelecidle_r;   450 // indicate if link up condition was made   451 assign  link_up = clr_wait_linkup;   453 // link goes down when line is idle   456 always @ (posedge clk)   458     rxelecidle_rr   <= rxelecidle_r;   459     rxelecidle_r    <= rxelecidle;   462 assign  link_down = rxelecidle_rr;   464 // indicate that device is requesting for oob   466 wire    cominit_req_set;   468 assign  cominit_req_set = state_idle & rxcominitdet;   469 always @ (posedge clk)   470     cominit_req_r <= (cominit_req_r | cominit_req_set) & ~(cominit_allow & cominit_req) & ~rst;   471 assign  cominit_req = cominit_req_set | cominit_req_r;   473 // detect which primitives sends the device after comwake was done   475     if (DATA_BYTE_WIDTH == 2)   477         reg detected_alignp_f;   478         always @ (posedge clk)   479             detected_alignp_f <= rst | ~state_wait_align ? 1'b0 :    480                                  ~|(rxdata ^ {8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 2'b01); // {D10.2, K28.5}   481         assign detected_alignp = detected_alignp_f & ~|(rxdata ^ {8'b01111011, 8'b01001010}) & ~|(rxcharisk ^ 2'b00); // {D27.3, D10.2}   483         reg detected_syncp_f;   484         always @ (posedge clk)   485             detected_syncp_f <= rst | ~state_wait_synp ? 1'b0 :    486                                 ~|(rxdata ^ {8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 2'b01); // {D21.4, K28.3}   487         assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {8'b10110101, 8'b10110101}) & ~|(rxcharisk ^ 2'b00); // {D21.5, D21.5}   490     if (DATA_BYTE_WIDTH == 4)   492         assign detected_alignp = ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}   493         assign detected_syncp  = ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}   496     if (DATA_BYTE_WIDTH == 8)   498         assign detected_alignp = ~|(rxdata ^ {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}) & ~|(rxcharisk ^ 8'h11); // {D27.3, D10.2, D10.2, K28.5}   499         assign detected_syncp  = ~|(rxdata ^ {2{8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}}) & ~|(rxcharisk ^ 8'h11); // {D21.5, D21.5, D21.4, K28.3}   503         always @ (posedge clk)   505             $display("%m oob module works only with 16/32/64 gtx input data width");   511 // buf inputs from gtx   512 always @ (posedge clk)   514     rxcominitdet <= rxcominitdet_in;   515     rxcomwakedet <= rxcomwakedet_in;   516     rxelecidle   <= rxelecidle_in;   518     rxcharisk    <= rxcharisk_in;   521 // set data outputs to upper levels   522 assign  rxdata_out    = rxdata;   523 assign  rxcharisk_out = rxcharisk;   525 // as depicted @ doc, p264, figure 163, have to insert D10.2 and align primitives after   526 // getting comwake from device   527 reg     [DATA_BYTE_WIDTH*8 - 1:0] txdata;   528 reg     [DATA_BYTE_WIDTH - 1:0]   txcharisk;   529 wire    [DATA_BYTE_WIDTH*8 - 1:0] txdata_d102;   530 wire    [DATA_BYTE_WIDTH - 1:0]   txcharisk_d102;   531 wire    [DATA_BYTE_WIDTH*8 - 1:0] txdata_align;   532 wire    [DATA_BYTE_WIDTH - 1:0]   txcharisk_align;   534 always @ (posedge clk)   536     txdata      <= state_wait_align ? txdata_d102 :   537                    state_wait_synp  ? txdata_align : txdata_in;   538     txcharisk   <= state_wait_align ? txcharisk_d102 :   539                    state_wait_synp  ? txcharisk_align : txcharisk_in;   542 // Continious D10.2 primitive   543 assign  txcharisk_d102  = {DATA_BYTE_WIDTH{1'b0}};   544 assign  txdata_d102     = {DATA_BYTE_WIDTH{8'b01001010}};   546 // Align primitive: K28.5 + D10.2 + D10.2 + D27.3   548     if (DATA_BYTE_WIDTH == 2)   551         always @ (posedge clk)   552             align_odd <= rst | ~state_wait_synp ? 1'b0 : ~align_odd;   554         assign txcharisk_align  = align_odd ? 2'b01 : 2'b00;   555         assign txdata_align     = align_odd ? {8'b01001010, 8'b10111100} : // {D10.2, K28.5}   556                                               {8'b01111011, 8'b01001010}; // {D27.3, D10.2}   559     if (DATA_BYTE_WIDTH == 4)   561         assign txcharisk_align  = 4'h1;   562         assign txdata_align     = {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}; // {D27.3, D10.2, D10.2, K28.5}   565     if (DATA_BYTE_WIDTH == 8)   567         assign txcharisk_align  = 8'h11;   568         assign txdata_align     = {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}; // 2x{D27.3, D10.2, D10.2, K28.5}   571         always @ (posedge clk)   573             $display("%m oob module works only with 16/32/64 gtx input data width");   578 // set data outputs to gtx   579 assign  txdata_out    = txdata;   580 assign  txcharisk_out = txcharisk; wire [DATA_BYTE_WIDTH - 1:0] 14386rxcharisk_in
14403wait_interval_elapsedwire
14391STATE_AWAITNOCOMWAKE3
14408retry_timerreg[31:0]
wire [DATA_BYTE_WIDTH*8 - 1:0] 14383txdata_out
wire [DATA_BYTE_WIDTH - 1:0] 14384txcharisk_out
wire [DATA_BYTE_WIDTH*8 - 1:0] 14385rxdata_in
14402retry_interval_elapsedwire
wire 14376rxcomwakedet_in
14407nocomwake_timerreg[31:0]
14417txelecidle_cntreg[9:0]
wire 14375rxcominitdet_in