// --------------------------------------------------------------------
// 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 Altera 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/Verilog or C/C++ 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
//                     E. Rd Sec. 1. JhuBei City,
//                     HsinChu County, Taiwan
//                     302
//
//                     web: http://www.terasic.com/   
//                     email: support@terasic.com
//
// --------------------------------------------------------------------
// --------------------------------------------------------------------
//
// Major Functions:	XTS Test Demo
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
//   Ver  :| Author            :| Mod. Date :| Changes Made:
//   V1.0 :| BEN               :| 15/12/11  :| Initial Revision
// --------------------------------------------------------------------
module TR4_XTS(

	//////////// CLOCK //////////
	OSC_50_BANK1,
	OSC_50_BANK3,
	OSC_50_BANK4,
	OSC_50_BANK7,
	OSC_50_BANK8,

	//////////// Loop //////////
	LOOP_CLKIN0,
	LOOP_CLKIN1,
	LOOP_CLKOUT0,
	LOOP_CLKOUT1,

	//////////// LED x 4 //////////
	LED,

	//////////// BUTTON x 4 //////////
	BUTTON,

	//////////// SWITCH x 4 //////////
	SW,

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

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

	//////////// Flash and SRAM Address/Data/OE/WM Share Bus //////////
	FSM_A,
	FSM_D,
	FSM_OE_n,
	FSM_WE_n,

	//////////// Flash Control //////////
	FLASH_ADV_n,
	FLASH_CE_n,
	FLASH_CLK,
	FLASH_RDY_BSY_n,
	FLASH_RESET_n,
	FLASH_WP_n,

	//////////// SSRAM Control //////////
	SSRAM_ADSC_n,
	SSRAM_ADSP_n,
	SSRAM_ADV_n,
	SSRAM_BE_n,
	SSRAM_CE1_n,
	SSRAM_CLK,

	//////////// MAX2 //////////
	MAX2_SCL,
	MAX2_SDA,

	//////////// Programming PLL //////////
//	HSMA_REFCLK_p,
//	HSME_REFCLK_p,
//	PGM_GXB_CLK_p1,

	//////////// HSMC-A, HSMC-A connect to XTS - Transceiver to SMA //////////
	ACLKIN_P,
	ACLKIN0,
	ACLKOUT_P,
	ACLKOUT0,
	ARX_P,
	ATX_P,

	//////////// HSMC-E, HSMC-E connect to XTS - Transceiver to SMA //////////
	ECLKIN_P,
	ECLKIN0,
	ECLKOUT_P,
	ECLKOUT0,
	ERX_P,
	ETX_P,
	//////////// HSMC A/B/C I2C //////////
	HSMC_ABC_SCL,
	HSMC_ABC_SDA 
);

//=======================================================
//  PARAMETER declarations
//=======================================================


//=======================================================
//  PORT declarations
//=======================================================

//////////// CLOCK //////////
input 		          		OSC_50_BANK1;
input 		          		OSC_50_BANK3;
input 		          		OSC_50_BANK4;
input 		          		OSC_50_BANK7;
input 		          		OSC_50_BANK8;

//////////// Loop //////////
input 		          		LOOP_CLKIN0;
input 		          		LOOP_CLKIN1;
output		          		LOOP_CLKOUT0;
output		          		LOOP_CLKOUT1;

//////////// LED x 4 //////////
output		     [3:0]		LED;

//////////// BUTTON x 4 //////////
input 		     [3:0]		BUTTON;

//////////// SWITCH x 4 //////////
input 		     [3:0]		SW;

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

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

//////////// Flash and SRAM Address/Data/OE/WM Share Bus //////////
output		    [25:1]		FSM_A;
inout 		    [31:0]		FSM_D;
output		          		FSM_OE_n;
output		          		FSM_WE_n;

//////////// Flash Control //////////
output		          		FLASH_ADV_n;
output		          		FLASH_CE_n;
output		          		FLASH_CLK;
input 		          		FLASH_RDY_BSY_n;
output		          		FLASH_RESET_n;
output		          		FLASH_WP_n;

//////////// SSRAM Control //////////
output		          		SSRAM_ADSC_n;
output		          		SSRAM_ADSP_n;
output		          		SSRAM_ADV_n;
output		     [3:0]		SSRAM_BE_n;
output		          		SSRAM_CE1_n;
output		          		SSRAM_CLK;

//////////// MAX2 //////////
output		          		MAX2_SCL;
inout 		          		MAX2_SDA;

//////////// Programming PLL //////////
//input 		          		HSMA_REFCLK_p;
//input 		          		HSME_REFCLK_p;
//input 		          		PGM_GXB_CLK_p1;

//////////// HSMC-A, HSMC-A connect to XTS - Transceiver to SMA //////////

input 		     [2:1]		ACLKIN_P;
input 		          		ACLKIN0;
output		     [2:1]		ACLKOUT_P;
output		          		ACLKOUT0;
input 		     [3:0]		ARX_P;
output		     [3:0]		ATX_P;

//////////// HSMC-E, HSMC-E connect to XTS - Transceiver to SMA //////////
//
input 		     [2:1]		ECLKIN_P;
input 		          		ECLKIN0;
output		     [2:1]		ECLKOUT_P;
output		          		ECLKOUT0;
input 		     [3:0]		ERX_P;
output		     [3:0]		ETX_P;
//////////// HSMC A/B/C I2C //////////
output		          		HSMC_ABC_SCL;
inout 		          		HSMC_ABC_SDA;


//=======================================================
//  REG/WIRE declarations
//=======================================================
parameter                FREQ=50000000;
parameter                DFREQ=10;



//=======================================================
//  External PLL Configuration ==========================
//=======================================================

//  Signal declarations
wire [ 3: 0] clk1_set_wr, clk2_set_wr, clk3_set_wr;
wire         rstn;
wire         conf_ready;
wire         counter_max;
wire  [7:0]  counter_inc;
reg   [7:0]  auto_set_counter;
reg          conf_wr;

//  Structural coding
assign clk1_set_wr = 4'd4; //100 MHZ
assign clk2_set_wr = 4'd4; //100 MHZ
assign clk3_set_wr = 4'd4; //100 MHZ

assign rstn = 1'b1;
assign counter_max = &auto_set_counter;
assign counter_inc = auto_set_counter + 1'b1;

always @(posedge OSC_50_BANK1 or negedge rstn)
	if(!rstn)
	begin
		auto_set_counter <= 0;
		conf_wr <= 0;
	end 
	else if (counter_max)
		conf_wr <= 1;
	else
		auto_set_counter <= counter_inc;


ext_pll_ctrl ext_pll_ctrl_Inst(
	.osc_50(OSC_50_BANK1), //50MHZ
	.rstn(rstn),

	// device 1 (HSMA_REFCLK)
	.clk1_set_wr(clk1_set_wr),
	.clk1_set_rd(),

	// device 2 (HSME_REFCLK)
	.clk2_set_wr(clk2_set_wr),
	.clk2_set_rd(),

	// device 3 (PGM_GXB_CLK)
	.clk3_set_wr(clk3_set_wr),
	.clk3_set_rd(),

	// setting trigger
	.conf_wr(conf_wr), // 1T 50MHz 
	.conf_rd(), // 1T 50MHz

	// status 
	.conf_ready(conf_ready),

	// 2-wire interface 
	.max_sclk(MAX_SCL),
	.max_sdat(MAX_SDA)

);


//=======================================================
//  Structural coding
//=======================================================
wire              CLK_100;
wire              CLK_E100;
wire     [3:0]    test_error;
wire     [3:0]    test_error1;
reg      [31:0]   count;
reg               divclk;

assign            FAN_CTRL = 1'b1;

 
cal_pll0 p1(
	.inclk0(OSC_50_BANK4),
	.c0(CLK_E100)
	);
pll p0
(
	.areset(),
	.inclk0(OSC_50_BANK3),
	.c0(CLK_100),
	.locked());
xcvr_test g0(

.cal_blk_clk(OSC_50_BANK3),
.xcvr_refclk(CLK_100),
.irst_n(BUTTON[0]),
.xcvr_tx(ATX_P[0]),
.xcvr_rx(ARX_P[0]),
.error_insert(BUTTON[1]),
.test_error(test_error[0]),
.tx_clock(),
);
xcvr_test g1(

.cal_blk_clk(OSC_50_BANK3),
.xcvr_refclk(CLK_100),
.irst_n(BUTTON[0]),
.xcvr_tx(ATX_P[1]),
.xcvr_rx(ARX_P[1]),
.error_insert(BUTTON[1]),
.test_error(test_error[1]),
.tx_clock(),
);
xcvr_test g2(

.cal_blk_clk(OSC_50_BANK3),
.xcvr_refclk(CLK_100),
.irst_n(BUTTON[0]),
.xcvr_tx(ATX_P[2]),
.xcvr_rx(ARX_P[2]),
.error_insert(BUTTON[1]),
.test_error(test_error[2]),
.tx_clock(),
);
xcvr_test g3(

.cal_blk_clk(OSC_50_BANK3),
.xcvr_refclk(CLK_100),
.irst_n(BUTTON[0]),
.xcvr_tx(ATX_P[3]),
.xcvr_rx(ARX_P[3]),
.error_insert(BUTTON[1]),
.test_error(test_error[3]),
.tx_clock(),
);

xcvr_test g4(

.cal_blk_clk(OSC_50_BANK4),
.xcvr_refclk(CLK_E100),
.irst_n(BUTTON[0]),
.xcvr_tx(ETX_P[0]),
.xcvr_rx(ERX_P[0]),
.error_insert(BUTTON[1]),
.test_error(test_error1[0]),
.tx_clock(),
);
xcvr_test g5(

.cal_blk_clk(OSC_50_BANK4),
.xcvr_refclk(CLK_E100),
.irst_n(BUTTON[0]),
.xcvr_tx(ETX_P[1]),
.xcvr_rx(ERX_P[1]),
.error_insert(BUTTON[1]),
.test_error(test_error1[1]),
.tx_clock(),
);
xcvr_test g6(

.cal_blk_clk(OSC_50_BANK4),
.xcvr_refclk(CLK_E100),
.irst_n(BUTTON[0]),
.xcvr_tx(ETX_P[2]),
.xcvr_rx(ERX_P[2]),
.error_insert(BUTTON[1]),
.test_error(test_error1[2]),
.tx_clock(),
);
xcvr_test g7(

.cal_blk_clk(OSC_50_BANK4),
.xcvr_refclk(CLK_E100),
.irst_n(BUTTON[0]),
.xcvr_tx(ETX_P[3]),
.xcvr_rx(ERX_P[3]),
.error_insert(BUTTON[1]),
.test_error(test_error1[3]),
.tx_clock(),
);

always@(posedge OSC_50_BANK3 or negedge BUTTON[0])
begin
 if(!BUTTON[0])
   count<=32'd0;
 else if(count==FREQ/DFREQ*2)
 begin
    count<=32'd0;
    divclk<=~divclk; 
	 end
 else
    count<=count+1'b1;
end
assign ACLKOUT_P[1]=divclk;
assign ACLKOUT_P[2]=divclk;
assign ACLKOUT0=divclk;

assign ECLKOUT_P[1]=divclk;
assign ECLKOUT_P[2]=divclk;
assign ECLKOUT0=divclk;

assign LED[0]  =  SW[2]?(SW[0]?~ACLKIN_P[1]:test_error[0]):(SW[0]?~ECLKIN_P[1]:test_error1[0]);
assign LED[1]  =  SW[2]?(SW[0]?~ACLKIN_P[2]:test_error[1]):(SW[0]?~ECLKIN_P[2]:test_error1[1]);
assign LED[2]  =  SW[2]?(SW[0]?ACLKIN0:test_error[2]):(SW[0]?ECLKIN0:test_error1[2]);
assign LED[3]  =  SW[2]?(SW[0]?1'b1:test_error[3]):(SW[0]?1'b1:test_error1[3]);
endmodule
