#include  <stdio.h>
#include  <string.h>
#include  <varargs.h>

#include   MUT_H
#include   MLO_H
#include   MPH_H
#include  "mbkgen.h"
# include  GRF_H
# include  GBS_H
# include  RSA_H
#include   DUT_H
#include   DGN_H
#include  "FpgenMBK.h"
#include  "FpgenMGN.h"


/*      Alliance CAD System 2.0                                   */
/*        FITPATH Package 0.0                                     */
/*                                                                */
/*  Author  :      Jean-Paul CHAPUT                               */
/*  E-mail  :  cao-vlsi@masi.ibp.fr                               */
/* ************************************************************** */
/*  module  :  "FpgenMBK.c"                                       */


/* Internals defines of module. */
#define        IC_FpMBK_MaxLenString             16384


/* Declaration of interface functions of module. */
/* extern void  DmlMBK_ErrorFpgen(void);
   extern void  DmlMBK_WarngFpgen(void);

   extern void  DmlMBK_DefLoFig(void);
   extern void  DmlMBK_SavLoFig(void);
   extern long  DmlMBK_LoConPower(char *aConName);
   extern void  DmlMBK_LoCon(     char *aConName,
                                  char  aConSide);
   extern void  DmlMBK_Import(va_list) va_dcl
   extern void  DmlMBK_Flatten();
   extern void  DmlMBK_GenericBool(  long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericMask(  long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericMux(   long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericBuse(  long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericAddf(  long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericShift( long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericConst( long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericComp(  long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericDff(   long  aFuncId, va_alist  aStdArgs);
   extern void  DmlMBK_GenericRfg(   long  aFuncId, va_alist  aStdArgs);
   */


/* Declaration of external variables of module. */
       FpgenVGlob_t fpgen_Glob = { (losig_list*)NULL, /* SigVdd    */
								   (losig_list*)NULL, /* SigVss    */
								   (locon_list*)NULL, /* ConVdd    */
								   (locon_list*)NULL, /* ConVss    */
							C_FPGEN_ConModeEXPLICIT , /* ConMode   */
							C_FPGEN_LSBIndexZero    , /* Msb0      */
							C_FPGEN_DataTypeTerminal, /* TypeDP    */
									     (char*)NULL, /* CurrFunc  */
								   (lofig_list*)NULL, /* CurrLoFig */
									              0L, /* CallDefLo */
									              0L  /* CallSavLo */
								 };


/* Declaration of internal variables of module. */
static char  StringBuffer[IC_FpMBK_MaxLenString];
static char *TablRootName[C_FPGEN_RootNameNB] = {  "buff",
	                                                "inv",
												    "or2",
												   "nor2",
												    "or3",
												   "nor3",
												   "and2",
												  "nand2",
												   "and3",
												  "nand3",
												   "xor2",
												  "xnor2",
											   "nor2mask",
											  "nand2mask",
											  "xnor2mask",
												"nmux2cs",
											     "mux2cs",
												 "mux3cd",
											    "nmux2fs",
												 "mux2fs",
												 "mux3fd",
												   "buse",
												  "nbuse",
												  "add2f",
												 "adsb2f",
												  "shift",
												  "const",
												    "nul",
												"platch1",
											   "nplatch1",
												    "pms",
												  "pdff" ,
												  "pdfft",
												 "rfg1cc",
												 "rfg2cc",
												 "rfg1fc",
												 "rfg2fc",
												 "rfg1c0",
												 "rfg2c0",
												 "rfg1f0",
												 "rfg2f0"};

/* Declarations of internal functions of module. */
#ifndef  ANSI_PROTO
#ifndef  HOME_PC
static       void  DmlMBK_GenericMask();
static       void  DmlMBK_GenericMux();
static       void  DmlMBK_GenericDff();
static       void  DmlMBK_GenericRfg();
#endif
static chain_list *DmlMBK_BusToChain();
static chain_list *DmlMBK_ChainToSig();
static chain_list *DmlMBK_NameToSig();
static chain_list *DmlMBK_MatchImplicitConn();
static       void  DmlMBK_xvLoIns();
static       void  DmlMBK_SwapWorkLofig();
static       void  DmlMBK_UdpCon();
#else
static chain_list *DmlMBK_NameToSig(chain_list *aPtChain,
									      char *aSigName,
									      long *aSigType);
static chain_list *DmlMBK_MatchImplicitConn(      char *aInstcName   ,
											chain_list *aChainConName,
											chain_list *aChainSigName,
											lofig_list *aPtLoFig     ,
											      long *aPtSigCount  )
static       void  DmlMBK_xvLoIns(      char *aModelName    ,
								        char *aInstcName    ,
								  chain_list *aChainImplConn,
								    va_alist  aStdArgs      );
#endif


/*  Function  :  'DmlMBK_DefLoFig'.                               */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_DEFLOFIG" (module "FpgenMGN"). */

extern void  DmlMBK_DefLoFig()
{
	if (fpgen_Glob.CallDefLo == 1L) 
	{
	    /* Check the value of MBK_SEPAR. */
		if (SEPAR != '.')
			Dut_PrintWarng(W_FPGEN_WARNG        , 
						   W_FPGEN_DEFLOMbkSepar,
						     fpgen_Glob.CurrFunc, SEPAR);

		/* Check the value of MBK_IN_PH and MBK_OUT_PH. */
		if (strcmp(IN_PH,OUT_PH))
			Dut_PrintWarng(W_FPGEN_WARNG          , 
						   W_FPGEN_DEFLOMbkInOutPH,
						     fpgen_Glob.CurrFunc  , IN_PH, OUT_PH);
	}

	fpgen_Glob.CurrLofig = WORK_LOFIG;

	/* Declaration of signals and terminals : */
	/*             - "vdd"                    */
	/*             - "vss"                    */

	/* Creation of SIGNAL Vdd. */
	num_index += 1;
	fpgen_Glob.SigVdd = addlosig(WORK_LOFIG      ,
								 num_index       ,
					  addchain((chain_list*)NULL,
							   (void*)"vdd"     ),
								 EXTERNAL        ,
								 C_SUPP_MBKNOCAPA);

	/* Creation of SIGNAL Vss. */
	num_index += 1;
	fpgen_Glob.SigVss = addlosig(WORK_LOFIG      ,
								 num_index       ,
					  addchain((chain_list*)NULL,
							   (void*)"vss"     ),
								 EXTERNAL        ,
								 C_SUPP_MBKNOCAPA);

	(void)Dut_AddUdpData(WORK_LOFIG, fpgen_Glob.TypeDP);
}


/*  Function  :  'DmlMBK_SavLoFig'.                               */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_SAVLOFIG" (module "FpgenMGN"). */

extern void  DmlMBK_SavLoFig()
{ 
	/* Look for the VDD power supplie. */
	if (Dut_GetLoConBySig(WORK_LOFIG,fpgen_Glob.SigVss) == (locon_list*)NULL)
		Dut_PrintError(E_FPGEN_ERROR        ,
					   E_FPGEN_SAVLOMissVSS ,
					     fpgen_Glob.CurrFunc);

	/* Look for the VSS power supplie. */
	if (Dut_GetLoConBySig(WORK_LOFIG,fpgen_Glob.SigVdd) == (locon_list*)NULL)
		Dut_PrintError(E_FPGEN_ERROR        ,
					   E_FPGEN_SAVLOMissVDD ,
					     fpgen_Glob.CurrFunc);

	/* Create the "*.dpr" file. */
	Dut_SaveUdp(WORK_LOFIG->NAME);
}


/*  Function  :  'DmlMBK_LoConPower'.                             */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_LOCON" (module "FpgenMGN").    */

extern long  DmlMBK_LoConPower(aConName)
	char *aConName;
{
	losig_list *PowerSig = (losig_list*)NULL;
	      char *NameVSS  = namealloc("vss");
	      char *NameVDD  = namealloc("vdd");

	/* Look for VSS power supply connector names. */
	if (isvss(aConName))
	{
	    /* The name of the power supply must be "vss". */
		if (namealloc(aConName) != NameVSS)
			Dut_PrintError(E_FPGEN_ERROR                 ,
						   E_FPGEN_LOCONPOWERBadNamePower,
						     fpgen_Glob.CurrFunc         ,
						                aConName         );
		else
			PowerSig = fpgen_Glob.SigVss;
	}

	/* Look for VSS power supply connector names. */
	if (isvdd(aConName))
	{
	    /* The name of the power supply must be "vss". */
		if (namealloc(aConName) != NameVDD)
			Dut_PrintError(E_FPGEN_ERROR                 ,
						   E_FPGEN_LOCONPOWERBadNamePower,
						     fpgen_Glob.CurrFunc         ,
						                aConName         );
		else
			PowerSig = fpgen_Glob.SigVdd;
	}


	/* If no power supply connector has been recognized, return false. */
	if (PowerSig == (losig_list*)NULL) return(FALSE);

	/* Check for a previously added power connector. */
	if (Dut_GetLoConBySig(WORK_LOFIG, PowerSig) != (locon_list*)NULL)
		Dut_PrintError(E_FPGEN_ERROR              ,
					   E_FPGEN_LOCONPOWERDuplicate,
					     fpgen_Glob.CurrFunc      ,
					                aConName      );

	/* Add the power connector. */
	(void)addlocon(WORK_LOFIG,
				   aConName  ,
				   PowerSig  ,
				   IN        );

	return(TRUE);
}


/*  Function  :  'DmlMBK_LoCon'.                                  */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_LOCON" (module "FpgenMGN").    */

extern void  DmlMBK_LoCon(aConName,
						  aConSide)
	char *aConName;
	long  aConSide;
{
	char  SUPP_ConSide;

	/* Check the argument "aConSide". */
	switch( aConSide )
	{
	    case C_FPGEN_ConSideEast:
	        SUPP_ConSide = C_SUPP_ConSideEast;
			break;
	    case C_FPGEN_ConSideWest:
	        SUPP_ConSide = C_SUPP_ConSideWest;
			break;
	    case C_FPGEN_ConSideNorth:
	        SUPP_ConSide = C_SUPP_ConSideNorth;
			break;
	    case C_FPGEN_ConSideSouth:
	        SUPP_ConSide = C_SUPP_ConSideSouth;
			break;
	    case C_FPGEN_ConSideDefault:
	        SUPP_ConSide = C_SUPP_ConSideDefault;
	        break;
	    default:
			Dut_PrintError(E_FPGEN_ERROR       ,
						   E_FPGEN_LOCONBadSide,
						   fpgen_Glob.CurrFunc ,
						   aConSide            ,
						   aConName            );
	}

	if (!is_bus(aConName))
		Dut_AddUdpCon(WORK_LOFIG, Dut_CheckName(aConName), SUPP_ConSide);
	else
		DmlMBK_UdpCon(                          aConName , SUPP_ConSide);
}


/*  Fonction  :  'DmlMBK_Import'.                                 */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_IMPORT" (module "FpgenMGN").   */

extern void  DmlMBK_Import(aStdArgs)
	va_list  aStdArgs;
{
	             char *ModelName;
				 char *InstName;
	       lofig_list *PtLoFig;


	/* Recuperation of fixed arguments : */
	/*     - Model name (ModelName).     */
	/*     - Instance name (InstName).   */
	ModelName = va_arg( aStdArgs, char*);
	InstName  = va_arg( aStdArgs, char*);

	/* Load the logical model. */
	PtLoFig = Dut_LoadLoFig( ModelName);

	/* Instanciate the logical figure. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
		   (chain_list*)NULL,
				    aStdArgs);
}


/*  Function  :  'DmlMBK_Flatten'.                                */
/* -------------------------------------------------------------- */
/*  MBK function associated to "DP_FLATTEN" (module "FpgenMGN").  */

extern void  DmlMBK_Flatten()
{ Dut_HierarchFlatten( WORK_LOFIG); }


/*  Function  :  'DmlMBK_GenericBool'.                            */
/* -------------------------------------------------------------- */
/*  Generic Macro-Function for all boolean operators.             */

extern void  DmlMBK_GenericBool(aFuncId,aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
				 long  Width;
	             long  Slice;
	             long     Drive;
	             long  MaxDrive;

				 char  StringBuffer[C_SUPP_MBKSZNAME];

    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - Operator bus wide (Width).  */
	/*     - LSB starting slice (Slice). */
	/*     - Output drive power (Drive). */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameInv:   MaxDrive =   C_INV_NBDRIVE; break;
	    case C_FPGEN_RootNameAnd2:  MaxDrive =  C_AND2_NBDRIVE; break;
	    case C_FPGEN_RootNameAnd3:  MaxDrive =  C_AND3_NBDRIVE; break;
	    case C_FPGEN_RootNameNand2: MaxDrive = C_NAND2_NBDRIVE; break;
	    case C_FPGEN_RootNameNand3: MaxDrive = C_NAND3_NBDRIVE; break;
	    case C_FPGEN_RootNameOr2:   MaxDrive =   C_OR2_NBDRIVE; break;
	    case C_FPGEN_RootNameOr3:   MaxDrive =   C_OR3_NBDRIVE; break;
	    case C_FPGEN_RootNameNor2:  MaxDrive =  C_NOR2_NBDRIVE; break;
	    case C_FPGEN_RootNameNor3:  MaxDrive =  C_NOR3_NBDRIVE; break;
	    case C_FPGEN_RootNameXor2:  MaxDrive = 1;               break;
	    case C_FPGEN_RootNameXnor2: MaxDrive = 1;               break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericBool"        ,
						   aFuncId              );
	}

	/* Read the and check the "Drive" parameters, if it exist. */
	if (MaxDrive > 1)
	{
		Drive = va_arg( aStdArgs, long);

		if (   (Drive < 1       )
			|| (Drive > MaxDrive))
		    Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONDrive  , 
						     fpgen_Glob.CurrFunc, InstName, Drive);
	}
	else
		Drive = 1;

	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONWidth  , 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice              < 0      )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);


	/* Build an explicit model name. */
	(void)sprintf(StringBuffer,"%s_%ldx%ldx%ldx%ld%c_cl",
				  TablRootName[aFuncId]                 ,
				      DP_WIDTH                          ,
				         Width                          ,
				         Slice                          ,
				         Drive                          ,
				  ((fpgen_Glob.Msb0) ? 'm' : 'l')       );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL       ;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT )
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
			case C_FPGEN_RootNameInv:
		        (void)Dgn_DispatchInv(ModelName      ,
									  Width          ,
									  Slice          ,
									  Drive          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
			case C_FPGEN_RootNameAnd2:
		        (void)Dgn_DispatchAnd2(ModelName      ,
									   Width          ,
									   Slice          ,
									   Drive          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameAnd3:
		        (void)Dgn_DispatchAnd3(ModelName      ,
									   Width          ,
									   Slice          ,
									   Drive          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameNand2:
		        (void)Dgn_DispatchNand2(ModelName      ,
										Width          ,
										Slice          ,
										Drive          ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
										           TRUE);
				break;
			case C_FPGEN_RootNameNand3:
		        (void)Dgn_DispatchNand3(ModelName      ,
										Width          ,
										Slice          ,
										Drive          ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
										           TRUE);
				break;
			case C_FPGEN_RootNameOr2:
		        (void)Dgn_DispatchOr2(ModelName      ,
									  Width          ,
									  Slice          ,
									  Drive          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
			case C_FPGEN_RootNameOr3:
		        (void)Dgn_DispatchOr3(ModelName      ,
									  Width          ,
									  Slice          ,
									  Drive          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
			case C_FPGEN_RootNameNor2:
		        (void)Dgn_DispatchNor2(ModelName      ,
									   Width          ,
									   Slice          ,
									   Drive          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameNor3:
		        (void)Dgn_DispatchNor3(ModelName      ,
									   Width          ,
									   Slice          ,
									   Drive          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameXor2:
		        (void)Dgn_DispatchXor2(ModelName      ,
									   Width          ,
									   Slice          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameXnor2:
		        (void)Dgn_DispatchXnor2(ModelName      ,
										Width          ,
										Slice          ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
										           TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'A');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}

	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName    ,
				    InstName    ,
			   (chain_list*)NULL,
				   aStdArgs     );
	
#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericMask'.                               */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericMask(aFuncId ,
								aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
				 long  Width;
				 long  Slice;
				 char  *Smask;
	             long *xlmask;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments :             */
	/*     - Specific function identifier.           */
	/*     - Instance name (InstName).   */
	/*     - Operator bus wide (Width).  */
	/*     - LSB starting slice (Slice). */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );
	Smask    = va_arg( aStdArgs, char*);


	/* Check the fixed arguments.                          */
	/* RQ :     These checks are performed in the genrator */
	/*      itself too.                                    */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameNor2mask:
	    case C_FPGEN_RootNameXnor2mask:
	    case C_FPGEN_RootNameNand2mask:
	        ChainImplConn = addchain(ChainImplConn,"msk");
	        break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						           "GenericMask",
						                 aFuncId);
	}


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR,
						   E_FPGEN_COMMONWidth, 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);

    /* Check the syntax of the string. */
    (void)Dut_XlStrCheck( Smask);

    xlmask = Dut_XlAlloc();

	/* Convert the string into an extended long. */
	Dut_XlStrToXl( Smask, xlmask);

   	/* Build a more explicit model name. */
   	(void*)sprintf(StringBuffer, "%s%s_%ldx%ldx%ld%c_cl",
				   TablRootName[aFuncId]                ,
				   Dut_XlToStr(xlmask,
   							 DP_WIDTH,
   			   C_SUPP_BaseHexadecimal)                  ,
   				   DP_WIDTH                             ,
				   Width                                ,
				   Slice                                ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')      );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL       ;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);
		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
		    case C_FPGEN_RootNameNor2mask:
		        (void)Dgn_DispatchNor2mask(ModelName      ,
										   Width          ,
										   Slice          ,
										   xlmask         ,
										   fpgen_Glob.Msb0,
										             FALSE,
										              TRUE,
										              TRUE);
				break;
		    case C_FPGEN_RootNameXnor2mask:
		        (void)Dgn_DispatchXnor2mask(ModelName      ,
											Width          ,
											Slice          ,
											xlmask         ,
											fpgen_Glob.Msb0,
											          FALSE,
											           TRUE,
											           TRUE);
				break;
		    case C_FPGEN_RootNameNand2mask:
		        (void)Dgn_DispatchNand2mask(ModelName      ,
											Width          ,
											Slice          ,
											xlmask         ,
											fpgen_Glob.Msb0,
											          FALSE,
											           TRUE,
											           TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'A');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	DmlMBK_xvLoIns(ModelName    ,
				    InstName    ,
				   ChainImplConn,
				   aStdArgs     );

	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericMux'.                             */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericMux(aFuncId ,
							   aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

	       chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
	             char *SelName;
				 long  Width;
				 long  Slice;
	             long  BusNB;
	             long  BusDecod;
	             long  BusSelWide;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - Operator bus wide (Width).  */
	/*     - LSB starting slice (Slice). */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );

	/* Check the fixed arguments.                          */
	/* RQ :     These checks are performed in the genrator */
	/*      itself too.                                    */

	        BusNB = 0;
	switch( aFuncId )
	{
	    case C_FPGEN_RootNameMux3fd:  BusNB    += 1;
	    case C_FPGEN_RootNameNmux2fs: ;
	    case C_FPGEN_RootNameMux2fs:  BusNB    += 3;
	                                  BusDecod  = FALSE;
	                                  break;
	    case C_FPGEN_RootNameMux3cd:  BusNB    += 1;
	    case C_FPGEN_RootNameNmux2cs: ;
	    case C_FPGEN_RootNameMux2cs:  BusNB    += 3;
	                                  BusDecod  = TRUE;
	                                  break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						            "GenericMux",
						                 aFuncId);
	}

	/* Compute the control bus wide. */
	if (BusDecod)
        for( BusSelWide=1; BusNB>>(BusSelWide+1); BusSelWide++);
	else
        BusSelWide = BusNB-1;

	/* Build the implicit connectors name list. */
	if (BusSelWide > 1)
	{
		sprintf( StringBuffer, "sel[%ld:0]", BusSelWide-1);
		SelName = namealloc( StringBuffer);
	}
	else
		SelName = namealloc( "sel");

	ChainImplConn = addchain( ChainImplConn, (void*)SelName);


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONWidth  , 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);


	/* Build a more explicit model name. */
	(void)sprintf(StringBuffer, "%s_%ldx%ldx%ld%c_cl",
				  TablRootName[aFuncId]              ,
				      DP_WIDTH                       ,
				         Width                       ,
				         Slice                       ,
				  ((fpgen_Glob.Msb0) ? 'm' : 'l')    );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL       ;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT )
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
		    case C_FPGEN_RootNameNmux2cs:
		        (void)Dgn_DispatchNmux2cs(ModelName      ,
										  Width          ,
										  Slice          ,
										  fpgen_Glob.Msb0,
										            FALSE,
										             TRUE,
										             TRUE);
				break;
		    case C_FPGEN_RootNameMux2cs:
		        (void)Dgn_DispatchMux2cs(ModelName      ,
										 Width          ,
										 Slice          ,
										 fpgen_Glob.Msb0,
										           FALSE,
										            TRUE,
										            TRUE);
				break;
		    case C_FPGEN_RootNameMux3cd:
		        (void)Dgn_DispatchMux3cd(ModelName      ,
										 Width          ,
										 Slice          ,
										 fpgen_Glob.Msb0,
										           FALSE,
										            TRUE,
										            TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'A');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}

	DmlMBK_xvLoIns(ModelName    ,
				    InstName    ,
				   ChainImplConn,
				   aStdArgs     );

	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericBuse'.                            */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericBuse(aFuncId ,
								aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

	       chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
				 long  Width;
				 long  Slice;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - Operator bus wide (Width).  */
	/*     - LSB starting slice (Slice). */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );

	/* Check the fixed arguments.                          */
	/* RQ :     These checks are performed in the genrator */
	/*      itself too.                                    */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameBuse:
	    case C_FPGEN_RootNameNbuse:
	        ChainImplConn = addchain(ChainImplConn,"sel");
	        break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericBuse"        ,
						   aFuncId              );
	}


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONWidth  , 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);


	/* Build a more explicit model name. */
	(void)sprintf(StringBuffer, "%s_%ldx%ldx%ld%c_cl",
				  TablRootName[aFuncId]              ,
				      DP_WIDTH                       ,
				         Width                       ,
				         Slice                       ,
				  ((fpgen_Glob.Msb0) ? 'm' : 'l')    );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL       ;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT )
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
			case C_FPGEN_RootNameBuse:
			    (void)Dgn_DispatchBuse(ModelName      ,
									   Width          ,
									   Slice          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
			case C_FPGEN_RootNameNbuse:
			    (void)Dgn_DispatchNbuse(ModelName      ,
										Width          ,
										Slice          ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
										           TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'A');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}

	DmlMBK_xvLoIns(ModelName    ,
				    InstName    ,
				   ChainImplConn,
				   aStdArgs     );

	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericAddf'.                            */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericAddf(aFuncId ,
							    aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
	             long  TypeCSA = 0L;
	             long  TypeSUB = 0L;
	             long  TypeASB = 0L;
	             long  BusInNB;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - numder of words (Words).    */
	InstName = va_arg( aStdArgs, char*);


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */
	BusInNB = 0;

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameAdsb2f:
	              TypeASB = 1L;
	        ChainImplConn = addchain(ChainImplConn,  "sub");
	    case C_FPGEN_RootNameAdd2f:
	        BusInNB      += 1;
	        ChainImplConn = addchain(ChainImplConn, "over");
	        ChainImplConn = addchain(ChainImplConn, "cout");
			break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericAddf"        ,
						   aFuncId              );
	}


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	/* Build a more explicit model name. */
	(void*)sprintf(StringBuffer, "%s_%ldx%ldx%ldx%c_bk",
				   TablRootName[aFuncId]               ,
				       DP_WIDTH                        ,
				       DP_WIDTH                        ,
				              0                        ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')     );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;
		(void)rsa(DP_WIDTH,  /* Size of words in bits.      */
				        0L,  /* No carry in.                */
				        0L,  /* No intermediate carry.      */
				        1L,  /* "over" on the north side.   */
				        0L,  /* direct output.              */
				   TypeCSA,  /* Two operand adder.          */
				   TypeSUB,  /* Substractor.                */
				   TypeASB,  /* Adder/substractor.          */
				        0L,  /* ovr     : BULL option.      */
				        0L,  /* Deci    : BULL option.      */
				        0L,  /* Stretch : BULL option.      */
				        0L,  /* Stretch2: BULL option.      */
				        0L,  /* LSB have index ZERO.        */
				        1L,  /* virtual connectors.         */
				      TRUE,  /* Layout view.                */
				     FALSE,  /* Icon.                       */
				      TRUE,  /* VHDL behavioral view.       */
				     FALSE,  /* Patterns.                   */
				     FALSE,  /* Datasheet.                  */
				     FALSE,  /* Outline.                    */
				      TRUE,  /* Connector netlist.          */
				     FALSE,  /* SPICE performances.         */
				 ModelName); /* Model name.                 */

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'P');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
			   ChainImplConn,
				   aStdArgs );
	
	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericShift'.                           */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericShift(aFuncId ,
								 aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - numder of words (Words).    */
	InstName = va_arg( aStdArgs, char*);


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameShift:
			break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericShift"       ,
						   aFuncId              );
	}


	/* List of controls connector names. */
	ChainImplConn = addchain(ChainImplConn, "left");
	ChainImplConn = addchain(ChainImplConn,  "rot");
	ChainImplConn = addchain(ChainImplConn,  "ext");


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	/* Build a more explicit model name. */
	(void*)sprintf(StringBuffer, "%s_%ldx%ldx%ldx%c_bk",
				   TablRootName[aFuncId]               ,
				       DP_WIDTH                        ,
				       DP_WIDTH                        ,
				              0                        ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')     );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;
		(void)bsg(DP_WIDTH,  /* Size of words in bits.      */
				        1L,  /* virtual connectors.         */
				        0L,  /* LSB have index ZERO.        */
				 ModelName,  /* Model name.                 */
				      TRUE,  /* Layout view.                */
				     FALSE,  /* Icon.                       */
				      TRUE,  /* VHDL behavioral view.       */
				     FALSE,  /* Patterns.                   */
				     FALSE,  /* Datasheet.                  */
				     FALSE,  /* Outline.                    */
				      TRUE); /* Connector netlist.          */

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'P');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
			   ChainImplConn,
				   aStdArgs );
	
	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericConst'.                           */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericConst(aFuncId ,
								 aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
	             long  Width;
	             long  Slice;
	             long *xlconst;
	             char  *Sconst;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - numder of words (Words).    */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );
	Sconst   = va_arg( aStdArgs, char*);


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameConst:
			break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericConst"       ,
						   aFuncId              );
	}

	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR,
						   E_FPGEN_COMMONWidth, 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);

    /* Check the syntax of the string. */
    (void)Dut_XlStrCheck( Sconst);

    xlconst = Dut_XlAlloc();

	/* Convert the string into an extended long. */
	Dut_XlStrToXl( Sconst, xlconst);

	/* Build a more explicit model name. */
	(void*)sprintf(StringBuffer, "%s%s_%ldx%ldx%ldx%c_cl",
				   TablRootName[aFuncId]                 ,
				   Dut_XlToStr(xlconst,
   							 DP_WIDTH ,
   			    C_SUPP_BaseHexadecimal)                  ,
				       DP_WIDTH                          ,
				          Width                          ,
				          Slice                          ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')       );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
		    case C_FPGEN_RootNameConst:
		        (void)Dgn_DispatchConst(ModelName      ,
										Width          ,
										Slice          ,
										xlconst        ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
									               TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'P');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
			   ChainImplConn,
				   aStdArgs );
	
	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericComp'.                            */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericComp(aFuncId ,
								aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
	             long  Width;
	             long  Slice;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - numder of words (Words).    */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameNul:
			break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericComp"        ,
						   aFuncId              );
	}

	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR,
						   E_FPGEN_COMMONWidth, 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);


	/* Build a more explicit model name. */
	(void*)sprintf(StringBuffer, "%s_%ldx%ldx%ldx%c_cl",
				   TablRootName[aFuncId]               ,
				       DP_WIDTH                        ,
				          Width                        ,
				          Slice                        ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')     );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
		    case C_FPGEN_RootNameNul:
		        (void)Dgn_DispatchNul(ModelName      ,
									  Width          ,
									  Slice          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'P');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
			   ChainImplConn,
				    aStdArgs);
	
	/* Attempt to delete the list of implicit connectors name. */
	/* (if it hasn't be done previously, in EXPLICIT mode)     */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericDff'.                             */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericDff(aFuncId ,
							   aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

	       chain_list *ChainImplConn = (chain_list*)NULL;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
				 long  Width;
				 long  Slice;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - Operator bus wide (Width).  */
	/*     - LSB starting slice (Slice). */
	InstName = va_arg( aStdArgs, char*);
	Width    = va_arg( aStdArgs, long );
	Slice    = va_arg( aStdArgs, long );

	/* Check the fixed arguments.                          */
	/* RQ :     These checks are performed in the genrator */
	/*      itself too.                                    */

	switch( aFuncId )
	{
	    case C_FPGEN_RootNamePlatch1:
	    case C_FPGEN_RootNameNplatch1:
	        ChainImplConn = addchain(ChainImplConn,   "ck");
	        break;
	    case C_FPGEN_RootNamePms:
	        ChainImplConn = addchain(ChainImplConn,  "ckm");
	        ChainImplConn = addchain(ChainImplConn,  "cks");
	        break;
	    case C_FPGEN_RootNamePdfft:
	        ChainImplConn = addchain(ChainImplConn,"scin" );
	        ChainImplConn = addchain(ChainImplConn,"scout");
	        ChainImplConn = addchain(ChainImplConn, "test");
	    case C_FPGEN_RootNamePdff:
	        ChainImplConn = addchain(ChainImplConn,  "wen");
	        ChainImplConn = addchain(ChainImplConn,   "ck");
			break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericDff"         ,
						   aFuncId              );
	}


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (Width == C_FPGEN_DEFAULTWidth)
		Width = DP_WIDTH;
	else
		if (   (Width < 1       )
			|| (Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONWidth  , 
						     fpgen_Glob.CurrFunc, InstName, Width);

	if (Slice == C_FPGEN_DEFAULTSlice)
		Slice = 0;
	else
		if (   (Slice       < 0       )
			|| (Slice+Width > DP_WIDTH))
			Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_COMMONSlice  , 
						     fpgen_Glob.CurrFunc, InstName, Slice);


	/* Build a more explicit model name. */
	(void)sprintf(StringBuffer, "%s_%ldx%ldx%ld%c_cl",
				  TablRootName[aFuncId]              ,
				      DP_WIDTH                       ,
				         Width                       ,
				         Slice                       ,
				  ((fpgen_Glob.Msb0) ? 'm' : 'l')    );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL       ;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT )
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;

		switch( aFuncId )
		{
		    case C_FPGEN_RootNamePlatch1:
		        (void)Dgn_DispatchPl1(ModelName      ,
									  Width          ,
									  Slice          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
		    case C_FPGEN_RootNameNplatch1:
		        (void)Dgn_DispatchNpl1(ModelName      ,
									   Width          ,
									   Slice          ,
									   fpgen_Glob.Msb0,
												 FALSE,
												  TRUE,
												  TRUE);
				break;
		    case C_FPGEN_RootNamePms:
		        (void)Dgn_DispatchPms(ModelName      ,
									  Width          ,
									  Slice          ,
									  fpgen_Glob.Msb0,
									            FALSE,
									             TRUE,
									             TRUE);
				break;
		    case C_FPGEN_RootNamePdff:
		        (void)Dgn_DispatchPdff(ModelName      ,
									   Width          ,
									   Slice          ,
									   fpgen_Glob.Msb0,
									             FALSE,
									              TRUE,
									              TRUE);
				break;
		    case C_FPGEN_RootNamePdfft:
		        (void)Dgn_DispatchPdfft(ModelName      ,
										Width          ,
										Slice          ,
										fpgen_Glob.Msb0,
										          FALSE,
										           TRUE,
										           TRUE);
				break;
		}

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'A');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}

	DmlMBK_xvLoIns(ModelName    ,
				    InstName    ,
				   ChainImplConn,
				   aStdArgs     );

	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);


#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_GenericRfg'.                             */
/* -------------------------------------------------------------- */

extern void  DmlMBK_GenericRfg(aFuncId ,
							   aStdArgs)
	   long  aFuncId;
	va_list  aStdArgs;
{
#define  access_ModelLofig  ((lofig_list*)(ModelPtype->DATA))

	static ptype_list *TABLPMODEL = (ptype_list*)NULL;

		   chain_list *ChainImplConn;
		   ptype_list *ModelPtype;
				 char *ModelName;
				 char *InstName;
	             char *Aw0Name;
	             char *Ar0Name;
	             char *Ar1Name;
	             long  Type;
				 long  Words;
				 long  Stuck;
	             long  BusReadNB;
				 long  BusAddrWide;


    /* If the function have been call before DP_DEFLO :      */
	/*     - Initialisation of error data base.              */
	/*     - Process error : "no previous call to DP_DEFLO". */
	if (fpgen_Glob.CallDefLo == 0)
	{
		DmlMBK_ErrorFpgen();
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_COMMONMissDefLo,
					     fpgen_Glob.CurrFunc  );
	}

	/* Recuperation of fixed arguments : */
	/*     - Instance name (InstName).   */
	/*     - numder of words (Words).    */
	InstName = va_arg( aStdArgs, char*);
	Words    = va_arg( aStdArgs, long );


	/* Check the fixed arguments.                           */
	/* RQ :     These checks are performed in the generator */
	/*      itself too.                                     */
	BusReadNB = 0;

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameRfg2f0:
	    case C_FPGEN_RootNameRfg2fc:
	        BusReadNB  += 1;
	    case C_FPGEN_RootNameRfg1f0:
	    case C_FPGEN_RootNameRfg1fc:
	        Type        = 0;
	        /* Compute width of decoder bus input. */
	        BusAddrWide = Words;
	        break;
	    case C_FPGEN_RootNameRfg2c0:
	    case C_FPGEN_RootNameRfg2cc:
	        BusReadNB  += 1;
	    case C_FPGEN_RootNameRfg1c0:
	    case C_FPGEN_RootNameRfg1cc:
	        Type   = 3;
	        /* Compute width of decoder bus input. */
	        for( BusAddrWide=1; Words>>(BusAddrWide+1); BusAddrWide++);
	        break;
	    default:
	        Dut_PrintError(E_FPGEN_ERROR        ,
						   E_FPGEN_HIDDCOMFuncId,
						     fpgen_Glob.CurrFunc,
						   "GenericRfg"         ,
						   aFuncId              );
	}

	switch( aFuncId )
	{
	    case C_FPGEN_RootNameRfg1f0:;
	    case C_FPGEN_RootNameRfg2f0:;
	    case C_FPGEN_RootNameRfg1c0:;
	    case C_FPGEN_RootNameRfg2c0:
	        Stuck = 1L; break;
	    case C_FPGEN_RootNameRfg1fc:;
	    case C_FPGEN_RootNameRfg2fc:
	    case C_FPGEN_RootNameRfg1cc:
	    case C_FPGEN_RootNameRfg2cc:
	        Stuck = 0L; break;
	}

	/* Build the list of implicit controls connectors. */
	sprintf( StringBuffer,   "ad_w[%ld:0]", BusAddrWide);
	Aw0Name = namealloc( StringBuffer);

	sprintf( StringBuffer, "ad_r_a[%ld:0]", BusAddrWide);
	Ar0Name = namealloc( StringBuffer);

	sprintf( StringBuffer, "ad_r_b[%ld:0]", BusAddrWide);
	Ar1Name = namealloc( StringBuffer);

	ChainImplConn = addchain((chain_list*)NULL, (void*)"we"   );
	ChainImplConn = addchain(    ChainImplConn, (void*)"ck_m" );
	ChainImplConn = addchain(    ChainImplConn, (void*)Aw0Name);
	ChainImplConn = addchain(    ChainImplConn, (void*)Ar0Name);

	if (BusReadNB == 1)	
		ChainImplConn = addchain( ChainImplConn, (void*)Ar1Name);


	if (InstName == (char*)NULL)
		Dut_PrintError(E_FPGEN_ERROR         ,
					   E_FPGEN_COMMONMissName,
					     fpgen_Glob.CurrFunc );

	if (   (Words < C_FPGEN_RFGMinWords) 
		|| (Words > C_FPGEN_RFGMaxWords))
		Dut_PrintError(E_FPGEN_ERROR          ,
					   E_FPGEN_RFGInvalidWords, 
					     fpgen_Glob.CurrFunc  , InstName, Words);

	/* Build a more explicit model name. */
	(void*)sprintf(StringBuffer, "%s_%ldx%ldx%ldx%ld%c_bk",
				   TablRootName[aFuncId]                  ,
				       DP_WIDTH                           ,
				       DP_WIDTH                           ,
				              0                           ,
				          Words                           ,
				   ((fpgen_Glob.Msb0) ? 'm' : 'l')        );
	ModelName = namealloc( StringBuffer);

	/* Search in list of already generated models. */
	for( ModelPtype  = TABLPMODEL;
		 ModelPtype != (ptype_list*)NULL;
		 ModelPtype  = ModelPtype->NEXT)
		if (access_ModelLofig->NAME == ModelName)
			break;

	/* Generation, if necessary of model. */
	if (ModelPtype == (ptype_list*)NULL)
	{
		/* Save the current logical figure. */
		DmlMBK_SwapWorkLofig();

		/* Add the newly generated model in head of list. */
		TABLPMODEL = addptype( TABLPMODEL, (void*)NULL);

		ModelPtype = TABLPMODEL;
		(void)rfg(   Words,  /* Number of words.          */
				  DP_WIDTH,  /* Size of words in bits.    */
			     BusReadNB,  /* Number of read buses.     */
				        1L,  /* D flip-flops.             */
				        0L,  /* Non-inverted outputs.     */
				        0L,  /* Normal power.             */
				        1L,  /* Write enable.             */
				        0L,  /* Write enable active high. */
				     Stuck,  /* Normal register 0.        */
				        0L,  /* Multi-access connectors.  */
				        0L,  /* Msb0 on slice 0.          */
				      Type,  /* Type of register.         */
				 ModelName,  /* Model name.               */
				      TRUE,  /* Layout view.              */
				     FALSE,  /* Outline.                  */
				      TRUE,  /* VHDL behavioral view.     */
				     FALSE,  /* Patterns.                 */
				     FALSE,  /* Data-sheet.               */
				      TRUE,  /* Connector netlist.        */
				     FALSE); /* Icon.                     */

		/* Recover the logical figure of model asked for. */ 
		access_ModelLofig = getlofig( ModelName, 'P');

		/* Restore current logical figure. */
		DmlMBK_SwapWorkLofig();
	}


	/* Instanciation of the newly created model. */
	DmlMBK_xvLoIns(ModelName,
				    InstName,
			   ChainImplConn,
				   aStdArgs );

	/* Attempt to delete the list of implicit connectors name. */
	if (ChainImplConn != (chain_list*)NULL)
		freechain( ChainImplConn);

	
#undef  access_ModelLofig
}


/*  Function  :  'DmlMBK_ErrorFpgen'.                             */
/* -------------------------------------------------------------- */
/*      Adds to the main error table all errors belongings to the 
	functions of module "fpgen". This function is normally called
	by 'DP_DEFLO' at is only first call.
	*/

extern void  DmlMBK_ErrorFpgen()
{
	static long  addcommonerror_FirstCall = TRUE;

	if (addcommonerror_FirstCall == TRUE)
	{
		/* Errors belonging to function DP_DEFLO. */
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_DEFLOCall,
"*** fpgen ***:DP_DEFLOFIG:Previous figure not saved by DP_SAVLOFIG.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_DEFLOWidthMax,
	"*** fpgen ***:DP_DEFLOFIG:Invalid MaxWidth:%ld\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_DEFLOWidthEven,
	"*** fpgen ***:DP_DEFLOFIG:Even width are not supported yet:%ld\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_DEFLOLsbPos,
	"*** fpgen ***:DP_DEFLOFIG:Invalid lsbpos:%ld\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_DEFLOBadType,
	"*** fpgen ***:DP_DEFLOFIG:Invalid data-path type:'%c'\n");

		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_SAVLOCall,
"*** fpgen ***:DP_SAVLOFIG:No data-path figure to save, use DP_DEFLOFIG.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_SAVLOMissVDD,
		"*** fpgen ***:%s:Power supply connector VDD is missing.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_SAVLOMissVSS,
		"*** fpgen ***:%s:Power supply connector VSS is missing.\n");

		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_LOCONPOWERDuplicate,
		"*** fpgen ***:%s:Redeclaration of power connector \"%s\".\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_LOCONPOWERBadNamePower,
"*** fpgen ***:%s:\"%s\" invalid power name (\"vdd\" or \"vss\" only).\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_LOCONBadSide,
		"*** fpgen ***:%s:Invalid side '%c' for connector \"%s\".\n");

		/* Errors shared by all generator functions. */
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONMissDefLo,
	"*** fpgen ***:%s:Missing previous call to DP_DEFLO.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONBusName,
	"*** fpgen ***:%s:%s:invalid bus name.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONNumSig,
"*** fpgen ***:%s:Discrepancy between model and instance terminal numbers.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONMissName,
	"*** fpgen ***:%s:Missing instance name.\n"     );
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONWidth   ,
	"*** fpgen ***:%s[%s]:Invalid width:%ld.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONSlice   ,
	"*** fpgen ***:%s[%s]:Invalid slice:%ld.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONDrive   ,
	"*** fpgen ***:%s[%s]:Invalid drive:%ld.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_COMMONBadModelName,
	"*** fpgen ***:%s[%s]:Invalid model name (forbidden suffix).\n");

		/* */
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_CONMODEUnknow,
	"*** fpgen ***:%s:Unknow CTRL terminal mode:%ld.\n");

		/* Errors shared by all hidden generic functions. */
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_HIDDCOMFuncId,
	"*** fpgen ***:%s:In hidden function:%s:Bad \"FuncId\":%ld.\n");

		/* */
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_MATCHINTERFNoMoreCon,
	"*** fpgen ***:%s:Unable to match interface, no more connectors.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_MATCHINTERFNoMoreSig,
	"*** fpgen ***:%s:Unable to match interface, no more signals.\n");

		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_RFGInvalidWords,
	"*** fpgen ***:%s[instance:%s]:Register words number out of range:%ld.\n");

		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_NAMETOSIGCtrlData,
	"*** fpgen ***:%s:Invalid connexion CTRL-DATA on signal:%s.\n");
		Dut_AddError( E_FPGEN_ERROR, E_FPGEN_NAMETOSIGCtrlCtrl,
	"*** fpgen ***:%s:Invalid connexion CTRL-CTRL on signal:%s.\n");

		addcommonerror_FirstCall = FALSE;
	}
}


/*  Fonction  :  'DmlMBK_WarngFpgen'.                                */
/* -------------------------------------------------------------- */
/*      Adds to the main warning tables all warnings belonging to    
    functions of module "fpgen.c".
	*/

extern void  DmlMBK_WarngFpgen()
{
	static long  addwarng_FirstCall = TRUE;

	if (addwarng_FirstCall == TRUE)
	{
		/* Warnings belonging to function DP_DEFLOFIG. */
		Dut_AddWarng(W_FPGEN_WARNG, W_FPGEN_DEFLOMbkSepar,
	"*** fpgen ***:%s:MBK_SEPAR different from \"_\":\"%c\".\n");
		Dut_AddWarng(W_FPGEN_WARNG, W_FPGEN_DEFLOMbkInOutPH,
	"*** fpgen ***:%s:MBK_IN_PH(%s) must be equal to MBK_OUT_PH(%s).\n");
				   
	   addwarng_FirstCall = FALSE;
	}					
	
}


/*  Function  :  'DmlMBK_BusToChain'                              */
/* -------------------------------------------------------------- */
/*      Transform a bus signal name to a chained list of sample
 *  signal names (in the MBK internal format). Then add it in
 *  front of the list "pthead". For check purpose it gives the
 *  bus wide in the long integer pointed by "pcount".
 */

static chain_list *DmlMBK_BusToChain(pthead,busname,pcount)
	chain_list *pthead;
		  char *busname;
		  long *pcount;
{
	chain_list *BusChainName;
	chain_list *TmpChain;

		  char  StringBuffer[C_SUPP_MBKSZNAME];
		  char  PinName[     C_SUPP_MBKSZNAME];
		  long  OrigIndex;
		  long  ExtrIndex;
		  long   TmpIndex;

	BusChainName = (chain_list*)NULL;

	/* Decod bus name. */
	if (!bus_decod(busname                 ,
				   StringBuffer,&OrigIndex ,
								&ExtrIndex ))
		Dut_PrintError( E_FPGEN_ERROR        ,
					    E_FPGEN_COMMONBusName,
					    fpgen_Glob.CurrFunc  ,
					    busname              );

	/* Creation of signal names associated to the bus. */
	if (OrigIndex > ExtrIndex)
	{
		for(TmpIndex = OrigIndex; TmpIndex >= ExtrIndex;
								  TmpIndex--           )
		{
			/* Name of bus pin. */
			(void)sprintf( PinName     ,
						  "%s %ld"     ,
						   StringBuffer,
						   TmpIndex    );

			/* Addition to the pin list. */
			BusChainName = addchain( BusChainName        ,
								(void*)namealloc(PinName));
		}
		/* Signal count. */
		*pcount = OrigIndex - ExtrIndex +1;
	}
	else
	{
		for(TmpIndex = OrigIndex; TmpIndex <= ExtrIndex;
								  TmpIndex++           )
		{
			/* Name of bus pin. */
			(void)sprintf( PinName     ,
						  "%s %ld"     ,
						   StringBuffer,
						   TmpIndex    );

			/* Addition a la liste des pattes. */
			BusChainName = addchain( BusChainName       ,
								(void*)namealloc(PinName));
		}
		/* Signal count. */
		*pcount = ExtrIndex - OrigIndex +1;
	}
	
	/* Add the list of pin bus to the front of the list. */
	for( TmpChain        = BusChainName     ;
		 TmpChain->NEXT != (chain_list*)NULL; 
		 TmpChain        = TmpChain->NEXT   );

	TmpChain->NEXT  = pthead;
	pthead = BusChainName;

	return( BusChainName);
}


/*  Function  :  'DmlMBK_ChainToSig'                              */
/* -------------------------------------------------------------- */
/*      Convert a 'chain_list' of signal names in a 'chain_list'
 *  of MBK signal objects. If the MBK signal is not already 
 *  existing in the netlist, it is created.
 */

static chain_list *DmlMBK_ChainToSig(ptchain)
	chain_list *ptchain;
{
	chain_list *TmpChain;
	chain_list *TmpChainName;
	losig_list *TmpSig;
	chain_list *ChainSig;
		  char *TmpName;

	/* Reset the front of the list. */
	ChainSig = (chain_list*)NULL;

	/*     Recover the MBK signals associated to signal */
	/* name. Create it if necessary.                    */
	for( TmpChain  = ptchain          ;
		 TmpChain != (chain_list*)NULL; 
		 TmpChain  = TmpChain->NEXT   )
	{
		TmpName = namealloc( (char*)(TmpChain->DATA));
		
		/* Go through the list of existing signals. */
		for( TmpSig  = WORK_LOFIG->LOSIG;
			 TmpSig != (losig_list*)NULL;
			 TmpSig  = TmpSig->NEXT     )
		{
			/* Go through the list of signal names. */
			for( TmpChainName  = TmpSig->NAMECHAIN ;
				 TmpChainName != (chain_list*)NULL ;
				 TmpChainName  = TmpChainName->NEXT)
				if ((char*)(TmpChainName->DATA) == TmpName)
					break;
			
			/* The name of the signal has been found. */
			if (TmpChainName != (chain_list*)NULL) break;
		}

		/* If not found : create it. */
		if (TmpSig == (losig_list*)NULL)
		{
			num_index += 1;
			TmpSig = addlosig( WORK_LOFIG                  ,
							   num_index                   ,
							   addchain( (chain_list*)NULL,
										 (void*)TmpName   ),
							   INTERNAL                    ,
							   0                           ,
							   0                           );
		}

		/* Addition of signal to the list. */
		ChainSig = addchain( ChainSig, (void*)TmpSig );
	}

	return( ChainSig);
}




/*  Function  :  'DmlMBK_NameToSig'                               */
/* -------------------------------------------------------------- */
/*  Add to the front of the MBK signal list pointed by "aPtChain"
 *  a new signal named "aSigName". A pointer to the new
 *  'chain_list' is returned.
 *    First the function search though the list of signals to
 *  find if it have been already created. If not found the
 *  function add a new signal.
 */

static chain_list *DmlMBK_NameToSig(aPtChain,
									aNameSig,
									aTypeSig)
	chain_list *aPtChain;
	      char *aNameSig;
	      long  aTypeSig;
{
	chain_list *TmpChainName;
	chain_list  *PtChainNew;
	losig_list *TmpSig;
	ptype_list *PtPtype;
		  char *TmpName;


	TmpName = namealloc((char*)(aNameSig));
		
	/* Go through the list of existing signals. */
	for(TmpSig  = WORK_LOFIG->LOSIG;
		TmpSig != (losig_list*)NULL;
		TmpSig  = TmpSig->NEXT     )
	{
	    /* Go through the list of signal names. */
	    for(TmpChainName  = TmpSig->NAMECHAIN ;
			TmpChainName != (chain_list*)NULL ;
			TmpChainName  = TmpChainName->NEXT)
			if ((char*)(TmpChainName->DATA) == TmpName)
				break;
			
		/* The name of the signal has been found. */
		if (TmpChainName != (chain_list*)NULL) break;
	}

	/* If not found : create it. */
	if (TmpSig == (losig_list*)NULL)
	{
	    num_index += 1;
		TmpSig = addlosig(WORK_LOFIG                 ,
						   num_index                 ,
						  addchain((chain_list*)NULL,
								   (void*)TmpName   ),
						  INTERNAL                   ,
						  0                          ,
						  0                          );
	}

	/* Addition of signal to the list. */
	PtChainNew = addchain(aPtChain, (void*)TmpSig);
	PtPtype    = getptype(TmpSig->USER, C_SUPP_UserTypeSig);
	    
	/* Check if the signal is typed. */
	if (PtPtype == (ptype_list*)NULL)
		TmpSig->USER = addptype(TmpSig->USER      ,
								C_SUPP_UserTypeSig,
								   (void*)aTypeSig);
	else
	{

	    /* Check for invalid connexions CTRL-DATA. */
	    if (PtPtype->DATA != (void*)aTypeSig)
			Dut_PrintError(E_FPGEN_ERROR            ,
						   E_FPGEN_NAMETOSIGCtrlData,
						     fpgen_Glob.CurrFunc    ,
						                 TmpName    );

		/* Check for invalid connexions CTRL-CTRL. */
	    if (   (PtPtype->DATA == (void*)C_FPGEN_TypeSigCTRL)
			&& (  aTypeSig    ==        C_FPGEN_TypeSigCTRL))
			Dut_PrintError(E_FPGEN_ERROR            ,
						   E_FPGEN_NAMETOSIGCtrlCtrl,
						     fpgen_Glob.CurrFunc    ,
						                 TmpName    );
	}

	return( PtChainNew);
}


/*  Function  :  'DmlMBK_MatchImplicitConn'                       */
/* -------------------------------------------------------------- */
/*  Read the locon list 'ptcon' and look for supplies connectors
 *  or implicit connectors. If one of those connectors is found
 *  a corresponding signal name is inserted at the right place in
 *  the signal name list 'ptchain'. 
 *    In the case of an implicit connector (i.e. a hidden control
 *  connector) it is added to the interface of the current logi-
 *  cal figure with a new signal.
 */

static chain_list *DmlMBK_MatchImplicitConn(aInstcName   ,
											aChainConName,
											aChainSigName,
											aPtLoFig     ,
											aPtSigCount  )
	      char *aInstcName;
	chain_list *aChainConName;
	chain_list *aChainSigName;
	lofig_list *aPtLoFig;
	      long *aPtSigCount;
{
	      char  *TmpName;
		  char  *SigName;
		  long   SigNameIndex;
		  long   SigType;
	locon_list  *PtCon;
	chain_list  *PtChainSigName;
	chain_list  *PtChainCon;
	chain_list  *PtChainSig = (chain_list*)NULL;

	
	PtChainSigName = aChainSigName;
	/* Initialize the number of added signals. */
	*aPtSigCount = 0;

	for(PtCon  = aPtLoFig->LOCON  ;
		PtCon != (locon_list*)NULL;
		PtCon  =  PtCon->NEXT     )
	{
	    switch( Dut_TypeConName(PtCon->NAME) )
		{
		    case C_SUPP_TypeConVdd:
		        /* Add a signal named "vdd" to the signal list. */
		          PtChainSig  = addchain(PtChainSig, (void*)fpgen_Glob.SigVdd);
				*aPtSigCount += 1;
				break;
		    case C_SUPP_TypeConVss:
		        /* Add a signal named "vss" to the signal list. */
		          PtChainSig  = addchain(PtChainSig, (void*)fpgen_Glob.SigVss);
				*aPtSigCount += 1;
				break;
		    case C_SUPP_TypeConImplicit:
				/* Name of the implicit signal and connector. */
				TmpName = concatname(aInstcName,PtCon->NAME);

				/* Creation of SIGNAL "TmpName". */
				PtChainSig = DmlMBK_NameToSig(PtChainSig,
											     TmpName,
									 C_FPGEN_TypeSigCTRL);
				*aPtSigCount += 1;

				/* Creation of CONNECTOR "TmpName". */
				(void)addlocon(WORK_LOFIG                     ,
							   TmpName                        ,
							   (losig_list*)(PtChainSig->DATA),
							   PtCon->DIRECTION               );
				

				break;
			case C_SUPP_TypeConNormal:
			default :
				SigType = C_FPGEN_TypeSigDATA;

				for(PtChainCon  =  aChainConName    ;
					PtChainCon !=  (chain_list*)NULL;
					PtChainCon  = PtChainCon->NEXT)
				{
					TmpName = (char*)PtChainCon->DATA;

					if (TmpName == PtCon->NAME)
					{
					    SigType = C_FPGEN_TypeSigCTRL;

						if (fpgen_Glob.ConMode == C_FPGEN_ConModeIMPLICIT)
						{
					        SigName = Dut_DecodMBKSigName(TmpName     ,
														 &SigNameIndex);
							TmpName = Dut_MakeImplicitConName(aInstcName     ,
															     SigName     ,
															     SigNameIndex);
						}
						break;
					}
				}

				/* Get the name of the signal :            */
				/* - DATA connector.                       */
				/* - CTRL connector when in EXPLICIT mode. */
				if (   (           SigType != C_FPGEN_TypeSigCTRL    )
					|| (fpgen_Glob.ConMode != C_FPGEN_ConModeIMPLICIT))
				{
				    /* Check the current signal. */
					if (PtChainSigName == (chain_list*)NULL)
						Dut_PrintError(E_FPGEN_ERROR               ,
									   E_FPGEN_MATCHINTERFNoMoreSig,
									     fpgen_Glob.CurrFunc       );

				           TmpName = (char*)(PtChainSigName->DATA);
					PtChainSigName = PtChainSigName->NEXT;

				    *aPtSigCount  += 1;
				}

				/* Creation of SIGNAL "TmpName". */
				PtChainSig = DmlMBK_NameToSig(PtChainSig,
											     TmpName,
											     SigType);

				if (   (           SigType == C_FPGEN_TypeSigCTRL    )
					&& (fpgen_Glob.ConMode == C_FPGEN_ConModeIMPLICIT))
					/* Creation of CONNECTOR "TmpName". */
					(void)addlocon(WORK_LOFIG                     ,
								   TmpName                        ,
								   (losig_list*)(PtChainSig->DATA),
								   PtCon->DIRECTION               );
	
				break;
		}

	}

	/* Check if all the signal have been matched with the conns. */
	if (PtChainSigName != (chain_list*)NULL)
		Dut_PrintError( E_FPGEN_ERROR               ,
					    E_FPGEN_MATCHINTERFNoMoreCon,
					    fpgen_Glob.CurrFunc         );

	/* Return the new head of signal chain list. */
	return(PtChainSig);
}


/*  Fonction  :  'DmlMBK_xvLoIns'.                                */
/* -------------------------------------------------------------- */
/*  This function is derived from the genlib LOINS.               */

static void  DmlMBK_xvLoIns(aModelName    ,
							aInstcName    ,
							aChainImplConn,
							aStdArgs      )
	      char *aModelName;     /* Name of the model to be instanciate.   */
	      char *aInstcName;     /* Name of the new instance.              */
	chain_list *aChainImplConn; /* List of the implicit connectors names. */
	   va_list  aStdArgs;       /* List of the explicit signal names.     */
{
	       lofig_list *PtLoFig;
		   chain_list *ChainConName = (chain_list*)NULL;
		   chain_list *ChainSigName = (chain_list*)NULL;
		   chain_list *ChainSig     = (chain_list*)NULL;

		   chain_list *PtChain;
	             char *TmpName;
	             long  TmpCount;


	/* Load the logical model. */
	PtLoFig = getlofig( aModelName, 'P');


	/* Build list of model unvectorized, implicit connectors names. */
	for(PtChain  =  aChainImplConn   ;
		PtChain !=  (chain_list*)NULL;
		PtChain  = PtChain->NEXT     )
	{
	    TmpName=(char*)(PtChain->DATA);

		if (!is_bus(TmpName))
		{
			/* Case of sample signals. */
			/* Check name consistancy. */
			TmpName = Dut_CheckName( TmpName);

			/* Add signal name in front of the list. */
			ChainConName =
				addchain(            ChainConName ,
						 (void*)namealloc(TmpName));
		}
		else

			/* Bus case. */
			ChainConName = DmlMBK_BusToChain(ChainConName ,
											      TmpName ,
											     &TmpCount);
	}

	/* Build list of unvectorized signal names.      */
	/* (check for name syntax and unvectorize buses) */
	while((TmpName=va_arg(aStdArgs,char*)) != (char*)NULL)
		if (!is_bus(TmpName))
		{
			/* Case of sample signals. */
			/* Check name consistancy. */
			TmpName = Dut_CheckName( TmpName);

			/* Add signal name in front of the list. */
			ChainSigName =
				addchain(            ChainSigName ,
						 (void*)namealloc(TmpName));
		}
		else
			/* Bus case. */
			ChainSigName = DmlMBK_BusToChain(ChainSigName ,
											      TmpName ,
											     &TmpCount);

	/* Add implicit signals and connectors and convert the list of */
	/* name in a list of MBK signal objects.                       */
	ChainSig = DmlMBK_MatchImplicitConn(  aInstcName,
										ChainConName,
										ChainSigName,
										PtLoFig     ,
									   &TmpCount    );

	/* Free two "chain_list" of name (implicit connectors and signals). */
	freechain( ChainSigName);
	freechain( ChainConName);

	/* Reverse order of MBK signals list. */
	ChainSig = reverse( ChainSig);

	/* Instanciation of the model. */
	(void)addloins( WORK_LOFIG, aInstcName, PtLoFig, ChainSig);
	/* Free the MBK signals list. */
	freechain( ChainSig);
}


/*  Fonction  :  'DmlMBK_SwapWorkLofig'                           */
/* -------------------------------------------------------------- */
/*      Swap the values of variables "WORK_LOFIG" (current 
	logical figure in GENLIB) with "SWAP_LOFIG", a temporary
	backup variable intern to 'fpgen'. This operation is needed
	for using genlib in the operator generators.
	*/

static void  DmlMBK_SwapWorkLofig()
{
	static lofig_list *SWAP_LOFIG = (lofig_list*)NULL;
	       lofig_list *TEMP_LOFIG;

	/* Swap logical figures 'SWAP' et 'WORK'. */
	TEMP_LOFIG = WORK_LOFIG;
	WORK_LOFIG = SWAP_LOFIG;
	SWAP_LOFIG = TEMP_LOFIG;
}


/*  Function  :  'DmlMBK_UdpCon'                                  */
/* -------------------------------------------------------------- */

static void  DmlMBK_UdpCon(aBusName,aBusSide)
	char *aBusName;
	char  aBusSide;
{
		  char  StringBuffer[C_SUPP_MBKSZNAME];
		  char  PinName[     C_SUPP_MBKSZNAME];
		  long  OrigIndex;
		  long  ExtrIndex;
		  long   TmpIndex;

	/* Decod bus name. */
	if (!bus_decod(aBusName                ,
				   StringBuffer,&OrigIndex ,
								&ExtrIndex ))
		Dut_PrintError( E_FPGEN_ERROR        ,
					    E_FPGEN_COMMONBusName,
					    fpgen_Glob.CurrFunc  ,
					    aBusName             );

	/* Creation of signal names associated to the bus. */
	if (OrigIndex > ExtrIndex)
		for(TmpIndex = OrigIndex; TmpIndex >= ExtrIndex;
								  TmpIndex--           )
		{
			/* Name of bus pin. */
			(void)sprintf( PinName     ,
						  "%s %ld"     ,
						   StringBuffer,
						   TmpIndex    );

			/* Addition to the pin user datas. */
			Dut_AddUdpCon( WORK_LOFIG, PinName, aBusSide);
		}
	else
		for(TmpIndex = OrigIndex; TmpIndex <= ExtrIndex;
								  TmpIndex++           )
		{
			/* Name of bus pin. */
			(void)sprintf( PinName     ,
						  "%s %ld"     ,
						   StringBuffer,
						   TmpIndex    );

			/* Addition to the pin user datas. */
			Dut_AddUdpCon( WORK_LOFIG, PinName, aBusSide);
		}	
}
