module le_top(PI0, PI12, PI3, RDYI0, RDYI12, RDYI3, YI0, YI1, YI2, YI3,
	      PO0, PO12, PO3, RDYO0, RDYO12, RDYO3, YO0, YO1, YO2, YO3,
	      LE_RAW_CLK, PCI_LE_RAW_CLKO, PCI_LE_RAW_CLKI, GLOBAL_RESET,
	      PCI_LEFT_LOCK, LED_BUS, TEST_D_BUS);

   input	 LE_RAW_CLK;
   input	 GLOBAL_RESET;

   input	 PCI_LE_RAW_CLKI;
   output	 PCI_LE_RAW_CLKO;
   output	 PCI_LEFT_LOCK;
 
   output [7:0]	 LED_BUS;
   output [21:0] TEST_D_BUS;
   
   output [31:0] PI0;
   output [31:0] PI12;
   output [31:0] PI3;
   
   input [31:0]	 PO0;
   input [31:0]	 PO12;
   input [31:0]	 PO3;
   
   reg [31:0]	 PO0_reg;
   reg [31:0]	 PO12_reg;
   reg [31:0]	 PO3_reg;

   output [1:0]	 RDYI0;
   output [2:0]	 RDYI12;
   output [1:0]	 RDYI3;
   
   input [1:0]	 RDYO0;
   input [2:0]	 RDYO12;
   input [1:0]	 RDYO3;

   reg [1:0]	 RDYO0_reg;
   reg [2:0]	 RDYO12_reg;
   reg [1:0]	 RDYO3_reg;

   output [2:0]	 YI0;
   output [2:0]	 YI1;
   output [2:0]	 YI2;
   output [2:0]	 YI3;

   input [2:0]	 YO0;
   input [2:0]	 YO1;
   input [2:0]	 YO2;
   input [2:0]	 YO3;

   reg [2:0]	 YO0_reg;
   reg [2:0]	 YO1_reg;
   reg [2:0]	 YO2_reg;
   reg [2:0]	 YO3_reg;

   reg [7:0]	 error_count;
   reg [21:0]	 debug_data;	 
   
   // Make sure we are not sending any data to Raw
   assign PI0 = 32'd0;
   assign PI12 = 32'd0;
   assign PI3 = 32'd0;

   assign RDYI0 = 2'd0;
   assign RDYI12 = 3'd0;
   assign RDYI3 = 2'd0;

   assign YI0 = 3'd0;
   assign YI1 = 3'd0;
   assign YI2 = 3'd0;
   assign YI3 = 3'd0;

   assign LED_BUS = error_count;
   assign TEST_D_BUS = debug_data;

   wire	gnd = 1'b0;
   wire	RAW_CLK;
   wire	locked1, locked2;
   wire	Reset = GLOBAL_RESET | ~locked1;

   // Bring in and deskew the Raw clock
   IBUFG_HSTL_I ibufg0 (.I(LE_RAW_CLK), .O(LE_RAW_CLK_tmp));

   DCM dll0(.CLKIN(LE_RAW_CLK_tmp), .CLKFB(RAW_CLK), .RST(GLOBAL_RESET), 
            .DSSEN(gnd), .PSINCDEC(gnd), .PSEN(gnd), .PSCLK(),
	    .CLK0(), .CLK90(), .CLK180(), .CLK270(),
            .CLK2X(RAW_CLK_tmp), .CLK2X180(), .CLKDV(), .CLKFX(), .CLKFX180(), 
            .LOCKED(locked1), .STATUS(), .PSDONE());

   BUFG rawClkBufG(.I(RAW_CLK_tmp), .O(RAW_CLK));

   // Send copy of the Raw clock to PCI and use DCM to make
   //  sure it arrives there at the same time we get it.
   DCM dll1(.CLKIN(LE_RAW_CLK_tmp), .CLKFB(RAW_CLK_fb_PCI), .RST(GLOBAL_RESET),
	    .DSSEN(gnd), .PSINCDEC(gnd), .PSEN(gnd), .PSCLK(),
	    .CLK0(PCI_LE_RAW_CLKO), .CLK90(), .CLK180(), .CLK270(),
            .CLK2X(), .CLK2X180(), .CLKDV(), .CLKFX(), .CLKFX180(),
            .LOCKED(locked2), .STATUS(), .PSDONE());

   assign PCI_LEFT_LOCK = locked2;
   
   IBUFG pciFbIBufg(.I(PCI_LE_RAW_CLKI),.O(RAW_CLK_fb_PCI));
      
   // Capture data from Raw, even though we don't use it
   always @(posedge RAW_CLK or posedge Reset) begin
      if (Reset) begin
	 RDYO0_reg <= 2'b00;
	 RDYO12_reg <= 3'b000;
	 RDYO3_reg <= 3'b00;
	 
	 YO0_reg <= 3'b000;
	 YO1_reg <= 3'b000;
	 YO2_reg <= 3'b000;
	 YO3_reg <= 3'b000;
	 
	 error_count <= 8'b11111111;
	 debug_data <= 22'd0;	 
      end // if (Reset) 
      else begin
	 RDYO0_reg <= RDYO0;
	 RDYO12_reg <= RDYO12;
	 RDYO3_reg <= RDYO3;
	 
	 YO0_reg <= YO0;
	 YO1_reg <= YO1;
	 YO2_reg <= YO2;
	 YO3_reg <= YO3;

	 PO0_reg <= PO0;
	 PO12_reg <= PO12;
 	 PO3_reg <= PO3;

	 if (((YO0_reg | YO1_reg | YO2_reg | YO3_reg) != 3'b000) |
	     ((RDYO0_reg | RDYO3_reg) != 3'b00) |
	     (RDYO12_reg != 3'b000))
	    error_count <= {error_count[6:0], 1'b0};

	 debug_data[5:0]   <= {YO0_reg,(PO0_reg != 32'd0),RDYO0_reg};
	 debug_data[15:6]  <= {YO2_reg,YO1_reg,(PO12_reg != 32'd0),RDYO12_reg};
	 debug_data[21:16] <= {YO3_reg,(PO3_reg != 32'd0),RDYO3_reg};
	 
      end // else: !if(Reset)
   end // always @ (posedge RAW_CLK or posedge Reset)
endmodule
