Jump to content

David Black

Members
  • Posts

    690
  • Joined

  • Last visited

  • Days Won

    154

Everything posted by David Black

  1. Is this homework? What are you trying to model? What level are you trying to model? What questions is your model supposed to answer? Until we know what you hope to gain, we cannot reply with anything very useful.
  2. That's what the schematic says. No idea what your SystemC code looks like. Also, why would you use SystemC for RTL design? Use SystemVerilog or VHDL instead. SystemC is not suited well to RTL.
  3. Pretty much impossible to know exactly what the problem is without the rest of the context. How and were are XMT_datareg and databus defined?
  4. Personally, I prefer to put SC_HAS_PROCESS directly into the constructor body, which works very reliably. All that SC_HAS_PROCESS does is to create a typedef called SC_CURRENT_USER_MODULE which refers to .... the current module name. It is only used in the three macros SC_THREAD, SC_METHOD and SC_CTHREAD. Syntactically, C++ allows a typedef to be created within a function (in this case the constructor function). Advantages of this approach: It's defined very close to the point of usage. The user of a header file, does not need to see it. /.h #import <systemc> // I never use systemc.h ... class Blah: sc_module { Blah(sc_module_name); ~Blah(); } //.cpp file #include "Blah.h" using namespace sc_core; Blah::Blah(sc_module_name nm): sc_module(nm) { SC_HAS_PROCESS(Blah); SC_THREAD(blah_thread); ... } Blah::~Blah(){ }
  5. Seems like a lot more code than needed. Where's the specification? Why are you using sc_int<8> everywhere instead of std::uint8_t ? HINT: sc_int<W> slows down performance and is not needed for 8, 16, 32 or 64 bit types Passing time through the constructor is fine.
  6. Read IEEE 1666-2011 sections 9 & 10. Available for free download from http://www.accellera.org/downloads/ieee. Or watch a free video from https://www.doulos.com/knowhow/systemc/. Or take a class on SystemC & TLM from https://www.doulos.com/content/training/systemc_training.php. TLM 2.0 is a marketable skill and I get many requests for job references. You will need to become proficient at C++, SystemC fundamentals, and then TLM 2.0 in addition to having a good basic knowledge of hardware and software design.
  7. IEEE 1666-2011 section 10.2 states: IEEE 1666-2011 section 10.3.4 states:
  8. Assumes you are using a version of c++ that supports c++11, just add -std=c++11 to fix this problem or move the constructor arguments to the initializer list of your constructor, which will require abandoning the SC_CTOR macro in favor of full C++ constructor syntax. Or you use the deferred vector construction. Gcc 4.8 or newer supports c++11 if I recall correctly.
  9. I doubt the reset.neg() is the issue in this case. Furthermore, I disagree that the approach is wrong. Being sensitive to both edges can have a purpose depending on the design. For instance, assuming a positive edge going reset, you might wish to clear various things out on the leading edge and check that they remained so at the trailing edge. The real problem lies somewhere in the methods I strongly suspect. Perhaps the stimuli. We need to see the implementations.
  10. Methods registered as processes via SC_THREAD are not allowed to have arguments and must have the signature: void METHODNAME(void); Think of it this way: When you register a method to be used as a SystemC process, you are telling the simulator kernel to invoke the method for you, and you are also implicitly stating you will not be invoking it yourself. I suspect you simply need to remove the SC_THREAD registration. put(data) will be called from another thread process, and hence does not need a process locally. If your channel requires a local process, it will need to be something that is not part of the interface class.
  11. Correct. sc_export's must be bound during construction.
  12. Technically, you are not supposed to call sc_stop() more than once during a given simulation. Since version 2.3, you now have the option of using sc_pause() if you wish to go back and forth. But there is a more fundamental issue that should be observed: There is no way to pause an SC_METHOD as Biplab is requesting. You simply must re-enter the method. This is a strong reason for using SC_THREAD, which allows the use of wait(). If for some strange reason you insist on using SC_METHOD, then your only alternative is to create a state machine implementation in combination with using next_trigger(). These comments also apply to using suspend()/resume(), disable()/enable(), or sc_pause()/sc_start().
  13. It looks like you solved your problem; however, just a C++ note as to using of the keyword 'virtual' with classes and the infamous diamond problem. // Example demonstrating proper use virtual class inheritance to solve the dreaded diamond problem. // Only a problem when base class contains data. #include <iostream> #include <systemc> struct Base { int m_i; Base():m_i(42){} }; // Only one of the following two required to use 'virtual' keyword, but two is safer struct A : virtual Base { int m_a; A(): m_a(1){} }; struct B : virtual Base { int m_b; B(): m_b(2){} }; // The following will only have one copy of 'var' from Base struct Final: A, B { Final() { std::cout << "Constructed Final with m_i=" << m_i << std::endl; } }; int sc_main(int argc, char* argv[]) { Final f; sc_assert( f.m_i == 42 ); return 0; } // Copyright 2015 by David Black // License: Apache 2.0
  14. What is the compilation error you are seeing?
  15. The problem is that a wire can only be driven with hld_force. The register model assumes they are modeled as regs. You did not indicate how the regs were connected to the wire, but it probably doesn't matter. SystemVerilog allows a single process to assign a reg that is connected to a wire from within a module; however, if more than a single process is involved (e.g. the register model), then wire/assign semantics follow. I suspect that is your problem. If you care to post an example of your modules and how the reg's/wire's are connected and driven, we could confirm this.
  16. Instead of using the SC_MODULE macro, try using a standard declaration: struct Task : sc_core::sc_module, A { ... };
  17. You can launch processes from within a method using sc_spawn(). The SC_THREAD and SC_METHOD macros are only valid inside module constructors. By default sc_spawn() specifies SC_THREAD style behavior. If you need to specify static sensitivity, you will need to use sc_spawn_options. You could also use dynamic sensitivity and process control as an alternative.
  18. Normal SV active regions. If you use clocking blocks for signal interface (and refrain from input delay of 0ns), you will not have any problems w.r.t. races.
  19. You can write assertion property that generates events when it detect how long WREADY is asserted and the specific conditions under which it occurs. By means of a simple function call you can then notify the monitor of the data (# cycles) and capture the information to be passed on to a coverage collector. Doulos demonstrate something very like this (measuring Reset pulse widths) in their UVM training.
  20. I'm afraid that information is subject to the rules of Accellera. Only members may get early access and view the current schedule. If your company is a member, then you can get more information privately.
  21. Ask Altera support re. Quartus. I doubt it.
  22. This is easy. Just name your b_transport implementations: b_transport_N, b_transport_E, b_transport_S, b_transport_W, and register them for the respective sockets. Do the same for all the other methods. I would probably use multi_passthrough flavor of sockets for this. Example: #include "tlm_utils/multi_passthrough_initiator_socket.h" #include "tlm_utils/multi_passthrough_target_socket.h" struct Bus: sc_module // with two bidirectional sockets North & South { tlm_utils::multi_passthrough_target_socket<Bus> targ_socket_N; tlm_utils::multi_passthrough_initiator_socket<Bus> init_socket_N; tlm_utils::multi_passthrough_target_socket<Bus> targ_socket_S; tlm_utils::multi_passthrough_initiator_socket<Bus> init_socket_S; SC_CTOR(Bus) : targ_socket_N("targ_socket_N") , init_socket_N("init_socket_N") , targ_socket_S("targ_socket_S") , init_socket_S("init_socket_S") { targ_socket_N.register_b_transport( this, &Bus::b_transport_N ); targ_socket_S.register_b_transport( this, &Bus::b_transport_S ); ... } virtual void b_transport_N( int id, tlm::tlm_generic_payload& trans, sc_time& delay ); virtual void b_transport_S( int id, tlm::tlm_generic_payload& trans, sc_time& delay ); ... };
  23. Keep in mind that if you add any fields the driver needs to see, they must be present in the base_pkt -OR- there must be some base_pkt methods that provide access via some type of return value.
  24. Could you elaborate on the statement, "they grab the counter value at the same time"? Who is "they"? How are you modeling the FSM behavior? Are you using an inferred FSM perhaps? Have you considered temporally decoupling your model and performing synchronization only when the timer needs to be read?
×
×
  • Create New...