Jump to content

David Black

Members
  • Posts

    681
  • Joined

  • Last visited

  • Days Won

    152

Posts posted by David Black

  1. The reset_signal_is() method stop any currently executing process when the designated signal channel becomes active (high or low depending on the arguments). Then it resets the context of the thread-style processes so that they are called from the beginning. It does not actually reset or change the values of any other channels. It does not need to do that for the method-style processes because they don't hold any state like threads do.

     

  2.  

    1. Have you considered reading the specification (IEEE-1666-2011) - see section 7.3 String Literals on page 199?
    2. Have you tried: `maddress->write(sc_bv<40>("0x8979E54200"));` and had problems?
    3. Are you properly trained in C++?

    Note: Using `operator->` is preferred over `operator.` 

    1. Derive from sc_signal and overload the read method to call write before returning the previous value
    2. That would be awkward because writes are not seen until the next delta cycle and there is no way to guarantee which process goes first. Processes are not differentiated on the basis of module when executed by the SystemC Kernel (and there is intentionally no mechanism to do so since it would violate the premises of event driven simulation.) I suppose you could setup a module based mapping and determine the owner during the update cycle. You could perhaps defer reads to block until the next delta cycle.
    3. Derive from sc_signal and provide a new method to signal an event. Not sure how useful this is if you cannot write a value.
    4. Same as #3

    All of this requires you to have a deep understanding of the event-driven simulator kernel and be capable of writing your own primitive channels. You should thoroughly understand how sc_signal works.  You might find the following useful: https://github.com/dcblack/SystemC-Engine (or sign-up for Doulos' Fundamentals of SystemC course).

    Notice that this is all simple behavioral modeling using C++ constructs. If you do not know C++ well, then you need to get educated. C++ is a relatively complex topic and you won't learn everything about it in a forum. Your best bet is to educate yourself: read a book, take a course and apply it.

     

     

  3. 2 hours ago, DavidC said:

    By "proper" clock mux I mean a run-time selectable MUX (very much like what you would get in a hardware implementation), that preserves the attributes of a SystemC clock object (e.g. the clock period, so that downstream of the MUX you can use this trick).

    A naïve implementation might have the interface below:

    SC_MODULE(clk_mux) {
      sc_in_clk     clk1;
      sc_in_clk     clk2;
      sc_in< bool > clk_sel;
      sc_out_clk    clk;
     };

    In practise, I'm not sure sc_out_clk can be used. What might have to be used instead is sc_export< sc_signal_in_if<bool> >. Anyway, the above is for illustration purposes only.

    The way I've worked around it so far is by using what I would call an 'elaboration-time' selectable MUX instead. Ports are bound to the right clock (clk1 or clk2) at elaboration, but once the simulation has started it's obviously not possible to switch clocks. While is this a step in the right direction, it's not as flexible as I'd like.

     

    Bonus question: assuming a run-time selectable MUX can be implemented in SystemC, is it possible for any blocks downstream to automatically detect that the clock they receive has changed ? (so the behaviour of these blocks could be adjusted, for example when the clock period changes during the course of a simulation) 

     

     

    This looks suspiciously like a professor’s homework assignment or exam. 
     

    the answer is yes and there are many ways to do it. 

  4. 21 hours ago, Andy Goodrich said:

    The code snippet you provided is incomplete, you should have cases for each state, and regardless of how you run through the FSMMethod routine you need to always execute a next_trigger or your method will be orphaned. Why can't you use an SC_CTHREAD for the implementation, what is the rationale for not having a static event list?

    Likely because it is a school assignment or possibly because they are using a tool that cannot synthesize threads.

    Hopefully, not because somebody told them that SC_METHODs are faster than SC_THREADs. That depends heavily upon the implementation of SystemC itself. I know of cases where it is the other way around (SC_THREAD is faster than SC_METHOD).

  5. I was unaware that Verilator had a flow to allow mixed simulations, but more pointedly:

    1. main should call sc_main (not the other way around)
      1. Usually we don't write main because SystemC provides it to automatically call sc_main
    2. main only has two forms in my experience:
      1. int main( int argc, char* argv[]) // normal
      2. int main() // usually for embedded or simple situations
      3. You really should return a value from main. Either 0 (gives not much information and implies success) or a calculated value resulting in 0 (success) or 1 to 127 (failure)
  6. To do this you would need a have an sc_process to observe the situation. You can of course traverse the design hierarchy and obtain a list of all processes; however, you will not be able to ascertain why they are suspended. 

    Your question is a bit vague. Perhaps you could put a working code example on EDAplayground.com and give us a link to consider. 
     

    You could record the __FILE__ and __LINE__ in every process just before suspension in a process specific variable.

  7. All, if you rewrite the core. SystemC is simply a C++ library. 


    I routinely use C++17 with SystemC.

    I will suggest we don’t use C++20 for a few more years because:

    1. Compilers are still too immature

    2. Some of the changes are quite radical and will take time for user education (e.g., coroutines, modules, and ranges)

    3. Some changes would possibly require to much refactoring (e.g., modules)

  8. Quite the opposite. Because SystemC uses cooperative multi-tasking (which also implies single threaded in the OS world), then coding is much simpler. That is precisely why they chose to use cooperative multitasking. This is identical to the model used by Verilog, SystemVerilog and VHDL. Hardware engineers do not want to be concerned with mutexes and data sharing. Furthermore, most of the time (99.9%) we simply don't worry about delta cycles. The time when you might worry about them is when you have to write your own primitive channels.

    From reading your questions, it seems clear that you are not following the simulation model very well. You need to keep in mind that SystemC processes are not pre-emptive. There is no way for a process to interrupt another process.

    One other area, which gets some programmers into trouble is when they try to introduce OS parallelism into the picture without a clear understanding that the SystemC scheduler is NOT OS thread-safe. That requires special handling and is an advanced topic. SC_THREADs and SC_METHODs are not real OS processes. SystemC processes cooperate with one another by yielding at points when they are ready to give up control. The yielding statement is `sc_core::wait` with all its overloads

  9. It is doubtful to support since it would devote too many resources (specification, design, implementation, security, verification, training) from too many companies (SYNOPSYS, Cadence, Siemens EDA, Aldec) for something of little real benefit (commercial and practical). Another language interface would fragment support for an already complex language. No thank you. 
     

    You can always use SWIG if you really feel the need. 
     

  10. Your observations are correct, but it really is not a problem. Even in Verilog you cannot do differently:

    // Verilog/SystemVerilog
    module Design( input CLK, AV, RD );
      always @(posedge CLK)
        if ( AV == 0 && RD == 1 ) begin
          WriteDataOut(...);
        end
    endmodule

    So in SystemC:

    #include <systemc>
    using namespace sc_core; //< Simplifying bad practice
    SC_MODULE(Design) {
      sc_in<bool> CLK, AV, RD
      SC_CTOR(Design) {
        SC_METHOD(main_method);
        sensitive << CLK.pos();
      }
      void main_method() {
        if( not AV->read() && RD->read() ) {
          WriteDataOut(...);
        }
      }
    };

    Event driven simulators trigger on events, not values.

    In case you get distracted, here is a solution that will not work despite appearances:

    #include <systemc>
    using namespace sc_core; //< Simplifying bad practice
    SC_MODULE(Design) {
      sc_in<bool> CLK, AV, RD
      SC_CTOR(Design) {
        SC_METHOD(main_method);
      }
      void main_method() {
        next_trigger( CLK->posedge_event() & AV->posedge_event() & RD->negedge_event()); //< not what you might think
        if( not AV->read() && RD->read() ) {
          WriteDataOut(...);
        }
      }
    };

    The & in the next trigger means that invocation will occur when all three events have happened; however, there is no requirement on when they occur. In other words, they won't be lined up correctly.

     

×
×
  • Create New...