/*******************************************************************************
* Grog : generic rom generator                                                 *
*                                                                              *
* Architecture and leaf cells defined at Bull's research center at les Clayes  *
*                                                                              *
* Leaf cells modifications to meet idps design rules                           *
* version 0.0 on April/June 1992, Frederic Petrot                              *
*                                                                              *
* All programming in Genlib                                                    *
* version 0.0 on April/June 1992, Frederic Petrot                              *
*                                                                              *
* version 0.1, by Frederic Petrot                                              *
* version 1.0, by Frederic Petrot                                              *
* version 1.1, by Frederic Petrot                                              *
* version 1.2, by Frederic Petrot                                              *
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include MUT_H
#include "grog.h"

static void usage();
static int legal(); 

/*
* main routine
*/
int main(argc, argv)
int argc;
char **argv;
{
/* parameters */
long nw = 0; /* word number */
long nb = 0; /* bits number */
long tr = 0; /* through routes */
long hz = 0; /* tri-state output */
long r = 0;  /* output bit order */
long msb = 0; /* most significant bit is called 2^(nbits - 1) by default */
char *codefile = NULL; /* coding input file name */
char blockname[32]; /* block name */
long layout = 0;
long netlist = 0;
long vhdl = 0;
long pat = 0;
long icon = 0;
long outline = 0;
long datasheet = 0;
long silent = 0;
long i;

   if (argc < 4)
      usage(argv[0]);

   nb = atoi(argv[1]);
   nw = atoi(argv[2]);
   codefile = argv[3];
	*blockname = '\0';

   for (i = 4; i < argc; i++) {
      if (!strcmp(argv[i], "-o")) {
			if (++i < argc)
         	sprintf(blockname, "%s", argv[i]);
			else
				usage(argv[0]);
      } else if (!strcmp(argv[i], "-layout"))
         layout = 1;
      else if (!strcmp(argv[i], "-physicalbox"))
         outline = 1;
      else if (!strcmp(argv[i], "-logicalbox"))
         netlist = 1;
      else if (!strcmp(argv[i], "-vhdl"))
         vhdl = 1;
      else if (!strcmp(argv[i], "-pattern"))
         pat = 1;
      else if (!strcmp(argv[i], "-icon"))
         icon = 1;
      else if (!strcmp(argv[i], "-datasheet"))
         datasheet = 1;
      else if (!strcmp(argv[i], "-tr"))
         tr = 1;
      else if (!strcmp(argv[i], "-hz"))
         hz = 1;
      else if (!strcmp(argv[i], "-r"))
         r = 1;
      else if (!strcmp(argv[i], "-msb0"))
         msb = 1;
      else if (!strcmp(argv[i], "-silent"))
         silent = 1;
      else
         usage(argv[0]);
   }

   if (!silent)
		alliancebanner("GRoG", GROG, "Generic ROm Generator", "92,93", ALC);

   if (!(layout | netlist | vhdl | outline | datasheet | icon | pat)) {
      fprintf(stderr, "At least one view is to be generated by %s\n", argv[0]);
      usage(argv[0]);
   }
   if (!nb || nb < 1 || nb > 64) {
      fprintf(stderr, "The bits argument must be in the allowed range, 1 to 64\n");
      usage(argv[0]);
   }
   if (!nw) {
      fprintf(stderr, "The words argument must be a legal number, 64 to 4096\n");
      usage(argv[0]);
   }
   if (isdigit(*codefile) && layout)
      fprintf(stderr, "Warning : the rom code is going to be random!\n");
   i = legal(&nw);
   if (!i)
      fprintf(stderr, "Warning : words number rounded up to legal value %d\n",
               nw);
   if (i == 2) {
      fprintf(stderr, "The words argument must be in the allowed range\n");
      usage(argv[0]);
   }
   if (*blockname == '\0') {
      sprintf(blockname, "r%dx%d_", nw, nb);
      if (tr)
         strcat(blockname, "t");
      if (hz)
         strcat(blockname, "z");
      if (r)
         strcat(blockname, "r");
      strcat(blockname, codefile);
   }

   grog(blockname, nb, nw, codefile, tr, hz, r, msb,
         layout, netlist, vhdl, pat, icon, outline, datasheet);
   if (silent)
      fputs(blockname, stdout);
   return 0;
}

/*
* word number adjustment for proper generator call
*/
static int legal(nw)
int *nw;
{
int i;

   for (i = 5; i < 9; i++) 
      if (*nw > (1 << i) && *nw < (1 << (i + 1))) {
         *nw = (1 << (i + 1));
         return 0;
      } else if (*nw == (1 << (i + 1)))
         return 1;

   for (i = 1; i < 8; i++)
      if (i * 512 < *nw && (i + 1) * 512 > *nw) {
         *nw = (i + 1) * 512;
         return 0;
      } else if (*nw == (i + 1) * 512)
         return 1;
   return 2;
}

/*
* usual unix usage message
*/
static void usage(s)
char *s;
{
int i = 0;

   fprintf(stderr, "Usage : %s bits words codefile ", s);
	fprintf(stderr, "[-hz] [-tr] [-r] [-msb0] [-o blockname]\n");
   do
      fputs(" ", stderr);
   while (i++ < strlen(s) + 8);
   fprintf(stderr, "[-layout] [-vhdl] [-pattern] [-icon] [-datasheet]\n");
   do
      fputs(" ", stderr);
   while (--i > 0);
   fprintf(stderr, "[-pattern] [-logicalbox] [-physicalbox]\n");
   exit(1);
}

