Examples: Counter
This example demonstrates how to create behavioral model of a bit counter.
To make this example generic we create a template module of arbitrary bit length, as shown in the picture.

To download the files for this design click the links below

project file: counters.gbl
module file: counter.gblmod
testbench file: testbench.gblmod

Start a new project, and call it counters. Add a new module to the project, call it counter. To make module a template, enter size_t N in the Template Parameters property line.

Open Module View and click input port button. Holding down Ctrl key, place 3 input ports somewhere in the design plane. Select each of the newly created ports, and change their properties: name (C, R, En) and type (bool).
Similarly create and output port Q and mame its type GBL::BitSet<N>
We created the following ports: C - clock input, R - reset, En - enable, Q - counter output.

Click on action button, and holding down Ctrl key place two event handlers: OnClock and OnReset. Change the Trigger properties of OnClock and OnReset event handlers to C and R correspondingly.

Module counter
GBL Designer created C++ code for this module with stubs for the event handlers. Now we need to enter the actual code for event handlers.

Open the Header tab or the Source tab depending on whether the Inline Functions property of the module was set to yes or no.
Add if(R) Q = 0; line to OnReset function, and if(C && En) ++Q; line to OnClock function.

The full code is shown below:

//--------------------------------------------------------------------------------
// GBL Designer generated module
// Module: counter
// 2006-2008(c) GB RESEARCH, LLC. ALL RIGHTS RESERVED
//--------------------------------------------------------------------------------

#ifndef counter_H9757
#define counter_H9757

#include "gbl.h"

namespace counters {

export template< size_t N >
class counter : public GBL::Module
{
	GBL::InPort< bool >	C;
	GBL::InPort< bool >	R;
	GBL::InPort< bool >	En;
	GBL::OutPort< GBL::BitSet<N> >	Q;
public:
	GBL_CONNECTOR4(C, R, En, Q)
	counter(const std::string& name = "") : GBL::Module(name)
	{
		Handler(&counter::OnReset) << R;
		Handler(&counter::OnClock) << C;
	}
//<GBL_user>
private:
	//----------------------------------------
	void OnReset()
	{
		if(R)
			Q = 0;
	}
	//----------------------------------------
	void OnClock()
	{
		if(C && En)
			++Q;
	}
//</GBL_user>
};

} // namespace counters

#endif
Now we will create a test module for this design. Click on New Module, call it testbench, set Test property to yes, change Trace File and Log File properties to the desired file names.

We will create two counters in this testbench: one 8-bit and one 16-bit, and look at the differences in their output signals using Xor module. Add the following modules from BasicModules package: ClockGen, StaticCast, and Xor2. Add two counter modules from the current project. Connect them as shown in the picture below, and set the properties of the modules and connectors correctly. We need StaticCast modules because Xor2 module expects the same signal type on its inputs, so we convert outputs from counters to size_t type.

To trace the signals add TraceAll function, set its type to trace and add all signals you want to trace to its Triggers property.
Add two more event handlers OnReset and ResetCounters. Make OnReset event handler sensitive to GBL::eReset() event, and OnReset sensitive to reset signal. Make changes in the auto-generated code (inside <GBL_user>...</GBL_user>), as shown below.
//--------------------------------------------------------------------------------
// GBL Designer generated module
// Module: testbench
// 2006-2008(c) GB RESEARCH, LLC. ALL RIGHTS RESERVED
//--------------------------------------------------------------------------------

#ifndef testbench_H9757
#define testbench_H9757

#include "gbl.h"
#include "counters.h"
#include "BasicModules.h"

namespace counters {

class testbench : public GBL::Module
{
	BasicModules::ClockGen		i1;
	counter< 3 >		i2;
	counter< 4 >		i4;
	BasicModules::Xor2< size_t >		i3;
	BasicModules::StaticCast< GBL::BitSet<3>, size_t >		i5;
	BasicModules::StaticCast< GBL::BitSet<4>, size_t >		i6;
	GBL::Signal< bool >	clock;
	GBL::ConstSignal< unsigned >	period;
	GBL::Signal< bool >	enable;
	GBL::Signal< bool >	en_count;
	GBL::Signal< bool >	reset;
	GBL::Signal< GBL::BitSet<3> >	q3;
	GBL::Signal< GBL::BitSet<4> >	q4;
	GBL::Signal< size_t >	out1;
	GBL::Signal< size_t >	out2;
	GBL::Signal< size_t >	out_xor;
	void TraceAll() { GBL::AddTrace(GetName() + ".clock", clock); 
	GBL::AddTrace(GetName() + ".en_count", en_count); 
	GBL::AddTrace(GetName() + ".enable", enable); 
	GBL::AddTrace(GetName() + ".out1", out1); 
	GBL::AddTrace(GetName() + ".out2", out2); 
	GBL::AddTrace(GetName() + ".out_xor", out_xor); 
	GBL::AddTrace(GetName() + ".q3", q3); 
	GBL::AddTrace(GetName() + ".q4", q4); 
	GBL::AddTrace(GetName() + ".reset", reset); }
public:
	testbench(const std::string& name = "") : GBL::Module(name)
		, i1(name + ".i1"), i2(name + ".i2"), i4(name + ".i4"), i3(name + ".i3")
		, i5(name + ".i5"), i6(name + ".i6")
		, period(4)
	{
		i1 ( period, enable, clock, GBL::N_C );
		i2 ( clock, reset, en_count, q3 );
		i4 ( clock, reset, en_count, q4 );
		i3 ( out1, out2, out_xor );
		i5 ( q3, out1 );
		i6 ( q4, out2 );
		Handler(&testbench::OnReset) << GBL::eReset();
		Handler(&testbench::ResetCounters) << reset;
		Handler(&testbench::TraceAll) << clock << en_count << enable << out1 << out2 << out_xor << q3 << q4 << reset;
	}
//<GBL_user>
private:
	//----------------------------------------
	void OnReset()
	{
		enable = true;
		en_count(GBL::Tick * 10) = true;
		reset = true;
	}
private:
	//----------------------------------------
	void ResetCounters()
	{
		if(reset)
			reset(GBL::Tick) = false;
		else
			reset(GBL::Tick * 175) = true;
	}
	//----------------------------------------
public:
	void Run()
	{
		GBL::Run(GBL::Tick * 400);
	}
//</GBL_user>
};

} // namespace counters

#endif
        
You can run your design either by pressing the Run button or simply by pressing F9.
After the run is successfully completed, select the testbench module tab and press on Tracer button. The Tracer will open the traces from the last run. They should look like in the picture below.


Copyright © 2008, GB Research LLC. All Rights Reserved.