⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pll.vhd

📁 用VHDL写的数字锁相环程序 pll.vhd为源文件 pllTB.vhd为testbench
💻 VHD
📖 第 1 页 / 共 2 页
字号:
	-- inputs : vcoClk, iResetL	-- outputs: pllActive	process (vcoClk, iResetL)		begin  -- process		if iResetL = '0' then               -- asynchronous reset (active low)			intPllActive1 	<= '0';			intPllActive2 	<= '0';			pllActive 	<= '0';		elsif vcoClk'event and vcoClk = '1' then  -- rising clock edge			intPllActive1 	<= '1';			intPllActive2 	<= intPllActive1;			pllActive 	<= intPllActive2;		end if;	end process;	-- purpose: latch and triple bank pllActive to generate clkResetL	-- type   : sequential	-- inputs : vcoClk, iResetL, iPllLock	-- outputs: iClkResetL	process (vcoClk, iResetL)		begin  -- process		if iResetL = '0' then               -- asynchronous reset (active low)			intClkResetL1 	<= '0';			intClkResetL2 	<= '0';			iClkResetL 	<= '0';		elsif vcoClk'event and vcoClk = '1' then  -- rising clock edge			intClkResetL1 <=  iPllLock or intClkResetL1;			intClkResetL2 	<= intClkResetL1;			iClkResetL 	<= intClkResetL2;		end if;	end process;	-- purpose: generate IPDReset	-- type   : sequential	-- inputs : refClk, iResetL	-- outputs: IPDReset	process (refClk, iResetL)		begin  -- process		if iResetL = '0' then               -- asynchronous reset (active low)			intIPDReset 	<= '0';			IPDReset 		<= '0';		elsif refClk'event and refClk = '1' then  -- rising clock edge			intIPDReset 	<= '1';			IPDReset 		<= intIPDReset;		end if;	end process;	iResetL 	<= porL and sleepL;	pllLock 	<= iResetL and iPllLock;	sysResetL 	<= iResetL and iSysResetL;	clkResetL 	<= iResetL and iClkResetL;-- synopsys translate_onend beh;--///////////////////////////////////////////////////////////////////////////--///////////////////////////////////////////////////////////////////////////--/--/ entity & architecture       : pllCore--/ Author			: ParthusCeva Inc.--/_______________________________________________________________________--/ --/        Copyright (c)  ParthusCeva Inc.--/ --/ This code is confidential and proprietary product of ParthusCeva. Any--/ unauthorized use, reproduction or transfer of this code is strictly--/ prohibited.--/_______________________________________________________________________--/ --/ Description: This entity & architecture contains a VHDL behavioural  --/ 	         (non-synthesizable) model of the PLL core.--/_______________________________________________________________________--/ --/--///////////////////////////////////////////////////////////////////////////--///////////////////////////////////////////////////////////////////////////library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_signed.all;entity pllCore4215 is	port (		divClkin	: in  std_logic;		porL		: in  std_logic;		sleepL		: in  std_logic;		VCODelayed	: in  std_logic;		FBD		: in  std_logic_vector(7 downto 0);		fbClk		: out std_logic;		lockDetAsync	: out std_logic;		vcoClk		: buffer std_logic;		filterVoltageBus: out real);end pllCore4215;architecture beh of pllCore4215 is-- synopsys translate_offfunction time2Real (constant T : time) return real is	begin  -- time2Real	return 1.0e-12 * real (T / ps);	end time2Real;function real2TimeShort (constant R : real) return time is	begin  -- real2TimeShort	return integer(R * 1.0e12) * ps;	end real2TimeShort;function real2TimeLong (constant R : real) return time is	begin  -- real2TimeLong	return integer(R * 1.0e9) * ns;	end real2TimeLong;--signal SETTLINGTIME		:real := 2.370000e-04;signal SETTLINGTIME		: real :=  2.300000e-05;signal DIVCLKNOM		: real := 4.500000e+06;signal VCOCLKNOM		: real := 2.880000e+08;signal DIVCLKTOL		: real := 0.300000;signal VCOCLKTOL		: real := 0.250000;signal KVCOTYP			: real := 966.571429;-- Parameters to the design (Generics may be better)signal CLKTOL : real := 10.0e-12;signal Vt : real := 0.5;-- End of parameterssignal divClkPeriodChanged : std_logic := '0';signal divClkPeriodGlobal : real := 0.0;signal FBDChanged : std_logic := '0';signal resetDone : std_logic := '0';signal divClkReset : std_logic := '0';signal intDivClkReset1 : std_logic := '0';signal intDivClkReset2 : std_logic := '0';signal divClkRe2Global : real := 0.0;signal divClkRe2 : real := 0.0;signal vcoClkHalfPeriod : real := 0.0;signal tdbuf : real := 0.0;signal noDivClk : std_logic := '0';signal invalidDivClk : std_logic := '0';signal invalidVcoClk : std_logic := '0';signal settlingTimeComplete : std_logic := '0';signal startTimeSet : std_logic := '0';signal invert : std_logic := '0';signal vcoValid : std_logic := '0';signal intVcoValid1 : std_logic := '0';signal intVcoValid2 : std_logic := '0';signal invalidInput : std_logic;signal done : std_logic := '0';signal starttime : real := 0.0;signal currtime : real := 0.0;signal reqtime : real := 0.0;signal delta : real := 0.0;signal filterVoltage : real;signal divClk : std_logic;signal FBDPrev : std_logic_vector(7 downto 0) := CONV_STD_LOGIC_VECTOR(59, 8);signal resetDoneDelayed : std_logic;signal i : integer;signal iFbClk : std_logic;signal countFBD : std_logic_vector(8 downto 0);signal iResetL : std_logic;begin  -- beh-----------------------------------------------------------------------------	iResetL <= porL and sleepL;	divClk <= divClkin;	-- FBD <= CONV_STD_LOGIC_VECTOR(59, 8);	-- purpose: Convert real number filterVoltage to output port filterVoltageBus	-- type   : combinational	-- inputs : filterVoltage	-- outputs: filterVoltageBus	process (filterVoltage)		begin  -- process		filterVoltageBus <= filterVoltage;		end process;	-----------------------------------------------------------------------------	-- purpose: Wait until there have been several divClk cycles after reset before monitoring for invalid input	-- type   : sequential	-- inputs : divClk, iResetL	-- outputs: divClkReset	process (divClk, iResetL)		begin  -- process		if iResetL = '0' then               -- asynchronous reset (active low)			intDivClkReset1 <= '0';			intDivClkReset2 <= '0';			divClkReset <= '0';		elsif divClk'event and divClk = '1' then  -- rising clock edge			intDivClkReset1 <= '1';			intDivClkReset2 <= intDivClkReset1;			divClkReset <= intDivClkReset2;		end if;	end process;	-----------------------------------------------------------------------------	-- purpose: Wait until there have been several vcoClk cycles to issue a valid signal	-- type   : sequential	-- inputs : vcoClk, iResetL	-- outputs: vcoLaid	process (vcoClk, iResetL)		begin  -- process		if iResetL = '0' then               -- asynchronous reset (active low)			intVcoValid1 <= '0';			intVcoValid2 <= '0';			vcoValid <= '0';		elsif vcoClk'event and vcoClk = '1' then  -- rising clock edge			intVcoValid1 <= '1';			intVcoValid2 <= intVcoValid1;			vcoValid <= intVcoValid2;		end if;	end process;	-----------------------------------------------------------------------------	-- purpose: Calculate the input clock period, monitor changes in it and make sure that its within range		process (divClkin)	variable divClkRe1, divClkRe2, divClkPeriod, divClkPeriodPrev : real := 0.0;		begin  -- process		if divClkin'event and divClkin = '1' then			divClkRe1 := divClkRe2;			divClkRe2 := time2Real(now);				divClkPeriodPrev := divClkPeriod;				divClkPeriod := divClkRe2 - divClkRe1;			divClkPeriodGlobal <= divClkPeriod;				if (((divClkPeriod - divClkPeriodPrev) > CLKTOL) or ((divClkPeriodPrev - divClkPeriod) > CLKTOL)) then				divClkPeriodChanged <= '1';			else				divClkPeriodChanged <= '0';			end if;				if divClkReset = '1' then				if (((1.0/divClkPeriod) < (DIVCLKNOM - (DIVCLKNOM * DIVCLKTOL))) or ((1.0/divClkPeriod) > (DIVCLKNOM + (DIVCLKNOM * DIVCLKTOL)))) then					invalidDivClk <= '1';				else					invalidDivClk <= '0';				end if;			else				invalidDivClk <= '0';			end if;		end if;	end process;	-----------------------------------------------------------------------------	-- because if there are no divClk edges then invalidDivClk cannot become active as it posedge divClk triggered	process (divClkin)		begin  -- process		divClkRe2Global <= time2Real(now);		end process;	process 		begin  -- process		wait for real2TimeShort(1.0/(2.0 * DIVCLKNOM));		if ((time2Real(now) - divClkRe2Global) > (2.0 / (DIVCLKNOM - ( DIVCLKNOM * DIVCLKTOL)))) then			noDivClk <= '1';		else			noDivClk <= '0';		end if;    	end process;	-----------------------------------------------------------------------------	-- Monitor for changes in the feedback divider number	process (divClk)		begin  -- process		if divClk'event and divClk = '1' then			if FBDPrev /= FBD then				FBDChanged <= '1';			else				FBDChanged <= '0';			end if;			FBDPrev <= FBD;		end if;	end process;	-----------------------------------------------------------------------------	-- Calculate the vco clock period, monitor changes in it and make sure that its within range	process		begin  -- process		wait until divClkin'event and divClkin = '1';		vcoClkHalfPeriod <= divClkPeriodGlobal / (real((CONV_INTEGER(UNSIGNED(FBD)) + 1)) * 2.0);		if (vcoValid = '1') then			if (((1.0 / ((divClkPeriodGlobal / (real((CONV_INTEGER(UNSIGNED(FBD)) + 1)) * 2.0)) * 2.0)) < (VCOCLKNOM - ( VCOCLKNOM * VCOCLKTOL))) or 			    ((1.0 / ((divClkPeriodGlobal / (real((CONV_INTEGER(UNSIGNED(FBD)) + 1)) * 2.0)) * 2.0)) > (VCOCLKNOM + ( VCOCLKNOM * VCOCLKTOL)))) then				invalidVcoClk <= '1';			else				invalidVcoClk <= '0';			end if;		else			invalidVcoClk <= '0';      		end if;	end process;	-----------------------------------------------------------------------------	-- Measure buffer delay	process	variable vcoClkRe, VCODelayedRe : real := 0.0;		begin  -- process		wait until vcoClk'event and vcoClk = '1';		if vcoValid = '0' then			tdbuf <= 0.0;			done <= '0';		elsif done = '1' then			tdbuf <= tdbuf;		else			vcoClkRe := time2Real(now);			wait until VCODelayed'event and VCODelayed = '1';			VCODelayedRe := time2Real(now);			if ((VCODelayedRe - vcoClkRe) > (vcoClkHalfPeriod * 2.0)) then				tdbuf <= VCODelayedRe - vcoClkRe - (vcoClkHalfPeriod * 2.0);				invert <= '0';			elsif ((VCODelayedRe - vcoClkRe) > vcoClkHalfPeriod) then				tdbuf <= (vcoClkHalfPeriod * 2.0) - (VCODelayedRe-vcoClkRe);				invert <= '0';			else				tdbuf <= VCODelayedRe - vcoClkRe;				tdbuf <= (divClkPeriodGlobal / 2.0) - tdbuf;				invert <= '1';			end if;			done <= '1';		end if;	end process;	-----------------------------------------------------------------------------	-- Check that always get an initial porL and also after going to an invalid input or vco clock frequency and back	-- 15/01/02 - added FBDChanged,divClkPeriodChanged to invalidInputto force a porl after changing divider ratio's	invalidInput <= (invalidDivClk or invalidVcoClk or noDivClk or FBDChanged or divClkPeriodChanged) when divClkReset = '1' else '0';	process		begin  -- process		wait until porL'event or (invalidInput'event and invalidInput = '1');		if invalidInput = '1' then			resetDone <= '0';		elsif porL = '1' and invalidInput = '0' then			resetDone <= '1';		elsif porL = '0' then			resetDone <= '0';		else			resetDone <= resetDone;		end if;	end process;	-----------------------------------------------------------------------------	--	resetDoneDelayed <= resetDone after real2TimeShort(6.0 * vcoClkHalfPeriod);	-----------------------------------------------------------------------------	-- Generate lock detect signal	process	variable lockStartTime : real := 0.0;		begin  -- process		wait until (divClk'event and divClk = '1') or sleepL'event or invalidInput'event or		resetDone'event or FBDChanged'event or divClkPeriodChanged'event;		if (not (resetDone = '1' and sleepL = '1')) or invalidInput = '1' or FBDChanged = '1' or divClkPeriodChanged = '1' then			lockDetAsync <= '0';			settlingTimeComplete <= '0';			startTimeSet <= '0';		else			if startTimeSet = '0' then				lockStartTime := time2Real(now);				startTimeSet <= '1';			end if;			if ((time2Real(now) - lockStartTime) > SETTLINGTIME) then				settlingTimeComplete <= '1';				lockDetAsync <= '1';			end if;		end if;    	end process;	-----------------------------------------------------------------------------	-- Generate Vco Clock	process		begin  -- process		if sleepL = '0' then			wait for 1 ns;			vcoClk <= '0';		elsif divClkReset = '0' or resetDoneDelayed = '0' then			wait for 1 ns;			vcoClk <= 'U';		else			wait until divClk'event and divClk = '1';			i <= 0;			for x in 0 to CONV_INTEGER(UNSIGNED(FBD)) loop				vcoClk <= '1';				wait for real2TimeShort(vcoClkHalfPeriod);				vcoClk <= '0';				if (x < CONV_INTEGER(UNSIGNED(FBD))) then					wait for real2TimeShort(vcoClkHalfPeriod);				end if;				i <= i + 1;			end loop;  -- x    		end if;	end process;	-----------------------------------------------------------------------------	-- Generate Feedback Clock	process		begin  -- process		wait until (VCODelayed'event and VCODelayed = '1') or sleepL'event or resetDone'event;		if divClkReset = '0' or resetDone = '0' then			iFbClk <= 'U';			countFBD <= "000000000";		elsif sleepL = '0' then			iFbClk <= '0';			countFBD <= "000000000";		else			if countFBD = FBD + 1 then				iFbClk <= '1';				countFBD <= "000000000";			else				iFbClk <= '0';				countFBD <= countFBD + 1;			end if;		end if;	end process;	-----------------------------------------------------------------------------	fbClk <= VCODelayed when FBD = "00000000" else iFbClk;	-----------------------------------------------------------------------------	-- Generate Filter Voltage	process (vcoClk)		begin  -- process		if resetDone = '0' or sleepL = '0' then			filterVoltage <= 0.0;		else			filterVoltage <= (1.0 / (KVCOTYP * vcoClkHalfPeriod * 2.0e-3)) + Vt;		end if;	end process;-- synopsys translate_onend beh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -