milind.shende5 Posted September 25, 2013 Report Share Posted September 25, 2013 Hello All, I am modeling A2D that uses a successive approximation algorithm. I have modeled A2D converter in SystemC and SystemC-AMS. But both of the models give me some errors. SC model ends up with infinite loop, and SC-AMS model ends with segmentation fault the models are as follows: SC models: Location of the while loop could be the serious problem. I have tried changing the location in side switch statement, but error persists. //error message: stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge ...... infinite loop // SC_A2D.h #include<systemc.h> enum adc_state {input, convert}; SC_MODULE(A2D_module) { sc_in_clk clk; sc_in_clk start; sc_in<double> ain; sc_out<sc_logic> eoc; sc_out<sc_lv<8> > dout; sc_signal <adc_state> status; void conversion_logic(); // void next_state_logic(); SC_CTOR(A2D_module) { SC_CTHREAD(conversion_logic, start.pos()); } }; //SC_A2D.cpp #include <SC_A2D.h> void A2D_module::conversion_logic() { eoc = SC_LOGIC_0; dout = "00000000"; double thresh, Vtemp; sc_lv<8> dtemp; int bit_cnt = 8; status = input; while(bit_cnt > 0) { switch (status){ cout << "begin !!!"; case input: if (start == 1) { cout << "stage 1: start edge" << endl; thresh = 5.0; Vtemp = ain; eoc = SC_LOGIC_0; status = convert; } break; case convert: if (clk == 1) { cout << "stage 2: clk edge" << endl; thresh = thresh/2.0; if (Vtemp > thresh) { cout << "stage 3: Vtemp > thresh" << endl; dtemp[bit_cnt]= '1'; Vtemp = Vtemp- thresh; } else { dtemp[bit_cnt]= '0'; } if (bit_cnt > 0) { cout << "stage 4: bit_cnt > 0" << endl; bit_cnt = bit_cnt - 1; } else { cout << "last stage: conversion" << endl; dout = dtemp; status = input; wait(10, SC_US); eoc = SC_LOGIC_1; } } break; } // end switch } // end while } // end method conversion_logic ------------------------------------------------------------------------------------------------------------- SC-AMS models: which gives segmentation fault // Error message: stage 1: Read Input stage 3: Convert Input stage 1: Read Input stage 2 : start edge stage 3: Convert Input stage 4: clk edge !!! bit_cnt = 7 stage 1: Read Input stage 3: Convert Input stage 1: Read Input stage 3: Convert Input stage 4: clk edge !!! Segmentation fault // A2D.h #include <systemc-ams> #include <systemc> #include <stdio.h> using namespace std; //ref: VHDL-AMS Model of A2D converter given in System designer's guide to VHDL-AMS on page 287 SCA_TDF_MODULE (a2d_nbit) { //port declaration sca_tdf::sca_in<double> ain; // analog input pin sca_tdf::sca_de::sca_in<bool> clk; //clock signal sca_tdf::sca_de::sca_in<bool> start; //clock signal sca_tdf::sca_de::sca_out<sc_dt::sc_logic> eoc; //end of conversion pin sca_tdf::sca_de::sca_out<sc_dt::sc_lv<8> > dout; //digitalized output a2d_nbit(sc_core::sc_module_name nm, double Vmax_ = 5.0, double delay_ = 10.0e-6, int bit_range_ = 8, bool start_x_ = 0, bool clk_x_ = 0): ain("ain"), start("start"),clk("clk"), eoc("eoc"), dout("dout"), Vmax(Vmax_), delay(delay_), bit_range(bit_range_), start_x(start_x_), clk_x(clk_x_){} void set_attributes() { set_timestep(50, sc_core::SC_US); eoc.set_delay(1); } void initialize() { eoc.initialize(sc_dt::SC_LOGIC_0); } void processing(); private: double delay; // ADC conversion time double Vmax; int bit_range; bool clk_x; bool start_x; }; // A2D.cpp void a2d_nbit :: processing() { // double Vin = ain.read(); double thresh; //Threshold to test input voltage double Vtemp; //snapshot of input voltage when conversion starts sc_dt::sc_lv<8> dtemp; //temparary output data enum state {input, convert}; int bit_cnt; state status = input; switch(status) // ref: systemC state machine example in SystemC user guide on page 171 { case input : cout << "stage 1: Read Input" << endl; if((start == true) && (start_x == false)) //if (start == true) { cout << "stage 2 : start edge" << endl; bit_cnt = bit_range; thresh = Vmax; Vtemp = ain; eoc = sc_dt::sc_logic('0'); } case convert: cout << "stage 3: Convert Input" << endl; if ((clk == true) && (clk_x == false)) //if (clk == true) { cout << "stage 4: clk edge !!!" << endl; thresh = thresh/2.0; if (Vtemp > thresh) { dtemp[bit_cnt]= '1'; Vtemp = Vtemp - thresh; } else { dtemp[bit_cnt]= '0'; } if (bit_cnt > 0) { bit_cnt = bit_cnt - 1; cout << " bit_cnt = " << bit_cnt << endl; } else { dout = dtemp; eoc = sc_dt::sc_logic('1'); status = input; } break; } default: break; } // end switch start_x = start; clk_x = clk; } ---------------------------------------------------------------------------------------------------------------- // voltage source: dummy_source.h #include<systemc-ams> #include<systemc> #include<iostream.h> #include<fstream.h> using namespace std; SCA_TDF_MODULE (dummy_src) { // sca_tdf::sca_de::sca_out<double> output; sca_tdf:: sca_out<double> output; ifstream infile; double val; dummy_src(sc_core::sc_module_name): output("output"){} void set_attributes() { set_timestep(50, sc_core::SC_US); infile.open("datalog.txt"); } void processing () { if (infile >> val) { output.write(val); } else { output.write(0.0); } } }; ------------------------------------------------------------------------------------------------------------- // top_level_entity : interface.h #include<systemc-ams> #include<systemc> #include<A2D.h> //#include<SC_A2D.h> #include<dummy_source.h> using namespace std; using namespace sc_core; SC_MODULE (interface2) { // A2D_module a2d; a2d_nbit a2d; dummy_src input_vtg; sc_core::sc_clock clk1; sc_core::sc_clock start1; SC_CTOR(interface2) :in("in"), out("out"), a2d("a2d"), input_vtg("input_vtg"), clk1("clk1", 100, sc_core::SC_US, 0.5), start1("start1", 200, sc_core::SC_US, 0.5), eoc("eoc") { input_vtg.output(in); a2d.ain(in); a2d.start(start1.signal()); a2d.clk(clk1.signal()); a2d.eoc(eoc); a2d.dout(out); } public: // sc_core::sc_signal <double> in; sca_tdf::sca_signal<double> in; sc_core::sc_signal<sc_dt::sc_lv<8> > out; sc_core::sc_signal<sc_logic> eoc; }; // top_level_entity: interface2.cpp #include<systemc-ams.h> #include<systemc.h> #include<iomanip> #include<interface2.h> int sc_main(int argc, char* argv[]) { interface2 if2_dut("if2_dut"); sca_util :: sca_trace_file* atfs = sca_util :: sca_create_tabular_trace_file("if2.dat"); sca_util :: sca_trace(atfs, if2_dut.clk1, "\tCLK"); sca_util :: sca_trace(atfs, if2_dut.start1, "\tSTART"); sca_util :: sca_trace(atfs, if2_dut.in, "\tINPUT"); sca_util :: sca_trace(atfs, if2_dut.out, "\tOUTPUT"); sca_util :: sca_trace(atfs, if2_dut.eoc, "\tEOC"); sc_start(400, SC_US); sca_util :: sca_close_tabular_trace_file (atfs); return 0; } ------------------- Quote Link to comment Share on other sites More sharing options...
dakupoto Posted September 26, 2013 Report Share Posted September 26, 2013 Hello All, I am modeling A2D that uses a successive approximation algorithm. I have modeled A2D converter in SystemC and SystemC-AMS. But both of the models give me some errors. SC model ends up with infinite loop, and SC-AMS model ends with segmentation fault the models are as follows: SC models: Location of the while loop could be the serious problem. I have tried changing the location in side switch statement, but error persists. //error message: stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge stage 1: start edge ...... infinite loop // SC_A2D.h #include<systemc.h> enum adc_state {input, convert}; SC_MODULE(A2D_module) { sc_in_clk clk; sc_in_clk start; sc_in<double> ain; sc_out<sc_logic> eoc; sc_out<sc_lv<8> > dout; sc_signal <adc_state> status; void conversion_logic(); // void next_state_logic(); SC_CTOR(A2D_module) { SC_CTHREAD(conversion_logic, start.pos()); } }; //SC_A2D.cpp #include <SC_A2D.h> void A2D_module::conversion_logic() { eoc = SC_LOGIC_0; dout = "00000000"; double thresh, Vtemp; sc_lv<8> dtemp; int bit_cnt = 8; status = input; while(bit_cnt > 0) { switch (status){ cout << "begin !!!"; case input: if (start == 1) { cout << "stage 1: start edge" << endl; thresh = 5.0; Vtemp = ain; eoc = SC_LOGIC_0; status = convert; } break; case convert: if (clk == 1) { cout << "stage 2: clk edge" << endl; thresh = thresh/2.0; if (Vtemp > thresh) { cout << "stage 3: Vtemp > thresh" << endl; dtemp[bit_cnt]= '1'; Vtemp = Vtemp- thresh; } else { dtemp[bit_cnt]= '0'; } if (bit_cnt > 0) { cout << "stage 4: bit_cnt > 0" << endl; bit_cnt = bit_cnt - 1; } else { cout << "last stage: conversion" << endl; dout = dtemp; status = input; wait(10, SC_US); eoc = SC_LOGIC_1; } } break; } // end switch } // end while } // end method conversion_logic ------------------------------------------------------------------------------------------------------------- SC-AMS models: which gives segmentation fault // Error message: stage 1: Read Input stage 3: Convert Input stage 1: Read Input stage 2 : start edge stage 3: Convert Input stage 4: clk edge !!! bit_cnt = 7 stage 1: Read Input stage 3: Convert Input stage 1: Read Input stage 3: Convert Input stage 4: clk edge !!! Segmentation fault // A2D.h #include <systemc-ams> #include <systemc> #include <stdio.h> using namespace std; //ref: VHDL-AMS Model of A2D converter given in System designer's guide to VHDL-AMS on page 287 SCA_TDF_MODULE (a2d_nbit) { //port declaration sca_tdf::sca_in<double> ain; // analog input pin sca_tdf::sca_de::sca_in<bool> clk; //clock signal sca_tdf::sca_de::sca_in<bool> start; //clock signal sca_tdf::sca_de::sca_out<sc_dt::sc_logic> eoc; //end of conversion pin sca_tdf::sca_de::sca_out<sc_dt::sc_lv<8> > dout; //digitalized output a2d_nbit(sc_core::sc_module_name nm, double Vmax_ = 5.0, double delay_ = 10.0e-6, int bit_range_ = 8, bool start_x_ = 0, bool clk_x_ = 0): ain("ain"), start("start"),clk("clk"), eoc("eoc"), dout("dout"), Vmax(Vmax_), delay(delay_), bit_range(bit_range_), start_x(start_x_), clk_x(clk_x_){} void set_attributes() { set_timestep(50, sc_core::SC_US); eoc.set_delay(1); } void initialize() { eoc.initialize(sc_dt::SC_LOGIC_0); } void processing(); private: double delay; // ADC conversion time double Vmax; int bit_range; bool clk_x; bool start_x; }; // A2D.cpp void a2d_nbit :: processing() { // double Vin = ain.read(); double thresh; //Threshold to test input voltage double Vtemp; //snapshot of input voltage when conversion starts sc_dt::sc_lv<8> dtemp; //temparary output data enum state {input, convert}; int bit_cnt; state status = input; switch(status) // ref: systemC state machine example in SystemC user guide on page 171 { case input : cout << "stage 1: Read Input" << endl; if((start == true) && (start_x == false)) //if (start == true) { cout << "stage 2 : start edge" << endl; bit_cnt = bit_range; thresh = Vmax; Vtemp = ain; eoc = sc_dt::sc_logic('0'); } case convert: cout << "stage 3: Convert Input" << endl; if ((clk == true) && (clk_x == false)) //if (clk == true) { cout << "stage 4: clk edge !!!" << endl; thresh = thresh/2.0; if (Vtemp > thresh) { dtemp[bit_cnt]= '1'; Vtemp = Vtemp - thresh; } else { dtemp[bit_cnt]= '0'; } if (bit_cnt > 0) { bit_cnt = bit_cnt - 1; cout << " bit_cnt = " << bit_cnt << endl; } else { dout = dtemp; eoc = sc_dt::sc_logic('1'); status = input; } break; } default: break; } // end switch start_x = start; clk_x = clk; } ---------------------------------------------------------------------------------------------------------------- // voltage source: dummy_source.h #include<systemc-ams> #include<systemc> #include<iostream.h> #include<fstream.h> using namespace std; SCA_TDF_MODULE (dummy_src) { // sca_tdf::sca_de::sca_out<double> output; sca_tdf:: sca_out<double> output; ifstream infile; double val; dummy_src(sc_core::sc_module_name): output("output"){} void set_attributes() { set_timestep(50, sc_core::SC_US); infile.open("datalog.txt"); } void processing () { if (infile >> val) { output.write(val); } else { output.write(0.0); } } }; ------------------------------------------------------------------------------------------------------------- // top_level_entity : interface.h #include<systemc-ams> #include<systemc> #include<A2D.h> //#include<SC_A2D.h> #include<dummy_source.h> using namespace std; using namespace sc_core; SC_MODULE (interface2) { // A2D_module a2d; a2d_nbit a2d; dummy_src input_vtg; sc_core::sc_clock clk1; sc_core::sc_clock start1; SC_CTOR(interface2) :in("in"), out("out"), a2d("a2d"), input_vtg("input_vtg"), clk1("clk1", 100, sc_core::SC_US, 0.5), start1("start1", 200, sc_core::SC_US, 0.5), eoc("eoc") { input_vtg.output(in); a2d.ain(in); a2d.start(start1.signal()); a2d.clk(clk1.signal()); a2d.eoc(eoc); a2d.dout(out); } public: // sc_core::sc_signal <double> in; sca_tdf::sca_signal<double> in; sc_core::sc_signal<sc_dt::sc_lv<8> > out; sc_core::sc_signal<sc_logic> eoc; }; // top_level_entity: interface2.cpp #include<systemc-ams.h> #include<systemc.h> #include<iomanip> #include<interface2.h> int sc_main(int argc, char* argv[]) { interface2 if2_dut("if2_dut"); sca_util :: sca_trace_file* atfs = sca_util :: sca_create_tabular_trace_file("if2.dat"); sca_util :: sca_trace(atfs, if2_dut.clk1, "\tCLK"); sca_util :: sca_trace(atfs, if2_dut.start1, "\tSTART"); sca_util :: sca_trace(atfs, if2_dut.in, "\tINPUT"); sca_util :: sca_trace(atfs, if2_dut.out, "\tOUTPUT"); sca_util :: sca_trace(atfs, if2_dut.eoc, "\tEOC"); sc_start(400, SC_US); sca_util :: sca_close_tabular_trace_file (atfs); return 0; } ------------------- Hello, Right now, the goal is to get your model(or rather something -- none of these irritating infinite loops or seg faults) to work, so it really does not matter whether you use SystemC or SystemC-AMS, or a combination. Am I right ? Then one has to consider the design. Consider a delta-sigma ADC. The actual delta-sigma modulator is purely analog, no queastions, but the decimation filter is purely digital. So you have no option but to use both SystemC and SystemC-AMS and use converter ports. Or you might stick only to SystemC-AMS and model the decimation filter using TDF. So this decision you have to make. May we suggest that for the time being keep the successive approximation ADC on the back burner. Model a very simple ADC as flash or single slope ADC. Get that to work just right, no infinite loops, or seg faults. Once you get one of these working, you can compare what you did in the two designs and find out what exactly is problem with the successive approximation case. Most likely, some control condition is not getting set/reset. Have you checked with gdb where the crash occurs ? Even for these simple cases, there are pure analog and pure digital parts that need to be modelled correctly. For the flash ADC the resistor chain and comparators are almost pure analog, but the thermometer encoder is definitely pure digital, For the single slope design, the comparator is almost pure analog, but the counter is pure digital. Also, for starters, focus on the actual physical design and experiment how it might be translated to a high level design. The problem with high level methods is determining how to abstract out the key steps, from the physical design. Hope that helps. milind.shende5 1 Quote Link to comment Share on other sites More sharing options...
milind.shende5 Posted September 26, 2013 Author Report Share Posted September 26, 2013 Hello All, Can we use "while loops" in SystemC-AMS constructs (TDF modeling) ? Can somebody refer a tutorial or a reference code which uses while loop in SC-AMS. thanks, Milind. Quote Link to comment Share on other sites More sharing options...
dakupoto Posted September 28, 2013 Report Share Posted September 28, 2013 Hello All, Can we use "while loops" in SystemC-AMS constructs (TDF modeling) ? Can somebody refer a tutorial or a reference code which uses while loop in SC-AMS. thanks, Milind. Hello Sir, There is no need to use a while loop, except perhaps in some special case, in the TDF framework. The TDF framework offers a set of methods that can be overriden and if used correctly/wisely will remove the need for a while loop. In the 'set_attributes()' method, one can use the built-in 'set_timestep()' method to set when data is read in from an input port, or read out to an output port. So at tick or sub-interval of the total simulation time, data is read in/out as specified. But this is what is done in pure SystemC as well, for a SC_THREAD or SC_CTHREAD. There A sensitivity list defines the triggering event, often a clock, at which the thread has to respond. So the thread is set up as an infinite loop, that 'waits' for a triggering event. So, SystemC-AMS provides a cleaner design that does not force the designer to explicitly track the triggering event. In the 'processing' method, the actual processing is done. Hope that helps. milind.shende5 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.