/*******************************************************************/
/*******************************************************************/
/**                                                               **/
/**  RFG_DATA ( width, high, n_bus, flip_flop, inverse_data,      **/
/**             low_power, write_enable, inverse_we, stuck, msb,  **/
/**             block_type )                                      **/
/**                                                               **/
/**  Version 6.03                                                 **/
/**                                                               **/
/*******************************************************************/
/*******************************************************************/

static char *ident_data="@(#)(RFG) data view generation, version 6.03 (05/01/1994)";

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

#define rfg_tech_name   ("PROL10")
#define rfg_tech_micron (0.875)    /* Width of one lambda in microns. */

/* Layers capacitances in pF/Lambda of minimal width segments. */

#if 0
#define rfg_tech_capa_gate (1254*(rfg_tech_micron*rfg_tech_micron*1e-6)*1)
#define rfg_tech_capa_poly (44*(rfg_tech_micron*rfg_tech_micron*1e-6)*1)
#define rfg_tech_capa_alu1 (21*(rfg_tech_micron*rfg_tech_micron*1e-6)*1)
#define rfg_tech_capa_alu2 (10*(rfg_tech_micron*rfg_tech_micron*1e-6)*2) /* 2 lambdas width segments */
#endif

#define rfg_tech_capa_gate (1670e-6)
#define rfg_tech_capa_poly (160e-6)
#define rfg_tech_capa_alu1 (160e-6)
#define rfg_tech_capa_alu2 (160e-6)

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

static void rfg_data (width, high, n_bus, flip_flop, inverse_data, 
               low_power, write_enable, inverse_we, stuck,
               hard_connectors, msb, block_type)

  long width, high, n_bus, flip_flop, inverse_data;
  long low_power, write_enable, inverse_we, stuck;
  long hard_connectors, msb, block_type;

{
long  b_width, b_height, w_alims;
long  nbr_trans_dec, nbr_trans_reg, nbr_trans;

float b_width_m, b_height_m;

FILE *out;

/*
if((out=mbkfopen(rfg_name_pref, "dts", "w"))==NULL)
  {
  (void) fprintf(stderr, "Unable to open output file \"%s.%s\" !!!\n", rfg_name_pref, "dts");
  exit(1);
  }
*/

out=stdout;

/********** Print block name. **********/

(void) fprintf(out, "Name : \"%s\".\n\n", rfg_name_pref);

/********** Print function. **********/

(void) fprintf(out, "Function : ");

if(block_type==rfg_reg_only)
  (void) fprintf(out, "Width optimised register file without decoders of ");
else if(block_type==rfg_reg_sep)
  (void) fprintf(out, "Register file without decoders of ");
else if(block_type==rfg_dec_sep)
  (void) fprintf(out, "Register file decoders for ");
else if(block_type==rfg_bank)
  (void) fprintf(out, "Complete register file of ");

(void) fprintf(out, "%ld registers of %ld bits,\n\t1 write bus, %ld read bus", width, high, n_bus+1);
if(flip_flop)
  (void) fprintf(out, ",\n\tclock edge-triggered flip-flop");
else
  (void) fprintf(out, ",\n\tclock level sensitive latch");
if(inverse_data)
  (void) fprintf(out, ",\n\tinverse data");
if(low_power)
  (void) fprintf(out, ",\n\tlow power consumption");
if(write_enable)
  if(inverse_we)
    (void) fprintf(out, ",\n\twrite enable actif on low level");
  else
    (void) fprintf(out, ",\n\twrite enable actif on high level");
if(stuck)
  (void) fprintf(out, ",\n\tregister at address 0 is stuck to a null value");
(void) fprintf(out, ".\n");
if(hard_connectors)
  (void) fprintf(out, "\tAll connectors are hard (one-access).\n");
else
  (void) fprintf(out, "\tDatapath connectors are multi-access.\n");
if(msb)
  (void) fprintf(out, "\tIndex 0 is gived to the most significant bit of each bus.\n\n");
else
  (void) fprintf(out, "\tIndex 0 is gived to the less significant bit of each bus.\n\n");

/********** Print technology. **********/

(void) fprintf(out, "Technology : \"%s\".\n\n", rfg_tech_name);

/********** Calculate width and height of block. **********/

if(rfg_cell_alims)
  w_alims=WIDTH("rfalck_c");
else
  w_alims=0;

b_width=2*rfg_half_rules + rfg_w_col_lin +
  (rfg_nbr_block+1)*(rfg_w_col_din+w_alims+rfg_w_col_dou) +
  width*rfg_w_col_mla + rfg_w_col_lou;
b_width_m=b_width*rfg_tech_micron;

b_height=rfg_hslice*rfg_num_slices;
if(hard_connectors)
  {
  b_height+=2*rfg_half_rules+(rfg_width_vss>>1);
  if(rfg_num_slices&1)
    b_height+=rfg_width_vdd>>1;
  else
    b_height+=rfg_width_vss>>1;
  }
b_height_m=b_height*rfg_tech_micron;

(void) fprintf(out, "Dimensions :\n");
(void) fprintf(out, "              Height  Width      Area\n");
(void) fprintf(out, "Lambdas        %5d  %5d%10d\n",
  b_height, b_width, b_height*b_width);
(void) fprintf(out, "Microns        %5.0f  %5.0f%10.0f\n\n",
  b_height_m, b_width_m, b_height_m*b_width_m);

/********** Number of transistors. **********/

#define Trfdi8    4  /* Trfdi8  = Trfdi16  */
#define Trfdi8n   2  /* Trfdi8n = Trfdi16n */
#define Trfdi     2
#define Trfl1b    8
#define Trfl2b    9
#define Trfbul1b  4
#define Trfbul2b  6
#define Trfdo1b   4
#define Trfdo2b   8
#define Trfbudo1b 2 
#define Trfbudo2b 4
#define Trfde1b   3  /* Trfde1b  = Trfed1bs  */
#define Trfde1bf  5  /* Trfde1bf = Trfed1bsf */
#define Trfde2b   6  /* Trfde2b  = Trfed2bs  */
#define Trfde2bf  10 /* Trfde2bf = Trfed2bsf */
#define Trflo1b   7
#define Trflo2b   14
#define Trfbus1b  2

#define Trfbsl    4
#define Trfblo    4

#define Trfcnars  6  /* Trfcnars = Trfcnard */
#define Trfchr    2  
#define Trfchw8   4  /* Trfchw8  = Trfchw16 */
#define Trfal2    4
#define Trfal4    8
#define Trfaw8    2  /* Trfaw8  = Trfaw16  */
#define Trfaw8n   4  /* Trfaw8n = Trfaw16n */
#define Trfcnrw1  2
#define Trfcnrw2  4
#define Trfcnrw3  6
#define Trfcna1   2
#define Trfcna2   4
#define Trfcna3s  6  /* Trfcna3s = Trfcna3d */
#define Trfcna4s  8  /* Trfcna4s = Trfcna4d */
#define Trfahb2   2
#define Trfahb4   4

if((block_type==rfg_reg_only) || (block_type==rfg_reg_sep) || (block_type==rfg_bank))
  {
  if(n_bus)
    nbr_trans_reg=((rfg_inv_data_cell ? Trfdi8n : Trfdi8)+(rfg_nbr_block+1)*Trfdi)*high+
      (Trfl2b*high+Trfbul2b)*width+
      (Trfdo2b*high+Trfbudo2b)*(rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)+
      (flip_flop ? (Trfde2b+Trflo2b)*high+Trfbus1b*2 : Trfde2bf*high);
  else
    nbr_trans_reg=((rfg_inv_data_cell ? Trfdi8n : Trfdi8)+(rfg_nbr_block+1)*Trfdi)*high+
      (Trfl1b*high+Trfbul1b)*width+
      (Trfdo1b*high+Trfbudo1b)*(rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)+
      (flip_flop ? (Trfde1b+Trflo1b)*high+Trfbus1b : Trfde1bf*high);
  }

if((block_type==rfg_dec_sep) || (block_type==rfg_bank))
  {
  if(n_bus)
    nbr_trans_dec=Trfbsl*width+
      (flip_flop ? Trfblo*2 : 0)+
      3*((rfg_nbr_block+1)*(rfg_nand_l+1)*Trfal2+
        (rfg_nand_l+1)*Trfcna1*width+
        (rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*(rfg_nand_h+1)*(Trfahb2+Trfcna1))+
      2*low_power*(width*Trfcnars+(rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*Trfchr)+
      write_enable*(rfg_nbr_block+1)*(inverse_we ? Trfaw8n : Trfaw8)+
      ((width>rfg_wblock ? 2 : 1)+write_enable)*Trfcnrw1*width+
      (rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*Trfchw8;
  else
    nbr_trans_dec=Trfbsl*width+
      (flip_flop ? Trfblo : 0)+
      2*((rfg_nbr_block+1)*(rfg_nand_l+1)*Trfal2+
        (rfg_nand_l+1)*Trfcna1*width+
        (rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*(rfg_nand_h+1)*(Trfahb2+Trfcna1))+
      low_power*(width*Trfcnars+(rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*Trfchr)+
      write_enable*(rfg_nbr_block+1)*(inverse_we ? Trfaw8n : Trfaw8)+
      ((width>rfg_wblock ? 2 : 1)+write_enable)*Trfcnrw1*width+
      (rfg_nbr_block>0 ? rfg_nbr_block+1 : 0)*Trfchw8;
  }

if((block_type==rfg_reg_only) || (block_type==rfg_reg_sep))
  nbr_trans=nbr_trans_reg;
else if(block_type==rfg_dec_sep) 
  nbr_trans=nbr_trans_dec;
else if(block_type==rfg_bank)
  nbr_trans=nbr_trans_dec+nbr_trans_reg;

(void) fprintf(out, "Number of transistors : %d.\n\n", nbr_trans);

#if 0
/********** Liste of connectors. **********/

(void) fprintf(out, "List of signals connectors :\n");
(void) fprintf(out, "****************************\n\n");
(void) fprintf(out, "  entries :\n");
(void) fprintf(out, "  ---------\n");

for(RFG_FIRST_CON(); RFG_TEST_CON(); RFG_NEXT_CON())
  {
  if((RFG_CON_TYPE()&rfg_con_in) && (!(RFG_CON_TYPE()&rfg_con_supply)))
    if(RFG_CON_VECTOR())
      if(RFG_CON_RANGE())
        (void) fprintf(out, "    %s[%ld,%ld];\n", RFG_CON_NAME(), RFG_CON_START_INDEX(), RFG_CON_END_INDEX());
      else
        (void) fprintf(out, "    %s[%ld];\n", RFG_CON_NAME(), RFG_CON_START_INDEX());
    else
      (void) fprintf(out, "    %s;\n", RFG_CON_NAME());
  }

(void) fprintf(out, "\n  outputs :\n");
(void) fprintf(out, "  ---------\n");

for(RFG_FIRST_CON(); RFG_TEST_CON(); RFG_NEXT_CON())
  {
  if((RFG_CON_TYPE()&rfg_con_out) && (!(RFG_CON_TYPE()&rfg_con_supply)))
    if(RFG_CON_VECTOR())
      if(RFG_CON_RANGE())
        (void) fprintf(out, "    %s[%ld,%ld];\n", RFG_CON_NAME(),
          RFG_CON_START_INDEX(), RFG_CON_END_INDEX());
      else
        (void) fprintf(out, "    %s[%ld];\n", RFG_CON_NAME(), RFG_CON_START_INDEX());
    else
      (void) fprintf(out, "    %s;\n", RFG_CON_NAME());
  }
#endif

/********** Print input capacitances. **********/

(void) fprintf(out, "Input capacitances :\n");

if((block_type==rfg_dec_sep) || (block_type==rfg_bank))
  {
  float capa1, capa2;

     /***** Address LSB capacitance *****/
  capa1=b_width*rfg_tech_capa_alu2+
    (rfg_nbr_block+1)* /* rfal2_c or rfal4_c */
      (7*rfg_tech_capa_alu1+
      15*rfg_tech_capa_poly+
      24*rfg_tech_capa_gate);
  
     /***** Address MSB capacitance *****/
  capa2=b_width*rfg_tech_capa_alu2+
    (rfg_nbr_block+1)* /* rfahb2_c or rfahb4_c */
      (4*rfg_tech_capa_alu2+
      44*rfg_tech_capa_alu1+
      19*rfg_tech_capa_poly+
      9*rfg_tech_capa_gate);
  switch(rfg_nand_h)
    {
    case 0 :
      capa2+=((rfg_nbr_block+1)>>1)* /* rfcna1_c */
      (23*rfg_tech_capa_alu2+
      32*rfg_tech_capa_alu1+
      16*rfg_tech_capa_poly+
      9*rfg_tech_capa_gate);
      break;
    case 1 :
      capa2+=((rfg_nbr_block+1)>>1)* /* rfcna2_c */
      (23*rfg_tech_capa_alu2+
      26*rfg_tech_capa_alu1+
      23*rfg_tech_capa_poly+
      12*rfg_tech_capa_gate);
      break;
    case 2 :
      capa2+=((rfg_nbr_block+1)>>1)* /* rfcna3d_c or rfcna3s_c */
      (23*rfg_tech_capa_alu2+
      49*rfg_tech_capa_alu1+
      44*rfg_tech_capa_poly+
      15*rfg_tech_capa_gate);
      break;
    case 3 :
      capa2+=((rfg_nbr_block+1)>>1)* /* rfcna4d_c or rfcna4s_c */
      (23*rfg_tech_capa_alu2+
      18*rfg_tech_capa_alu1+
      41*rfg_tech_capa_poly+
      18*rfg_tech_capa_gate);
      break;
    default :
      capa2=0L;
    }
     /***** Max of Address LSB and MSB capacitances *****/
  if(capa2>capa1)
    capa1=capa2;

  (void) fprintf(out, "    - ad_w   = %.3f pF.\n", capa1);
  if(write_enable)
    {
    float capa;

    capa=b_width*rfg_tech_capa_alu2;
    if(rfg_nbr_block_p)
      {
      if(inverse_we)
        { /* rfaw16n_c */
        capa+=rfg_nbr_block_p*
          (7*rfg_tech_capa_alu1+
          22*rfg_tech_capa_poly+
          21*rfg_tech_capa_gate);
        }
      else
        { /* rfaw16_c */
        capa+=rfg_nbr_block_p*
          (7*rfg_tech_capa_alu1+
          14*rfg_tech_capa_poly+
          45*rfg_tech_capa_gate);
        }
      }
    if((rfg_width_f>0) && (rfg_width_f<=8))
      {
      if(inverse_we)
        { /* rfaw8n_c */
        capa+=7*rfg_tech_capa_alu1+
          22*rfg_tech_capa_poly+
          12*rfg_tech_capa_gate;
        }
      else
        { /* rfaw8_c */
        capa+=7*rfg_tech_capa_alu1+
          14*rfg_tech_capa_poly+
          24*rfg_tech_capa_gate;
        }
      }
    (void) fprintf(out, "    - we     = %.3f pF.\n", capa);
    }
  (void) fprintf(out, "    - ad_r_a = %.3f pF.\n", capa1);	
  if(n_bus)
    {
    (void) fprintf(out, "    - ad_r_b = %.3f pF.\n", capa1);
    }
  (void) fprintf(out, "    - ck_m   = %.3f pF.\n", 
     /***** main wire in alu2 *****/
    b_width*rfg_tech_capa_alu2+ 
     /***** wire in alu1 *****/
    rfg_cell_alims*(rfg_nbr_block+1)*
      rfg_hslice*rfg_num_slices_dec*rfg_tech_capa_alu1+ 
     /***** latchs nands input rfbsl_c *****/
    width*
      (7*rfg_tech_capa_alu1+
      15*rfg_tech_capa_poly+
      24*rfg_tech_capa_gate)+
     /***** output latchs input rfblo_c *****/ 
    flip_flop*(n_bus+1)*
      (7*rfg_tech_capa_alu1+
      13*rfg_tech_capa_poly+
      12*rfg_tech_capa_gate));
  }

if((block_type==rfg_reg_only) || (block_type==rfg_reg_sep))
  {
  float capa;

  capa=3*rfg_tech_capa_alu1+
    34*rfg_tech_capa_poly+
    81*rfg_tech_capa_gate;
  (void) fprintf(out, "    - w      = %.3f pF.\n", capa);
  if(flip_flop)
    {
    (void) fprintf(out, "    - w_r_a  = %.3f pF.\n", capa);
    if(n_bus)
      {
      (void) fprintf(out, "    - w_r_b  = %.3f pF.\n", capa);
      }
    }
  (void) fprintf(out, "    - r_a    = %.3f pF.\n", capa);
  if(n_bus)
    {
    (void) fprintf(out, "    - r_b    = %.3f pF.\n", capa);
    }
  if(rfg_nbr_block)
    {
    (void) fprintf(out, "    - s_a    = %.3f pF.\n", capa);
    if(n_bus)
      {
      (void) fprintf(out, "    - s_b    = %.3f pF.\n", capa);
      }
    }
  }

if((block_type==rfg_reg_only) || (block_type==rfg_reg_sep) || (block_type==rfg_bank))
  {
  float capa;

  if(rfg_inv_data_cell)
    if(rfg_type_lin)
      { /* rfdi16n_c */
      capa=rfg_half_rules*rfg_tech_capa_alu2+
        53*rfg_tech_capa_alu1+
        39*rfg_tech_capa_poly+
        60*rfg_tech_capa_gate;
      }
    else
      { /* rfdi8n_c */
      capa=rfg_half_rules*rfg_tech_capa_alu2+
        23*rfg_tech_capa_alu1+
        25*rfg_tech_capa_poly+
        30*rfg_tech_capa_gate;
      }
  else
    if(rfg_type_lin)
      { /* rfdi16_c */
      capa=rfg_half_rules*rfg_tech_capa_alu2+
        42*rfg_tech_capa_alu1+
        36*rfg_tech_capa_poly+
        30*rfg_tech_capa_gate;
      }
    else
      { /* rfdi8_c */
      capa=(rfg_half_rules+7)*rfg_tech_capa_alu2+
        29*rfg_tech_capa_alu1+
        45*rfg_tech_capa_poly+
        15*rfg_tech_capa_gate;
      }

  (void) fprintf(out, "    - in_a   = %.3f pF.\n", capa);
  }

(void) fprintf(out, "\n");

/********** Print timing. **********/

if(block_type==rfg_bank)
  {
  float time, res;

  time=res=0;

  (void) fprintf(out, "Timing (typical) :\n");

  (void) fprintf(out, "    - tc1  = %.3f ns.\n", time);
  (void) fprintf(out, "    - tc0  = %.3f ns.\n", time);
  (void) fprintf(out, "    - taws = %.3f ns.\n", time);
  (void) fprintf(out, "    - tawh = %.3f ns.\n", (float) 0);
  (void) fprintf(out, "    - tdts = %.3f ns.\n", time);
  (void) fprintf(out, "    - tdth = %.3f ns.\n", (float) 0);
  if(flip_flop)
    {
    (void) fprintf(out, "    - tars = %.3f ns.\n", time);
    (void) fprintf(out, "    - tarh = %.3f ns.\n", (float) 0);
    }
  (void) fprintf(out, "    - trda = %.3f + %.3f * Cload ns.\n", time, res);
  if(!flip_flop)
    {
    (void) fprintf(out, "    - tpd  = %.3f + %.3f * Cload ns.\n", time, res);
    }

  (void) fprintf(out, "\n");
  }

/*
(void) fclose(out);
*/
}

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