Jump to content

David Black

  • Content Count

  • Joined

  • Last visited

  • Days Won


David Black last won the day on February 6

David Black had the most liked content!


About David Black

  • Rank
    Advanced Member

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1,532 profile views
  1. Assumption: TLM means TLM 2.0 Each system has at least one initiator (presumably the CPU). Initiators cannot talk directly to one another because that would be like saying function f1() can somehow cause function f2() to call f1() and interchange information. It just doesn't work. However, f1() can deposit data in an agreed upon shared data location, and f2() can then interrogate that memory location. Furthermore, in SystemC, the call of f1() can also invoke an sc_event to wake up the other process from sleep. There is a danger to be aware of depending on how the information is transferred. If the information is exchanged atomically, there is not problem, and this is easy to accomplish in SystemC modeling since it is currently a cooperative multi-tasking environment. However, if your channels simulate timewise transfer of data, then you may need to include a SystemC mutex. A trivial way of ensuring synchronization would be to simply use an sc_fifo or a tlm_fifo in the target object. Suggestion: Learn SystemC core concepts before learning TLM-2.0.
  2. David Black

    how can i know which event triggered a process?

    Simple answer: there really is no straightforward way to do this. Of course if you wanted to get into the internals of the SystemC implementation, it is possible; however, that completely violates the standard. As to why this is not allowed: performance. The desire to have efficiency overrides the desire for corner cases such as yours. How can you work around this? Several possible approaches, but here one I would use: Create a new event class that adds tracking and an API to access it. This is easy to do if you know your C++ and SystemC well enough. Trivial outline of concept:: static const sc_core::sc_process_handle NONEXISTANT; struct Tracked_Event { void notify( void ); // sets m_process_handle and notifies m_event void notify( sc_core::sc_time delay ); // same except waits for delay sc_process_handle get_trigger( void ) { return m_process_handle; } void clear( void ) { m_process_handle = NONEXISTANT; }; private: sc_core::sc_event m_event; sc_core::sc_processhandle m_process_handle; }; struct Event_array { Event_array( int depth ); void wait( void ); // clears all m_process on entry, then waits for an m_event Tracked_event operator[]( int ); sc_vector<sc_core::sc_process_handle> get_trigger_list( void ); private: sc_vector<Tracked_Event> m_event_array; sc_core::uint64 m_delta_count; };
  3. David Black

    How to reset a thread in SystemC

    SC_THREADs are simply threads that are sensitive to a clock. Instead of wait(10ns), you wait(2), which means to "wait 2 clocks". Does not work for SC_METHOD though (no equivalent).
  4. In LT with Temporal Delay, the initiators maintain a local variable (sometimes with the aid of the Quantum Keeper) that represents time. Although time is not as important, we don't want to throw it completely away. So each initiator keeps a variable that represents how far ahead of the simulator's notion of time it has progressed. You can represent execution of instructions by simply adding a time value to that variable. Targets want to know the current simulated (not simulator) time so they can respond appropriately. For example, a timer definitely needs a notion of time in order to timeout. So initiators pass their local notion of the "current time" to the target. If a target wants to represent the notion of a time change, it can add to that delay, which will be reflected in the initiator since the b_transport call passes it by reference. LT models don't completely avoid sc_core::wait(), but they do try to minimize it because context switches affect performance. Adding to a local variable doesn't have as much of a hit.
  5. I think there are a few more options, but first, you need to acutely aware of the issue of OS thread safety. The SystemC kernel is not generally thread-safe unless you use async_request_update(), and a queue. I've done this several times. That said you have several options: Place software inside a SystemC SC_THREAD and provide convenience methods to initiate TLM transport calls. This is the simplest SystemC approach, but does not allow for modeling the actual CPU planned to be used and hence timing is not very accurate. This has the fastest performance from the SystemC point of view. Place the software on a development board that has the target CPU and some type of communications to the machine where you will run SystemC. I generally use TCP/IP sockets. Replace the driver with a special socket call passing packets to to a remote machine and receiving back the response. On the SystemC side, create an OS thread to receive the socket and inject the message into SystemC via the async_request_update call and an unbounded STL queue or FIFO of some type. A TLM 1.0 FIFO might do. A receiving thread can then pass the data into the SystemC simulation and return the result. This is somewhat more overhead, but allows for a more accurate target CPU. Obtain an ISS (Instruction Set Simulator) for the target processor and interface it to SystemC. This varies in complexity. You might look at existing models or talk with vendors such as Cadence or Mentor. Or perhaps your CPU vendor (e.g. Arm has some very nice models). As @Eyck suggested QEMU, DBT-RISE´╗┐-RISCV´╗┐. Also Gem5 (Google it).
  6. David Black

    How to reset a thread in SystemC

    Use SystemC 2.3 is your only easy option. I would expect much help from others to recreate what has already been done. You could also recast threads into cthreads (which has always worked).
  7. David Black

    Count number of SC_THREAD and/or SC_METHOD

    Caveat: That is the number of statically allocated processes. It does not account for dynamic threads or processes (i.e. sc_spawn'ed), which would be more difficult to track. Mind you, it is pretty complete and most likely static is what you are after.
  8. David Black

    Log File Parsing

    Just a few short thoughts: 1. If using SystemC or UVM, you should use restrict messages to the respective SC_REPORT_* or `uvm_report_* macros. These have standardized output formats, which makes them easier to use. 2. If using SystemVerilog without UVM, then use $info, $error, etc. for similar reasons 3. At the end of a simulation, you can detect how many errors etc. and use a return code. If would also suggest always printing a summary of the run (e.g. how many warnings and erros), and ALWAYS show one of two messages at the end: PASSED or FAILED. Makes life easier. My reason for the original logscan tool was situations where you don't have control over the error messages (e.g. certain EDA tools output).
  9. David Black

    Verifying Verification Components

    @kilroy369 I had forgotten that one. Much better suggestion. Same basic idea.
  10. David Black

    Verifying Verification Components

    I would do something I've previously done with SystemC (where uvm_error hails from). Basically, replaced the report handler with my own intercept to recategorize errors. Then added a mechanism to register "expected" errors, warnings, fatals. Prior to a point where an error was going to be injected, I would issue something like: begin_expect_error( "packet failure", 2 ); inject_error( ... ); wait_for_appropriate_time_or_event(); end_expect_error( "packet failure" ); If the report handler sees up to two errors, I would change the message severity to INFO and count off the expected error. At the end_expect_error call, I would check that exactly the number of expected errors occurred or consider it an error. Also, have to consider the possibility of the end_ call never happening.
  11. If your question on UVM is whether the repository is open to modifications, the answer is no. The UVM proof of concept library is carefully managed by Accellera as part of the standard's development. I cannot answer the question about test suites.
  12. David Black

    Log File Parsing

    Surprisingly, to me at least, a perl script I wrote in 1997 still appears to be popular. You can find it here: <https://github.com/dcblack/logscan/blob/master/README.md>.
  13. SystemC's implementation code is not generally an area we discuss except in the extremely rare instance we find a bug. Please read IEEE-1666 standards document (freely available via accellera.org). The behavior is correct.
  14. David Black

    Initial value port

    [Sorry for delay. For some reason I was not notified of your reply.] The point of my challenge was that you would not initialize the FIFO beyond allowing to come up empty. At least I have never see a FIFO that would be pre-filled. At start_of_simulation, you can initialize all you want as long as you can do everything within a single delta cycle. Hence you can write signals and fffos. Effectively, start_of_simulation is when activity is allowed to start happening.
  15. Based on the question, it seems to me that you need to take a class in C++. Anyhow, of course you cannot execute an object file. You need a fully linked executable. Files ending in .o are not executable because they do not contain fully resolved code. Linking is part of the process of compilation. If your code compiled, I expect there is another file either with no extension or perhaps with .x or .exe. In any event, you definitely should not ever have to add the execute privilege (chmod +x). In fact, that was a bold and dangerous move on your part.