- A Logic Circuit Simulation Library in C++





(libLCS Example) Functional module of a 4-bit counter


The aim of this example is to implement a functional module for a positive edge triggered 4-bit counter. The block digram for the module is as shown below. It is a very simple module without a reset pin.

four_bit_counter_module.jpg

The code to implement and test the above module is as follows.

#include <iostream>
#include <lcs/bus.h>
#include <lcs/clock.h>
#include <lcs/module.h>
#include <lcs/simul.h>
#include <lcs/changeMonitor.h>

using namespace lcs;
using namespace std;

// Let the name of our counter module be Counter.
// It has to be derived from the class lcs::Module.
class Counter : public Module
{
public:

    // The constructor should take the output bus and the
    // clock input as the arguments.
    Counter(const Bus<4> &outbus, const InputBus<> &clk);

    // The virtual destructor.
    virtual ~Counter();

    // Since our counter module will be triggered by the
    // positive edge of the clock, it has to override the
    // function lcs::Module::onPosEdge.
    virtual void onPosEdge(int portId);

private:
    // Private members to store references to the output
    // bus and the clock input.
    Bus<4> outBus;
    InputBus<> clock;
};

Counter::Counter(const Bus<4> &outbus, const InputBus<> &clk)
       : Module(), outBus(outbus), clock(clk)
{
    // Register with the clock input to be notified of
    // a lcs::LINE_POS_EDGE event.
    clock.notify(this, LINE_POS_EDGE, 0);

    // Lock the outbus. Note that we are using the default
    // parameter of zero for the delay. See lcs::Bus::lock
    // for more information.
    outBus.lock(this);

    // Set the value on the output bus value to zero so that the
    // counter value is zero immediately after construction.
    Bus<4>::LineAccessor output = outBus.getLineAccessor(this);
    output = 0;
}

Counter::~Counter()
{
    // De-register with the clock input so that it will stop
    // notifying line events to a non-existant module.
    clock.stopNotification(this, LINE_POS_EDGE, 0);

    // Unlock the output bus so as to make it available for
    // use by other modules.
    outBus.unLock(this);
}

void Counter::onPosEdge(int portId)
{
    int val;
    outBus >> val; // We are making use of the over loaded operator>>
                   // to write the bus contents into an integer variable.

    Bus<4>::LineAccessor output = outBus.getLineAccessor(this);
    if (val == 15) // If the bus holds a value of fifteen, then reset the value to zero.
    {
        output = 0;
    }
    else // If the bus holds a value other than 15, then increment it by 1.
    {
        output = val+1;
    }
}

int main(void)
{
    Bus<4> output;
    Clock clk = Clock::getClock();

    Counter counter(output, clk);

    ChangeMonitor<4> count(output, string("Count"));

    Simulation::setStopTime(4000);
    Simulation::start();
    Simulation::terminate();

    return 0;
}

The output when the above program is compiled and run is as follows.

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

Copyright © 2006, 2007 Siva Chandra