在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4400|回复: 8

[讨论] systemverilog在module中例化program的问题

[复制链接]
发表于 2015-10-28 15:02:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
在IEEE Standard sv中说module中可以例化program: 捕获.JPG 现在有个疑问:如下例:
想法很简单:
      一个设计模块module adder,加法器,两个输入a和b,一个输出o。
      一个验证模块program p,一个输入i(对应设计模块的输出),两个输出x和y(分别对应设计模块的a和b)。
      一个tb模块,将设计模块和验证模块连接起来。
      实现:类随机变量随机化值送给设计模块,设计模块执行后的结果由类中的任务打印输出。
module adder(a,b,o);
  input bit [1:0] a;
  input bit [1:0] b;
  output bit [2:0]o;
  always@(*)
   begin
     o = a + b;
   end
endmodule

program p(input bit [2:0] i, output [1:0]x, output [1:0]y);
  class c;
    rand bit [1:0] m;
    rand bit [1:0] n;
    task display();
      $display("the value of a is %2b!", m);

$display("the value of b is %2b!", n);

$display("the value of result is %3b!", i);
    endtask:display
  endclass:c


  c c0;


  initial
    begin
       c0 = new;
       c0.randomize();
       c0.display;
    end


endprogram:p


module tb;
  wire [1:0]a;
  wire [1:0]b;
  wire [2:0]o;

   addr a0(
     .a(a),
     .b(b),
     .o(o)
   );
   p p0(
     .x(a),
     .y(b),
     .i(o)
   );
endmodule
编译执行结果:
the value of a is10!
the value of b is 01!
the value of result is 000!



只执行了program部分程序,adder模块和tb模块根本没起作用,想问一下,如果想实现我说的功能,应该如何改进?


谢谢
 楼主| 发表于 2015-10-28 15:32:41 | 显示全部楼层
把设计模块adder去掉,只保留验证模块和tb模块,通过tb模块直接初始化的方式向验证模块中传值,编译和运行都有正确的结果的。设计模块为什么不行呢?是因为他们运行同时运行的原因吗?
program p(input bit [2:0] i, input [1:0]x, input [1:0]y);
  class c;
    task display();
      $display("the value of a is %2b!", x);
      $display("the value of b is %2b!", y);
      $display("the value of result is %3b!", i);
    endtask:display
  endclass:c
  c c0;
  initial
    begin
       c0 = new;
       c0.display;
    end
endprogram:p

module tb;
  logic [1:0]a;
  logic [1:0]b;
  logic [2:0]o;
   p p0(
     .x(a),
     .y(b),
     .i(o)
   );
  initial
    begin
      a = 2'b01;
      b = 2'b10;
      o  = a + b;
    end
endmodule:tb
编译执行结果:
the value of a is01!
the value of b is 10!
the value of result is 011!
发表于 2015-10-28 16:10:49 | 显示全部楼层
第一个里面加个延时试一下。
initial
    begin
       c0 = new;
       c0.randomize();
      #1ns;
       c0.display;
    end
 楼主| 发表于 2015-10-28 19:39:48 | 显示全部楼层
回复 3# luyaker
不对。我试一下虚拟接口看看
发表于 2015-10-28 21:01:55 | 显示全部楼层
对的,它们确实不是在同一个area里面执行的。module的执行要比tb早,而且你这里没有时间点的概念,相当于tb执行了一次,那在同一时刻tb就晚于module,所以module采样不到变化,就不会触发always进程语句。你可以试试加入时钟周期到module和tb中,你会看到,第一拍tb产生a和b以后,第二拍module才会根据上一拍的a和b计算,大概是这个意思。用vif估计也不行。你可以试试我说的。
发表于 2015-10-29 08:49:39 | 显示全部楼层
仔细看了一下,testbench不对,往class里面传递参数可以使用new函数,当然要改的地方还有几个,好好修改一下吧
 楼主| 发表于 2015-10-29 10:53:13 | 显示全部楼层
本帖最后由 似水如烟 于 2015-10-29 11:03 编辑

回复 5# gaurson 我会试一下你说的这种方法。采用virtual的方式(同样需要加入延时,使类的打印任务晚于设计模块的执行,即:验证模块->设计模块->延时->验证模块),已经仿真运行,结果也可以正常打印。
采用virtual后的程序改为如下:
//定义接口
interface itf;
  logic [1:0]a;
  logic [1:0]b;
  logic [2:0]o;
  modport DUT(
    input a,b,
    output o
  );
  modport PM(
    input o,
    output a,b
  );
endinterface:itf;

//module adder(a,b,o);
module adder(itf itf0);
//  input bit [1:0] a;
//  input bit [1:0] b;
//  output bit [2:0]o;
  always@(*)
   begin
//     o = a + b;
     itf0.o = itf0.a + itf0.b;
   end
endmodule

//program p(input bit [2:0] i, output [1:0]x, output [1:0]y);
program p(itf itf0);
  class c;
    rand bit [1:0] m;
    rand bit [1:0] n;


    virtual itf vif;
    function new(virtual itf itf0);
       vif = itf0;
    endfunction:new


    function value();
       vif.a = m;
       vif.b = n;
    endfunction:value

    task display();
      $display("the value of a is %2b!", m);
     $display("the value of b is %2b!", n);
//     $display("the value of result is %3b!", i);
     $display("the value of result is %3b!", vif.o);
    endtask:display
  endclass:c

  c c0;

  initial
    begin
//       c0 = new;
       c0 = new(itf0);
       c0.randomize();
       c0.value();
       #1;//设计模块为纯组合逻辑的原因,时序逻辑应该是不需要延时的
       c0.display();
    end

endprogram:p

module tb;
//  wire [1:0]a;
//  wire [1:0]b;
//  wire [2:0]o;
   itf itf0();
//   addr a0(
//     .a(a),
//     .b(b),
//     .o(o)
//   );
   adder a0(itf0);
//   p p0(
//     .x(a),
//     .y(b),
//     .i(o)
//   );
    p p0(itf0);
endmodule
编译执行结果:
the value of a is10!
the value of b is 01!
the value of result is 101!
发表于 2015-10-31 11:25:51 | 显示全部楼层
回复 7# 似水如烟


   结果还是错误的啊。。。
 楼主| 发表于 2015-11-2 09:15:15 | 显示全部楼层
回复 8# rxg111sc
程序是编译执行过的,应该是没错的。你可以把你编译的的代码和log信息贴一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-15 09:39 , Processed in 0.026238 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表