Simple adder ipblock

From Gezel2

Jump to: navigation, search

Here is an example how you can develop your own ipblock. An ipblock in GEZEL is a mechanism to generate new simulation primitives (in C++) that look like black boxes in GEZEL. We develop a small adder, and show an example of the GEZEL code, the C++ code, and the compilation commands.

GEZEL code

Below is the GEZEL code. It includes an ipblock definition (ipblock ablock ..) which selects an ipblock of type 'myblock', and which passes a parameter 'thisparam=thatval'. The ipblock is included in a small testbench that feeds an incrementing sequence of numbers on the 'a' input and a constant value 2 on the 'b' input.

 ipblock ablock(in a, b : ns(8); out c : ns(8)) {
   iptype "myblock";
   ipparm "thisparam=thatval";
 }
 
 dp top {
   sig a, b, c : ns(8);
   reg a1 : ns(8);
   use ablock(a, b, c);
   always {
     a = a1;
     b = 2;
     $display("a ", a, " b ", b, " c ",c);
     a1 = a1 + 1;
   }
 }
 
 system S {
   top;
 }

C++ code

We need to design a C++ class to describe the implementation of this ipblock. The following file shows this C++ class. This class MUST be called myblock. This is how the simulator figures out the correspondence between the 'myblock' mentioned in the GEZEL file, and the C++ implementation to be used for 'myblock'. Moreover, the class MUST be compiled into a shared library called 'libmyblock.so' (more on that below).

class myblock : public aipblock {
 public:
  myblock(char *name);
  void setparm(char *);
  void run();
  void out_run();
  bool checkterminal(int n, char *tname, aipblock::iodir d);
  bool cannotSleepTest();
  bool needsWakeupTest();
};

We will discuss each of the methods below.

  • The constructor initializes the class. All ipblock inherit from a baseclass aipblock. The default initialization for aipblock is to pass it the instance name (which will be 'ablock' when parsing the GEZEL file above).
 myblock::myblock(char *name) : aipblock(name) {}
  • The setparm method is called for each 'ipparm' that is mentioned in the GEZEL file. The kind and number of ipparm is user-defined, and depends on the application. In this example, we simply print the parameter and return.
 void myblock::setparm(char *_name) {
   cerr << "set parm: " << _name << "\n";
 }
  • The run method is called once per cycle. This method must read the inputs and produce corresponding outputs. There is a predefined array 'ioval[]' (actually, a vector<gval *>) for each input/output on an ipblock. The matching between inputs/outputs in GEZEL and C++ is positional: the first input or output is connected to ioval[0], the second to ioval[1], and so forth. Since this is a simple adder block, the run method will simply add two inputs and return the result. Note that gval is GEZELs arbitrary-length internal data type. Consult the source code for the operations available on gval (listed in gval.h).
 void myblock::run() {
   ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());
 }
  • The out_run method is used when an ipblock uses registered outputs. It is empty in this case since we are developing a combinatorial block.
 void myblock::out_run() {
 
 }
  • The checkterminal method is called by the parser for each input and output of the ipblock. The calling order follows the position of inputs and outputs. This function performs a simple check if the user has included the inputs and outputs with the correct direction and port name.
 bool myblock::checkterminal(int n, char *tname, aipblock::iodir d) {
   switch(n) {
   case 0 :
     return (isinput(d)  && isname(tname, "a"));
     break;
   case 1 :
     return (isinput(d) && isname(tname, "b"));
     break;
   case 2 :
     return (isoutput(d) && isname(tname, "c"));
     break;
   }
   return false;
 }
  • The cannotSleepTest and needsWakeupTest methods control the simulator scheduler. For typical ipblock (like the current one), you make them return default values: false for cannotSleepTest and true for needsWakeupTest. With more advanced ipblock such as cosimulation interfaces, these methods enable control of the GEZEL scheduler from within a foreign simulator. Refer to the GEZEL User Manual or study the gplatform source code for more information.
 bool myblock::cannotSleepTest(){
   return false;
 }
 
 bool myblock::needsWakeupTest(){
   return true;
 }
  • Finally, the create_myblock C function (which MUST be called create_myblock, ie. the suffix must match the class name) instantiates a myblock class and returns a pointer to it. It is part of the dynamic-class-loading mechanism.
 extern "C" aipblock *create_myblock(char *instname) {
   return new myblock(instname);
 }

Simulation

Before simulation can start, the C++ code must be compiled into a shared library. This is done with the following commands. Note the -fPIC flag during compilation and the -shared flag during linking. The exact paths to use will depend on the installation directories used for GEZEL.

 g++ -fPIC -O3 -I/opt/gezel-2.0//include/gezel -c myblock.cxx 
 g++ -shared -O3 -Wl,--rpath -Wl,/home/schaum/gezel/devel/build/lib \
    myblock.o /opt/gezel-2.0/lib/libipconfig.so \
   /opt/gezel-2.0//lib/libfdl.so -lgmp -ldl -o libmyblock.so

Once you have the libmyblock.so, you can simply start the simulator (fdlsim). When an ipblock is encountered which is not available within the simulator, the dynamic-link library path will be searched for a library of a matching name. If an ipblock of type 'myblock' is needed, a search is done for a shared library 'libmyblock.so'. When the library is found, it is linked-in to the simulation and the create_myblock function is called. All of this is transparent for the user. Here is the simulation output.

 /opt/gezel-2.0//bin/fdlsim ipb.fdl 5
 set parm: thisparam=thatval
 a 0 b 2 c 2
 a 1 b 2 c 3
 a 2 b 2 c 4
 a 3 b 2 c 5
 a 4 b 2 c 6

Ipblock give considerable flexibility in design and simulation development. They allow GEZEL to be integrated into a bigger simulation setup without having to open up the simulator internals. Very often, when you find that GEZEL cannot describe a particular feature or situation, an ipblock may be the solution.

Personal tools