You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在Verilog顶层模块中实例化子目录内的模块

嘿,这个问题我之前做项目的时候也碰到过,其实有几种实用的方法能解决,具体选哪种要看你用的EDA工具和项目结构,我给你详细说说:

方法1:修改编译脚本/工程设置(最推荐)

这是业界最常用的方式,能让你的Verilog代码保持干净,不用硬编码路径,移植性也更好。不同工具的操作略有不同:

  • ModelSim/QuestaSim:在编译.do脚本里,先添加子目录到包含路径,再编译子目录里的文件:
    # 添加子目录到包含路径
    +incdir+./your_subdir
    # 编译子目录下的所有Verilog文件
    vlog ./your_subdir/*.v
    # 再编译顶层模块
    vlog top.v
    
    或者用-y选项指定模块搜索路径,工具会自动在该目录下查找你实例化的模块:
    vlog -y ./your_subdir top.v
    
  • Vivado:可以在Tcl脚本里直接读取子目录的文件:
    read_verilog ./your_subdir/*.v
    read_verilog top.v
    
    也可以在图形界面右键工程→SettingsIP→Verilog Include Directories,添加子目录后再把subdir里的文件加入工程。
  • Quartus Prime:在工程界面的Files标签下点击Add Files,选择子目录里的Verilog文件;或者在SettingsCompiler Settings→Include Directories里添加子目录路径。
方法2:使用`include指令(小项目临时用用)

如果是小项目不想折腾脚本,也可以直接在顶层模块里用include把子目录的模块文件包含进来。比如子目录叫sub_modules,里面有my_module.v`,顶层代码可以这么写:

// 先包含子目录里的模块文件
`include "./sub_modules/my_module.v"

module top(
    // 顶层端口定义
);
    // 实例化子目录里的模块
    my_module u_my_module(
        .clk(clk),
        .rst_n(rst_n),
        // 其他端口连接
    );
endmodule

不过这种方式有几个坑要注意:

  • 如果子目录里的文件还`include了其他文件,路径要相对于顶层模块所在的目录,不然会找不到;
  • 容易出现重复包含问题,建议在被包含的模块文件里加保护宏:
    `ifndef MY_MODULE_V
    `define MY_MODULE_V
    module my_module(...);
        // 模块内容
    endmodule
    `endif
    
  • 大项目不推荐,会让代码耦合度变高,维护起来麻烦。
方法3:工具扩展的路径语法(少用,不通用)

有些EDA工具支持非标准的Verilog语法指定路径,比如Synopsys工具可用-y编译选项指定模块搜索路径,或者在代码里用`define定义路径,但这种方式不通用,换工具可能就失效,除非迫不得已不建议用。

总的来说,优先选方法1,既能保持代码整洁,又方便项目维护。

内容的提问来源于stack exchange,提问作者David

火山引擎 最新活动