
(2)定義自己的結(jié)構(gòu)體,這一點主要是為了編程方便,例如輸入輸出信號對應的變量在各函數(shù)中基本上都會用到,可以把這些變量定義成一個結(jié)構(gòu),便于參數(shù)傳遞。例如,可以把3.1節(jié)的sim.vhd輸入輸出信號對應的變量定義成結(jié)構(gòu):
typedef struct {
driverID out1;
driverID out2;
signallID in1;
signaled in2;
}PorStruct;
其中,driverID表示輸出信號對應的變量;signalID表示輸入信號對應的變量。這樣,這里定義的變量out1、out2、in1、in2就分別與sim.vhd中的信號out1、out2、in1、in2相對應。
(3)編寫初始化函數(shù)
初始化函數(shù)的定義為:
init_func(mtiReginoIdT region,char *param,mtiInterfaceListT *generics,mtiInterfaceListT *ports)
各參數(shù)的仿義可以參閱modelsim用戶手冊。
下面結(jié)合上面給出的初始化函數(shù)要完成的任務進行詳細說明。
a.初始化全局變量(略)
b.設(shè)置VHDL輸入輸出信號與C程序變量的對應關(guān)系。這是通過調(diào)用mti_FindPort函數(shù)實現(xiàn)的。mti_FindPort函數(shù)定義為:
mtiSignalIdT mti_FindPort(mtiInterfaceListT *list,char *name);
例如,定義輸入輸出信號對應的結(jié)構(gòu)ip:
PortStruct ip;
就可以用:
ip.in1=mti_FindPort(ports,“in1”);
來實現(xiàn)輸入信號in1與變量in1的對應關(guān)系。
對輸出信號來說,它的目的是產(chǎn)生驅(qū)動。因此,這些變量(out1和out2)除了要找到對應的輸出信號外,還要驅(qū)動這些信號。對信號的驅(qū)動可以通過調(diào)用mti_CrateDriver函數(shù)來實現(xiàn)。該函數(shù)的定義為:
mtiDriverIdT mti_CreateDriver(mtiSignalIdT sig);
由于這些變量一般只用于對外驅(qū)動,因此可以簡單寫成下面的形式:
ip.out1 = mti+CreateDriver(mti_FindPort(ports,“out1”));
c.調(diào)用mti_ScheduleDriver函數(shù),設(shè)置輸出信號的初始狀態(tài)。mti_ScheduleDriver函數(shù)的定義為:
void mti_ScheduleDriver(mtiDriverIdT driver,long value,mtiDelayT delay,mtiDriverModeT mode);
其中,driver是輸出信號對應的變量名,如ip.out1和ip.out2;value是要設(shè)置(驅(qū)動)的值,如高電平('1',對應value為3)、低電平('0',對應value為2)、高阻('Z',對應value為4)、未賦值('U',對應value為0)等等;delay是從當前時間開始到把信號驅(qū)動成給定值(value)的等待時間,單位與仿真器當前使用的最小時間單位相同;mode為信號模式,有兩個值可供選擇:MTI_INERTIAL或者是MTI_TRANSPORT,分別對應于標準VHDL語言的INERTIAL和TRANSPORT。例如,設(shè)置信號out1的初始狀態(tài)為低電平:
mti_ScheduleDriver(ip.out1,2,0,MTI_INERTIAL);
d.設(shè)置在仿真器重新仿真(運行命令restart)或退出仿真(運行命令quit-sim)等情況下調(diào)用的函數(shù)。這一部分主要是為了釋放內(nèi)存或者保存當前狀態(tài)等。以restart為例,假設(shè)在程序中用malloc申請了存儲空間buf,在仿真器“restart”時需要釋放,就可以用以下的函數(shù)調(diào)用來注冊:
mti_AddRestartCB(free,buf);
注冊后,當仿真器運行命令restart時就會調(diào)用free(buf)。
其它一些函數(shù)可以參照modelsim的用戶手冊,這里不再詳述。
e.設(shè)置敏感表,給出在某些信號發(fā)生某些變化時(如時鐘上升沿等)執(zhí)行的函數(shù)。例如,在輸入信號in1發(fā)生變化時,要執(zhí)行函數(shù)in1_change(in1_change為用戶定義好的函數(shù)),可以這樣定義:
processed proc;
proc=mti_CreateProcess ("P_in 1 change",in1_change,&ip);
mti_Sensitize(proc,ip.in1,MTI_EVENT);
也就是說,先創(chuàng)建進程,然后設(shè)置敏感表。當滿足敏感表的條件時,仿真器就會執(zhí)行該進程。mti_CreateProcess函數(shù)的定義為:
mtiProcessIdT mti_CreateProcess(char *name,mtiVoidFuncPtrT func,void *Param);
其中,name是將要在仿真器窗口中顯示的名稱;func是要執(zhí)行的函數(shù);后面的param是要傳給func的參數(shù)。mti_Sensitize的定義為:
void mti_Sensitize(mtiProcessIdT proc,mtiSignalIdT sig,mtiProcessTriggerT when);
其中,proc為調(diào)用mti_CreateProcess的返回值;sig為信號名,即VHDL文件的輸入輸出信號對應于C程序的變量;when可以取MTI_EVENT或者MTI_ACTIVE兩種值。
3.3 C程序的編譯
對Windows平臺,采用的編譯器是Microsoft Visual C++,并用如下的命令進行編譯:
cl -c -I<install_dir>app.c
link -dll -export:<C_init_function>app.obj <install_dir>modeltech.lib
上面的<install_dir>是modelsim的安裝目錄,<C_init_function>是C程序的初始化函數(shù)名,如我們給出的sim.c的sim_init。編譯之后就可以生成.dll文件。
仿真向量是用C語言還是用HDL直接產(chǎn)生,要視設(shè)計者的應用而定,選取最簡單的方式。在大多數(shù)情況下,用C語言和HDL聯(lián)合生成測試向量會更方便些。





