// ===========================================================
// Deserializer: Top level of the Des half of the SerDes.
//
// Default parallel output bus width is 32 bits.
//
// Intended for testing with the DeserializerTst module.
// ------------------------------------------------------------
// 2010-05-12 jmw:  v. 1.4 Added ParOutT port for optional part
//            of Step 7.  Added second always block to clock out
//      on that port, using DecoderParClk.
// 2006-06-05 jmw:  v. 1.3 Renamed instances consistent with
//      names in Serializer.
// 2006-05-24 jmw:  v. 1.2 Renamed ParValidReg to ParValidr;
//      renamed FIFOReadCmd input port to ReadReq
// 2006-05-23 jmw:  v. 1.1 Connected FIFO WriteIn to DesDecoder
//      ParValid; modified ParValid logic.
// 2006-05-19 jmw:  v. 1.0 Implemented.
// ============================================================
//
module Deserializer
  #(parameter AWid = 5   // Configures FIFO default depth.
   ,          DWid = 32  // Addressable widths everywhere.
   )
  ( output[DWid-1:0] ParOut, ParOutT
  , output ParValid, DecoderParClk
  , output FIFOEmpty, FIFOFull
  , input ParOutClk, SerialIn, ReadReq, SerValid, Reset
  );
//
wire[DWid-1:0] FIFO_Out, DecodeToFIFO;
wire SerialClk, SerRxToDecode, ParValidDecode;
//
reg[DWid-1:0] ParBuf;  // The buffer shown in the figure.
reg[DWid-1:0] ParBufTx; // The optionaal Tx-domain buffer.
reg ParValidr;
//
// -------------------------------------------------------
// Runtime:
assign ParOut   = ParBuf;   // Could add delays here:
assign ParValid = ParValidr;
assign ParOutT  = ParBufTx; // Optional.
//
// The output buffer functionality
// (may be done any of several ways):
//
always@(posedge ParOutClk, posedge Reset)
  begin : OutputBuffer
  if (Reset==1'b1)
       begin
       ParBuf    <=  'b0;
       ParValidr <= 1'b0;
       end
  else begin
       ParBuf    <= (ReadReq==1'b1)? FIFO_Out : 'b0;
       ParValidr <=  ReadReq && (~FIFOEmpty);
       end
  end
//
// The second output, for the OPTIONAL part of Step 7:
//
always@(posedge DecoderParClk, posedge Reset)
  begin : OutputInTxDomain
  if (Reset==1'b1)
       ParBufTx  <=  'b0;
  else begin
       ParBufTx  <= (ReadReq==1'b1)? FIFO_Out : 'b0;
       end
  end
//
// -------------------------------------------------------
// Structure:
//
FIFOTop #( .AWid(AWid), .DWid(DWid) )
FIFO_Rx1 ( .Dout(FIFO_Out), .Din(DecodeToFIFO)
         , .ReadIn(ReadReq), .WriteIn(ParValidDecode)
         , .Full(FIFOFull), .Empty(FIFOEmpty)
         , .ClkR(ParOutClk), .ClkW(DecoderParClk)
         , .Reseter(Reset)
         );
//
DesDecoder #( .DWid(DWid) )
DesDec_Rx1  ( .ParOut(DecodeToFIFO), .ParValid(ParValidDecode)
            , .ParClk(DecoderParClk), .SerClk(SerialClk)
            , .SerIn(SerRxToDecode), .SerValid(SerValid)
            , .Reset(Reset)
            );
//
SerialRx
SerRx_Rx1 ( .SerClk(SerialClk), .SerData(SerRxToDecode)
          , .SerLinkIn(SerialIn), .ParClk(DecoderParClk)
          , .Reset(Reset)
          );
//
endmodule // Deserializer.
//
