Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


karthickg last won the day on June 5

karthickg had the most liked content!


About karthickg

  • Rank

Profile Information

  • Gender
    Not Telling
  • Location
    Bangalore, India

Recent Profile Visitors

1,020 profile views
  1. karthickg

    SC_METHOD performance improvement discussion

    Are you only looking at disabling process_output from getting triggered when reset is on? In that case, it is as simple as: void fir::process_output() { if (reset.read() == 0) { //reset sequence next_trigger(reset.pos()); } else if (clk.read() == 0) { //Ignore the trigger just after reset is de-asserted and //sync to next clock edge next_trigger(clk.pos()); // Note: will work even if we comment out line above, due to static sensitivity } else { if(enable.read()) { //normal operation } } } But this may not really get you a significant improvement in itself. You may want to check what is going on in "normal operation" - and see if you can optimize that.
  2. I'm guessing you are trying to read the signal values immediately after calling write(). That won't return the values just written due to how update semantics work with primitive channels in SystemC. To make sure this is the cause of confusion, you can try creating a thread in your model where the signal values are written and read back after a delta-cycle wait: SC_MODULE(some_module) { sc_signal<pixel> p1; sc_signal<pixel> p2; void some_thread() { p1.write(pixel(1, 2, 3)); p2.write(pixel(4, 5, 6)); // Read and print p1 and p2 // Values won't be updated here wait(0, SC_NS); // Read and print p1 and p2 // Values will be updated here };
  3. Could be a CR-LF issue as well - in case the package was unzipped on Windows and then copied to the Ubuntu machine. Easiest way out will be to download the tar-ball again and unzip/untar on Ubuntu.
  4. It is possible to support "dynamic" model creation using SystemC, for example by reading command line parameters or a configuration file - if done before simulation starts. Once simulation starts, we can't create new models or add more ports. As an example, the following can be done: a. Have multiple top-levels, select one specific during a simulation run (using a command line argument or an environment variable or a config file, etc) b. Create models and connections "on the fly", based on a connection topology in a configuration file. An example can be, a network simulation where the number of end-stations change in every simulation run. c. Create bridges/switches that should add ports as and when connections are being made I do not know enough to answer to your questions in the later part of the post.
  5. Hi Bas, In trying to explain this a bit more, I looked up the double format. As per http://en.wikipedia.org/wiki/Double-precision_floating-point_format, the 8-byte double format can handle 15-17 significant decimal digits without loss of precision. When assigning, double d2 = (double) ull; the width of ull (4614 2566 5655 2045 848) is 19 significant decimal digits, which causes loss in precision.
  6. Hi Bas, Did you mean to say: double d = 3.1415926535897931; unsigned long long * ullp = (unsigned long long *) &d; out_port.write(*ullp); // sc_out<doubleunsigned long long> out_port; connected via sc_signal<doubleunsigned long long> to in_port unsigned long long ull = in_port.read(); // sc_in<doubleunsigned long long> in_port; connected via sc_signal<doubleunsigned long long> to out_port double * dp = (double *) &ull; Also, what is the output of sizeof(double) and sizeof(unsigned long long) in your case?
  7. karthickg

    Parameterised module instantiation

    [snip] SC_MODULE( sub_mod ) { sc_in<sc_bv<BUS_WIDTH> > in; . . sub_mod(sc_module_name nm,int BUS_WIDTH):sc_module(nm) { } }; The error has got nothing to do with SystemC, the code is not valid C++.. you can't use a constructor parameter ('int BUS_WIDTH') as a parameter to the template instance ('sc_in<sc_bv<BUS_WIDTH> >').
  8. karthickg

    Static order of execution for the SystemC Scheduler

    The standard doesn't provide any "hooks" by which the user can control the order in which the processes must trigger. The standard only says (my emphasis):
  9. Hi Philipp, Thanks, I was curious to know why the standard doesn't implement set_sensitive for spawned processes, and your response clarifies that. The issue is not so much about having to use "wait(event_list)" instead of just "wait()" - that is not a disadvantage at all (for me). The main problem is different.. My design requires a spawned method to set a boolean flag (say, m_flag) whenever a certain event (say, m_event) fires. This can be easily done: // Where the method gets spawned sc_spawn_options opt; opt.set_sensitive(m_event); opt.dont_initialize(); // Note! opt.spawn_method(); sc_spawn(sc_bind(&my_module::flag_event, this, some_var), NULL, &opt); // .... // Method body: void my_module::flag_event(int some_var) { m_flag = true; next_trigger(); } However, if the method has to wait for sc_event_or_list, then set_sensitive can't be used, and so dont_initialize can't be used. The flag_event has to now distinguish between the invocation at start of simulation, and the subsequent invocations when an event in the or'd list fires: sc_spawn_options opt; opt.spawn_method(); m_did_initialize = false; // Note! sc_spawn(sc_bind(&my_module::flag_event, this, some_var), NULL, &opt); // .... // Method body: void my_module::flag_event(int some_var) { if(m_did_initialize) { m_flag = true; next_trigger(m_event_or_list); } else { m_did_initialize = true; next_trigger(m_event_or_list); } } This is just plain clumsy to read, and needs an extra if-check every time the method gets invoked. I can think of a way to eliminate the if-check at simulation time: by having one more spawned method, but that is even more clumsy code; not worth the run-time cost (in my case). So I guess I do not have any alternative here. Thanks for your inputs anyway.
  10. Hello, Thanks for your reply - after seeing which, I had to go back to the standard to check to ascertain what is allowed and what is not.. My understanding is as below.. Quoting from the specification: So - what you have written certainly applies to unspawned processes. For spawned processes, The only question that remains is, can set_sensitivity be called on processes spawned after start of simulation? I'm not able to find an explicit yes or no in the specification, however there is an example (page 66) that shows that set_sensitivity can be called after start of simulation.
  11. karthickg

    Channel vs port value update

    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).
  12. Hello, To allow setting static sensitivity of dynamically spawned processes to an or'd list of sc_events, I expected to see a method like: void sc_spawn_options::set_sensitivity(const sc_event_or_list *); but do not see any such. next_trigger and wait however, do accept a reference to sc_event_or_list, so it appears to be inconsistent? For, dynamic sensitivity can use sc_event_or_list, but not static sensitivity.. I suppose we can't use sc_event_or_list to set the static sensitivity of statically spawned threads either (created using SC_THREAD/SC_METHOD) - but that is not my need. Further, there doesn't seem to be any way to retrieve the list of sc_event from an sc_event_or_list (as, say, std::vector<sc_event *>). If that was possible, then I could have called the set_sensitivity(const sc_event *) method repeatedly, for all events in the or'd list. Any help appreciated, thanks.
  13. Is it possible to model serial interfaces in TLM2? Yes, certainly - UART, SPI, I2C, etc. Specifically on MIPI - I have no idea, maybe someone else can comment. On how to go about modeling such interfaces - why not use TLM initiator/target socket itself?
  14. karthickg

    simulating time delays in SystemC

    There are two modules - one of them is clearly a memory. Let us call it 'memory': class memory : public sc_module { // ... }; ..And the other is reading from the memory, let us call it 'master': class master : public sc_module { // ... }; Now, before we can look at solving your question, we need to define how 'master' and 'memory' communicate. One option is via plain signals, for example an APB-like interface (a poort choice for a memory, but easier to list the signals): class master : public sc_module { public: sc_out<uint32_t> paddr; // Address sc_out<uint32_t> pwdata; // Write data sc_in<uint32_t> prdata; // Read data sc_in<bool> pready; // Ready signal from slave sc_in<bool> ptx_type; // Transfer type, read or write sc_out<bool> psel; // Select slave }; // class memory has the inverse of the above set of ports: sc_in for sc_out and vice versa The master class can start a 'write' transfer by writing the address and data on paddr/pwdata, and asserting the psel signal. Then, until the pready signal is asserted by memory, it has to wait. The memory will wait for required time (to simulate RAM access delay) before asserting pready: void master_thread() { // ... paddr = 0x1000; pwdata = 0x1234; psel = 1; wait(pclk.posedge_event()); // Wait for one clock to pass, to allow the slave to respond // Note: the exact number of clock cycles that the master has to wait depends on the bus protocol spec // Wait for slave: if it is not yet ready if(pready != 1) { wait(pready.posedge_event()); } // ... } If the master-memory communication is with a TLM style higher level interface, then it is easier. Assuming a blocking API, it can be as simple as: class master : public sc_module { apb_tlm_port master_port; // TLM APB master port // ... }; void master_thread(void) { // ... // Function will only return when the slave has completed the write, after delays if applicable master_port.write(0x1000, 0x1234); // ... }
  15. karthickg

    simulating time delays in SystemC

    Your question doesn't make sense.. you do not seem to understand how SystemC scheduling works. It is not possible to insert a wait statement "without removing the process from the runnable set and without allowing other thread to resume". The converse of that statement is actually true - it is only when a SystemC wait statement gets executed that an other thread is allowed to resume (and the current thread yields). The good news is, it is certainly possible to model memory delays with how the threads work in SystemC. It requires the modules to synchronize over the connected ports - so the 'memory' model will signal when the data is available, and the 'master' model should wait for that signal from memory.