Giuli0 Posted August 14, 2014 Report Share Posted August 14, 2014 Hello everybody, While working on a systemC project, I discovered that probably I have some confused ideas about signals and ports. Let's say I have something like this: //cell.hpp SC_MODULE(Cell){ sc_in<sc_uint<16> > datain; sc_in<sc_uint<1> > addr_en; sc_in<sc_uint<1> > enable; sc_out<sc_uint<16> > dataout; SC_CTOR(Cell) { SC_THREAD(memory_cell); sensitive << enable << datain << addr_en; } private: void memory_cell();}; //cell.cpp void Cell::memory_cell(){ unsigned short data_cell=11; while(true) { //wait for some input wait(); if (enable->read()==1 && addr_en->read()==1) { data_cell=datain->read(); } else { if(enable->read()==0 && addr_en->read()==1) { dataout->write(data_cell); } } }} //test.cppSC_MODULE(TestBench){ sc_signal<sc_uint<1> > address_en_s; sc_signal<sc_uint<16> > datain_s; sc_signal<sc_uint<1> > enable_s; sc_signal<sc_uint<16> > dataout_s; Cell cella; SC_CTOR(TestBench) : cella("cella") { // Binding cella.addr_en(address_en_s); cella.datain(datain_s); cella.enable(enable_s); cella.dataout(dataout_s); SC_THREAD(stimulus_thread); } private: void stimulus_thread() { //write a value: datain_s.write(81); address_en_s.write(1); enable_s.write(1); wait(SC_ZERO_TIME); //read what we have written: enable_s.write(0); address_en_s.write(1); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; //let's cycle the memory again: address_en_s.write(0); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; } }; I've tried running this modules and I've noticed something weird (at least, weird for me): when the stimulus writes a value (81), after the wait(SC_ZERO_TIME) the memory thread finds its datain, enable and address_enable values already updated. This is what I expected to happen. The same happens when the stimulus changes the enable_es value, in order to run another cycle in the memory thread and copy the datacell value into the memory cell dataout port. What I don't understand is why after the memory module writes into its dataout port and goes again to the wait() statement at the beginning of the while loop, the stimulus module still has the old value on its dataout_s channel (0), and not the new value(81), which has just been copied by the memory module. Then, if I run another cycle of the memory loop (for example changing some values on the stimulus channels), the dataout channel finnally updates. In other words, it looks like that if I write into the stimulus channels and then switch to the memory thread, the memory finds the values updated. But if the memory thread writes into its ports, and then i switch to the stimulus thread, the thread still sees the old values on its channels (binded to the memory ports). I don't know if I am clear, and I am sure that maybe this is a naive question, but i am a newbie with systemC and I need to understand this thing. Quote Link to comment Share on other sites More sharing options...
karthickg Posted August 14, 2014 Report Share Posted August 14, 2014 Try changing, //read what we have written: enable_s.write(0); address_en_s.write(1); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; To, //read what we have written: enable_s.write(0); address_en_s.write(1); wait(SC_ZERO_TIME); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; This is not the recommended solution! But only a step towards debugging the problem. Also, print the return value of sc_time_stamp() and sc_delta_count() in memory thread after wait(), and in the stimulus thread after each wait(SC_ZERO_TIME). Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted August 14, 2014 Report Share Posted August 14, 2014 Hi. Short answer: going through two signals means two delta cycles, sc_wait(SC_ZERO_TIME) waits for one delta cycle. When you write to a signal, you can read the new value in the next delta cycle. sc_wait(SC_ZERO_TIME) waits for exactly one delta cycle. What happens here is: delta 0: tb: write (81,1,1) to the signals, then wait for next delta cell: init data_cell to 11, then wait delta 1: tb: write (0,1) to the signals, then wait for next delta cell: triggered by tb write in previous delta, read data_in delta 2: tb: cout data_out (should be initial value), write 0 to addr_en, then wait for next delta cell: triggered by tb write in previous delta, write dataout delta 3: tb: cout dataout (should be new value now, written in last delta) cell: triggered by tb write in previous delta, no action because of 'if' in general, it might be a good idea to separate stimulus and monitor: Use a different thread (or method) sensitive to dataout that prints every value change of dataout (together with time_stamp and delta_count as mentioned by Karthick Gururaj. Greetings Ralph Quote Link to comment Share on other sites More sharing options...
Giuli0 Posted August 14, 2014 Author Report Share Posted August 14, 2014 Try changing, //read what we have written: enable_s.write(0); address_en_s.write(1); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; To, //read what we have written: enable_s.write(0); address_en_s.write(1); wait(SC_ZERO_TIME); wait(SC_ZERO_TIME); cout << "Output value: " << dataout_s.read() << endl; This is not the recommended solution! But only a step towards debugging the problem. Also, print the return value of sc_time_stamp() and sc_delta_count() in memory thread after wait(), and in the stimulus thread after each wait(SC_ZERO_TIME). Thanks Karthick, now it works, but I am not sure why! Using you suggestion, generally speaking I think that the mechanism works like this: If I write something in threadA during delta number 1, it will only be available in threadB during delta num2. And if deltaB writes something during its delta num2, threadA has to wait delta num3 in order to read it. This is why the stimulus thread needs 2 wait(SC_ZERO_TIME) statements in order to read the correct output from the memory, because it has to forward its delta value. Am I right? And if all of this is right, what could be a more reccomended solution, instead of using two wait statements? Quote Link to comment Share on other sites More sharing options...
Giuli0 Posted August 14, 2014 Author Report Share Posted August 14, 2014 Hello Ralph, I was trying and answering to Karthick and I didn't see your answer. After reading it, I guess I was right. ThreadA and threadB are connected through a signal. ThreadA writes on the signal during its delta numb1, and this value will be seen by threadB only during its delta number2. Right? Thanks you both Karthick and Ralph! Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted August 15, 2014 Report Share Posted August 15, 2014 Yes. But it is independent from threads. Its a property of signals with delta cycle semantics. If you change the value of a signal by writing to it, you will read the old value until the next update phase in the simulation (which is in fact the beginning of the next delta cycle). It does not matter wether you are in the same tread or not. In the update phase, you get both: The value changes to the new one and the event according the the value change sets all processes sensitive to this event to 'runnable'. Greetings Ralph 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.