Jump to content

SC_CTHREAD and activation on both edges


Lubomir Bogdanov

Recommended Posts

Hello,

I'm trying to make an SC_CTHREAD trigger on both clock edges. However, I see only pos and neg methods of the sc in clk class. So, I did this:

 

SC_CTOR(microprocessor){

SC_CTHREAD(fetch, clock.pos());
SC_CTHREAD(fetch, clock.neg());

SC_CTHREAD(decode, clock.pos());
SC_CTHREAD(execute, clock.pos());
SC_CTHREAD(interrupt, clock.pos());

}

and then in the thread I put this:

void microprocessor::fetch(){
	while(1){
		wait();
		
		read_write = 1;
		address_bus = 0x00;
		instr_data_bus = 0x00;

		if(clock){
			cout << "clock_1 " << endl;
		}
		else{
			cout << "clock_0 " << endl;
		}
	}
}

But when I run the simulation, I get the following warning:

Warning: (W505) object already exists: mcu.cpu.fetch. Latter declaration will be renamed to mcu.cpu.fetch_0
In file: ../../../src/sysc/kernel/sc_object_manager.cpp:153

 

Am I doing something wrong? The code works as expected, but since I'm new to SystemC, I suspect that

this is not how to work on both edges ...

 

Regards,

L. B.

Link to comment
Share on other sites

If you qant to trigger on both edges you just need to use value_changed().

You get the warning since you are creating a thread with the same method for 2 different sensitivity lists. Since the method name is used to create the thread object you get a warning when creating the second thread object. You may ignore it (and actually it is possible to switch this message off) but the better way is to use the value_changed event finder.

Link to comment
Share on other sites

Simply being sensitive to the clock port should work.

Replace:

SC_CTHREAD(fetch, clock.pos());
SC_CTHREAD(fetch, clock.neg());

with:

SC_CTHREAD(fetch, clock);

When you are sensitive to a port, SystemC infers sensitivity to a method default_event(). For the sc_signal class, default_event() maps to value_changed_event(). sc_clock provides an sc_signal<bool>.

Link to comment
Share on other sites

Hello,

I tried this:


SC_MODULE(microprocessor){
  	sc_in_clk clock {"m_clock"};
  	sc_out<bool> read_write {"m_read_write"};
	sc_in<bool> interrupt_request {"m_interrupt_request"}; 
	sc_inout<sc_lv<16>> instr_data_bus {"m_instr_data_bus"};
	sc_out<sc_lv<20>> address_bus {"m_address_bus"};
  
SC_CTOR(microprocessor){
		SC_CTHREAD(fetch, clock.value_changed());
		SC_CTHREAD(decode, clock.pos());
		SC_CTHREAD(execute, clock.pos());
		SC_CTHREAD(interrupt, clock.pos());
	}
}

void microprocessor::fetch(){
	while(1){
		wait();

		if(clock){
			cout << "clock_1 " << endl;
		}
		else{
			cout << "clock_0 " << endl;
		}
	}
}

and I got the expected output without the warnings this time:

 

============== [0] 0 ==============
============== [0] 1 ==============
============== [1] 0 ==============
clock_0
============== [1] 1 ==============
clock_1
============== [2] 0 ==============
clock_0
============== [2] 1 ==============
clock_1
============== [3] 0 ==============
clock_0
============== [3] 1 ==============
clock_1
============== [4] 0 ==============
clock_0
============== [4] 1 ==============
clock_1
============== [5] 0 ==============
clock_0
============== [5] 1 ==============
clock_1

...

 

However, when I tried David's solution:

SC_CTHREAD(fetch, clock);

I got this, which I believe is not OK:

============= [0] 0 ==============
============== [0] 1 ==============
============== [1] 0 ==============
============== [1] 1 ==============
clock_1
============== [2] 0 ==============
============== [2] 1 ==============
clock_1
============== [3] 0 ==============
============== [3] 1 ==============
clock_1
============== [4] 0 ==============
============== [4] 1 ==============
clock_1
============== [5] 0 ==============
============== [5] 1 ==============
clock_1

 

which leads me to believe that I'm invoking the sc_start( ) method the wrong way:

 

int sc_main(int argc, char* argv[]){
	sc_signal<bool> clock;
	sc_lv<64> irq_lines;
	sc_signal<bool> irq;
	int i;
	microcontroller mcu("mcu");

	mcu.clock(clock);	

	for(i = 0; i < 20; i++){
		cout << "============== [" << i << "] 0 ==============" << endl;
		clock = 0;
		sc_start(1, SC_MS);

		cout << "============== [" << i << "] 1 ==============" << endl;
		clock = 1;
		sc_start(1, SC_MS);
	}

	return 0;
}

 

Anyway, I'll use Eyck's method for now ...

Cheers

Link to comment
Share on other sites

You should push most of the code in sc_main into a top_module and use sc_clock. Advancing the simulator from sc_main is not a good way to run a simulation. You can control simulation via a free running thread in top_module such as monitor, which I illustrate below.

Take a look at https://edaplayground.com/x/JTMK

In the future when requesting help, please put your code example on EDA Playground. Your code in this posting had numerous errors that I corrected.

 

Link to comment
Share on other sites

OK, sorry about the errors - I wasn't expecting that someone would actually test the code 🙂 I basically edited it by hand to make it more readable without caring about syntax.

 

OK, I understand now what you mean - I've seen this type of project structure in SystemC tutorials but didn't quite get it. I will correct my code ...

 

Regards,

L. B.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...