Jump to content

All Activity

This stream auto-updates     

  1. Yesterday
  2. Hi Eyck, In fact, "wait()" doesnt work. So can you have a brief utilization of these functions? Kind regards, Hai Dang
  3. Hi Eyck, It works with your solution. I initialized the counter value from 0 then i tried with 1, it seems that there is no difference (or small difference). void Bus::b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) { sc_dt::uint64 global_addr = trans.get_address(); int slaveid = this->address_to_slaveid(global_addr); if(slaveid < 0) { trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); std::cout << "\e[1;31m" << this->name() << ": " << "\e[1;31mInvalid address " << global_addr << std::endl; return; } sc_dt::uint64 slave_addr = global_addr - this->starts[slaveid]; this->post(); trans.set_address(slave_addr); this->initiator_socket[slaveid]->b_transport(trans, delay); trans.set_address(global_addr); //std::cout << "\e[1;31m MB " << id << std::endl; sc_core::wait(this->bus_delay); } And i have a doubt that: "post()" or "wait()" is better in this case? Thank you a lot for your helps. HD
  4. Last week
  5. TRANG

    timer with systemC

    Thank for your support,
  6. Philipp A Hartmann

    timer with systemC

    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.
  7. TRANG

    timer with systemC

    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.
  8. Eyck

    timer with systemC

    But what is the issue with running the simulation for 3*period? Best regards
  9. From the snippets you provide it looks ok. Assuming that bus_mutex is a sc_mutex this is you problem. sc_mutex does not do arbitration. It selects randomly which waiting thread to grant the lock (actually the next activated process base on an even notification) . But what you expect is arbitration. So either you write an arbiter or you may use and ordered semaphore with an initial counter value of 1. You may find an implementation here: https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/scc/ordered_semaphore.h The semaphore grant access based on a queue. So eventually you get first-comes-first-serves (FCFS) behavior, but all requestors have equal priority. Best regards
  10. TRANG

    timer with systemC

    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.
  11. Philipp A Hartmann

    timer with systemC

    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.
  12. TRANG

    timer with systemC

    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?
  13. David Black

    Simple program problem

    Your code is operating correctly; however, you are displaying the results at the wrong time. This is because the write() method of sc_signal is not the same as a simple store operation. In normal programming, you expect that if you do: variable = 5; Then immediately after storing the value into your variable, the variable will contain the value. You might then assume that the write() of sc_signal is the same. It is not. It takes a small amount of time for the value to be stored. The amount of time is tiny and is refered to as a "delta delay" time. You can cause your program to wait a delta cycle before displaying the result, but it is slightly more complicated because you are using an SC_METHOD style process instead of the SC_THREAD style process. If you are using C++11 you can replace your cout line with this to see correct answer: sc_spawn( [&]{ wait( SC_ZERO_TIME ); ///< wait one delta-cycle delay cout << "@" << sc_time_stamp() <<"(" << sc_delta_count() << ")" << " || in1:" << in1.read() << " + in2:" << in2.read() << "= val:" << out.read() << endl; });
  14. Hello everyone, I want to create a system of 7 initiator sockets (masters) connect to a Bus and then to one target socket (slave). I use the multi_passthrough_initiator_socket and multi_passthrough_target_socket. tlm_utils::multi_passthrough_initiator_socket<Bus> initiator_socket; tlm_utils::multi_passthrough_target_socket<Bus> target_socket; Then i connect the masters and slave to the bus. bus << master_0; bus << master_1; bus << master_2; bus << master_3; bus << master_4; bus << master_5; bus << master_6; bus << sharedmemory; In the b_transport function, i use sc_mutex. void Bus::b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) { sc_dt::uint64 global_addr = trans.get_address(); int slaveid = this->address_to_slaveid(global_addr); if(slaveid < 0) { trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); std::cout << "\e[1;31m" << this->name() << ": " << "\e[1;31mInvalid address " << global_addr << std::endl; return; } sc_dt::uint64 slave_addr = global_addr - this->starts[slaveid]; this->bus_mutex.lock(); trans.set_address(slave_addr); this->initiator_socket[slaveid]->b_transport(trans, delay); trans.set_address(global_addr); std::cout << "Master ID" << id << std::endl; // I print the ID to check if they are working sc_core::wait(this->bus_delay); this->bus_mutex.unlock(); } When i run the program, there are always 3/7 masters working, so the program is blocked. What's the problem here? Thank you alot for your helps. Kind regards, HD
  15. Philipp A Hartmann

    timer with systemC

    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 );
  16. AdrianAlter

    Simple program problem

    Hey everyone! I'm a total beginner with SystemC as i'm just starting to learn about it; i'm doing a simple program that takes two inputs and either sums or multiplies them depending on the signal i'm asserting. This is the code: #include <systemc.h> SC_MODULE( operation ){ sc_in<bool> clock; sc_in<bool> enable; sc_in<bool> reset; sc_in<bool> mult; sc_in<sc_uint<8>> in1; sc_in<sc_uint<8>> in2; sc_out<sc_uint<8>> out; sc_uint<8> val; void func(){ cout << "in1: " << in1.read() << endl; if(reset.read() == 1){ out = 0; out.write(val); cout << "@" << sc_time_stamp() << " ||RESET asserted. VAL: " << out.read() << endl; }else if(enable.read() == 1){ val = val + in1.read() + in2.read(); out.write(val); cout << "@" << sc_time_stamp() << " || I summed the numbers. VAL: " << out.read() << endl; }else if(mult.read() == 1){ val = val * in2.read(); out.write(val); cout << "@" << sc_time_stamp() << " || I multiplied the numbers. VAL: " << out.read() << endl; }else{ cout << "@" << sc_time_stamp() << " || doing nothing atm" << endl; } } SC_CTOR( operation ){ cout << "@" << sc_time_stamp() << " || executing new " << endl; SC_METHOD(func); sensitive << reset; sensitive << clock.pos(); } }; #include <systemc.h> #include <and.cpp> int sc_main(int argc, char* argv[]){ sc_signal<bool> clock; sc_signal<bool> reset; sc_signal<bool> enable; sc_signal<bool> mult; sc_signal<sc_uint<8>> result; sc_signal<sc_uint<8>> num1; sc_signal<sc_uint<8>> num2; int i = 0; clock = 1; operation operation("TEST"); operation.clock(clock); operation.reset(reset); operation.enable(enable); operation.mult(mult); operation.out(result); operation.in1(num1); operation.in2(num2); enable = 1; reset = 0; mult = 0; num1 = 1; num2 = 2; clock = 0; sc_start(10, SC_MS); clock = 1; sc_start(10, SC_MS); return 0; } And the output: SystemC 2.3.3-Accellera --- Jun 5 2019 18:17:04 Copyright (c) 1996-2018 by all Contributors, ALL RIGHTS RESERVED @0 s || executing new in1: 1 @0 s || I summed the numbers. VAL: 0 in1: 1 @10 ms || I summed the numbers. VAL: 3 The problem is that at first cycle, VAL is 0, and should be 3, and at second cycle it should be 6. What am I doing wrong? Thanks, Adrian
  17. TRANG

    timer with systemC

    Thank @Eyck I understand that. Do you have any idea for this problem? How to resolve? Thanks very much.
  18. Eyck

    timer with systemC

    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
  19. TRANG

    timer with systemC

    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.
  20. Thank you Eyck for the quick response. I've tried your suggestion in my program and it seems to work fine. Regards, Ness
  21. Hi @Eyck, Yes for clock based events,this would be much better approach and it worked. Thanks a lot for your help 🙂 Regards, Shubham
  22. My fault, SC_THREAD has a sensitivity list and you can call wait() for the default event. In my experience -and this guided my answer- it is better to have no sensitivity list and wait explicitly for events. When specifying a port in the sensitivity list you need to use an event finder (with .pos()) as the port is not bound yet and hence does not have an event associated. In the thread itself you can use the pos_edge event. So your code shown above is correct. BR
  23. Well, actually a scenaron having a sc_main linking various shared objects which in turn reference the SystemC library as shared object works. So I suspect you build process is somehow wrong. To help you here you would need to post the your build log or at least the linker calls for your user and util liba and for your executable. Best regards
  24. I get odd behavior when I link 2 independent DLLs that both require systemc to my program. In the first DLL are a bunch of Utility code that is used in my project along with a default sc_main (Call this Utils) In the second are user specific systemc code (call this User) Both are compiled linking to libsystemc.so In the program file which is the top frame work I link both User and Utils. First observation: Order matters. If User is imported before Utils then sc_main is not found. This makes sense since sc_main lives in Utils all wire/binding done in the User code are not properly registered (this assumes Utils is imported prior to User) Generally the User code gets errors such as terminating with uncaught exception of type sc_core::sc_report: Error: (E118) find event failed: port is not bound: port 'player_instance_name.ClockIn' (sc_in) In file: ../../../src/sysc/communication/sc_event_finder.cpp:51 Aborted Obviously the port selected for failure is which ever port is listed first (in this example a clock). Second observation adding a sc_main to User code eliminates the error but import order still matters import must have User code first and Utils code second All of this implies that each library must have its own sc_main and that only the last imported file will have all of its behavior honored (ie. binding registrations). I have not tried wiring/binding in Utils and wiring/binding in User to see if there are further issues. Likely I'm being naive in my implementation but is there a way around this behavior since it will be brittle to my end users? It seems there must be some internal assumptions about sc_main and port registration/wiring.
  25. Hi @eyck, As far as lrm is concerned with,i can see sensitive list in sc_thread.It is as follows , So, i had missed this concept of posedge event. When i included pos_edge event ,i was able to controll the process. Just to cross check ,i included only wait() without any arguments in second thread,during that time my second thread was not running.So ,process is controlled by clock now. Yes, i had forgotten to delete the pointer created payload.Thank you for pointing it out. Regards, Shubham
  26. You should consult the LRM again.:SC_THREAD does not have a sensitivity list. Moreover you create a memory leak creating the transaction object using new and not deleting it. And your thread ends after 10 accesses. Basically you need to wait for the clock explicitly while (1) { // wait for the rising edge wait(clk.posedge_event()); tlm::tlm_generic_payload trans; // setup the transaction ... // execute the access i_socket->b_transport(*trans, delay); } In your solution the loop in your threads are based on timed delays hence it is not reactiong on your clocks at all. Best regards
  27. Your trace function calls sc_trace(sc_trace_file *, sc_object*, const char*) which is not overloaded and hence issues the warning. You would need to test for each single template instance of sc_signal<T> and then call the appropriate sc_trace function. And example you can find in https://git.minres.com/SystemC/SystemC-Components/src/branch/master/src/tracer_base.cpp#L90. Or you may use the SystemC Components Library (SCC) as a whole since it provides already this functionality. Best regards
  1. Load more activity
×