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.
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; }
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; }
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.
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; }
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; }