Carmichael Posted March 2, 2015 Report Share Posted March 2, 2015 Hi everyone, Recently, I am studying systemc and have a problem on semaphore channel. Actually, I found an example of semaphore channel on asic world (http://www.asic-world.com/systemc/channels3.html). This example provides 3 processes (SC_CTHREAD): bus_semaphore(), do_read() and do_write(). like below, ------------------------------------------------------------------------------------------------------- #include <systemc.h>SC_MODULE (sc_semaphore_example) {sc_in<bool> clock;sc_semaphore bus;int cnt;void bus_semaphore() {while (true) {wait();cout << "@" << sc_time_stamp() <<" Check if semaphore is 0 " << endl;if (bus.get_value() == 0) {cout << "@" << sc_time_stamp() <<" Posting 2 to semaphore " << endl;bus.post();bus.post();if (cnt >= 3) {sc_stop(); // sc_stop triggers end of simulation}cnt ++;}}}void do_read() {while (true) {wait();cout << "@" << sc_time_stamp() <<" Checking semaphore for intance 0"<<endl;// Check if semaphore is availableif (bus.trywait() != -1) {cout << "@" << sc_time_stamp() <<" Got semaphore for intance 0"<<endl;wait(2);}}}void do_write() {while (true) {wait();cout << "@" << sc_time_stamp() <<" Checking semaphore for intance 1"<<endl;// Wait till semaphore is availablebus.wait();cout << "@" << sc_time_stamp() <<" Got semaphore for intance 1"<<endl;wait(3);}}SC_CTOR(sc_semaphore_example) : bus(0){cnt = 0;SC_CTHREAD(do_read,clock.pos());SC_CTHREAD(do_write,clock.pos());SC_CTHREAD(bus_semaphore,clock.pos());}};int sc_main (int argc, char* argv[]) {sc_clock clock ("my_clock",1,0.5);sc_semaphore_example object("semaphore");object.clock (clock.signal());sc_start(0); // First time called will init schedularsc_start(); // Run the simulation till sc_stop is encounteredreturn 0;// Terminate simulation} ===================== simulation result given ==================== @1 ns Check if semaphore is 0@1 ns Posting 2 to semaphore@1 ns Checking semaphore for intance 1@1 ns Got semaphore for intance 1@1 ns Checking semaphore for intance 0@1 ns Got semaphore for intance 0@2 ns Check if semaphore is 0@2 ns Posting 2 to semaphore@3 ns Check if semaphore is 0@4 ns Check if semaphore is 0@4 ns Checking semaphore for intance 0@4 ns Got semaphore for intance 0@5 ns Check if semaphore is 0@5 ns Checking semaphore for intance 1@5 ns Got semaphore for intance 1@6 ns Check if semaphore is 0@6 ns Posting 2 to semaphore@7 ns Check if semaphore is 0@7 ns Checking semaphore for intance 0@7 ns Got semaphore for intance 0@8 ns Check if semaphore is 0@9 ns Check if semaphore is 0@9 ns Checking semaphore for intance 1@9 ns Got semaphore for intance 1@10 ns Check if semaphore is 0@10 ns Posting 2 to semaphore@10 ns Checking semaphore for intance 0@10 ns Got semaphore for intance 0 --------------------------------------------------------------------------------------------------------- There might be a problem about the former two threads. At the first 1ns for this example, the first process bus_semaphore() works and can print out all of the two lines like "@1 ns ....". At the same time in this thread then, the semaphore value (bus) changes into 2 (bus.post()). Then this thread will wait for the next clock posedge. So far everything is good. For the second process, do_read(), also at the 1ns, the first "@" line can be printed out normally, but then what about the expression trywait() in the next if-statement? The first and second process should start to work at the same time (all have wait()at the beginning), that is to say we cannot determine whether the trywait() (in the second process) executes before or after the bus.post() statement (in the first process), so we don't know if the second "@" line of the second process will be printed out. But the simulation result shows that the trywait() will execute after the bus.post() executes such that the second "@..." statement in the second process will be printed out. My question is how can I be sure that the trywait() will execute after the bus.post()'s execution? Shouldn't they execute simultaneously? Thanks a lot! Wayne Quote Link to comment Share on other sites More sharing options...
Carmichael Posted March 2, 2015 Author Report Share Posted March 2, 2015 I think I've figured out what the problem is. The order of processes defined in SC_CTOR is really important which is reverse order of definitions in SC_CTOR. Quote Link to comment Share on other sites More sharing options...
apfitch Posted March 3, 2015 Report Share Posted March 3, 2015 The order of declaration of processes in a module constructor is not significant. The behaviour of sc_semaphore is non-deterministic - please read the description in section 6.2.94 of the IEEE 1666-2011 LRM, where it makes it clear that the behaviour is non-deterministic by design (thanks to the use of immediate notify in the evaluation phase of the scheduler), kind regards Alan Quote Link to comment Share on other sites More sharing options...
Carmichael Posted March 3, 2015 Author Report Share Posted March 3, 2015 Thanks a lot for your reply, Alan. Actually, I also thought the order of declaration of processes in a constructor should not be significant. But the example shown above makes me confused. Someone told me that the order is the key, which is reverse order of definitions in the constructor. Then I did some simulations about this by vista 3.1.2 and found that it seems right. You mean this code is actually not a good example for the use of sc_semaphore and we should code without this non-deterministic factor, right? Thanks, Wayne Quote Link to comment Share on other sites More sharing options...
apfitch Posted March 3, 2015 Report Share Posted March 3, 2015 The key to understanding this is that the simulator you are using is not the standard. The standard is the LRM, the Accellera simulator is deliberately described in the working group as a "Proof of Concept implementation". It is not a "reference simulator" as people sometimes say - the reference is the LRM. The LRM clearly states that the execution order of processes within the evaluation phase of the scheduler is *not* deterministic, the simulator is free to choose any runnable process to run in any order (runnable meaning "triggered"). In the case of sc_semaphore, whether a process is made runnable depends on immediate notification (notification within the evaluation phase of the scheduler) and that is non-deterministic. So the behaviour of a particular simulator/compiler does not prove anything about the order of execution of processes. If you want deterministic behaviour you must guarantee it by your design (e..g by using explicit events and delta delays to guarantee the order of execution of processes) kind regards Alan Quote Link to comment Share on other sites More sharing options...
Carmichael Posted March 3, 2015 Author Report Share Posted March 3, 2015 Really thanks for your help! It's pretty helpful. Regards, Wayne 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.