OpenCores
URL https://opencores.org/ocsvn/sgmii/sgmii/trunk

Subversion Repositories sgmii

[/] [sgmii/] [trunk/] [src/] [mSGMII.v] - Rev 26

Go to most recent revision | Compare with Previous | Blame | View Log

/*
Copyright � 2012 JeffLieu-jefflieu@fpga-ipcores.com
 
	This file is part of SGMII-IP-Core.
    SGMII-IP-Core is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    SGMII-IP-Core is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with SGMII-IP-Core.  If not, see <http://www.gnu.org/licenses/>.
 
File		:
Description	:
	This core implements:
	B1000-X Standard
	PCS/PMA of SGMII MAC Side
Remarks		:
Revision	:
	Date	Author		Description
02/09/12	Jefflieu
*/
 
`timescale 1ns/10ps
`include "SGMIIDefs.v"
 
module mSGMII 
(
	//Tranceiver Interface
	input	i_SerRx,
	output	o_SerTx,
	input	i_CalClk,
	input	i_RefClk125M,
	input	i_ARstHardware_L,
 
	//Local BUS interface
	//Wishbonebus, single transaction mode (non-pipeline slave)
	input	i_Cyc,
	input	i_Stb,
	input	i_WEn,
	input	[31:00] 	i32_WrData,
	input	[07:00]		iv_Addr,
	output	[31:00]		o32_RdData,
	output	o_Ack,
 
	input	i_Mdc,
	inout	io_Mdio,
 
	output	o_Linkup,
	output	o_ANDone,
	//This is used in Phy-Side SGMII 
	input 	i_PhyLink,
	input	i_PhyDuplex,
	input 	[1:0] i2_PhySpeed,	
 
 
	output	[1:0] o2_SGMIISpeed,
	output	o_SGMIIDuplex,
 
	//GMII Interface
	output 	o_TxClk,
	output 	o_RxClk,
	input	[07:00] i8_TxD,
	input	i_TxEN,
	input	i_TxER,
	output	[07:00] o8_RxD,
	output	o_RxDV,
	output	o_RxER,
	output	o_GMIIClk,
	output	o_MIIClk,
	output	o_Col,
	output	o_Crs);
 
	wire 	w_ClkTx,w_ClkRx;	
	wire 	w_ClkSys;
	wire	w_Loopback;
	reg		r_RestartAN;
	wire	w_ANEnable;
	wire	[15:00] w16_Status;
	wire 	w_MIIRst_L;
	wire	w_ANComplete;
 
	wire 	[07:00] w8_RxCG_SyncToRxver;
	wire	w_RxCGInv_SyncToRxver;
	wire	w_RxCGCtrl_SyncToRxver;
	wire	w_SyncStatus,w_RxEven,w_IsComma,w_OSValid;
	wire	w_IsI1Set,w_IsI2Set,w_IsC1Set,w_IsC2Set,w_IsTSet,w_IsVSet,w_IsSSet,w_IsRSet;
 
	wire	w_Receiving;
	wire	w_Transmitting;
	wire	w_CheckEndKDK,w_CheckEndKD21_5D0_0,w_CheckEndKD2_2D0_0,w_CheckEndTRK,w_CheckEndTRR,w_CheckEndRRR,w_CheckEndRRK,w_CheckEndRRS;
	reg		r_CheckEndKDK,r_CheckEndKD21_5D0_0,r_CheckEndKD2_2D0_0,r_CheckEndTRK,r_CheckEndTRR,r_CheckEndRRR,r_CheckEndRRK,r_CheckEndRRS;
 
	wire	[2:0] w3_XmitState;
	wire	[16:01] w16_TxConfigReg;
	wire 	[15:00] w16_RxConfigReg;
	wire	[15:00] w16_LcAdvAbility;
	wire	[15:00] w16_LpAdvAbility;
	wire	w_RUDIConfig;
	wire	w_RUDIIdle;
	wire	w_RUDIInvalid;
	wire	w_ARstLogic_L;
	wire 	w_MIIReset_L;
	wire	w_ANRestart;
	//This delay stage is for the function checkend
	reg	[07:00]	r8_RxCodeGroup[0:2];
	reg 	r_RxCgInvalid[0:2];
	reg 	r_RxCgCtrl[0:2];
	wire  	[2:0] w3_PreCheckIsSSet;
	wire  	[2:0] w3_PreCheckIsTSet;
	wire  	[2:0] w3_PreCheckIsRSet;
	wire	[2:0] w3_PreCheckIsComma;
	wire 	[2:0] w3_PreCheckIsD21_5;
	wire	[2:0] w3_PreCheckIsD2_2;
	wire	[2:0] w3_PreCheckIsD;
	wire	[2:0] w3_PreCheckIsD0_0;
	wire 	w_GxBPowerDown;
	wire	w_TxCodeCtrl, w_TxCodeValid, w_RxCodeInvalid, w_RxCodeCtrl;
	wire 	[07:00] w8_TxCode, w8_RxCode;
	wire	w_SignalDetect;
	wire	w_TxForceNegDisp;
	wire	w_PllLocked;
	wire	[20:00] w21_LinkTimer;
	wire 	w_TxEN,w_TxER,w_RxER, w_RxDV;
	wire	[07:00] w8_RxD, w8_TxD;
	wire 	w_BitSlip;
	wire 	w_Invalid;//Not Used
	wire 	w_TxEven;//Not Used
	wire 	w_CurrentParity;
 
	//MII Clock Gen
	reg [6:0] 	r7_Cntr;
	reg r_MIIClk;
	reg r_MIIClk_D;
	wire w_SamplingClk;
 
	integer DELAY;
 
	assign o_Linkup = w_SyncStatus;
	assign o_ANDone = w_ANComplete;
	assign o_TxClk = w_ClkTx;
	assign o_RxClk = w_ClkRx;
 
	mRateAdapter	u0RateAdapter(
	//MAC Side signal
	.i_TxClk		(o_MIIClk),	
	.i_TxEN			(i_TxEN	),
	.i_TxER			(i_TxER	),	
	.i8_TxD			(i8_TxD	),			
	.i_RxClk		(o_MIIClk),
	.o_RxEN			(o_RxDV),
	.o_RxER			(o_RxER),
	.o8_RxD			(o8_RxD),
	.i2_Speed		(o2_SGMIISpeed),
	//SGMII PHY side
	.i_SamplingClk	(w_SamplingClk),
	.i_GClk			(w_ClkSys),
	.o_TxEN			(w_TxEN),
	.o_TxER			(w_TxER),
	.o8_TxD			(w8_TxD),
	.i_RxEN			(w_RxDV),
	.i_RxER			(w_RxER),
	.i8_RxD			(w8_RxD));
 
	generate
		genvar STAGE;
		for(STAGE=0;STAGE<3;STAGE=STAGE+1)
		begin:PreCheck
			assign w3_PreCheckIsComma[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b1 && r8_RxCodeGroup[STAGE]==`K28_5)?1'b1:1'b0;			
			assign w3_PreCheckIsTSet[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b1 && r8_RxCodeGroup[STAGE]==`K29_7)?1'b1:1'b0;
			assign w3_PreCheckIsRSet[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b1 && r8_RxCodeGroup[STAGE]==`K23_7)?1'b1:1'b0;
			assign w3_PreCheckIsD21_5[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b0 && r8_RxCodeGroup[STAGE]==`D21_5)?1'b1:1'b0;
			assign w3_PreCheckIsD2_2[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b0 && r8_RxCodeGroup[STAGE]==`D2_2)?1'b1:1'b0;
			assign w3_PreCheckIsD[STAGE]		= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b0)?1'b1:1'b0;
			assign w3_PreCheckIsD0_0[STAGE] 	= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b0 && r8_RxCodeGroup[STAGE]==`D0_0)?1'b1:1'b0;
			assign w3_PreCheckIsSSet[STAGE]		= (r_RxCgInvalid[STAGE]==1'b0 && r_RxCgCtrl[STAGE]==1'b1 && r8_RxCodeGroup[STAGE]==`K27_7)?1'b1:1'b0;
		end
	endgenerate
 
	assign w_CheckEndKDK 		= w3_PreCheckIsComma[2] & w3_PreCheckIsD[1]&w3_PreCheckIsComma[0];
	assign w_CheckEndRRR 		= &(w3_PreCheckIsRSet);
	assign w_CheckEndTRK 		= w3_PreCheckIsTSet[2] & w3_PreCheckIsRSet[1] & w3_PreCheckIsComma[0];
	assign w_CheckEndTRR 		= w3_PreCheckIsTSet[2] & w3_PreCheckIsRSet[1] & w3_PreCheckIsRSet[0];
	assign w_CheckEndKD21_5D0_0	= w3_PreCheckIsComma[2] & w3_PreCheckIsD21_5[1] & w3_PreCheckIsD2_2[0];
	assign w_CheckEndKD2_2D0_0 	= w3_PreCheckIsComma[2] & w3_PreCheckIsD2_2[1] & w3_PreCheckIsD2_2[0];
	assign w_CheckEndRRK		= w3_PreCheckIsRSet[2] & w3_PreCheckIsRSet[1] & w3_PreCheckIsComma[0];
	assign w_CheckEndRRS		= w3_PreCheckIsRSet[2] & w3_PreCheckIsRSet[1] & w3_PreCheckIsSSet[0];
 
	always@(posedge w_ClkRx)
		begin
			r8_RxCodeGroup[0] 	<= w8_RxCode;
			r_RxCgCtrl[0] 		<= w_RxCodeCtrl;
			r_RxCgInvalid[0] 	<= w_RxCodeInvalid;
			for(DELAY=1;DELAY<3;DELAY=DELAY+1)
				begin
				r8_RxCodeGroup[DELAY] 	<= r8_RxCodeGroup[DELAY-1];
				r_RxCgInvalid[DELAY] 	<= r_RxCgInvalid[DELAY-1];
				r_RxCgCtrl[DELAY]		<= r_RxCgCtrl[DELAY-1];				
				end			
		end
 
	assign o_Col = w_Transmitting & w_Receiving;
	assign o_Crs = 1'b0;
	assign w_ARstLogic_L 	= w_PllLocked & i_ARstHardware_L & (w_MIIRst_L);
	mRegisters	u0Registers(
	.w_ARstLogic_L	(w_ARstLogic_L),
	.i_Clk			(w_ClkSys),
	.i_Cyc			(i_Cyc),
	.i_Stb			(i_Stb),
	.i_WEn			(i_WEn),
	.i8_Addr		(iv_Addr),
	.i32_WrData		(i32_WrData),
	.o32_RdData		(o32_RdData),
	.o_Ack			(o_Ack),
	.o_Stall		(),
 
	.io_Mdio		(io_Mdio),
	.i_Mdc			(i_Mdc),
 
	//Register in and out,
 
	//MAC-Side SGMII
	.o2_SGMIISpeed		(o2_SGMIISpeed),
	.o_SGMIIDuplex		(o_SGMIIDuplex),
 
	//Phy-Side SGMII
	.i_PhyLink			(i_PhyLink	),
	.i_PhyDuplex		(i_PhyDuplex),
	.i2_PhySpeed		(i2_PhySpeed),
	.o21_LinkTimer		(w21_LinkTimer),
 
	.i16_TxConfigReg	(w16_TxConfigReg),
	.o_MIIRst_L			(w_MIIRst_L),
	.o_ANEnable			(w_ANEnable),
	.o_ANRestart		(w_ANRestart),
	.o_Loopback			(w_Loopback),
	.o_GXBPowerDown		(w_GxBPowerDown),
	.o16_LcAdvAbility	(w16_LcAdvAbility),
	.i3_XmitState		(w3_XmitState),
	.i_SyncStatus		(w_SyncStatus),	
	.i_ANComplete		(w_ANComplete),
	.i16_LpAdvAbility	(w16_LpAdvAbility));
 
	 mSyncCtrl u0SyncCtrl(
	.i_Clk				(w_ClkRx		),
	.i_Cke				((~w_GxBPowerDown)	),
	.i_ARst_L			(w_ARstLogic_L	),
	.i_CtrlLoopBack		(w_Loopback		),
 
	.i8_RxCodeGroupIn	(r8_RxCodeGroup[2]	),
	.i_RxCodeInvalid	(r_RxCgInvalid[2]	),
	.i_RxCodeCtrl		(r_RxCgCtrl[2]		),
	.i_SignalDetect		(w_SignalDetect		),
 
	.o8_RxCodeGroupOut	(w8_RxCG_SyncToRxver	),	
	.o_RxCodeInvalid	(w_RxCGInv_SyncToRxver	),
	.o_RxCodeCtrl		(w_RxCGCtrl_SyncToRxver	),
	.o_RxEven			(w_RxEven				),
	.o_SyncStatus		(w_SyncStatus			),	
	.o_BitSlip			(w_BitSlip),
	.o_IsComma			(w_IsComma	),
	.o_OrderedSetValid	(w_OSValid	),
	.o_IsI1Set			(w_IsI1Set	),
	.o_IsI2Set			(w_IsI2Set	),
	.o_IsC1Set			(w_IsC1Set	),
	.o_IsC2Set			(w_IsC2Set	),
	.o_IsTSet			(w_IsTSet	),
	.o_IsVSet			(w_IsVSet	),
	.o_IsSSet			(w_IsSSet	),
	.o_IsRSet			(w_IsRSet	));
 
	always@(posedge w_ClkRx)
	begin
	r_CheckEndKDK			<= w_CheckEndKDK;
	r_CheckEndKD21_5D0_0	<= w_CheckEndKD21_5D0_0;
	r_CheckEndKD2_2D0_0	    <= w_CheckEndKD2_2D0_0;
	r_CheckEndTRK			<= w_CheckEndTRK;
	r_CheckEndTRR			<= w_CheckEndTRR;
	r_CheckEndRRR			<= w_CheckEndRRR;	   
	r_CheckEndRRK			<= w_CheckEndRRK;
	r_CheckEndRRS			<= w_CheckEndRRS;
	end
 
	mReceive	u0Receive(
	.i8_RxCodeGroupIn		(w8_RxCG_SyncToRxver	),
	.i_RxCodeInvalid       	(w_RxCGInv_SyncToRxver	),
	.i_RxCodeCtrl          	(w_RxCGCtrl_SyncToRxver	),
	.i_RxEven 	         	(w_RxEven				),
 
	.i3_Xmit				(w3_XmitState),
 
	.i_IsComma				(w_IsComma	),
	.i_OrderedSetValid      (w_OSValid	),
	.i_IsI1Set              (w_IsI1Set	),
	.i_IsI2Set              (w_IsI2Set	),
	.i_IsC1Set              (w_IsC1Set	),
	.i_IsC2Set              (w_IsC2Set	),
	.i_IsTSet               (w_IsTSet	),
	.i_IsVSet               (w_IsVSet	),
	.i_IsSSet               (w_IsSSet	),
	.i_IsRSet               (w_IsRSet	),
 
	.i_CheckEndKDK			(r_CheckEndKDK			),
	.i_CheckEndKD21_5D0_0	(r_CheckEndKD21_5D0_0	),
	.i_CheckEndKD2_2D0_0	(r_CheckEndKD2_2D0_0	),
	.i_CheckEndTRK			(r_CheckEndTRK			),
	.i_CheckEndTRR			(r_CheckEndTRR			),
	.i_CheckEndRRR			(r_CheckEndRRR			),
	.i_CheckEndRRK			(r_CheckEndRRK			),
	.i_CheckEndRRS			(r_CheckEndRRS			),
 
	.o16_RxConfigReg	(w16_RxConfigReg),
	.o_RUDIConfig		(w_RUDIConfig),
	.o_RUDIIdle			(w_RUDIIdle),
	.o_RUDIInvalid		(w_RUDIInvalid),
 
	.o_RxDV				(w_RxDV	),
	.o_RxER				(w_RxER	),
	.o8_RxD				(w8_RxD	),
	.o_Invalid			(w_Invalid),
	.o_Receiving		(w_Receiving),
	.i_Clk				(w_ClkRx),
	.i_ARst_L			(w_ARstLogic_L));
 
	mANCtrl	u0ANCtrl(
	.i_Clk				(w_ClkRx			),
	.i_ARst_L			(w_ARstLogic_L		),
	.i_Cke				((~w_GxBPowerDown)		),
	.i_RestartAN		(w_ANRestart		),
	.i_SyncStatus		(w_SyncStatus		),
	.i_ANEnable			(w_ANEnable			),
	.i21_LinkTimer		(w21_LinkTimer		),
	.i16_LcAdvAbility	(w16_LcAdvAbility	),
	.o16_LpAdvAbility	(w16_LpAdvAbility	),
	.o_ANComplete		(w_ANComplete		),
	.i16_RxConfigReg	(w16_RxConfigReg	),
	.i_RUDIConfig		(w_RUDIConfig		),
	.i_RUDIIdle			(w_RUDIIdle			),
	.i_RUDIInvalid		(w_RUDIInvalid		),	
	.o3_Xmit			(w3_XmitState		),
	.o16_TxConfigReg	(w16_TxConfigReg	));
 
	mTransmit	u0Transmit(
	.i3_Xmit			(w3_XmitState		),
	.i16_ConfigReg		(w16_TxConfigReg	),
 
	.i_TxEN				(w_TxEN				),	
	.i_TxER				(w_TxER				),
	.i8_TxD				(w8_TxD				),
 
 
	.o_Xmitting			(w_Transmitting		),	
	.o_TxEven			(w_TxEven			),
	.o8_TxCodeGroupOut	(w8_TxCode			),
	.o_TxCodeValid		(w_TxCodeValid		),
	.o_TxCodeCtrl		(w_TxCodeCtrl		),
	.i_CurrentParity	(w_CurrentParity	),
 
	.i_Clk				(w_ClkTx			),
	.i_ARst_L			(w_ARstLogic_L		));
 
	assign w_SignalDetect=~w_RxCodeInvalid;
 
	/*mXcver #(.pXcverName("AltArriaV"))u0Xcver(
 
	.i_SerRx			(i_SerRx			),
	.o_SerTx			(o_SerTx			),
 
	.i_RefClk125M		(i_RefClk125M		),
	.o_TxClk			(w_ClkSys			),
	.i_CalClk			(i_RefClk125M		),
	.i_GxBPwrDwn		(w_GxBPowerDown		),
	.i_XcverDigitalRst	(~w_ARstLogic_L		),	
	.o_PllLocked		(w_PllLocked		),
 
	.o_SignalDetect		(),
	.o8_RxCodeGroup		(w8_RxCode			),
	.o_RxCodeInvalid	(w_RxCodeInvalid	),
	.o_RxCodeCtrl		(w_RxCodeCtrl		),
 
	.i8_TxCodeGroup		(w8_TxCode			),
	.i_TxCodeValid		(w_TxCodeValid		),
	.i_TxCodeCtrl		(w_TxCodeCtrl		),
	.i_TxForceNegDisp	(w_TxForceNegDisp	),
	.o_RunningDisparity	(w_CurrentParity));*/
 
 
	mAltA5GXlvds u0Xcverlvds(
	.i_SerRx			(i_SerRx			),
	.o_SerTx			(o_SerTx			),
 
	.i_RefClk125M		(i_RefClk125M		),
	.o_TxClk			(w_ClkTx			),
	.o_RxClk			(w_ClkRx			),
	.i_GxBPwrDwn		(w_GxBPowerDown		),
	.i_XcverDigitalRst	(~i_ARstHardware_L	),	
	.o_PllLocked		(w_PllLocked		),
	.i_RxBitSlip		(w_BitSlip			),
 
	.o_SignalDetect		(),
	.o8_RxCodeGroup		(w8_RxCode			),
	.o_RxCodeInvalid	(w_RxCodeInvalid	),
	.o_RxCodeCtrl		(w_RxCodeCtrl		),
 
	.i8_TxCodeGroup		(w8_TxCode			),
	.i_TxCodeValid		(w_TxCodeValid		),
	.i_TxCodeCtrl		(w_TxCodeCtrl		),
	.i_TxForceNegDisp	(1'b0	),
	.o_RunningDisparity	(w_CurrentParity));
 
	assign w_ClkSys	 = w_ClkTx;
	assign o_GMIIClk = w_ClkSys;
 
	always@(posedge w_ClkSys or negedge i_ARstHardware_L )
	if(~i_ARstHardware_L)
	begin
		r7_Cntr 	<= 7'h0;
		r_MIIClk 	<= 1'b0;	
	end else		
	begin
		if(o2_SGMIISpeed==2'b01)
			begin
			if(r7_Cntr==7'h4) r7_Cntr<=7'h0; else r7_Cntr<=r7_Cntr+7'h1;
			if(r7_Cntr==7'h4) r_MIIClk<=1'b1; else if(r7_Cntr==7'h1) r_MIIClk<=1'b0;
			end
		else if(o2_SGMIISpeed==2'b00)
			begin
			if(r7_Cntr==7'h49) r7_Cntr<=7'h0; else r7_Cntr<=r7_Cntr+7'h1;
			if(r7_Cntr==7'h49) r_MIIClk<=1'b1; else if(r7_Cntr==7'h24) r_MIIClk<=1'b0;
			end		
		r_MIIClk_D <= r_MIIClk;
	end
	assign w_SamplingClk = (r_MIIClk_D & (~r_MIIClk));
 
	//Insert Clock Buffer or PLL if necessary
	mClkBuf u0ClkBuf(.i_Clk(r_MIIClk),.o_Clk(o_MIIClk));
 
endmodule
 
 
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.