Jump to content

Roman Popov

Members
  • Content Count

    305
  • Joined

  • Last visited

  • Days Won

    35

Reputation Activity

  1. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    You have controversial requirements:
    a) put stored value when enable == 1 , which sounds like a dff with output_enable 
    b) put input to output when enable == 1, which sounds more like a latch
    Anyway, in both cases you will need to make process sensitive to enable signal. And usually such  low-level logic is modeled with SC_METHODs.
    In SystemC context "register" usually means some memory-mapped CSR on TLM bus 🙂   
  2. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    What do you mean exactly by "modeling a register"?
    If you are working on synthesizable code (i.e. using Mentor/Cadence HLS tools), then it is not possible to have 0-delay communication between threads in synthesizable code, as you wanted in original post. At least it was not possible last time I've used these tools. 
    If you are working on some non-synthesizable high-level model, then you can model "register" any way you like, you don't even have to use sc_signal<> for that purpose. 
     
  3. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    If you want immediate communications  between threads, then you should use regular SC_THREADs and wait on event, like  wait(some_signal.value_changed_event());
  4. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    You have 2 clocked processes. Any communication between them will take at least 1 clock cycle. If you need request and response, then you have at least 2 cycle latency.
  5. Like
    Roman Popov got a reaction from David Black in Systemc performance   
    Real-life simulation performance usually depends a lot on modeling style. For high-level TLM-2.0 models share of simulation time consumed by SystemC primitives is usually much lower, comparing to time consumed by "business logic" of models.  Efficiency of simulation kernel (like context switches and channels) is much more important for low-level RTL simulations.
  6. Like
    Roman Popov reacted to karthickg in SC_METHOD performance improvement discussion   
    Are you only looking at disabling  process_output from getting triggered when reset is on? In that case, it is as simple as:
    void fir::process_output() { if (reset.read() == 0) { //reset sequence next_trigger(reset.pos()); } else if (clk.read() == 0) { //Ignore the trigger just after reset is de-asserted and //sync to next clock edge next_trigger(clk.pos()); // Note: will work even if we comment out line above, due to static sensitivity } else { if(enable.read()) { //normal operation } } } But this may not really get you a significant improvement in itself. You may want to check what is going on in "normal operation" - and see if you can optimize that.
  7. Like
    Roman Popov got a reaction from mladia in Support for C++11/14 in SystemC 2.3.2   
    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
  8. Thanks
    Roman Popov got a reaction from Teddy Minz in Synthetizable FFT function in SystemC   
    From SystemC standard:
    SystemC requires that you add sc_module_name as a parameter to module constructors, like this:
    MULT(sc_module_name, int var_a, int var_b); MULT(sc_module_name); This is a hack that allows SystemC kernel to track lifetime of constructor.
  9. Thanks
    Roman Popov got a reaction from Teddy Minz in Synthetizable FFT function in SystemC   
    If you code your FFT as a pure C++ function, Vivado HLS will generate inputs and outputs automatically from function parameters and based on INTERFACE pragmas. And you can import generated RTL into Vivado IP integrator.  Check out Xilinx documentation, and ask on Xilinx forums. 
    Please also note that you can implement FFT in a various ways (with different micro-architectures), and achieve various performance vs area numbers. And HLS also requires quite a lot of learning to achieve good results.
     
  10. Thanks
    Roman Popov got a reaction from Teddy Minz in Synthetizable FFT function in SystemC   
    Xilinx HLS tools have very limited SystemC support, you should probably code your FFT in pure C++.
  11. Thanks
    Roman Popov got a reaction from JorgeAbarca in write different types of data in a custom port   
    But even this won't fix your error.  Because compiler will still complain about assigning sc_logic to double, even if it is in always false branch.
    What you need is if-constexpr and std::is_same if you have C++17.  Or SFINAE, if you don't.  Something like this may work:
    if constexpr (std::is_same_v<T, sc_dt::sc_logic>) { out = SC_LOGIC_Z; } else { out = 0; }  
  12. Like
    Roman Popov got a reaction from Teddy Minz in SystemC implementation from C-code sources   
    You should start with learning your synthesis tool documentation. C++/SystemC synthesis is very tool-specific. 
  13. Like
    Roman Popov reacted to tjd in tlm_fifo nb_peek   
    Just generated one.  There is a tarball attached that contains a producer, consumer, and a main that connects the two.  Also included is a simple bash script with my compilation commands and the log generated from running the script where I've also appended the G++ version to it.
     
    tlm_ex.tar
  14. Like
    Roman Popov got a reaction from maehne in How can I have a virtual interface in systemC analogous to systemverilog   
    SystemC has no special concept similar to SystemVerilog interfaces.  Instead you can use regular SystemC modules to work as SystemVerilog interfaces.
     
    SystemC has it's own notion of interface that is similar to interface notion in object-oriented programming: interface is basically a set of pure virtual functions.
    So for example you can define a simple memory interface as a set of mem_read and mem_write functions. SystemC requires that interfaces inherit virtually from sc_interface:
    struct memory_if : virtual sc_interface { virtual uint32_t mem_read( uint32_t address) = 0; // reads data from memory at given address virtual void mem_write( uint32_t address, uint32_t data) = 0; // writes data to memory at given address }; Next you can define a module that implements and exports this interface.  For example:
    struct memory_module : sc_module, memory_if { sc_export<memory_if> mem_export{"mem_export"}; SC_CTOR(memory_module) { mem_export.bind(*this); } private: std::array<uint32_t , 1024> mem; uint32_t mem_read(uint32_t address) override { return mem.at(address >> 2); } void mem_write(uint32_t address, uint32_t data) override { mem.at(address >> 2) = data; } }; You can have other modules implementing memory_if.  For example you can write a module that translates mem_read and mem_write function calls into a cycle-accurate signal-level memory protocol.  And this is what SystemVerilog interfaces often do.  
    Now the closest analog to SystemVerilog virtual interface is SystemC sc_port. For example you can define a test_module that has a sc_port<memory_if> and sends memory reads and writes using this port:
    struct test_module : sc_module { sc_port<memory_if> mem_port{"mem_port"}; SC_CTOR(test_module) { SC_THREAD(test_thread); } private: void test_thread() { cout << " test_thread \n"; const int TEST_SIZE = 10; for (int i = 0; i < TEST_SIZE; ++i) { cout << hex << "Write mem[" << i * 4 << "] = " << i << "\n"; mem_port->mem_write(i*4, i); } for (int i = 0; i < TEST_SIZE; ++i) { cout << hex << "Read mem[" << i * 4 << "] == " << mem_port->mem_read( i * 4 ) << "\n"; } } };  
    To create a simulation you instantiate both memory_module and test_module and bind port to export:
    int sc_main (int argc, char **argv) { test_module tmod{"tmod"}; memory_module mmod{"mmod"}; tmod.mem_port.bind(mmod.mem_export); sc_start(); return 0; }  
  15. Like
    Roman Popov reacted to David Black in How can I implement SC_FORK JOIN_ANY /SC_FORK JOIN_NONE   
    Read up on sc_spawn and sc_process_handle. Basically, you can do something like:
    // Example of fork-join any std::vector<sc_process_handle> process_handles; process_handles.push_back( sc_spawn( [&](){ ... } ); //< repeat as needed ... sc_event_or_list terminated_events; for( auto& ph : process_handles ) { terminated_events |= ph.terminated_event(); } wait( terminated_events ); //< wait for any process to exit for( auto& ph : process_handles ) { ph.kill(); } // Example of fork-join none (void)spawn( [&](){ ... } ); //< repeat as needed ...  
  16. Thanks
    Roman Popov reacted to Eyck in TLM transaction tracing   
    Maybe a little bit late but there are socket implementations available which do trace tlm transactions int a SCV database. They can be found at https://github.com/Minres/SystemC-Components/tree/master/incl/scv4tlm and are used e.g. at https://github.com/Minres/SystemC-Components/blob/5f7387ab7e3dfc2ff6a7cac6fbe834ed7ec8ae36/incl/sysc/tlmtarget.h which in turn serve as building blocks in https://github.com/Minres/SystemC-Components-Test/tree/master/examples/simple_system
    The setup given by Kai is put into sysc::tracer where all the tracing setup (VCD & SCV) is impelemted.
    Best regards
    -Eyck
  17. Like
    Roman Popov got a reaction from TRANG in Initial value port   
    Nice, I didn't know such a method exists! Looks like it does what you want.
  18. Like
    Roman Popov reacted to TRANG in Initial value port   
    Thank @David Black and @Roman Popov
    Thank you so much!!!
    But I think that, initialize the value depend on specification model require.
    Ex:  Model A can reset Model B  with reset port active with LOW level
    Then sc_out<bool> resetPort; in the Model A must be set initialize the value for resetPort is 1 on constructor
    So I think that , Should set initialize the value of port on constructor
     -->  Clearly
    -->  Easy maintain source code
    / //A.h class A: public sc_module { public: sc_in<bool> clkAPM; sc_out<bool> resetPort; sc_signal<bool> sig; ... ///A.cpp A::A(sc_module_name name) :sc_module(name) // Initializing ,clkAPM("clkAPM") ,resetPort("resetPort") ,sig("sig") {//{{{ /// Initializing resetPort.initialize(true); sig.write(true); SC_METHOD(AMethod); dont_initialize(); sensitive << sig ; ...  
  19. Like
    Roman Popov got a reaction from TRANG in Why sc_signal<T>::trace() is deprecated ?   
    Hi all, For debugging purposes it may be useful to add all signals in design to trace file. However, sc_signal::trace() which may allow to do it automatically is deprecated. Why is that?   In general I think it will be useful to add trace method to sc_interface, so that all channels that support tracing can implement it. And then it will be possible to implement something like: sc_trace_all(sc_trace_file *tf) // add all objects that support tracing to trace file.
  20. Like
    Roman Popov got a reaction from swami060 in sc_in/sc_out : hierarchical connections   
    Yes, but direction of binds matters. 
    For example if you want to bind  ( in0 -> in1 -> signal  ) then you will need to write:
    in0 ( in1 ); in1 ( signal ); OR
    in1 ( signal ); in0 ( in1 ); In your examples you bind like this:
    Ex1:  port0 <- port1 -> signal  // port0 not binded
    Ex2:  signal <- port0 -> signal  // port0 binded to 2 signals 
    I agree that error message in first case is misleading.  
  21. Like
    Roman Popov got a reaction from maehne in Array when declare port for model   
    This is a very old style.
    With a modern SystemC you can have the same with sc_vector:
    //exxe.h class EXXE : public sc_module { public:     sc_vector<sc_in<sc_dt::uint64>>  SC_NAMED(clock,3);     sc_vector<sc_in<bool>>           SC_NAMED(input,5);     EXXE(sc_module_name);     ~EXXE(); } But as David mentioned, before starting learning SystemC you should learn C++ first.  Trying to understand SystemC without being proficient with C++ is a waste of time.
  22. Like
    Roman Popov got a reaction from David Black in Wrapping an RTL model in a TLM LT Model   
    The problem is, when you integrate RTL IP into Loosely-Timed  VP that way, the whole simulator will have a performance of cycle-accurate model. Because clock generator will be always on, and Verilated model will be triggered even if it is idle. So don't try to boot Linux with such a simulator.
    If your RTL IP supports power gating or clock gating, it is a good idea to disable clock generation when RTL IP is turned off. In that case you don't pay for what you don't use: you can boot your OS quickly and then enable clock generator when you start to debug IP-specific driver code.
  23. Like
    Roman Popov got a reaction from David Black in Wrapping an RTL model in a TLM LT Model   
    The problem is, when you integrate RTL IP into Loosely-Timed  VP that way, the whole simulator will have a performance of cycle-accurate model. Because clock generator will be always on, and Verilated model will be triggered even if it is idle. So don't try to boot Linux with such a simulator.
    If your RTL IP supports power gating or clock gating, it is a good idea to disable clock generation when RTL IP is turned off. In that case you don't pay for what you don't use: you can boot your OS quickly and then enable clock generator when you start to debug IP-specific driver code.
  24. Thanks
    Roman Popov reacted to AmeyaVS in What is SystemC library special in?   
    Hello @Elvis Shera,
    It seems your SystemC library has been build with different C++ standard flag.
    Can you post the output of following commands?:
    # Compiler version you are using g++ -v # Library Properties: nm -C $SYSTEMC_HOME/lib-linux64/libsystemc.so | grep api_version Regards,
    Ameya Vikram Singh
  25. Like
    Roman Popov got a reaction from Jayshree in 2d array data passing through generic payload   
    Those questions are covered in detail in paragraphs 14.1 and 14.2 of SystemC standard.  Can't answer in a better way.
    TLM2.0 simulations are not cycle-accurate, so you don't have clock edge events.  In AT modeling style you should call wait(delay) after each transport call.  In LT modeling style all initiators are temporaly decoupled and can run ahead of simulation time, usually for a globally specified time quantum. 
    For debugging you can use the same techinques as in cycle-accurate modeling:
    Source-level debugging with breakpoints and stepping Transaction and signal tracing Logging Comparing with RTL, debugging using waveform won't be that effective, because in AT/LT modeling state of model can change significantly in a single simulator/waveform step.  Usually preffered way is combination of logging and source-level debug. Debugging TLM models is harder comparing to RTL. Also C++ is much more complex and error-prone comparing to VHDL/Verilog. 
×