#include <stdio.h>

int gener();
int puiss();
char valeur();

main()
{
 int i;
 

 i= gener(8,1,1);
}

int gener(l,c,u)
int l,c,u;
{
 FILE *fich;
 int i,j,k;
 char name[13];

 name[0] = 'r';
 name[1] = 'b';
 name[2] = 'i';
 name[3] = 't';
 name[4] = '_';
 name[5] = valeur(l);
 name[6] = '_';
 name[7] = valeur(c);
 name[8] = '.';
 name[9] = 'v';
 name[10] = 'b';
 name[11] = 'e';
 name[12] = '\0';

 fich = fopen(name, "w");
 fprintf(fich,"ENTITY  rbit_%d_%d IS\n",l,c);

 fprintf(fich,"PORT (\n"); 
 fprintf(fich,"   wl	:	IN BIT_VECTOR(0 TO %d);\n",puiss(l)-1);
 fprintf(fich,"   sel	:   	IN BIT_VECTOR(0 TO %d);\n",puiss(c)-1);
 fprintf(fich,"   read	:   	IN BIT ;\n");
 fprintf(fich,"   write :	IN BIT ;\n");
 if(u==1){
 fprintf(fich,"   ent	:   	IN BIT;\n");
 fprintf(fich,"   sor	:   	OUT BIT;\n");
         }
 else {
 fprintf(fich,"   sor	:   	INOUT MUX_BIT BUS ;\n");
      }
 fprintf(fich,"   vdd	:	IN BIT ;\n");
 fprintf(fich,"   vss	:	IN BIT) ;\n");
 fprintf(fich,"END rbit_%d_%d ;\n",l,c);
 fprintf(fich,"\n\n\n"); 
 fprintf(fich,"ARCHITECTURE rbitarch OF rbit_%d_%d IS \n",l,c);
 for(i=0;i<l;i++)
 {
  fprintf(fich," signal wl%d : BIT_VECTOR(0 TO %d);\n",i,puiss(l-i)-1);
 }
 fprintf(fich," signal wla : BIT_VECTOR(0 TO %d);\n",l-1);
 for(i=0;i<c;i++)
 {
  fprintf(fich," signal sl%d : BIT_VECTOR(0 TO %d);\n",i,puiss(c-i)-1);
 }
 if(c==1) fprintf(fich," signal csa : BIT;\n");
 else fprintf(fich," signal csa : BIT_VECTOR(0 TO %d);\n",c-1);
 for(i=0;i<16;i++)
 {
  fprintf(fich," signal mem%d : REG_VECTOR(0 TO %d) REGISTER ;\n",i,puiss(l+c-4)-1);
 }
 fprintf(fich,"  signal msig0 : BIT_VECTOR(0 TO %d);\n",puiss(l+c-4)-1);
 fprintf(fich,"  signal msig1 : BIT_VECTOR(0 TO %d);\n",puiss(c)-1);
 fprintf(fich,"  signal msig2 : BIT_VECTOR(0 TO %d);\n",puiss(c)-1);
 fprintf(fich,"  signal msig3 : BIT_VECTOR(0 TO %d);\n",puiss(l+c-4)-1);
 if(u==0){
          fprintf(fich,"  signal kar   : BIT; \n");
         }

 fprintf(fich,"begin\n");
 fprintf(fich,"--  Recoding --\n\n\n");

 fprintf(fich,"  wl0 <= wl ;\n");
 for(i=0;i<l;i++)
 {
  fprintf(fich,"  with wl%d(0 TO %d) select\n",i,puiss(l-1-i)-1);
  fprintf(fich,"  wla(%d) <= '0' when ",i);
  if(i>l-3) {
             fprintf(fich,"B\"");
             for(j=0;j<puiss(l-1-i);j++)
              fprintf(fich,"0");
            }
  else {
        fprintf(fich,"X\"");
        for(j=0;j<puiss(l-i-3);j++)
         fprintf(fich,"0");
       }
  fprintf(fich,"\" ,\n");
  fprintf(fich,"            '1' when others ;\n");
  if(i<l-1)
  {
   fprintf(fich,"  with wla(%d) select\n",i);
   fprintf(fich,"  wl%d <= wl%d(0 TO %d) when '0',\n",i+1,i,puiss(l-1-i)-1);
   fprintf(fich,"          wl%d(%d TO %d) when '1';\n",i,puiss(l-1-i),puiss(l-i)-1);
  }
 }

 fprintf(fich,"  sl0 <= sel ;\n");
 for(i=0;i<c;i++)
 {
  fprintf(fich,"  with sl%d(0 TO %d) select\n",i,puiss(c-1-i)-1);
  if(c==1) fprintf(fich,"  csa     <= '0' when B\"");
  else fprintf(fich,"  csa(%d) <= '0' when B\"",i);
  for(j=0;j<puiss(c-i-1);j++)
   fprintf(fich,"0");
  fprintf(fich,"\" ,\n");
  fprintf(fich,"            '1' when others ;\n");
  if(i<c-1)
  {
   fprintf(fich,"  with csa(%d) select\n",i);
   fprintf(fich,"  sl%d <= sl%d(0 TO %d) when '0',\n",i+1,i,puiss(c-1-i)-1);
   fprintf(fich,"          sl%d(%d TO %d) when '1';\n",i,puiss(c-1-i),puiss(c-i)-1);
  }
 }
 fprintf(fich,"\n\n\n-- Read Operation --\n\n");
 fprintf(fich,"  with wla(0 TO 3) select\n");
 fprintf(fich,"  msig0 <= mem0 when B\"0000\",\n");
 for(i=1;i<16;i++)
 {
  fprintf(fich,"           mem%d when B\"",i);
  j=i;
  for(k=3;k>=0;k--)
  {
   if(j>=puiss(k)) {
                    fprintf(fich,"1");
                    j = j - puiss(k);
                   }
   else fprintf(fich,"0");
  }
  if(i==15) fprintf(fich,"\";\n");
  else fprintf(fich,"\",\n");
 }
 fprintf(fich,"\n\n");
 fprintf(fich,"  with wla(4 TO %d) select\n",l-1);
 fprintf(fich,"  msig1 <= msig0(0 TO %d) when B\"",puiss(c)-1);
 for(i=0;i<l-4;i++)
  fprintf(fich,"0");
 fprintf(fich,"\",\n");
 for(i=1;i<puiss(l-4);i++)
 {
  fprintf(fich,"           msig0(%d TO %d) when B\"",puiss(c)*i,puiss(c)*(i+1)-1);
  j=i;
  for(k=l-5;k>=0;k--)
  {
   if(j>=puiss(k)) {
                    fprintf(fich,"1");
                    j = j - puiss(k);
                   }
   else fprintf(fich,"0");
  }
  if(i==puiss(l-4)-1) fprintf(fich,"\";\n");
  else fprintf(fich,"\",\n");
 }
 fprintf(fich,"\n\n");
 if(c==1) fprintf(fich,"  with write & read & csa select\n");
 else fprintf(fich,"  with write & read & csa(0 TO %d) select\n",c-1);
 if(u==1){
          fprintf(fich,"  sor <= msig1( 0 ) when B\"01");
         }
 else{
      fprintf(fich,"  kar <= msig1( 0 ) when B\"01");
     }
 for(i=0;i<c;i++)
  fprintf(fich,"0");
 fprintf(fich,"\",\n");
 for(i=1;i<puiss(c);i++)
 {
  fprintf(fich,"         msig1( %d ) when B\"01",i);
  j=i;
  for(k=c-1;k>=0;k--)
  {
   if(j>=puiss(k)) {
                    fprintf(fich,"1");
                    j = j - puiss(k);
                   }
   else fprintf(fich,"0");
  }
  fprintf(fich,"\",\n");
 }
 fprintf(fich,"         '0'  when others ;\n");
 fprintf(fich,"\n\n");
 if(u==0){
          fprintf(fich,"  rop:block ( write & read = B\"01\")\n");
          fprintf(fich,"      begin\n");
          fprintf(fich,"            sor <= guarded kar;\n");
          fprintf(fich,"      end block ;\n");
         }
 fprintf(fich,"\n\n");
 fprintf(fich,"-- Write Operation --\n");
 if(u==0){
          name[0]='s';
          name[1]='s';
          name[2]='s';
          name[3]='\0';
         }
 else {
          name[0]='e';
          name[1]='n';
          name[2]='t';
          name[3]='\0';
      }

 switch(c)
 {
   case 1:
          {
           fprintf(fich,"  with write & read & csa select\n");
           fprintf(fich,"  msig2 <= msig1(0) & %s when B\"100\" ,\n",name);
           fprintf(fich,"           %s & msig1(1) when B\"101\" ,\n",name);
           fprintf(fich,"           msig1(0 TO 1)  when others ;\n");
           break;
          }
   case 2:
   case 3:
   case 4:
          {
           fprintf(fich,"  with write & read & csa(0 TO %d) select\n",c-1);
           fprintf(fich,"  msig2 <= msig1(0 TO %d) & %s when B\"10",puiss(c)-2,name);
           for(i=0;i<c;i++)
            fprintf(fich,"0");
           fprintf(fich,"\",\n");
           fprintf(fich,"           msig1(0 TO %d) & %s & msig1(%d) when B\"10",puiss(c)-3,name,puiss(c)-1);
           for(i=0;i<c-1;i++)
            fprintf(fich,"0");
           fprintf(fich,"1\",\n");
           for(i=2;i<puiss(c)-2;i++)
           {
            fprintf(fich,"           msig1(0 TO %d) & %s & msig1(%d TO %d) when B\"10",puiss(c)-i-2,name,puiss(c)-i,puiss(c)-1);
            j=i;
            for(k=c-1;k>=0;k--)
            {
             if(j>=puiss(k)) {
                              fprintf(fich,"1");
                              j = j - puiss(k);
                             }
             else fprintf(fich,"0");
            }
            fprintf(fich,"\" , \n");
           }
            fprintf(fich,"           msig1( 0 ) & %s & msig1(2 TO %d) when B\"10",name,puiss(c)-1);
           for(i=0;i<c-1;i++)
            fprintf(fich,"1");
           fprintf(fich,"0\",\n");
            fprintf(fich,"           %s & msig1(1 TO %d) when B\"10",name,puiss(c)-1);
           for(i=0;i<c;i++)
            fprintf(fich,"1");
           fprintf(fich,"\" ,\n");
           fprintf(fich,"           msig1(0 TO %d)  when others ;\n",puiss(c)-1);
           break;
          }
    default: break;
 }

 fprintf(fich,"\n\n");
 fprintf(fich,"  with wla(4 TO %d) select\n",l-1);
 fprintf(fich,"  msig3 <= msig0(0 TO %d) & msig1(0 TO %d) when B\"",(puiss(l-4)-1)*(puiss(c))-1,puiss(c)-1);
 for(i=0;i<l-4;i++)
  fprintf(fich,"0");
 fprintf(fich,"\",\n");
 for(i=1;i<puiss(l-4)-1;i++)
 {
  fprintf(fich,"           msig0(0 TO %d) & msig1(0 TO %d) & msig0(%d TO %d) when B\"",(puiss(l-4)-(i+1))*puiss(c)-1,puiss(c)-1,(puiss(l-4)-i)*puiss(c),puiss(l+c-4)-1);
  j=i;
  for(k=l-5;k>=0;k--)
  {
   if(j>=puiss(k)) {
                    fprintf(fich,"1");
                    j = j - puiss(k);
                   }
   else fprintf(fich,"0");
  }
  fprintf(fich,"\" , \n");
 }
  fprintf(fich,"           msig1(0 TO %d) & msig0(%d TO %d) when B\"",puiss(c)-1,puiss(c),puiss(l+c-4)-1);
 for(i=0;i<l-4;i++)
  fprintf(fich,"1");
 fprintf(fich,"\";\n");

 fprintf(fich,"\n\n");

 fprintf(fich,"-- Register Write --");
 fprintf(fich,"\n\n");
  for(i=0;i<16;i++)
  {
   fprintf(fich," wb%d : block (((write and not(read)) = '1') and (wla(0 TO 3) = B\"",i);
   j=i;
   for(k=3;k>=0;k--)
   {
    if(j>=puiss(k)) {
                     fprintf(fich,"1");
                     j = j - puiss(k);
                    }
    else fprintf(fich,"0");
   }
   fprintf(fich,"\" ))\n");
   fprintf(fich,"        begin\n");
   fprintf(fich,"             mem%d <= guarded msig3;\n",i);
   fprintf(fich,"        end block;\n");
   fprintf(fich,"\n\n");
  }
   fprintf(fich,"\n\n");
   fprintf(fich,"\n\n");

 fprintf(fich,"-- End of description --\n");
 fprintf(fich,"end rbitarch ; \n");
}

int puiss(i)
int i;
{
 if(i==0) return(1);
 else return(2*puiss(i-1));
}
 
char valeur(i)
int i;
{
 switch(i)
 {
  case 1:{ return('1'); break;}
  case 2:{ return('2'); break;}
  case 3:{ return('3'); break;}
  case 4:{ return('4'); break;}
  case 5:{ return('5'); break;}
  case 6:{ return('6'); break;}
  case 7:{ return('7'); break;}
  case 8:{ return('8'); break;}
  default: break;
 }
}

