Jump to content

Roman Popov

Members
  • Posts

    353
  • Joined

  • Last visited

  • Days Won

    47

Everything posted by Roman Popov

  1. Do you mean you've reached a maximum possible fibers limit? According to MS documentation: https://msdn.microsoft.com/en-us/library/ms682402%28VS.85%29.aspx So you have two options: Increase virtual memory. If you are compiling for 32bit , try switching into 64 bit. Decrease stack size. Try to decrease stack size using set_stack_size method (Check SystemC LRM for documentation). I agree. Unfortunately there is no SystemC bugtracker to track such requests. So our best hope is that someone from SystemC committee will read this thread and add error checking to CreateFiber call.
  2. Unlike method processes, thread processes are triggered only once. With one exception of this rule: if you define reset signal for process (using reset_signal_is or async_reset_signal_is ), it will be restarted (triggered) on reset condition.
  3. I think majority of SystemC users work on Linux, because most of commercial simulators (VCS, Incisive) have no Windows versions. So Linux version is required. But, to be honest, I don't see much value in dedicated SystemC IDE. Existing C++ IDEs, like Visual Studio (with Resharper C++ plugin) already work very well with SystemC. So instead I would prefer a SystemC-aware plugin for Visual Studio, with some static checks capabilities, like detecting unbind ports, infinite loops without wait(), etc.
  4. This is my plan. My plan is opposite: if this sort of syntax will be helpful for users, commercial vendors will probably support it in existing systemc synthesis tools. Speaking about SystemC "language" complexity: this is indeed the case with current SystemC. Because of that most HW designers prefer Verilog/SystemVerilog. But features I've presented are about reducing SystemC syntax complexity, not about further complication. So code will be more compact, less verbose and error-prone. Personally I find one good thing about HW design in SystemC: If I will lose my job in semiconductor industry, I can find another one as C++ programmer Something I couldn't do if I were a SystemVerilog programmer.
  5. If we combine expression templates and in-place initialization, enhanced C++11 syntax can look something like that: SC_MODULE(demo_mod) { sc_in<int> a_in{"a_in"}; // second optional parameter is assignment expression sc_out<sc_int<8>> b_out{"b_out", a_in + c_sig}; // constant zero output sc_out<int> zero_out{"zero_out", 0}; sc_signal<sc_uint<4>> c_sig{"c_sig"}; // some bus port amba::apb_slave apb_in{"apb_in"}; // sencond optional paramteter to sc_module_name is binding function some_module inst_name {{"inst_name", [&]() { inst_name.in0(a_in); inst_name.apb_in(apb_in); // bus binding inst_name.in1(10); // bind to constant inst_name.out0(); // unconnected by design }}}; sc_signal<sc_uint<8>> d_sig{"d_sig"}; SC_CTOR(demo_mod) { // assignment d_sig.assign( (c_sig , c_sig) - 10 ); SC_THREAD(test_thread); } sc_signal<sc_uint<8>> e_sig{"e_sig"}; void test_thread() { int var = 12; // wait for expression wait( c_sig[0] && (a_in == 12) ); // evaluates expression e_sig = a_in + b_out.range(3,0) + d_sig + 12; sc_stop(); } };
  6. No, it's not possible to create or connect ports after elaboration.
  7. Your code compiles without errors.
  8. I don't see where T operator&() is overloaded in sc_signal (In SystemC 2.3.1 that I use). operator const T& () const overloads cast to T. So you can still get a reference to sc_signal.
  9. You can do this with pointer to port or using sc_vector; for example: SC_MODULE (test_mod) { sc_in<unsigned> *data_port; ... SC_CTOR(test_mod) { if (create_data_port) data_port = new sc_in<unsigned> ("port_name"); } }
  10. Where is Driver.h ? I don't see a place where you create SC_THREAD(proc_driver)
  11. Hello kihtrak, In your source code you don't assign any value to bin. Please provide a minimal simulation source code to reproduce your problem. Otherwise nobody can help you.
  12. I don't see where you assign 1 to bin , show all related code.
  13. One more powerful feature of Verilog are implicit signals and methods. Consider following example: logic clk; logic [7:0] addr; logic write_en; logic slave0_irq; logic slave1_irq; master master0 ( .clk(clk), .addr(addr), .write_en(write_en), .interrupt_vec( {slave1_irq, slave0_irq} ) ); slave slave0 ( .clk(clk), .addr(addr[6:0]), .write_en(write_en && addr[7] == 0 ), .interrupt(slave0_irq) ); slave slave1 ( .clk(clk), .addr(addr[6:0]), .write_en(write_en && addr[7] == 1 ), .interrupt(slave1_irq) ); In Verilog I can bind port to signal sub-range without explicitly defining additional signal and creating a method to extract sub-range: Verilog: .addr(addr[6:0]), SystemC: sc_signal<sc_bv<7> > subaddr{"subsignal"}; ... void extract_subrange_method() { subaddr = addr.read().range(6,0); } ... SC_METHOD(extract_subrange_method); sensitive << addr; ... slave0.addr(subaddr); About 7 LOC in SystemC vs 1 LOC in Verilog. Verilog allows to merge multiple signals into one: .interrupt_vec( {slave1_irq, slave0_irq} ) Or even more complex expressions : .write_en(write_en && addr[7] == 1 ), So if I rewrite whole module from Verilog to SystemC I will get about 150-200 LOC vs 35 LOC in original Verilog file. SystemC desperately needs similar syntax if it wants to grow as HDL. Mixing Verilog and SystemC is not an option: in general I have HLS-style and RTL-style code in same module. So we either need an HLS for Verilog, or facelift for SystemC. It feels like it is possible to implement such type of binding at library level, without creating additional "SystemC preporcessor". Because we bind sc_ports to sc_signals (not to primitive types (char, int)) it is possible to improve those classes to support this type of syntax. For example we can apply expression templates over sc_signals: https://en.wikipedia.org/wiki/Expression_templates So expression like this: write_en && addr[7] == 1 over sc_signals will return some class sc_expression that will contain both: recursive function to compute expression list of sc_signals that will go into sensitivity list Next, during port binding create anonymous sc_signal with the same type as port. And spawn a method that will assign this signal a value computed by expression template.
  14. http://stackoverflow.com/questions/31204335/multiple-inheritance-different-address-same-address
  15. Here is an example of using sc_vector to create array of modules and loop to bind ports. Suppose you want to delay some signal by N clocks. So you want to connect N D-flipflops in chain (like in shift register). And suppose you want to have N as a paramter. Here is that ""delay_line"" implementation using DFFs : #include "systemc.h" SC_MODULE(dff) { sc_in<bool> clk{"clk"}; sc_in<bool> d{"d"}; sc_out<bool> q{"q"}; SC_CTOR(dff) { SC_METHOD(update_method); sensitive << clk.pos(); } void update_method () { q = d; } }; template <int N> SC_MODULE(delay_line) { sc_in<bool> clk{"clk"}; sc_in<bool> d{"d"}; sc_out<bool> q{"q"}; sc_vector< dff > dff_vec{"dff_vec", N}; sc_vector< sc_signal<bool> > dq_vec{"dq_vec", N - 1 }; SC_CTOR(delay_line) { // bind input of dff chain dff_vec[0].d(d); // bind output of dff chain dff_vec[N-1].q(q); // bind clock signals for each dff for (int i = 0; i < N; ++i) { dff_vec[i].clk(clk); } // bind internal dff to dff data signals for (int i = 0; i < N - 1; ++i) { dff_vec[i].q(dq_vec[i]); dff_vec[i+1].d(dq_vec[i]); } } }; template <int N> SC_MODULE(test) { sc_clock clk{"clk", 1, SC_NS}; sc_signal<bool> d{"d"}; sc_signal<bool> q{"q"}; delay_line<N> delay_line_inst {"delay_line_inst"}; SC_CTOR(test) { delay_line_inst.clk(clk); delay_line_inst.q(q); delay_line_inst.d(d); SC_THREAD(test_thread); sensitive << clk.posedge_event(); } void test_thread() { d = 1; int i = 0; do { wait(); cout << "delay line out[" << i++ << " ]: " << q.read() << endl; } while (!q.read()); } }; int sc_main(int, char **) { test<5> delay_line_test{"delay_line_test"}; sc_start(); return 0; } You can run this example in Visual Studio 2013 or with GCC 4.8 or later with -std=c++11 flag Please note that it is a low-level style of modeling. You should avoid doing such a low-level stuff, unless you have no other options.
  16. use sc_vector. Yes, you can bind vector of ports to vector of signals using loop.
  17. We are facing this too. Hope to see VS2015 support soon. There are issues with modern C++ support in VS2013.
  18. Some syntax to create methods/threads out of constructor body would be helpful too. For example by creating classes sc_thread and sc_method. imagine something like SC_MODULE (foo) { SC_CTOR(foo); // sc_method ( sensitivity_list , process_handle ) sc_method sum_method ( {a,b,c} , [&]() { sum = a + b + c; } }; void diff_method_body(); sc_method diff_method ( {x,y} , diff_method_body ); }; void foo::diff_method_body() { diff = x - y; }
  19. Check following member functions described in IEEE1666-2011 5.12.8 Member functions for bound ports and port-to-port binding 5.12.8.1 size 5.12.8.2 operator-> 5.12.8.3 operator[] Looks like everything should be bound before end_of_elaboration callback You can also look into reference SystemC implementation source code to get the details.
  20. I've noticed that SystemC uses different thread libraries depending on OS: quickthreads on linux and fibers on Windows. Which one is faster? Did someone benchmarked wait-heavy SystemC simulations on Windows and Linux?
  21. I've checked on Windows now, yes it's segfaults when tries to dereference pointer to sig during deferred biding. Unfortunately there is no mechanism in C++ to check if pointer is valid, so SystemC kernel can't save us from this type of mistakes.
  22. yes, my mistake. I've looked into wrong dump. VCS created two: wave.vcd produced by sc_trace has 2 us of waveform. And vpd dump created by VCS itself has 3 us. I'm not aware of VCD file format, but probably it makes sense to update VCD when simulation ends? In that case you will see what you expect: if you run simulation for 3 us you will have waveform of 3 us. Even if nothing has changed during last us..
  23. It seems like it makes sense to merge sc_*int and sc_big*int types. Wide buses are all around in modern systems. For example 64 bytes is common size of cache line. I do not see a good reason to keep two types for representing types with user-defined size. For example in Verilog I have single common type for all cases: bit [31:0] address; bit [511:0] data; But in SystemC I will have to use different types: sc_uint<32> address; sc_biguint<512> data; Specializing sc_uint depending on size will not break compatibility with existing Systemc 2.3 code . constexpr bool is_biguint(unsigned x) { return x > 64; } template<int n, bool isbig = is_biguint(n)> struct sc_uint {}; template<int n> struct sc_uint <n, true>: public sc_unsigned { }; template<int n> struct sc_uint <n, false>: public sc_uint_base { };
  24. One more thing to consider is positional port binding using initializer list. While I never use this feature, I think it can be implemented in some better way. Looks like there is a limitation of maximum 64 ports with current sc_module : void operator () ( const sc_bind_proxy& p001, const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL, const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL, const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL, ... const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL, const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL ); };
  25. Well, in my case your simulation does not produces segfault. But obviously you have a problem your code: The problem is that you create your signal on call stack. Basically it is local to before_end_of_elaboration function. Once control returns from before_end_of_elaboration, signal sig is destroyed. So if you will try to read from port in1 you will have a segfault: void fun(){ in1.read(); } Solution is to make your signal a member of module: class test : public sc_module { public: sc_in<bool> in1; sc_signal<bool> sig; SC_HAS_PROCESS(test); test(sc_module_name name){ SC_THREAD(fun); } void fun(){ in1.read(); } void before_end_of_elaboration(){ in1.bind(sig); } };
×
×
  • Create New...