|
|
|
|
|
|
|
|
|
|
|
Introduction
|
|
|
If you refer to any book on programming language it starts with "hello World" program, once you have written the program, you can be sure that you can do something in that language . |
|
|
|
|
|
Well I am also going to show how to write a "hello world" program in SystemC, followed by "counter" design in SystemC. |
|
|
|
|
|
Hello World Program
|
|
|
|
|
|
1 // All systemc modules should include systemc.h header file
2 #include "systemc.h"
3 // Hello_world is module name
4 SC_MODULE (hello_world) {
5 SC_CTOR (hello_world) {
6 // Nothing in constructor
7 }
8 void say_hello() {
9 //Print "Hello World" to the console.
10 cout << "Hello World.\n";
11 }
12 };
13
14 // sc_main in top level function like in C++ main
15 int sc_main(int argc, char* argv[]) {
16 hello_world hello("HELLO");
17 // Print the hello world
18 hello.say_hello();
19 return(0);
20 }
You could download file hello.cpp here
|
|
|
|
|
|
Words in green are comments, blue are reserved words, Any program in SystenC should include the file systemc.h header file at the beginin of the file. This file contains all the macros and SystemC templates. Any program in SystemC starts with reserved word SC_MODULE <module_name>, In the above example line 4 contains module hello_world. (Note: We can have compiler pre-processor statements like #include, #define statements before module declaration). |
|
|
|
|
|
Line 5 contains constructor SC_CTOR, which is similar to new in C++, line 8 contains function say_hello, this function prints the "Hello World" text to stdout when this function is called. |
|
|
|
|
|
In SystemC if you have multiple lines within a block, you need to use { and }. Module ends with };, in this case line 12. |
|
|
|
|
|
We have sc_main at line 15, which is top level function like main in C++. In sc_main we instanciate module hello_world. On line 18 we call the function say_hello. |
|
|
|
|
|
Hello World Program Output
|
|
|
|
|
|
To compile and simulate the above example in Linux, use below commands. |
|
|
|
|
|
- g++ -I. -I$SYSTEMC_HOME/include -L. -L$SYSTEMC_HOME/lib-linux -o sim hello.cpp -lsystemc -lm
- ./sim
|
|
|
|
|
|
In the above command line options $SYSTEMC_HOME is the SystemC installation directory. Below is output of the execution of program hello.cpp |
|
|
|
|
|
SystemC 2.0.1 --- Oct 6 2006 19:17:37
Copyright (c) 1996-2002 by all Contributors
ALL RIGHTS RESERVED
Hello World.
|
|
|
|
|
|
|
|
|
|
|
|
Counter Design Block
|
|
|
|
|
|
|
|
|
|
|
|
Counter Design Specs
|
|
|
|
|
|
- 4-bit synchronous up counter.
- active high, asynchronous reset.
- Active high enable.
|
|
|
|
|
|
Counter Design
|
|
|
|
|
|
1 //-----------------------------------------------------
2 // This is my second Systemc Example
3 // Design Name : first_counter
4 // File Name : first_counter.cpp
5 // Function : This is a 4 bit up-counter with
6 // Synchronous active high reset and
7 // with active high enable signal
8 //-----------------------------------------------------
9 #include "systemc.h"
10
11 SC_MODULE (first_counter) {
12 sc_in_clk clock ; // Clock input of the design
13 sc_in<bool> reset ; // active high, synchronous Reset input
14 sc_in<bool> enable; // Active high enable signal for counter
15 sc_out<sc_uint<4> > counter_out; // 4 bit vector output of the counter
16
17 //------------Local Variables Here---------------------
18 sc_uint<4> count;
19
20 //------------Code Starts Here-------------------------
21 // Below function implements actual counter logic
22 void incr_count () {
23 // At every rising edge of clock we check if reset is active
24 // If active, we load the counter output with 4'b0000
25 if (reset.read() == 1) {
26 count = 0;
27 counter_out.write(count);
28 // If enable is active, then we increment the counter
29 } else if (enable.read() == 1) {
30 count = count + 1;
31 counter_out.write(count);
32 cout<<"@" << sc_time_stamp() <<" :: Incremented Counter "
33 <<counter_out.read()<<endl;
34 }
35 } // End of function incr_count
36
37 // Constructor for the counter
38 // Since this counter is a positive edge trigged one,
39 // We trigger the below block with respect to positive
40 // edge of the clock and also when ever reset changes state
41 SC_CTOR(first_counter) {
42 cout<<"Executing new"<<endl;
43 SC_METHOD(incr_count);
44 sensitive << reset;
45 sensitive << clock.pos();
46 } // End of Constructor
47
48 }; // End of Module counter
You could download file first_counter.cpp here
|
|
|
|
|
|
Counter Test Bench
|
|
|
Any digital circuit, no matter how complex, needs to be tested. For the counter logic, we need to provide a clock and reset logic. Once the counter is out of reset, we toggle the enable input to the counter, and check the waveform to see if the counter is counting correctly. The same is done in SystemC |
|
|
|
|
|
|
|
|
|
|
|
Counter testbench consists of clock generator, reset control, enable control and monitor/checker logic. Below is the simple code of testbench without the monitor/checker logic. |
|
|
|
|
|
1 #include "systemc.h"
2 #include "first_counter.cpp"
3
4 int sc_main (int argc, char* argv[]) {
5 sc_signal<bool> clock;
6 sc_signal<bool> reset;
7 sc_signal<bool> enable;
8 sc_signal<sc_uint<4> > counter_out;
9 int i = 0;
10 // Connect the DUT
11 first_counter counter("COUNTER");
12 counter.clock(clock);
13 counter.reset(reset);
14 counter.enable(enable);
15 counter.counter_out(counter_out);
16
17 sc_start(1);
18
19 // Open VCD file
20 sc_trace_file *wf = sc_create_vcd_trace_file("counter");
21 // Dump the desired signals
22 sc_trace(wf, clock, "clock");
23 sc_trace(wf, reset, "reset");
24 sc_trace(wf, enable, "enable");
25 sc_trace(wf, counter_out, "count");
26
27 // Initialize all variables
28 reset = 0; // initial value of reset
29 enable = 0; // initial value of enable
30 for (i=0;i<5;i++) {
31 clock = 0;
32 sc_start(1);
33 clock = 1;
34 sc_start(1);
35 }
36 reset = 1; // Assert the reset
37 cout << "@" << sc_time_stamp() <<" Asserting reset\n" << endl;
38 for (i=0;i<10;i++) {
39 clock = 0;
40 sc_start(1);
41 clock = 1;
42 sc_start(1);
43 }
44 reset = 0; // De-assert the reset
45 cout << "@" << sc_time_stamp() <<" De-Asserting reset\n" << endl;
46 for (i=0;i<5;i++) {
47 clock = 0;
48 sc_start(1);
49 clock = 1;
50 sc_start(1);
51 }
52 cout << "@" << sc_time_stamp() <<" Asserting Enable\n" << endl;
53 enable = 1; // Assert enable
54 for (i=0;i<20;i++) {
55 clock = 0;
56 sc_start(1);
57 clock = 1;
58 sc_start(1);
59 }
60 cout << "@" << sc_time_stamp() <<" De-Asserting Enable\n" << endl;
61 enable = 0; // De-assert enable
62
63 cout << "@" << sc_time_stamp() <<" Terminating simulation\n" << endl;
64 sc_close_vcd_trace_file(wf);
65 return 0;// Terminate simulation
66
67 }
You could download file first_counter_tb.cpp here
|
|
|
|
|
|
SystemC 2.0.1 --- Oct 6 2006 19:17:37
Copyright (c) 1996-2002 by all Contributors
ALL RIGHTS RESERVED
Executing new
@0 s Asserting reset
WARNING: Default time step is used for VCD tracing.
@10 ns De-Asserting reset
@40 ns Asserting Enable
@41 ns :: Incremented Counter 0
@43 ns :: Incremented Counter 1
@45 ns :: Incremented Counter 2
@47 ns :: Incremented Counter 3
@49 ns :: Incremented Counter 4
@51 ns :: Incremented Counter 5
@53 ns :: Incremented Counter 6
@55 ns :: Incremented Counter 7
@57 ns :: Incremented Counter 8
@59 ns :: Incremented Counter 9
@61 ns :: Incremented Counter 10
@63 ns :: Incremented Counter 11
@65 ns :: Incremented Counter 12
@67 ns :: Incremented Counter 13
@69 ns :: Incremented Counter 14
@71 ns :: Incremented Counter 15
@73 ns :: Incremented Counter 0
@75 ns :: Incremented Counter 1
@77 ns :: Incremented Counter 2
@79 ns :: Incremented Counter 3
@80 ns De-Asserting Enable
@80 ns Terminating simulation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|