- A Logic Circuit Simulation Library in C++





(libLCS Example) 2-bit fulladder module as a hybrid of behavioral and block level compenents


The aim of this example is to illustrate defining and implementing modules which are constructed as a hybrid of other modules and behavioral models. We take a simple example wherein a 2-bit fulladder module is built using two 1-bit fulladder components. One of these 1-bit fulladder is the off-the-shelf fulladder module provided in libLCS. The other fulladder module is implemented as a behavioral model. The block diagram for such a scheme is as follows.

2bit_fa_module.jpg


The following code is the complete program which implements the above 2-bit fulladder module.

#include <lcs/lcs.h>

using namespace lcs;

// Since the module is going to have few behavioral constructs, we should derive 
// it from the base class lcs::Module.
class TwoBitFullAdder : public Module
{
public:
    // The constructor takes arguments which establish the external connections.
    TwoBitFullAdder(const Bus<3> &sum, const InputBus<2> &a, const InputBus<2> &a);

    ~TwoBitFullAdder();

    // This is a virtual function which has to be overidden. It is declared in the 
    // base class Module. This is the function which should incorporate the behavioral
    // model for a one bit fulladder.
    virtual void onStateChange(int portId);

private:

    InOutBus<1> c1; // The carry input for the fulladder with a behavioral model.
    InputBus<2> a_, b_; // The inputs to our 2-bit fulladder.
    Bus<3> s; // The sum output of our full adder.
    FullAdder *fa; // The fulladder module which will be created in the constructor.
};

TwoBitFullAdder::TwoBitFullAdder(const Bus<3> &sum, const InputBus<2> &a, const InputBus<2> &b)
    : Module(), c1(0), a_(a), b_(b), s(sum)
{
    Bus<> cin(0); // The carry input to the fulladder module.
    fa = new FullAdder(s[0], c1, a[0], b[0], cin); // Initialising the fulladder module.

    // The 2-bit fulladder module has to respond to state changes in the relevant 
    // input bits and the carry output of the fulladder module. Hence the module has to request 
    // notification of line events from these signals. Note here that the carry input c1 for the 
    // behavioral model is declared to be of type lcs::InOutBus. If it were to be declared 
    // as a normal lcs::Bus object, then it will not be able to notify the behavioral
    // model about the events on its lines.
    c1.notify(this, LINE_STATE_CHANGE, 1);
    a_.notify(this, LINE_STATE_CHANGE, 2, 1);
    b_.notify(this, LINE_STATE_CHANGE, 3, 1);
}

TwoBitFullAdder::~TwoBitFullAdder()
{
    delete fa;

    c1.stopNotification(this, LINE_STATE_CHANGE, 1);
    a_.stopNotification(this, LINE_STATE_CHANGE, 2, 1);
    b_.stopNotification(this, LINE_STATE_CHANGE, 3, 1);
}

void TwoBitFullAdder::onStateChange(int portId)
{
    // When a state change occurs on of the lines c1[0] or a_[1] or b[1],
    // The behavioral model should compute the bit values for the second 
    // and third sum output bits and write them onto the output bus. 
    // This is done as follows.
    s[1] = (~a_[1] & ~b_[1] & c1[0]) | (~a_[1] & b_[1] & ~c1[0]) |
                    (a_[1] & ~b_[1] & ~c1[0]) | (a_[1] & b_[1] & c1[0]);;
    s[2] = (~a_[1] & b_[1] & c1[0]) | (a_[1] & ~b_[1] & c1[0]) |
                      (a_[1] & b_[1] & ~c1[0]) | (a_[1] & b_[1] & c1[0]);
}

int main(void)
{
    Bus<2> a, b; // Inputs 
    Bus<3> sum;  // Sum output

    // Initialising a 2-bit fulladder module.
    TwoBitFullAdder adder(sum, a, b);

    // A tester to generate inputs for the 2-bit fulladder module.
    Tester<4> tester((a, b)); 

    ChangeMonitor<2> amon(a, "A");
    ChangeMonitor<2> bmon(b, "B");
    ChangeMonitor<3> smon(sum, "SUM");

    Simulation::setStopTime(2000);
    Simulation::start();
        
    return 0;
}

The following is the output when the following is compiled and run.

At time: 0,     A: 00
At time: 0,     B: 00
At time: 0,     SUM: 000
At time: 200,   A: 01
At time: 200,   SUM: 001
At time: 300,   A: 10
At time: 300,   SUM: 010
At time: 400,   A: 11
At time: 400,   SUM: 011
At time: 500,   A: 00
At time: 500,   B: 01
At time: 500,   SUM: 001
At time: 600,   A: 01
At time: 600,   SUM: 010
At time: 700,   A: 10
At time: 700,   SUM: 011
At time: 800,   A: 11
At time: 800,   SUM: 100
At time: 900,   A: 00
At time: 900,   B: 10
At time: 900,   SUM: 010
At time: 1000,  A: 01
At time: 1000,  SUM: 011
At time: 1100,  A: 10
At time: 1100,  SUM: 100
At time: 1200,  A: 11
At time: 1200,  SUM: 101
At time: 1300,  A: 00
At time: 1300,  B: 11
At time: 1300,  SUM: 011
At time: 1400,  A: 01
At time: 1400,  SUM: 100
At time: 1500,  A: 10
At time: 1500,  SUM: 101
At time: 1600,  A: 11
At time: 1600,  SUM: 110

Copyright © 2006, 2007 Siva Chandra