Jump to content

Roman Popov

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Roman Popov

  1. Hi johnmac, What you try to do is conceptually wrong: Ready and Valid should be two separate signals. Initiator drives the Valid signal, and responder drives the Ready. There is an example of ready-valid channel that comes together with SystemC, check in systemc/examples/sysc/2.3/sc_rvd If your final goal is synthesizable code, then both Mentor and Cadence synthesis tools already have it implemented in their libraries. Check vendor documentation. If you still want to simulate your design, you can try to use SC_UNCHECKED_WRITERS instead of SC_MANY_WRITERS. This will disable a check for multiple drivers in a single delta cycle.
  2. Hard to say something without a complete source code. The purpose of TLM-2.0 standard is model interoperability. So that TLM model developed by one vendor can be used in VP developed by other vendor. Building systems using low-level TLM-2.0 APIs can be quite hard. For device and system modeling you should probably use some high-level framework built on-top of TLM-2.0 standard. If you look for something open-source try to check GreenLib https://www.greensocs.com/docs , or SCML https://www.synopsys.com/cgi-bin/slcw/kits/reg.cgi . Large semiconductor vendors can have proprietary TLM frameworks, so check if there is one developed inside your company.
  3. No. If you want to model a gate with a delay to output you will need to attach a delay line (check AmeyaVS code on a thread I've referenced before) to output signal. But first I suggest you to learn what each line in your code does, and understand why it does not work.
  4. I don't work on Windows. But as far as I remember executable should be somewhere in project sub-directory called "Release" or "Debug". Sorry, can't help you more here.
  5. In the working directory (active directory when you launch the executable). Search for "and_gate.vcd"
  6. I've removed next_trigger and simulated your code. Check attached waveform. Check how to model delay line here:
  7. If by queue you mean payload event queue ( peq_with_cb_and_phase or peq_with_get), then it's purpose is to sort transactions based on delay annotation. Considering your example with two transactions: suppose you recieved 1st transaction with delay 40ns, and 2nd with delay 10 ns. Then you have to process 2nd transaction before 1st. Payload event queue may help with this.
  8. Your code is not correct. Why did you put next_trigger(5, SC_NS) inside a method? Remove it, and you will get correct waveform for and gate.
  9. Consider for example modern bus protocols like AMBA-AXI with out-of-order transaction termination. 2nd transaction can terminate before 1st in this case. It is not possible to model this with a single b_transport call. I think AT modeling was designed for such cases.
  10. Hard to say without debugging. In source code I see they are registered using "RegexpCollectionPrettyPrinter", probably sc_dt::sc_int<(.*)> matches sc_signal<sc_int<2>> ? By curiosity, may I know how you manage signals/ports? Signal has m_cur_val and m_new_val fields, storing current and next signal value. So they are pretty-printed as "m_cur_val -> m_new_val". Ports are just decorated pointers, signal port has m_interface field holding a pointer to signal, so pretty-printer dereferences it, casts to dynamic type and prints it the same way as signal. Actually you can do much more with GDB Python API. I have even written SystemC to Verilog converter using GDB (Generates complete netlist, but without process bodies). Commercial SystemC interactive simulators/debuggers are also based on GDB AFAIK.
  11. I'm not using this particular pretty-printer, since we have a better one internally. But simply by looking at source code, it seems like it does not supports signals/ports: https://github.com/AHeimberger/SystemC-2.3-Pretty-Printer/blob/master/systemc23/systemc23printers.py
  12. Thanks for explanation. In some scenarios std::terminate is what you actually want, since some exceptions are actually programming bugs, like for example out-of-bounds access in std::vector::at. And in this case you want debugger to show you a stack trace to the point where exception was originally thrown. According to this post from Herb Sutter : https://herbsutter.com/2018/07/02/trip-report-summer-iso-c-standards-meeting-rapperswil/ such kind of exceptions will migrate to contracts in future. So it seems like a C++ standard library design flaw, rather than SystemC problem. A side note rgd. debugging: if you use gdb there is a command 'catch throw' which stops execution right at the point where the (original) exception is thrown. This will break on each SystemC thread reset, since they are implemented using exceptions. Some other more precise mechanism required. 'catch throw std::out_of_range' works for std::vector::at. But catching base classes, like 'catch throw std::logic_error' does not .
  13. Disclaimer: I'm not an expert in C++ exceptions field. I've noticed that SystemC catches / re-throws standard exceptions. Why it does so? In practice that complicates debugging: instead of having a stacktrace to place where exception was originally thrown, I have a stack trace to place where systemc catches/rethrows it, which is not helpful at all. Should it be better to only catch sc_report?
  14. Some thoughts on these topics: During elaboration any C++ should be supported, including standard library. Language/library restrictions should only be imposed on process bodies (SC_THREADs and SC_METHODs). Otherwise SystemC synthesis would not be competitive vs languages focused on structure generation. Some design teams are already switching from SystemC to Chisel due to limitations in SystemC tools. std::array can be supported, but adds little value compared to C-style arrays. sc_vector should be supported. But unfortunately it only supports sc_object types. So I can't for example create sc_vector<sc_int<32>> to model RAM with elaboration-time defined size. std::vector allows expansion during simulation, that won't be synthesizable. I think it would be a good idea to extend sc_vector with non-sc_object types support. Also more flexible API can be added, like emplace_back(...) for elaboration-time programming. Attributes can't be used with template-based compile-time programming and elaboration-time programming. Macros will be the only way to program with attributes. That is bad. Instead, why not to to standardize a set of functions to pass synthesis directives? As usual, there is a compromise between simulation performance and flexibility of usage. I looked through proposals, and I think it would be nice to have both AC datatypes and improvement to existing bigint SystemC datatypes. From flexibility perspective, sc_unsigned and sc_signed are ideal, because they can be used both with template-based meta-programming and elaboration-time programming. So we have the same structural programming flexibility as in Chisel or MyHDL. AC datatypes are less flexible, but more efficient.
  15. Can't reproduce on my machine (Ubuntu 16.04, gcc 6.3). Probably something specific to Ubuntu 18.04. Can you check with some older OS?
  16. You can create a delayed clock signal that can be used to synchronize testbench threads. With a delta cycle delay you can achieve a behavior you want (enforce all testbench processes to be evaluated on next delta cycle after DUT process). However, such a test environment won't be reusable for non-verilated code (RTL simulation with commercial Verilog simulators, Gate-level simulation, etc). In a RTL design with a single clock domain Verilator converts all Verilog processes into a single SystemC clocked SC_METHOD. This SC_METHOD executes in a single delta cycle. However, in other Verilog simulators each Verilog process will be executed separately. For example, there can be a combinatorial logic process that can introduce arbitrary number of delta-cycle delays between clocked process in DUT and testbench. So sampling with a delta-cycle delay will not work. In a timing-aware gate-level simulation delay can be any time period less then a clock period (if design meets timing constraints). In that case sampling on a falling edge of a clock may not work. Canonical solution to this problem is to sample output on the next clock cycle. So, for example, to test a single D flip-flop you will need 3 clock cycles: On a 1st clock cycle test sets input data, on a 2nd cycle DFF captures input data, on a 3rd clock cycle test verifies DFF output data.
  17. I don't know much about SystemVerilog scheduling, but in SystemC there is no difference between RTL code and testbench code. So you should not rely on order of process evaluation inside a single delta cycle. In practice, I also use Verilator for verification of HLS-generated Verilog designs, but I've never needed a delayed sampling. Verilator does not introduce any additional delays to model so I can use original SystemC testbench as is. Why do you need delayed sampling?
  18. --Deleted-- I've re-read original post from Philipp and it provides detail explanation why it was made this way.
  19. No. Only assignment (or write() method) triggers update request. Constructor initializes signal value directly. So sig0 constructor generates no events and method1 is not activated.
  20. Most likely you have C++98 in CMake cache. You don't need to modify SystemC CMakeLists, just set c++ standard from command line. Check here for detailed instructions https://stackoverflow.com/questions/46875731/setting-up-a-systemc-project-with-cmake-undefined-reference-to-sc-core
  21. Here is an example illustrating initialization semantics. #include <systemc.h> SC_MODULE(test_init) { SC_CTOR(test_init) { SC_METHOD(method0); SC_METHOD(method1); sensitive << sig0; dont_initialize(); SC_METHOD(method2); sensitive << sig1; dont_initialize(); sig1 = 1; } void method0() { cout << "method0\n"; } sc_signal<int> sig0{"sig0",42}; void method1() { cout << "method1 sig0 == " << sig0 << endl; } sc_signal<int> sig1{"sig1"}; void method2() { cout << "method2 sig1 == " << sig1 << " sig0 == " << sig0 << endl; } }; int sc_main (int argc, char**argv) { test_init mod{"mod"}; sc_start(); return 0; } Simulation output: method0 method2 sig1 == 1 sig0 == 42 I think it covers both questions.
  22. Yes, this is how reference open-source SystemC kernel is implemented. You can compile SystemC in debug mode and step into wait(t) inside debugger to see for yourself. Such an implementation is not mandatory by SystemC standard, but afaik most commercial SystemC simulators are derived from reference one and most likely are implemented in the same way.
  23. In general, there is no such concept as a "list of sleep processes" in SystemC. Because, really, all processes are sleeping, except the one that is currently evaluated. For scheduling, there are two "lists" that simulator needs to maintain (my interpretation of LRM 4.2.1): Set of runnable processes - that are process that will be evaluated in a current evaluation phase (current delta cycle). Event notification queue, where notifications are prioritized by time. First come delta notifications (The set of delta notifications and time-outs), then timed notifications, prioritized by notification time (The set of timed notifications and time-outs) Probably the source of confusion here, is when you call wait(0,SC_NS) you don't see any event. But in fact there is a hidden "internal" event that you notify when you call wait(). This hidden event implements "time-outs". > Yes, wait(X, SC_NS) works the same way as event.notify(X,SC_NS). SystemC scheduling is all about event notifications. There are 3 types: event.notify() - Immediate notification. This will put all processes subscribed to event into set of runnable processes. That is, they will be executed in the current delta cycle. event.notify(SC_ZERO_TIME) - Delta notification. This will put delta event notification into event notification queue. event.notify( sc_time > 0 ) - Timed notification. This will put timed event notification into event notification queue.
  24. This is unexpected. Probably you don't see a full simulation log or your simulator has a bug. Try to add delta cycle counts to log: void p1(void) { while (true) { cout << "p1: " << sc_time_stamp() << " delta " << sc_delta_count() << endl; wait(0, SC_NS); } } void p2(void) { while (true) { cout << "p2: " << sc_time_stamp() << " delta " << sc_delta_count() << endl; wait(0, SC_NS); } }
  25. Did you configured it with pthreads as described in release notes? In general, if possible you should use Visual Studio or MinGW on Windows. Cygwin is not widely used with SystemC so some bugs are possible. Also SystemC with cygwin/pthreads is much slower then with fibers.
  • Create New...