Jump to content
Zoumson

sc_main function for timer in SystemC

Recommended Posts

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. 

Screen Shot 2019-12-04 at 19.26.21.png

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Thanks 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);
  }

 

Share this post


Link to post
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...