Jump to content

SystemC-AMS Extention Segmentation Fault


Recommended Posts

Hello Folks,

I have a simple RC-Filter (eln) driven from a discrete controlled voltage source. When I run this stand-alone, as an executable, all is fine, I get the traces etc...  But, when I call this from an external C-Programm, I get the segmentation fault with no much information. the external C-program is actually doing nothing more than calling the sc_main, so that it can run the integrated small stimuli (the same used when I run the SC_model alone. 

Any idea why that might happen?

 

Elvis

Link to comment
Share on other sites

Your problem description is a bit contradictory: If you would call your SystemC application as a new process from a really extern C program, there should be no problem as you describe it. However, if you actually mean that you have implemented your own main() function and linked it together with your SystemC application (i.e., sc_main() which instantiates your SystemC model), then you are not allowed to directly call sc_main() from the main() function! Instead, you have to call sc_elab_and_sim(argc, argv) to start elaboration and simulation of your SystemC model. After some preparations, sc_elab_and_sim() hands over control to sc_main(). See clause 4.3 of IEEE Std 1666-2011 for more details.

A minimum complete example exposing just your problem would help to give a better answer.

Link to comment
Share on other sites

Hi, Thank you for your answer. The problem I am trying to solve is, I think, generic.  I.e. I want to use my SystemC/AMS model from an external C program. The body of the model is:

 

sca_util::sca_trace_file *tfp = NULL;
SCAClass* aC; // this is a pointer to a class contain an sc_signal<double>

int sc_main(int argc, char* argv[]) {  
  // analog signals
  sca_eln::sca_node node_in;
  sca_eln::sca_node node_out;
  sca_eln::sca_node_ref gnd;
  aC = SCAClass::Instance();

  // instantiate a voltage source
  sca_eln::sca_de_vsource src("src", 1.0);      // discrete event voltage source with an initial value of 1
  src.set_timestep(0.5, sc_core::SC_US);        // time-step for voltage source
  src.inp(aC->sig);
  src.p(node_in);
  src.n(gnd);
  
  // RC filter
  rc_eln dut("dut");
  dut.in(node_in);
  dut.out(node_out);
  
  // open simulation trace
  tfp = sca_util::sca_create_vcd_trace_file("rc_filter.vcd");
  sca_trace(tfp,node_in,"node_in");
  sca_trace(tfp, node_out,"node_out");
  sca_trace(tfp, aC->sig,"sig");
  
  sc_core::sc_start(0, sc_core::SC_MS);
  cout<<"@"<<sc_time_stamp()<<". Started SystemC-AMS Scheduler"<<endl;
  return(0);
}

I basically would like to have some function I can call from the C program which:

1) initializes all what is needed.

2) changes the value of the class member. in this case the sc_signal<double>   

3) advances the simulation time

4) stops everything with a clean exit.

I have created C_API for the class and class functions but Its clear that i am still missing bits.... How can I do this. 

my SystemC-AMs model will likely be called/loade as a shared library.

Thanks again. 

 

 

 

Link to comment
Share on other sites

Your point 1) to 4) should typically be implemented in your sc_main(). Note that you can pass into sc_main() command line arguments in the same way as you can do in plain C into main() via the argc and argv parameters. This would allow you to set up your simulation differently according to the passed parameters.

Note, you don't need to call sc_main() multiple times to just change the value of a signal. An sc_signal has a write() member function, which you can call from sc_main() to update the signal's value and then continue simulation by calling again sc_start(). However, using this approach for anything but the most simple stimuli (e.g., for generating the truth table of a combinatoric circuit) becomes very tedious. Instead, stimuli should be generated from some dedicated stimuli process. Note that a TDF module is usually the best and most performant choice for generating an arbitrary stimuli for a ELN/LSF model.

Regarding your planned use of the SystemC AMS model as a shared library: Please note that the SystemC simulation kernel of the Accellera proof-of-concept implementation cannot be restarted once simulation has been finished with sc_stop(). This is a long standing issue caused by the fact that certain allocated resources by the kernel are only freed once the whole OS process executing the SystemC kernel has been terminated. As long as your shared library will stay in memory, this is not the case. Therefore, you won't be able to do another elaboration and simulation.

I suggest that you have a look at a good introduction book on SystemC (e.g. "SystemC from the Ground Up") and the SystemC AMS User's Guide to learn more about how to set up test benches in SystemC.

Link to comment
Share on other sites

Thank you, 

I forgot that I can use the input argument to the sc_main. However, as you mentioned this is not the way for more complex simulations.  In fact, the external program does not have to be necessary a testbench, it can be another model, maybe it can be a tool who processes the model output and it would be nice to see some examples of this kind of interface with SC/AMS. Moreover, C represents a bridge towards more other tools. 

Regarding the restart option, yes, I am aware that I cannot restart simulation once a sc_stop() has been sent but that is ok for me. I will have a look at the references you provided but I am assuming they will not discuss the scenario as per this thread. I have googled a bit but there seems not to be enough on this while I think it might be important.... 

Link to comment
Share on other sites

As SystemC is just a C++ library, you can pass in and out information to your model by many different means. Command line arguments are just one option. Another simple way is using the standard input, output, and error streams. You can also use sockets and named pipes. The interface to your outside world should be also properly represented in your SystemC model, e.g., by dedicated stimuli and monitor modules, which open up the required communication channels to the outside world and handle then the synchronisation. In its most simple form, you can just use blocking reads and writes to your communication channel. You may also need to cease execution to the SystemC kernel to advance simulation time using wait(). 

What you are asking for seems quite standard for many co-simulation scenarios and there have been many papers about this.

Link to comment
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...