SystemCでカウンターつくってみた(Makefile, DUT, TB)

SystemC Japan 2014が近くなってきましたね。僕は家のPCにSystemCをインストールして、はじめてカウンターをつくってみたよ。

ディレクトリ構成はこんなかんじ。
./Makefile
./src/counter.h
./src/counter.cpp
./testbench/tb.h
./testbench/tb.cpp
./testbench/top.h
./testbench/main.cpp


Makefile

CC = g++
SYSTEMC = /usr/local/systemc-2.3.0
INCDIR = -I. -I/usr/local/systemc-2.3.0/include -I./src -I./testbench
LIBDIR = -L. -L/usr/local/systemc-2.3.0/lib-linux64
LIBS = -lsystemc -lm
CFLAGS = -O2 -Wall

TARGET = run.x
SRCS = main.cpp tb.cpp counter.cpp
OBJS = $(SRCS:.cpp=.o)

all : $(TARGET)
$(TARGET) : $(OBJS)
        $(CC) $(CFLAGS) $(INCDIR) $(LIBDIR) -o $(TARGET) $(OBJS) $(LIBS)
main.o : testbench/main.cpp
        $(CC) $(CFLAGS) $(INCDIR) -c testbench/main.cpp
tb.o : testbench/tb.cpp
        $(CC) $(CFLAGS) $(INCDIR) -c testbench/tb.cpp
counter.o : src/counter.cpp
        $(CC) $(CFLAGS) $(INCDIR) -c src/counter.cpp
clean :
        @rm -f *.o *.vcd $(TARGET)


counter.h

#ifndef _COUNTER_H_
#define _COUNTER_H_

#include <systemc.h>

SC_MODULE(counter){
    sc_in_clk           CLK;
    sc_in<bool>         RST;
    sc_out<sc_uint<4> > O_COUNTER;

    void count_proc();
    void count_func(const sc_uint<4> i_counter, sc_uint<4>& o_counter);

    SC_CTOR(counter)
    : CLK("CLK")
    , RST("RST")
    , O_COUNTER("O_COUNTER")
    {
        SC_CTHREAD(count_proc, CLK.pos());
        reset_signal_is(RST, false);
    }
};

#endif


counter.cpp

#include "counter.h"

void counter::count_proc(){
    O_COUNTER.write(0);
    wait();

    while(true){
        sc_uint<4> i_counter = O_COUNTER.read();
        sc_uint<4> o_counter;
        count_func(i_counter, o_counter);

        O_COUNTER.write(o_counter);
        wait();
    }
}

void counter::count_func(const sc_uint<4> i_counter, sc_uint<4>& o_counter){
    if(i_counter == 10){
        o_counter = 0;
    }else{
        o_counter = i_counter + 1;
    }
}


tb.h

#ifndef _TB_H_
#define _TB_H_

#include <systemc.h>

SC_MODULE(tb){
    sc_in_clk          CLK;
    sc_out<bool>       RST;
    sc_in<sc_uint<4> > O_COUNTER;

    void tb_proc();

    SC_CTOR(tb){
        SC_THREAD(tb_proc);
        sensitive << CLK.pos();
    }
};

#endif


tb.cpp

#include "tb.h"

void tb::tb_proc(){
    RST.write(false);
    for(int i=0; i<10; i++) wait();
    RST.write(true);
    for(int i=0; i<1000; i++) wait();

    sc_stop();
}


top.h

#ifndef _TOP_H_
#define _TOP_H_

#include <systemc.h>
#include "counter.h"
#include "tb.h"

SC_MODULE(top){
    sc_clock               CLK;
    sc_signal<bool>        RST;
    sc_signal<sc_uint<4> > O_COUNTER;

    counter DUT;
    tb      TB;

    SC_CTOR(top)
    : CLK("CLK", 10, SC_NS)
    , DUT("DUT")
    , TB("TB")
    {
        DUT.CLK(CLK);
        DUT.RST(RST);
        DUT.O_COUNTER(O_COUNTER);
        TB.CLK(CLK);
        TB.RST(RST);
        TB.O_COUNTER(O_COUNTER);
    }
};

#endif


main.cpp

#include <systemc.h>
#include "top.h"

int sc_main(int argc, char* argv[]){
    top i_top("i_top");

    sc_trace_file* fp = sc_create_vcd_trace_file("counter_test");
    fp->set_time_unit(1.0, SC_NS);
    sc_trace(fp, i_top.DUT.CLK, "CLK");
    sc_trace(fp, i_top.DUT.RST, "RST");
    sc_trace(fp, i_top.DUT.O_COUNTER, "O_COUNTER");

    sc_start();

    return 0;
}