Jump to content

David Black

  • Content Count

  • Joined

  • Last visited

  • Days Won


David Black last won the day on July 9

David Black had the most liked content!


About David Black

  • Rank
    Advanced Member

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1,309 profile views
  1. SC_UNCHECKED_WRITERS also means allowing nasty race conditions.
  2. I think this all boils down to use cases: Programmer wants the fastest possible implementation of a virtual platform to develop their software on that is register accurate and functionally correct. Solution is to use Loosely Timed (LT) modeling style. Must maintain functional/register accuracy, but try to reduce anything that slows down simulation speed. Things that slow down simulation speed include I/O (logging messages), context switching, copying data unnecessarily, arbitration and using the bus in general. Architect wants to know if a particular configuration will work when taking into account all data traffic, which requires relatively accurate timing information on bus accesses. Solution is to use Approximately Timed (AT) modeling style. Speed of simulation is secondary, but speed of model creation is still high. RTL might provide the information, but has too much detail and takes too long to create. Skipping the bus (i.e. using DMI) is inappropriate as we need to see all bus traffic. Arbitration aspects are necessary. We can still minimize I/O somewhat, but some context switching is required to provide valid timing information. Notice that I did not mention blocking (B) vs non-blocking (NB), because that is not the issue. Blocking style is actually easier to code and avoids context switching required by AT, so it is used for LT style. Interestingly, we try to avoid actual blocking (using wait) when coding b_transport in order to improve performance. Temporal decoupling and DMI are simulation speedup techniques for LT and completely inappropriate for AT. If your bus supports it, we can reduce the number of NB calls to one, but many buses need to be modeled with more than one call. It is all very protocol dependent. It is also potentially tricky to get all of this correctly coded. Some buses like Arm's AXI require additional phases to properly represent all of the timing information needed.
  3. David Black


    Sorry, but I'm bit too busy for that. As I indicated, choice 1 is the best option. It is both easier and safer. Coding mistakes with the other options are highly likely and as a non-standard approach, you likely won't get any support or help when it breaks. Something you might not have considered: You can easily pass configuration information to your SystemC designs in many different ways: Access command-line options (i.e. like Linux) using sc_argc() and sc_argv() -- See https://github.com/dcblack/sc-command-line Test and get values via environment variables. Read a configuration file. Prompt the user at the command line.
  4. David Black


    You cannot. SystemC cannot be restarted without exiting and restarting the entire program. That said, you have three choices: Call your executable repeatedly from a script, saving the data in uniquely named log files. Same as 1 except you could use Linux 'exec' call to chain simulations together; however, be very careful with this. Probably #1 above is simpler and better for that reason. If you are able to deal with only having a single elaboration, then you could do the following: Create a global start_time_offset variable that you update between calls. Make sure you report/act-on time as if it is sc_time_stamp() - start_time_offset. Observation: #1 is still simpler and there are really no real advantages to this approach.
  5. Use a multi_pass_thru_socket and a simple loop (incomplete - extend as needed): #include <systemc> #include <tlm> #include <tlm_utils/simple_initiator_socket.h> #include <tlm_utils/multi_passthrough_initiator_socket.h> struct Broadcast : sc_core::sc_module tlm_utils::simple_target_socket target_socket<>; tlm_utils::multi_pass_through_initiator_socket initiator_socket<Broadcast>; SC_CTOR(Broadcast) : target_socket("target_socket") , initiator_socket("initiator_socket") { target_socket.register_b_transport( this, &Broadcast::b_transport ); } void b_transport(tlm::tlm_generic_payload& payload, sc_time& delay); }; void Broadcast::b_transport(tlm::tlm_generic_payload& payload, sc_time& delay) { for (size_t i=0; i<initiator_socket.size(); ++i) { initiator_socket[i]->b_transport(payload, delay); } } Of course you need to be careful with this because technically you probably need to copy the payload (i.e. create an individual transaction per target). If it is a an IGNORE_COMMAND and you use appropriately designed extensions, then it might work.
  6. David Black

    learning systemc

    Step 1: Become a proficient C++ coder. You should be very comfortable with C++ before tackling SystemC. Casual or novice knowledge is not good enough. For a list of topics, see alternate discussion on the topic of learning SystemC. Step 2. Review step 1 and make sure you can write code for each topic without hesitancy. Step 3. Read SystemC: From the Ground Up [Note: I am an author and therefore biased, but certainly not because it brings me any income worth noting]
  7. David Black

    learning systemc

    Step 1: Become a proficient C++ coder. You should be very comfortable with C++ before tackling SystemC. Casual or novice knowledge is not good enough.
  8. Looks to me like you are declaring sc_clock objects inside the constructor on the stack, which will then be immediately destroyed at the end of construction. They should be class members. Also, you appear to have the intent of using PHREADs; however, SystemC is not thread-safe unless you take special precautions. I would also suggest you consider using std::unique_ptr<> instead managing pointers yourself. Safety first.
  9. TLM2 is completely different from RTL type of connection. Interface won't work. Nor is there timing you can count on since it could be either AT or LT without timing. You also need to specify if you are interfacing between SV and SC or is this native SV UVM to UVM TLM2.
  10. David Black

    A void value confusion

    Based on what I see, the * shouldn't even be there at all since the -> takes care of it. Either use: mNeuron->dendrit[index].write(value); or (*mNeuron).dendrit[index].write(value); However, I'm more concerned that you're not using ports to access members of a module (assuming Dendrit_Set is not part of module Neuron). That violates a rather fundamental principle of SystemC. It's legal C++, but questionable SystemC.
  11. David Black

    SystemC linking problem in Ubuntu

    On the surface I would say you have a problem with your own code, but I cannot say much more because you did not share the code with us. At a minimum I would need to see main.cpp, but if you have other source files (e.g. state.cpp, which I would expect since any self-respecting C++ coder would put each class into its own CLASSNAME.cpp and CLASSNAME.h (or .hpp) file). Note: This has nothing to do with Ubuntu and likely little to do with the SystemC version.
  12. David Black

    Passing event to SC_CTHREAD macro

    The only use I see for SC_CTHREAD is synthesis tools, and this is really just a legacy issue and a vendor tools issue. The same SC_THREAD could have been used for posedge_event. This would change the coding of wait in your code though: wait(5); // 5 clock delay becomes for(int i=5; i--;) wait();// prior to C++17 which could easily be addressed with: void nWait(size_t n) { while(n--) wait(); } and allows nWait(5);
  13. I went and looked at the website where this stuff was supposed to be and found problems. I then dug around and found an archived copy, did a quick sanity check, and I've now published it on GitHub under github.com/dcblack/SCFTGU_BOOK As noted, I am working on a modern version, but time is limited.
  14. David Black

    Implement sc_trace for std::string

    Perhaps you would be willing to share your work as an Apache 2.0 licensed github project with the minimal code needed and a screen snapshot of the results.
  15. David Black

    reset method or thread

    Reset is accomplished by throwing an exception. You cannot perform cleanup *before*, but you can perform cleanup on the way out in two manners. First, automatically created objects will of course run their destructors as guaranteed by C++. Second, you can catch exceptions by strategic placement of try-catch blocks and looking for the appropriate sc_exception. It is required by SystemC that you rethrow after catching; otherwise, you will corrupt the SystemC kernel.