/***************************************************************
**  techno.c               technology parameter module        **
**  950801 TGR 0.1         (from SMM venus.h/motorola.h)      **
***************************************************************/

#define IN_TECHNO
#include <stdio.h>
#include <math.h> 
#include "techno.h"

extern int ld();
static int technology=0;

int cinv, cand, cor, cnand, cnor;
int cxor, cxnor, cmux, cdriv, cff;
int cramcell, delta;
int DRAMfac; 
double romfac; 
int dinv, dand, dor, dnand, dnor;
int dxor, dxnor, dmux, ddriv, dff;

char* name_techno()             /* name of current technology */
{
  switch(technology)
  { case MOTOROLA:
      return (char*)"Motorola";
      break;
    case VENUS:
      return (char*)"Venus";
      break;
    default:
      return (char*)"unknown";
      break;
  }
}

int init_techno(par)    /* initialize cost and delay of basic 
                           components */
int par;
{
  switch(par)
  { case MOTOROLA:
      cinv=1;  cand=2;  cor =2;  cnand=2; cnor=2;
      cxor=4;  cxnor=4; cmux=3;  cdriv=5; cff=8;
      cramcell=2;       romfac=8.0;       delta=1;
      dinv=1;  dand=2;  dor =2;  dnand=1; dnor=1;
      dxor=2;  dxnor=2; dmux=2;  ddriv=2; dff=4;
      break;
    case VENUS:
      cinv=1;  cand=2;  cor =2;  cnand=2; cnor=2;
      cxor=6;  cxnor=6; cmux=3;  cdriv=6; cff=12;
      cramcell=12;      romfac=6.0;       delta=1;
      dinv=1;  dand=1;  dor =1;  dnand=1; dnor=1;
      dxor=2;  dxnor=2; dmux=2;  ddriv=1; dff=4;
      break;
    default:
      fprintf(stderr,
              "techno.c: init_techno() unknown parameter\n");
      exit(1);
  }
  technology=par;
  return 0;
}

/* -----------------------------------------------------------*/
/*     ROM and RAM units (A x n)                              */
/* -----------------------------------------------------------*/

int cram(A,n)           /* on chip static RAM */
int A,n;
{ switch(technology)
  { case MOTOROLA:
      if (n>1)
        return (A+3)*(ld(ld(n))+n)*cramcell ;
      else
        return (A+3)*n*cramcell ;
      break;
    case VENUS:
      return A*n*cramcell ;
      break;
    default:
      fprintf(stderr,"techno.c: cram() unkown technology\n");
      exit(1);
  }
}
 
int dram(A,n) int A,n;
{ switch(technology)
  { case MOTOROLA:
      if (A >= 128)
        return 10 + 3*ld(A);
      else
        return ld(n) + A/4;
      break;
    case VENUS:
      return ceil(1.5*ld(A)); 
      break;
    default:
      fprintf(stderr,"techno.c: dram() unkown technology\n");
      exit(1);
  }
}
 

int cram2(A,n)                  /* Dualport RAM;  A < 128 */
int A,n;
{ switch(technology)
  { case MOTOROLA:
    case VENUS:
      return ceil(cram(A,n)*1.6);
      break;
    default:
      fprintf(stderr,"techno.c: cram2() unkown technology\n");
      exit(1);
  }
}
 
int dram2(A,n) int A,n;
{ switch(technology)
  { case MOTOROLA:
    case VENUS:
      return ceil(dram(A,n)*1.5);
      break;
    default:
      fprintf(stderr,"techno.c: dram2() unknown technology\n");
      exit(1);
  }
}

int cram3(A,n)                  /* Dualport RAM;  A < 128 */
int A,n;
{ switch(technology)
  { case MOTOROLA:
    case VENUS:
      return ceil(cram(A,n)*2.2);
      break;
    default:
      fprintf(stderr,"techno.c: cram2() unkown technology\n");
      exit(1);
  }
}
 
int dram3(A,n) int A,n;
{ switch(technology)
  { case MOTOROLA:
    case VENUS:
      return ceil(dram(A,n)*2.0);
      break;
    default:
      fprintf(stderr,"techno.c: dram2() unknown technology\n");
      exit(1);
  }
}

int crom(A,n)                   /* on chip ROM */
int A,n;
{return (int)(cram(A,n)/romfac);
}
 
int drom(A,n) 
int A,n;
{return dram(A,n) ;
}
 

int cDRAM(A,n)                   /* off-chip DRAM */
int A,n;
{return (int)(cram(A,n)/DRAMfac);
}
 
int dDRAM(A,n) 
int A,n;
{return dram(A,n)*DRAMfac ;
}
 
