Site hosted by Angelfire.com: Build your free website today!
 
Brief Bus Functional Model of 8051

Sohail Syed
sohail_syed@mentor.com

I used Mentor Modelsim verilog simulator to run this bus functional model of 8051 using PLI 1.0. I also checked the same with other simulators and found all of them 100% compatible. The advantage of Mentor simulator is that it create DLL instead of using the static linking. It does the same on the sun and HP platform thus makes it easier to keep the control over the binaries. I compiled, simulated the design on the NT PLATFORM and found no problems/bugs. Enclosed also the complete design with verilog instantiation of the design. I am enclosing the compilation instruction for PC which is very uncommon.

Here are some description of the code.

Compilation instruction using VC4.2

 
cl -c -Ic:\tools\fet\fpgadv30\Modeltech\include uc8051.c
link -dll  uc8051.obj c:\tools\fet\fpgadv30\Modeltech\win32\mtipli.lib
 

file: entry.c
(For PC users only who want to make a DLL).

 
#define WIN32_LEAN_AND_MEAN
#include 
#include 
#include 
#include 
#include 
#include "uc.h"
_declspec( dllexport ) void init_usertfs();


BOOL WINAPI DllMain(HINSTANCE hinstDLL,      // handle to DLL module
                    DWORD     fdwReason,     // reason for calling function
                    LPVOID    lpReserved )   // reserved
{
 // DWORD tid = GetCurrentThreadId();

  switch( fdwReason ) {
    case DLL_PROCESS_ATTACH:
      //printf("DLL:\tProcess attach (tid = %x)\n", tid);
      break;

    case DLL_THREAD_ATTACH:
      //printf("DLL:\tThread attach (tid = %x)\n", tid);
      break;

    case DLL_THREAD_DETACH:
      //printf("DLL:\tThread detach (tid = %x)\n", tid);
      break;

    case DLL_PROCESS_DETACH:
      //printf("DLL:\tProcess detach (tid = %x)\n", tid);
      break;
  }
  return TRUE;
}

void init_usertfs()
{
  p_tfcell usertf;

  for (usertf = veriusertfs; usertf; usertf++) {
    if (usertf->type == 0) {
      break;
    }
    mti_RegisterUserTF(usertf);
  }
}

file: uc.h

 
#include 

#ifdef __WIN32__

#include 
#include 
#include 
#include 
#endif

#include "veriuser.h"
#include "acc_user.h"

#define  UCHAR  unsigned char

/* **********Function Calls************* */
#define PLI_UC_8051_TASK            "$divideBy2Clk"
#define PLI_UC_READ_TASK            "$ucRead"
#define PLI_UC_WRITE_TASK           "$ucWrite"

#define PLI_CASE_UC_8051_TASK        0
#define PLI_CASE_UC_READ_TASK        1
#define PLI_CASE_UC_WRITE_TASK       2

#define PLI_UC_PARAM_COUNT           9
#define PLI_CLK_UC_PARAM             1
#define PLI_RST_UC_PARAM             2
#define PLI_EA_UC_PARAM              3
#define PLI_PSEN_UC_PARAM            4
#define PLI_ALE_UC_PARAM             5
#define PLI_PORT0_UC_PARAM           6
#define PLI_PORT1_UC_PARAM           7
#define PLI_PORT2_UC_PARAM           8
#define PLI_PORT3_UC_PARAM           9

#define PLI_READ_PARAM_COUNT         2
#define PLI_ADDRESS_READ_PARAM       1
#define PLI_DATA_READ_PARAM          2

#define PLI_WRITE_PARAM_COUNT        2
#define PLI_ADDRESS_WRITE_PARAM      1
#define PLI_DATA_WRITE_PARAM         2

#define VCL_ID_CLK          0
#define VCL_ID_RST          1
#define VCL_ID_EA           2
#define VCL_ID_PSEN         3
#define VCL_ID_ALE          4
#define VCL_ID_PORT3        8

/* ********************** UC Main State Machine ****************/
#define UC_MAIN_STATE_IDLE           0
#define UC_MAIN_STATE_SEND_ALE       1
#define UC_MAIN_STATE_SEND_ADDRESS   2
#define UC_MAIN_STATE_SENT_ALE       3
#define UC_MAIN_STATE_SENT_ADDRESS   4
#define UC_MAIN_STATE_WAIT_FOR_RDWR  5
#define UC_MAIN_STATE_SENT_RDWR      6

#define CLOCK_WIDTH_OF_ALE           2
#define CLOCK_WIDTH_OF_XXX_AFTER_ALE 2
#define CLOCK_WIDTH_OF_RDWR          5

typedef struct _uc8051S {
  handle clkHandle;
  handle rstHandle;
  handle eaHandle;
  handle psenHandle;
  handle aleHandle;
  handle port0Handle;
  handle port1Handle;
  handle port2Handle;
  handle port3Handle;
  handle readDataHandle;
  char   *tfInstance;
  UCHAR signalId;
  UCHAR clkVal;
  UCHAR clkTriggered;
  UCHAR rstVal;
  UCHAR rstTriggered;
  UCHAR eaVal;
  UCHAR eaTriggered;
  UCHAR psenVal;
  UCHAR psenTriggered;
  UCHAR aleVal;
  UCHAR aleTriggered;
  UCHAR port3Val;
  UCHAR port3Triggered;


  UCHAR aleClkCount;
  UCHAR xClkCount;
  UCHAR rdwrClkCount;
  UCHAR ucMainState;

  UCHAR ucAddress;
  UCHAR RD_;
  UCHAR WR_;
  int   readData;
  int   writeData;

}uc8051S;
uc8051S *pUc8051S;

typedef struct _userVclDataS {
  UCHAR    id;
  uc8051S  *pUc8051S;
}userVclDataS;

typedef struct _infoListBufferS{
  handle readDataHandle;
  UCHAR ucAddress;
  UCHAR RD_;
  UCHAR WR_;
  int   readData;
  int   writeData;
  struct _infoListBufferS  *next;
  struct _infoListBufferS  *prev;

}infoListBufferS;

handle gReadDataHandle;
UCHAR gUcAddress;
UCHAR gRD_;
UCHAR gWR_;
int   gWriteData;

infoListBufferS *pFirst,*pLast,*pMoving,*pCurrent;
static char tmpUcStr[4096];


/* function prototype */
static int ucConsumerRoutine(p_vc_record p_record);
static void ucSynchronize();
static void ucPrintMsg(uc8051S *pUc8051S, char *msg);
void driveSignal(handle driveHandle,UCHAR driveVal);
void driveVectorSignal(handle driveHandle, UCHAR driveVal);
void driveVectorScalarSignal(handle driveHandle,UCHAR driveVal);
int  readVectorSignal(handle driveHandle);
void ucInitLL(void);
void scheduleTask(void);
infoListBufferS *allocateLLBuffer(void);
void processTask(void);
void removeTask(void);
static void ucMainStateMachine();

#ifdef __MAIN__
void initUc();
void callMainFunc();
#else
extern void initUc();
extern void callMainFunc();
#endif

extern int ucCheck_tf();
extern int ucCall_tf();
extern int ucMisc_tf();

#ifdef __MAIN__

/*******************************************************************/
/*** VERIUSER_VERSION_STR                                        ***/
/*** Contents of this string will be printed out after product   ***/
/*** version information is printed out (the -q option will      ***/
/*** suppress this print). Example :                             ***/
/*** char *veriuser_version_str = "Internal version 1.5b_1.3\n"; ***/
/*******************************************************************/
char *veriuser_version_str = "";

err_intercept(level,facility,code)
int level;
char *facility;
char *code;
{
     return(true);
}

s_tfcell veriusertfs[]={
  { usertask, 0, ucCheck_tf, 0, ucCall_tf, ucMisc_tf,
       "$uc8051", 1},
  { usertask, 1, ucCheck_tf, 0, ucCall_tf, ucMisc_tf,
       "$ucRead", 1},
  { usertask, 2, ucCheck_tf, 0, ucCall_tf, ucMisc_tf,
       "$ucWrite", 1},
  {0}
};

int (*endofcompile_routines[])() =
{
    /*** my_eoc_routine, ***/
  0 /*** final entry must be 0 ***/
};

#else
extern s_tfcell veriusertfs[];
#endif

File: ucpli.c

 
#define __MAIN__
#include "uc.h"

static int vclSignalAddRoutine();

int ucCheck_tf(int data , int reason)
{
  int nump;

  nump=tf_nump();
  switch(data){
  case PLI_CASE_UC_8051_TASK:
    if(nump != PLI_UC_PARAM_COUNT){
      tf_error("Parameters should be 9");
    }
    if(tf_typep(PLI_CLK_UC_PARAM) == tf_nullparam){
      tf_error("CLK cannot be a Null Param\n");
     }
    if(tf_typep(PLI_RST_UC_PARAM) == tf_nullparam){
      tf_error("RST cannot be a Null Param\n");
     }
    if(tf_typep(PLI_EA_UC_PARAM) == tf_nullparam){
      tf_error("EA cannot be a Null Param\n");
     }
    if(tf_typep(PLI_PSEN_UC_PARAM) == tf_nullparam){
      tf_error("PSEN cannot be a Null Param\n");
     }
    if(tf_typep(PLI_ALE_UC_PARAM) == tf_nullparam){
      tf_error("ALE cannot be a Null Param\n");
     }

    if(tf_typep(PLI_PORT0_UC_PARAM) != tf_readwrite){
      tf_error("PORT0 should  be a R/W Param\n");
    }
    if(tf_typep(PLI_PORT1_UC_PARAM) != tf_readwrite){
      tf_error("PORT1 should  be a R/W Param\n");
    }
    if(tf_typep(PLI_PORT2_UC_PARAM) != tf_readwrite){
      tf_error("PORT2 should  be a R/W Param\n");
    }
    if(tf_typep(PLI_PORT3_UC_PARAM) != tf_readwrite){
      tf_error("PORT3 should  be a R/W Param\n");
    }
    break;

  case PLI_CASE_UC_READ_TASK:
    if(nump != PLI_READ_PARAM_COUNT){
      tf_error("Parameters should be 2");
    }
    if(tf_typep(PLI_ADDRESS_READ_PARAM) == tf_nullparam){
      tf_error("READ Address cannot be a Null Param\n");
    }
    if(tf_typep(PLI_DATA_READ_PARAM) != tf_readwrite){
      tf_error("READ DATA  should  be a R/W Param\n");
    }

    break;

  case PLI_CASE_UC_WRITE_TASK:
    if(nump != PLI_WRITE_PARAM_COUNT){
      tf_error("Parameters should be 2");
    }
    if(tf_typep(PLI_ADDRESS_WRITE_PARAM) == tf_nullparam){
      tf_error("WRITE Address cannot be a Null Param\n");
    }
    if(tf_typep(PLI_DATA_WRITE_PARAM) == tf_nullparam){
      tf_error("WRITE DATA  should not be a NULL Param\n");
    }

    break;
  }
}

int ucCall_tf(int data , int reason)
{
  int nump;
  nump = tf_nump();
  switch(data){

  case PLI_CASE_UC_8051_TASK:
    if ((pUc8051S = (uc8051S *)malloc(sizeof(uc8051S))) == (uc8051S *)NULL) {
    return 0;
    }
    pUc8051S->clkHandle = acc_handle_tfarg(PLI_CLK_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for Clk");
      return 0;
    }
    pUc8051S->rstHandle = acc_handle_tfarg(PLI_RST_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for RST");
      return 0;
    }

    pUc8051S->eaHandle = acc_handle_tfarg(PLI_EA_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for EA");
      return 0;
    }
    pUc8051S->psenHandle = acc_handle_tfarg(PLI_PSEN_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for PSEN");
      return 0;
    }
    pUc8051S->aleHandle = acc_handle_tfarg(PLI_ALE_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for ALE");
      return 0;
    }
    pUc8051S->port0Handle = acc_handle_tfarg(PLI_PORT0_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for Port0");
      return 0;
    }
    pUc8051S->port1Handle = acc_handle_tfarg(PLI_PORT1_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for Port1");
      return 0;
    }
    pUc8051S->port2Handle = acc_handle_tfarg(PLI_PORT2_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for PORT2");
      return 0;
    }

    pUc8051S->port3Handle = acc_handle_tfarg(PLI_PORT3_UC_PARAM);
    if(acc_error_flag){
      io_printf("could'nt get Handle for Port3");
      return 0;
    }
    if(!vclSignalAddRoutine()){
      io_printf("Addition of Specific Signal in the Verilog Kernel Database
failed");
    }
    pUc8051S->tfInstance = tf_getinstance();
    initUc();
    ucInitLL();
    break;
  case PLI_CASE_UC_READ_TASK:
    gUcAddress = tf_getp(PLI_ADDRESS_READ_PARAM);
    gReadDataHandle = acc_handle_tfarg(PLI_DATA_READ_PARAM);
    gRD_ = 1;
    gWR_ = 0;
    scheduleTask();
    break;
  case PLI_CASE_UC_WRITE_TASK:
    gUcAddress = tf_getp(PLI_ADDRESS_WRITE_PARAM);
    gWriteData = tf_getp(PLI_DATA_WRITE_PARAM);
    gWR_ = 1;
    gRD_ = 0;
    scheduleTask();
    break;
  }
}

int ucMisc_tf(int data , int reason)
{
  switch(reason){
  case reason_endofcompile:
   // io_printf("called from misctf- Reason End Of Compile \n");
    break;
  case reason_synch:
    ucSynchronize();
    break;
  default:
  //  io_printf("default Misctf\n");
    break;
  }

}

static int vclSignalAddRoutine()
{
userVclDataS *pUserVclDataS;

  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_CLK;
  acc_vcl_add(pUc8051S->clkHandle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);

  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_RST;
  acc_vcl_add(pUc8051S->rstHandle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);

  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_EA;
  acc_vcl_add(pUc8051S->eaHandle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);

  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_PSEN;
  acc_vcl_add(pUc8051S->psenHandle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);

  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_ALE;
  acc_vcl_add(pUc8051S->aleHandle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);



  if ((pUserVclDataS = (userVclDataS *)malloc(sizeof(userVclDataS))) ==
(userVclDataS *)NULL) {
    return 0;
  }
  pUserVclDataS->pUc8051S = pUc8051S;
  pUserVclDataS->id = VCL_ID_PORT3;
  acc_vcl_add(pUc8051S->port3Handle, ucConsumerRoutine, (char *)pUserVclDataS,
    vcl_verilog_logic);


}

static int ucConsumerRoutine(p_vc_record pVcRecord)
{

userVclDataS *pUserVclDataS;

  pUserVclDataS = (userVclDataS *)pVcRecord->user_data;
  pUc8051S = (uc8051S *)pUserVclDataS->pUc8051S;

  switch (pUserVclDataS->id) {
    case VCL_ID_CLK:
      if ((pVcRecord->out_value.logic_value == vcl1) &&
          (pUc8051S->clkVal == vcl0)) {
        pUc8051S->clkTriggered = 1;
      }
      pUc8051S->clkVal = pVcRecord->out_value.logic_value;
      break;
    case VCL_ID_RST:
      pUc8051S->rstVal = pVcRecord->out_value.logic_value;
      pUc8051S->rstTriggered = 1;
      break;
    case VCL_ID_EA:
      pUc8051S->eaVal = pVcRecord->out_value.logic_value;
      pUc8051S->eaTriggered = 1;
      break;
    case VCL_ID_PSEN:
      pUc8051S->psenVal = pVcRecord->out_value.logic_value;
      pUc8051S->psenTriggered = 1;
      break;
    case VCL_ID_ALE:
      if ((pVcRecord->out_value.logic_value == vcl1) &&
          (pUc8051S->aleVal == vcl0)) {
        pUc8051S->aleTriggered = 1;
      }
      pUc8051S->aleVal = pVcRecord->out_value.logic_value;

      break;
    case VCL_ID_PORT3:
      pUc8051S->port3Val = pVcRecord->out_value.logic_value;
      pUc8051S->port3Triggered = 1;
      break;
  }


  tf_isynchronize(pUc8051S->tfInstance);

}

static void ucSynchronize()
{
  static int i=0;
  s_acc_value  sVal;

    if(pUc8051S->clkTriggered){
      callMainFunc();
//      ucPrintMsg(pUc8051S,"CLK Triggered \n ");
      pUc8051S->clkTriggered = 0;
    }
    if(pUc8051S->rstTriggered){
    //  ucPrintMsg(pUc8051S,"RST Triggered \n ");
      pUc8051S->rstTriggered = 0;
    }
    if(pUc8051S->eaTriggered){
     // ucPrintMsg(pUc8051S,"EA Triggered \n ");
      pUc8051S->eaTriggered = 0;
    }

    if(pUc8051S->psenTriggered){
      //ucPrintMsg(pUc8051S,"PSEN Triggered \n ");
      pUc8051S->psenTriggered = 0;
    }
    if(pUc8051S->aleTriggered){
     // u//cPrintMsg(pUc8051S,"ALE Triggered \n ");
      pUc8051S->aleTriggered = 0;
    }
    if(pUc8051S->port3Triggered){
     // ucPrintMsg(pUc8051S,"PORT3 Triggered \n ");
      pUc8051S->port3Triggered = 0;
    }
}

File: uc8051.c

 
#include 
#include "veriuser.h"
#include "acc_user.h"
#define __GLOBALVAR__
#include "uc.h"

void initUc() {
pUc8051S->signalId             = 0;
pUc8051S->clkVal               = vcl0;
pUc8051S->clkTriggered         = 0;
pUc8051S->rstVal               = vcl0;
pUc8051S->rstTriggered         = 0;
pUc8051S->eaVal                = vcl0;
pUc8051S->eaTriggered          = 0;
pUc8051S->psenVal              = vcl0;
pUc8051S->psenTriggered        = 0;
pUc8051S->aleVal               = vcl0;
pUc8051S->aleTriggered         = 0;
pUc8051S->port3Val             = 0;
pUc8051S->port3Triggered       = 0;
pUc8051S->ucAddress            = 0;
pUc8051S->aleClkCount          = 0;
pUc8051S->xClkCount            = 0;
pUc8051S->rdwrClkCount         = 0;
pUc8051S->ucMainState          = UC_MAIN_STATE_IDLE;
pUc8051S->RD_                  = 0;
pUc8051S->WR_                  = 0;
if(pFirst){
  removeTask();
}

}

void ucInitLL(void)
{
  pFirst = pLast = pMoving = (infoListBufferS *) NULL;
}

infoListBufferS *allocateLLBuffer(void)
{
  infoListBufferS *pTemp;
  if ((pTemp = (infoListBufferS *)malloc(sizeof(infoListBufferS))) ==
    (infoListBufferS *)NULL) {
    ucPrintMsg(pUc8051S,"Out of memory!\n ");
    return 0;
  }
  pTemp->next = pTemp->prev = (infoListBufferS *) NULL;
  return(pTemp);

}

void scheduleTask(void)
{
  pCurrent = allocateLLBuffer();
  pCurrent->ucAddress = gUcAddress;
  if(gRD_){
    pCurrent->RD_ = 1;
    pCurrent->WR_ = 0;
    pCurrent->readDataHandle = gReadDataHandle;
  }else{
    pCurrent->WR_ = 1;
    pCurrent->RD_ = 0;
    pCurrent->writeData = gWriteData;
  }

  if(!pFirst){
    pFirst = pLast = pMoving = pCurrent;
    pFirst->next = pFirst->prev = (infoListBufferS *) NULL;
  }else{
    pMoving             = pLast;
    pMoving->next       = pCurrent;
    pMoving->next->prev = pMoving;
    pMoving->next->next = (infoListBufferS *) NULL;
    pMoving             = pMoving->next;
    pLast               = pMoving;
  }
}

void removeTask(void)
{
  if(pFirst == pLast){
    pFirst = pLast = pMoving = pCurrent = (infoListBufferS *) NULL;
  }else{
    pMoving             = pFirst;
    pFirst              = pFirst->next;
    pFirst->prev        = (infoListBufferS *) NULL;
    free(pMoving);
  }
}

void processTask(void)
{
    pUc8051S->RD_       = pFirst->RD_;
    pUc8051S->WR_       = pFirst->WR_;
    pUc8051S->ucAddress = pFirst->ucAddress;
    pUc8051S->writeData = pFirst->writeData;
    if(pFirst->RD_){
      pUc8051S->readDataHandle = pFirst->readDataHandle;
    }
}

void callMainFunc(void)
{
 ucMainStateMachine();
}
static void ucMainStateMachine()
{
UCHAR  readData;
  switch(pUc8051S->ucMainState){
  case UC_MAIN_STATE_IDLE:
    if(pFirst){
      processTask();
      if(pUc8051S->RD_ || pUc8051S->WR_){
        pUc8051S->ucMainState = UC_MAIN_STATE_SEND_ALE;
      }
    }
    break;
  case UC_MAIN_STATE_SEND_ALE:
    driveSignal(pUc8051S->aleHandle,(UCHAR) vcl1);
    pUc8051S->ucMainState = UC_MAIN_STATE_SEND_ADDRESS;
    break;
  case UC_MAIN_STATE_SEND_ADDRESS:
    driveVectorSignal(pUc8051S->port0Handle,pUc8051S->ucAddress );
    pUc8051S->ucMainState = UC_MAIN_STATE_SENT_ALE;
    break;
  case UC_MAIN_STATE_SENT_ALE:
    pUc8051S->xClkCount++;
    if(pUc8051S->xClkCount == CLOCK_WIDTH_OF_XXX_AFTER_ALE){
       pUc8051S->ucMainState = UC_MAIN_STATE_SENT_ADDRESS;
       driveVectorScalarSignal(pUc8051S->port0Handle,vclX );
       pUc8051S->xClkCount = 0;
    }else{
      driveSignal(pUc8051S->aleHandle,vcl0);
      //driveVectorScalarSignal(pUc8051S->port0Handle,vclX );
    }
    break;
  case UC_MAIN_STATE_SENT_ADDRESS:
    pUc8051S->rdwrClkCount++;
    if(pUc8051S->RD_){
      driveVectorSignal(pUc8051S->port3Handle,0x80);
    }else{
      if(pUc8051S->WR_){
        driveVectorSignal(pUc8051S->port3Handle,0x40);
      }
    }
    pUc8051S->ucMainState = UC_MAIN_STATE_WAIT_FOR_RDWR;

    break;
  case UC_MAIN_STATE_WAIT_FOR_RDWR:

   pUc8051S->rdwrClkCount++;
   if(pUc8051S->RD_){
      readData = (UCHAR) readVectorSignal(pUc8051S->port0Handle);
      driveVectorSignal(pUc8051S->readDataHandle,readData);
      pUc8051S->RD_ = 0;
    }else{
      if(pUc8051S->WR_){
        driveVectorSignal(pUc8051S->port0Handle,pUc8051S->writeData);
        pUc8051S->WR_ = 0;
      }
    }
    if(pUc8051S->rdwrClkCount == CLOCK_WIDTH_OF_RDWR){
       pUc8051S->ucMainState = UC_MAIN_STATE_SENT_RDWR;
       driveVectorSignal(pUc8051S->port3Handle,vcl0);
       pUc8051S->rdwrClkCount = 0;
    }
    break;
  case UC_MAIN_STATE_SENT_RDWR:
      driveVectorScalarSignal(pUc8051S->port0Handle,vclZ);
      pUc8051S->ucMainState = UC_MAIN_STATE_IDLE;
      initUc();
    break;
  }
}

void driveSignal(handle driveHandle,UCHAR driveVal)
{
  s_acc_value accVal;
  s_setval_delay accDelay;

  accDelay.model= accTransportDelay;
  accDelay.time.type = accRealTime;
  accDelay.time.real =   (double) 0.1;
  accVal.format = accScalarVal;
  accVal.value.scalar =  driveVal;
  acc_set_value(driveHandle,&accVal,&accDelay);
}

void driveVectorSignal(handle driveHandle,UCHAR driveVal)
{
  s_acc_value accVal;
  s_setval_delay accDelay;

  accDelay.model= accTransportDelay;
  accDelay.time.type = accRealTime;
  accDelay.time.real =   (double) 0.1;
  accVal.format = accIntVal;
  accVal.value.integer =  driveVal;
  acc_set_value(driveHandle,&accVal,&accDelay);
}

void driveVectorScalarSignal(handle driveHandle,UCHAR driveVal)
{
  s_acc_value accVal;
  s_setval_delay accDelay;
  s_acc_vecval pVecVal[8];
  UCHAR driveBit;
  UCHAR mod=1,XORZ=0;
  int i;
 // io_printf("Drive Val = %d \n",driveVal);
 // io_printf("DriveBits are ");
  accVal.value.vector =  (p_acc_vecval) malloc(8 * sizeof(s_acc_vecval));
  for( i = 0; i< 8;i++){
    driveBit = (driveVal & mod) >> i;
    mod <<=1;
    if(driveVal == vclX){
        accVal.value.vector[i].aval = 1;
        accVal.value.vector[i].bval = 1;
        XORZ = 1;
    }
    if(driveVal == vclZ){
        accVal.value.vector[i].aval = 0;
        accVal.value.vector[i].bval = 1;
        XORZ = 1;
    }
    if(!XORZ){
      if(driveBit == 0 ){
        accVal.value.vector[i].aval = 0;
        accVal.value.vector[i].bval = 0;
      }
      if(driveBit == 1){
        accVal.value.vector[i].aval = 1;
        accVal.value.vector[i].bval = 0;
      }
    }
    XORZ = 0;
  ////  io_printf("%d",driveBit);
  }

  accDelay.model= accTransportDelay;
  accDelay.time.type = accRealTime;
  accDelay.time.real =   (double) 0.1;
  accVal.format = accVectorVal;
  //accVal.value.vector =  driveVal;
  acc_set_value(driveHandle,&accVal,&accDelay);

}


int readVectorSignal1(handle driveHandle)
{
int size;
s_acc_value value;
int index1,min_size;
static char table[4]={'0','1','z','x'};
static char outstring[33];

  io_printf("value of %s is ",acc_fetch_name(driveHandle));
  size = ((acc_fetch_size(driveHandle) - 1)/32 ) + 1;
  value.format = accVectorVal;
  value.value.vector = (p_acc_vecval)malloc(size * sizeof(s_acc_vecval));

  (void)acc_fetch_value(driveHandle,"%%",&value);
  for(index1 = size - 1; index1 >= 0; index1--){
    register int index2;
    int abits = value.value.vector[index1].aval;
    int bbits = value.value.vector[index1].bval;
    if(index1 == size -1){
      min_size = (acc_fetch_size(driveHandle) % 32);
      if(!min_size){
        min_size = 32;
      }
    }else{
      min_size = 32;
    }
    outstring[min_size] = '\0';
    min_size--;
    outstring[min_size] = table[((bbits & 1) << 1) | (abits & 1)];
    abits >>= 1;
    for(index2 = min_size - 1; index2 >= 0; index2--){
      abits >>= 1;
      bbits >>= 1;
    }
    io_printf("%s",outstring);
  }
  io_printf("\n");
  return(0);
}
int readVectorSignal2(handle driveHandle)
{
int size;
s_acc_value value;
int index1,min_size;
static char table[4]={'p','1','z','x'};
static char outstring[33];
  io_printf("Time: %s :", tf_strgettime());

  size = ((acc_fetch_size(driveHandle) - 1) % 32 ) + 1;
  io_printf("value of %s(size = %d) is ",acc_fetch_name(driveHandle),size);
  value.format = accVectorVal;
  value.value.vector = (p_acc_vecval)malloc(size * sizeof(s_acc_vecval));

  (void)acc_fetch_value(driveHandle,"%%",&value);
  for(index1 = size - 1; index1 >= 0; index1--){
    register int index2;
    register int abits = value.value.vector[index1].aval;
    register int bbits = value.value.vector[index1].bval;
    if(index1 == size -1){
      min_size = (acc_fetch_size(driveHandle) % 32);
      io_printf("minsize = %d ",min_size);
      if(!min_size){
        min_size = 32;
      }
    }else{
   //   min_size = 32;
    }
    io_printf("\n finminsize = %d ",min_size);
    outstring[min_size] = '\0';
    min_size--;
    outstring[min_size] = table[((bbits & 1) << 1) | (abits & 1)];
    io_printf("abits = %d bbits=%d table: %c",abits,bbits,outstring[min_size]);
   /* abits >>= 1;
    for(index2 = min_size - 1; index2 >= 0; index2--){
      abits >>= 1;
      bbits >>= 1;
    } */
    io_printf("%s",outstring);
  }
  io_printf("\n");
  return(0);
}

int readVectorSignal(handle driveHandle)
{
s_acc_value value;
  value.format = accDecStrVal;
  (void)acc_fetch_value(driveHandle,"%%",&value);
  return(atoi(value.value.str));
}

static void ucPrintMsg(uc8051S *pUc8051S, char *msg)
{
  io_printf("Time: %s UC 8051 : %s",
    tf_strgettime(),msg);
}

File: uc.v


module uc8051();

reg  [7:0] port0, port1,port2,port3;
reg [15:0] MC_ADDR;
reg        PSEN;
reg        ALE;
reg        EA;
reg        RST;
wire       CE_;
reg  [7:0] dataRead;
reg        clk;

initial begin
   clk   = 0;
   RST   = 0;
   forever #80 clk = ~clk;
end

initial begin
   $dumpvars;
   $dumpfile("usbtester.vcd");
   $uc8051(clk,RST,EA,PSEN,ALE,port0,port1,port2,port3);
#400
   $display("started");
#10 
   $ucWrite(8'h23,8'h21);
   $display("Middle");
   $ucRead(0,dataRead);
#10
   $ucWrite(8'h25,8'h31);
   $display("end");

end
endmodule


Vineyard Research Inc.