////////////////////////////////////////////////////////////////////
////                                                              ////
////  Advantech Co., Ltd	FPGA Design                           ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////  Project	: TI Shannon EVM FPGA                             ////
////  File name	: shevm_fpga_core.v		                          ////
////  Description                                                 ////
////      		: Shannon EVM FPGA Core MODULE                    ////
////  Created Date                                                ////
////			: 2010/12/09									  ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2010 Advantech Co., Ltd                        ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

	`include "params.v"


`define Rev_ID	16'h000d

module shevm_fpga_core(
		//GLOBAL	
	main_48mhz_clk_r_i,   	//FPGA 48MHZ Reference clock source
	vcc3_aux_pgood_i,     	//FPGA power good indication
	
		//DSP SPI	
	dsp_sspcs1_i,		  	//DSP SPI Chip Select
	dsp_sspck_i,			//DSP SPI clock
	dsp_sspmiso_o,			//DSP SPI data input from FPGA
	dsp_sspmosi_i,          //DSP SPI data output to FPGA
	
		//POWER ON	
	vcc5_pgood_i,			//5V power good indication
	vcc2p5_pgood_i,			//2.5V power good indication
	vcc1p8_pgood_i,         //1.8V power good indication
	vcc1p5_pgood_i,			//1.5V power good indication
	vcc0p75_pgood_i,		//0.75V power good indication

	sys_pgood_o,			//system power good indication
	
	vcc_5v_en_o,    		//5V power enable
	vcc2p5_en_o,			//2.5V power enable
	vcc1p8_en1_o,          	//1.8V power enable
	vcc1p5_en_o,			//1.5V power enable		
	vcc0p75_en_o,			//0.75V power enable
	
		//GPIO
	bm_gpio_i,				//Boot Mode switch inputs
	dsp_gpio_i,				//DSP GPIO inputs
	dsp_gpio_o,				//DSP GPIO outputs for boot strapping
	dsp_gpio_en,			//DSP GPIO IO control
	
	gpio3_alt_miso,         
    gpio3_alt_miso_outen,   // enable the DSP GPIO MISO to output polarity
	
		//RESET	buttons & input switch
	full_reset_i,			//full reset button input
	cold_reset_i,			//hard(cold) reset button input
	warm_reset_i,			//warm reset button input
	fpga_rst_n_i,			//FPGA JTAG reset input
	trgrstz_i, 				//trgrst from emulation card
	pciessen_i,				//PCIESSEN switch for boot strapping
	user_define_i,  		//User Defined switch input
	
		//DEBUG	
	debug_led_o,			//Debug LEDs
	
		//DSP Interface 
	dsp_porz_o,				//DSP POR
	dsp_resetfullz_o,		//DSP Full Reset
	dsp_resetz_o,			//DSP Reset
	dsp_lresetz_o,			//DSP local reset
	dsp_coresel_o,			//DSP core select
	dsp_resetstat_ni,		//DSP resetstat
	dsp_nmiz_o,				//DSP NMI
	dsp_lresetnmienz_o,		//DSP Lreset and NMI enable
	dsp_bootcomplete_i,		//DSP boot complete indication
	dsp_paclksel_o,			//DSP PA clock select
	dsp_hout_i,				//DSP HOUT
	dsp_sysclkout_i,		//DSP SYSCLKOUT
	dsp_timi0_o,			//DSP Timier 0 and PCIESSEN boot strapping
	
		//MMC Interface	
	mmc_detect_ni,			//MMC detect
	mmc_resetstat_no,		//MMC resetstat from DSP resetstat
	mmc_por_in_amc_ni,		//MMC POR request
	mmc_wr_amc_ni,			//MMC warm reset request
	mmc_bootcomplete_o,		//MMC boot complete from DSP boot complete
	
		//PHY Interface	
	phy_int_ni,				//PHY Interrupt
	phy_rst_no,				//PHY reset
	
		//UCD9222	
	ucd9222_pg1_i,			//ucd9222 #1 power good and also for the CVDD DSP core power good
	ucd9222_pg2_i,			//ucd9222 #2 power good and also for the VCC1V0 DSP core power good
	ucd9222_ena1_o,   		//ucd9222 #1 power and the CVDD DSP core power enable
	ucd9222_ena2_o,			//ucd9222 #2 power and the VCC1V0 DSP core power enable
	pgucd9222_i,			//both ucd9222 and the VCC1V0/CVDD DSP core power are valid
	ucd9222_rst_no,			//ucd9222 reset
	
		//PMBUS	& Smart-Reflex
	dsp_vcl_1_i,			//DSP smart-reflex clock
	dsp_vd_1_o,				//DSP smrat-reflex data
	pca9306_en_o,			//smart-reflex buffer enable
	pmbus_clk_o,			//PM bus clock
	pmbus_dat_i,			//PM bus data in
	pmbus_dat_o,			//PM bus data out
	pmbus_dat_en,			//PM bus data IO control
	
		//MISC	
	nand_wp_o,				//NAND flash write protect
	nor_wp_no,				//NOR flash write protect
	eeprom_wp_o,			//EEPROM write protect
	xds560_il_o,			//XDS560 inter-lock
	
	fpga_update_en,         //FPGA update enable
	 	
		//CLOCK Generator SPI interface & Control
	clock2_sspcs1_o,
	clock2_sspck_o,
	clock2_sspsi_o,
	clock2_sspso_i,
	refclk2_pd_no,
	clock2_pll_lock_i,
	clock3_sspcs1_o,
	clock3_sspck_o,
	clock3_sspsi_o,
	clock3_sspso_i,
	refclk3_pd_no,
	clock3_pll_lock_i,
	debug_sig,
	
      //PCIE SWITCH CLOCK CONTROL
   fpga_ics557_oe_o, 
	fpga_ics557_pd_no, 
	fpga_ics557_sel_o,

      //VID OE CONTROL			
  vid_oe_no 			
			
);

/************************/  
/**** 	GLOBAL	   	*****/
/************************/
input	main_48mhz_clk_r_i;
input	vcc3_aux_pgood_i;

/************************/  
/**** DSP SPI		*****/
/************************/
input	dsp_sspcs1_i;
input	dsp_sspck_i;
output	dsp_sspmiso_o;
input	dsp_sspmosi_i;

/************************/  
/**** 	POWER ON	*****/
/************************/
input	vcc5_pgood_i;
input	vcc2p5_pgood_i;
input	vcc1p8_pgood_i;
input	vcc1p5_pgood_i;
input	vcc0p75_pgood_i;

output	sys_pgood_o;

output	vcc_5v_en_o;
output	vcc2p5_en_o;
output	vcc1p8_en1_o;
output	vcc1p5_en_o;
output	vcc0p75_en_o;

reg		vcc1p5_en_o;
reg		vcc1p8_en1_o;
reg		vcc0p75_en_o;
reg		vcc2p5_en_o;
reg		vcc_5v_en_o;

wire  	sys_pgood_o;

/************************/  
/**** 	GPIO	    *****/
/************************/
input	[15:0]	bm_gpio_i;
input	[15:0]	dsp_gpio_i;
output	[15:0]	dsp_gpio_o;
output	dsp_gpio_en;

output 	gpio3_alt_miso;             // enable the DSP GPIO MISO to output polarity
output 	gpio3_alt_miso_outen;       // enable the DSP GPIO MISO to output polarity

reg   	dsp_gpio_en;
reg 	[15:0]  dsp_gpio_ctrl_delay;

/***********************/  
/**** 	RESET	   *****/
/***********************/
input		full_reset_i;
input		warm_reset_i;
input		cold_reset_i;
input		fpga_rst_n_i;
input       trgrstz_i;
input       pciessen_i;
input		user_define_i;  

wire		full_reset;
wire		warm_reset;
wire		cold_reset;

wire	[15:0]	dsp_gpio_o;

/***********************/  
/**** 	DEBUG	   *****/
/***********************/
output	[3:0]	debug_led_o;

wire	[3:0]	debug_led_o;

/*************************************/  
/**** 	DSP Interface & CONTROL  *****/
/*************************************/
output	dsp_porz_o;
output	dsp_resetfullz_o;
output	dsp_resetz_o;
output	dsp_lresetz_o;
input	dsp_resetstat_ni;
output	dsp_lresetnmienz_o;
output	[3:0]	dsp_coresel_o;
output	dsp_nmiz_o;
output	dsp_paclksel_o;
input	dsp_hout_i;
input	dsp_bootcomplete_i;
input	dsp_sysclkout_i;
output 	dsp_timi0_o; 

reg 	dsp_timi0_o;

wire	dsp_porz_o;
wire	dsp_resetfullz_o;
wire	dsp_resetz_o;
wire	dsp_lresetz_o;
wire	dsp_lresetnmienz_o;
wire	[3:0]	dsp_coresel_o;
wire	dsp_nmiz_o;
wire	dsp_paclksel_o;

/***************************/  
/**** 	MMC Interface  *****/
/***************************/
input	mmc_detect_ni;
output	mmc_resetstat_no;
input	mmc_por_in_amc_ni;
input	mmc_wr_amc_ni;
output	mmc_bootcomplete_o;

/***************************/  
/**** 	PHY Interface  *****/
/***************************/
input	phy_int_ni;
output	phy_rst_no;

wire	phy_rst_no;

/***********************/  
/**** 	UCD9222	   *****/
/***********************/
input	ucd9222_pg1_i;
input	ucd9222_pg2_i;
output	ucd9222_ena1_o;
output	ucd9222_ena2_o;
input	pgucd9222_i;
output	ucd9222_rst_no;

reg		ucd9222_ena1_o;
reg		ucd9222_ena2_o;
reg		ucd9222_rst_no;	

/*******************************/ 
/****  PMBUS & Smart-Reflex ****/
/*******************************/ 
input	dsp_vcl_1_i;   
output	dsp_vd_1_o;
output	pca9306_en_o;
output	pmbus_clk_o;
input	pmbus_dat_i;
output	pmbus_dat_o;
output	pmbus_dat_en;

wire	dsp_vd_1_o;
wire	pca9306_en_o;

/*******************/  
/**** 	MISC   *****/
/*******************/
output	nand_wp_o;
output	xds560_il_o;
output	nor_wp_no;
output	eeprom_wp_o;

output 	fpga_update_en;

wire	nand_wp_o;
wire	xds560_il_o;
wire    xds560_il_en;
wire	nor_wp_no;
wire	eeprom_wp_o;

wire	fpga_update_en;

/***************************/  
/**** 	CLOCK GEN SPI   ****/
/***************************/
output	clock2_sspcs1_o;
output	clock2_sspck_o;
output	clock2_sspsi_o;
input	clock2_sspso_i;
output	refclk2_pd_no;
input	clock2_pll_lock_i;

output	clock3_sspcs1_o;
output	clock3_sspck_o;
output	clock3_sspsi_o;
input	clock3_sspso_i;
output	refclk3_pd_no;
input	clock3_pll_lock_i;

reg		clock2_sspcs1_d1;

reg		refclk2_pd_no;
reg		refclk3_pd_no;

output	[31:0] debug_sig;
wire	[31:0] debug_sig;


/*************************************/  
/**** 	PCIE CLOCK MUX CONTROL   ****/
/*************************************/
output fpga_ics557_oe_o; 
output fpga_ics557_pd_no; 
output fpga_ics557_sel_o;

reg fpga_ics557_oe_o=1'b0;
reg fpga_ics557_pd_no=1'b0;
reg fpga_ics557_sel_o=1'b0; //1:HCSI 0:LVDS

reg fpga_ics557_sel_r=1'b0; //1:HCSI 0:LVDS troy


/*************************************/  
/****        VID OE CONTROL       ****/
/*************************************/
output vid_oe_no;
reg vid_oe_no=1'b1;


////////////////////////////////////////////////////////////
/***************************/  
/**** Internal Signals *****/
/***************************/
wire	fpga_ireset_n; 		//FPGA INTERNAL RESET

wire	fpga_update_lock_reset_n;  //FPGA Update Lock Register Reset

reg		[511:0]	spi_reg;       //configuration register for 00-3F = 512 bit
reg		[7:0]	spi_r;            //configuration register read data



reg		[3:0]	PW_SM;		//Power Sequence State-Machine 
parameter SM_IDLE	=4'h0; 
parameter SM_V2P5	=4'h1; 
parameter SM_PMBS	=4'h2; 
parameter SM_PMB2	=4'h3; 
parameter SM_V1P8	=4'h4; 
parameter SM_V1P5	=4'h5; 
parameter SM_V075	=4'h6; 
parameter SM_CLKG	=4'h7;
parameter SM_PORWR	=4'h8; 
parameter SM_WAIT	=4'h9; 
parameter SM_PWOK	=4'ha; 
parameter SM_POFF1	=4'hb;
parameter SM_POFF2	=4'hc;
parameter SM_FAIL	=4'hd;   //PM_Fail //20110103

reg		[23:0]	PW_c;
reg		[7:0]	fail_power_c;
reg		power_fail;
reg		all_power;

reg		[23:0]	set_clk2_c;
reg		[23:0]	set_clk3_c;
reg		set_clk2;
reg		set_clk3;

reg		half_clk;

// power good signals sync to 48MHz clock
reg 	[1:0] vcc5_pgood_d;
reg 	[1:0] vcc2p5_pgood_d;
reg 	[1:0] vcc1p8_pgood_d;
reg 	[1:0] vcc1p5_pgood_d;
reg 	[1:0] vcc0p75_pgood_d;
reg 	[1:0] ucd9222_pg1_d;
reg 	[1:0] ucd9222_pg2_d;
reg 	[1:0] pgucd9222_d;
reg 	[1:0] clock2_pll_lock_d;
reg 	[1:0] clock3_pll_lock_d;
reg 	[1:0] dsp_resetstat_nd;

reg     [15:0]	bm_gpio;     
reg		[15:0]	dsp_gpio;
reg		mmc_bootcomplete;   //stable signal with 1 sync should be OK 
reg		mmc_wr_amc_n_s1;
reg		mmc_wr_amc_n;
reg		mmc_por_in_amc_n_s1;
reg		mmc_por_in_amc_n;
reg		mmc_resetstat_n;
reg		mmc_detect_n;
reg		phy_int_n_s1;
reg		phy_int_n;
reg		fpga_rst_n_s1;
reg		fpga_rst_n;
reg		cold_reset_s1;
reg		cold_reset_s2;
reg		warm_reset_s1;
reg		warm_reset_s2;
reg		full_reset_s1; 
reg		full_reset_s2; 
reg		user_define;  //DC switch with 1 sync should be OK
reg		pciessen;
reg		trgrstz_s1;
reg		trgrstz;
reg		dsp_resetstat_n;  //stable signal with 1 sync should be OK 
reg		spi2_busy_s1;
reg		spi2_busy_s2;
reg		spi3_busy_s1;
reg		spi3_busy_s2;
reg		set_spi_reg_128;
reg		spi_reg_128_s1;
reg		spi_reg_128;
reg		set_spi_reg_256;
reg		spi_reg_256_s1;
reg		spi_reg_256;
reg		[31:0]	spi_reg_c2_s1;
reg		[31:0]	spi_reg_c2;
reg		[31:0]	spi_reg_c3_s1;
reg		[31:0]	spi_reg_c3;
reg		a_spi_reg_128;
reg		[31:0]	a_spi_reg_c2;
reg		a_spi_reg_256;
reg		[31:0]	a_spi_reg_c3;

reg		[3:0] PG_ST;

reg		clock3_sspcs1_d1;

reg		mmc_por_in_amc_n_48s1;		
reg		mmc_por_in_amc_n_48s2;		
reg		mmc_wr_amc_n_48s1;			
reg		mmc_wr_amc_n_48s2;			
reg		fullreset_n_48s1;		
reg		fullreset_n_48s2;		
reg		warmreset_n_48s1;			
reg		warmreset_n_48s2;
reg		coldreset_n_48s1;			
reg		coldreset_n_48s2;	
reg		dsp_resetstat_n_48s1;
reg		dsp_resetstat_n_48s2;	
reg		trgrstz_48s1;
reg		trgrstz_48s2;	
reg		fpga_rst_n_48s1;
reg		fpga_rst_n_48s2;	

///////////////////////////
reg		fpga_update_lock_reset_n_48s1;
reg		fpga_update_lock_reset_n_48s2;
reg		fpga_update_lock_reset_n_48s3;
////////////////////////////

reg		por_req_n;  		
reg		resetfull_req_n;	
reg	    hardreset_req_n;	
reg	    softreset_req_n;	

reg  [2:0] spi_10h_bit432 = 3'h0;       
reg  [2:0] spi_20h_bit432 = 3'h0;       

wire    por_out_n;			
wire    resetfull_out_n;	
wire    reset_out_n;		




wire 	spi_rw;
wire 	spi_cs;
wire 	spi_rdy;
wire	[7:0]	spi_w;
wire	[7:0]	spi_a;

wire	[31:0]	clock2_datao;
wire	[31:0]	clock3_datao;
wire	spi2_busy;
wire	spi3_busy;
wire	[7:0]	clock2_baudi;
wire	[31:0]	clock2_datai;
wire	[7:0]	clock3_baudi;
wire	[31:0]	clock3_datai;

wire	clock2_pll_lock_status;
wire	clock3_pll_lock_status;

wire	clock2_pll_lock;
wire	clock3_pll_lock;

/////////////////////////// alternative DSP GPIO SPI for FPGA update control   //// 20101230
wire	spi_fpga_update_en;         // set from DSP SPI
wire 	alt_fpga_update_lock_en;    // set from DSP GPIO SPI
wire    alt_dsp_gpio_spi_reset_n;   // disable DSP GPIO SPI during the boot configuration 
wire 	alt_spi_rw;                 // nc
wire 	alt_spi_cs;					// nc								
wire 	alt_spi_rdy;                // nc
wire	[7:0]	alt_spi_w;          // nc
wire	[7:0]	alt_spi_a;          // nc
wire	[7:0]	alt_spi_r;          // nc
wire   	lock_reset;                 // reset lock value during the POR & RESETFULL
wire   	gpio3_alt_miso;             // enable the DSP GPIO MISO to output polarity
wire   	gpio3_alt_miso_outen;       // enable the DSP GPIO MISO to output polarity
wire    alt_miso_outen;
wire	power_fail_check;           //20100103

wire 	[13:1] force_bootmode;      //20110219

reg		[7:0] latch_pgs;            //20110128




wire clk2_por, clk3_por;                  
wire clk2_resetfull, clk3_resetfull;
wire clk2_resetz, clk3_resetz;        

reg clk_mux_control_latch=1'b0;
 

///////////////////////// test only 20110104 Matt
reg    [27:0] freerun_counter;
reg    [3:0] heart_beat;
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) begin 
		freerun_counter <= 28'h0;
		heart_beat <= 4'h0;
	end	
//	else if(freerun_counter[25:0]==26'h0) begin 
	else if(freerun_counter[23:0]==24'h0) begin 
        freerun_counter <= freerun_counter + 1'b1;
        heart_beat <= heart_beat + 1'b1;
    end
    else begin	
		freerun_counter <= freerun_counter + 1'b1;
	end
end	
//`endif

always@(freerun_counter or latch_pgs)  //20110128 ///////////// power fail debug_led
begin
	case(freerun_counter[27:26])
	2'b00 : PG_ST[3:0] <= {2'b00, latch_pgs[1:0]};
	2'b01 : PG_ST[3:0] <= {2'b01, latch_pgs[3:2]};
	2'b10 : PG_ST[3:0] <= {2'b10, latch_pgs[5:4]};
	2'b11 : PG_ST[3:0] <= {2'b11, latch_pgs[7:6]};
	endcase
end	
////////////////////////////////////////////// 20110128 power fail debug led

////////////////////////////////////////////////////////////
/***********************/  
/**** Assignments  *****/
/***********************/	
assign 	dsp_coresel_o = (PW_SM>=4'h7 && PW_SM<=4'ha) ? 4'h0 : 4'h0;
assign 	dsp_paclksel_o = (bm_gpio_i[13:11] == 3'b010) ? 1'b0 : 1'b1;   //Matt 20101207  --> Need to be confirmed
assign 	dsp_lresetnmienz_o = (PW_SM>=4'h7 && PW_SM<=4'ha) ? 1'b1 : 1'b0;
assign 	dsp_nmiz_o = (PW_SM>=4'h7 && PW_SM<=4'hb) ? 1'b1 : 1'b0;
assign 	dsp_lresetz_o = (PW_SM>=4'h7 && PW_SM<=4'hb) ? 1'b1 : 1'b0;
//assign 	dsp_porz_o = (PW_SM>=4'h8 && PW_SM<=4'ha) ? por_out_n : 1'b0;
assign 	dsp_porz_o = (PW_SM>=4'h8 && PW_SM<=4'ha) ? por_out_n & clk2_por & clk3_por: 1'b0;//troy20120117
//assign 	dsp_resetfullz_o = (PW_SM>=4'h9 && PW_SM<=4'hb) ? resetfull_out_n : 1'b0;
assign 	dsp_resetfullz_o = (PW_SM>=4'h9 && PW_SM<=4'hb) ? resetfull_out_n & clk2_resetfull & clk3_resetfull: 1'b0;//troy20120117
//assign 	dsp_resetz_o = (PW_SM>=4'h7 && PW_SM<=4'hb) ? reset_out_n : 1'b0;
assign 	dsp_resetz_o = (PW_SM>=4'h7 && PW_SM<=4'hb) ? reset_out_n & clk2_resetz & clk3_resetz: 1'b0;//troy20120117

assign  power_fail_check = (PW_SM==4'hb || PW_SM==4'hc || PW_SM==4'hd)? 1'b1 : 1'b0;   //20110111

assign 	mmc_resetstat_no = dsp_resetstat_ni;
assign 	mmc_bootcomplete_o = dsp_bootcomplete_i;

assign	sys_pgood_o = all_power;
assign	force_bootmode [13:1] = (bm_gpio_i[6:5]==2'b00 && bm_gpio_i[3:1]==3'b000)? bm_gpio_i[13:1] : 13'h405; //20110219
assign	dsp_gpio_o = {bm_gpio_i[15:14], force_bootmode[13:1], bm_gpio_i[0]};  //20110219
assign	debug_led_o = (power_fail_check)? ~PG_ST[3:0] : ((dsp_gpio_en)? ~PW_SM[3:0] : ((fpga_update_en)? ~heart_beat[3:0] : spi_reg[67:64])); //20110219									

assign 	phy_rst_no = (dsp_porz_o==1'b1 && dsp_resetfullz_o==1'b1) ? spi_reg[81] : 1'b0; //20110219
assign 	nand_wp_o = (PW_SM==4'ha && dsp_resetstat_ni==1'b1 && dsp_gpio_en==1'b0) ? spi_reg[98] : 1'b0;

assign  xds560_il_en = spi_reg[99];
assign 	xds560_il_o = (PW_SM==4'ha) ? (1'b0 & xds560_il_en) : 1'b0; 
assign 	nor_wp_no = (PW_SM==4'ha && dsp_resetstat_ni==1'b1 && dsp_gpio_en==1'b0) ? spi_reg[100] : 1'b0;
assign 	eeprom_wp_o = (PW_SM==4'ha && dsp_resetstat_ni==1'b1 && dsp_gpio_en==1'b0) ? spi_reg[101] : 1'b1;
assign 	pca9306_en_o = (PW_SM==4'ha) ? spi_reg[102] : 1'b0;

assign 	clock2_baudi = spi_reg[143:136];
assign 	clock2_datai = spi_reg[191:160];
assign 	clock3_baudi = spi_reg[271:264];
assign 	clock3_datai = spi_reg[319:288];

assign  fpga_update_lock_reset_n = (dsp_porz_o==1'b0 || dsp_resetfullz_o==1'b0)? 1'b0 : 1'b1;
assign  lock_reset = (~fpga_update_lock_reset_n_48s2 && fpga_update_lock_reset_n_48s3 )? 1'b1 : 1'b0;

	assign	fpga_update_en = (spi_reg[119:112]==`FPGA_UPDATE_UNLOCK_CODE)? 1'b1 : 1'b0; 
	assign  alt_dsp_gpio_spi_reset_n = 1'b0;
	assign  gpio3_alt_miso_outen = 1'b0;
	assign 	gpio3_alt_miso = 1'b0;


	assign clock2_pll_lock = clock2_pll_lock_status;
	assign clock3_pll_lock = clock3_pll_lock_status;


//FPGA Internal Reset Block
fpga_internal_reset i_reset(main_48mhz_clk_r_i, vcc3_aux_pgood_i, fpga_ireset_n);


CDCE62005_2x clk2
   (.FPGA_48MHz          (main_48mhz_clk_r_i)     ,
    .FPGA_rst            (fpga_ireset_n)          ,
    .Vccpg               (set_clk2)               ,
    .PLL_Lock2           (clock2_pll_lock_status) ,
    .start               (set_spi_reg_128)        ,
    .busy                (spi2_busy)              ,
    .ready               (spi2_ready)             ,

    .clk2_por_en         (spi_10h_bit432[0]),                   
    .clk2_resetfull_en   (spi_10h_bit432[1]),             
    .clk2_resetz_en      (spi_10h_bit432[2]),                
    .clk2_por            (clk2_por         ),                      
    .clk2_resetfull      (clk2_resetfull   ),                
    .clk2_resetz         (clk2_resetz      ),          
  
    .iClock_div          (clock2_baudi)       ,
    .Write_data          (clock2_datai)       ,
    .Read_data           (clock2_datao)       ,
    .CLOCK2_SSPCS_o      (clock2_sspcs1_o)    ,
    .CLOCK2_SSPCK_o      (clock2_sspck_o)     ,
    .CLOCK2_SSPSI_o      (clock2_sspsi_o)     ,
    .CLOCK2_SSPSO_i      (clock2_sspso_i)     );


CDCE62005_3x clk3
   (.FPGA_48MHz          (main_48mhz_clk_r_i    ),
    .FPGA_rst            (fpga_ireset_n         ),
    .Vccpg               (set_clk3              ),
    .PLL_Lock3           (clock3_pll_lock_status),
    .start               (set_spi_reg_256       ),
    .busy                (spi3_busy             ),
    .ready               (spi3_ready            ),
    
    .clk3_por_en         (spi_20h_bit432[0]),           
    .clk3_resetfull_en   (spi_20h_bit432[1]),     
    .clk3_resetz_en      (spi_20h_bit432[2]),        
    .clk3_por            (clk3_por         ),              
    .clk3_resetfull      (clk3_resetfull   ),        
    .clk3_resetz         (clk3_resetz      ),           
    
    .iClock_div          (clock3_baudi          ),
    .Write_data          (clock3_datai          ),
    .Read_data           (clock3_datao          ),
    .CLOCK3_SSPCS_o      (clock3_sspcs1_o       ),
    .CLOCK3_SSPCK_o      (clock3_sspck_o        ),
    .CLOCK3_SSPSI_o      (clock3_sspsi_o        ),
    .CLOCK3_SSPSO_i      (clock3_sspso_i        ));



dsp_spi spi(	
  spi_cs,
  spi_rw,
  spi_a,
  spi_w,
  spi_r,
  spi_rdy,
  
  dsp_sspcs1_i,
  dsp_sspck_i,
  dsp_sspmiso_o,
  dsp_sspmosi_i,
  wr_event_cng
	);
	
reg wr_cng_1t=1'b0;
reg wr_cng_2t=1'b0;
reg wr_cng_3t=1'b0;
wire wr_event_pulse;
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
if (~fpga_ireset_n) begin
wr_cng_1t<=1'b0;
wr_cng_2t<=1'b0;
wr_cng_3t<=1'b0;
end
else begin
wr_cng_1t<=wr_event_cng;
//wr_cng_1t<=wr_event_cng_by_cs;
wr_cng_2t<=wr_cng_1t;
wr_cng_3t<=wr_cng_2t;
end
assign wr_event_pulse = wr_cng_2t^wr_cng_3t;


//////////////////////////////////////////////////////////////////////
// DSP SPI interface
//////////////////////////////////////////////////////////////////////
debouncer debouncer1(main_48mhz_clk_r_i,fpga_ireset_n,full_reset_i,full_reset);
debouncer debouncer2(main_48mhz_clk_r_i,fpga_ireset_n,warm_reset_i,warm_reset);
debouncer debouncer3(main_48mhz_clk_r_i,fpga_ireset_n,cold_reset_i,cold_reset);

//////////////////////////////////////////////////////////////////////
// pseudo-random number generator
//////////////////////////////////////////////////////////////////////


always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) begin 
		clock2_sspcs1_d1 <= 1'b1;
		clock3_sspcs1_d1 <= 1'b1;
		mmc_por_in_amc_n_48s1 <= 1'b1;
		mmc_por_in_amc_n_48s2 <= 1'b1;
		mmc_wr_amc_n_48s1 <= 1'b1;
		mmc_wr_amc_n_48s2 <= 1'b1;	
		fullreset_n_48s1 <= 1'b1;
		fullreset_n_48s2 <= 1'b1;
		warmreset_n_48s1 <= 1'b1;
		warmreset_n_48s2 <= 1'b1;
		coldreset_n_48s1 <= 1'b1;
		coldreset_n_48s2 <= 1'b1;
		dsp_resetstat_n_48s1 <= 1'b1;
		dsp_resetstat_n_48s2 <= 1'b1;
		trgrstz_48s1 <= 1'b1;
		trgrstz_48s2 <= 1'b1;	
		fpga_rst_n_48s1 <= 1'b1;
		fpga_rst_n_48s2 <= 1'b1;
		por_req_n <= 1'b1;
		resetfull_req_n <= 1'b1;
		hardreset_req_n <= 1'b1;	
		softreset_req_n <= 1'b1;
		fpga_update_lock_reset_n_48s1 <= 1'b1;
		fpga_update_lock_reset_n_48s2 <= 1'b1;
		fpga_update_lock_reset_n_48s3 <= 1'b1;
	end	
	else begin 
		clock2_sspcs1_d1 <= clock2_sspcs1_o;
		clock3_sspcs1_d1 <= clock3_sspcs1_o;
		mmc_por_in_amc_n_48s1 <= mmc_por_in_amc_ni;
		mmc_por_in_amc_n_48s2 <= mmc_por_in_amc_n_48s1;
		mmc_wr_amc_n_48s1 <= mmc_wr_amc_ni;
		mmc_wr_amc_n_48s2 <= mmc_wr_amc_n_48s1;	
		fullreset_n_48s1 <= full_reset;
		fullreset_n_48s2 <= fullreset_n_48s1;
		warmreset_n_48s1 <= warm_reset;
		warmreset_n_48s2 <= warmreset_n_48s1;
		coldreset_n_48s1 <= cold_reset;
		coldreset_n_48s2 <= coldreset_n_48s1;
		dsp_resetstat_n_48s1 <= dsp_resetstat_ni;
		dsp_resetstat_n_48s2 <= dsp_resetstat_n_48s1;
		trgrstz_48s1 <= trgrstz_i;
		trgrstz_48s2 <= trgrstz_48s1;	
		fpga_rst_n_48s1 <= fpga_rst_n_i;
		fpga_rst_n_48s2 <= fpga_rst_n_48s1;
		por_req_n <= 1'b1; //mmc_por_in_amc_n_48s2 ;   //20110218
	    resetfull_req_n <= fullreset_n_48s2 & mmc_por_in_amc_n_48s2; // trgrstz_48s2;  //20110218
		hardreset_req_n <= 1'b1; //coldreset_n_48s2;	//20110219
		softreset_req_n <= warmreset_n_48s2 & mmc_wr_amc_n_48s2 & trgrstz_48s2;   //20110218
		fpga_update_lock_reset_n_48s1 <= fpga_update_lock_reset_n;
		fpga_update_lock_reset_n_48s2 <= fpga_update_lock_reset_n_48s1;
		fpga_update_lock_reset_n_48s3 <= fpga_update_lock_reset_n_48s2;
	end	
end

/////////////////////////////// debug
assign debug_sig = {
  16'h0,      //d31-d16         
  fpga_update_en, por_out_n, resetfull_out_n, reset_out_n, PW_SM[3:0],  //d15-d8
  xds560_il_en, por_req_n, resetfull_req_n, hardreset_req_n,             //d7-d4 
  softreset_req_n, dsp_porz_o, dsp_resetfullz_o, dsp_resetz_o};  //d3-d0

  reset_req_s reset_req_ctrl(main_48mhz_clk_r_i, fpga_ireset_n, por_req_n, resetfull_req_n, hardreset_req_n,
  softreset_req_n, dsp_porz_o, dsp_resetfullz_o, dsp_resetz_o, dsp_resetstat_n_48s2, por_out_n, 
  resetfull_out_n, reset_out_n);

//////////////////////////////////////////////////////////////////////
// FPGA Configuration Registers
//////////////////////////////////////////////////////////////////////
always@(negedge fpga_ireset_n or posedge main_48mhz_clk_r_i )	
  //reset status
	if (~fpga_ireset_n) begin
  //offset                 0f0e 0d0c 0b0a 0908 0706 0504 0302 0100  
//  spi_reg[127:  0] <= {96'h0000_001C_0002_0000_0000_0000, `Rev_ID, 16'h8004};  //Reset default value //20110218
  //0x08 bit[3:0]
    spi_reg[67:64]  <= 4'b0;
  //0x0A bit[1]           
    spi_reg[81]     <= 1'b1;    
  //0x0C bit[6:2] bit[0]-96  bit[1]-97 bit[2]-98            
    spi_reg[102:98] <= 5'b0_0111;
  //0x0F bit[7:0]            
    spi_reg[127:120]<= 8'b0;       

  //GEN2 0x1f~0x10 255~128         
  //offset                     1f1e 1d1c 1b1a 1918 1716 1514 1312 1110 
//    spi_reg[255:128] <= 128'h0000_0000_0000_0000_0000_0000_0000_0300;  //Reset default value
//    set_spi_reg_128  <=1'b0;
    spi_reg[143:136] <=8'h03;//offset 0x11
    spi_reg[191:160] <=32'h0;//offset 0x17~0x14  
   
   //GEN3 0x2f~0x20 384~256 
   //offset                    2f2e 2d2c 2b2a 2928 2726 2524 2322 2120 
//    spi_reg[383:256] <= 128'h0000_0000_0000_0000_0000_0000_0000_0300;  //Reset default value
//    set_spi_reg_256  <= 1'b0;
    spi_reg[271:264] <=8'h03;//offset 0x21
    spi_reg[319:288] <=32'h0;//offset 0x27~0x24

   //PMBUS 
   //offset                    3f3e 3d3c 3b3a 3938 3736 3534 3332 3130 
//	  spi_reg[511:384] <= 128'h0000_0000_0000_0000_0000_0000_0000_0000;  //Reset default value


    spi_10h_bit432 <= 3'h0;
    spi_20h_bit432 <= 3'h0;	
	
  end
	
  //configuration register write	
  else if (wr_event_pulse) begin		 
		case (spi_a)
		//  8'h0: Device ID  (RO)  8004
		//  8'h2: Revision ID  (RO) 0001
		//  8'h4: BM GPIO (RO)
		//  8'h6: DSP GPIO (RO in normal operation)
       8'h8: spi_reg[67:64] <= spi_w[3:0];  //Debug_LED
		//  8'h9: MMC Control (RO)	
       8'hA: spi_reg[81] <= spi_w[1];	 //PHY control, bit 0 (RO) = PHY INIT		
    //  8'hB: Reset Button Status
       8'hC: spi_reg[102:98] <= spi_w[6:2]; // Miscellaneous Register
		//  8'hD: Reserved	
    //  8'hE: spi_reg[119:112] <= spi_w[7:0]; //FPGA updat lock register
       8'hF:  spi_reg[127:120] <= spi_w[7:0]; //Scratch Register
	
	
       8'h10: spi_10h_bit432  <= spi_w[4:2];       
       8'h11: spi_reg[143:136] <= spi_w;  //CLK_Gen2 clock setting baud rate
    //  8'h12: Reserved
    //  8'h13: Reserved		
       8'h14: spi_reg[167:160] <= spi_w;	  //clk_gen2 w_byte0		
       8'h15: spi_reg[175:168] <= spi_w;   //clk_gen2 w_byte1
       8'h16: spi_reg[183:176] <= spi_w;   //clk_gen2 w_byte2
       8'h17: spi_reg[191:184] <= spi_w;   //clk_gen2 w_byte3
		//  8'h18: clk_gen2 r_byte0 (RO)
    //  8'h19: clk_gen2 r_byte1 (RO)
    //  8'h1A: clk_gen2 r_byte2 (RO)	
    //  8'h1B: clk_gen2 r_byte3 (RO)	
    //  8'h1F~1C: reserved		
        

      8'h20: spi_20h_bit432   <= spi_w[4:2];      
      8'h21: spi_reg[271:264] <= spi_w;  //CLK_Gen3 clock setting baud rate
    //  8'h22: Reserved
    //  8'h23: Reserved		
      8'h24: spi_reg[295:288] <= spi_w;  //clk_gen3 w_byte0			
      8'h25: spi_reg[303:296] <= spi_w;  //clk_gen3 w_byte1	
      8'h26: spi_reg[311:304] <= spi_w;  //clk_gen3 w_byte1
      8'h27: spi_reg[319:312] <= spi_w;  //clk_gen3 w_byte1
    //  8'h28: clk_gen3 r_byte0 (RO)
    //  8'h29: clk_gen3 r_byte1 (RO)
    //  8'h2A: clk_gen3 r_byte2 (RO)	
    //  8'h2B: clk_gen3 r_byte3 (RO)	
    //  8'h2F~2C: reserved	     
        
      
    // Following Reserved for PM bus ...............
    //  8'h30: spi_reg[391:384] <= spi_w; 
    //  8'h31: spi_reg[399:392] <= spi_w;  
    //  8'h32: spi_reg[407:400] <= spi_w;
    //  8'h33: spi_reg[415:408] <= spi_w;		
    //	8'h34: spi_reg[423:416] <= spi_w; 			
    //	8'h35: spi_reg[431:424] <= spi_w;  	
    //	8'h36: spi_reg[439:432] <= spi_w;  
    //	8'h37: spi_reg[447:440] <= spi_w;  
    //  8'h38: spi_reg[455:448] <= spi_w; 
    //  8'h39: spi_reg[463:456] <= spi_w; 
    //  8'h3A: spi_reg[471:464] <= spi_w; 	
    //  8'h3B: spi_reg[479:472] <= spi_w; 
    //  8'h3C: spi_reg[487:480] <= spi_w; 
    //  8'h3D: spi_reg[495:488] <= spi_w; 
    //  8'h3E: spi_reg[503:496] <= spi_w; 
    //  8'h3F: spi_reg[511:504] <= spi_w; 		
    
     endcase
	end
	
always@(negedge fpga_ireset_n or posedge main_48mhz_clk_r_i )
  if (~fpga_ireset_n) begin
    fpga_ics557_sel_r <= 1'b0;	
  end
  else if (clk_mux_control_latch)begin
    fpga_ics557_sel_r <= bm_gpio_i[10];  
  end
  else if (wr_event_pulse) begin	 
    case (spi_a)
		// PCIE CLOCK SWITCH CONTROL                    
      8'h50: fpga_ics557_sel_r <= spi_w[0];                                                              
    endcase
  end


always@(negedge fpga_ireset_n or posedge main_48mhz_clk_r_i )
  if (~fpga_ireset_n) 
    fpga_ics557_sel_o <= 1'b0;
  else if (PW_SM < SM_PWOK)	 
    fpga_ics557_sel_o <= bm_gpio_i[10];  
  else if (PW_SM >= SM_PWOK)	 
    fpga_ics557_sel_o <= fpga_ics557_sel_r;   	
	
	
	
	
assign spi_reg_128_rstn=fpga_ireset_n & clock2_sspcs1_o;	
always@(negedge spi_reg_128_rstn or posedge main_48mhz_clk_r_i )
  if (~spi_reg_128_rstn)
    set_spi_reg_128  <=1'b0;
	else if (wr_event_pulse)
    case (spi_a)
      8'h10: set_spi_reg_128 <= spi_w[0];   //Clk_Gen2 control	 
    endcase

assign spi_reg_256_rstn=fpga_ireset_n & clock3_sspcs1_o;	
always@(negedge spi_reg_256_rstn or posedge main_48mhz_clk_r_i )
   if (~spi_reg_256_rstn)
       set_spi_reg_256  <=1'b0;
	else if (wr_event_pulse)
     case (spi_a)
       8'h20: set_spi_reg_256 <= spi_w[0];   //Clk_Gen3 control	 
     endcase  
	
	
	
	
assign update_lock_rstn=fpga_ireset_n & (~(~fpga_update_lock_reset_n_48s2 && fpga_update_lock_reset_n_48s3));
always@(negedge update_lock_rstn or posedge main_48mhz_clk_r_i )
  if (~update_lock_rstn)
    //0x0E bit[7:0]
    spi_reg[119:112]<= 8'b0;  
	else if (wr_event_pulse)
    case (spi_a)	 
      8'hE: spi_reg[119:112] <= spi_w[7:0]; //FPGA updat lock register
    endcase



always@(*)		
begin
	if (~fpga_ireset_n) begin
	    //offset                 0f0e 0d0c 0b0a 0908 0706 0504 0302 0100  
 //    spi_reg[127:  0] <= 128'h0000_001C_0002_0000_0000_0000_0002_8004;  //Reset default value //initial test version
		 

    //0x07-0x00
    spi_reg[63:0]    <= {32'h0, `Rev_ID, 16'h8004};  //Reset default value    
		
    //0x08 bit[7:4]
		spi_reg[71:68]   <= 4'b0;
		//0x09
		spi_reg[79:72]   <= 8'b0;		
		//0x0a bit[0] bit[7:2]
		spi_reg[80]      <= 1'b0;	
		spi_reg[87:82]   <= 6'b0;		
		//0x0b
		spi_reg[95:88]   <= 8'b0;
		//0x0c bit[7] bit[1:0]		
		spi_reg[97:96]   <=2'b0;
		spi_reg[103]     <=1'b0;
		//0x0d
		spi_reg[111:104] <=8'b0;	

      //GEN2 
		//0x10 bit[135-128]
		spi_reg[135:128] <=8'b0;
      //0x13-0x12 bit[159:144] 		
		spi_reg[159:144] <=16'b0;
      //0x1f-0x18 bit[255:192] 		
		spi_reg[255:192] <=64'b0;
      
      //GEN3
		//0x20 bit[263-256]
		spi_reg[263:256] <=8'b0;
      //0x23-0x22 bit[287:272] 		
		spi_reg[287:272] <=16'b0;
      //0x2f-0x28 bit[383:320] 		
		spi_reg[383:320] <=64'b0;		
		
      //PMBUS
		//offset                 3f3e 3d3c 3b3a 3938 3736 3534 3332 3130 
      spi_reg[511:384] <= 128'h0000_0000_0000_0000_0000_0000_0000_0000;  //Reset default value
      //GEN1
		//0x40 bit[519-512]
//		spi_reg[519:512] <=8'b0;
      //0x43-0x42 bit[543:528] 		
//		spi_reg[543:528] <=16'b0;
      //0x4f-0x48 bit[639:576] 		
//		spi_reg[639:576] <=64'b0;				
	end
//Read Only registers
	else begin
		  spi_reg[39:32] <= bm_gpio[7:0];    //  8'h4: BM GPIO (RO)
		  spi_reg[47:40] <= bm_gpio[15:8];
		  spi_reg[55:48] <= dsp_gpio[7:0];   //  8'h4: BM GPIO (RO)
		  spi_reg[63:56] <= dsp_gpio[15:8];
		  // 8'h9: MMC control
		  spi_reg[76:72] <= {mmc_bootcomplete,mmc_wr_amc_n,mmc_por_in_amc_n,mmc_resetstat_n,mmc_detect_n};	
		  // 8'hA: PHY control
		  spi_reg[80] <= phy_int_n;
		  // 8'hB: Reset Button & Misc SW
//		  spi_reg[91:88] <= {fpga_rst_n,cold_reset_s2,warm_reset_s2,full_reset_s2}; //Matt:20101207 should change to debounced signals
		  spi_reg[91:88] <= {1'b0,cold_reset_s2,warm_reset_s2,full_reset_s2}; //troy 20110119 delete jtag reset signal 
		  spi_reg[95:92] <= {user_define,pciessen,trgrstz,dsp_resetstat_n}; //20101205
		  
		  
		  spi_reg[111:104] <= {5'h0, dsp_sysclkout_i, dsp_hout_i, fpga_update_en};  //read only for fpga_update_en


//GEN2
		  spi_reg[129] <= spi2_busy_s2;
		  spi_reg[128] <= spi_reg_128;        
		  spi_reg[132:130] <= spi_10h_bit432;		
    	  
//		  if (~clock2_sspcs1_o) set_spi_reg_128 <= 1'b0; 
		  spi_reg[223:192] <= spi_reg_c2;
		  
		  
//GEN3
		  spi_reg[257] <= spi3_busy_s2;
		  spi_reg[256] <= spi_reg_256;		 
		  spi_reg[260:258] <= spi_20h_bit432;	
		  
//		  if (~clock3_sspcs1_o) set_spi_reg_256 <= 1'b0;
		  spi_reg[351:320] <= spi_reg_c3;              		  	  
	end
end



















always@(fpga_ireset_n or clock2_sspcs1_d1 or clock2_sspcs1_o or clock2_datao or 
        clock3_sspcs1_d1 or clock3_sspcs1_o or clock3_datao or set_spi_reg_128 or set_spi_reg_256)
begin
  if (~fpga_ireset_n ) begin
	    a_spi_reg_128 <= 1'b0;
			a_spi_reg_c2[31:0] <= 32'h0;
	end		
	else if (~clock2_sspcs1_d1 && clock2_sspcs1_o) begin
			a_spi_reg_128 <= 1'b0;
			a_spi_reg_c2[31:0] <= clock2_datao;
	end
	else if (set_spi_reg_128 && clock2_sspcs1_o) begin 	
      a_spi_reg_128 <= 1'b1;			
	end	
	else if (clock2_sspcs1_d1 && ~clock2_sspcs1_o) begin
			a_spi_reg_128 <= 1'b0;
	end
	
		
	if (~fpga_ireset_n ) begin
	    a_spi_reg_256 <= 1'b0;
			a_spi_reg_c3[31:0] <= 32'h0;
	end		
	else if (~clock3_sspcs1_d1 && clock3_sspcs1_o) begin
			a_spi_reg_256 <= 1'b0;
			a_spi_reg_c3[31:0] <= clock3_datao;
	end	
	else if (set_spi_reg_256 && clock3_sspcs1_o) begin 	
      a_spi_reg_256 <= 1'b1;		
	end	
  else if (clock3_sspcs1_d1 && ~clock3_sspcs1_o) begin
			a_spi_reg_256 <= 1'b0;
	end
	
end	

//////////////////////////////////////////////////////////////////////
// Signals re-sync to DSP SPI clock
//////////////////////////////////////////////////////////////////////
always@(posedge dsp_sspck_i or negedge fpga_ireset_n)
begin
    if (~fpga_ireset_n) begin
        bm_gpio[15:0] <= 16'h0;     //DC switch with 1 sync should be OK 
		dsp_gpio[15:0] <= 16'h0;
		mmc_bootcomplete <= 1'b0;   //stable signal with 1 sync should be OK 
		mmc_wr_amc_n_s1 <= 1'b1;
		mmc_wr_amc_n <= 1'b1;
		mmc_por_in_amc_n_s1 <= 1'b1;
		mmc_por_in_amc_n <= 1'b1;
		mmc_resetstat_n <= 1'b0;
		mmc_detect_n <= 1'b1;
		phy_int_n_s1 <= 1'b1;
		phy_int_n <= 1'b1;
		fpga_rst_n_s1 <= 1'b1;
		fpga_rst_n <= 1'b1;
		cold_reset_s1 <= 1'b1;
		cold_reset_s2 <= 1'b1;
		warm_reset_s1 <= 1'b1;
		warm_reset_s2 <= 1'b1;
		full_reset_s1 <= 1'b1; 
		full_reset_s2 <= 1'b1; 
		user_define <= 1'b0;  //DC switch with 1 sync should be OK
		pciessen <= 1'b0;     //DC switch with 1 sync should be OK
		trgrstz_s1 <= 1'b1;
		trgrstz <= 1'b1;
		dsp_resetstat_n <= 1'b0;  //stable signal with 1 sync should be OK 
		spi2_busy_s1 <= 1'b0;
		spi2_busy_s2 <= 1'b0;
		spi3_busy_s1 <= 1'b0;
		spi3_busy_s2 <= 1'b0;
		spi_reg_128_s1 <= 1'b0;
		spi_reg_128 <= 1'b0;
		spi_reg_256_s1 <= 1'b0;
		spi_reg_256 <= 1'b0;
		spi_reg_c2_s1 <= 32'h0;
		spi_reg_c2 <= 32'h0;
		spi_reg_c3_s1 <= 32'h0;
		spi_reg_c3 <= 32'h0;
    end
	else begin
	    bm_gpio[15:0] <= bm_gpio_i[15:0];     //DC switch with 1 sync should be OK 
		dsp_gpio[15:0] <= dsp_gpio_i[15:0];   //stable signal( before DSP read ) with 1 sync should be OK
		mmc_bootcomplete <= mmc_bootcomplete_o;   //stable signal with 1 sync should be OK 
		mmc_wr_amc_n_s1 <= mmc_wr_amc_ni;
		mmc_wr_amc_n <= mmc_wr_amc_n_s1;
		mmc_por_in_amc_n_s1 <= mmc_por_in_amc_ni;
		mmc_por_in_amc_n <= mmc_por_in_amc_n_s1;
		mmc_resetstat_n <= mmc_resetstat_no;	//stable signal with 1 sync should be OK 
		mmc_detect_n <= mmc_detect_ni;         //stable signal with 1 sync should be OK
		phy_int_n_s1 <= phy_int_ni;
		phy_int_n <= phy_int_n_s1;
		fpga_rst_n_s1 <= fpga_rst_n_i;
		fpga_rst_n <= fpga_rst_n_s1;
		cold_reset_s1 <= cold_reset;
		cold_reset_s2 <= cold_reset_s1;
		warm_reset_s1 <= warm_reset;
		warm_reset_s2 <= warm_reset_s1;
		full_reset_s1 <= full_reset; 
		full_reset_s2 <= full_reset_s1; 
		user_define <= user_define_i;  //DC switch with 1 sync should be OK
		pciessen <= pciessen_i; 
		trgrstz_s1 <= trgrstz_i;
		trgrstz <= trgrstz_s1;
		dsp_resetstat_n <= dsp_resetstat_ni;  //stable signal with 1 sync should be OK 
		spi2_busy_s1 <= spi2_busy;
		spi2_busy_s2 <= spi2_busy_s1;
		spi3_busy_s1 <= spi3_busy;
		spi3_busy_s2 <= spi3_busy_s1;
		spi_reg_128_s1 <= a_spi_reg_128;
		spi_reg_128 <= spi_reg_128_s1;
		spi_reg_256_s1 <= a_spi_reg_256;
		spi_reg_256 <= spi_reg_256_s1;
		spi_reg_c2_s1 <= a_spi_reg_c2;
		spi_reg_c2 <= spi_reg_c2_s1;
		spi_reg_c3_s1 <= a_spi_reg_c3;
		spi_reg_c3 <= spi_reg_c3_s1;
	end	
end	   






//always@(fpga_ireset_n or spi_rw or spi_rdy or spi_reg or spi_a or fpga_ics557_sel_o)		
always@(*)
begin
	if (~fpga_ireset_n) spi_r <= 8'h0;
//configuration register read		
     else begin
		case (spi_a)
			8'h0: spi_r <= spi_reg[7:0];  //device ID
			8'h1: spi_r <= spi_reg[15:8];
			8'h2: spi_r <= spi_reg[23:16]; //revision ID
			8'h3: spi_r <= spi_reg[31:24];								
			8'h4: spi_r <= spi_reg[39:32]; //BM_GPIO
			8'h5: spi_r <= spi_reg[47:40];
			8'h6: spi_r <= spi_reg[55:48]; //DSP_GPIO
			8'h7: spi_r <= spi_reg[63:56];
			8'h8: spi_r <= {4'h0,spi_reg[67:64]};  //debug_LED
			8'h9: spi_r <= {3'h0,spi_reg[76:72]};  //MMC control						
			8'hA: spi_r <= {6'h0,spi_reg[81:80]};  //PHY control			
			8'hB: spi_r <= spi_reg[95:88];  //Reset & SW
			8'hC: spi_r <= {1'h0,spi_reg[102:98], 2'h0};  //Misc	
			8'hD: spi_r <= spi_reg[111:104]; // FPGA update lock status register
      8'hE: spi_r <= spi_reg[119:112];     // FPGA update lock register			
			8'hF: spi_r <= spi_reg[127:120];     // Scratch
			
			8'h10: spi_r <= {6'h0,spi_reg[129:128]}; //clk2 control
			8'h11: spi_r <= spi_reg[143:136];  // clk2 spi clk setting
		//	8'h12: spi_r <= spi_reg[151:144];  //Reserved
		//	8'h13: spi_r <= spi_reg[159:152];  //Reserved
			8'h14: spi_r <= spi_reg[167:160];  //clk2 write data
			8'h15: spi_r <= spi_reg[175:168];
			8'h16: spi_r <= spi_reg[183:176];
			8'h17: spi_r <= spi_reg[191:184];
			8'h18: spi_r <= spi_reg[199:192];  //clk2 read data			
			8'h19: spi_r <= spi_reg[207:200];
			8'h1A: spi_r <= spi_reg[215:208];
			8'h1B: spi_r <= spi_reg[223:216];
												
			8'h20: spi_r <= {6'h0,spi_reg[257:256]}; //clk3 control
			8'h21: spi_r <= spi_reg[271:264];  // clk3 spi clk setting
		//	8'h22: spi_r <= spi_reg[279:272];  //Reserved
		//	8'h23: spi_r <= spi_reg[287:280];
			8'h24: spi_r <= spi_reg[295:288];  //clk3 write data
			8'h25: spi_r <= spi_reg[303:296];
			8'h26: spi_r <= spi_reg[311:304];
			8'h27: spi_r <= spi_reg[319:312];
			8'h28: spi_r <= spi_reg[327:320];  //clk3 read data		
			8'h29: spi_r <= spi_reg[335:328];
      8'h2A: spi_r <= spi_reg[343:336];
			8'h2B: spi_r <= spi_reg[351:344];	
       
		  8'h50: spi_r <= {7'b0,fpga_ics557_sel_o};
			
			default: spi_r <= 8'h0;
		endcase
	end
end


////////////// DSP Timer 0
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) half_clk <= 1'h0;
	else half_clk <= ~half_clk;
end
//////////////// DSP Boot Configuration
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) begin
			dsp_gpio_en <= 1'b1;
			dsp_gpio_ctrl_delay <= 16'h0;
			dsp_timi0_o <= pciessen_i;
	end
	
	else if ((~dsp_porz_o && ~dsp_resetstat_nd[1]) || (~dsp_resetfullz_o && ~dsp_resetstat_nd[1])) begin
			dsp_gpio_en <= 1'b1;
			dsp_gpio_ctrl_delay <= 16'h0;
			dsp_timi0_o <= pciessen_i;
			
	end		
	
	else if (~dsp_resetstat_nd[1] && dsp_gpio_en ) begin
	        dsp_gpio_en <= 1'b1;
			dsp_gpio_ctrl_delay <= 16'h0;
			dsp_timi0_o <= pciessen_i; 
	end		

    else if (dsp_gpio_ctrl_delay >= `DSP_GPIO_Output_delay_time) begin		//1ms
			dsp_gpio_en <= 1'b0;	
			dsp_timi0_o <= half_clk; 
	end
	else begin			
			dsp_gpio_en <= 1'b1;
			dsp_gpio_ctrl_delay <= dsp_gpio_ctrl_delay + 1;	
			dsp_timi0_o <= pciessen_i; 
	end								
end		
/////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// EVM Power Control & Sequence
//////////////////////////////////////////////////////////////////////

always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) 
		all_power <= 1'b0;
	else 
		all_power <= vcc5_pgood_d[1] & vcc2p5_pgood_d[1] & ucd9222_pg1_d[1] & ucd9222_pg2_d[1] & pgucd9222_d[1] & vcc1p8_pgood_d[1] & vcc1p5_pgood_d[1] & vcc0p75_pgood_d[1];
end	
		
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) fail_power_c <= 8'h0;
	else if ((PW_SM==4'ha) && (~all_power)) fail_power_c <= fail_power_c + 1'b1;
	else fail_power_c <= 8'h0;
end
/*******************************/  
/**** 	POWER ON SEQUENCE  *****/
/*******************************/
//parameter SM_IDLE	=4'h0; 
//parameter SM_V2P5	=4'h1; 
//parameter SM_PMBS	=4'h2; 
//parameter SM_PMB2	=4'h3; 
//parameter SM_V1P8	=4'h4; 
//parameter SM_V1P5	=4'h5; 
//parameter SM_V075	=4'h6; 
//parameter SM_CLKG	=4'h7;
//parameter SM_PORWR	=4'h8; 
//parameter SM_WAIT	=4'h9; 
//parameter SM_PWOK	=4'ha; 
//parameter SM_POFF1	=4'hb;
//parameter SM_POFF2	=4'hc;
//parameter SM_FAIL	=4'hd;  
always@(posedge main_48mhz_clk_r_i or negedge fpga_ireset_n)		
begin
	if (~fpga_ireset_n) begin
		PW_SM <= SM_IDLE;
		ucd9222_ena1_o <= 1'b0;
		ucd9222_ena2_o <= 1'b0;
		ucd9222_rst_no <= 1'b1;			 //reset //20110211
		vcc1p5_en_o <= 1'b0;
		vcc1p8_en1_o <= 1'b0;
		vcc0p75_en_o <= 1'b0;
		vcc2p5_en_o <= 1'b0;
		vcc_5v_en_o <= 1'b1;//troy20110411
		refclk2_pd_no <= 1'b0;	
		refclk3_pd_no <= 1'b0;	 
		PW_c <= 24'h0;
		power_fail <= 1'b0;
		vcc5_pgood_d   <= 2'b00;
        vcc2p5_pgood_d <= 2'b00;
        vcc1p8_pgood_d <= 2'b00;
        vcc1p5_pgood_d <= 2'b00;
        vcc0p75_pgood_d<= 2'b00;
        ucd9222_pg1_d  <= 2'b00;
        ucd9222_pg2_d  <= 2'b00;
        pgucd9222_d    <= 2'b00;
        clock2_pll_lock_d <= 2'b00;
        clock3_pll_lock_d <= 2'b00;
        dsp_resetstat_nd  <= 2'b00;
		set_clk2_c <= 24'h0;
		set_clk3_c <= 24'h0;
		set_clk2 <= 1'b0;
		set_clk3 <= 1'b0;
		//PG_ST <= 4'h0;
		latch_pgs <= 8'h0;   //20110128
		
    fpga_ics557_oe_o   <= 1'b0;
    fpga_ics557_pd_no  <= 1'b0;

    vid_oe_no          <= 1'b1;			
   
    clk_mux_control_latch        <= 1'b0;//troy20111201		    
	end
	else begin
	    vcc5_pgood_d      <= {vcc5_pgood_d[0],vcc5_pgood_i};
        vcc2p5_pgood_d    <= {vcc2p5_pgood_d[0],vcc2p5_pgood_i};
        vcc1p8_pgood_d    <= {vcc1p8_pgood_d[0],vcc1p8_pgood_i};
        vcc1p5_pgood_d    <= {vcc1p5_pgood_d[0],vcc1p5_pgood_i};
        vcc0p75_pgood_d   <= {vcc0p75_pgood_d[0],vcc0p75_pgood_i};
        ucd9222_pg1_d     <= {ucd9222_pg1_d[0],ucd9222_pg1_i};
        ucd9222_pg2_d     <= {ucd9222_pg2_d[0],ucd9222_pg2_i};
		pgucd9222_d       <= {pgucd9222_d[0],pgucd9222_i};
        clock2_pll_lock_d <= {clock2_pll_lock_d[0],clock2_pll_lock};
        clock3_pll_lock_d <= {clock3_pll_lock_d[0],clock3_pll_lock};
        dsp_resetstat_nd  <= {dsp_resetstat_nd[0],dsp_resetstat_ni};
	    
		case (PW_SM)

		SM_IDLE: begin
                        if (PW_c >= `PowerOn_idle_time) begin//11ms
                                PW_SM      <= SM_V2P5;
                                PW_c       <= 24'h0;
                                power_fail <= 1'b0;
						end
                        else begin
                                PW_SM          <=SM_IDLE;
                                ucd9222_ena1_o <= 1'b0;
                                ucd9222_ena2_o <= 1'b0;
                                ucd9222_rst_no <= 1'b1;
                                vcc1p5_en_o    <= 1'b0;
                                vcc1p8_en1_o   <= 1'b0;
                                vcc0p75_en_o   <= 1'b0;
                                vcc2p5_en_o    <= 1'b0;
                                vcc_5v_en_o    <= 1'b1;//troy 20110411
                                refclk2_pd_no  <= 1'b0;
                                refclk3_pd_no  <= 1'b0;
                                PW_c           <= PW_c + 1;
                                power_fail     <= 1'b0;
								//PG_ST <= 4'h0;
								latch_pgs <= 8'h0;   //20110128
								
                        fpga_ics557_oe_o   <= 1'b0;//troy 20110509
                        fpga_ics557_pd_no  <= 1'b0;//troy 20110509								
                        vid_oe_no          <= 1'b1;//troy 20110509											
                        end  
				end

                SM_V2P5: begin
                         vcc2p5_en_o <= 1'b1;
                         vcc_5v_en_o <= 1'b1;
						 ucd9222_rst_no <= 1'b1;
                         if(vcc5_pgood_d[1] & vcc2p5_pgood_d[1]) begin//10ms
                            if(PW_c >= `PowerOn_v2p5_time) begin
                               PW_SM <= SM_PMBS;
                               PW_c  <= 24'h0;
                            end

                            else begin
                                PW_SM <= SM_V2P5;
                                PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;
                        end

                        else begin
                             PW_SM <= SM_V2P5;
                     /*        PW_c  <= PW_c + 1;    //disable PM_Fail //20110103
                             if (PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 PW_SM      <= SM_FAIL;
                             end                          

                             else power_fail <= 1'b0;   */
                        end
                end

                SM_PMBS: begin
                         ucd9222_ena1_o <= 1'b1;
                         ucd9222_ena2_o <= 1'b1;								 
                         //if (ucd9222_pg1_d[1]) begin	//10ms
                             if(PW_c >= `PowerOn_pmbs_time) begin



                                PW_SM <= SM_PMB2;
                                PW_c  <= 24'h0;
                             end

                             else begin
                                  PW_SM <= SM_PMBS;
                                  PW_c  <= PW_c + 1;
                             end
                             power_fail <= 1'b0;
                         /* end
                        
                         else begin			
                             PW_SM <= SM_PMBS;
                             PW_c  <= PW_c + 1;
                             if(PW_c >= `PowerOn_fail_time) begin
                                power_fail <= 1'b1;
                                //PW_SM      <= SM_FAIL;  //20110103 for Alex debug
								PW_SM <= SM_PMBS;     //20110103 for Alex debug
                             end
                             else power_fail <= 1'b0;
                         end       */    //disable PM_Fail //20110103
                end

                SM_PMB2: begin
                         ucd9222_ena2_o <= 1'b1;
                         //if(ucd9222_pg2_d[1] & pgucd9222_d[1]) begin	
						 if(ucd9222_pg1_d[1] & ucd9222_pg2_d[1] & pgucd9222_d[1]) begin	
                            if(PW_c >= `PowerOn_pmb2_time) begin


                               PW_SM <= SM_V1P8;
                               PW_c  <= 24'h0;
							   set_clk2_c <= 24'h0;
							   set_clk3_c <= 24'h0;
                            end

                            else begin
                                 PW_SM <= SM_PMB2;
                                 PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;
                         end

                         else begin
                              PW_SM <= SM_PMB2;
                         /*     PW_c  <= PW_c + 1;
                              if(PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 //PW_SM      <= SM_FAIL;   //20110103 for Alex debug
								 PW_SM <= SM_PMB2;
                              end

                              else power_fail <= 1'b0;   */
                         end
                end

                SM_V1P8: begin
                         vcc1p8_en1_o <= 1'b1;
                         if(vcc1p8_pgood_d[1]) begin//10ms
						    refclk2_pd_no <= 1'b1;   //Matt 20101215
                            if(PW_c >= `PowerOn_v1p8_time) begin
							   refclk3_pd_no <= 1'b1;	 //Matt 20101215
							   set_clk2 <= 1'b1;         //Initial clk2
							   if(set_clk2_c  >= `Set_Clk2_time) begin
							      if(clock2_pll_lock_d[1]) begin 
								     set_clk3 <= 1'b1;  
							         if(set_clk3_c  >= `Set_Clk3_time) begin
										PW_SM <= SM_V1P5;
										PW_c  <= 24'h0;
										set_clk2_c <= 24'h0;
										set_clk3_c <= 24'h0;
									 end
                                     else begin	
                                        PW_SM <= SM_V1P8;
										set_clk3_c <= set_clk3_c +1;
									 end
                                  end
								  else begin
									 PW_SM <= SM_V1P8;
								  end
                               end
                               else begin	
                                     PW_SM <= SM_V1P8;
                                 	 set_clk2_c <= set_clk2_c +1;	
                               end									 					
                            end

                            else begin
                              PW_SM <= SM_V1P8;
                              PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;
                         end

                         else begin
                              PW_SM <= SM_V1P8;
                         /*     PW_c  <= PW_c + 1;
                              if(PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 PW_SM      <= SM_FAIL;
                              end

                              else power_fail <= 1'b0;    */
                         end
                end

                SM_V1P5: begin
                         vcc1p5_en_o <= 1'b1;						 							 
                         if(vcc1p5_pgood_d[1]) begin//10ms	
                            if(PW_c >= `PowerOn_v1p5_time) begin
	                             fpga_ics557_pd_no  <= 1'b1;//troy 20110509			
                               vid_oe_no          <= 1'b0;//troy 20110509			

                               PW_SM <= SM_V075;
                               PW_c  <= 24'h0;
                            end

                            else begin
                                 PW_SM <= SM_V1P5;
                                 PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;
                         end

                         else begin
                              PW_SM <= SM_V1P5;
                         /*     PW_c  <= PW_c + 1;
                              if(PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 PW_SM      <= SM_FAIL;
                              end

                              else power_fail <= 1'b0;   */
                         end
                end

                SM_V075: begin
                         vcc0p75_en_o <= 1'b1;
                         if(vcc0p75_pgood_d[1]) begin//10ms	
                            if(PW_c >= `PowerOn_v075_time) begin



                               PW_SM <= SM_CLKG;
                               PW_c  <= 24'h0;
                            end
                            
                            else begin
                                 PW_SM <= SM_V075;
                                 PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;							
                         end

                         else begin			
                              PW_SM <= SM_V075;
                         /*     PW_c  <= PW_c + 1;
                              if(PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 PW_SM      <= SM_FAIL;
                              end

                              else power_fail <= 1'b0;     */
                         end
                end

                SM_CLKG: begin
					 
                         if(clock2_pll_lock_d[1] & clock3_pll_lock_d[1]) begin//10ms	
                            fpga_ics557_oe_o   <= 1'b1;//troy 20110509                         
                            if(PW_c >= `PowerOn_clkg_time) begin
                               PW_SM <= SM_PORWR;
                               PW_c  <= 24'h0;
                            end

                            else begin
                                 PW_SM <= SM_CLKG;
                                 PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;							
                         end

                         else begin			
                              PW_SM      <= SM_CLKG;	 
                         /*     PW_c       <= PW_c + 1;
                              power_fail <= 1'b0;        */
                         end
                end
				
				SM_PORWR: begin    // POR deasserted	
				         power_fail <= 1'b0;
                         if(PW_c >= `PowerOn_wait_time) begin
                               PW_SM <= SM_WAIT;
                               PW_c  <= 24'h0;
                         end
                            
                         else begin
                               PW_SM <= SM_PORWR;
                               PW_c  <= PW_c + 1;
                         end

                end

                SM_WAIT: begin
                         if(dsp_resetstat_nd[1]) begin//10ms	
                            if(PW_c >= `PowerOn_wait_time) begin



                               PW_SM <= SM_PWOK;
                               PW_c  <= 24'h0;
                               clk_mux_control_latch<=1'b1;//troy20110812
                               
                               
                            end
                            
                            else begin
                                 PW_SM <= SM_WAIT;
                                 PW_c  <= PW_c + 1;
                            end
                            power_fail <= 1'b0;							
                         end

                         else begin			
                              PW_SM <= SM_WAIT;
                          /*    PW_c  <= PW_c + 1;
                              if(PW_c >= `PowerOn_fail_time) begin
                                 power_fail <= 1'b1;
                                 PW_SM      <= SM_FAIL;  //20110101
                              end

                              else power_fail <= 1'b0;    */
                         end
                end

                SM_PWOK: begin			
                         power_fail <= 1'b0;
                         PW_c       <= 24'h0;	
                         
						             clk_mux_control_latch<=1'b0;//troy 20111201                         
                         
                         if(fail_power_c > `PowerOk_fail_time) PW_SM <= SM_POFF1;
                         else                                  PW_SM <= SM_PWOK;								
                end

                SM_POFF1: begin
                          power_fail <= 1'b1;
						  latch_pgs[3:0] <= {vcc0p75_pgood_d[1], pgucd9222_d[1], ucd9222_pg2_d[1], ucd9222_pg1_d[1]};  //20110128
						  latch_pgs[7:4] <= {vcc5_pgood_d[1], vcc2p5_pgood_d[1], vcc1p8_pgood_d[1], vcc1p5_pgood_d[1]};  //20110128
						  //PG_ST[3:0] <= {vcc0p75_pgood_d[1], pgucd9222_d[1], ucd9222_pg2_d[1], ucd9222_pg1_d[1]};
                          if(PW_c >= `PowerOff_delay_time) begin
                             PW_SM <= SM_POFF2;
                             PW_c  <= 24'h0;
                          end
                          
                          else begin  
                               PW_SM <= SM_POFF1;
                               PW_c  <= PW_c + 1;
                          end  
                end	
			
                SM_POFF2: begin
                          power_fail     <= 1'b1;
                          PW_SM          <= SM_POFF2;

                          ucd9222_ena1_o <= 1'b0;
                          ucd9222_ena2_o <= 1'b0;
                          ucd9222_rst_no <= 1'b1;			
                          vcc1p5_en_o    <= 1'b0;
                          vcc1p8_en1_o   <= 1'b0;
                          vcc0p75_en_o   <= 1'b0;
                          vcc2p5_en_o    <= 1'b0;
                          //vcc_5v_en_o    <= 1'b0;//troy20110411	
                          refclk2_pd_no  <= 1'b0;	
                          refclk3_pd_no  <= 1'b0;	   	  
                          PW_c           <= 24'b0;
                end

              SM_FAIL: begin	
                         PW_SM <= SM_FAIL;		 
                end  
			  default: begin
				         PW_SM <= SM_IDLE;
			  end		 
																																				
		endcase
					
	end
end

endmodule 

