// Chuck Benz, Hollis, NH   Copyright (c)2005
// http://asics.chuckbenz.com
//
// The information and description contained herein is the
// property of Chuck Benz.
//
// This information may only be used under license from
// Chuck Benz Asic & FPGA Design, or it's assignees.  Any 
// other use or modification is prohibited
//
// $Id: sit_ver_x4_cdr.v,v 1.2 2005/07/27 15:15:53 cbenz Exp cbenz $
//

/* sit_ver_x4.v - this is the verilog module encapsulating the
 * simulation interconnection technology - connecting to another
 * simulation on another system. This verilog module uses Verilog-2001
 * file IO with named pipes to communicate with a separate process
 * running on this system. That process opens a socket to the other
 * simulation, either directly or through a sit server.

 * This 22-Jul-05 version is the first attempt to track varying clocks,
 * actually doing so independently on each lane of serial data.
 * For each lane, in a 80 bit sample time, we will report on how
 * many times we moved the clock by "delta" and whether or not that
 * resulted in one extra or one less sample of data.

 * For x4 module, we'll use a different data type (6), and do all 
 * nibbles from link 0, then all from link 1, then all from link 2...
 * instead of 20 nibbles of data, we'll have 80, so we'll use 100 byte packets.

 */

`timescale 1ns / 10ps

module sit_ver_x4_cdr (tdata, rdata) ;

  input  [3:0] tdata ;
  output [3:0] rdata ;
  reg    [3:0] rdata ;

  parameter bit_period = 0.40 ;
  parameter delta = 0.01 ;
  parameter half_link_delay = 80 ; // how many bits we'll pack into a packet.
				// which is also half the link latency...
  parameter ifile="sit_pipei" ;
  parameter ofile="sit_pipeo" ;
  parameter filename_from_param_only = 0 ;

  integer  fd_i, fd_o ;
  integer  len_in ;
  reg [8*100-1:0] rcvbuf ;
  reg [8*64:1] filename ;
  reg [8*65:1] ifilename ;
  reg [8*65:1] ofilename ;

  reg    tclk, rclk0, rclk1, rclk2, rclk3 ;
  reg [half_link_delay:0] tx_data, tx_data_sent ;
  reg [half_link_delay:0] tx_dat[0:3] ;
  reg [half_link_delay:0] rx_data ;
  reg [half_link_delay:0] rx_dat1[0:3] ;
  reg [half_link_delay:0] rx_dat2[0:3] ;
  reg [7:0] tx_cntr, tx_cntr0, tx_cntr1, tx_cntr2, tx_cntr3 ;
  reg [1:0] rx_ptr, rx_flag, tx_flag ;
  reg [3:0] rxdatflags ;
  reg [9:0] rx_adj1 [0:3] ;
  reg [9:0] rx_adj2_0, rx_adj2_1, rx_adj2_2, rx_adj2_3 ;
  reg [9:0] rx_cntr0, rx_cntr1, rx_cntr2, rx_cntr3 ;
  reg [9:0] rx_cntr_lim1 [0:3] ;
  reg [9:0] rx_cntr_lim2 [0:3] ;
  reg [7:0] rx_interval_adj [0:3] ;

  integer i, i1 ;
  reg [7:0] tmpdata ;
  reg [15:0] tmpdata2 ;
  integer rx_block ;
  reg [31:0] expect ;
  reg       eof_ifile = 0 ;

  wire tclk0, tclk1, tclk2, tclk3 ;
  wire [3:0] tdata_cdr, spedup, slowed ;
  reg [3:0]  en_adj = 0 ;
  reg [9:0]  num_adj0, num_adj1, num_adj2, num_adj3;
reg rclk0_adj = 0 ;

  sit_cdr tcdr0 (.din(tdata[0]), .rdata(tdata_cdr[0]), .rclk(tclk0),
		 .spedup(spedup[0]), .slowed(slowed[0]), .en_adj(en_adj[0])) ;
  sit_cdr tcdr1 (.din(tdata[1]), .rdata(tdata_cdr[1]), .rclk(tclk1),
		 .spedup(spedup[1]), .slowed(slowed[1]), .en_adj(en_adj[1])) ;
  sit_cdr tcdr2 (.din(tdata[2]), .rdata(tdata_cdr[2]), .rclk(tclk2),
		 .spedup(spedup[2]), .slowed(slowed[2]), .en_adj(en_adj[2])) ;
  sit_cdr tcdr3 (.din(tdata[3]), .rdata(tdata_cdr[3]), .rclk(tclk3),
		 .spedup(spedup[3]), .slowed(slowed[3]), .en_adj(en_adj[3])) ;
  defparam tcdr0.half_clk = bit_period / 2 ;
  defparam tcdr1.half_clk = bit_period / 2 ;
  defparam tcdr2.half_clk = bit_period / 2 ;
  defparam tcdr3.half_clk = bit_period / 2 ;
  defparam tcdr0.delta = delta ;
  defparam tcdr1.delta = delta ;
  defparam tcdr2.delta = delta ;
  defparam tcdr3.delta = delta ;

  /* Format for data, by bytes:
   * 1 - header flag (rotates through values of C/B/A/F)
   * 2 - type: 7 for this data packet
   * 3 - length in DW of data, / 4 (includes real data only, not time info)
   * 4 - rsvd
   * 5-12 - 2 bytes per link (0-3) for time adjustments, bytes 5/6 for link 0:
   *    bits 11:10:
   *       00 - N samples
   *       01 - N-1 samples
   *       10 - N+1 samples, extra is 0
   *       11 - N+1 samples, extra is 1
   *    bits 9:0 - signed # of clock adjustments, -512 to 511
   *      (but actual # of slips will be limited to just under 1 bit time)
   * 13-32 - link0 data - each byte represents a nibble
   *    of serial data encoded as values 0x30-0x41 - 0x40 being Z, 0x41 as X.
   *    (X and Z get spread to full nibble).
   * 33-52 - link1 data
   * 53-72 - link2 data
   * 73-92 - link3 data
   * 100 - a \n to finish the packet.
   *
   * we're using 80 bits per packet, so it will look like:
   *
C65 ........@@?5=4751:3256<5:::::::::::::::::::::::::>0;=4751:3256<5::::::::::::::::::::::::       
B65 ........::::::::::::::::::::@@?5=4751:3256<5::::@@?5=4751:3256<5::::@@?5=4751:3256<5::::       
A65 ........:>0;=4751:3256<5::::....
   */

/*
 * 1. Accumulate serial data based on tclk0-tclk3 sampling.
 * 2. count number of adjustments. If we reach (bit_period-3*delta)/delta,
 *    then don't allow any more adjustments in this "packet interval"
 * 3. When we reach nominal "half_link_delay" (based on ideal clock), take data
 *    and send data. Some links may (eventually) be ahead/behind by 1 bit time.
 * 
 * 4. receive data when any link thinks it needs more.
 * 5. spread out needed adjustments by interval = (half_link_delay) / num_adj
 *    (interval being a truncated integer), with 1st adjustment immediately.
*/

  task send_data ;
  begin
    case (tx_flag)
	0: $fwrite (fd_o, "C7") ;
	1: $fwrite (fd_o, "B7") ;
	2: $fwrite (fd_o, "A7") ;
	3: $fwrite (fd_o, "F7") ;
    endcase
    tx_flag = tx_flag + 1 ;
    tmpdata = half_link_delay/16 + 8'h30 ;
    $fwrite (fd_o, "%s ", tmpdata) ;
    /* calculate clock adj bytes... */

    if (tx_cntr0 == half_link_delay)
	tmpdata2 = num_adj0 ;
    else if (tx_cntr0 == (half_link_delay-1))
	tmpdata2 = num_adj0 | 12'h400 ;
    else if (tx_cntr0 == (half_link_delay+1))
	tmpdata2 = (num_adj0 | 12'h800 |
		    ((tx_dat[0] >> (half_link_delay - 10)) & 12'h400)) ;
    else $display ($stime, " link0 something is wrong: report to developer");
    tmpdata2[13:6] = tmpdata2[11:6] << 2 ;
    tmpdata2 = tmpdata2 + 16'h3030 ;
    $fwrite (fd_o, "%s", tmpdata2) ;

    if (tx_cntr1 == half_link_delay)
	tmpdata2 = num_adj1 ;
    else if (tx_cntr1 == (half_link_delay-1))
	tmpdata2 = num_adj1 | 12'h400 ;
    else if (tx_cntr1 == (half_link_delay+1))
	tmpdata2 = (num_adj1 | 12'h800 |
		    ((tx_dat[1] >> (half_link_delay - 10)) & 12'h400)) ;
    else $display ($stime, " link1 something is wrong: report to developer");
    tmpdata2[13:6] = tmpdata2[11:6] << 2 ;
    tmpdata2 = tmpdata2 + 16'h3030 ;
    $fwrite (fd_o, "%s", tmpdata2) ;

    if (tx_cntr2 == half_link_delay)
	tmpdata2 = num_adj2 ;
    else if (tx_cntr2 == (half_link_delay-1))
	tmpdata2 = num_adj2 | 12'h400 ;
    else if (tx_cntr2 == (half_link_delay+1))
	tmpdata2 = (num_adj2 | 12'h800 |
		    ((tx_dat[2] >> (half_link_delay - 10)) & 12'h400)) ;
    else $display ($stime, " link2 something is wrong: report to developer");
    tmpdata2[13:6] = tmpdata2[11:6] << 2 ;
    tmpdata2 = tmpdata2 + 16'h3030 ;
    $fwrite (fd_o, "%s", tmpdata2) ;

    if (tx_cntr3 == half_link_delay)
	tmpdata2 = num_adj3 ;
    else if (tx_cntr3 == (half_link_delay-1))
	tmpdata2 = num_adj3 | 12'h400 ;
    else if (tx_cntr3 == (half_link_delay+1))
	tmpdata2 = (num_adj3 | 12'h800 |
		    ((tx_dat[3] >> (half_link_delay - 10)) & 12'h400)) ;
    else $display ($stime, " link3 something is wrong: report to developer");
    tmpdata2[13:6] = tmpdata2[11:6] << 2 ;
    tmpdata2 = tmpdata2 + 16'h3030 ;
    $fwrite (fd_o, "%s", tmpdata2) ;

    num_adj0 = 0 ;
    num_adj1 = 0 ;
    num_adj2 = 0 ;
    num_adj3 = 0 ;
    tx_cntr0 = 0 ;
    tx_cntr1 = 0 ;
    tx_cntr2 = 0 ;
    tx_cntr3 = 0 ;

    tmpdata = 0 ;
    tx_data_sent = tx_dat[0] ;
    for (i1=0; i1<4 ; i1=i1+1) begin
      tx_data = tx_dat[i1] ;
      for (i=0; i<half_link_delay; i=i+1) begin
	if ((tmpdata < 16) && (tx_data[i] === 0))
	  tmpdata = tmpdata << 1 ;
	else if ((tmpdata < 16) && (tx_data[i] === 1))
	  tmpdata = (tmpdata << 1) | 1 ;
	else if ((tmpdata != 16) && (tx_data[i] === 1'bz))
	  tmpdata = 17 ;
	else if (tx_data[i] === 1'bx)
	  tmpdata = 16 ;
	if (3 == (i & 3)) begin
	  tmpdata = tmpdata + 48 ;
	  $fwrite (fd_o, "%s", tmpdata) ;
	  tmpdata = 0 ;
	end
      end
      tx_dat[i1] = 0 ;
    end  // end of for loop
    /* we've written 12+ half_link_delay) bytes, fill in the remainder */
    $fwrite (fd_o, "    ");
    $fwrite (fd_o, "   \n");
    $fflush (fd_o) ;
  end
  endtask

  task rcv_data ;
  begin
   rxdatflags = 4'hf ;
   rx_block = rx_block + 1 ;
   if ((rx_block > 1) && ~eof_ifile) begin
    len_in = $fgets (rcvbuf, fd_i) ;
    if ((len_in < 100) && (len_in > 0))
	rcvbuf = rcvbuf << ((100 - len_in)*8) ;
    if (len_in == 0) begin
      $display ($stime, " EOF on file/pipe %s.", ifilename) ;
      eof_ifile = 1 ;
      end
    else if (rcvbuf[(8*(100-1)-1):(8*(100-2))] == "3") begin
      $display ($stime, " end record on file/pipe %s.", ifilename) ;
      eof_ifile = 1 ;
      end
    else if (rcvbuf[(8*(100-1)-1):(8*(100-2))] == "5") begin
      /* text string message from remote side, display it */
      tmpdata = (100 - 4 - (4 * rcvbuf[(8*(100-2)-1):(8*(100-3))]) ;
      $display ("%m: %s", rcvbuf[8*(100-4)-1:8*tmpdata] );
      end
    else while (rcvbuf[(8*(100-1)-1):(8*(100-2))] != "7") begin
	$display ("sit_link non-x4-data record: %s in %s", 
		  (rcvbuf[(8*(100-1)-1):(8*(100-2))]), rcvbuf) ;
	case (rcvbuf[(8*100)-1:8*99])
	  8'h43: rx_flag = 1 ;
	  8'h42: rx_flag = 2 ;
	  8'h41: rx_flag = 3 ;
	  8'h46: rx_flag = 0 ;
	endcase
	len_in = $fgets (rcvbuf, fd_i) ;
	if ((len_in < 100) && (len_in > 0))
          rcvbuf = rcvbuf << ((100 - len_in)*8) ;
    end
    case (rx_flag)
      0: expect = "C7  " ;
      1: expect = "B7  " ;
      2: expect = "A7  " ;
      3: expect = "F7  " ;
    endcase
    expect[15:8] = half_link_delay/16 + 8'h30 ;
    if (~eof_ifile && (len_in != 100))
      $display ($stime, " error reading from file %s, non-100 char record",
	ifilename) ;
    else if (~eof_ifile && (rcvbuf[(8*100)-1:8*96] != expect))
       $display ($stime, " surprising rx pkt hdr, %s,\n expected %s", 
		 rcvbuf[(8*100)-1:8*96], expect) ;
    case (rcvbuf[(8*100)-1:8*99])
	8'h43: rx_flag = 1 ;
	8'h42: rx_flag = 2 ;
	8'h41: rx_flag = 3 ;
	8'h46: rx_flag = 0 ;
    endcase
    rx_data = 0 ;
    if (~eof_ifile)
      for (i1=0;i1<4;i1=i1+1) begin
	for (i=half_link_delay; i>0; i=i-4) begin
	/* start at end of data and shift it left so [0] is first on wire.
      	 *   with 8 prefix bytes, 20 data bytes, 12 unused bytes,
      	 * first bits on wire in byte 9, last byte 28.
	 * byte 100 is in bits 7:0
     	 * byte 92 is in bits 9*8-1 to 8*8 (link3 last nibble)
	 * byte 32 is in bits 69*8-1 to 68*8 (link0 last nibble)
	 * byte 13 is in bits 88*8-1 to 87*8 (link0 first nibble)
	 * 
	 * bytes 5/6 are in bits 96*8-1 to 94*8
      	 */
	tmpdata = (rcvbuf >> (8*(88-i1*20-i/4)) & 8'hff) - 8'h30 ;
	if (tmpdata == 16)
	  rx_data =  {rx_data, 4'bxxxx} ;
	else if (tmpdata == 17)
	  rx_data =  {rx_data, 4'bzzzz} ;
	else
	  rx_data = {rx_data, tmpdata[0], tmpdata[1], tmpdata[2], tmpdata[3]} ;
	end
      tmpdata2 = (rcvbuf >> (8*(94-i1*2)) & 16'hffff) - 16'h3030 ;
      rx_dat1[i1] = {tmpdata2[12], rx_data[half_link_delay-1:0]} ;
      /* rx_adj bit [9] is the sign, change bits [8:0] to absolute value... */
      if (tmpdata2[11]) begin
	rx_adj1[i1] = {tmpdata2[11], ~tmpdata2[10:8], ~tmpdata2[5:0]} ;
        rx_adj1[i1] = rx_adj1[i1] + 1 ;
        end
      else
	rx_adj1[i1] = {tmpdata2[11:8], tmpdata2[5:0]} ;
      rx_cntr_lim1[i1] = (tmpdata2[13:12] == 1) ?
			  (half_link_delay - 1) :
			  (half_link_delay + tmpdata2[13]) ;
      end
//    $display ("rcv line %s", rcvbuf);
//    $display ($stime, " rcv data for link0: adj %d, cntrlim %d, data:\n%b",
//		rx_adj1[0], rx_cntr_lim1[0], rx_dat1[0]);
    end
   end
  endtask

  initial begin
    tclk = 1 ;
    rclk0 = 0 ;
    rclk1 = 0 ;
    rclk2 = 0 ;
    rclk3 = 0 ;
    tx_cntr = 0 ;
    num_adj0 = 0 ;
    num_adj1 = 0 ;
    num_adj2 = 0 ;
    num_adj3 = 0 ;
    tx_cntr0 = 0 ;
    tx_cntr1 = 0 ;
    tx_cntr2 = 0 ;
    tx_cntr3 = 0 ;
    rx_ptr = 0 ;
    tx_flag = 0 ;
    rx_flag = 0 ;
    rx_block = 0 ;
    if (filename_from_param_only ||
	! $value$plusargs("SIT_FILENAME=%s", filename)) begin
	/* order is important here - open o before i. */
      fd_o = $fopen (ofile, "w") ;
      fd_i = $fopen (ifile, "r") ;
      ifilename = ifile ;
      ofilename = ofile ;
    end
    else begin
      $display ("taking file name from command line: %s", filename) ;
      ifilename = (filename << 8) | "i" ;
      ofilename = (filename << 8) | "o" ;
	/* order is important here - open o before i. */
      fd_o = $fopen (ofilename, "w") ;
      fd_i = $fopen (ifilename, "r") ;
    end
  rxdatflags = 0 ;
  for (i1=0;i1<4;i1=i1+1) begin
     rx_adj1[i1] = 0 ;
     rx_cntr_lim1[i1] = half_link_delay ;
     rx_cntr_lim2[i1] = half_link_delay ;
     tx_dat[i1] = 0 ;
     end
  rx_cntr0 = 0 ;
  rx_cntr1 = 0 ;
  rx_cntr2 = 0 ;
  rx_cntr3 = 0 ;
  rx_adj2_0 = 0 ;
  rx_adj2_1 = 0 ;
  rx_adj2_2 = 0 ;
  rx_adj2_3 = 0 ;
  end

  always #bit_period tclk = ~tclk ;

  always @ (tclk) begin
    tx_cntr = tx_cntr + 1 ;
    if (tx_cntr == half_link_delay) begin
      tx_cntr = 0 ;
      send_data ;
    end
  end

  always @ (posedge tclk0) begin
    #(2*delta) ;
    tx_data = tx_dat[0] ;
    tx_data[tx_cntr0] = tdata[0] ;
    tx_dat[0] = tx_data ;
    tx_cntr0 = tx_cntr0 + 1 ;
    if (spedup[0])
      num_adj0 = num_adj0 + 1 ;
    else if (slowed[0])
      num_adj0 = num_adj0 - 1 ;
    en_adj[0] = (num_adj0 <= ((bit_period/delta)-3)) ||
		(num_adj0 >= (1024-(bit_period/delta))) ;
    end
  always @ (posedge tclk1) begin
    #(2*delta) ;
    tx_data = tx_dat[1] ;
    tx_data[tx_cntr1] = tdata[1] ;
    tx_dat[1] = tx_data ;
    tx_cntr1 = tx_cntr1 + 1 ;
    if (spedup[1])
      num_adj1 = num_adj1 + 1 ;
    else if (slowed[1])
      num_adj1 = num_adj1 - 1 ;
    en_adj[1] = (num_adj1 <= ((bit_period/delta)-3)) ||
		(num_adj1 >= (1024-(bit_period/delta))) ;
    end
  always @ (posedge tclk2) begin
    #(2*delta) ;
    tx_data = tx_dat[2] ;
    tx_data[tx_cntr2] = tdata[2] ;
    tx_dat[2] = tx_data ;
    tx_cntr2 = tx_cntr2 + 1 ;
    if (spedup[2])
      num_adj2 = num_adj2 + 1 ;
    else if (slowed[2])
      num_adj2 = num_adj2 - 1 ;
    en_adj[2] = (num_adj2 <= ((bit_period/delta)-3)) ||
		(num_adj2 >= (1024-(bit_period/delta))) ;
    end
  always @ (posedge tclk3) begin
    #(2*delta) ;
    tx_data = tx_dat[3] ;
    tx_data[tx_cntr3] = tdata[3] ;
    tx_dat[3] = tx_data ;
    tx_cntr3 = tx_cntr3 + 1 ;
    if (spedup[3])
      num_adj3 = num_adj3 + 1 ;
    else if (slowed[3])
      num_adj3 = num_adj3 - 1 ;
    en_adj[3] = (num_adj3 <= ((bit_period/delta)-3)) ||
		(num_adj3 >= (1024-(bit_period/delta))) ;
    end

  always begin
    #(bit_period / 2) rclk0 <= 1 ;
    if (rx_adj2_0[8:0] != 0) begin
       if ((rx_cntr0 % rx_interval_adj[0]) != 1)
	 #(bit_period / 2) rclk0 <= 0 ;
       else begin
         rx_adj2_0[8:0] = rx_adj2_0[8:0] - 1 ;
         rclk0_adj <= ~rclk0_adj ;
	 if (rx_adj2_0[9]) // slowed
	   #((bit_period / 2) + delta) rclk0 <= 0 ;
         else  // spedup
	   #((bit_period / 2) - delta) rclk0 <= 0 ;
	end
       end
    else
	 #(bit_period / 2) rclk0 <= 0 ;
    end
  always begin
    #(bit_period / 2) rclk1 <= 1 ;
    if (rx_adj2_1[8:0] != 0) begin
       if ((rx_cntr1 % rx_interval_adj[1]) != 1)
	 #(bit_period / 2) rclk1 <= 0 ;
       else begin
	 rx_adj2_1[8:0] = rx_adj2_1[8:0] - 1 ;
	 if (rx_adj2_1[9]) // slowed
	   #((bit_period / 2) + delta) rclk1 <= 0 ;
	 else  // spedup
	   #((bit_period / 2) - delta) rclk1 <= 0 ;
	 end
       end
    else
	 #(bit_period / 2) rclk1 <= 0 ;
    end
  always begin
    #(bit_period / 2) rclk2 <= 1 ;
    if (rx_adj2_2[8:0] != 0) begin
       if ((rx_cntr2 % rx_interval_adj[2]) != 1)
	 #(bit_period / 2) rclk2 <= 0 ;
       else begin
	 rx_adj2_2[8:0] = rx_adj2_2[8:0] - 1 ;
	 if (rx_adj2_2[9]) // slowed
	   #((bit_period / 2) + delta) rclk2 <= 0 ;
	 else  // spedup
	   #((bit_period / 2) - delta) rclk2 <= 0 ;
	 end
       end
    else
	 #(bit_period / 2) rclk2 <= 0 ;
    end
  always begin
    #(bit_period / 2) rclk3 <= 1 ;
    if (rx_adj2_3[8:0] != 0) begin
       if ((rx_cntr3 % rx_interval_adj[3]) != 1)
	 #(bit_period / 2) rclk3 <= 0 ;
       else begin
	 rx_adj2_3[8:0] = rx_adj2_3[8:0] - 1 ;
	 if (rx_adj2_3[9]) // slowed
	   #((bit_period / 2) + delta) rclk3 <= 0 ;
	 else  // spedup
	   #((bit_period / 2) - delta) rclk3 <= 0 ;
	 end
       end
    else
	 #(bit_period / 2) rclk3 <= 0 ;
    end

  always @ (posedge rclk0) begin
      if (rx_cntr0 == rx_cntr_lim2[0]) begin
	if ((rxdatflags[0] == 0) && (rxdatflags != 0))
	  $display (" link0 wants new data, but not all links took theirs: ",
			"report to developer");
	else if (rxdatflags[0] == 0)
	  rcv_data ;
	rxdatflags[0] = 0 ;
        rx_dat2[0] = rx_dat1[0] ;
	rx_adj2_0 = rx_adj1[0] ;
	rx_cntr_lim2[0] = rx_cntr_lim1[0] ;
	rx_cntr0 = 0 ;
	if (rx_adj2_0[8:0] != 0)
	  rx_interval_adj[0] = rx_cntr_lim2[0] / rx_adj2_0[8:0] ;
        end
      rx_data = rx_dat2[0] ;
      rdata[0] = rx_data[rx_cntr0] ;
      rx_cntr0 = rx_cntr0 + 1 ;
    end
  always @ (posedge rclk1) begin
      if (rx_cntr1 == rx_cntr_lim2[1]) begin
	if ((rxdatflags[1] == 0) && (rxdatflags != 0))
	  $display (" link1 wants new data, but not all links took theirs: ",
			"report to developer");
	else if (rxdatflags[1] == 0)
	  rcv_data ;
	rxdatflags[1] = 0 ;
        rx_dat2[1] = rx_dat1[1] ;
	rx_adj2_1 = rx_adj1[1] ;
	rx_cntr_lim2[1] = rx_cntr_lim1[1] ;
	rx_cntr1 = 0 ;
	if (rx_adj2_1[8:0] != 0)
	  rx_interval_adj[1] = rx_cntr_lim2[1] / rx_adj2_1[8:0] ;
        end
      rx_data = rx_dat2[1] ;
      rdata[1] = rx_data[rx_cntr1] ;
      rx_cntr1 = rx_cntr1 + 1 ;
    end
  always @ (posedge rclk2) begin
      if (rx_cntr2 == rx_cntr_lim2[2]) begin
	if ((rxdatflags[2] == 0) && (rxdatflags != 0))
	  $display (" link2 wants new data, but not all links took theirs: ",
			"report to developer");
	else if (rxdatflags[2] == 0)
	  rcv_data ;
	rxdatflags[2] = 0 ;
        rx_dat2[2] = rx_dat1[2] ;
	rx_adj2_2 = rx_adj1[2] ;
	rx_cntr_lim2[2] = rx_cntr_lim1[2] ;
	rx_cntr2 = 0 ;
	if (rx_adj2_2[8:0] != 0)
	  rx_interval_adj[2] = rx_cntr_lim2[2] / rx_adj2_2[8:0] ;
        end
      rx_data = rx_dat2[2] ;
      rdata[2] = rx_data[rx_cntr2] ;
      rx_cntr2 = rx_cntr2 + 1 ;
    end
  always @ (posedge rclk3) begin
      if (rx_cntr3 == rx_cntr_lim2[3]) begin
	if ((rxdatflags[3] == 0) && (rxdatflags != 0))
	  $display (" link3 wants new data, but not all links took theirs: ",
			"report to developer");
	else if (rxdatflags[3] == 0)
	  rcv_data ;
	rxdatflags[3] = 0 ;
        rx_dat2[3] = rx_dat1[3] ;
	rx_adj2_3 = rx_adj1[3] ;
	rx_cntr_lim2[3] = rx_cntr_lim1[3] ;
	rx_cntr3 = 0 ;
	if (rx_adj2_3[8:0] != 0)
	  rx_interval_adj[3] = rx_cntr_lim2[3] / rx_adj2_3[8:0] ;
        end
      rx_data = rx_dat2[3] ;
      rdata[3] = rx_data[rx_cntr3] ;
      rx_cntr3 = rx_cntr3 + 1 ;
    end

 wire #bit_period rclk0_del = rclk0 ;
endmodule
/* 
 * $Log: sit_ver_x4_cdr.v,v $
 * Revision 1.2  2005/07/27 15:15:53  cbenz
 * Revision 1.1  2005/07/25 12:56:02  cbenz
 */
