systemC的组合逻辑建模

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了systemC的组合逻辑建模相关的知识,希望对你有一定的参考价值。


一般声明systemC类模块的格式为

SC_MODULE(类名){
    端口声明:  sc_in sc_out sc_inout
    在内部链接可能需要使用的信号    
    声明需要使用的一般函数
    声明需要使用的进程函数或者线程函数
    子模块的声明或者其指针的声明
    数据变量的声明
    //  构造函数
    SC_CTOR(类名){
            注册进程或者线程函数
            声明敏感量列表
    }
};

一旦函数在构造函数中进行了声明,那么这个函数就不再是一个简单的方法了。

(1)在构造函数中使用SC_METHOD声明:那么这个一个进程方法,它会被敏感量所触发。触发后进入到函数执行,执行完毕后将执行权转交给仿真内核。

          进程方法必须是有限循环的。

(2)在构造函数中使用SC_THREAD声明:那么这是一个线程方法,它会被敏感量触发。一般而言,触发后会停止线程方法的挂起状态,从而继续执行,直

          到遇    到下一个wait语句从而再次挂起。线程函数一般是无限循环的。

接下来博主就举组合逻辑的例子-----关于数据选择器multiplexer的建模:

base.h:

#ifndef BASE 
#define BASE 
 
#include "systemc.h" 
#include <iostream> 
#endif

simulus.h:

#include "base.h" 
 
#ifndef SIMULUS 
#define SIMULUS 
 
SC_MODULE(simulus){ 
    //   signal drivers  
    sc_out<bool>  cs ; 
    sc_out<sc_uint<3> > select ; 
     
     
    void prc_simulus(); 
     
    SC_CTOR(simulus){ 
        SC_THREAD(prc_simulus);    //  因为信号需要不断的生成,所以需要使用THREAD线程方法
    } 
}; 
 
#endif

stimulus.cpp:

#include "simulus.h"
void simulus::prc_simulus(){
    //  signal generates process
    sc_uint<3> temp(0) ;
    
    cs = 0 ;
    
    for(;;){
        select = temp ;
        temp++ ;
        wait(10,SC_NS);      每次使线程挂起10ns
    }
}

monitor.h:

#include "base.h" 
 
#ifndef MONITOR 
#define MONITOR 
 
SC_MODULE(monitor){ 
    sc_in<bool> cs ; 
    sc_in<sc_uint<3> > select ; 
    sc_in<sc_uint<8> > mul_out; 
     
    void prc_monitor(); 
     
    SC_CTOR(monitor){ 
        SC_METHOD(prc_monitor); 
        sensitive<<mul_out;               //  输出监视,监视multiplexer的输出
    }; 
}; 
 
#endif

monitor.cpp:

#include "monitor.h"
void monitor::prc_monitor(){
    //    在这个输出中无法使用c语言的函数进行输出,因为类型无法匹配,
    //    并且systemc2.x 的版本较老了,没有办法使用其内建的to_string函数
    cout<<cs.read()<<" "<<select.read()<<" "<<mul_out.read()<<std::endl ;
}

dut.h(Design under test -----   multiplexer ):

#include "../base.h" 
 
#ifndef DUT 
#define DUT 
 
SC_MODULE(multiplexer){ 
     
     
    sc_in<bool> cs_n ; 
    sc_in<sc_uint<3> >select ; 
    sc_out<sc_uint<8> >  mul_out ; 
     
    void prc_mul(); 
     
    SC_CTOR(multiplexer){ 
        SC_METHOD(prc_mul); 
        sensitive<<cs_n<<select ; 
    }; 
     
}; 
 
#endif

dut.cpp:

#include "dut.h"
void multiplexer::prc_mul()        //  数据选择器的内部逻辑实现
{
    sc_uint<8> temp = 0 ;
    temp = ~temp ;
    if( cs_n )
        mul_out = temp ;
    else {
        temp[select.read()] = 0 ;
        mul_out = temp ;
    }
}

最后的总测试文件main.cpp:

#include "simulus.h"
#include "dut/dut.h"
#include "monitor.h"
int sc_main(int argc , char * argv[]){
    //    signal defination
    sc_signal<sc_uint<3> > select_sig;
    sc_signal<sc_uint<8> > mul_out_sig;
    sc_signal<bool> cs_sig ;
    
    sc_trace_file * vcd = sc_create_vcd_trace_file("record");     //  创立一个vcd记录文件
    
    //  istance the component
    simulus sim("select");
    sim(cs_sig,select_sig);
    
    multiplexer mul("multiplexer");
    mul(cs_sig,select_sig,mul_out_sig);
    
    monitor mon("monitor");
    mon(cs_sig,select_sig,mul_out_sig);
    
    sc_trace(vcd,select_sig,"select");
    sc_trace(vcd,mul_out_sig,"multiplexer");    //   将需要记录的文件加入到vcd文件中
    sc_start(1000,SC_NS);        //   仿真时间为1000ns
    
    sc_close_vcd_trace_file(vcd);               //    仿真结束后关闭vcd文件
    return 0 ;
}

最后的仿真结果:

技术分享图片

以上是关于systemC的组合逻辑建模的主要内容,如果未能解决你的问题,请参考以下文章

systemC的同步时序建模

jchdl进展 - 20180918

systemC三态建模

SystemC事务级建模03之DMI

SystemC传输级别建模从tlm_generic_payload中提取两个整数

从验证的角度,systemverilog和systemc谁更合适