6.1 一个简单的存储器设计
为了说明激励生成器和监视器,我们用一个简单的存储器作为DUT。它有一个通过外部接口可寻址的、可读可写的内存空间。我们将简要地介绍一下接口和DUT的各种操作。图6-1说明了这个存储器的所有管脚。
图6-1 Memory的示意图
每个管脚的定义和功能如表6-1所示。
表 6-1
存储器有独立的读和写的总线。将数据总线一分为二就不需要有用三态门实现的双向总线了。当req被置高时,存储器就开始工作了。它会根据rw管脚的电平来决定这时是一个读操作还是一个写操作。地址是从addr管脚获取的。当存储器完成了对需求的响应,不论是将一个新的数据写入到存储器中,还是读取了一个数据放到读数据总线上,ack就被置高了。
我们从管脚接口开始创建这个器件。在SystemVerilog中,用接口这一结构来包含所有的管脚接口。
如上的接口的第一部分定义了接口中包含的管脚以及它们的类型和长度。第二部分设置了modport。
这三组modport都含有相同的一组信号,但这些信号的输入输出方向是不同的,用来支持不同的连接模式。存储器自己使用的是slave_mp的modport,其中rd_data被定义成输出,wr_data被定义成输入。另一个器件(如激励产生器)使用master_mp的modport来驱动存储器。正如监视器所要求的那样,所有monitor_ mp的modport中的管脚都是输入。在下面的各节中,我们将看到接口和modport是如何被用于连接激励产生器和监视器的。
SystemC使用接口的方法与SystemVerilog类似,但是C++没有专门的接口结构,而是使用接口类来包含所有的端口定义。每个端口的定义使用sc_in< >,sc_out< >或者sc_inout< >来标明信号的方向,尖括号中的参数是信号的数据类型。存储器是一个管脚级的器件,所以对一位的信号使用bool类型,对象addr这样的总线使用sc_uint类型。下面是“主接口”的定义。
“从接口”与SystemVerilog的对应部分类似,是存储器自己用来跟外界通信的。信号的方向也是相对于存储器定义的。
最后为了连接监视器,它的接口只有输入端口。
存储器的通信协议可以用图6-2所示的状态机来表示。
图6-2 Memory的FSM
当存储器在等待req信号被置高时,它处于WAIT REQ状态。在下一个时钟周期,当req被置高时,状态就切换到了SEND ACK,同时数据被传输到rd_data总线上或从wr_data总线传输到内部(取决于什么类型的请求在被执行)。当ack被置高,就表明该响应已经结束。最后状态又重新回到WAIT REQ来等待下一个请求。DUT的代码如下所示:
DUT的核心是对状态机的实现。在“always@”模块中的时钟驱动着状态机,所以状态只能在时钟的上升沿时改变。状态机是围绕着有两种情况的case语句来建立的,每种情况对应着状态机的一种状态。
如图6-3所示,我们将用一个含有激励产生器和监视器的简单的验证平台来测试这个存储器。所有的三个器件,激励产生器、监视器和存储器(DUT)都连接到相同的总线上。
在顶层模块中,该三个组件被连接,同时一个时钟产生器被创建。所有的连接都是通过SystemVerilog接口实现的。激励产生器,也被称为主器件,是通过master_mp的modport来连接的。而DUT则通过slave_mp的modport来连接。
图6-3 简单的验证平台
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。