// --------------------------------------------------------------------
// Copyright (c) 2010 by Terasic Technologies Inc. 
// --------------------------------------------------------------------
//
// Permission:
//
//   Terasic grants permission to use and modify this code for use
//   in synthesis for all Terasic Development Boards and Altrea Development 
//   Kits made by Terasic.  Other use of this code, including the selling 
//   ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL or Verilog source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Terasic provides no warranty regarding the use 
//   or functionality of this code.
//
// --------------------------------------------------------------------
//           
//                     Terasic Technologies Inc
//                     356 Fu-Shin E. Rd Sec. 1. JhuBei City,
//                     HsinChu County, Taiwan
//                     302
//
//                     web: http://www.terasic.com/
//                     email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions: DE4 CAMERA LINK PCIe demo
//                  CLR -----> HSMC-> B 
//                  PCIe-----> x8 Gen2
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
//   Ver  :| Author            :| Mod. Date :| Changes Made:
//   V1.0 :| Peli Li           :| 11/18/2010:| Initial Revision
// --------------------------------------------------------------------

module DE4_GOLDEN_TOP (

	//////// CLOCK //////////
	GCLKIN,
	GCLKOUT_FPGA,
	OSC_50_BANK2,
	OSC_50_BANK3,
	OSC_50_BANK4,
	OSC_50_BANK5,
	OSC_50_BANK6,
	OSC_50_BANK7,
	PLL_CLKIN_p,

	//////// External PLL //////////
	MAX_I2C_SCLK,
	MAX_I2C_SDAT,

	//////// LED x 8 //////////
	LED,

	//////// BUTTON x 4, EXT_IO and CPU_RESET_n //////////
	BUTTON,
	CPU_RESET_n,
	EXT_IO,

	//////// DIP SWITCH x 8 //////////
	SW,

	//////// SLIDE SWITCH x 4 //////////
	SLIDE_SW,

	//////// SEG7 //////////
	SEG0_D,
	SEG0_DP,
	SEG1_D,
	SEG1_DP,

	//////// Temperature //////////
	TEMP_INT_n,
	TEMP_SMCLK,
	TEMP_SMDAT,

	//////// Current //////////
	CSENSE_ADC_FO,
	CSENSE_CS_n,
	CSENSE_SCK,
	CSENSE_SDI,
	CSENSE_SDO,

	//////// Fan //////////
	FAN_CTRL,

	//////// EEPROM //////////
	EEP_SCL,
	EEP_SDA,

	//////// SDCARD //////////
	SD_CLK,
	SD_CMD,
	SD_DAT,
	SD_WP_n,
	
	/////// PCIe x 8 //////////
	PCIE_PREST_n,
	PCIE_REFCLK_p,
	PCIE_RX_p,
	PCIE_SMBCLK,
	PCIE_SMBDAT,
	PCIE_TX_p,
	PCIE_WAKE_n,

	//////// RS232 //////////
	UART_CTS,
	UART_RTS,
	UART_RXD,
	UART_TXD,

	//////// Ethernet x 4 //////////
	ETH_INT_n,
	ETH_MDC,
	ETH_MDIO,
	ETH_RST_n,
	ETH_RX_p,
	ETH_TX_p,

	//////// Flash and SRAM Address/Data Share Bus //////////
	FSM_A,
	FSM_D,

	//////// Flash Control //////////
	FLASH_ADV_n,
	FLASH_CE_n,
	FLASH_CLK,
	FLASH_OE_n,
	FLASH_RESET_n,
	FLASH_RYBY_n,
	FLASH_WE_n,

	//////// SSRAM Control //////////
	SSRAM_ADV,
	SSRAM_BWA_n,
	SSRAM_BWB_n,
	SSRAM_CE_n,
	SSRAM_CKE_n,
	SSRAM_CLK,
	SSRAM_OE_n,
	SSRAM_WE_n,

	//////// 3-Ports High-Speed USB OTG //////////
	OTG_A,
	OTG_CS_n,
	OTG_D,
	OTG_DC_DACK,
	OTG_DC_DREQ,
	OTG_DC_IRQ,
	OTG_HC_DACK,
	OTG_HC_DREQ,
	OTG_HC_IRQ,
	OTG_OE_n,
	OTG_RESET_n,
	OTG_WE_n,

	//////// DDR2 SODIMM //////////
	M1_DDR2_addr,
	M1_DDR2_ba,
	M1_DDR2_cas_n,
	M1_DDR2_cke,
	M1_DDR2_clk,
	M1_DDR2_clk_n,
	M1_DDR2_cs_n,
	M1_DDR2_dm,
	M1_DDR2_dq,
	M1_DDR2_dqs,
	M1_DDR2_dqsn,
	M1_DDR2_odt,
	M1_DDR2_ras_n,
	M1_DDR2_SA,
	M1_DDR2_SCL,
	M1_DDR2_SDA,
	M1_DDR2_we_n,
	//////// HSMC-A //////////
	DVI_EDID_WP,
	DVI_RX_CLK,
	DVI_RX_CTL,
	DVI_RX_D,
	DVI_RX_DDCSCL,
	DVI_RX_DDCSDA,
	DVI_RX_DE,
	DVI_RX_HS,
	DVI_RX_SCDT,
	DVI_RX_VS,
	DVI_TX_CLK,
	DVI_TX_CTL,
	DVI_TX_D,
	DVI_TX_DDCSCL,
	DVI_TX_DDCSDA,
	DVI_TX_DE,
	DVI_TX_DKEN,
	DVI_TX_HS,
	DVI_TX_HTPLG,
	DVI_TX_ISEL,
	DVI_TX_MSEN,
	DVI_TX_PD_N,
	DVI_TX_SCL,
	DVI_TX_SDA,
	DVI_TX_VS,

	//////// HSMC-B //////////
	CLR_CLKIN_n1,
	CLR_CLKIN_n2,
	CLR_CLKIN_p1,
	CLR_CLKIN_p2,
	CLR_CLKIN0,
	CLR_CLKOUT_n2,
	CLR_CLKOUT_p2,
	CLR_D,
//	CLR_GXB_RX_p,
//	CLR_GXB_TX_p,
	CLR_OUT_n1,
	CLR_OUT_p1,
	CLR_OUT0,
	CLR_RX_n,
	CLR_RX_p,
	CLR_TX_n,
	CLR_TX_p,

	//////// HSMC I2C //////////
	HSMC_SCL,
	HSMC_SDA, 
	
	//  test 
	//,serial_flag
//	testcnt,testcntO //DDR2 test
);

//=======================================================
//  PARAMETER declarations
//=======================================================
parameter  IMAGE_WITH    =  32'h00000280;  //640
parameter  IMAGE_HEIGHT  =  32'h000001E0;  //480
//note: if you want to change the image resolution,you should change the belows:
//1.the ccd_capture output image resolution
//2.RAW2RGB module (line buffer taps distance)
//3.DDR2 frame buffer size
//4.PCIe software application output resolution
//=======================================================
//  PORT declarations
//=======================================================

//////////// CLOCK //////////
input		          		GCLKIN;
output		          	GCLKOUT_FPGA;
input		          		OSC_50_BANK2;
input		          		OSC_50_BANK3;
input		          		OSC_50_BANK4;
input		          		OSC_50_BANK5;
input		          		OSC_50_BANK6;
input		          		OSC_50_BANK7;
input		          		PLL_CLKIN_p;

//////////// External PLL //////////
output		          	MAX_I2C_SCLK;
inout		          		MAX_I2C_SDAT;

//////////// LED x 8 //////////
output	reg [7:0]		LED;

//////////// BUTTON x 4, EXT_IO and CPU_RESET_n //////////
input		     [3:0]		BUTTON;
input		          		CPU_RESET_n;
inout		          		EXT_IO;

//////////// DIP SWITCH x 8 //////////
input		     [7:0]		SW;

//////////// SLIDE SWITCH x 4 //////////
input		     [3:0]		SLIDE_SW;

//////////// SEG7 //////////
output		  [6:0]		SEG0_D;
output		        		SEG0_DP;
output		   [6:0]		SEG1_D;
output		        		SEG1_DP;

//////////// Temperature //////////
input		          		TEMP_INT_n;
output		          	TEMP_SMCLK;
inout		          		TEMP_SMDAT;

//////////// Current //////////
output		          	CSENSE_ADC_FO;
output		   [1:0]		CSENSE_CS_n;
output		         	CSENSE_SCK;
output		          	CSENSE_SDI;
input		          		CSENSE_SDO;

//////////// Fan //////////
output		          	FAN_CTRL;

//////////// EEPROM //////////
output		          	EEP_SCL;
inout		          		EEP_SDA;

//////////// SDCARD //////////
output		          	SD_CLK;
inout		          		SD_CMD;
inout		     [3:0]		SD_DAT;
input		          		SD_WP_n;

//////////// PCIe x 8 //////////
input		          	   PCIE_PREST_n;
input		          	   PCIE_REFCLK_p;
input			 [7:0]		PCIE_RX_p;
input		          	   PCIE_SMBCLK;
inout		          	   PCIE_SMBDAT;
output		 [7:0]		PCIE_TX_p;
output		            PCIE_WAKE_n;

//////////// RS232 //////////
output		        		UART_CTS;
input		          		UART_RTS;
input		          		UART_RXD;
output		        		UART_TXD;

//////////// Ethernet x 4 //////////
input		     [3:0]		ETH_INT_n;
output		   [3:0]		ETH_MDC;
inout		     [3:0]		ETH_MDIO;
output		        		ETH_RST_n;
input		     [3:0]		ETH_RX_p;
output		   [3:0]		ETH_TX_p;

//////////// Flash and SRAM Address/Data Share Bus //////////
output		  [25:1]		FSM_A;
inout		    [15:0]		FSM_D;

//////////// Flash Control //////////
output		        		FLASH_ADV_n;
output		        		FLASH_CE_n;
output		        		FLASH_CLK;
output		        		FLASH_OE_n;
output		        		FLASH_RESET_n;
input		          		FLASH_RYBY_n;
output		          	FLASH_WE_n;

//////////// SSRAM Control //////////
output		          	SSRAM_ADV;
output		          	SSRAM_BWA_n;
output		          	SSRAM_BWB_n;
output		          	SSRAM_CE_n;
output		        		SSRAM_CKE_n;
output		          	SSRAM_CLK;
output		          	SSRAM_OE_n;
output		          	SSRAM_WE_n;

//////////// 3-Ports High-Speed USB OTG //////////
output		  [17:1]		OTG_A;
output		        		OTG_CS_n;
inout		    [31:0]		OTG_D;
output		        		OTG_DC_DACK;
input		          		OTG_DC_DREQ;
input		          		OTG_DC_IRQ;
output		          	OTG_HC_DACK;
input		          		OTG_HC_DREQ;
input		          		OTG_HC_IRQ;
output		          	OTG_OE_n;
output		          	OTG_RESET_n;
output		          	OTG_WE_n;

//////////// DDR2 SODIMM //////////
output		  [15:0]		M1_DDR2_addr;
output		   [2:0]		M1_DDR2_ba;
output		        		M1_DDR2_cas_n;
output		   [1:0]		M1_DDR2_cke;
inout		     [1:0]		M1_DDR2_clk;
inout		     [1:0]		M1_DDR2_clk_n;
output		   [1:0]		M1_DDR2_cs_n;
output		   [7:0]		M1_DDR2_dm;
inout		    [63:0]		M1_DDR2_dq;
inout		     [7:0]		M1_DDR2_dqs;
inout		     [7:0]		M1_DDR2_dqsn;
output		  [1:0]		M1_DDR2_odt;
output		        		M1_DDR2_ras_n;
output		  [1:0]		M1_DDR2_SA;
output		        		M1_DDR2_SCL;
inout		          		M1_DDR2_SDA;
output		          	M1_DDR2_we_n;

//////////// HSMC-A //////////
output		          	DVI_EDID_WP;
input		          		DVI_RX_CLK;
input		     [3:1]		DVI_RX_CTL;
input		    [23:0]		DVI_RX_D;
inout		          		DVI_RX_DDCSCL;
inout		          		DVI_RX_DDCSDA;
input		          		DVI_RX_DE;
input		          		DVI_RX_HS;
input		          		DVI_RX_SCDT;
input		          		DVI_RX_VS;
output		          	DVI_TX_CLK;
output		   [3:1]		DVI_TX_CTL;
output		  [23:0]		DVI_TX_D;
inout		          		DVI_TX_DDCSCL;
inout		          		DVI_TX_DDCSDA;
output		        		DVI_TX_DE;
output		        		DVI_TX_DKEN;
output		        		DVI_TX_HS;
output		        		DVI_TX_HTPLG;
output		        		DVI_TX_ISEL;
output		        		DVI_TX_MSEN;
output		        		DVI_TX_PD_N;
output		          	DVI_TX_SCL;
inout		          		DVI_TX_SDA;
output		          	DVI_TX_VS;

//////////// HSMC-B //////////
input		          		CLR_CLKIN_n1;
input		          		CLR_CLKIN_n2;
input		          		CLR_CLKIN_p1;
input		          		CLR_CLKIN_p2;
input		          		CLR_CLKIN0;
input 		          	CLR_CLKOUT_n2;
input 		          	CLR_CLKOUT_p2;
inout		     [3:0]		CLR_D;
//input		     [7:0]		CLR_GXB_RX_p;
//output		     [7:0]		CLR_GXB_TX_p;
input 		          	CLR_OUT_n1;
input 		          	CLR_OUT_p1;
input 		          	CLR_OUT0;
input		    [16:0]		CLR_RX_n;
input		    [16:0]		CLR_RX_p;
input		    [16:0]		CLR_TX_n;
input		    [16:0]		CLR_TX_p;

//////////// HSMC I2C //////////
output		          	HSMC_SCL;
inout		          		HSMC_SDA;


//=======================================================
//  REG/WIRE declarations
//=======================================================
// CAMERA LINK
wire							CLR_CLK_120;
wire							CLR_BASE_CLK;
wire		     [9:0]		CLR_BASE_D;
wire							CLR_BASE_FVAL;
wire							CLR_BASE_DVAL;
//frame buffer
wire	       [15:0]	   Read_DATA1;
wire	       [15:0]	   Read_DATA2;
wire                    wrt_full_port0;
wire                    ip_init_done;
//ccd capture
wire	       [15:0]	   X_Cont;
wire	       [15:0]	   Y_Cont;
wire		     [9:0]		cap_data;
wire							cap_dval;
wire                    oWRITE_w1;
wire		     [9:0]		red;
wire		     [9:0]		green;
wire		     [9:0]		blue;
wire                    dval;
wire						   start;
wire						   rst_n;

//PCIe
reg                     sc_rd_dval;
wire 	        [11:0]    sc_rd_addr;
reg 	        [31:0]    sc_rd_data;
wire                    sc_rd_read;
wire          [11:0]    sc_wr_addr;
wire 	        [31:0]    sc_wr_data;
wire	                  sc_wr_write;

wire	        [31:0]    dmard_addr;
wire	                  dmard_read;
wire	                  dmard_rdvalid;
wire	       [127:0]    dmard_data;

wire	                  dmawr_write;
wire	        [31:0]    dmawr_addr;
wire	       [127:0]    dmawr_data;
wire	        [15:0]    dmawr_be;

wire	                  user_int_ack;
wire	                  fifo_mem_sel;

wire                    clk_out_buf;
wire         [31:0]     ddr2_write_data_32;

//=======================================================
//  Structural coding
//=======================================================
//switch on the fan
assign FAN_CTRL = 1'b1;

//camera link
assign	CLR_BASE_CLK	=	CLR_CLKIN_p1;
assign	CLR_BASE_D[0]	=	CLR_OUT0;
assign	CLR_BASE_D[1]	=	CLR_CLKIN0;
assign	CLR_BASE_D[2]	=	CLR_D[0];
assign	CLR_BASE_D[3]	=	CLR_D[2];
assign	CLR_BASE_D[4]	=	CLR_TX_p[0];
assign	CLR_BASE_D[5]	=	CLR_TX_p[1];
assign	CLR_BASE_D[6]	=	CLR_TX_n[4];
assign	CLR_BASE_D[7]	=	CLR_TX_n[0];
assign	CLR_BASE_D[8]	=	CLR_D[1];
assign	CLR_BASE_D[9]	=	CLR_D[3];
assign	CLR_BASE_FVAL	=	CLR_TX_n[5];
assign	CLR_BASE_DVAL	=	CLR_TX_p[6];
//reset module
Reset_Delay	Reset_Delay_cmp
		(
			.iCLK(OSC_50_BANK7),
//			.iCLK(CLR_BASE_CLK),
			.iRST(BUTTON[0]),
			.oRST_0(),
			.oRST_1(rst_n),
			.oRST_2(start)
		);
//camera link video capture
CCD_Capture  CCD_Capture_cmp
		(
			.iRST_n(rst_n),				
			.iGO(start),					
			.iWidth(IMAGE_WITH),			   
			.iHeight(IMAGE_HEIGHT),			

			.iCLK(CLR_BASE_CLK),			
			.iDATA(CLR_BASE_D),			
			.iFVAL(CLR_BASE_FVAL),		
			.iLVAL(CLR_BASE_DVAL),		
			.oX_CONT(X_Cont),				
			.oY_CONT(Y_Cont),				
			.oDATA(cap_data),				
			.oDVAL(cap_dval),				
			.oFINISH(),				
			.oFIFO_DVAL(oWRITE_w1),		
			.oLED(),
			.oWidth(oWidth),
			.oHeight(oHeight),
			.oStatus(oStatus)
		);
//bayer filter output change to 10-bit RGB
RAW2RGB  RAW2RGB_cmp
		(
			.iX_Cont(X_Cont),				
			.iY_Cont(Y_Cont),				
			.iDATA(cap_data),				
			.iDVAL(cap_dval),				
			.iCLK(CLR_BASE_CLK),			
			.iRST(rst_n),				
			.oRed(red),						
			.oGreen(green),				
			.oBlue(blue),					
			.oDVAL(dval)					
		);

//DDR2 Read and Write as Frame Buffer
DE4_SOPC   u8    (
                         // global signals
						   .clk_50(OSC_50_BANK7),
						   .reset_n(rst_n), //Button[0]

						 // the_Read_Port0   pcie as master
						   .iCLK_F_to_the_Read_Port0(clk_out_buf), 
						   .iIP_INIT_DONE_to_the_Read_Port0(ip_init_done),
						   .iREAD_ACK_F_to_the_Read_Port0(fifo_read), 
						   .iRST_n_F_to_the_Read_Port0(read_rstn),
						   .oEMPTY_F_from_the_Read_Port0(),
						   .oPORT_READY_F_from_the_Read_Port0(),
						   .oREAD_DATA_F_from_the_Read_Port0(ddr2_write_data_32),
						   
						 // the_Write_Port0     
						   .iCLK_F_to_the_Write_Port0( CLR_BASE_CLK ), 
						   .iFLUSH_REQ_F_to_the_Write_Port0(),
						   .iIP_INIT_DONE_to_the_Write_Port0(ip_init_done),
						   .iRST_n_F_to_the_Write_Port0(rst_n),
						   .iWRITE_DATA_F_to_the_Write_Port0({red[9:2],green[9:2],blue[9:2],8'h00}), //1'b0,green[9:5],blue[9:0],1'b0,green[4:0],red[9:0] ddr2_write_data //bit width not the same
						   .iWRITE_F_to_the_Write_Port0(dval),
						   .oBURST_COUNT_from_the_Write_Port0(),
						   .oFLUSH_BUSY_F_from_the_Write_Port0(write_busy),
						   .oFULL_F_from_the_Write_Port0(wrt_full_port0),
						  						  
						  // the_ddr2   
						   .global_reset_n_to_the_ddr2(rst_n),
						   .local_init_done_from_the_ddr2(ip_init_done),
						   .mem_addr_from_the_ddr2(M1_DDR2_addr),
						   .mem_ba_from_the_ddr2(M1_DDR2_ba),
						   .mem_cas_n_from_the_ddr2(M1_DDR2_cas_n),
						   .mem_cke_from_the_ddr2(M1_DDR2_cke),
						   .mem_clk_n_to_and_from_the_ddr2(M1_DDR2_clk_n),
						   .mem_clk_to_and_from_the_ddr2(M1_DDR2_clk),
						   .mem_cs_n_from_the_ddr2(M1_DDR2_cs_n),
						   .mem_dm_from_the_ddr2(M1_DDR2_dm),
						   .mem_dq_to_and_from_the_ddr2(M1_DDR2_dq),
						   .mem_dqs_to_and_from_the_ddr2(M1_DDR2_dqs),
						   .mem_dqsn_to_and_from_the_ddr2(M1_DDR2_dqsn),
						   .mem_odt_from_the_ddr2(M1_DDR2_odt),
						   .mem_ras_n_from_the_ddr2(M1_DDR2_ras_n),
						   .mem_we_n_from_the_ddr2(M1_DDR2_we_n),
                        
                         );
//prevent from read at starting because of none data in the ddr2
reg	[15:0]write_cnt;
always@(posedge CLR_BASE_CLK) //CLR_BASE_CLK
	if (~{SW[2] ? BUTTON[0]: LED[0] })
		write_cnt <= 0;
	else if ( (dval) & (write_cnt != 65536) )
		write_cnt <= write_cnt + 1;
			                  
reg	read_rstn;
	always@(posedge CLR_BASE_CLK) //CLR_BASE_CLK
		begin
			if (~{SW[2] ? BUTTON[0]: LED[0] })
				read_rstn <= 0;
			else if (write_cnt == 256)
				read_rstn <= 1;
		end

//PCIe read from ddr2 readport
//	Terasic PCI Express x8 Interface
top_example_chaining_pipen1b core
(
  .core_clk_out (clk_out_buf),
  .gen2_speed (gen2_speed),
  .local_rstn (1'b1), //1'b1
  .pcie_rstn (1'b1), //input from pc pcie port PCIE_PREST_n 1'b1
  .phy_sel_code (),
  .pipe_mode (1'b0),
  .pld_clk (clk_out_buf),
  .refclk (PCIE_REFCLK_p),
  .rx_in0 (PCIE_RX_p[0]),
  .rx_in1 (PCIE_RX_p[1]),
  .rx_in2 (PCIE_RX_p[2]),
  .rx_in3 (PCIE_RX_p[3]),
  .rx_in4 (PCIE_RX_p[4]),
  .rx_in5 (PCIE_RX_p[5]),
  .rx_in6 (PCIE_RX_p[6]),
  .rx_in7 (PCIE_RX_p[7]),

  .tx_out0 (PCIE_TX_p[0]),
  .tx_out1 (PCIE_TX_p[1]),
  .tx_out2 (PCIE_TX_p[2]),
  .tx_out3 (PCIE_TX_p[3]),
  .tx_out4 (PCIE_TX_p[4]),
  .tx_out5 (PCIE_TX_p[5]),
  .tx_out6 (PCIE_TX_p[6]),
  .tx_out7 (PCIE_TX_p[7]),
  
  //Single Cycle Memory or Register R/W Local Interface  
  .sc_rd_addr       (sc_rd_addr),
  .sc_rd_data       (sc_rd_data),
  .sc_rd_read       (sc_rd_read),
  .sc_rd_dval 		  (sc_rd_dval),
      
  .sc_wr_addr       (sc_wr_addr),
  .sc_wr_data       (sc_wr_data),
  .sc_wr_write		  (sc_wr_write),
// DMA Read 
  .oDMARD_ADDR(dmard_addr),
  .oDMARD_READ(dmard_read),
  .oDMARD_RDVALID(dmard_rdvalid),
  .iDMARD_DATA(dmard_data),  
  .oDMARD_FRAME(dmard_frame),
// DMA Write
  .oDMAWR_WRITE(dmawr_write),
  .oDMAWR_ADDR(dmawr_addr),
  .oDMAWR_DATA(dmawr_data),
  .oDMAWR_BE(dmawr_be),
// DMA Interface Selection : 0--> memory, 1--> fifo
  .oFIFO_MEM_SEL(fifo_mem_sel),				
// PCI Express Interrupt
  .oINT_ACK(int_ack),
  .iINT_STS(int_sts),
  .oUSER_INT_ACK(user_int_ack),
//system clk 
  .iCLK_50(OSC_50_BANK2)  
  
);

//	Address Decode for Controlling LED & xor Register
reg	[31:0]xor_reg;
always@(posedge clk_out_buf)
	begin
		if ( (sc_wr_write) & ( sc_wr_addr == 32'h4 ) )
			LED <= sc_wr_data[7:0];
		else if ( (sc_wr_write) & ( sc_wr_addr == 32'h10 ) )
			xor_reg <= sc_wr_data;
	end

//	Address Decode for Button Status Monitor
always@(posedge clk_out_buf)
	begin
		if ( ( sc_rd_read ) & ( sc_rd_addr == 32'h4 ) )
			begin
				sc_rd_dval <= 1;
				sc_rd_data <= { 28'h0, BUTTON[3:0]};
			end
		else if ( ( sc_rd_read ) & ( sc_rd_addr == 32'h10 ) )
			begin
				sc_rd_dval <= 1;
				sc_rd_data <= xor_reg;
			end
		else
			begin
				sc_rd_data <= 0;
				sc_rd_dval <= 0;
			end
	end
	
//	Memory or FIFO Bus Selection
wire	ram_read;
wire	fifo_read;
assign	ram_read  = (~fifo_mem_sel)? dmard_read 	: 0;
assign	fifo_read = ( fifo_mem_sel)? dmard_rdvalid 	: 0;

wire	ram_write;
wire	fifo_write;
assign	ram_write = (~fifo_mem_sel)? dmawr_write 	: 0;
assign	fifo_write= ( fifo_mem_sel)? dmawr_write 	: 0;	

assign	dmard_data = (fifo_mem_sel )? {ddr2_write_data_32,96'h0000000000000000000000} : 0;

//============================================
//	Interrupt
//	Interrupt Generator
	reg	btn_press;
	always@(posedge OSC_50_BANK3)
		begin
			if (~CPU_RESET_n)
				btn_press <= 0;
			else if ( ((~BUTTON[1]) | (~BUTTON[2]) | (~BUTTON[3])) & (~btn_press) )
				btn_press <= 1;
			else if (press_cnt == 25000000)
				btn_press <= 0;
		end
		
	reg	[31:0]press_cnt;	
	always@(posedge OSC_50_BANK3)
		begin
			if (btn_press)
				press_cnt <= press_cnt + 1;
			else
				press_cnt <= 0;
		end
		
	reg	press_new;
	reg	press;	
	reg	press_falling;
	always@(posedge OSC_50_BANK3)
		begin
			press_new <= btn_press;
			press <= press_new;
			if (~press_new & press)
				press_falling <= 1;
			else
				press_falling <= 0;
		end
	
	wire	int_ack;
	reg	int_sts;	
	always@(posedge clk_out_buf)
		begin
			if (~CPU_RESET_n)
				int_sts <= 0;
			else if (press_falling)
				int_sts <= 1;
			else if (user_int_ack)
				int_sts <= 0;
				
		end


endmodule
