Reconfigurable Computing S. Reda, Brown University Reconfigurable Computing (EN2911X, Fall07) Lecture 14: SystemC (2/3) Prof. Sherief Reda Division of Engineering, Brown University
Reconfigurable Computing S. Reda, Brown University Ports module process in1 clk out Ports are the means through which modules communicate with other modules. There are three basic port types that inherent from sc_port : Input ports for receiving data Output ports for sending out data Input/output ports which combine the two An input port must be of type sc_in which is a template SystemC class sc_in portname declares a input port of type T example: sc_in > myinport special case : sc_in_clk clkname declares an input port of type bool
Reconfigurable Computing S. Reda, Brown University Port types An output port must be of type sc_out which is a template SystemC class sc_out portname declares a output port of type T example: sc_in > myinport Special: sc_out_clk clkname declares an output port of type bool An input/output port must be of type sc_inout, which is a templatized primitive SystemC class sc_inout portname declares a in/out port of type T example: sc_inout > myinport
Reconfigurable Computing S. Reda, Brown University Synthesizable operations associated with ports There are two operations associated with ports read and write. –sc_inout ports can be written to and read from –sc_in ports can only be read from –sc_out ports can only be written to Examples sc_in portname; T thedata = portname.read(); sc_out portname; portname.write(data);
Reconfigurable Computing S. Reda, Brown University Port mapping Ports can be mapped in any order. If myModuleA is an object of class ModuleA myModuleA.a1(in1); myModuleA.a2(in2); myModuleB.b2(in3); myModuleB.b3(out1);
Reconfigurable Computing S. Reda, Brown University Hierarchical design A module may contain sub-module instances in its body to form hierarchy There are no restrictions on the level of the hierarchy
Reconfigurable Computing S. Reda, Brown University Hierarchical design SC_MODULE(Top) { sc_in > in1; sc_in > in2; sc_in > in3; sc_out > out; // module instances ModuleA *myModuleA; ModuleB *myModuleB; // signal declarations signal > sig; SC_CTOR(Top) { … } }; SC_CTOR(Top) { myModuleA = new ModuleA (“mA”); ModuleA->a1(in1); ModuleA->a2(in2); ModuleA->a3(sig); MyModuleB = new ModuleB (“mB”); ModuleB->b1(sig); ModuleB->b2(in3); ModuleB->b3(out1); }
Reconfigurable Computing S. Reda, Brown University Processes Processes describe the parallel behavior of hardware systems. Processes execute concurrently. The code within a process, however, executes sequentially. Three types of SystemC processes: –SC_THREAD –SC_THREAD (special ) –SC_METHOD Process declaration must exist within its module constructor. process’s sensitivity to clock, resets and other signal ports are specified when the process is declared SC_MODULE(my_module) { sc_in_clk clock; void my_thread(); … SC_CTOR(my_module) { SC_THREAD (my_thread); sensitive << clock.pos(); };
Reconfigurable Computing S. Reda, Brown University Process body A thread process body within a module definition SC_MODULE (my_module) { void my_method();... }; A thread process body outside a module definition The process body contains the implementation of the process. Like C++ functions, it may be defined: within the module definition, typically in a.h header file outside the module, typically in a.cpp file SC_MODULE (my_module) { void my_method() {... }... }; my_module.h void my_module::my_thread() {... } my_module.cpp
Reconfigurable Computing S. Reda, Brown University SC_THREAD processes A thread is a process that is called only once and never gets called again after termination (unless with a global reset) The thread process body is composed of two stages separated by the wait() statement The synthesis stage of a thread process should be typically written as a non-terminating loop. wait() can be used in the synthesis part which suspends the thread and resumes upon an event from the thread’s associated clock edge void my_thread() { …. // compile-time initialization stage wait(); ….. // run-time hardware synthesis stage }
Reconfigurable Computing S. Reda, Brown University Thread mechanisms Any statements between two wait() statements will be constructed as combinational logic. These two examples creates the same logic wait(); c = (a&0xF0) >> 4) | (b&0x0F)<<4); wait(); c = (a&0xF0); c = c >> 4; d = (b&0x0F); d = d <<4; e = c|d; wait(); The synthesis stage runs when it receives the signal to which the process is sensitive. The thread may be sensitive to a positive edge or a negative edge but not both. All the values assigned to variables in the initialization stage must be resolvable at compile-time. They can’t contain signal or port reads
Reconfigurable Computing S. Reda, Brown University Thread example void my_module::run() { int a, b; // end of compile-time initialization stage wait(); // start of runtime synthesized hardware stage a = 1; // clock cycle 1 wait(); a = a+1; // clock cycle 2 b = 5; // clock cycle 2 wait() a = b; // clock cycle 3 b = b+1; // clock cycle 3 wait(); ….. }
Reconfigurable Computing S. Reda, Brown University SC_METHOD processes A method process can be used to model either synchronous or combinational hardware SC_METHOD process must not contain wait() statements and must always terminate A method must be sensitive to all the ports and signals it reads Executed every time a trigger or temporal event occurs. Each signal and port written to must be written to on every execution of the SC_METHOD SC_MODULE(adder) { sc_in > in1; sc_in > in2; sc_out > out; public: void add() { out = in1.read()+in2.read(); } SC_CTOR(adder) { SC_METHOD(add); sensitive << in1 << in2; }
Reconfigurable Computing S. Reda, Brown University Process sensitivity list A sensitivity list identifies which input ports and signals trigger execution of the code within a process. A process can read from and write to ports, internal signals, and internal variables. Processes use signals to communicate with each other. One process can cause another process to execute by assigning a new value to a signal that interconnects them. SC_MODULE (my_module) { void my_thread(); sc_port clock;... SC_CTOR (my_module) { SC_THREAD (my_thread); sensitive<<clock.pos(); }... };
Reconfigurable Computing S. Reda, Brown University Synthesis and compilation flow Rest of code (testbenches, SW code) Synthesizable subset Celoxica agility synthesizer Quartus II Verilog/edif Visual C++ SystemC library executable
Reconfigurable Computing S. Reda, Brown University Using signals to communicate between processes and modules SW HEX0 runadd display x SC_MODULE(incr) { private: sc_signal x; int d[8]; public: sc_in > SW; sc_out > HEX0; void runadd(); void display(); public: SC_CTOR(incr) { SC_METHOD(runadd); sensitive << SW; SC_METHOD(display); sensitive << x; }; incr incr.h
Reconfigurable Computing S. Reda, Brown University Implementing the processes void incr::display() { int digit, i=0; int t=x; sc_uint hex; digit=t%10; if (digit == 0) hex = 64; else if (digit == 1) hex = 121; else if (digit == 2) hex = 36; else if(digit == 3) hex = 48; else if(digit == 4) hex = 25; else if(digit == 5) hex = 18; else if(digit == 6) hex = 3 else if(digit == 7) hex = 120; else if(digit == 8) hex = 0; else if(digit == 9) hex = 24; HEX0=hex; } void adder::runadd() { int y; y=SW.read(); x=y+1; } SW HEX0 runadd display x incr
Reconfigurable Computing S. Reda, Brown University Synthesis point: ag_main #include #include // void ag_main() { adder incr(“incr"); } Use the produced Verilog file from Celoxica’s Agility compiler with the Quartus II software
Reconfigurable Computing S. Reda, Brown University Testing and verifying your code in a C++ development environment SW HEX0 runadd display x incrtestbench SC_MODULE(tester) { int x; public: sc_out > SW; sc_in > HEX0; void run(void) { wait(); while(1) { cout << "enter a number" << endl; cin >> x; SW.write(x); wait(); cout << "answer " << HEX0.read() ; } SC_CTOR(tester) { SC_THREAD(run); sensitive << HEX0 ; } };
Reconfigurable Computing S. Reda, Brown University Simulation entry point sc_main #include #include "adder.sc.h" using namespace std int sc_main(int argc, char *argv[]) { sc_signal > SW; sc_signal > HEX0; incr incr1(“incr1"); tester test1("test"); ad1.SW(SW); ad1.HEX0(HEX0); test1.SW(SW); test1.HEX0(HEX0); sc_start(); return 0; } elaboration execution
Reconfigurable Computing S. Reda, Brown University Launch your executable (simulator) This time you are using the Visual C++ compiler together with the SystemC library Simulate your system by executing it on the command prompt