Jump to content

TRANG

Members
  • Content Count

    52
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by TRANG


  1. Hi all,

    I have 2 models, model A and model B

    Model A has an output port out_A (bool)

    Model B has an input port in_B (bool)

    when integrate, I will instance 3 objects of Model A, 1 object of Model B

    //file @connection.cpp
    ...
    void initializeENV(){
    ...
    objA_1 = new ModelA("objA_1");
    objA_2 = new ModelA("objA_2");
    objA_3 = new ModelA("objA_3");
    
    objB = new ModelB("objB");
    ...
    }

    the value of in_B = objA_1->out_A or objA_2->out_A or objA_3->out_A

    I think that, if I bind as below . It is wrong. Because of when objA_1->out_A is change then affect to obj_2->out_A and objA_3->out_A. Is my understand correct?

    //file @connection.cpp
    ...
    sc_signal<bool> sig_1;
    sc_signal<bool> sig_2;
    sc_signal<bool> sig_3;
    void initializeENV(){
    ...
    objA_1 = new ModelA("objA_1");
    objA_2 = new ModelA("objA_2");
    objA_3 = new ModelA("objA_3");
      
    objB = new ModelB("objB");
    
      objA_1->out_A(sig_1);
      objA_2->out_A(sig_2);
      objA_3->out_A(sig_3);
      objB->in_B(sig_1);
      objB->in_B(sig_2);
      objB->in_B(sig_3);
      
    ...
    }

    How to resolve it? How to bind 3 out_A ports to in_B port? .I can't use SC_METHOD in this case.

    Thank all.

     


  2. Master and Slave use same clock, so I think Slave need only care data_in.

    class slave : public sc_module {
        public:
        sc_in<bool> clk;
        sc_in<uint32_t> data_in;
        slave(sc_module_name name):clk("clk"),data_in("data_in"){
            SC_HAS_PROCESS(slave);
            SC_METHOD(run);
            dont_initialize();
            sensitive << data_in;
        }
        void run(){
            cout<<hex<<data_in.read()<<endl;
        }
        ~slave(){
        }
    };

    or

    class slave : public sc_module {
        public:
        sc_in<bool> clk;
        sc_in<uint32_t> data_in;
        slave(sc_module_name name):clk("clk"),data_in("data_in"){
            SC_HAS_PROCESS(slave);
            SC_THREAD(run);
            dont_initialize();
            sensitive << data_in;
        }
        void run(){
            cout<<hex<<data_in.read()<<endl;
        }
        ~slave(){
        }
    };

     


  3. 5 hours ago, Philipp A Hartmann said:

    The match will occur (almost) at the "correct" point in time during the simulation.  However, if you sample the value from an unrelated process, there might be some process evaluation ordering dependency (i.e. whether the update_method had already been run).  It depends on your requirements, whether this might be an issue. 

    If you do the checks outside of the simulation, i.e. between sc_start calls, you would need to complete the deltas (as per the loop sketched above) before every check. You cannot call sc_start during end_of_simulation.

    Thank for your support,


  4. 7 hours ago, Eyck said:

    But what is the issue with running the simulation for 3*period?

    Best regards

    I'm sorry make you confused.

    Summary:

    if my test case is:

    sc_start(2*period,time_unit);
    while (sc_pending_activity_at_current_time()) {
            sc_start(SC_ZERO_TIME);
        }

    or

    sc_start(3*period,time_unit);

    then compare match occur.( is correct)

    If my test case is:

    sc_start(2*period,time_unit);

    then compare match don't occur .

    I want to my source code detect when time simulate near the over to pending to execute event m_update before over.


  5. 11 minutes ago, Philipp A Hartmann said:

    I don't fully understand the question?  My snippet above runs all remaining delta cycles at the current time without advancing the time any further. You can wrap your original sc_start call with the loop in a small helper function (e.g. sc_start_including_deltas(...) , if you find yourself copying the snippet too often.

    i try :

    void GTimer::end_of_simulation()
    {
        while (sc_pending_activity_at_current_time()) {
            sc_start(SC_ZERO_TIME);
        }
    }

    But It is not true?

    My problem is the time simulates is over before trigger event. I want to force trigger event before end simulate.


  6. 3 hours ago, Philipp A Hartmann said:

    You can run the delta cycles at the current time until everything settles:

    
    while( sc_pending_activity_at_current_time() )
      sc_start( SC_ZERO_TIME );

     

    Thanks @Philipp A Hartmann

    it is OK if I use :

    sc_start(2*period,time_unit);
    while( sc_pending_activity_at_current_time() )
      sc_start( SC_ZERO_TIME );

    But I want to pending in my code. Is it possible?


  7. 4 hours ago, Eyck said:

    If you run a simulation until a certain point it time the kernel stops before evaluating the processes at this time point. So if you schedule an event for lets say 100ns and simulate for 100ns then the process being sensitive to this event will not be executed (yet). So this is intended behavior.

    BR

    Thank @Eyck

    I understand that. Do you have any idea for this problem? How to resolve?

    Thanks very much.


  8. Hi all,

    I'm using systemC to build timer model. ( Timer support compares match, overflow, underflow)

    //constructor
        SC_METHOD(evaluate_method);
        dont_initialize();
        sensitive << m_evaluate;
    
        SC_METHOD(update_method);
        dont_initialize();
        sensitive << m_update;
    void GTimer::evaluate_method()
    {
        //check if compare match
        if(CNT_value == compare_match_value){
             compare_match_handling();
        }
        ...
         m_update.notify((double)period * compare_match_value, time_unit);
    }
    void GTimer::update_method()
    {
        CNT_value = get_counter_value();
        m_evaluate.notify();
    }
    GT_API unsigned int GTimer::get_counter_value()
    {
        unsigned int value;
        sc_time current_time = sc_time_stamp();
        value = (current_time.to_double() - start_time.to_double()) / period;
        return value;
    }

    Ex:

    I set compare_match_value = 2;

    period = 1000.0

    time_unit = SC_PS

    when I start timer and simulate on 2* period

    sc_start(2*period ,time_unit)

    compare match don't occur. because the time simulate is over but m_update event not trigger.

    If I start timer and simulate on 3* period

    compare match occur.

    Do you have any idea? ( I want to compare match occur when I start timer and simulate on 2*period)

    Thank all.


  9. On 12/13/2017 at 4:15 AM, CapUnderPantsRLZ said:

    "Personally, I prefer to put SC_HAS_PROCESS directly into the constructor body, which works very reliably. All that SC_HAS_PROCESS does is to create a  "

    : "All that SC_HAS_PROCESS does is to create a ", now explain to your compiler to 'construct' something, that it was not defined before the constructor call. do you do that? ) That it is precisely why the authors of SystemC: From the Ground Up, explained to place SC_HAS_PROCESS before the constructors.

    GCC,  lets this kind of 'thing' pass, try with Clang++ now.

     

    don't place that in the header file, instead, it is in , ., (whatever extension you are using) that will contain it inside your own namespace if it is the case.

    Hi @CapUnderPantsRLZ

    in 1666-2011.pdf

    Quote

    macro SC_HASS_PROCESS shall be invoked within the class definition or the constructor body of the module.

    So, I think @David Black is exactly.

    https://stackoverflow.com/questions/45308468/systemc-multiple-module-implementations-in-single-cpp-file


  10. 12 hours ago, David Black said:

    Notify (either case) is non-blocking, so your call to notify followed by initialize will happen. Then after you return, the notified element(s) may execute.

    Notify() implies execution will be in the same delta-cycle; whereas, notify(SC_ZERO_TIME) postpones to the next one and allows other processes in the current delta-cycle to complete.

    Take a look at <https://github.com/dcblack/SystemC-Engine/blob/master/Engine_v2.4.pdf>.

    Thank you so much, @David Black


  11. Hi all,

    I try code bellow

    SC_METHOD(APMMethod);
    sensitive << mAPMEvent;
    ...
    void APMMethod(){
      printf("Reset port\n");
      ...
    }
    ...
    void Initialize()
    {
       for(unsigned int i=0; i< 50; i++){
           mAPM_reg[i].value = 0;
           printf("Initialize %s\n",mAPM_reg[i].name);
        }
    }
    ...
    void EnableReset(){
        //reset port
        mAPMEvent.notify(SC_ZERO_TIME);
        //initialize reg
        Initialize();
    }
     

    When EnableReset occur. 

    My output is:

    Intialize APM_REG1
    Intialize APM_REG2
    ...
    
    Reset port

    I try with 

    mAPMEvent.notify();

    But the same output.

    1. why Initialize() call before APMMethod().

    2. when to use notiffy() or notify(SC_ZERO_TIME)?

    Thanks all.


  12. 36 minutes ago, Philipp A Hartmann said:

    In SystemC 2.3.2 and later, you can use the sc_event::triggered() member function to query, if an event was triggered (and thus might have caused your method to run):

    
    if( event1.triggered() ){
      std::cout << "event1 got triggered";
    }
    if( event2.triggered() ){
      std::cout << "event2 got triggered";
    }

    Please note that if both events were triggered in/for the same evaluation phase, your method might well be run only once.

    I can't see that because my lib is 2.3.1.

    So, with 2.3.1, we don't have a solution.

    Thank Philipp.

     


  13. On 5/23/2019 at 5:01 PM, David Black said:

    You can only specify sensitivity on objects that have events or event finders directly accessible at the time of construction. Normally this means using either a suitable channel, port or explicit event. If you wrap your int's with a channel such as sc_signal<T>, you can do it.

    Example - https://www.edaplayground.com/x/5vLP

    Hi @David Black,

    If I have

    sc_event event1;
    sc_event event2;
    ...
    SC_METHOD( My_method );
    sensitive << event1 << event2;
    dont_initialize();

    How to detect My_method sensitive by event1 or event2?


  14. I read some source code.

    class TlmExtension : public tlm_extension<TlmExtension>
    {
      ...
    };
    void setExtension(tlm::tlm_generic_payload &in, tlm::tlm_generic_payload &out)
    {
        TlmExtension *input  = (TlmExtension *)0;
        TlmExtension *output = new TlmExtension;
        in.get_extension(input);
        if (input != NULL) {
            output->setNum(input->getNum());
            output->setChannel(input->getChannel());
            out.set_extension(output);
        }
    }

     

    I think above code is wrong. Because of when exit  setExtension  function. We cant delete object create by new operator (output )

    How to resolve this problem?  Thanks.

    BR.

     


  15. I'm learning simple socket with 2 examples:

    ex1: https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/tlm2_getting_started_3.cpp

    ex2: in lib : systemc-2.3.3\examples\tlm\common\include\models\SimpleBusLT.h

    I know that :

    //Initiator
    tlm_utils::simple_initiator_socket<Initiator>            initiator_socket;
    ...
    tlmTrans.set_data_length(emdata_length);
    tlmTrans.set_data_ptr(emdata_ptr);
    initiator_socket->b_transport(tlmTrans, localTime);
    ...
    //Target
    tlm_utils::simple_target_socket<Target>            target_socket;
    ...
    target_socket.register_b_transport(this, &Target::b_transport);
    ...
    virtual void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay)
    {
    	//receive data from tlmTrans Initiator
    }

    I only understand "register_b_transport" function.  But I see others function , Can you explain it? and how to use?

    //Initiator
    initiator_socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidateDMIPointers);
    
    ...
    //Target
    target_socket.register_b_transport(this, &Target::initiatorBTransport);
    target_socket.register_transport_dbg(this, &Target::transportDebug);
    target_socket.register_get_direct_mem_ptr(this, &Target::getDMIPointer);

     


  16. 24 minutes ago, AmeyaVS said:

    Hello @TRANG,

    You probably need to change from this:

    
    sc_vector< simple_initiator_socket_tagged<Router >* > initiator_socket;

    to this:

    
    sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;

    And to understand the better use of sc_vector you can probably search and find many references on  using sc_vector in the forum or on stackoverflow such as these ones:

    Hope these helps.

    Regards,

    Ameya Vikram Singh

    Thanks @AmeyaVS

    how to set base name for each initiator_socket?

    Suppose, I have initiator_socket[4]. I only initialize initiator_socket as bellow code.

    sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;
    ...
    ///
    Router::Router():initiator_socket("initiator_socket",4)
    {}

    I can't set base name for each initiator_socket as my expected.

    ex:   initiator_socket[0]   : " initiator_0_socket"

             initiator_socket [ 1]    : " initiator_1_socket"

             initiator_socket [ 2]    : " initiator_2_socket"

             initiator_socket [ 3]    : " initiator_3_socket"


  17. 4 hours ago, Eyck said:

    Just looked further: there is a typo in case 1. It should read

    
    //bind
      for(int i=0;i<3;i++){
        objA->initiator_socket[i]->bind(*(objB->target_socket[i]));
      }

    as you use an array of pointers. Again, sc_vector eases your life:

    
    //Model A
    sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<ModelA>> initiator_socket;
      ...
    // Model B
    sc_core::sc_vector<tlm_utils::simple_target_socket_tagged<ModelB>> target_socket;
      ...
    //bind
      for(int i=0;i<3;i++){
        objA->initiator_socket[i].bind(objB->target_socket[i]);
      }
                         
        

    The same applies to case 2:

    
    //bind
    objA->initiator_socket1->bind(*(objB->target_socket2));
    objA->initiator_socket2->bind(*(objB->target_socket3));
    objA->initiator_socket3->bind(*(objB->target_socket1));

    Best regards

    Thank @Eyck @David Black

     

    ///Constructor 
    for (unsigned int channel = 0 ; channel < NUM_CHANNEL ; channel++) {
        char socketName[100];
        sprintf(socketName,"initiator%d",channel);
        initiator_socket[channel] = new tlm_utils::simple_initiator_socket_tagged<ModelA>(socketName);
    }
    ....

    I want to use pointer to set name for each inittiator_socket[channel] (as above code I used "socketName" variable)

    @Eyck Can you show me how to use sc_vector and set name for each inittiator_socket? 

    Thanks all.


  18. Hi all,

    I want to understand more about simple_initiator_sọket and simple_target_socket. How is it working??

    Suppose, "Model A 3 initiator" -->  <-- "3 target Model B"

    Case 1:

    //Model A
    tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket[3];
      ...
    // Model B
    tlm_utils::simple_target_socket_tagged<ModelB>* target_socket[3];
      ...
    //bind
      for(int i=0;i<3;i++){
        objA->initiator_socket[i]->bind(objB->target_socket[i]);
      }

    Case 2:

    //Model A
    tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket1;
    tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket2;
    tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket3;
      ...
    // Model B
    tlm_utils::simple_target_socket_tagged<ModelB>* target_socket1;
    tlm_utils::simple_target_socket_tagged<ModelB>* target_socket2;
    tlm_utils::simple_target_socket_tagged<ModelB>* target_socket3;
      ...
    //bind
    objA->initiator_socket1->bind(objB->target_socket2)
    objA->initiator_socket2->bind(objB->target_socket3)
    objA->initiator_socket3->bind(objB->target_socket1)
    

     

    Question 1: Is both above code is correct?                   

    Question 2: In case 2,  I set "bind" between Model A and Model B (unordered declare, initiator_socket1 with target_socket2 ,..... ). Is it right?         

    Thanks all.

×