|
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.
|