/*------------------------------------------------------------------
-- TITLE : pattgenc.c
-----------------------------------------------------------------
-- PROGRAMM: C Interface to the VHDL model
-- AUTHOR  : Thierry Schneider
-----------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include "pattgenc.h"

/* Cette structure est utilisee durant toute la simulation pour stocker
la valeur des differents signaux */
static struct C_interface io_IF;

/* ============================================================= */
/* ============================================================= */
void VHDL_IF_init(region, param, generics, ports)
    regionID region;
    char *param;
    interface_list *generics;
    interface_list *ports;
{
    struct VHDL_interface *ip;
    processID      proc;
    
    ip = (struct VHDL_interface *) mti_Malloc(sizeof(struct VHDL_interface));
    
    /* inputs mapping */
    ip->patt_clk = mti_FindPort(ports, "patt_clk");
    ip->cnt_reset= mti_FindPort(ports, "cnt_reset");
    ip->exit_c   = mti_FindPort(ports, "exit_c");
    
   /* outputs mapping */
   ip->data = mti_CreateDriver(mti_FindPort(ports, "data"));

   proc = mti_CreateProcess("all_vars",(funcptr) VHDL_IF_exec, ip);
   
   /* Sensitize all inputs */
   mti_Sensitize(proc, ip->patt_clk,  MTI_EVENT);
   mti_Sensitize(proc, ip->cnt_reset, MTI_EVENT);
   mti_Sensitize(proc, ip->exit_c,    MTI_EVENT);
   
   Init_C_model(&io_IF);
}

/* .............................................................. */
long ArrayStd2Long(table, nbrbit)
    char *table;
    long nbrbit;
{
    long x, b, i;

    b = 1L;
    x = 0;
    for(i=0; i<nbrbit; i++)
    {
        if (table[nbrbit-1-i]==STD_1)  x = x | b;
        b = b << 1;
    }
 
    return(x);
}

/* .............................................................. */
void Long2ArrayStd(table, value, nbrbit)
     char *table;
     long value;
     long nbrbit;
 {
     long b, i;
 
     b = 1L;
     for(i=0; i<nbrbit; i++)
     {
         if ((value & b)==b)    table[nbrbit-1-i] = STD_1;
         else                   table[nbrbit-1-i] = STD_0;
         b = b << 1;
     }
 }
 
 /* .............................................................. */
 long Std2Long(std)
     long std;
 {
     long retour;
     if (std==STD_1)    retour = 1;
     else               retour = 0;
     return(retour);
 }
 
 /* .............................................................. */
 long Long2Std(value)
     long value;
 {
    long retour;
    if ((value & 1)==1)    retour = STD_1;
    else                   retour = STD_0;
    return(retour);

 
 /* .............................................................. */
 void VHDL_IF_exec (VHDL_IF)
     struct VHDL_interface *VHDL_IF;
 {
     long x;
     char vector[32];
 
     x = mti_GetSignalValue(VHDL_IF->patt_clk);
     io_IF.patt_clk = Std2Long(x);
     
     x = mti_GetSignalValue(VHDL_IF->cnt_reset);
     io_IF.cnt_reset    = Std2Long(x);
     
     x = mti_GetSignalValue(VHDL_IF->exit_c);
     io_IF.exit_c    = Std2Long(x);
     
     /* all inputs have been read and written is the structure. We can
        can the C model */
 
     Exec_C_model(&io_IF);
 
     /* Now we read all outputs and send them to the VHDL model. */
     
     Long2ArrayStd(vector, io_IF.data, 8);
     mti_ScheduleDriver(VHDL_IF->data,(long) vector,0,MTI_INERTIAL);
 }
 
 /* .............................................................. */
 void VHDL_print (txt)
     char *txt;
 {
     mti_PrintMessage(txt);
 }
 
 /* ============================================================ */
 /* ============================================================ */

 char txt[256];
 long prev_patt_clk;
 FILE *in;
 
 /* .............................................................. */
 void Init_C_model(C_IF)
     struct C_interface *C_IF;
 {
     long i;
 
     prev_patt_clk = 0;
     in  = fopen("pattern.bin","rb");
 
     if (in)  sprintf(txt,"pattern.bin successfully opened \n");
     else     sprintf(txt,"Error : unable to open file pattern.bin \n");
 
     VHDL_print(txt);
 }
 
 /* .............................................................. */
 void Exit_C_model()
 {
     if (in) 
     {
         fclose(in);
         sprintf(txt, "closing input file \n");
         VHDL_print(txt);
     }
     in = 0;
 }
 
 
 /* .............................................................. */
 void Exec_C_model(C_IF)
     struct C_interface *C_IF;
 {
     int c;
     
     if (C_IF->cnt_reset==1)
     {
         if (in) 
             fseek(in,0,0);
         C_IF->data = 0;
     }
     else
     {
         if ((C_IF->patt_clk==1) && (prev_patt_clk==0)) 
         {
             if (in)
                 c=fgetc(in);
             else
                 c=0;
                 
             if (c==EOF)
             {
                 fseek(in,0,0);
                 if (in)
                     c=fgetc(in);
                 else
                     c=0;
             }
             C_IF->data = c;
         }
     }
     if (C_IF->exit_c==1)        
         Exit_C_model();
     
     prev_patt_clk = C_IF->patt_clk;
 }
 /* .............................................................. */