Jump to content

David Black

Members
  • Content Count

    320
  • Joined

  • Last visited

  • Days Won

    68

David Black last won the day on April 3

David Black had the most liked content!

About David Black

  • Rank
    Advanced Member

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1,645 profile views
  1. Use the appropriate target convenience socket.
  2. David Black

    The problem of reading the custom structure is reasonable.

    sc_core::sc_signal<T> requires that you define the following: T::operator=(const T&) T::operator==(const T&) ostringstream&. operator<<( ostringstream&,const T& )
  3. Where do you set send_ptr? What with : cout << "send_ptr: " << hex << send_ptr << endl;
  4. Bind it... or change the binding policy to SC_ZERO_OR_MORE_BOUND but risk a NULL dereference crash if you forget to check for binding at run time.
  5. David Black

    sc_uint and unsigned int

    First, let me say that I would never use sc_signal<unsigned int>. Instead use sc_signal<std::uint32_t> for portability reasons. There are two considerations: sc_signal<uint32_t> is likely to be significantly faster than sc_signal<sc_uint<32>>. Especially if using the PoC implementation. sc_signal<sc_uint<32>> may be required by some synthesis tools if that is something you care about. If you want to be agnostic to both situations, you could set up a typedef header for your project and use your own names.
  6. David Black

    Constrained Random Performance

    For starters, you need to read section 18.14 of the SystemVerilog manual on the topic of Random Stability because $urandom_range() and t.trandomize() have very different seeds and simulation characteristics. This may affect your ability to validate bug fixes. As to why you saw such differences, did you try different simulators? Please do not disclose which simulators if you did since this would violate licensing agreements issued by EDA vendors to prevent simulator bashing. The reason I ask is that there can be a significant difference between vendors due to the constraint solver implementations. $urandom_range does not have to undergo constraint solver issues. Admittedly, your constraints look similar in effect, but the implications can be more complex.
  7. David Black

    SystemC implementation from C-code sources

    SystemC is not C. SystemC is C++, which is rather different (more complicated) than simple C. So you would do well to educate yourself in C++ before tackling SystemC. As to how to encapsulate an algorithm in SystemC, it rather depends heavily on the model, the inputs, the outputs, and what exactly you are trying to get from the model. Why are you using SystemC? Do you have specific tools in mind? What are you specifically using SystemC to accomplish? High level partitioning? Synthesis? Create a virtual platform? Analyze communications performance? You need to be much more specific.
  8. What do you see under /usr/local/systemc2.3.1/lib-linux64? In other words, what does the following reveal: ls -l /usr/local/systemc2.3.1/lib-linux64
  9. David Black

    Functional coverage- VCS

    This is a tools issue and not a UVM topic per se. This forum focuses on UVM issues. Your problem probably needs to be discussed on a Synopsys forum (not Accellera). That said, I believe vcs writes to log and database files located in the same directory where the tool was launched. So you should create separate directories for each run. This will likely require some simple (not necessarily trivial) scripting automation. vcs may also have some switches to help redirect file outputs. I recommend RTFM at a minimum.
  10. David Black

    Temporal Decoupling

    I believe it would be fair to say that there are no universally accepted best practices, and the system design will dictate much of the implementation. In the case of shared memory, the target would need to have some idea that the memory of interest is shared. So you would need somewhere in the system to have a mapping. It might be the entire device, or a memory map might exist as a configurable object. When the target receives a read request for shared memory, it would then synchronize in order to be certain that any writes from the past are completed in other initiators. Depending on your design, you might be able to reduce the number of synchronizations if you can know apriori the nature of the sharing. E.g. if a block of memory was shared using a mutex, then synchronization might be limited to the mutex with the assumption that if you own the mutex, then the block is not written to by other initiators. This of course has some risks in the face of software defects.
  11. David Black

    how can i know which event triggered a process?

    Responding to Phillip: I'm guessing this is coming up for the next update of the standard and is currently under consideration. I guess I need to find more time to get synced up to the latest additions since 2.3.
  12. Don't know how I missed that issue...
  13. If you will read the SystemC standard, you will see that Initators are required to set the response initially to TLM_INCOMPLETE_RESPONSE. Targets are obliged to change this to either TLM_OK_RESPONSE or one of the valid error returns. Seems your downstream targets never saw the transaction. Perhaps the address decoding (in the interconnect) went wrong. You are obliged to set the command, address, data pointer, data length, streaming width, byte enable pointer, DMI hint and response. I suggest RTFM, then debug the interconnect andr targets for a receipt.
  14. Port requires a pointer towards the object containing implementations of methods specified in the interface. Export provides the very pointer that port needs. Port goes from caller towards callee. Export goes from callee towards caller. Pseudo-graphically: // +----------------------------------------------------------------------------------+ // |struct Top : sc_module { | // | | // | initiator.p1.bind( target.x1 ); | // | | // | Initiator initiator{"orgin"}; Target target{"target"}; | // | +------------------------------------+ +--------------------------------------+ | // | |struct Initiator : sc_module { | |struct Target : sc_module { | | // | | | | | | // | | sc_port<IF> p1{"p1"}; | | sc_export<IF> x1{"x1"}; | | // | | caller.p0.bind( p1 ); | | x1.bind( callee.x0 ); | | // | | | | | | // | | Caller caller{"caller"}; | | Callee callee{"callee"}; | | // | | +----------------------------+ | | +------------------------------+ | | // | | |struct Caller : sc_module { | | | |struct Callee : sc_module, IF | | | // | | | | | | | | | | // | | | sc_port<IF> p0{"p0"}; | | | | sc_export<IF> x0{"x0"}; | | | // | | | SC_THREAD(thread1); | | | | Data m_data; | | | // | | | | | | | x0.bind(*this); | | | // | | | | | | | | | | // | | | .------------------. | | | | .----------------------. | | | // | | | | void thread1() | | | | | | void xfer( data& d ) | | | | // | | | | { | | | | | | { | | | | // | | | | p0->xfer( v ); | [p0]->[p1]->[x1]->[x0] | // Save/load d | | | | // | | | | } | | | | | | auto t = d; | | | | // | | | | | | | | | | d = m_data; | | | | // | | | | | | | | | | // Transform t | | | | // | | | | | | | | | | m_data = t; | | | | // | | | | | | | | | | } | | | | // | | | '------------------' | | | | '----------------------' | | | // | | | | | | | | | | // | | |}; | | | | | | | // | | +----------------------------+ | | +------------------------------+ | | // | | | | | | // | |}; | |}; | | // | +------------------------------------+ +--------------------------------------+ | // | | // |}; | // +----------------------------------------------------------------------------------+
  15. There is no rule stating that you must use the quantum keeper. Design your own.
×