// ===========================================================
// FindPattern:  Uses verilog code developed in the Textbook
// to search for and identify the frame pattern to be used
// in the SerDes design.
//
// For simplicity, a fixed 64-bit vector is searched for the
// pattern, rather than a real-time serial stream.
// The vector is initialized and then kept constant.
//
// ------------------------------------------------------------
// 2013-08-01 jmw: v. 1.0 Rewrote v. 1.6 of original 
//            FindPatternBeh.v to implement Text Sect. 8.1.2
//            "Function for Synthesizable PLL Sync".
//            The original Lab11 implementation apparently has
//            been lost.
// ============================================================
//
`timescale 1ns/100ps
//
module FindPattern ( output Found, input StartSearch );
  //
  // If there's time, try changing this:
  reg[63:0] VecHi =
/*    The numbers in this comment help identify bits in this vector:
 *     'a'     pad 3     'b'      pad 2    'y'      pad 1    'z'      pad 0
 *    60         50         40          30         20         10          0
 *  32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 */
64'b01100001_00011000_01100010_00010000_01111001_00001000_01111010_00000000;
  integer PadHi  =  7;
  integer PadWid =  8;
  integer AdrHi  = 63;
  integer OffSet = 63;  // Just 64 bits in above testcase stream.
  // The 4 x 8 = 32 bits predefined pad-bytes:
  localparam pad_00 = 8'b000_00_000;
  localparam pad_01 = 8'b000_01_000;
  localparam pad_10 = 8'b000_10_000;
  localparam pad_11 = 8'b000_11_000;
  //
  // The function, as in Section 8.1.2 of the Textbook:
  //
  function
  checkPad (input[63:0] Stream, input[7:0] pad, input[63:0] iX);
    reg OK;     // Flags pattern match
    integer i   // i is the data stream offset.
          , j;  // j is the pad-byte pattern offsed.
    begin
    i = iX;     // Init to stream MSB to be searched.
    OK = 0;     // Init to failed state.
    begin : For  // Capitalized, this is NOT a verilog keyword.
    for (j = PadHi; j >= 0; j = j - 1)
      begin
      if (Stream[i] == pad[j])
           OK = 1;
      else begin
           OK = 0;
           disable For; // Capitalized: break the for loop.
           end
      i = i - 1;
      end // for loop.
    end // For.
    checkPad = OK;
  end
  endfunction
  //
  reg FoundPads;  // Flags successful find of 64-bit frame padding.
  assign #1 Found = FoundPads;
  //
  always @ (posedge StartSearch)
     if (   checkPad( VecHi, pad_11, OffSet - (1*PadWid) )
         && checkPad( VecHi, pad_10, OffSet - (3*PadWid) )
         && checkPad( VecHi, pad_01, OffSet - (5*PadWid) )
         && checkPad( VecHi, pad_00, OffSet - (7*PadWid) )
        ) FoundPads = 1;
     else FoundPads = 0;
  //
  //
endmodule // FindPattern.
//
`ifdef DC
`else
module FindPatternTst;
  //
  reg StartSearchStim;
  wire FoundWatch;
  //
  initial
    begin
    #0   StartSearchStim = 1'b0;
    #5   StartSearchStim = 1'b1;
    #100 StartSearchStim = 1'b0;
    #5   StartSearchStim = 1'b1;
    #100 $finish;
    end
  //
  FindPattern FindPatternInst1( .Found(FoundWatch), .StartSearch(StartSearchStim) );
  //
endmodule //FindPatternTst.
`endif
