Iverilog源码分析 -- VPI scope的实现
在Verilog里面采用module/endmodule 來組成整個design的hierarchy結構, 比如, 如下的代碼:
會產生如下的hierarchy結構:
目前在Verilog的LRM, 有如下幾種scope類型:
- Module
- Task
- Funcion
- Named block
在IVerilog 里面, 定義了如下6中scope以及相關的定義如下:
-
vpiModule
-
vpiTask
-
vpiFunction
上述3中, 比較常見, 忽略例子; -
vpiNamedBegin
begin: scope_namedeclaration;state1state2...stateNend
begin … end之間的語句是串行執行的; -
vpiNamedFork
fork: scope_namedeclaration;state1state2...stateNjoin
fork … join之間的語句是并行執行的; -
vpiGenScope
1 、generate-for語句必需用genvar關鍵字定義for的索引變量;
module gray2bin1 (bin, gray); parameter SIZE = 8; // this module is parameterizable output [SIZE-1:0] bin; input [SIZE-1:0] gray; genvar i;generate for(i=0; i<SIZE; i=i+1)begin:bitassign bin[i] = ^gray[SIZE-1:i];end endgenerate endmodule
2、 for的內容必須用begin…end塊包起來,哪怕只有一句;
3、 begin…end塊必須起個名字;
在vvp/vpi_scope.cc里面, 對于上述6中類型的scope, 每一種定義了一個class, 繼承自__vpiScope積累。
在Iverilog的整個流程里面, IVerilog負責產生一個xx.vvp 文件, 這是一個網表結構的文件, vvp程序會讀取該文件, 產生vvp內存的信號;
從*.v scope的產生
在verilog .v文件里面,每次碰到一個scope, 在parser.y文件定義了每一種label對應的處理函數:
void compile_scope_decl(char*label, char*type, char*name, char*tname,char*parent, long file_idx, long lineno,long def_file_idx, long def_lineno, long is_cell) {count_vpi_scopes += 1;char vec_type;char sign_flag;unsigned wid;__vpiScope*scope;if (strcmp(type,"module") == 0) {scope = new vpiScopeModule(name, tname);} else if ( sscanf(type, "function.vec%c.%c%u", &vec_type, &sign_flag, &wid) == 3 ) {int type_code;if (sign_flag=='s') {type_code = vpiSizedSignedFunc;} else if (sign_flag=='u') {type_code = vpiSizedFunc;} else if (sign_flag=='i') {type_code = vpiIntFunc;} else {assert(0);type_code = vpiSizedFunc;}vvp_bit4_t init_val = vec_type == '4' ? BIT4_X : BIT4_0;scope = new vpiScopeFunction(name, tname, false, type_code, wid, init_val);} else if ( sscanf(type, "autofunction.vec%c.%c%u", &vec_type, &sign_flag, &wid) == 3 ) {int type_code;switch (sign_flag) {case 's':type_code = vpiSizedSignedFunc;break;case 'u':type_code = vpiSizedFunc;break;default:assert(0);type_code = vpiSizedFunc;break;}vvp_bit4_t init_val = vec_type == '4' ? BIT4_X : BIT4_0;scope = new vpiScopeFunction(name, tname, true, type_code, wid, init_val);} else if (strcmp(type,"function.obj") == 0) {scope = new vpiScopeFunction(name, tname, false, vpiSizedFunc, 0, BIT4_0);} else if (strcmp(type,"autofunction.obj") == 0) {scope = new vpiScopeFunction(name, tname, true, vpiSizedFunc, 0, BIT4_0);} else if (strcmp(type,"function.real") == 0) {scope = new vpiScopeFunction(name, tname, false, vpiRealFunc, 0, BIT4_0);} else if (strcmp(type,"autofunction.real") == 0) {scope = new vpiScopeFunction(name, tname, true, vpiRealFunc, 0, BIT4_0);} else if (strcmp(type,"function.str") == 0) {scope = new vpiScopeFunction(name, tname, false, vpiOtherFunc, 0, BIT4_0);} else if (strcmp(type,"autofunction.str") == 0) {scope = new vpiScopeFunction(name, tname, true, vpiOtherFunc, 0, BIT4_0);} else if (strcmp(type,"function.void") == 0) {scope = new vpiScopeFunction(name, tname, false, vpiOtherFunc, 0, BIT4_0);} else if (strcmp(type,"autofunction.void") == 0) {scope = new vpiScopeFunction(name, tname, true, vpiOtherFunc, 0, BIT4_0);} else if (strcmp(type,"task") == 0) {scope = new vpiScopeTask(name, tname);} else if (strcmp(type,"autotask") == 0) {scope = new vpiScopeTaskAuto(name, tname);} else if (strcmp(type,"fork") == 0) {scope = new vpiScopeFork(name, tname);} else if (strcmp(type,"autofork") == 0) {scope = new vpiScopeForkAuto(name, tname);} else if (strcmp(type,"begin") == 0) {scope = new vpiScopeBegin(name, tname);} else if (strcmp(type,"autobegin") == 0) {scope = new vpiScopeBeginAuto(name, tname);} else if (strcmp(type,"generate") == 0) {scope = new vpiScopeGenerate(name, tname);} else if (strcmp(type,"package") == 0) {scope = new vpiScopePackage(name, tname);} else if (strcmp(type,"class") == 0) {scope = new vpiScopeClass(name, tname);} else {scope = new vpiScopeModule(name, tname);assert(0);}scope->file_idx = (unsigned) file_idx;scope->lineno = (unsigned) lineno;scope->def_file_idx = (unsigned) def_file_idx;scope->def_lineno = (unsigned) def_lineno;scope->item = 0;scope->nitem = 0;scope->live_contexts = 0;scope->free_contexts = 0;if (is_cell) scope->is_cell = true;else scope->is_cell = false;current_scope = scope;compile_vpi_symbol(label, scope);free(label);free(type);delete[] name;delete[] tname;if (parent) {static vpiHandle obj;compile_vpi_lookup(&obj, parent);assert(obj);__vpiScope*sp = dynamic_cast<__vpiScope*>(obj);vpip_attach_to_scope(sp, scope);scope->scope = dynamic_cast<__vpiScope*>(obj);/* Inherit time units and precision from the parent scope. */scope->time_units = sp->time_units;scope->time_precision = sp->time_precision;} else {scope->scope = 0x0;vpip_root_table.push_back(scope);/* Root scopes inherit time_units and precision from thesystem precision. */scope->time_units = vpip_get_time_precision();scope->time_precision = vpip_get_time_precision();} }添加scope的自對象
current_scope是一個全局變量, 指到當前正在處理的scope:
__vpiScope* vpip_peek_current_scope(void) {return current_scope; } void vpip_attach_to_scope(__vpiScope*scope, vpiHandle obj) {assert(scope);scope->intern.push_back(obj); }總結
以上是生活随笔為你收集整理的Iverilog源码分析 -- VPI scope的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度ueditor自适应(编辑器自适应页
- 下一篇: 应用网站图标 下载网站图标