返回介绍

11.23 参数化的类

发布于 2020-09-09 22:55:50 字数 1776 浏览 1237 评论 0 收藏 0

如果定义一个基本类,它的对象在实例化的时候可以具有不同的数组尺寸或数据类型,那么这种功能通常很有用。我们可以不必为每一个尺寸或类型编写相同的代码,并且可以为本质上不同并且不可互换的对象使用同一个说明(这与C++的类模板类似)。

普通的Verilog参数机制可以用来参数化一个类:

class vector #(int size = 1);
    bit [size-1:0] a;
endclass

接下来,这个类的实例就可以像模块或接口一样实例化:

vector #(10) vten;        // 尺寸为10的vector对象
vector #(.size(2)) vtwo;  // 尺寸为2的vector对象
typedef vector#(4) Vfour; // vector尺寸为4的类

当将类型作为参数的时候,这个功能特别有用:

class stack #(type T = int);
    local T items[];

    task push(T a);
        ...
    endtask

    task pop(ref T a);
        ...
    endtask
endclass

上面的类定义了一个基本的stack类,它可以使用任意类型实例化:

stack is;             // 缺省:int类型的堆栈
stack#(bit[1:10]) bs; // 10位向量的堆栈
stack#(real) rs;      // 实数的堆栈

任何类型都可以用作参数,包括用户定义的类型,例如类或结构体。

基本类和真实参数值的组合被称作一个特例(或变种)。类的每一个特例又具有一组单独的静态成员变量(这与C++模板类一致)。为了在多个类特例间共享静态成员变量,这些变量必须放置在一个非参数化的基类中。

class vector #(int size = 1);
    bit [size-1:0] a;
    static int count = 0;

    function void disp_count();
        $display("count: %d of size %d", count, size);
    endfunction
endclass

上面例子中的变量count只能通过对应的disp_count方法访问。对于vector类的每一个特例,count都具有它自己的唯一的拷贝。

为了避免必须在声明中或产生该类的参数中重复特例,我们应该使用typedef:

typedef vector#(4) Vfour;
typedef stack#(Vfour) Stack4;
Stack4 s1, s2;  // 声明Stack4类型的对象

一个参数化的类可以扩展另外一个参数化的类,例如:

class C #(type T = bit); ... endclass           // 基类
class D1 #(type P = real) extends C;            // T的类型为bit(缺省)
class D2 #(type P = real) extends C #(integer); // T的类型为integer
class D3 #(type P = real) extends C #(P);       // T的类型为P

D1类使用基类的缺省类型(bit)参数扩展了基类CD2类使用一个integer参数扩展了基类。D3类使用参数化类型(P,它使得扩展类被参数化)扩展了基类C

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文