
앞서도 얘기 했지만 primitive channel에는 대표적으로 sc_signal과 sc_fifo가 있다. 그 외 여러가지가 있지만 자세한 것은 spec을 참조 하도록 하고 여기서는 가장 사용 빈도가 높은 sc_signal과 sc_fifo에 대해서만 알아 보자.
1. sc_signal<T>
이 channel에는 sc_signal_inout_if<T>의 read/write method 함수가 구현 되어 있다. 즉 sc_signal은 verilog HDL의 wire와 같은 개념으로써 module과 module간의 통신 매개체가 되는 것이다.
channel을 사용할 때 공통적으로 주의해야 할 사항이 있다. 그것은 동시성을 위한 메카니즘인데 channel의 read/write method를 통해 어떤 값을 읽고 쓸 경우 그 결과는 시뮬레이션 단위 지연 시간 만큼 후에 반영이 된다는 것이다.
예를 들어 보자. 아래 a라는 sc_signal에 초기 값이 0이라고 가정하자.
sc_signal<int> a; int y; a.write(10); y = a.read();
자 y에는 어떤 값이 있을까? 답은 0이다. 그럼 언제 10이라는 값이 써지는 것일 까? 아래 예제를 보자.
a.write(10); wait(); y = a.read();
이제 y를 출력하면 10이 들어가 있다. 즉 SystemC simulation kernel이 현재 시간에 pending 되어 있는 모든 event처리 (여기서는 a.write(10);)을 진행하고 다음 event로 simulation time을 증가 시켜야 (여기서는 wait();) 결과 값이 반영되는 것이다.
2. sc_fifo<T>
sc_fifo에는 blocking read/write method와 non-blocking read/write method 그리고 몇 가지 FIFO 상태를 알 수 있는 method가 구현 되어 있다.
보통 functional modeling이나 transaction level modeling에서는 block read/write method를 사용하고 실제 RTL level의 HW구현에는 non-blocking method를 사용한다.
block method는 read()/write()이고 non-blocking method는 nb_read()/nb_write()이다.
read()를 call하면 fifo에 데이터가 있으면 return하고 데이터가 없으면 데이터가 들어올 때 까지 return하지 않는다. nb_read()를 call하면 데이터가 있으면 데이터를 읽고 true를 return하고 데이터가 없으면 false를 return한다. write()를 call하면 fifo에 빈영역이 있으면 바로 write하고 빈 영역이 없으면 빈 영역이 생길 때 까지 기다렸다 write하고 return 한다. nb_write()를 call 하면 빈 영역이 있으면 바로 write하고 true를 return하고 빈 영역이 없으면 false를 return한다.
이 외에 num_available()이란 method가 있는데 이것은 읽을 수 있는 데이터 갯수를 리턴한다.
num_free() 는 쓰기 가능한 빈 영역 갯수를 리턴한다.
sc_fifo를 이용한 예제는 아래와 같다
#include <stdio.h> #include <systemc.h> class Adder : public sc_module { public : sc_in_clk clk; sc_in<int> a; sc_in<int> b; sc_fifo_out<int> y; SC_HAS_PROCESS(Adder); Adder(sc_module_name name) : sc_module(name) { SC_THREAD (main); sensitive << clk.pos(); } void main(); }; void Adder::main() { while(1) { y.write(a+b); wait(); } } int sc_main(int argc, char *argv[]) { sc_signal<int> a; sc_signal<int> b; sc_fifo<int> y_fifo(10); sc_clock clk("clock", 10, SC_NS, 0.5, 0.0, SC_NS); Adder u_Adder("adder"); u_Adder.clk(clk); u_Adder.a(a); u_Adder.b(b); u_Adder.y(y_fifo); a = 10; b = 20; sc_start(100, SC_NS); printf("%d + %d = %d\n", a.read(), b.read(), y_fifo.read()); return 0; }
'SystemC Tutorial' 카테고리의 다른 글
Ch5. sc_export 사용하기 (0) | 2008.01.17 |
---|---|
Ch4. SystemC 활용하기 - 사용자 정의 인터페이스/채널 (2) | 2007.11.10 |
Ch2. SystemC의 구성 요소 - 인터페이스,포트,채널 (0) | 2007.11.10 |
Ch1. SystemC의 구성요소 - module (0) | 2007.05.15 |
Ch0. SystemC - Introduction (0) | 2007.05.15 |