Lubomir Bogdanov Posted January 29, 2023 Report Posted January 29, 2023 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. Quote
Eyck Posted January 29, 2023 Report Posted January 29, 2023 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. Quote
Lubomir Bogdanov Posted January 29, 2023 Author Report Posted January 29, 2023 OK, thanks for your help! Quote
David Black Posted January 30, 2023 Report Posted January 30, 2023 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>. Quote
Lubomir Bogdanov Posted January 30, 2023 Author Report Posted January 30, 2023 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 Quote
David Black Posted February 4, 2023 Report Posted February 4, 2023 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. Quote
Lubomir Bogdanov Posted February 7, 2023 Author Report Posted February 7, 2023 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. Quote
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.