Zoumson Posted December 4, 2019 Report Share Posted December 4, 2019 I am new to SystemC, and this is my first program. I have timer module already built. sc_main should contain the following points: Instantiation of timer module Trace ports/variable: clock start timeout count start signal to create a trace which contains a waveform of exactly 30 cycles (300ns, that is.) This 30-cycle waveform should include following scenarios: reset the timer for 3 cycles before it is released for counting, during counting reset the timer before count reaches 0, and during counting reset the timer after count reaches 0 clock frequency: 100MHZ Could anyone tell me how to improve my sc_main to get the desired output? Thanks in advance code files timer.h #include "systemc.h" SC_MODULE(timer) { sc_in<bool> start; // ports sc_out<bool> timeout; sc_in<bool> clock; int count; // data and function members void runtimer(); SC_CTOR(timer) { // constructor SC_THREAD(runtimer); sensitive << clock.pos() // sensitivity list << start; count = 0; } }; timer.cpp // timer.cpp #include "timer.h" void timer::runtimer() { while(1) { if (start.read()) { cout << "Timer: timer start detected "<< endl; count = 5; timeout.write(0); } else { if (count == 0) timeout.write(1); else { count--; timeout.write(0); } } wait(); } } main.cpp // main.cpp #include "systemc.h" #include "timer.h" int sc_main(int argc, char* argv[]) { sc_signal<bool> TIMEOUT, START, COUNT; sc_time clkPrd(10, SC_NS);// period sc_clock CLOCK("clock", clkPrd, 0.50, SC_ZERO_TIME, true); // timer clock // Binding timer tm("timer"); tm.count = COUNT; tm.timeout(TIMEOUT); tm.start(START); tm.clock(CLOCK); // sensitivity list tm << START << TIMEOUT << CLOCK; // tracing: sc_trace_file *tf = sc_create_vcd_trace_file("RESULT.vcd"); // External signals sc_trace(tf, CLOCK, "clock"); sc_trace(tf, START, "start"); sc_trace(tf, TIMEOUT, "timeout"); sc_trace(tf, COUNT, "count"); sc_start(30*clkPrd); // simulate for 30 cycles s sc_close_vcd_trace_file(tf); return(0); } Desired waveform output is attached. Quote Link to comment Share on other sites More sharing options...
Eyck Posted December 4, 2019 Report Share Posted December 4, 2019 It would be good if you could provide a description of the problem you see (or better error messages or alike) when building the unit. I see 2 things in your code: the statement labeled with '// sensitivity list' tm << START << TIMEOUT << CLOCK; is wrong. You did this already in the constructor (SC_CTOR(timer)) of your module. The sensitivity list of your timer is wrong. The thread should only wait for the positive edge of clock, start is a data signal which is sampled/read upon the rising edge of the clock I suggest to change the implementation from a coding style point of view: add a trace function to your timer module: void trace(sc_core::sc_trace_file* tf){ sc_trace(tf, clock, clock.name()); sc_trace(tf, start, start.name); sc_trace(tf, timeout, timeout.name()); sc_trace(tf, count, (std::string(name())+".count").c_str()); } The module knows what to trace, so in your sc_main you just call tm.trace(tf); usually it is beneficial to put the stimuli stuff into a separate unit. Either a testbench instantiating and wiring your module. Or into a stimuli module where you have at sc_main only the wiring. This increases re-usability. I personally prefer the testbench approach, this unifies sc_main(): int sc_main(int argc, char* argv[]) { // testbench timer_tb tmtb("timer_tb"); // tracing: sc_trace_file *tf = sc_create_vcd_trace_file("RESULT.vcd"); tmtb.trace(tf); // simulation sc_start(); sc_close_vcd_trace_file(tf); return(!sc_core::sc_stop_called()); } The timer_tb has to call sc_stop() once it is finished with stimuli. But this is a matter of taste. BR Zoumson 1 Quote Link to comment Share on other sites More sharing options...
Zoumson Posted December 5, 2019 Author Report Share Posted December 5, 2019 @EyckThanks for your input, the main issue for me was the sensitivity list, I just removed it from the sc_main and it works. And about defining the stimuli in a separated file, how can i achieve this if the stimuli make call to sc_start() periodically? The code is as follow, it works well, just want to know how to move the stimuli apart in a separated file int sc_main(int argc, char* argv[]) { // stimuli sc_signal<bool> START, TIMEOUT; sc_time clkPrd(10, SC_NS);// period sc_clock CLOCK("clock", clkPrd); // timer // Binding timer tm("timer"); tm.clock(CLOCK); tm.start(START); tm.timeout(TIMEOUT); // tracing sc_trace_file *tf = sc_create_vcd_trace_file("RESULT.vcd"); tm.trace(tf); // 3 cycles delay ---> first time START.write(1); sc_start(3*clkPrd); // start counting ---> first time START.write(0); sc_start(3*clkPrd); // reset before count reaches 0; 3 cycles delay ---> first time START.write(1); sc_start(3*clkPrd); // start counting again until count = 0 START.write(0); sc_start(5*clkPrd); // reset after count = 0; 3 cycles delay START.write(1); sc_start(3*clkPrd); // start counting ---> second time START.write(0); sc_start(3*clkPrd); // reset before count reaches 0 ---> second time START.write(1); sc_start(1*clkPrd); // start counting again until count = 0 ---> second time START.write(0); sc_start(6*clkPrd); // reset after count = 0; 3 cycles delay ---> second time START.write(1); sc_start(3*clkPrd); sc_close_vcd_trace_file(tf); return(0); } Quote Link to comment Share on other sites More sharing options...
Eyck Posted December 10, 2019 Report Share Posted December 10, 2019 Well, the timer_tb gets a SC_THREAD which has exactly your sequence of writing to START and advancing time. The only difference is to use wait() instead of sc_start()... 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.