Jump to content

Eyck

Members
  • Content Count

    197
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by Eyck

  1. sc_time_stamp() returns a sc_time objec, not a string. It seems the use in a particular context (e.g. cout<<sc_time_stamp()) triggers an implicit type conversion. Pls. refer to the standard how to convert to particular unit.
  2. As the error message says: you forgot to bind a port. Since the are no names given (which I always suggest to do) it is a generated name. Moreover the sc_vector is not initialized to a certain size. So for your module do (C++11 assumed) it should look like: // Module defintion SC_MODULE (mux) { //inputs sc_in<bool> clk{"clk"}; sc_in<bool> reset{"reset"}; sc_in<bool> enable{"enable"}; sc_in<sc_uint<8> > in{"in"}; //output ports sc_vector<sc_out<sc_uint<8> > > out{"out", 8}; and sc_main should look like
  3. If you setup SC_THREADs the SystemC kernel invokes them and you do not have any control in which order SC_METHODS and SC_THREADS get invoked/resumed. SystemC gives no guarantee about the order of within a delta cycle. So the 2nd or 3rd stage of your pipeline could be executed before or after the 1st stage. If you use POD (C++ types and classes) they immediately change their value when being written. If you now have a variable V between the 1st and the 2nd stage it depends on the order of invocation if the 2nd stage reads the value in the same delta-cycle (1st stage is invoked before 2nd stage)
  4. You would do it like this: int sc_main(int argc, char* argv[]) { // Ports sc_signal <bool> reset; sc_signal <bool> clock; sc_signal<sc_uint<8> > input; sc_vector<sc_signal<sc_uint<8>>> output; //instance and port binding mux bind("mux"); bind.reset(reset); bind.clk(clock); bind.in(input); bind.out(output); // Open VCD file sc_trace_file *wf = sc_create_vcd_trace_file("mux"); ... ... But you cannot call sc_start before opening the VCD database. sc_start initializes the VCD output so yo
  5. You can access elements using array index operator like this: in2[0][1]=42.0; But you write you want to put values onto the array. You cannot write onto ports as these are only proxys and do not hold values. You need to create a similar sc_signal array and connect it to the ports. sc_signals hold values so you can put values on them using write(). A side node: you should declare your vectors as: sc_vector<sc_vector<sc_in<float>>> in2{"in2", 4, [](char const* name, size_t idx) -> sc_vector<sc_in<float>>*{ return new sc_vector<sc_in<
  6. When implementing some simulation control I usually have the logic as part of a SC_THREAD. Once the thread is active it is save to access all the other data structures as -like @David Black mentioned- SystemC is cooperative multi tasking. Based on the GUI thread you can then decide to run for a certain time, until a certain event, or stop simulation entirely using sc_stop()
  7. Your problem is the use of POD (plain old datatype) for communication between the processes. Why? As soon as you write onto it all other processes see the update. So the behavior of your design depends on the scheduling of the processes. If Design::process is scheduled before Design::second_stage_process the second_stage_process sees the updates of process. Actually there are 2 ways out: you just have one thread and call the function from the output to the input: void Design::process() { txProcess(); intermediateProcess(); rxProcess(); } Although it will work in you
  8. Esp. as educational project you should implement it in 2 threads which communicate with each other. Since they run in the same process space you can access data safely once the simulation is in paused state. But you cannot restart the simulation without restarting the process it self. SystemC uses static global variables storing the simulation state and those get only initialized at program start.
  9. Actually there is a default time unit in sc_time.h: // ---------------------------------------------------------------------------- // STRUCT : sc_time_params // // Struct that holds the time resolution and default time unit. // ---------------------------------------------------------------------------- struct SC_API sc_time_params { double time_resolution; // in femto seconds bool time_resolution_specified; bool time_resolution_fixed; sc_time::value_type default_time_unit; // in time resolution bool default_time_unit_specified; sc_time_pa
  10. Basically there are other ways if you have a process handle. But for this you need to get a emthod handle. To do this you have 2 options: You don't use SC_METHOD rather use sc_spawn directly (my _handle is a the part of you rmodule: sc_core::sc_spawn_options opt; opt.dont_initialize(); opt.spawn_method(); my_handle = sc_core::sc_spawn(func, name, &opt); this->sensitive << my_handle; this->sensitive_pos << my_handle; (if you don't use satic sensitivity you can skipe the last 2 liens). Using the handle you can change the sensitivity: reinterp
  11. sc_clock triggers itself based on the period and the (in your case default) constructor settings. The period is the default_time_unit.
  12. There is no guarantee which method or thread is activated first There is no means to give priority. Why would you like to do this? In my experience you have a thought problem if you believe you need to do this. thread activation is more expensive (in terms of computing power) than method as the thread context needs to be restored and saved. But threads keep an internal state so they are good to describe state machines.
  13. Each thread will invoked once since they are sensitive to clock. If you use here plain C++ types you will run into issues as you mentioned since it is not specified in which order the threads are activated. Therefor you need to use a signal to cummunicate between the threads: if you write to a signal you will still read the old value until the update phase is executed. This is followed by the next eavaluate phase in the next delta cycle or timestep. This way it doesn't matter in which order the threads are invoked. You should (re-)read some books or check with some online tutorials about
  14. You declare your modules as local variables in the constructor. Leaving the constructor they are destroyed. Something like this should work: SC_MODULE(dispenser){ sc_in<bool> input1; sc_in<bool>input2; sc_out<bool>out1; sc_signal<bool> s1; module1 m1; module2 m2; SC_CTOR(dispenser): input1("input1"), input2("input2"), out1("out1"), s1("s1"), m1("module1"), m2("module2") { m1.in1(input1); m1.in2(input2) m1.outA(s1); m2.input1(input1); m2.input2(s1); m2.out(out1); } }; I highly advice to name al
  15. You create 5 signals carrying a TraceVector. Doing so the default constructor is used which does reserve space for elements but has a size of 0... I can't tell where the assertion comes from. For those cases a debugger is pretty helpfull B-)
  16. As I wrote, I do not know Xcelium. But I would check the error in bpad_10634.err...
  17. First: you forgot the indicees into the arrays in your constructor and method. Second: the constructor of adder will not work. 'a' as well as the other ports are plain arrays of e.g. sc_in<sc_uint<4> > which does not have any constructor (and does not call any constructor of the elements). You may use as std::vector but this does not really solve the issue as std::vector just calls the default constructor of the element. You should use sc_core::sc_vector which allows named initialization as well as hierarchical binding: SC_MODULE(adder) { sc_core::sc_vectory<sc_in<
  18. Yes, it can be compiled against SystemC 2.3.3. There are even packages for Conan (conan.io) available at bintray (https://bintray.com/minres/conan-repo) where SCV is built against SystemC 2.3.3 RB
  19. How did you build and isntall SystemC? If you use cmake the file is being copied....
  20. But even in this case you register the thread only in the (inheritance) leave module. You could do: dummy_master(sc_module_name name) : ahb_master(name) { cout<<"Executing new"<<endl; SC_THREAD(ahb_master::tick); sensitive << bus_grant.pos(); } for the default behavior.
  21. You are defining a thread in ahb_master and a thread in dummy_master where both have the same name (tick) but a different C++ signature (ahb_master::tick and dummy_master::tick). Actually defining the tick thread in ahb_master doesnt make any sense, moreover since it doesn't do anything it will be declared immediately after simulation start. BR
  22. Your memory management is wrong. At first you pull 1 tx from the memory manager and reuse it all the time. This means you are changing your transaction in the request phase while it is in the response phase of the previous access. So you need to use mm.alloc() for each off the accesses. The purpose of the memory manager is to take care when to release/re-use the transaction. And here your second issue comes: you should always call acquire()/release() in a balanced way but your lut only calls release(). What happens then is that the transaction is pushed into the pls deque in the memory manage
  23. Why would you want to change the address after sending it? Actually only interconnect components are allowed to change the address of an transaction (this is what the standard says). I would alwys keep in mind how this is handled in haerdware.... One option to address this is to add an extension to your transaction holding the original adress and other information you need. But this comes at the cost of interoperability (if this is a criteria for you). BR
  24. Since you are talking about timing I would stick to a more AT like modeling style using the non-blocking transport functions. In this case you should use a memory manager (see section 14.5 of the IEEE standard). For this you need to implement the tlm::tlm_mm_interface (there a few implementations out there, you may google them). The mechanism works similar to a C++ shared pointer. The initiator always pulls a new transaction from the memeory manager and sends via its socket. Each component dealing with the transaction calls acquire() on the payload and release() once it is finished with it. Up
  25. Well, the timer_tb gets a SC_THREAD which has exactly your sequence of writing to START and advancing time. The only difference is to use wait() instead of sc_start()...
×
×
  • Create New...