Previous: System Time and Sequential Circuit Elements, Up: Introduction to libLCS


3.5 Utility Modules

libLCS provides few off-the-shelf utility modules which a user can use in his/her simulations. Each of these modules is described in detail in this section.

3.5.1 Buffer

The Buffer template class can be used as a delay buffer for any bus. This class requires two template parameters. The first parameter indicates the number of lines in the bus for which it acts as a buffer, and the second parameter indicates the delay. The declaration of the Buffer class is as follows:

     template <unsigned int lines, unsigned int delay = 0>
     class Buffer;

The Buffer class is defined in the header file lcs/buffer.h. Note that the above declaration indicates a default value of 0 for the delay of the buffer module. A small example illustrating its usage is as below. The buffer class constructor requires the output bus as the first argument, and the input bus as the second argument.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     using namespace std;
     
     int main(void)
     {
         Bus<5> output, input;
     
         // Declaring a 5 input buffer with a delay of
         // 5 system time units.
         Buffer<5, 5> buffer(output, input);
     
         ChangeMonitor<5> cm(input, "input", DUMP_ON);
         ChangeMonitor<5> cb(output, "output", DUMP_ON);
     
         Tester<5> tester(input);
     
         Simulation::setStopTime(5000);
         Simulation::start();
     
         return 0;
     }

3.5.2 FanOut

The FanOut template class (which requires two template parameters) encapsulates a module which takes a single input and generates a user specified number of copies of the input as output. The desired number of outputs should be specified as the first template parameter. The second template parameter specifies the input to output propogation delay. The declaration of the FanOut class is as follows:

     template <unsigned int n = 1, unsigned int delay = 0>
     class FanOut;

The FanOut class is defined in the header file lcs/fanout.h. Note that the above declaration indicates a default value of 1 output line, and a default value of 0 propogation delay of the fanout module. A small example illustrating its usage is as below. The FanOut class constructor requires the output bus as the first argument, and the single-line input bus as the second argument.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     using namespace std;
     
     int main(void)
     {
         Bus<5> output;
         Clock clk = Clock::getClock();
         
         // Initialising a FanOut object which takes the 
         // system clock as input and generates 5 copies 
         // of it. Also, the time delay between the new 
         // copies and the input clock pulse is specified 
         // through the second template parameter as 5 
         // system time units.
         FanOut<5, 5> fanout(output, clk); 
     
         ChangeMonitor<1> cm(clk, "clk", DUMP_ON);
         ChangeMonitor<5> cb(output, "output", DUMP_ON);
     
         Simulation::setStopTime(5000);
         Simulation::start();
     
         return 0;
     }

3.5.3 Register

libLCS provides a module class, a template class named Register, which encapsulates a hardware register. The register module reuires one input data bus, one clock signal input, and one output data bus. The input bus and the output bus should have the same width. This width is also equal to the width of the register. The input data bus line states are tranferred to the output data bus lines at the occurance of a pulse edge on the clock signal input.


The Register class is defined in the header file register.h. The class declaration is as follows:
     template<unsigned int bits = 1, PulseEdge edgeType = POS_EDGE, unsigned int delay = 0>
     class Register; // Derived publicly from the class Module.

The third template parameter delay indicates the input to output propogation delay of the register module in system time units. Below is a simple example, which uses feedback around a (2-bit register + two NOT gates) system, to illustrate the usage of the module class Register.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     
     int main(void)
     {
         Bus<2> in(3), out(0);
     
         Clock clk = Clock::getClock();
     
         // Initialising a 2-bit register which 
         // which responds to positive edges on
         // its clock input. The input to output
         // propogation delay of the register is 
         // 0 time units.
         Register<2, POS_EDGE, 0> reg(out, in, clk);
     
         Not<> n1(in[0], out[0]);
         Not<> n2(in[1], out[1]);
     
         ChangeMonitor<2> cmop(out, "Output");
     
         Simulation::setStopTime(2000);
         Simulation::start();
     
         return 0;
     }

It is upto to the reader to compile and run to verify the result of the above simulation.


The Register class has an overloaded operator[] as its member which enables reading (but not writing) of the register bits by indexing suitably.

3.5.4 Counter

A template module class Counter is among the off-the-shelf utilities classes provided by libLCS. The template parameters specify the bit-width of the counter and the triggering event which leads to an increment in the count value of the counter. The class Counter is defined in the header file counter.h. The class declaration is as follows.

     template<unsigned int bits, LineEvent event = LINE_POS_EDGE>
     class Counter; // Derived publicly from the class Module

The following example illustrates the usage of the class Counter. It is upto to the user to compile and run to verify the result of the simulation.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     
     int main(void)
     {
         Bus<4> out;
         Clock clk = Clock::getClock();
     
         // Initialising a 4-bit counter which 
         // increments the count at the occurance
         // of a  positive edge on its clock input.
         Counter<4, LINE_POS_EDGE> cnt(out, clk);
     
         ChangeMonitor<4> cmop(out, "Count");
     
         Simulation::setStopTime(4000);
         Simulation::start();
     
         return 0;
     }

3.5.5 Shift Register

There exists an off-the-shelf template module class which encapsulates a shift register. It is defined in the header file lcs/shiftreg.h and has the following class declaration.

     template <unsigned int bits = 1, PulseEdge edgeType = POS_EDGE, Shift shift = LEFT_SHIFT, unsigned int delay = 0>
     class ShiftReg; // Derived publicly from the class Module.

As can be seen from the above class declaration, the shift register class requires four template arguments: 1. Number of bits in the register (that is, the register width), 2. The type of pulse edge on the clock input which triggers the shift operation, 3. A parameter indicating the type of shift (left shift or right shift), 4. The propogation delay. The following example illustrates the usage of the off-the-shelf shift register class.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     
     int main(void)
     {
         Bus<4> out(0), count(0);
         Clock clk = Clock::getClock();
     
         // We will make use of the second bit of the counter output 
         // as the input to our shift register.
         Counter<4> counter(count, clk);
     
         // Initialising a shift register of width 4 bits which is triggered
         // on occurance of a positive edge on its clock input, and shifts the 
         // input right. The input to the shift register is the second bit of
         // the counter module.
         ShiftReg<4, POS_EDGE, RIGHT_SHIFT> reg(out, count[1], clk);
     
         ChangeMonitor<4> cmop(out, "Reg Value");
     
         Simulation::setStopTime(4000);
         Simulation::start();
     
         return 0;
     }