Jump to content

All Activity

This stream auto-updates     

  1. Yesterday
  2. Hi @AmeyaVS I have solved this problem. This runtime error shows up when I try to trace out the wave of sc_fifo. Use the built-in trace() method of sc_fifo instate of sc_trace() solving this problem. #include "system.h" SYSTEM *top = NULL; int sc_main (int argc, char* argv[]) { top = new SYSTEM("top"); sc_trace_file *tr= sc_create_vcd_trace_file("pe"); sc_trace(tr,top->clk_sig,"clock"); top->Input.trace(tr); top->Output.trace(tr); sc_trace(tr,top->rst_sig,"rst"); sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING ); sc_start(); sc_close_vcd_trace_file(tr); return 0; }
  3. Last week
  4. I agree with Bas, recently integrated a model to UVM driver/component using standard TLM socket (simple_initiator_socket), tried with TLM put port first but didn't work. -RC
  5. Hello @chatbq, There is not enough context, probably the exception is being thrown from another module. Overall the code seems fine. You can try and see from where the exception is being thrown from the debugger. Regards, Ameya Vikram Singh
  6. Hi everyone, I have a runtime error when trying to simulate a sc_module An example of my code architecture is presented hereunder, do you see any problem? Here is my error: Error: (E519) wait() is only allowed in SC_THREADs and SC_CTHREADs: in SC_METHODs use next_trigger() instead In file: ../../../src/sysc/kernel/sc_wait.cpp:94 pe.h #include "systemc.h" template<typename IN_T, typename OUT_T> SC_MODULE (pe) { sc_in<bool> clk; sc_in<bool> rst; sc_fifo_in<IN_T> Input; sc_fifo_out<OUT_T> Output; void pe_proc(); SC_HAS_PROCESS(pe); pe(sc_module_name name_, int p_time_) : sc_module(name_), p_time(p_time_) { SC_CTHREAD(pe_proc, clk.pos()); reset_signal_is(rst, true); } private: int p_time; }; template<typename IN_T, typename OUT_T> void pe<IN_T, OUT_T>::pe_proc(void) { IN_T in_val; OUT_T out_val; // Reset code // Reset internal variables in_val = 0; out_val = 0; // Reset outputs wait(); while (true) { // Read inputs in_val = Input.read(); // Algorithm code for (int i = 0; i < p_time; i++) { wait(); } // write outputs out_val = (OUT_T) in_val; Output.write(out_val); } }
  7. Hello All I am trying to list out all the ports, sockets in a given SystemC platform. For that I am traversing the hierarchy using sc_get_top_level_object/get_child_object and able to list out all the ports and sockets. But for TLM 2 sockets I get two entries there for example - top_inst.init_inst.initiator_socket - top_inst.init_inst.initiator_socket_export_0 and - top_inst.memory_inst.target_socket - top_inst.memory_inst.target_socket_port_0 It is obvious because each TLM2 socket internally have one port and one sc_export. Is there a way that I get only those sockets which are visible in SystemC model header file for example I want to have only the following - top_inst.init_inst.initiator_socket - top_inst.memory_inst.target_socket Thanks Khushi
  8. Hello All I am trying to understand the hierarchical events and for this I created a SystemC class which contains a sc_event object. - How I can control an event to make it hierarchical or non-hierarchical ? -What is the example use case or hierarchical events. Can anyone help me on this ? Thanks Khushi
  9. tudor.timi

    Transaction Design Patterns

    Regarding point 4: If you want reusable abstractions, one of them is "register/memory accesses". Most hardware blocks use bus transactions to update/query special function registers or memory locations. This is also an abstraction that software/firmware engineers understand. You should look into that. There is so much variation in bus protocols that it's difficult to talk about a universal abstraction. It's also mostly pointless, as when you're talking about verifying bus level aspects, you're interested in the details of that bus protocol.
  10. tudor.timi

    Transaction Design Patterns

    The blog post you quoted w.r.t. working with types is correct regarding " The correct thing to do from an OOP perspective is to create a virtual function ", but not regarding the further points. In that case, where a protocol uses heterogeneous transaction types (i.e. different kinds have different properties), you're better off using the visitor pattern. The transactions would have a virtual function accept function.
  11. tudor.timi

    Transaction Design Patterns

    Regarding point number 3, I don't see why the coupling between transaction, driver and monitor is a bad thing. If you treat transactions as mere data classes, the behavior based on this data will have to be implemented in a different class. Should a transaction know how to drive itself and how to monitor itself? Should it also know how to cover itself? What if you have to add another operation, like tracing itself in a waveform viewer? Do you add that to the transaction class too? This violates the single responsibility principle.
  12. tudor.timi

    Transaction Design Patterns

    Regarding point number 1: Transactions aren't supposed to model traditional classes (not sure what the correct term for such classes is), which contain behavior (i.e. methods) and make use of polymorphism. Transactions are data classes, where you bundle information together to pass around, similar to plain old structs. Contrast the following examples: // Bad design // Using tag classes, where a "tag" field controls the behavior of methods is a code smell class service; direction_e dir; function void do_stuff(); if (dir == READ) do_read(); else do_write(); endfunction endclass // Better design, have two classes interface class service; pure virtual function void do_stuff(); endclass class read_service; virtual function void do_stuff(); // do read stuff endfunction endclass class write_service; // ... endclass In the case above, it makes sense to create different classes for handling reads and writes, because you have a common abstraction (doing stuff), which comes in two different flavors. How would you handle processing different kinds of transactions in a driver (for example) if you had different classes for read and for write? You'd need to cast, which is very frowned upon (at least in the software world). My point about transactions being data classes isn't strictly true w.r.t how they are currently used in the industry. Transactions are also used for randomization, which is a polymorphic operation. Even here though, assuming you want to generate a list of transactions, where some of them are reads, some of them are writes, it will be impossible to do this in a single step if you build up your class hierarchy in such a way that you have a 'read_transaction' class and a 'write_transaction' class. This is because you can't choose an object's type (and I mean from the point of view of the compiler) via randomization. Finally, why is 'direction' the field you choose to specialize on? Assuming you would also have another field in your transaction class called 'sec_mode', which could be either 'SECURE' or 'NONSECURE', would you be inclined to say that you need to create a 'secure_transaction' and a 'non_secure_transaction' because they are different things? Because you also chose to specialize based on direction, would you have 'secure_read_transaction', 'secure_write_transaction', 'nonsecure_read_transaction' and 'nonsecure_write_transaction'? What would happen if you would add another field called 'priviledge_mode', which could be 'PRIVILEGED' or 'UNPRIVILEGED'?
  13. tudor.timi

    Transaction Design Patterns

    Regarding point number 2: Having both a write_data and a read_data field in the transaction is bad design. A field called data would be sufficient and it would contain that data being transmitted in that transaction, whether it is a read or a write (i.e. regardless of what direction that data flows). The direction field tells you whether you're dealing with read_data or with write_data. Having both fields makes for a pretty difficult to use API if you want to do things irrespective of the direction: if (trans.direction == READ) do_stuff(trans.read_data); else do_stuff(trans.write_data); You'll find your code repeating these conditional statements all over. Contrast this to the case where you only have data: do_stuff(trans.data);
  14. Earlier
  15. https://matthieu-moy.fr/sc-during/doc/html/index.html I have found some library, which for the first look sound interesting and useful Is there any collective experience with it?
  16. Grisha

    Build error SystemC 2.3.3 with C++17

    +1. I tried to understand why I can't build under c++14 very long. Until I found this post. Thank you.
  17. From the standard: "Tagged? Incoming interface method calls are tagged with an id to indicate the socket through which they arrived."
  18. I have a multipass through target with nb_btransport_fw registered. init1 (target) init2 (target) Something like this target.register_nb_transport_fw( this, &top::nb_transport_fw); tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay){ } does the id parameter identify the incoming initiators or is it the id of the target socket which means this is stuck at 0?
  19. Use the appropriate target convenience socket.
  20. I have two multipass through initiators bound to same target. Is there a way to know the id of calling initiator?
  21. The list of open source UVM repositories can also provide an answer to question 4. I couldn't find any well supported (project with many stars) library of sequence items. There are many verification components for various bus protocols but they all have a single sequence items tailored specifically for that bus. This leads me back to question 3...
  22. The blog post also touches my third question although not providing an answer
  23. Looking at open source UVM repositories I think it safe to say that keeping all transaction types within the same sequence item class is the most common design pattern (the only pattern I found when looking at many of these repos). Luckily, I also found an interesting blog post about type handles that address what I'm looking for. There is a way of doing what I'm looking for although standard practice seems to be something else. I guess that keeping everything in one packet is more convenient. I think this answers my first question.
  24. Well, without lnowing the implementation it is hard to tell. I suppose your initiator sockets are connected to target sockets at he bus and the initiator sockets of the bus are connected to the target sockets of your target components. All these sockets need to be bound to each other (by calling bind() or the operator() function). There is no concept of bind-by-name in SystemC. Maybe you should have a look here: https://www.doulos.com/knowhow/systemc/tlm2/tutorial__3/ Sockets need to be bound except they are declared with the appropriate binding policy (the 4th template of the sockets). If this is not the case you need to create dummy targets.
  25. I'm guessing you are trying to read the signal values immediately after calling write(). That won't return the values just written due to how update semantics work with primitive channels in SystemC. To make sure this is the cause of confusion, you can try creating a thread in your model where the signal values are written and read back after a delta-cycle wait: SC_MODULE(some_module) { sc_signal<pixel> p1; sc_signal<pixel> p2; void some_thread() { p1.write(pixel(1, 2, 3)); p2.write(pixel(4, 5, 6)); // Read and print p1 and p2 // Values won't be updated here wait(0, SC_NS); // Read and print p1 and p2 // Values will be updated here };
  26. Andy Goodrich

    The problem of reading the custom structure is reasonable.

    I addition to the requirements mentioned by David, you need to define a constructor with 3 arguments for pixel, something like: struct pixel { sc_dt::sc_uint<8> r; sc_dt::sc_uint<8> g; sc_dt::sc_uint<8> b; pixel() :r(0), g(0), b(0) {} pixel( const sc_dt::sc_uint<8>& r_init, const sc_dt::sc_uint<8>& g_init, const sc_dt::sc_uint<8>& b_init ) : r(r_init), g(g_init), b(b_init) {} };
  27. I found an example from UVM Primer that has dedicated transactions as well as monitors for input and output so I guess that answers my second question.
  1. Load more activity