在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的实现相关推荐

  1. Iverilog 源码分析 -- VPI的实现

    在IVerilog中VVP可以通过-m或者-M制定需要加载的模块,本文介绍一下VPI的模块工作机制. 每个模块通过vpip_load_module来加载指定的动态链接库, 然后在动态链接库里面找到&q ...

  2. Iverilog 源码分析 -- VCD的实现机制

    VCD是Verilog LRM中定义的, 本文介绍Iverilog 基于VPI机制的VCD的实现过程.在vpi目录下面, 定义了不同模块加载的实现.如下显示了Iverilog下面已经支持的实现: vo ...

  3. Hhadoop-2.7.0中HDFS写文件源码分析(二):客户端实现(1)

    一.综述 HDFS写文件是整个Hadoop中最为复杂的流程之一,它涉及到HDFS中NameNode.DataNode.DFSClient等众多角色的分工与合作. 首先上一段代码,客户端是如何写文件的: ...

  4. djangorestframework源码分析1:generics中的view执行流程

    djangorestframework源码分析 本文环境python3.5.2,djangorestframework (3.5.1)系列 djangorestframework源码分析-generi ...

  5. 实际测试例子+源码分析的方式解剖MyBatis缓存的概念

    前言: 前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ 欢迎工作一到五年的Java工程师朋友们加入Java架构开发:79 ...

  6. SpringMVC之源码分析--ViewResolver(四)

    概述 本章继续学习ViewResolver另一个实现类ContentNegotiatingViewResolver解析器,该类的主要作用是根据同一请求的某些策略,选择对应的View进行渲染.可以把Co ...

  7. AbstractBeanDefinition:lenientConstructorResolution属性源码分析

    版本:spring-framework-4.1 一概述 在看AbstractBeanDefinition源码时,注意到lenientConstructorResolution属性有诸多不疑,现在通过示 ...

  8. 14.QueuedConnection和BlockingQueuedConnection连接方式源码分析

    QT信号槽直连时的时序和信号槽的连接方式已经在前面的文章中分析过了,见https://blog.csdn.net/Master_Cui/article/details/109011425和https: ...

  9. SpringMVC之源码分析--LocaleResolver和ThemeResolver应用

    概述 以上分析了Spring MVC的LocaleResolver和ThemeResolver两个策略解析器,在实际项目中很少使用,尤其是ThemeResolver,花精力去分析他们,主要是为了系统的 ...

最新文章

  1. 使用python调用zabbix接口截取监控图并生成Word文档
  2. 厉害了!Antiilatency推出移动位置追踪器!
  3. Phalcon控制器
  4. java中的stack类和C++中的stack类的区别
  5. 路由器和交换机分别起什么作用,它们之间有什么区别?
  6. 计算机学院志愿公益活动,计算机学院开展学雷锋主题公益活动
  7. Acoustic Echo Cancellation (AEC) 回音消除技术探索
  8. atom系列服务器,这才叫四两拨千斤!Atom将登陆服务器
  9. Struts2之类型转换器
  10. java用不起_Java,泛型不起作用
  11. android x5内核 下载地址,X浏览器-X5内核版本
  12. 数据挖掘 文本分类(三)本地文档分词再保存到本地
  13. 英语字母演变——wsdchong
  14. 技术人员谈管理之项目风险规避
  15. video在iPhone浏览器上播放没有声音
  16. c++ leetcode 500-600
  17. toLua++使用(转)
  18. MIMIC III数据集详细介绍
  19. 浅谈:网站到底要不要备案?
  20. C++控制台打飞机小游戏

热门文章

  1. 物联网的常用几种协议
  2. android 设置状态栏全透明,背景延伸到状态栏
  3. 移动硬盘文件或目录损坏且无法读取解决方法
  4. 如何干净地删除labview
  5. 静脉输液的安全管理PPT模板
  6. 条码扫描枪----针对MS-3扫码器的工作原理
  7. 单核处理器、多核处理器、多处理器与多线程编程,cpu调度
  8. 实现分页列表跨页全选
  9. Seetaface 03 Seetaface python版 win10 vs2015编译
  10. GBase 8a 监控配置