利用perl脚本生成基于ncverilog的模块级仿真环境,对于做IP的IC人员来说,可极大减少搭环境的时间。

 概述

以16位乘法器为例,输入有a、b、sign,分别为乘数,被乘数以及符号选择,输出c为运算结果。sign=1计算有符号乘法,sign=0计算无符号乘法,模块名称为MUTI_16X16。

仿真环境基本结构

运行perl脚本,可生成testbench.v、run.f 、testcase.v(激励文件)以及Makefile。

simenv.pl脚本内容

对于一个模块来说,我们只需要定义模块的module 名称、输入信号、输出信号以及相关的地址参数,若有地址,可以WIDTH(n)形式定义n为具体地址,若没有地址可不写,即@addr_array数组为空。

#! /user/bin/perl
    use strict;

#---------------------------------------------------------
# variable define
#---------------------------------------------------------
#--------------------
# Module Name
#--------------------
    my $top_name = "MUTI_16X16";

#--------------------
# Input Collection
#--------------------
    my @in_array = qw(
       [15:0]a
       [15:0]b
       sign
    );

#--------------------
# Output Collection
#--------------------
    my @out_array = qw(
       [31:0]c
       );

#--------------------
# Addr Collection
#--------------------
    my @addr_array = qw(

    );

#---------------------------------------------------------
#*********************************************************
# generate testbench.v files
#*********************************************************
#---------------------------------------------------------
    my $outf0 = "testbench.v";
    if (-e $outf0){
    system("rm -rf $outf0");
    }
    open (OUTFILE0, ">>$outf0");
    print OUTFILE0 "
//----------------------------------
//signals_type declare
//----------------------------------

`timescale 1ns / 1ns

 module test;
\n";

#------------------------
#input declare
#------------------------
  open (OUTFILE0, ">>$outf0");

  foreach my $tbins (@in_array) {

  my $tbins_new = join " " , "reg" ,$tbins;

  print OUTFILE0 " $tbins_new;\n";
}

#--------------------
#newline
#--------------------
  open (OUTFILE0, ">>$outf0");
  print OUTFILE0 "\n";

#------------------------
#output declare
#------------------------
  open (OUTFILE0, ">>$outf0");

  foreach my $tbouts (@out_array) {

  my $tbouts_new = join " " , "wire" ,$tbouts;

  print OUTFILE0 " $tbouts_new;\n";
}

#--------------------
#print head
#--------------------
  open (OUTFILE0, ">>$outf0");
  print OUTFILE0 "
//----------------------------------
//module instance
//----------------------------------
$top_name\n";

#--------------------
#print addr
#--------------------
  open (OUTFILE0, ">>$outf0");
  if(@addr_array > 1){
    foreach my $addr_one (@addr_array){
        if($addr_one eq @addr_array[0]){
          print OUTFILE0 "#(\n  .$addr_one,\n";
        }
        elsif($addr_one eq @addr_array[-1]){
          print OUTFILE0 "  .$addr_one\n)\ntop(\n";
        }
        else{
          print OUTFILE0 "  .$addr_one,\n";
        }
    }
  }
  elsif(@addr_array eq 1){
    print OUTFILE0 "#(\n  .@addr_array[0]\n)\ntop(\n";
  }
  else{
    print OUTFILE0 "top(\n";
  }

#------------------------
#input instance
#------------------------
  open (OUTFILE0, ">>$outf0");

  foreach my $modins (@in_array) {

  if($modins =~ /[[0-9:0-9]][a-zA-Z0-9]/){
      my @tempin = split "]" ,$modins;
      print OUTFILE0 " .$tempin[-1]($tempin[-1]),\n";
  }
  else{
     print OUTFILE0 " .$modins($modins),\n";
  }
}

#--------------------
#newline
#--------------------
  open (OUTFILE0, ">>$outf0");
  print OUTFILE0 "\n";

#------------------------
#output instance
#------------------------
  open (OUTFILE0, ">>$outf0");

  foreach my $modouts (@out_array) {

  if($modouts eq @out_array[-1]){

      if($modouts =~ /[[0-9:0-9]][a-zA-Z0-9]/){
          my @tempout = split "]" ,$modouts;
          print OUTFILE0 " .$tempout[-1]($tempout[-1])\n);\n";
      }
      else{
         print OUTFILE0 " .$modouts($modouts)\n);\n";
      }
  }
  else{
      if($modouts =~ /[[0-9:0-9]][a-zA-Z0-9]/){
          my @tempout = split "]" ,$modouts;
          print OUTFILE0 " .$tempout[-1]($tempout[-1]),\n";
      }
      else{
         print OUTFILE0 " .$modouts($modouts),\n";
      }
  }
}

#------------------------
#print stil & waves
#------------------------
  open (OUTFILE0, ">>$outf0");
  print OUTFILE0 "
//------------------------------------
//testcase.v
//------------------------------------
`include \"./testcase.v\"

//------------------------------------
//waves
//------------------------------------
initial
begin
 \$fsdbDumpfile(\"waves.fsdb\");
 \$fsdbDumpvars;
 \$fsdbDumpflush;
end

endmodule
\n";

  close  OUTFILE0;

#---------------------------------------------------------
#*********************************************************
# generate testcase.v files
#*********************************************************
#---------------------------------------------------------
    my $outf1 = "testcase.v";
    if (-e $outf1){
    system("rm -rf $outf1");
}
    open (OUTFILE1, ">>$outf1");
    print OUTFILE1 "

//----------------------------------
//initial input_signals
//----------------------------------
 initial
 begin\n";

#------------------------
#initial
#------------------------
  open (OUTFILE1, ">>$outf1");

  foreach my $testcins (@in_array) {

  if($testcins eq @in_array[-1]){
      if($testcins =~ /[[0-9:0-9]][a-zA-Z0-9]/){
          my @testcase = split "]" ,$testcins;
          print OUTFILE1 " $testcase[-1] = 'd0;\n
 \#1_000_000;
 \$finish;
 end";
      }
      else{
         print OUTFILE1 " $testcins = 'd0;\n
 \#1_000_000;
 \$finish;
 end";
      }
  }
  else{
      if($testcins =~ /[[0-9:0-9]][a-zA-Z0-9]/){
          my @testcase = split "]" ,$testcins;
          print OUTFILE1 " $testcase[-1] = 'd0;\n";
      }
      else{
         print OUTFILE1 " $testcins = 'd0;\n";
      }
  }
}
\n";

  close  OUTFILE1;

#---------------------------------------------------------
#*********************************************************
# generate run.f files
#*********************************************************
#---------------------------------------------------------
    my $outf2 = "run.f";
    if (-e $outf2){
    system("rm -rf $outf2");
    }
    open (OUTFILE2, ">>$outf2");
    print OUTFILE2 "
//----------------------------------
//add testbench.v
//----------------------------------
./testbench.v\n";

	my @verfiles = glob("../src/*");
    print OUTFILE2 "
//----------------------------------
//add .v files
//----------------------------------\n";
       foreach my $cds (@verfiles) {
       print OUTFILE2 "$cds\n";
       }

  close  OUTFILE2;

#---------------------------------------------------------
#*********************************************************
# generate Makefile
#*********************************************************
#---------------------------------------------------------
    my $outf3 = "Makefile";
    if (-e $outf3){
    system("rm -rf $outf3");
    }
    open (OUTFILE3, ">>$outf3");
    print OUTFILE3 "

#--------------------------------------------
#NC
#--------------------------------------------
one:clean
	ncverilog  +access+rwc +nc64bit -f run.f -l ncverilog.log
	-rm -rf *.history *novas*

#--------------------------------------------
#verdi
#--------------------------------------------
verdi:
	verdi -f run.f -nologo -ssf waves.fsdb &

clean:
	-rm -rf *.log  *.fsdb verdiLog *novas*

\n";

  close  OUTFILE3;

  • 19
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: ncverilog是Cadence公司推出的一款Verilog仿真工具,可以用于Verilog代码的编译、仿真和调试。下面是一个ncverilog脚本的示例: ``` #!/bin/csh -f # 设置仿真参数 set SIM_TOP = top_module # 顶层模块名称 set SIM_TIME = 100ns # 仿真时间 set SIM_OPTS = +access+r # 仿真选项 # 编译设计 ncverilog -sv -f filelist.f -y $ENV{VERILOG_LIB} $SIM_OPTS # 运行仿真 ncsim $SIM_TOP +gui -time $SIM_TIME $SIM_OPTS ``` 以上脚本中,通过设置变量`SIM_TOP`、`SIM_TIME`和`SIM_OPTS`来指定需要仿真的顶层模块仿真时间仿真选项。然后使用`ncverilog`命令编译设计,`-sv`选项表示使用SystemVerilog语法,`-f`选项指定文件列表,`-y`选项指定Verilog库文件的路径,`$SIM_OPTS`表示将之前设置的仿真选项传递给`ncverilog`命令。最后使用`ncsim`命令运行仿真,`+gui`选项表示使用图形界面,`-time`选项指定仿真时间,`$SIM_OPTS`表示将之前设置的仿真选项传递给`ncsim`命令。 ### 回答2: ncverilog脚本是一种用于仿真、验证和调试硬件设计的脚本语言,主要用于支持Verilog设计过程中的仿真和调试。ncverilog脚本可以通过指定仿真器的运行参数、文件路径、模块名字、仿真时钟、仿真时长等来配置仿真过程。 在ncverilog脚本中,可以使用一系列命令来控制仿真过程。最常见的命令包括: 1. `+access`: 用于指定仿真所需的设计文件路径。 2. `+define+:<macro>`: 用于定义和设置仿真过程中的宏。 3. `+incdir+:<directory>`: 用于指定包含文件的路径。 4. `+libext+:<extension>`: 用于指定库文件的扩展名。 5. `+loadpli1.0:<module>`: 用于加载和调用PLI(Programming Language Interface)模块。 6. `+ncaccess+r`: 用于在仿真过程中读取保存的波形数据文件。 7. `+nowarnTFMPC`: 用于禁止显示某些警告信息。 8. `+structs`: 用于启用对结构体的支持。 9. `+define+CDSLIB`: 用于指定CDS库文件的路径。 10. `+sv`: 用于启用SystemVerilog的支持。 11. `+sv_lib+:<library>`: 用于指定SystemVerilog库文件的路径。 通过编写和执行ncverilog脚本,可以实现对硬件设计的仿真和调试操作,以验证和验证设计的功能和正确性。同时,ncverilog还提供了一系列仿真工具和调试器,包括波形查看器、断点设置和信号分析等,方便工程师对设计进行分析和调试。 总而言之,ncverilog脚本是硬件设计中重要的仿真和调试工具,通过配置和执行ncverilog脚本,可以方便地对Verilog设计进行仿真和验证,提高设计的可靠性和性能。 ### 回答3: ncverilog脚本是一种用于编译和仿真硬件设计的脚本语言,通常用于工程师在数字电路设计中进行验证和调试的过程中。 使用ncverilog脚本,工程师可以简化测试和仿真的流程,提高设计的效率。脚本通常包含一系列指令和选项,指导仿真工具对设计进行仿真和验证。这些指令和选项可以控制仿真的时钟周期,仿真时间,波形文件的输出等。 在编写ncverilog脚本时,需要以下几个步骤: 1. 定义顶层模块:指定设计中的顶层模块以供仿真工具调用。 2. 添加仿真文件:将设计文件和测试文件添加到仿真工具的库中,以供仿真使用。 3. 设置仿真时钟:指定仿真时钟的频率和周期,以确保仿真环境与实际硬件一致。 4. 定义仿真参数:指定仿真时间的长度,仿真工具的精度等参数,以满足仿真需求。 5. 添加波形文件:根据设计需求,可以将期望输出的波形文件添加到仿真工具中,方便验证设计的正确性。 6. 运行仿真:执行仿真指令,启动仿真过程。在仿真过程中,工程师可以观察波形输出,验证设计的功能和性能。 使用ncverilog脚本进行设计仿真,可以帮助工程师快速进行验证和调试,及时发现和纠正设计中的问题。通过掌握ncverilog脚本的编写和使用,工程师可以提高硬件设计的效率和质量,并加快产品的上市时间

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值