日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Iverilog源码分析 -- VPI scope的实现

發布時間:2024/1/1 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 … end之間的語句是串行執行的;

    begin: scope_namedeclaration;state1state2...stateNend
  • vpiNamedFork
    fork … join之間的語句是并行執行的;

    fork: scope_namedeclaration;state1state2...stateNjoin
  • vpiGenScope

    1 、generate-for語句必需用genvar關鍵字定義for的索引變量;
    2、 for的內容必須用begin…end塊包起來,哪怕只有一句;
    3、 begin…end塊必須起個名字;

    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

在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的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。