Jump to content
SiGa

Debug assertion fails when using sc_trace

Recommended Posts

 I am debugging a problem with my custom datatype for sc_trace.

I use my datatype for sc_signal, which is inside a sc_vector. Then I trace each signal inside the sc_vector.

To narrow down my problem I removed all unnecessary parts for debugging. I still get the error, even though I'm not tracing a single signal.

image.png.9a5db2d224223ff2f98f3485e8f650bd.png

 

My MWE:

main.cpp:

// SystemC_FirstTest.cpp : Defines the entry point for the console application.
//
#pragma once
//#define WIN32_LEAN_AND_MEAN //needed for tcp (winsock, ws2)

#include <systemc.h>
#include "globals.h"

SC_MODULE(mA) {
	sc_inout<int> SC_NAMED(A);

	void stim() {
		wait(1, SC_SEC);
		A.write(0);
		wait(1, SC_SEC);
		A.write(1);
	};

	SC_CTOR(mA) {
		SC_THREAD(stim);
	}
};

SC_MODULE(mB) {
	sc_inout<int> SC_NAMED(A);

	void stim() {
		wait(0.8, SC_SEC);
		A.write(2);
		wait(1.1, SC_SEC);
		A.write(3);
	};
	SC_CTOR(mB) {
		SC_THREAD(stim);
	}
};

int sc_main(int argc, char** argv)
{
	sc_vector< sc_signal<int, SC_MANY_WRITERS > > stub_vec("top_stub", 5);
	sc_vector< sc_signal<TraceVector, SC_MANY_WRITERS > > sim_vec("top_sim_", 5);
	
	mA SC_NAMED(modA);
	mB SC_NAMED(modB);

	modA.A(stub_vec[0]);
	modB.A(stub_vec[0]);

	sc_trace_file *tf = sc_create_vcd_trace_file("traces");
	if (!tf) {
		cout << "Empty TraceFile could not be generated." << endl;
	}

	//sc_trace(tf, &(stub_vec[0]), "yolo");
	//sc_signal<int, SC_MANY_WRITERS > testSig;
	//sc_trace(tf, &testSig, "yolo_more");

	//for (int i = 0; i < 5; i++) {
		//sc_trace(tf, &(sim_vec[i]), sim_vec[i].name() );
	//}

	// start simulation
	sc_start();
	sc_close_vcd_trace_file(tf);
	return 0;
}

globals.h:

#pragma once
#include <systemc.h>
#include <vector>

// Vector that is traceable by sc_trace	
class TraceVector {
private:
	std::vector<int> vec;
public:
	// Methods for accessing list
	const std::vector<int>& read() const {
		return vec;
	}
	void write(std::vector<int> var) {
		if (var.size() != 4) {
			throw std::invalid_argument("Argument is not size 4!");
		}
		this->vec.assign(var.begin(), var.end());
	}

	// CTOR
	TraceVector() {
		vec.reserve(4);
	}
	// CTOR for init values
	TraceVector(std::vector<int> var) {
		if (var.size() != 4) {
			throw std::invalid_argument("Argument is not size 4!");
		}
		vec = var;
	}

	// Required by sc_signal<> and sc_fifo<>
	TraceVector operator= (const TraceVector& var) {
		write(var.read());
		return *this;
	}
	// Required by sc_signal<>
	bool operator== (const TraceVector& var) const {
		auto temp = var.read();
		// size check
		if (temp.size() != vec.size()) {
			return false;
		}
		// element wise comparison
		bool equal = std::equal(vec.begin(), vec.end(), temp.begin());
		return equal;
	}
};
// Required functions by SystemC
ostream& operator<< (ostream& os, const TraceVector& var);
void sc_trace(sc_trace_file* tf, const TraceVector& var, const std::string& nm);

globals.cpp:

#include "globals.h"

// Required functions by SystemC
ostream& operator<< (ostream& os, const TraceVector& var) {
	os << "{";
	for (auto& val : var.read()) {
		os << val << " ";
	}
	os << "}";
	return os;
}
void sc_trace(sc_trace_file* tf, const TraceVector& var, const std::string& nm) {
	int pos = 0;
	//static int temp = 0;
	//sc_core::sc_trace(tf, temp, nm + "_test");
	for (auto& val : var.read()) {
		// use namespace, compiler otherwise chooses wrong function
		sc_core::sc_trace(tf, val, nm + "." + std::to_string(pos++));
	}
}

 

Where is the vector subscript error coming from?

Why is it even appearing when I'm not tracing a signal with my custom type?

When I completely remove tracing, no error appears.

Share this post


Link to post
Share on other sites

You create 5 signals carrying a TraceVector. Doing so the default constructor is used which does reserve space for elements but has a size of 0...

I can't tell where the assertion comes from. For those cases a debugger is pretty helpfull B-)

Share this post


Link to post
Share on other sites

Thanks for pointing out that I missed filling the vector in the default constructor. This reminds me, that I initialized my sc_signal<TraceVector...> with a TraceVector containing all 0.  Which probably caused the non-default constructor to be used. 

Fix for default constructor:

// CTOR
TraceVector() {
	vec.reserve(4);
	vec.push_back(0);
	vec.push_back(0);
	vec.push_back(0);
	vec.push_back(0);
}

If I comment out the complete TraceVector part of my code and just have my mA and mB, even then I get the same error.

It also can't be because of an empty trace file. I tried it with a dummy signal in it and without.

The error appears after I called sc_start().

After some stepping through the SystemC framework, the last step-into I can perform is in sc_simcontext.h(409-435) in this block:

// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

// Not MT safe.

#if 1
extern SC_API sc_simcontext* sc_curr_simcontext;
extern SC_API sc_simcontext* sc_default_global_context;

inline sc_simcontext*
sc_get_curr_simcontext()
{
    if( sc_curr_simcontext == 0 ) {
        sc_default_global_context = new sc_simcontext;
        sc_curr_simcontext = sc_default_global_context;
    }
    return sc_curr_simcontext; // <-- debug assertion when returning. Second execution of this part after my step-into point.
}
#else
    extern SC_API sc_simcontext* sc_get_curr_simcontext();
#endif // 0
inline sc_status sc_get_status()
{
    return sc_get_curr_simcontext()->get_status();
}


// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

The last of my code executed is: 

SC_MODULE(mB) {
	sc_inout<int> SC_NAMED(A);

	void stim() {
		wait(8, SC_SEC);
		A.write(2);
		wait(1.1, SC_SEC); // <-- stepping into this
		A.write(3);
	};
	SC_CTOR(mB) {
		SC_THREAD(stim);
	}
};

Additionally I have the call stack:

    Name                                                                                                                                Language
    CoSimulator.exe!std::vector<class sc_core::vcd_trace *,class std::allocator<class sc_core::vcd_trace *> >::operator[](unsigned int) Unknown
    CoSimulator.exe!sc_core::vcd_trace_file::cycle(bool)                                                                                Unknown
    CoSimulator.exe!sc_core::sc_simcontext::trace_cycle(bool)                                                                           Unknown
    CoSimulator.exe!sc_core::sc_simcontext::do_timestep(class sc_core::sc_time const &)                                                 Unknown
    CoSimulator.exe!sc_core::sc_simcontext::simulate(class sc_core::sc_time const &)                                                    Unknown
    CoSimulator.exe!sc_core::sc_start(class sc_core::sc_time const &,enum sc_core::sc_starvation_policy)                                Unknown
    CoSimulator.exe!sc_core::sc_start(void)                                                                                             Unknown
>   CoSimulator.exe!sc_main(int argc, char * * argv) Line 64                                                                            C++
    [External Code] 
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]                                                  Unknown

 

I don't understand why this fails. I am not using any special things at this point.

 

Share this post


Link to post
Share on other sites

I found the culprit. 

int sc_main(int argc, char** argv)
{
    sc_vector< sc_signal<int, SC_MANY_WRITERS > > stub_vec("top_stub", 5);
    sc_vector< sc_signal<TraceVector, SC_MANY_WRITERS > > sim_vec("top_sim_", 5);
    
    mA SC_NAMED(modA);
    mB SC_NAMED(modB);

    modA.A(stub_vec[0]);
    modB.A(stub_vec[0]);

    sc_trace_file *tf = sc_create_vcd_trace_file("traces");
    if (!tf) {
        cout << "Empty TraceFile could not be generated." << endl;
    }

    // sc_trace(tf, &stub_vec[0], "yolo"); // <-- debug assertion!
    sc_trace(tf, stub_vec[0], "yolo"); // dont use &-operator for signal tracing!
    // start simulation
    sc_start();
    sc_close_vcd_trace_file(tf);
    return 0;
}

Three things learned:

  • Don't use tracefiles when empty -> debug assert
  • Don't use &-operator for signal tracing -> debug assert
  • Even if errors come from framework, it is probably your own error...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...