Felix

技术源于积累,成功始于执着!

利用TCL脚本(do文件)管理仿真流程简明教程(一)ActiveHDL RTL仿真篇

1
阅读(852) 评论(0)

熟悉FPGA开发的朋友都知道,仿真(Simulation)是FPGA开发中的一个重要的步骤和过程,目前来说用于FPGA仿真的引擎主要有:Aldec公司的Active-HDL / Riviera Pro;Mentor Graphics公司的ModelSim / Questa;Cadence公司的NC-Verilog / NC-VHDL / NCSim以及Synopsys公司的 VCS software。Lattice公司的IDE Diamond 集成了ActiveHDL Lattice Edition。拥有Diamond的license之后可以免费使用ActiveHDL软件进行仿真。(注:同时只能打开一个仿真工程,否则会报license的错误!)

ActiveHDL支持三种类型的仿真(三个阶段):

·RTL

·Post-Map Gate-Level

·Post-Rate Gate-Level-Timing

在我之前的博文中,有简单介绍过如何在Diamond IDE中调用ActiveHDL软件进行仿真的简单例子:

http://blog.chinaaet.com/justlxy/p/5100051801

有兴趣的可以再去看一看。

如本篇博文的标题所示,今天要聊的是高级一点的内容:利用TCL脚本(do文件)管理ActiveHDL RTL仿真流程。标题中的(一)表示,后续可能还会继续发布关于ActiveHDL 另外两种仿真流程的TCL脚本控制方法以及Modelsim软件的相关内容。

废话不多说,回到正题上:

1、首先,为什么要用TCL脚本

个人觉得,TCL脚本这个东西更适合Linux系统的玩家,尤其是那些喜欢shell编程的家伙们。TCL脚本对于他们来说似乎更加得心应手。对于Windows系统的用户来说,TCL脚本似乎用处并不大,因为我们一般更习惯使用图形用户界面(GUI)来进行操作,对于TCL 控制台(在Diamond IDE的最下方,如下图,其他公司的IDE也是类似的)似乎并不怎么感冒。

image.png

但是,对于开发前期来说,文件结构和内容并未完全确定,使用TCL脚本语言来管理仿真流程可以显著的提高开发效率,节省很多时间。虽然ActiveHDL软件都有很多的TCL命令(宏控制命令,Marco Commands),但是和仿真流程控制相关的,只是其中的很少的一部分而已,这也正是我们今天所有介绍的内容之一。还有就是,仿真流程控制也只用到了很少一部分的TCL脚本语言的语法,完全没有比较去彻底的掌握TCL语言,虽然TCL语言本身还是很简单的,相对于其他的编程语言来说。

2、Diamond工程的建立

这一部分似乎和本文的内容并不相关,但是为了便于理解后面的内容,还是简单的过一遍。

image.png

样例工程共有三个输入文件:test.v是顶层文件,DividerClkOdd.v是奇数分频的文件,mypll.ipx是ipexpress产生的关于PLL的配置文件。

其中,test.v文件的内容如下:

//
// File           : test.v
// Author          : Xianyou Li
// Date           : 7/20/2017
// Version          : 0.01
// Abstract          : Test the PLL module in IPexpress
//
// Modification History:
// Date         By    Version   Change Description
//
// ===========================================================
// 7/20/2017     Xianyou   0.01        Original
// 
// ===========================================================
`timescale 1ns / 1ps
module test(clk_in,clk_out,rst_n);
    input clk_in; 
    input rst_n; 
    output [4:0] clk_out;
    
    wire clkop,clkos,clkos2,clkos3,cklodd;
    
    mypll pll_inst (.CLKI(clk_in),//12Mhz input
            .CLKOP(clkop),//60Mhz output
            .CLKOS(clkos),//50MHz output
            .CLKOS2(clkos2),//40MHz output
            .CLKOS3(clkos3));//10Mhz output 
            
    DividerClkOdd # (.N (5)) div_inst 
                    (.clk_in(clkos),//50Mhz input
                    .clk_out(clkodd),//10Mhz output
                    .rst_n(rst_n));
                    
    assign clk_out = {clkop,clkos,clkos2,clkos3,clkodd};
endmodule

DividerClkOdd.v文件内容如下:

//
// File             : DividerClkOdd.v
// Author            : Xianyou Li
// Date             : 7/20/2017
// Version            : 0.01
// Abstract           : 
//
// Modification History:
// Date      By    Version  Change Description
// ===========================================================
// 7/20/2017   Xianyou    0.01    Original
// 
// ===========================================================
`timescale 1ns / 1ps
module DividerClkOdd(clk_in,clk_out,rst_n);
    parameter N = 9;
    
    input clk_in,rst_n;
    output clk_out;
    
    reg pclk,nclk;
    reg [31:0] cnt1,cnt2;
    
    //Generate pclk
    always @ (posedge clk_in or negedge rst_n)
        begin
            if(!rst_n)
                begin
                    cnt1 <= 32'd0;
                    pclk <= 1'b0;
                end
              else if(cnt1 == (N - 1)/2)
                begin
                    cnt1 <= cnt1 + 1'b1;
                    pclk <= ~pclk;
                end
              else if(cnt1 == N - 1)
                begin
                    cnt1 <= 32'd0;
                    pclk <= ~pclk;
                end
              else
                begin
                    cnt1 <= cnt1 + 1'b1;
                end
        end
    
    //Generate nclk
    always @ (negedge clk_in or negedge rst_n)
        begin
            if(!rst_n)
                begin 
                    cnt2 <= 32'd0;
                    nclk <= 1'b0;
                end
            else if(cnt2 == (N - 1)/2)
                begin
                    cnt2 <= cnt2 + 1'b1;
                    nclk <= ~nclk;
                end
            else if(cnt2 == N - 1)
                begin
                    cnt2 <= 32'd0;
                    nclk <= ~nclk;
                end
            else
                begin
                    cnt2 <= cnt2 + 1'b1;
                end
        end
    
    //Generate clk_out
    assign clk_out = pclk | nclk;
endmodule

代码都比较简单,此处不再详细描述。

但是需要说明一下工程的文件结构,以便于理解下文的内容。

image.pngimage.png

总文件夹Test0816_1下面一共有五个文件夹,如右上图所示。其中,doc文件夹存放说明文档;proj文件夹下存放Diamond工程文件;sim/ActicveHDL文件夹下存放仿真文件(do文件也存放在这里);source文件下存放源文件(输入文件);source/ipexpress文件夹下存放由Ipexpress产生的文件;testbench文件夹下存放的是测试文件。

3、建立TCL脚本文件(*.do文件

新建文本文件,然后将文件名称改为rtl_verilog.do,注意包括文件名后缀也要改过来!使用notepad++打开并编辑,输入如下内容:

image.png

下面简单分析一下文件的内容:

Row1:新建一个叫做SIM_DIR的变量,用于保存do文件所在的路径;

Row3:切换当前工作路径;

Row5-8:检查当前指定库文件是否存在,不存在则新建;

    -->vlib 指令功能:Creates a new design library and modifies the library list (library.cfg) that describes mappings between logical names and library index files (*.lib). The command can also be used to compact a library and generate an Active-HDL design description file (*.adf) allowing you to open a library as a design. 【该指令与alib指令等价】

Row10:创建仿真工程(注意本行末尾的点不能少);

Row11:打开仿真工程;

Row12:删除所有的unit,如果是第一次新建仿真工程,则可以不写,因为此时是空的,根本就没有什么可以删除的。

    -->adel指令功能:Deletes a design unit from a design library

Row14:再次切换到仿真目录下;

Row16-18:添加源文件(输入文件);

Row20:添加Testbench文件;

    -->vlog指令与alog指令等价。

        -->参数 -dbg意义:Generates debugging information that is required for setting code breakpoints, stepping through the source code, and generation of code coverage data. To generate the debugging information, this argument must be explicitly specified. 

    -->..(就是英文输入法下的两个点)表示上一层目录。

Row22:开始仿真;

    -->vsim指令介绍:Invokes the simulator and initializes the process of simulation.【该指令与asim等价】

        -->+access +r参数:Enables read access. Read access allows you to record signals to the simulation database, examine signal values with the examine command and/or debugging tools.

        -->-L ovi_machxo3l参数:指定仿真库名称,因为本工程选用的是Lattice MachXO3L器件,所以库名称为ovi_machxo3l;

        -->-PL参数:Similar to -L, however, the libraries specified with this argument are searched before libraries specified with the -L argument. In Verilog, -PL overrides bindings determined at compile time, i.e. if a given unit was visible to the compiler during compilation and another unit with the same name is also available in a library specified with the -PL argument, then the unit from the library specified by -PL will be bound at load time.

Row24&27:创建信号分组标题,高度32,红色加粗字体;

Row25&26&28:添加需要观察的信号到波形窗口;

Row30:开始运行 指定运行时间300us;

4、运行TCL脚本文件(do文件)

首先打开ActiveHDL软件,然后点击Tool->Execute macro ,如下图所示:

image.png

找到do文件所在的目录,选中,打开即可:

image.png


运行结果如下图所示:

image.png

5、参考阅读

5.1、ActiveHDL Online Help

5.2、Active-HDLLatticeEditionTutorial.PDF