
#include "compMatrix.h"
#include <ctime>


void printW(FILE* file, cfixed_t a[NL][NA]){
   fprintf(file,"[");
   for (int i = 0; i < NL; i++) {

      for (int j = 0; j < NA; j++) {
			
		  fprintf(file,"%f+%fi", a[i][j].real.to_double(),a[i][j].imag.to_double());
			  
		  if(j == NA-1){
			  fprintf(file,";");
		  }
		  else{
			  fprintf(file,",");
		  }
      }
   }
   fprintf(file,"];\n");
}

void printY(FILE* file, cfixed_t a[NA]){
   fprintf(file,"[");
    for (int j = 0; j < NA; j++) {
			
		 fprintf(file,"%f+%fi", a[j].real.to_double(),a[j].imag.to_double());
		fprintf(file,",");
	}
	fprintf(file,"];\n");
}

void printRes(FILE* file, cfixed_t a[NL]){

   fprintf(file,"res%d: [", 0);
    for (int j = 0; j < NL; j++) {
			
		 fprintf(file,"%f+%fi", a[j].real.to_double(),a[j].imag.to_double());
		fprintf(file,",");
	}
	fprintf(file,"];\n");

}

int main(int argc, char **argv)
{
	
	cfixed_t W[NL][NA];
	cfixed_t y[NA];
	cfixed_t res[NL];
	
	cfixed_t WMem[NL][NA];
	cfixed_t yMem[NA];
	cfixed_t resMem[NL];
	
	
	ihc::stream_in<cfixed_t> WStream;
	ihc::stream_in<cfixed_t> yStream;
	ihc::stream_out<cfixed_t> resStream;
	
	mm_host_t1 mm_W(WMem, 32*16*128);
	mm_host_t2 mm_y(yMem, 32*128);
	mm_host_t3 mm_res(resMem, 32*16*16);
	
	
	int fileend=0;
	int scnt;
	int   m, n;
	float tmp1, tmp2;
	
	FILE* fpa;
	fpa=fopen("W_16x16_100ds.txt", "rt");
	if(fpa==0){
		printf("Error Opening MatrixStream!\n");
		return(1);
	}
	
	FILE *file = fopen("results_Comp.m", "w");
	if (file == NULL) {
		printf("Error opening file!\n");
		return(1);
	}
		
	
	
	for(n=0;n<NL;n++){
		for(m=0;m<NA;m++){
			scnt = fscanf(fpa, "%e %ei\n", &tmp1, &tmp2);
			if (scnt < 0) {
				printf("Error reading Input B Matrix!\n");
				fileend = 1;
				break;
			}
			W[n][m].real = tmp1; W[n][m].imag = tmp2;
		}
	}
	
		fprintf(file, "W = \n");	
		printW(file, W);

		//Generar datos de entrada yStream
		    srand(time(nullptr)); // Seed
			
			
  for(int i = 0; i < NL; i++) {
    // Iterate over the columns of the matrix
	#pragma ii 1
    for(int j = 0; j < NA; j++) {
	
		WStream.write(W[i][j]);
		WMem[i][j] = W[i][j];
	}
  }
  	for(int k = 0; k<NA; k++){
		
		unsigned int rand_int_r = rand() & 0x7FFF; // 15 bits
		fixed16 fixed16_val_r = 2* (rand_int_r-1) / 32768.0; // Convert to fixed-point
		y[k].real = fixed16_val_r;
		
		unsigned int rand_int_i = rand() & 0x7FFF; // 15 bits
		fixed16 fixed16_val_i = 2* (rand_int_i-1) / 32768.0; // Convert to fixed-point
		y[k].imag = fixed16_val_i;
	
	}
	
	for(int k = 0; k<NA; k++){
		yStream.write(y[k]);
		yMem[k] = y[k];
	}
	fprintf(file, "y%d = \n",0);	
	printY(file, y);
	
	ihc_hls_enqueue_noret(&c_compSTR,  WStream,  yStream, resStream);  
	ihc_hls_component_run_all(c_compSTR);
	ihc_hls_enqueue_noret(&c_compMM_m,  mm_W,  mm_y, mm_res);  
	ihc_hls_component_run_all(c_compMM_m);
	

    for(int j = 0; j < NL; j++) {
		res[j] = resStream.read();
	}

  
  printRes(file, res);
  fprintf(file, "\n\n And now, for someting completely different: \n");
  
  printRes(file, resMem);
	fclose(file);
}