SystemC入门笔记(2)


学过了C/C++,SystemC很快就能入门。了解了小的模块设计之后,也就能够拼出一个简单的轻量级系统。

轻量级系统设计

该系统包含测试激励、两个不同的数据处理单元、总线、仲裁器、UART以及监视器。

1.仲裁器

  • filter.h

    #include"systemc.h"
    SC_MODULE(filter)
    {
        sc_in<char> char_in;          //定义输入端口
        sc_out<char> char_out;        //定义输出端口
    
        void prc_filter();
    
        SC_CTOR(filter)
        {
            SC_METHOD(prc_filter);
            sensitive << char_in;
        }
    };
  • filter.cpp,当字母不是“systemc”中的一个,则输出#,否则原样输出。

    #include"filter.h"
    void filter::prc_filter() {
    
        char_out = '#';
    
        if (char_in == 's' || char_in == 'y' || char_in == 't' || char_in == 'e' || char_in == 'm' || char_in == 'c')
            char_out = char_in;
    }
  • change_case.h

    #include"systemc.h"
    SC_MODULE(change_case)
    {
        sc_in<char> char_in;
        sc_out<char> char_out;
    
        void prc_change_case();
    
        SC_CTOR(change_case)
        {
            SC_METHOD(prc_change_case);
            sensitive << char_in;
        }
    };
  • change_case.cpp,调用函数toupper实现小写转换成大写,并传递给输出

    #include"change_case.h"
    void change_case::prc_change_case() {
          char_out = (char)toupper(char_in);
    }
  • arbiter.h

    #include"systemc.h"
    SC_MODULE(arbiter) {
        //定义一个输出端口,作用是一个选通信号
        sc_out<bool>a_selector;
        void arb();
        SC_CTOR(arbiter) {
            SC_METHOD(arb);
        }
    };
  • arbiter.cpp,用于裁决filter与change_case谁工作,实现两者的交替工作

    #include"a.h"
    bool s = 1;
    void arbiter::arb() {
        next_trigger(10,SC_NS);
        s = !s;        //每隔10ns,s的值会取反
        a_selector = s;
    }

2.总线

  • m_bus.h

    #include"systemc.h"
    SC_MODULE(m_bus)
    {
        sc_in<char> char_in1;
        sc_in<char> char_in2;
        sc_in<bool> selector;
        sc_out<char> char_out;
    
        void prc_m_bus();
    
        SC_CTOR(m_bus)
        {
            SC_METHOD(prc_m_bus);
            sensitive << char_in1 << char_in2 << selector;
        }
    };
  • m_bus.cpp

    #include"m_bus.h"
    void m_bus::prc_m_bus() {
        if (selector == 0)
            //当selector=0,输出char_in1
            char_out = char_in1;
        else if (selector == 1)
            //当selector=1,输出char_in2
            char_out = char_in2;
        else;
    }

3.UART

将bus的输出一位一位读进来,然后一位一位传递到monitor输出。

  • UART.h

    #include"systemc.h"
    SC_MODULE(UART)
    {
        sc_in<char> char_in;
        sc_out<char> char_out;
    
        void prc_UART();
    
        SC_CTOR(UART)
        {
            SC_METHOD(prc_UART);
            sensitive << char_in;
        }
    };
  • UART.cpp

    #include"UART.h"
    void UART::prc_UART() {
          char_out = char_in;
    }

4.testbench

用于产生激励与监测(模块)

  • testbench.h

    #include"systemc.h"
    SC_MODULE(driver)    //激励模块
    {
        sc_out<char> d_char; // char generator
    
        void prc_drive();
    
        SC_CTOR(driver)
        {
            SC_METHOD(prc_drive);
        }
    };
    SC_MODULE(monitor)        //监测模块
    {
        sc_in<char> m_char;
    
        void prc_monitor();
    
        SC_CTOR(monitor)
        {
            SC_METHOD(prc_monitor);
    
        }
    };
  • testbench.cpp

    #include"testbench.h"
    int i=0;
    void driver::prc_drive() {
        char arr[27] = "abcdefghijklmnopqrstuvwxyz";
        //d_char端口调用write函数,把arr[i]写进端口,然后i自增.
        d_char.write(arr[i++]);
        next_trigger(20, SC_NS);
        //延时,方便查看结果
        for (int i = 0; i<100000000; i++);
    }
    void monitor::prc_monitor() {
        //输出当前仿真时间以及UART的输入
        cout << "AT " << sc_simulation_time() << " UART output is : " << m_char << endl;
        next_trigger(10, SC_NS);
    }

5.main

  • main.cpp

    #include"systemc.h"
    #include"arbiter.h"
    #include"change_case.h"
    #include"filter.h"
    #include"m_bus.h"
    #include"testbench.h"
    #include"UART.h"
    int sc_main(int argc, char * argv[]) {
        sc_signal<char>a, b, c,e,f;
        sc_signal<bool>d;
        sc_clock testclk("testclk",1,SC_NS);
    
        arbiter a1("a1");
        change_case c1("c1");
        filter f1("f1");
        m_bus m1("m1");
        driver d1("d1");
        UART u1("u1");
        monitor moni("moni");
    
        d1.d_char(a);
    
        c1.char_in(a);
        c1.char_out(b);
    
        f1.char_in(a);
        f1.char_out(c);
    
        a1.a_selector(d);
    
        m1.char_in1(b);
        m1.char_in2(c);
        m1.selector(d);
        m1.char_out(e);
    
        u1.char_in(e);
        u1.char_out(f);
    
        moni.m_char(f);
    
        sc_start(530,SC_NS);
        return 0;
    }

    运行结果

    运行结果
    filter与change_case模块交替运行,当filter模块工作时,将除了包含在“systemc”中的6个字符以外的所有字符都用“#”代替。


文章作者: Tqraf
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Tqraf !
评论
  目录