/*
 * Electric(tm) VLSI Design System
 *
 * File: pla.c
 * Programmable Logic Array Generator
 * Written by: Sundaravarathan R. Iyengar, Schlumberger Palo Alto Research
 * Last modified by: Steven M. Rubin, Static Free Software
 *
 * Copyright (c) 2000 Static Free Software.
 *
 * Electric(tm) is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 *
 * Static Free Software
 * 4119 Alpine Road
 * Portola Valley, California 94028
 * info@staticfreesoft.com
 */

#include "config.h"
#if PLAAID

#include "global.h"
#include "pla.h"
#include "planmos.h"

/* the PLA aid table */
static KEYWORD planmosonoffopt[] =
{
	{"on",          0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"off",         0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
static COMCOMP planmosonoffp = {planmosonoffopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("State of this switch"), 0};
static COMCOMP planmosoptip = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Number of inputs to nMOS PLA"), 0};
static COMCOMP planmosoptop = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Number of outputs to nMOS PLA"), 0};
static COMCOMP planmosoptpp = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Number of p-terms to nMOS PLA"), 0};
static COMCOMP planmosoptvp = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Width of VDD wires in nMOS PLA"), 0};
static COMCOMP planmosoptgp = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Width of Ground wires in nMOS PLA"), 0};
static COMCOMP planmosoptfp = {NOKEYWORD,topoffile,nextfile,NOPARAMS,NOBACKUP,
	INPUTOPT, " \t", M_("File name with nMOS PLA personality table"), 0};
static COMCOMP planmosoptbp = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("Name given to nMOS PLA"), 0};
static KEYWORD planmosoopt[] =
{
	{"file",             1,{&planmosoptfp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"inputs",           1,{&planmosoptip,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"outputs",          1,{&planmosoptop,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"pterms",           1,{&planmosoptpp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"verbose",          1,{&planmosonoffp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"flexible",         1,{&planmosonoffp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"fixedangle",       1,{&planmosonoffp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"buttingcontact",   1,{&planmosonoffp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"samesideoutput",   1,{&planmosonoffp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"vddwidth",         1,{&planmosoptvp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"groundwidth",      1,{&planmosoptgp,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"name",             1,{&planmosoptbp,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
static COMCOMP planmosop = {planmosoopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, INPUTOPT, " \t", M_("nMOS PLA switch setting option"), 0};
static KEYWORD placmosopt[] =
{
	{"n-plane",        0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"p-plane",        0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"decoder",        0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"generate-pla",   0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
static COMCOMP placmosp = {placmosopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
	INPUTOPT, " \t", M_("CMOS PLA action"), 0};
static KEYWORD plaopt[] =
{
	{"nmos",    1,{&planmosop,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"cmos",    1,{&placmosp,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
COMCOMP pla_plap = {plaopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
	0, " \t", M_("Select a PLA generator to use"), 0};

AIDENTRY *pla_aid;				/* the PLA aid object */
INTBIG    pla_lam;				/* Feature size in internal units */
INTBIG    pla_filetypeplatab;	/* PLA table disk file descriptor */

/* PLA access routine called from electric user interface */
void pla_init(INTBIG *argc, char *argv[], AIDENTRY *thisaid)
{
	/* only initialize during pass 1 */
	if (thisaid == NOAID || thisaid == 0) return;
	pla_aid = thisaid;

	/* initialize the nMOS PLA generator */
	pla_fin = NULL;
	pla_verbose = OFF;
	pla_userbits = FIXANG;
	pla_buttingcontact = ON;
	pla_samesideoutput = OFF;
	pla_VddWidth = 0;
	pla_GndWidth = 0;
	(void)strcpy(pla_infile, INFILE);
	(void)strcpy(pla_name, DEFNAME);
	pla_alv = pla_atg = pla_arg = pla_otv = NOVDDGND;
	pla_org = pla_icg = pla_icv = pla_ocg = pla_ocv = NOVDDGND;

	/* setup file descriptor */
	pla_filetypeplatab = setupfiletype("", "*.*", MACFSTAG('TEXT'), 0, "platab", _("PLA table"));
}

/*
 * This routine is called each time the user issues the command,
 */
INTSML pla_set(INTSML count, char *par[])
{
	REGISTER INTSML len;
	REGISTER char *pp;

	if (count == 0)
	{
		count = ttygetparam(_("PLA option:"), &pla_plap, MAXPARS, par);
		if (count == 0)
		{
			ttyputerr(_("Aborted"));
			return(1);
		}
	}
	len = strlen(pp = par[0]);

	if (namesamen(pp, "nmos", len) == 0)
	{
		if (count < 3)
		{
			pla_displayoptions();
			return(0);
		}
		pla_setoption(par[1], par[2]);
		return(0);
	}

	if (namesamen(pp, "cmos", len) == 0)
	{
		if (count == 1)
		{
			count = ttygetparam(_("CMOS PLA option:"), &placmosp, MAXPARS-1, &par[1]) + 1;
			if (count == 1)
			{
				ttyputerr(_("Aborted"));
				return(1);
			}
		}

		len = strlen(pp = par[1]);
		if (namesamen(pp, "generate-pla", len) == 0)
		{
			plac_generate();
			return(0);
		}
		if (namesamen(pp, "decoder", len) == 0)
		{
			plac_dec();
			return(0);
		}
		if (namesamen(pp, "n-plane", len) == 0)
		{
			plac_n_generate();
			return(0);
		}
		if (namesamen(pp, "p-plane", len) == 0)
		{
			plac_p_generate();
			return(0);
		}
		ttyputbadusage("tellaid pla cmos");
		return(1);
	}

	/* Invalid control to the PLA generator.  Print a small summary */
	ttyputbadusage("tellaid pla");
	return(1);
}

void pla_slice(void)
{
	if (pla_Make() == ERRORRET)
	{
		ttyputerr(_("nMOS PLA '%s' is incompletely defined"), pla_name);
		if (pla_fin != NULL) xclose(pla_fin);
		aidturnoff(pla_aid, 0);
		setactivity(_("Incomplete nMOS PLA generated"));
		return;
	}
	xclose(pla_fin);
	aidturnoff(pla_aid, 0);
	setactivity(_("nMOS PLA generated"));
}

void pla_done(void) {}

#endif  /* PLCAID - at stop */
