现在的位置: 首页 > 综合 > 正文

第二部分 编写PLI应用程序

2014年01月03日 ⁄ 综合 ⁄ 共 2212字 ⁄ 字号 评论关闭

 

  先前我们所看的例子太基础也没有实际用途。让我们看计数器的例子,写一个DUT的参考模型以及用C写的Checker程序,并把它链入到VerilogTestbench。首先列出我们要用PLIC模型的要求。

  •   调用C模型的方法,当输入信号有任何变化时;
  •   获得verilog代码中改变了的信号值或者任何C代码内部的信号的方法
  •   通过C代码驱动Verilog内部值

VerilogPLI提供一系列满足以上要求的程序(函数)。

PLI 应用的SPEC

我们定义使用PLI的计数器testbench的要求。 该PLI函数我们称作$counter_monitor

  •   C实现一个计数器逻辑
  •   C实现一个检测逻辑
  •   checker失败时,终止仿真

 

调用C函数
C写计数器非常简单,但是什么时候我们要增加计数器的值呢?所以我们就需要监测时钟信号的变化(顺便说一句,通过verilog代码驱动复位和时钟信号是个好习惯)一旦时钟发生变化,计数器函数就要被执行。这可以通过以下的函数实现:
    
使用acc_vcl_add程序。该函数的语法可以查阅Verilog PLI LRM基本上acc_vcl_add程序能检测许多信号,一旦任何一个信号改变就会调用用户定义的函数(也就是定制的C程序)。VCL程序有4个自变量:

  •    需要监测对象的句柄
  •    用户C程序,当对象值变化就会调用它
  •    传递给C程序的字符串
  •    预定义的VCL标志:vcl_verilog_logic    -- 逻辑监测
                        vcl_verilog_strength -- 
    强度监测

acc_vcl_add(net, display_net, netname, vcl_verilog_logic);

C代码 - 基础
Counter_monitor是我们在verilog testbench中将要调用的C函数。就像任何其他的C代码,我们需要包含针对我们所要开发的特定的应用的头文件。我们这里,需要包含acc 程序include文件。

access函数 acc_initialize 初始化access程序的环境,在程序调用任何的access程序前必须要调用的。在退出调用access程序的C应用程序前,在程序的最后必须要退出access程序环境,调用acc_close

1

#include "acc_user.h"

2

 

3

handle clk ;

4

handle reset ;

5

handle enable ;

6

handle dut_count ;

7

void counter ();

8

 

9

void counter_monitor() {

10

 

acc_initialize();

11

 

clk = acc_handle_tfarg(1);

12

 

reset = acc_handle_tfarg(2);

13

 

enable = acc_handle_tfarg(3);

14

 

dut_count = acc_handle_tfarg(4);

15

 

acc_vcl_add(clk,counter,null,vcl_verilog_logic);

16

 

acc_close();

17

}

18

 

19

void counter () {

20

 

io_printf( "Clock changed staten" );

21

}

为了能accessing verilog对象,我们使用句柄。句柄是指预定义的数据类型,它是是设计层次中某个对象的指针。每个句柄传递给access函数有关唯一可以accessible对象的类型信息,以及如何哪里能找到有关此对象的信息。但是,我们如何把某个特定对象的信息给句柄呢?我们可以通过许多途径,但是现在我们用verilog采用参数传递的方式给$counter_monitor, 这些参数在C程序中可以采用acc_handle_tfarg()函数获得,这里自变量和代码中一样是数字。

因此clk = acc_handle_tfarg(1) 使得clk作为第一参数传递的句柄。类似我们给所有的句柄赋值。现在我们可以把clk加入我们需要检测的信号列表中,acc_vcl_add(clk,counter,null,vcl_verilog_logic)。这里clk是句柄,counter是当clk发生变化时,需要执行的用户函数。

函数counter()就不作任何解释了,它是类似于hello world简单的代码。

Verilog 代码
下面是计数器例子的简单的testbenchWe call the C-function using the syntax shown in code below. If object thats been passed is a instant, then it should be passed inside double quotes. Since all our objects are nets or wires, there is no need to pass them inside double quote.

1

module counter_tb();

2

reg enable;

3

reg reset;

4

reg clk_reg;

5

wire clk;

6

wire [3:0] count;

7

 

8

initial begin

9

 

enable = 0;

10

 

clk_reg = 0;

11

 

reset = 0;

12

 

$display( "%g , Asserting reset" 

抱歉!评论已关闭.