Next: , Previous: Logic Gates, Up: Introduction to libLCS


3.4 System Time and Sequential Circuit Elements

In this section, we will present the concept of system time, the class Clock, the off-the-shelf flipflop modules, and the module FrequencyDivider.

3.4.1 System Time

The libLCS simulation system has a system timer. This timer is turned on automatically whenever a libLCS simulation is started. The timer starts ticking up from time zero until the stop-time. As presented in the section A Simple Example, a libLCS simulation starts with a call to the static member function Simulation::start(). A simulation lasts for the duration for which the system timer was set to run for. The stop time has to be set by a call to the static member function Simulation::setStopTime(unsigned int).

3.4.2 The class Clock

Apart from a system timer, the libLCS simulation system also has a clock provided through the singleton class Clock. It is defined in the header file lcs/clock.h. It is essestially a pulse generator with equal high and low periods. It should be obtained through the static function Clock::getClock(). By default, the pulse width is set to 100 system time units (equivalent to a time period of 200 system time units). It can be set to a value of one's choice by using the static member function Clock::setPulseWidth(unsigned int). A detailed example, which illustrates the use of a clock, is presented in a later subsection below.

3.4.3 Flipflops

There exist of-the-shelf modules for D and JK flipflops in libLCS. They are provided as template classes requiring two template parameters. The first template parameter determines if the flipflop is positive edge triggered or negetive edge triggered. The second template parameter determines the input to output propogation delay of the flipflop. The following are the template class declarations for the flipflop modules.

  1. The D-flipflop template class declaration:
              template<PulseEdge type = POS_EDGE, unsigned int delay = 0>
              class DFlipFlop;
         

  2. The JK-flipflop template class declaration:
              template<PulseEdge type = POS_EDGE, unsigned int delay = 0>
              class JKFlipFlop;
         

The trigger type of the flipflops is specified by an enumerated data type PulseEdge. The first template parameter in the above class declarations is of this type. It takes a default value of POS_EDGE which specifies a positive edge triggered flipflop. The other value it can take is NEG_EDGE which indicates a negetive edge triggered flipflop.
3.4.3.1 Flipflop header files

The following is the list of all flipflop modules and the corresponding header files in which the flipflop module classes are defined.

  1. D-flipflop
              lcs/dflipflop.h
         

  2. JK-flipflop
              lcs/jkflipflop.h
         

3.4.4 An Example

In this subsection, we will present an example which illustrates the use of the system timer, the system clock and the D-flipflop modules. The aim of the example is to construct and simulate a 4-bit counter using D-flipflops. The circuit diagram is as below. The bit sequence D3D2D1D0 in that order is the output of our counter circuit.

four_bit_counter.jpg
The following is the full listing of the program which constructs and simulates the circuit shown in the above figure. There exists a general rule with all flipflop module class constructors. The outputs of the modules will be the passed as arguments to the constructors before the inputs are passed as arguments. In case of D-flipflops, the first argument to the flipflop constructor is the Q output. The next arguments are the D input, clock input, and the active-high reset input in that order. (In case of a JK-flipflop, the order of arguments to the constructor is as follows: the Q output, J input, K input, clock input, the active-high reset input. All arguments are single-line bus objects.)
     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     using namespace std;
     
     int main(void)
     {
         // Declare single line busses for each node in the
         // circuit. The flipflop output nodes have been set
         // to zero to start with. The busses are initialised
         // with the default template parameter of 1. The reset
         // line to be used for all the flipflops has been set 
         // to 0.
         Bus<> q0(0), q1(0), q2(0), q3(0), d0, d1, d2, d3, rst(0);
     
         // Initialise a clock object.
         Clock clk = Clock::getClock();
     
         // Initialise the NOT gates in the circuit. The NOT
         // gates are initialised with the default template
         // parameter corresponding to a propogation delay of
         // zero.
         Not<> n1(d0, q0), n2(d1, q1), n3(d2, q2), n4(d3, q3);
     
         // Initialise the 4 positive edge-triggered flipflops
         // using the default template parameters.
         DFlipFlop<> ff1(q0, d0, clk, rst), ff2(q1, d1, q0, rst), 
                     ff3(q2, d2, q1, rst), ff4(q3, d3, q2, rst);
     
         // Initialise a ChangeMonitor object to monitor
         // the output bit sequence of our counter circuit.
         ChangeMonitor<4> count((d0,d1,d2,d3), string("Count"), DUMP_ON);
     
         Simulation::setStopTime(4000); // Set the stop time.
         Simulation::start(); // Start the simulation.
     
         return 0;
     }

When the above program is compiled and executed, the following output is obtained on the standard output.

At time: 0,     Count: 1111
At time: 100,   Count: 0000
At time: 300,   Count: 0001
At time: 500,   Count: 0010
At time: 700,   Count: 0011
At time: 900,   Count: 0100
At time: 1100,  Count: 0101
At time: 1300,  Count: 0110
At time: 1500,  Count: 0111
At time: 1700,  Count: 1000
At time: 1900,  Count: 1001
At time: 2100,  Count: 1010
At time: 2300,  Count: 1011
At time: 2500,  Count: 1100
At time: 2700,  Count: 1101
At time: 2900,  Count: 1110
At time: 3100,  Count: 1111
At time: 3300,  Count: 0000
At time: 3500,  Count: 0001
At time: 3700,  Count: 0010
At time: 3900,  Count: 0011

Since the ChangeMonitor object for the output has been initialed with DUMP_ON, a VCD file for the simulation is generated. The following is the screenshot of the GTKWave plot of the generated VCD file.
4_bit_counter_using_dff.jpg

3.4.5 The class FrequencyDivider

libLCS provides a module which divides the frequency of the input signal by a specified factor. This module, defined in the file lcs/freqdiv.h, is provided as a template class with the following declaration.

     template<unsigned int factor, unsigned int delay = 0>
     class FrequencyDivider;

The first template parameter factor specifies the factor by which the input frequency is divided. The second template parameter delay, which takes a default value of 0, specifies the input to output propogation delay. The example below illustrates the usage of a frequency divider module. It uses the system clock as an input to the frequency divider which divides the clock frequency by 7. A zero delay module is used.

     
     #include <lcs/lcs.h>
     
     using namespace lcs;
     using namespace std;
     
     int main(void)
     {
         Bus<1> b;
         Clock clk = Clock::getClock();
     
         // A frequency divider, which divides 
         // the input clock frequecy by 7 and has
         // a zero propogation delay, is declared.
         // The first argument to the constructor 
         // is the output of the frequency divider, 
         // and the second argument is the input.
         // In this case, we are using the system 
         // clock as the input.
         FrequencyDivider<7> fd(b, clk);
     
         ChangeMonitor<1> cm(clk, "clk");
         ChangeMonitor<1> cb(b, "b");
     
         Simulation::setStopTime(5000);
         Simulation::start();
     
         return 0;
     }

When the above program is compiled and executed, the following output is obtained.


At time: 0,	b: 0
At time: 100,	clk: 1
At time: 100,	b: 1
At time: 200,	clk: 0
At time: 300,	clk: 1
At time: 400,	clk: 0
At time: 500,	clk: 1
At time: 600,	clk: 0
At time: 700,	clk: 1
At time: 800,	clk: 0
At time: 800,	b: 0
At time: 900,	clk: 1
At time: 1000,	clk: 0
At time: 1100,	clk: 1
At time: 1200,	clk: 0
At time: 1300,	clk: 1
At time: 1400,	clk: 0
At time: 1500,	clk: 1
At time: 1500,	b: 1
At time: 1600,	clk: 0
At time: 1700,	clk: 1
At time: 1800,	clk: 0
At time: 1900,	clk: 1
At time: 2000,	clk: 0
At time: 2100,	clk: 1
At time: 2200,	clk: 0
At time: 2200,	b: 0
At time: 2300,	clk: 1
At time: 2400,	clk: 0
At time: 2500,	clk: 1
At time: 2600,	clk: 0
At time: 2700,	clk: 1
At time: 2800,	clk: 0
At time: 2900,	clk: 1
At time: 2900,	b: 1
At time: 3000,	clk: 0
At time: 3100,	clk: 1
At time: 3200,	clk: 0
At time: 3300,	clk: 1
At time: 3400,	clk: 0
At time: 3500,	clk: 1
At time: 3600,	clk: 0
At time: 3600,	b: 0
At time: 3700,	clk: 1
At time: 3800,	clk: 0
At time: 3900,	clk: 1
At time: 4000,	clk: 0
At time: 4100,	clk: 1
At time: 4200,	clk: 0
At time: 4300,	clk: 1
At time: 4300,	b: 1
At time: 4400,	clk: 0
At time: 4500,	clk: 1
At time: 4600,	clk: 0
At time: 4700,	clk: 1
At time: 4800,	clk: 0
At time: 4900,	clk: 1
At time: 5000,	clk: 0
At time: 5000,	b: 0