Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


karthickg last won the day on September 18

karthickg had the most liked content!

1 Follower

About karthickg

  • Rank

Profile Information

  • Gender
    Not Telling
  • Location
    Bangalore, India

Recent Profile Visitors

891 profile views
  1. 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.
  2. 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.
  3. 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.
  4. 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?
  5. 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> >').
  6. 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):
  7. 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.
  8. 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.
  9. 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).
  10. 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.
  11. 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?
  12. 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); // ... }
  13. 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.
  14. karthickg

    Polling scenario

    If, a. In real hardware there is no interrupt signal, and b. The initiator can be replaced by an Instruction Set Simulator in future, then, I would suggest to let initiator poll the register content in the target (with some delay between the polls). Suppose the target blocks the initiator's read until the register gets updated - you'll run in to the following issues (as a sample): a. When the initiator is replaced by ISS, the ISS executes S/W which might expect a completely different behavior from the target. This can lead to dead-locks.. for instance, if the S/W has a "poll_thread" that is polling the register, and a "worker_thread" that does something causing the target's register to get updated, it is very much possible that the changed behavior on the target side causes a dead-lock. b. The target can hold the bus until the register gets updated. This can block other masters from accessing the bus - affecting the measured performance c. The behavior above can again potentially lead to a dead-lock, if a DMA is required before the register can get updated (the DMA will be blocked until the bus is free, and the bus is busy until the register gets updated, the regsiter gets updated after the DMA happens). In general, the SystemC model must be as smart as the RTL- but no further.
  15. karthickg

    Polling scenario

    What is the "Initiator" here? Is it emulating a processor model (and can, perhaps, execute the embedded software as well)? Or is it a DMA agent of a peripheral? In either case, what is the hardware behavior? Does the initiator poll the value of the register until it detects the register has been updated? Also, what is the behavior on the target/slave side? If the target "blocks the read until the register gets updated", the behavior corresponds to a "slave device introducing bus wait cycles until the register gets updated". Is this the behavior of the real hardware? Note that, depending on how the bus is modeled, if the slave blocks the read, it can potentially block other masters on the bus as well. That side-effect may not be something you want to introduce. In real H/W, if polling is costly, the design would have provisioned for an interrupt from the target/slave when the register is updated. Perhaps you can model it the same way? So, it is not easy to answer your question conclusively - it all depends on what you are trying to model.