/*******************************************************************/
/*******************************************************************/
/**                                                               **/
/**  RFG_MAIN                                                     **/
/**                                                               **/
/**  Version 6.03                                                 **/
/**                                                               **/
/*******************************************************************/
/*******************************************************************/

static char *ident_main="@(#)(RFG) main, version 6.03 (03/12/1993)";

/*******************************************************************/

#include "rfg_head.h"
#include "grf603.h"

#include MUT_H

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

/*******************************************************************/

/*
#include "rfg_disp.c"
*/

/*******************************************************************/

long convert(t)
  char t;
 
{
long i;
if( ((t>='0')&&(t<='9')) || ((t>='a')&&(t<='v')) )
  {
  i=t-'0';
  if(i>9)
    i-=('a'-'9')-1;
  return(i);
  }
else
  {
  (void) fprintf(stderr, "Error : illegal character \"%c\" in crunch name !!!\n", t);
  exit(1);
  }
return(-1);
}
 
/*******************************************************************/
/*******************************************************************/
/**                                                               **/
/**  MAIN ( argc, argv )                                          **/
/**                                                               **/
/*******************************************************************/
/*******************************************************************/

int main(argc, argv)
  long argc;
  char *argv[];

{
long width, high, n_bus;
long flip_flop=0L;
long inverse_data=0L, low_power=0L;
long write_enable=0L, inverse_we=0L;
long stuck=0L;
long hard_connectors=1L;
long msb=0L;
long block_type= -1L;
char *name_blocks=NULL;
long layout=0L, outline=0L, vhdl=0L, pat=0L, data=0L, netlist=0L, icon=0L;

long i, j;
long help=0L;

#ifdef rfg_crunch_name
long deco=0L;
#endif

char *prog_name, *result; 

#ifdef GENVIEW

width=2L;
high=2L;
n_bus=1L;
flip_flop=0L;
inverse_data=0L;
low_power=0L;
write_enable=0L;
inverse_we=0L;
stuck=0L;
hard_connectors=1L;
msb=0L;

block_type=rfg_bank;

name_blocks="test";

layout=1L;
outline=1L;
vhdl=0L;
pat=0L;
data=0L;
netlist=0l;
icon=0L;

#else

if((prog_name=strrchr(argv[0], '/'))!=NULL)
  prog_name++;
else
  prog_name=argv[0];

if(argc<=1)
  help=1;
else
  {
  if(strcmp(argv[1], "-h")==0)
    help=2L;
  else

#ifdef rfg_crunch_name
    if(strcmp(argv[1], "-deco")==0)
      deco=1L;
    else
#endif

      if(argc<6)
        help=1;
  }

/***************/
/* Print help. */
/***************/

if(help>=1)
  { 
  (void) fprintf(stderr,    "Usage: %s bits words busses ro|rs|ds|ba\n", prog_name);
  (void) fprintf(stderr,    "            [-ff] [-id] [-lp] [-wel|-weh] [-stuck] [-virtual] [-msb0]\n");
  (void) fprintf(stderr,    "            [-layout] [-icon] [-vhdl] [-patterns] [-datasheet]\n");
  (void) fprintf(stderr,    "            [-physical_box] [-logical_box]\n");
  (void) fprintf(stderr,    "            [-o name_prefix]\n");
  if(help>1)
    {
    (void) fprintf(stderr,"\n          Generator function.\n");
    (void) fprintf(stderr,  "          -------------------\n\n");
    (void) fprintf(stderr,  "            Description of parameters and options:\n\n");

    (void) fprintf(stderr,  "            bits          : number of bits in a register ( %ld <= bits <= %ld, must be even).\n",
      rfg_HIGH_MIN, rfg_HIGH_MAX);
    (void) fprintf(stderr,  "            words         : number of registers ( %ld <= words <= %ld, must be even).\n",
      rfg_WIDTH_MIN, rfg_WIDTH_MAX);
    (void) fprintf(stderr,  "            busses        : number of read bus ( 1 or 2 ).\n");
    (void) fprintf(stderr,  "            ro            : generate an optimised registers without decoders block,\n");
    (void) fprintf(stderr,  "                            uncompatible with generated decoders blocks.\n");
    (void) fprintf(stderr,  "            rs            : generate registers without decoders block.\n");
    (void) fprintf(stderr,  "            ds            : generate decoders block.\n");
    (void) fprintf(stderr,  "            ba            : generate complete registers bank block.\n\n");
  
    (void) fprintf(stderr,  "           -ff            : edge-triggered flip-flop.\n");
    (void) fprintf(stderr,  "           -id            : inverse data.\n");
    (void) fprintf(stderr,  "           -lp            : low power (use only if words > 16).\n");
    (void) fprintf(stderr,  "           -weh           : write enable input active on high level.\n");
    (void) fprintf(stderr,  "           -wel           : write enable input active on low level.\n");
    (void) fprintf(stderr,  "           -stuck         : register at address 0 is stuck to a null value.\n");
    (void) fprintf(stderr,  "           -virtual       : multi-access connectors.\n");
    (void) fprintf(stderr,  "           -msb0          : index 0 is gived to the most significant bit of each bus.\n\n");
  
    (void) fprintf(stderr,  "           -layout        : generate layout view.\n");
    (void) fprintf(stderr,  "           -icon          : generate icon view.\n");
    (void) fprintf(stderr,  "           -vhdl          : generate vhdl view.\n");
    (void) fprintf(stderr,  "           -patterns      : generate patterns view.\n");
    (void) fprintf(stderr,  "           -datasheet     : display data sheet.\n");
    (void) fprintf(stderr,  "           -physical_box  : generate physical outline view.\n");
    (void) fprintf(stderr,  "           -logical_box   : generate logical connectors view.\n\n");

#ifdef rfg_crunch_name
    (void) fprintf(stderr,  "           -o name_prefix : prefix for all generated files (%ld characters max).\n\n",
    rfg_pref_length);
#else
    (void) fprintf(stderr,  "           -o name_prefix : prefix for all generated files.\n\n");
#endif

    }

#ifdef rfg_crunch_name
  (void) fprintf(stderr,    "       %s -deco crunch_name\n", prog_name);
  if(help>1)
    {
    (void) fprintf(stderr,"\n          Name decrunch function.\n");
    (void) fprintf(stderr,  "          -----------------------\n\n");
    (void) fprintf(stderr,  "            -deco crunch_name : crunch_name form is \"XXYYYYY\", where\n");
    (void) fprintf(stderr,  "                                \"XX\" is the prefix of bank generator blocks name and\n");
    (void) fprintf(stderr,  "                                \"YYYYY\" are 5 charaters for parameters incoding.\n\n");
    }
#endif

  (void) fprintf(stderr,    "       %s -h\n", prog_name);
  if(help>1)
    {
    (void) fprintf(stderr,"\n          Help (long form).\n");
    (void) fprintf(stderr,  "          -----------------\n\n");
    }
  exit(1);
  }

/*
(void) fputs("\n", stdout);
(void) fprintf(stdout, "                 @@@@@@   @@@@@@@  @@@@@ \n");
(void) fprintf(stdout, "                 @     @  @       @     @\n");
(void) fprintf(stdout, "                 @     @  @       @      \n");
(void) fprintf(stdout, "                 @@@@@@   @@@@    @  @@@@\n");
(void) fprintf(stdout, "                 @   @    @       @ @   @\n");
(void) fprintf(stdout, "                 @    @   @       @     @\n");
(void) fprintf(stdout, "                 @     @  @        @@@@@ \n");
(void) fputs("\n", stdout);
(void) fprintf(stdout, "          Alliance CAD system,          RFG 6.03\n");
(void) fprintf(stdout, "          Tool: RFG,     Register File Generator\n");
(void) fprintf(stdout, "          (c) copyright 1993 MASI, CAO-VLSI team\n");
(void) fprintf(stdout, "          E-mail support:   cao-vlsi@masi.ibp.fr\n");
(void) fputs("\n", stdout);
(void) fflush(stdout);
*/

alliancebanner("RFG", "6.03", "Register File Generator", "1993", ALC_VER);

#ifdef rfg_crunch_name
/******************/
/* Decrunch name. */
/******************/

if(deco)
  {
  long k;
  char type[3];

  if(2>=argc)
    {
    (void) fprintf(stderr, "Error : missing <crunch_name> !!!\n");
    exit(1);
    }
  j=strlen(argv[2]);
  if(j!=7)
    {
    (void) fprintf(stderr, "Error : illegal length of crunch name (must by 7) !!!\n");
    exit(1);
    }
  
  /************************/
  /* decrunch parameters. */
  /************************/
  
  for(j=2, k=0; j<7; j++)
    {
    k<<=5;
    k+=convert(argv[2][j]);
    }
  
  width          =((k>>rfg_deca_width)&rfg_mask_width)+2;
  high           =((k>>rfg_deca_high)&rfg_mask_high)+2;
  n_bus          =(k>>rfg_deca_bus)&rfg_mask_bus;
  flip_flop      =(k>>rfg_deca_ff)&rfg_mask_ff;
  inverse_data   =(k>>rfg_deca_id)&rfg_mask_id;
  low_power      =(k>>rfg_deca_lp)&rfg_mask_lp;
  write_enable   =(k>>rfg_deca_we)&rfg_mask_we;
  inverse_we     =(k>>rfg_deca_iwe)&rfg_mask_iwe;
  stuck          =(k>>rfg_deca_st)&rfg_mask_st;
  hard_connectors=(k>>rfg_deca_hc)&rfg_mask_hc;
  msb            =(k>>rfg_deca_msb)&rfg_mask_msb;
  
  if(width<=rfg_wblock)     /* if width <= rfg_wblock : low_power = 0. */
    low_power=0;
  inverse_we&=write_enable; /* if no write_enable : inverse_we = 0. */
  
  type[0]=argv[2][0];
  type[1]=argv[2][1];
  type[2]=0;
   
  if(strcmp(type, "ro")==0)
    block_type=rfg_reg_only;
  else if(strcmp(type, "rs")==0)
    block_type=rfg_reg_sep;
  else if(strcmp(type, "ds")==0)
    block_type=rfg_dec_sep;
  else if(strcmp(type, "ba")==0)
    block_type=rfg_bank;
  else
    { 
    (void) fprintf(stderr, "Error : illegal crunch name prefix \"%s\" !!!\n", type);
    exit(1);
    }

  name_blocks=argv[2];

  /*****************************/
  /* print result of decrunch. */
  /*****************************/
  
  (void) rfg (width, high, n_bus, flip_flop, inverse_data,
    low_power, write_enable, inverse_we, stuck,
    hard_connectors, msb, block_type, name_blocks,
    0L, 0L, 0L, 0L, 1L, 0L,
    0L);
  exit(0);
  }
#endif

/********************/
/* Read parameters. */
/********************/

(void) sscanf(argv[1], "%ld", &high);
if(high<rfg_HIGH_MIN)
  { (void) fprintf(stderr,"Error : number of bits in register must be greater or equal to %ld !!!\n", rfg_HIGH_MIN);
    exit(1); }
if(high>rfg_HIGH_MAX)
  { (void) fprintf(stderr,"Error : number of bits in register must be lower or equal to %ld !!!\n", rfg_HIGH_MIN);
    exit(1); }
if(high&1L)
  { (void) fprintf(stderr,"Error : number of bits in register must be even !!!\n");
    exit(1); }

(void) sscanf(argv[2], "%ld", &width);
if(width<rfg_WIDTH_MIN)
  { (void) fprintf(stderr,"Error : number of registers must be greater or equal yo %ld !!!\n", rfg_WIDTH_MIN);
    exit(1); }
if(width>rfg_WIDTH_MAX)
  { (void) fprintf(stderr,"Error : number of registers must be lower or equal to %ld !!!\n", rfg_WIDTH_MAX);
    exit(1); }
if(width&1L)
  { (void) fprintf(stderr,"Error : number of registers must be even !!!\n");
    exit(1); }

(void) sscanf(argv[3], "%ld", &n_bus);
if((--n_bus|1L)!=1L)
  { (void) fprintf(stderr,"Error : number of read bus must be 1 or 2 !!!\n");
    exit(1); }

if(strcmp(argv[4], "ro")==0)
  block_type=rfg_reg_only;
else if(strcmp(argv[4], "rs")==0)
  block_type=rfg_reg_sep;
else if(strcmp(argv[4], "ds")==0)
  block_type=rfg_dec_sep;
else if(strcmp(argv[4], "ba")==0)
  block_type=rfg_bank;
else
  { (void) fprintf(stderr,"Error : you must specifie one of \"ro\", \"rs\", \"ds\" or \"ba\" !!!\n");
    exit(1); }

for(i=5L;i<argc;i++)
  {
  if(argv[i][0]=='_')
    {
    for(j=1; argv[i][j]=='_'; j++);
    if(argv[i][j]!='\0')
      (void) fprintf(stderr, "Warning : unknow argument \"%s\" it will be ignored !!!\n", argv[i]);
    }
  else
    {
    if(strcmp(argv[i], "-ff")==0)
      flip_flop=1L;
    else if(strcmp(argv[i], "-id")==0)
      inverse_data=1L;
    else if(strcmp(argv[i], "-lp")==0)
      low_power=1L;
    else if(strcmp(argv[i], "-wel")==0)
      {
      write_enable=1L;
      inverse_we=1L;
      }
    else if(strcmp(argv[i], "-weh")==0)
      {
      write_enable=1L;
      inverse_we=0L;
      }
    else if(strcmp(argv[i], "-stuck")==0)
      stuck=1L;
    else if(strcmp(argv[i], "-virtual")==0)
      hard_connectors=0L;
    else if(strcmp(argv[i], "-msb0")==0)
      msb=1L;

    else if(strcmp(argv[i], "-o")==0)
      {
      i++;
      if(i>=argc)
        { (void) fprintf(stderr,"Error : \"name_prefix\" missing after \"-o\" option !!!\n");
          exit(1); }

      name_blocks=argv[i];
      if(strlen(name_blocks)==0)
        name_blocks=NULL;

#ifdef rfg_crunch_name
      if(strlen(name_blocks)>rfg_pref_length)
        { (void) fprintf(stderr,"Error : length of \"name_prefix\" must be lower or equal to %ld !!!\n",
            rfg_pref_length);
          exit(1); }
#endif

      }

    else if(strcmp(argv[i], "-layout")==0)
      layout=1L;
    else if(strcmp(argv[i], "-icon")==0)
      icon=1L;
    else if(strcmp(argv[i], "-vhdl")==0)
      vhdl=1L;
    else if(strcmp(argv[i], "-patterns")==0)
      pat=1L;
    else if(strcmp(argv[i], "-datasheet")==0)
      data=1L;
    else if(strcmp(argv[i], "-physical_box")==0)
      outline=1L;
    else if(strcmp(argv[i], "-logical_box")==0)
      netlist=1L;
    else
      (void) fprintf(stderr, "Warning : unknow argument \"%s\" it will be ignored !!!\n", argv[i]);
    }
  }

#ifndef rfg_floating_con
/* only hard connectors could be used */
if(hard_connectors==0L)
  { (void) fprintf(stderr, "Error : \"-virtual\" could not be used for this reduced version of the generator !!!\n");
    exit(1); }
#endif

if(!layout && !outline && !vhdl && !pat && !data && !netlist && !icon)
  { (void) fprintf(stderr,"Error : you must specifie at less one view !!!\n");
    exit(1); }

if(layout && outline)
  { (void) fprintf(stderr,"Error : you cannot generate a layout and a physical_box view at same time !!!\n");
    exit(1); }

#endif

/***** call the Bank Generator Dispatch function *****/

result=rfg (width, high, n_bus, flip_flop, inverse_data,
  low_power, write_enable, inverse_we, stuck,
  hard_connectors, msb, block_type, name_blocks,
  layout, outline, vhdl, pat, data, netlist,
  icon);

if(!data)
(void) printf("The prefix of all generated files is \"%s\".\n\n", result);

return (0);
}

/*******************************************************************/
