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

📄 lpm_counter.tdf

📁 基于SIIGX的PCIe的Kit
💻 TDF
📖 第 1 页 / 共 4 页
字号:
-------------------------------------------------------------------------------
--
--	LPM_COUNTER Parameterized Megafunction
--
--	Copyright (C) 1988-1999 Altera Corporation
--	Any megafunction design, and related net list (encrypted or decrypted),
--	support information, device programming or simulation file, and any other
--	associated documentation or information provided by Altera or a partner
--	under Altera's Megafunction Partnership Program may be used only to
--	program PLD devices (but not masked PLD devices) from Altera.  Any other
--	use of such megafunction design, net list, support information, device
--	programming or simulation file, or any other related documentation or
--	information is prohibited for any other purpose, including, but not
--	limited to modification, reverse engineering, de-compiling, or use with
--	any other silicon devices, unless such use is explicitly licensed under
--	a separate agreement with Altera or a megafunction partner.  Title to
--	the intellectual property, including patents, copyrights, trademarks,
--	trade secrets, or maskworks, embodied in any such megafunction design,
--	net list, support information, device programming or simulation file, or
--	any other related documentation or information provided by Altera or a
--	megafunction partner, remains with Altera, the megafunction partner, or
--	their respective licensors.  No other licenses, including any licenses
--	needed under any third party's intellectual property, are provided herein.
--
--	Version 3.0
--
-------------------------------------------------------------------------------

INCLUDE "lpm_constant";
INCLUDE "lpm_decode";
INCLUDE "lpm_add_sub";
INCLUDE "cmpconst";
INCLUDE "lpm_compare";
INCLUDE "lpm_counter";
INCLUDE "dffeea";
INCLUDE "alt_synch_counter";
INCLUDE "alt_synch_counter_f";
INCLUDE "alt_counter_f10ke";
INCLUDE "alt_counter_stratix";
INCLUDE "aglobal60";		-- device family definitions

FUNCTION p8count(clk, clrn, setn, ldn, dnup, gn,  h, g, f, e, d, c, b, a)
 RETURNS 		(qh, qg, qf, qe, qd, qc, qb, qa, cout);

FUNCTION f8count(clk, clrn, setn, ldn, dnup, gn,  h, g, f, e, d, c, b, a)
 RETURNS		(qh, qg, qf, qe, qd, qc, qb, qa, cout);

OPTIONS NAME_SUBSTITUTION = ON;
OPTIONS TREAT_DEFAULT_VALUE_AS_UNUSED = ON;

-------------------------------------------------------------------------------
PARAMETERS
(
	LPM_WIDTH,
	LPM_DIRECTION			=	"DEFAULT",					-- optional, "UP", "DOWN" or "DEFAULT"
	LPM_MODULUS				=	0,							-- optional, for modulus counters
	LPM_AVALUE				=	"UNUSED",					-- optional, asynchronous set value (loaded by aset)
	LPM_SVALUE				=	"UNUSED",					-- optional, synchronous set value (loaded by sset)
	LPM_PORT_UPDOWN			=	"PORT_CONNECTIVITY",		-- "PORT_USED", "PORT_UNUSED" or "PORT_CONNECTIVITY"

	DEVICE_FAMILY,											-- optional
	CARRY_CHAIN				=	"IGNORE",					-- optional
	CARRY_CHAIN_LENGTH		=	32,							-- optional
	NOT_GATE_PUSH_BACK		=	"OFF",						-- optional, "ON" or "OFF"
	CARRY_CNT_EN			=	"SMART",					-- optional, "SMART", "ON" or "OFF"
	LABWIDE_SCLR			=	"ON",						-- optional, "ON" or "OFF"
	USE_NEW_VERSION			=	"TRUE",						-- optional, "TRUE" or "FALSE"
	CBXI_PARAMETER			=	"NOTHING"
);
-- Constant defenition
-- this constant is to determine the minimum maximum chain length that will be 
-- tolerated by the newer version of the counter
CONSTANT LOWER_CHAIN_LIMIT = 4;
-------------------------------------------------------------------------------
-- Determines whether or not to pass this function on to another module

DEFINE USE_OLD_VERSION() = USE_NEW_VERSION == "FALSE" # CARRY_CNT_EN == "OFF" #
						   LABWIDE_SCLR == "OFF" # !USE_CARRY_CHAINS() #
						   CARRY_CHAIN_LENGTH < LOWER_CHAIN_LIMIT # LPM_WIDTH <= 1
						   -- also check if there is a wysiwyg implementation
						   -- available
						   # (FAMILY_APEX20K() == 0 & FAMILY_APEX20KE() == 0 & FAMILY_APEXII() == 0
						   		& FAMILY_FLEX6000() == 0 & FAMILY_MERCURY() == 0
								& FAMILY_FLEX10KE() == 0 & FAMILY_STRATIX() == 0
								& FAMILY_FLEX10K() == 0
							 );
						   -- currently only APEX20K & APEX20KE have the wysiwyg
						   -- implemntation available to force the chains

-------------------------------------------------------------------------------
-- Determines whether clearbox is used.

DEFINE CBX_FAMILY() = ((FAMILY_STRATIX() == 1 # FAMILY_STRATIXII() == 1 # FAMILY_CYCLONEII() == 1) ? 1 : 0);

-------------------------------------------------------------------------------
-- unified netlist connectivity check
DEFINE USED_UPDOWN() = LPM_PORT_UPDOWN == "PORT_USED" # (LPM_PORT_UPDOWN != "PORT_UNUSED" & USED(updown));

-------------------------------------------------------------------------------
-- Evaluated functions

DEFINE break_chain_here(p) = -- When to break carry chains
	  CEIL(LPM_WIDTH div 2) < CARRY_CHAIN_LENGTH & p == CEIL(LPM_WIDTH div 2)
	# CEIL(LPM_WIDTH div 2) >= CARRY_CHAIN_LENGTH & (p mod (CARRY_CHAIN_LENGTH-2)) == 0;

DEFINE ModulusCounter() =		-- do we need separate modulus checking logic?
	((LPM_MODULUS != 0) & !((LPM_WIDTH<32) & (LPM_MODULUS==2^LPM_WIDTH)));

DEFINE Ceil_Log2_Modulus() = -- Number of bits needed for this LPM_MODULUS
	(LPM_MODULUS != 0) ?
		(LPM_MODULUS<0 ? (LPM_MODULUS==2^31 ? 31:32) : CEIL(LOG2(LPM_MODULUS)))
					  : 1;

DEFINE OK_to_use_pcustom() =	-- If counter is simple enough, use custom logic for p-term
	  (LPM_WIDTH<=MAXPIA_SIZE())
	& (FAMILY_FLEX() == 0)
	& USED(aconst) == 0 & USED(sconst) == 0
	& USED(aset) == 0 & USED(sset) == 0
	& USED(aload) == 0 & USED(sload) == 0 & USED(data) == 0
	& !ModulusCounter();

DEFINE OK_to_use_8count() =		-- Can we just use 8count?
	  (LPM_WIDTH<=MAXPIA_SIZE())
	& (FAMILY_FLEX()==0 # !USE_CARRY_CHAINS())
	& (Is_multiple_of_8(LPM_WIDTH) # USED(cout)==0)
	& (USED(cnt_en)==0 # USED(cout)==0)
	& USED(aconst)==0 & USED(sconst)==0 & USED(clk_en)==0
	& USED(aset)==0 & USED(sclr)==0 
	& (USED(sset)==0 # (USED(sload)==0 & USED(aload)==0))
	& !ModulusCounter();

DEFINE Is_multiple_of_8(a) = (CEIL(a div 8) == FLOOR(a div 8));

-- if aconst or aset is used in a FLEX 8000 or FLEX 10K device, NOT_GATE_PUSH_BACK must be turned off
DEFINE need_not_gate_push_back_off() =	
	  (NOT_GATE_PUSH_BACK == "ON")
	& (FAMILY_FLEX() == 1)
	& (FAMILY_HAS_NATIVE_ALOAD() == 1)
	& (USED(aconst) # USED(aset));

-- If the device family doesn't have preset capability,
--  then we will need external async control logic 
DEFINE NEED_dffeea() = (FAMILY_HAS_PRESET()==0) & (USED(aload) # (USED(aclr) & USED(aset)));

-------------------------------------------------------------------------------
-- For FLEX devices

-- UP or DOWN counter ?
DEFINE COUNT_ONLY_UP() = ((LPM_DIRECTION=="UP") # ((LPM_DIRECTION=="DEFAULT") & !USED_UPDOWN()));
DEFINE COUNT_ONLY_DOWN() = (LPM_DIRECTION=="DOWN");
DEFINE COUNT_UP() = (!COUNT_ONLY_DOWN());				--   up or up/down counter
DEFINE COUNT_DOWN() = (!COUNT_ONLY_UP());				-- down or up/down

-- check if we use clr for modulus overflow
DEFINE UseSyncClrModUp() = ( (COUNT_ONLY_UP() # USED_UPDOWN()) & (LPM_MODULUS != 0)
	& (nBasicExtraSyncInput()>0)	-- don't use clr if basic counter
-- FLEX10K and 8K specific: to be removed when SPR42458 is closed
--	& !(((FAMILY_FLEX10K()==1) # (FAMILY_FLEX8000()==1)) & USED_UPDOWN() %& !USED(SCLR)%)
	);

-- count the number of extra sync inputs
DEFINE nBasicExtraSyncInput() = ExtraUpDown() + (USED(clk_en) & 1) + (USED(cnt_en) & 1) + (USED(cin) & 1) +
	(USED(sclr) & 1) + (USED(sset) & 1) + (USED(sload) & 1) +
	(ModulusCounter() & COUNT_UP() & 1) + (ModulusCounter() & COUNT_DOWN() & 1);

DEFINE UseFuncSCLR() = (UseSyncClrModUp() # USED(sclr));
DEFINE UseClearableCounterMode() = (FAMILY_HAS_CLEARABLE_COUNTER_MODE() & UseFuncSCLR() & !USED_UPDOWN());
DEFINE UseLabWideSclr()= ((FAMILY_HAS_LABWIDE_SCLR()==1) & UseFuncSCLR() & (LABWIDE_SCLR=="ON"));
--	& (nBasicExtraSyncInput()>2));	-- don't use lab-wide clr if basic counter

DEFINE FLEXUseCarryChain() =
--	!(need_not_gate_push_back_off()) & !(OK_to_use_8count()) &
	!USED(sconst) & (FAMILY_FLEX()==1) & (USE_CARRY_CHAINS()) & (CARRY_CHAIN_LENGTH>3) & (LPM_WIDTH > 1);

-------------------------------------------------------------------------------
-- The dedicated inputs of a counter are UpDown, SClr and Data/nLoad (FLEX10K).
-- The FLEX LCELL have an extra input to accommodate any extra sync signal 
--  like SSet or Wrap (modulus).

-- Check if sclr should be counted as an extra input.
DEFINE ExtraInputSClr() = (UseFuncSCLR() & !UseClearableCounterMode() & !UseLabWideSclr() & 1);
-- modulus
DEFINE UpWrapLoad() = (ModulusCounter() & COUNT_UP() & !UseSyncClrModUp() & 1);
DEFINE DnWrapLoad() = (ModulusCounter() & COUNT_DOWN() & 1);
-- updown
DEFINE ExtraUpDown() = (USED_UPDOWN() & !FAMILY_HAS_UPDOWN_COUNTER_MODE() & 1);
-- inputs with feedback
DEFINE ExtraClkEn() = (USED(clk_en) & %!FAMILY_HAS_ENABLE_LUT_INPUT() &% 1);
DEFINE ExtraCntEn() = (USED(cnt_en) & !CntEnThroughCarryChain() & 1);
DEFINE ExtraExternalFeedback() =
		( USED_UPDOWN() & !FAMILY_HAS_UPDOWN_COUNTER_MODE() & (ExtraClkEn() # ExtraCntEn()) ) #
		( ExtraClkEn() & ExtraCntEn() );
DEFINE nFeedbackInputs() = ( ExtraClkEn() + ExtraCntEn() + ExtraExternalFeedback() );

-- count the number of extra sync inputs
DEFINE nExtraSyncInput() = ExtraUpDown() + ExtraClkEn()*2 + 
	ExtraInputSClr() + (USED(sset) & 1) + UpWrapLoad() + DnWrapLoad() + (USED(sload) & 1);

-- Check if we use the carry chain to propagate cnt_en
DEFINE CntEnThroughCarryChain() = USED(cnt_en) & FLEXUseCarryChain() & !USED(cout) &
	( (CARRY_CNT_EN=="ON") # ((CARRY_CNT_EN=="SMART") & (nExtraSyncInput()>1)) );

-- # of inputs that may use the nLoad input
DEFINE nLoadInput() = (
	  (USED(clk_en) & !FAMILY_HAS_ENABLE_LUT_INPUT() & 1)	-- use ENA_DATA ?
	+ (ExtraCntEn() &										-- use LUTCntEn ?
		(USED(clk_en) # (USED_UPDOWN() & !FAMILY_HAS_UPDOWN_COUNTER_MODE()))	-- with LUT0
		# UpWrapLoad() # DnWrapLoad())	-- or with wrap
	+ ExtraInputSClr() + (USED(sset) & 1) + UpWrapLoad() + DnWrapLoad() + (USED(sload) & 1)
	);

DEFINE nLoadDataInput() = ExtraUpDown() + nFeedbackInputs() 
	+ ExtraInputSClr() + (USED(sset) & 1) +	UpWrapLoad() + DnWrapLoad() + (USED(sload) & 1);

-- Check if we use the LOAD LCELL scheme
DEFINE LoadMuxLCELL() =	FLEXUseCarryChain() & !SpecialCase();
-- Special cases where the legacy expression leads to a better result
DEFINE SpecialCase() = USED(clk_en) & (USED(sclr) # USED(sset)) & (nBasicExtraSyncInput()==2);

-- Extra carry-out for modulus down counters
DEFINE SizeCarryChain() = (LPM_WIDTH+1);
DEFINE UseExtraCarryBit4DownWrap() = (DnWrapLoad() & !(
--  speed up simple counters by not using the extra carry-out but a comparator instead
	!USED_UPDOWN() &
	!(%USED(sclr) #% USED(sset) # USED(sload)) & !(USED(cnt_en) & USED(clk_en))
											 ));

FUNCTION @CBXI_PARAMETER(data[LPM_WIDTH-1..0], clock, clk_en, cnt_en, updown, cin, aclr, aset, aconst, aload, sclr, sset, sconst, sload)
RETURNS( q[LPM_WIDTH-1..0], cout, eq[15..0]);


-------------------------------------------------------------------------------
SUBDESIGN LPM_COUNTER
(
	clock						: INPUT;
	clk_en						: INPUT = VCC;	-- clock Enable
	cnt_en						: INPUT = VCC;	-- count Enable
	updown						: INPUT = VCC;	-- VCC counts up, GND counts down
	aclr, aset, aconst, aload	: INPUT = GND;
	sclr, sset, sconst, sload	: INPUT = GND;
	data[LPM_WIDTH-1..0]		: INPUT = GND;	-- used by aload and/or sload
	cin							: INPUT = VCC;

	q[LPM_WIDTH-1..0]			: OUTPUT;		-- counter output
	cout						: OUTPUT;

-- LPM specification calls for the following, but MAX+PLUS II only implements
-- 16 eq outputs:
--	eq[2^LPM_WIDTH-1..0]		: OUTPUT;
	eq[15..0]					: OUTPUT;		-- Counter decode output
)


-------------------------------------------------------------------------------
VARIABLE
	IF (CBX_FAMILY() == 1 & CBXI_PARAMETER != "NOTHING") GENERATE
		auto_generated : @CBXI_PARAMETER WITH (CBXI_PARAMETER = "NOTHING");
	ELSE GENERATE
	IF USE_OLD_VERSION() GENERATE
		IF need_not_gate_push_back_off() GENERATE
			c2: lpm_counter WITH( NOT_GATE_PUSH_BACK="OFF", CBXI_PARAMETER = "NOTHING" );	-- New LPM_COUNTER instance
		ELSE GENERATE
			IF OK_to_use_pcustom() GENERATE
				IF LPM_DIRECTION!="DOWN" GENERATE
					and_a[LPM_WIDTH-1..0]:NODE;
				END GENERATE;
				and_b[LPM_WIDTH-1..0]: NODE;
				dffs[LPM_WIDTH-1..0]: DFFE;					-- state storage
			ELSE GENERATE
				IF OK_to_use_8count() GENERATE		-- feature set is limited to 8count, so use 8count
					IF FAMILY_FLEX()==1 GENERATE
						p8c[CEIL(LPM_WIDTH div 8)-1..0]: f8count;
					ELSE GENERATE
						p8c[CEIL(LPM_WIDTH div 8)-1..0]: p8count;
					END GENERATE;
				ELSE GENERATE

					-- state storage
					IF NEED_dffeea() GENERATE
						dffs[LPM_WIDTH-1..0]: dffeea;
					ELSE GENERATE
						IF NEED_DFFEA_FOR_ASYNC() GENERATE
							dffs[LPM_WIDTH-1..0]: DFFEA;
						ELSE GENERATE
							dffs[LPM_WIDTH-1..0]: DFFE;
						END GENERATE;
					END GENERATE;

					-- Device aware customization. For device having aload port
					IF NEED_DFFEA_FOR_ASYNC() GENERATE
						aclr_actual							: NODE;
						a_val[LPM_WIDTH-1..0]				: NODE;
						safe_q[LPM_WIDTH-1..0]				: NODE;
						
						IF (USED(aset) # USED(aconst)) & USED(aclr) GENERATE
							a_data[LPM_WIDTH-1..0]				: NODE;
							effective_prn[LPM_WIDTH-1..0]		: NODE;
							effective_clrn[LPM_WIDTH-1..0]		: NODE;
							pre_latch_signal[LPM_WIDTH-1..0]	: NODE;
							latch_signal[LPM_WIDTH-1..0] 		: NODE;
							pre_hazard[LPM_WIDTH-1..0]			: NODE;				
						END GENERATE;
					END GENERATE;

					IF USED(LPM_AVALUE) GENERATE
						ac: lpm_constant WITH( LPM_WIDTH=LPM_WIDTH, LPM_CVALUE=LPM_AVALUE, CBXI_PARAMETER = "NOTHING" );
					END GENERATE;

					IF USED(LPM_SVALUE) GENERATE
						sc: lpm_constant WITH( LPM_WIDTH=LPM_WIDTH, LPM_CVALUE=LPM_SVALUE, CBXI_PARAMETER = "NOTHING" );
					END GENERATE;

					IF FLEXUseCarryChain() GENERATE
						carrybit[SizeCarryChain()-1..0]	: carry_sum;
						Count[LPM_WIDTH-1..0]			: NODE;
						
						IF LoadMuxLCELL() GENERATE

							IF nLoadInput()<=1 GENERATE nLoad:NODE;	ELSE GENERATE nLoad:LCELL; END GENERATE;

							IF nLoadDataInput()<=3 GENERATE
								LoadLCELL[LPM_WIDTH-1..0]: NODE;
							ELSE GENERATE
								LoadLCELL[LPM_WIDTH-1..0]: LCELL;
							END GENERATE;

							IF UseClearableCounterMode() # (UseLabWideSclr() & (USED(clk_en) # UseSyncClrModUp())) GENERATE
								nClr	: LCELL;
							ELSE GENERATE
								nClr	: NODE;
							END GENERATE;

							IF USED(clk_en)
							# (USED_UPDOWN() & !FAMILY_HAS_UPDOWN_COUNTER_MODE())
							# (USED(cnt_en) & !CntEnThroughCarryChain())
							#  UseClearableCounterMode()
							# (!UseLabWideSclr() & UseFuncSCLR())
							#  USED(sset)
							# !USED(cnt_en)
							GENERATE		-- LUT 0-5 or no cnt_en
								Wrap : NODE;
							ELSE GENERATE	-- LUT 6-7 with cnt_en: special wrap
								Wrap : LCELL;
							END GENERATE;

							LoadModulus[LPM_WIDTH-1..0]	: NODE;
							LoadCntEn[LPM_WIDTH-1..0]	: NODE;
							LoadSLoad[LPM_WIDTH-1..0]	: NODE;
							LoadSSet[LPM_WIDTH-1..0]	: NODE;
							nState[LPM_WIDTH-1..0]		: NODE;

							UseSClr, UseSSet, UseSLoad								: NODE;
							UseLoadCntEn, UseLoadSLoad, UseLoadSSet					: NODE;
							DnWrapOnly, UseModulus, ENA_DATA, SyncClr, LoadUpWrap	: NODE;
							LUTCntEn, UseLUTCntEn									: NODE;

						ELSE GENERATE	-- no LoadMuxLCELL
							DontWrap: NODE;
						END GENERATE;
						
					ELSE GENERATE	-- FLEX doesn't UsesCarryChain
						nState[LPM_WIDTH-1..0]: NODE;

	-- Adder/encoder for next-state logic when count is enabled
						IF COUNT_ONLY_UP() GENERATE
							add_sub	: lpm_add_sub WITH( LPM_WIDTH=LPM_WIDTH, CBXI_PARAMETER = "NOTHING",
														ONE_INPUT_IS_CONSTANT="YES",
														LPM_DIRECTION="ADD" );
						ELSE GENERATE
							IF COUNT_ONLY_DOWN() GENERATE
								add_sub	: lpm_add_sub WITH( LPM_WIDTH=LPM_WIDTH, CBXI_PARAMETER = "NOTHING",

⌨️ 快捷键说明

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