在SystemC TLM中,接口是一个C++的抽象类。抽象类中的所有方法都是用“=0”标识表示的纯虚函数。C++不允许创建抽象类的对象,因为抽象类对象是没有意义的。 在SystemC中,sc_interface是所有接口的基类,任何一个接口必须直接或间接继承sc_interface。
此外,接口不包含任何数据成员。下面是一个接口实例,首先定义一个存储器读接口mem_read_if,然后定义一个存储器写接口mem_write_if,接着定义一个存储器的复位接口reset_if,最后利用这3个接口定义随机存取存储器的接口ram_if:
# ifndef _MEM_IF_H
# define _MEM_IF_H
# include “systemc.h”
enum transfer_status {TRANSFER_OK=0, TRANSFER_ERROR}; template < class T >
class mem_read_if : public sc_interface
{
public:
virtual transfer_status read (unsigned int address, T& data)=0;
// 定义存储器读的方法
};
template < class T >
class mem_write_if : public sc_interface
{
public:
virtual transfer_status write (unsigned int address, T& data)=0;
// 定义存储器写的方法
};
class reset_if : public sc_interface
{
public:
virtual bool reset ( )=0; // 定义存储器复位的方法
};
template < class T >
class ram_if : public mem_write_if < T >, mem_read_if < T >, reset_if
{
public:
virtual unsigned int start_address ( ) const=0; //定义获取存储器首地址的方法
virtual unsigned int end_address ( ) const=0; //定义获取存储器终止地址的方法
};
#endif
从上面的存储器接口的定义可以看出,接口是可以分层的,复杂的接口可以由多个简单的接口继承而得到。
从接口的定义可以看出,在SystemC中的接口仅仅定义了一组通信方法,并不包含这些方法的具体实现。为了实现这些方法,使建模的模块具有实用的功能,SystemC中针对事务级建模引入了通道的概念。
通道是接口方法的具体实现,通过继承一个或多个接口实现模型的具体功能。针对上述存储器接口ram_if,其通道的定义如下:
#ifndef _RAM_H
#define _RAM_H
#include "systemc.h"
#include "mem_if.h"
template < class T >
class ram : public sc_module, ram < T >
{
public:
ram (sc_module_name name, unsigned int start_address, unsigned int end_address)
: sc_module (name)
, m_start_address (start_address)
, m_end_address (end_address){
sc_assert (end_address >=start_address);
mem=new T[end_address -start_address];
} //构造函数
~ ram ( ) {
if (mem) {delete mem; mem=0}
} //析构函数
transfer_status read (unsigned address, T& data)
{
if (address < m_start_address || address > m_end_address) {
data=0;
return TRANSFER_ERROR;
}
data=mem [address -start_address];
return TRANSFER_OK;
}
transfer_status write (unsigned address, T& data)
{
if (address < m_start_address || address > m_end_address) {
return TRANSFER_ERROR; }
mem [address -m_start_address]=data;
return TRANSFER_OK;
}
bool reset( ) {...}
inline unsigned int start_address ( ) const {...}
inline unsigned int end_address ( ) const {...}
private:
T* mem;
unsigned int m_start_address, m_end_address
};
#endif
在SystemC中,端口与特定的通道接口相连。进程通过特定的端口调用通道的接口提供的方法。对于(1)中提出的基本端口类型sc_in、sc_out以及sc_inout,可以调用的接口方法仅有write ( )和read ( ),但对于事务级建模,这些端口已经不能够满足需求。比如,当端口与总线接口或存储器接口相连时,需要同时提供地址和数据,事务级模型需要执行与数据读写无关的一些操作如复位操作等。
在SystemC中,一个端口可以同时连接到一个或多个实现了同一接口的通道之上。端口的定义如下:
sc_port < Interface Type, ChannelNumber=1 >
Interface Type是端口所要连接的通道的接口类型。ChannelNumber代表端口所要连接的最大通道数,默认值是1。对于上面定义的的接口ram_if,下面的端口定义都是合法的:
sc_port < ram_if > ram_port1; //连接到一个RAM上
sc_port < ram_if, N > ram_portN; //连接到N个RAM上
根据上述存储器接口ram_if及相应通道的定义,可以定义一个模块Component通过端口对其进行访问,如下:
SC_MODULE (Component) {
sc_in_clk clk;
sc_port < ram_if < int > > ram_port; // 实例化端口
void action ( );
int data;
unsigned int address;
SC_CTOR ( ) {
SC_METHOD (action, clk.pos( ));
}
};
void Component :: action ( ){
wait ( );
int i=0;
while (i++< 100) {
address=0;
if (transfer_status status=ram_port - > write (address, data)) {
// 通过端口ram_port调用存储器写方法
cout < < "Write RAM successfully" < < endl;
}
else cout < < "Write RAM fail" < < endl;
if (transfer_status status=ram_port - > read (address, data)) {
// 通过端口ram_port调用存储器读方法
cout < < "Read RAM successfully" < < endl;
}
else cout < < "Read RAM fail" <
全部0条评论
快来发表一下你的评论吧 !