Jump to content

All Activity

This stream auto-updates

  1. Today
  2. Yesterday
  3. Hi David Black, Thankyou for your response, I have good knowledge on basic UVM RAL and my requirement is about RAL implementation especially "accessing register from more than one master". From your response i got to know that is being covered as part of Doulos UVM Adopter course. Can you please share the course and Price details , i tried sending a enquiry form to doulous from link " https://www2.doulos.com/forms/enquiry " but it didn't work for some reason.
  4. Last week
  5. #include <systemc.h> #include <pthread.h> #include <unistd.h> using namespace std; class ThreadSafeEventIf : public sc_interface { virtual void notify(sc_time delay = SC_ZERO_TIME) = 0; virtual const sc_event &default_event(void) const = 0; protected: virtual void update(void) = 0; }; class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf { public: ThreadSafeEvent(const char *name = ""): event(name) {} void notify(sc_time delay = SC_ZERO_TIME) { this->delay = delay; async_request_update(); } const sc_event &default_event(void) const { return event; } protected: virtual void update(void) { event.notify(delay); } sc_event event; sc_time delay; }; sc_event GenScEvent; sc_event workingFinishEvent; // finish event int workingFlag = 0; // maybe dnot need a lock SC_MODULE(Foo) { public: SC_CTOR(Foo) { SC_THREAD(main); SC_METHOD(eventTriggered); sensitive << threadSafeEvent; dont_initialize(); } private: void main() { //extra forever thread to avoid simulation exit while (1) { usleep(1*1000*1000); // check if there is any instruction every one sec. wait(SC_ZERO_TIME); if(workingFlag){ // check working wait(workingFinishEvent); // wait the working finish } usleep(1*1000*1000); } } void eventTriggered() { // printf("Foo: Got event from pthread \n"); GenScEvent.notify(); } public: ThreadSafeEvent threadSafeEvent; }; void* PollingThread(void* arg) { int cnt = 0; while (1) { cnt++; printf("[POLL]: %d: Before generating event from PollingThread \n", cnt); usleep(3*1000*1000); Foo *foo = (Foo*)(arg); foo->threadSafeEvent.notify(); printf("[POLL]: %d: Event notified from PollingThread \n", cnt); } }; class sc_top : public sc_module { private: SC_HAS_PROCESS(sc_top); public: sc_top(sc_module_name name="SCTOP"): sc_module(name) { SC_THREAD(processing_thread); } void processing_thread(); }; void sc_top::processing_thread() { int cnt =0; while (1) { printf("[PROC]: processing_thread called \n"); cout << "[PROC]: Wait GenScEvent time: " << sc_time_stamp(); wait(GenScEvent); workingFlag = 1; cnt++; wait(10, SC_SEC); // advance simulation time cout << "[PROC]: Got and Finish "<<cnt << " GenScEvent time: " << sc_time_stamp(); workingFinishEvent.notify(); workingFlag = 0; } } int sc_main(int argc, char *argv[]) { Foo foo("foo"); sc_top u_sc_top("u_sc_top"); pthread_t thread; pthread_create(&thread, NULL, PollingThread, &foo); sc_start(); return 0; } this example is a better one. it won't destory simulation time.
  6. My use-case is in `SC_METHOD` or `SC_(C)THREAD` if exception caught I can see the ori stack trace with c++ not rethrow or caught by `sc_report`. The stack trace isn't my exception. I don't want to use `catch throw` to get stack trace which I really need.
  7. hi yaohe, I understand your question and I met same problem too. We want the simulation keep alive and wait asyn events, but the extra SC_THREAD "main"(as you said) destroy simulation time. Do you solve this problem now? Or I hope the example blew can solve it: #include <systemc.h> #include <pthread.h> #include <unistd.h> using namespace std; class ThreadSafeEventIf : public sc_interface { virtual void notify(sc_time delay = SC_ZERO_TIME) = 0; virtual const sc_event &default_event(void) const = 0; protected: virtual void update(void) = 0; }; class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf { public: ThreadSafeEvent(const char *name = ""): event(name) {} void notify(sc_time delay = SC_ZERO_TIME) { this->delay = delay; async_request_update(); } const sc_event &default_event(void) const { return event; } protected: virtual void update(void) { event.notify(delay); } sc_event event; sc_time delay; }; sc_event GenScEvent; sc_event workingFinishEvent; // finish event int workingFlag = 0; // maybe dnot need a lock SC_MODULE(Foo) { public: SC_CTOR(Foo) { SC_THREAD(main); SC_METHOD(eventTriggered); sensitive << threadSafeEvent; dont_initialize(); } private: void main() { //extra forever thread to avoid simulation exit while (1) { usleep(1*1000*1000); // check if there is any instruction every one sec. wait(SC_ZERO_TIME); if(workingFlag){ // check working wait(workingFinishEvent); // wait the working finish } usleep(1*1000*1000); } } void eventTriggered() { // printf("Foo: Got event from pthread \n"); GenScEvent.notify(); } public: ThreadSafeEvent threadSafeEvent; }; void* PollingThread(void* arg) { int cnt = 0; while (1) { cnt++; printf("[POLL]: %d: Before generating event from PollingThread \n", cnt); usleep(3*1000*1000); Foo *foo = (Foo*)(arg); foo->threadSafeEvent.notify(); printf("[POLL]: %d: Event notified from PollingThread \n", cnt); } }; class sc_top : public sc_module { private: SC_HAS_PROCESS(sc_top); public: sc_top(sc_module_name name="SCTOP"): sc_module(name) { SC_THREAD(processing_thread); } void processing_thread(); }; void sc_top::processing_thread() { int cnt =0; while (1) { printf("[PROC]: processing_thread called \n"); cout << "[PROC]: Wait GenScEvent time: " << sc_time_stamp(); wait(GenScEvent); workingFlag = 1; cnt++; wait(10, SC_SEC); // advance simulation time cout << "[PROC]: Got and Finish "<<cnt << " GenScEvent time: " << sc_time_stamp(); workingFinishEvent.notify(); workingFlag = 0; } } int sc_main(int argc, char *argv[]) { Foo foo("foo"); sc_top u_sc_top("u_sc_top"); pthread_t thread; pthread_create(&thread, NULL, PollingThread, &foo); sc_start(); return 0; }
  8. Hi BR, I noticed that the two paths at minres are 404 errored now. Is the github path the replicate of that? https://github.com/vherdt/riscv-vp/tree/master Best Regards, User 128
  9. The difference between sc_buffer and sc_signal is that sc_buffer<T>::write issues an event on every write; whereas, sc_signal<T>::write only issues an event if the value changes (e.g., from 0 to 1 or 1 to 0). I would have to see all your code (preferably on EDA playground) to understand the issue.
  10. Earlier
  11. Something like the following might be a clue... uvm_reg regs[$]; regmodel.get_registers(regs); foreach( regs[i] ) begin `uvm_report_info("Register",regs[i].get_name()) end
  12. Hello @Allen yang, It is possible to get a stack trace, but then again what is your use-case? Regards, Ameya Vikram Singh
  13. Hi @AmeyaVS, When I try `vector::at` in `SC_METHOD` or `SC_(C)THREAD`, the stack can't be show. I try to rewrite `sc_except.cpp::sc_handle_exception`, it didn't work. Can you help me figure out this? Regards, Allen
  14. You could setup the masters to access through a common agent and use the lock/unlock methods in the sequence. This something I teach in Doulos UVM Adopter course.
  15. SystemC is not designed to allow more than one sc_main to run. If you want more than one kernel to run, you will need to launch a separate OS process and use IPC. You will probably also need to learn how to use the new sc_suspend_all method and its cousins from section 4.6.3 in IEEE-1666-2023. This also requires you to use SystemC 3.0 (released just over a week ago on March 29th, 2024) and C++17. async_request_update can then be used to resume. Please note this is an advanced topic and requires have a solid grasp of SystemC simulation semantics including the subtle differences between SystemC processes (SC_THREAD and SC_METHOD) and OS processes vs OS threads. [Hint: SystemC is mostly not OS thread-safe; hence, the need for async_request_update and the suspend mcchanisms.]. You will also need a strong understanding of software concurrency including thread_local variables, std::mutex, std::lock_guard, and std::atomic. In other words, you need to be a proficient Modern C++ programmer. Hacking, googling, and even AI won't do the job.
  16. Hello @Allen yang, You could try removing the catch all block itself, so that the exceptions is thrown from the sc_main method. Regards, Ameya Vikram Singh
  17. Hi @AmeyaVS, Thank you for your help. Do you mean that I should rewrite `sc_main_main.cpp` by myself fixing `catch(...) ...` code ? Can I just use code below? catch( ... ) { // don't translate other escaping exceptions }
  18. Hi Philipp, I met this problem two days ago. I use `catch throw` and find code bug. And I want to kown how to add catch blocks to sc_main and my our SystemC process?
  19. Hello @Allen yang, It is because sc_main is called within a context of a try catch block. See this: https://github.com/accellera-official/systemc/blob/bec101067d808f93bf215031dff6fa9ab7035995/src/sysc/kernel/sc_main_main.cpp#L66-L108\ Captured the snippet from the implementation and reproduced below. try { pln(); // Perform initialization here sc_in_action = true; // copy array of pointers to keep allocated pointers for later release std::vector<char*> argv_call = argv_copy; status = sc_main( argc, &argv_call[0] ); // Perform cleanup here sc_in_action = false; } catch( const sc_report& x ) { sc_report_handler::get_handler() ( x, sc_report_handler::get_catch_actions() ); } catch( ... ) { // translate other escaping exceptions sc_report* err_p = sc_handle_exception(); if( err_p ) sc_report_handler::get_handler() ( *err_p, sc_report_handler::get_catch_actions() ); delete err_p; } You can see there is a broader catch( ... ) statement which is causing the exception to be handled instead of being thrown. You can possibly try writing you own main function but will need to take care of additional SystemC kernel initialization sequences. Hope this helps. Regards, Ameya Vikram Singh
  20. Nowadays, I use at function to access vector and it out of range. However, it didn't pause and the program shutdown only. #include <systemc> int sc_main(int args, char* argv[]) { std::vector<int> vec = {1, 2, 3}; int num1 = vec.at(1); int num2 = vec.at(10); return 0; } Here's the result: root@xxx:/home# SystemC 2.3.3-Accellera --- Jan 25 2024 15:41:45 Copyright (c) 1996-2018 by all Contributors, ALL RIGHTS RESERVED Error: (E549) uncaught exception: vector::_M_range_check: __n (which is 10) >= this->size() (which is 3) In file: ../../../src/sysc/kernel/sc_except.cpp:101 root@xxx:/home# I expected it will be like below, and the program will be crash and output coredump file. terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 10) >= this->size() (which is 3)
  21. Hi, Suppose I knew the part of register name or any field of the register Is there any way to get or read the name of the register using any of the RAL Methods?
  22. I want to control the SystemC model through an external program to complete the required instructions. I tried many methods, but failed. After reading the following posts : It realy helps a lot . I have solved my problem, and i want to share it. here is the example that "main thread controlling sub_thread(systemc module) to complete instructions": #include <systemc.h> #include <pthread.h> #include <unistd.h> using namespace std; class ThreadSafeEventIf : public sc_interface { virtual void notify(sc_time delay = SC_ZERO_TIME) =0; virtual const sc_event &default_event(void) const =0; protected: virtual void update(void) = 0; }; class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf { public: ThreadSafeEvent(const char *name = ""): event(name) {} void notify(sc_time delay = SC_ZERO_TIME) { this->delay = delay; async_request_update(); } const sc_event &default_event(void) const { return event; } protected: virtual void update(void) { event.notify(delay); } sc_event event; sc_time delay; }; sc_event ConvTriggerEvent; sc_event StopEvent; SC_MODULE(Foo) { public: SC_CTOR(Foo) { SC_THREAD(main); SC_METHOD(eventTriggered); sensitive << threadSafeEvent; dont_initialize(); SC_METHOD(stopEventTriggered); sensitive << threadStopEvent; dont_initialize(); } private: void main() { //extra forever thread to avoid sistemc eixt while (1) { wait(100, SC_NS); } } void eventTriggered() { printf("Foo: Got event from pthread \n"); ConvTriggerEvent.notify(); } void stopEventTriggered(){ printf("Foo: want to stop sc module \n"); StopEvent.notify(); } public: ThreadSafeEvent threadSafeEvent; ThreadSafeEvent threadStopEvent; } void* AIThread(void* arg) { sc_start(); // The systemc runs continuously, waiting external instruction return NULL; } class AI_Process : sc_module{ public: SC_HAS_PROCESS(AI_Process); AI_Process(sc_module_name name){ SC_THREAD(RunAIChip); SC_THREAD(StopAIChip); } int cnt = 0; void RunAIChip(){ while(true){ printf("[ai chip info]: Wait instruction ... \n"); wait(ConvTriggerEvent); cnt ++; printf("[ai chip info]: %d Conv Process ... \n",cnt); } } void StopAIChip(){ wait(StopEvent); sc_stop(); } }; int sc_main(int argc, char *argv[]) { Foo foo("foo"); AI_Process ai("ai_process"); pthread_t thread; pthread_create(&thread, NULL, AIThread, NULL); int cnt = 0; while (cnt < 2) { cnt++; usleep(3*1000*1000); foo.threadSafeEvent.notify(); } printf("==========================================") while (cnt < 4) { cnt++; usleep(3*1000*1000); foo.threadSafeEvent.notify(); // call systemc at any time you want } printf("==========================================") while (cnt < 6) { cnt++; usleep(3*1000*1000); foo.threadSafeEvent.notify(); } printf("==========================================") usleep(5*1000*1000); foo.threadStopEvent.notify(); pthread_join(thread, NULL); printf("==========================================") return 0; } the result : [ai chip info]: Wait instruction ... Foo: Got event from pthread [ai chip info]: 1 Conv Process ... [ai chip info]: Wait instruction ... ================================================= Foo: Got event from pthread [ai chip info]: 2 Conv Process ... [ai chip info]: Wait instruction ... Foo: Got event from pthread [ai chip info]: 3 Conv Process ... [ai chip info]: Wait instruction ... ================================================= Foo: Got event from pthread [ai chip info]: 4 Conv Process ... [ai chip info]: Wait instruction ... Foo: Got event from pthread [ai chip info]: 5 Conv Process ... [ai chip info]: Wait instruction ... ================================================= Foo: Got event from pthread [ai chip info]: 6 Conv Process ... [ai chip info]: Wait instruction ... Foo: want to stop sc module Info: /OSCI/SystemC: Simulation stopped by user. =================================================
  23. maybe the solution above is not good. I find better solution here : thanks .
  24. hi, thank you for your solution. Here is my c++ program to call an systemc module according to your solution: class DoFFT: public sc_module { public: SC_HAS_PROCESS(DoFFT); DoFFT(sc_module_name name){ SC_THREAD(dofft); }; void dofft(){ cout << " # calculate fft !"<< endl; }; }; int sc_main(int argc, char* argv[]) { DoFFT dofft("do"); sc_start(1, SC_SEC); cout << " sc_main finish !" << endl; return 0; } int main(){ sc_main(0, NULL); cout << " here is main fun !" << endl; sc_main(0, NULL); return 0; } It works when i only add one "sc_main()" in main function. But there is error when i add more than one, as shown in above mian function. what if i want to call this systemc module multi times ?
  25. Hi All, Requirement : UVM RAL implementation: 2 Masters are trying access same register of single register Block/ uvm_register Map. Hi All, I have similar requirement where we have 2(two) master agents are trying to access/program the same register in single Register Block. 1) Master_1 --> Write's 'h444 to Reg_0 present in Regblock_A 2) Master_2 --> Reads Reg_0 should get the Read data 'h444 (which is our earlier write). Can you please share your inputs on how to implement this in my ENV? Any reference docs, links are appreciated.
  26. I found an issue with byte_en signal. My RAL model is defined as following: test_reg[31:0]: fld0[1:0], fld1[9:2] ”test_reg” is 32bits. The “fld0” at bit[1:0], “fld1” at bit[9:2], other bits are reserved. I am using a AHB bus monitor connecting to my RAL model through uvm_reg_predictor. Using my AHB master driver (not using register model), I did following sequence: 1. Write all 1’s to the register. 2. Write all 0’s to the register but with byte_en set to 4’b0001. 3. Then I read the register, expecting DUT and RAL to give 32’h30. But I get a compare error from RAL. This is unexpected. In step 1, my register value is 32’h3f. Then, in step 2, because I am only updating a byte, I am expecting the register value to be 32’h30 in test_reg. In step 3, the compare_on_read show that the register value in RAL is actually 32’h0 instead of 32’h30. Obviously, byte_en is not honored in UVM prediction code. Upon further investigation, I found following code in uvm_reg_field that contributed to the error: “ // do_predict function void uvm_reg_field::do_precit(rvm_reg_item rw, …………….., uvm_reg_byte_en_t be = -1); … if(rw.path == UVM_FRONTDOOR || rw.path == UVM_PREDICT) field_val = XpredictX(m_mirrored, field_val, rw.map); ” Here field_val is not considering “be”. For field_val to updated correctly, we need to take “be” into consideration. Otherwise for the case, current code will update the whole field and give an incorrect expect value of 32’h0. Here is the proposed fix for this issue. “ // do_predict function void uvm_reg_field::do_precit(rvm_reg_item rw, …………….., uvm_reg_byte_en_t be = -1); … // Add following lines to fix the problem. for(int I=0; i<$size(m_mirrored); i++) begin Int orrigin_idx = i+get_lsb_pos(); // origin_idx is the location of the bit in the register, before shifting the field. If(!be[origin_idx/8]) // this will look at the corresponding byte enable bit. Field_val[i] = m_mirrored[i]; // if the bit is not enabled, we will not update it. end if(rw.path == UVM_FRONTDOOR || rw.path == UVM_PREDICT) field_val = XpredictX(m_mirrored, field_val, rw.map); ” Similar issue also exists in uvm_reg_predictor. After applying the fix, we are getting correct value on partial field updates.
  27. Hi Kushi, The idea of 1685-2014 is to support this with the isPresent element. This functionality has been removed in 1685-2022 but it can be supported with the Accellera Vendor Extensions for 1685-2022. Please see https://accellera.org/images/downloads/standards/ip-xact/1685-2022-VE-1.0-Specification.zip My own opinion is that this RTL code describes 2 different IPs (one with ABC defined and one with ABC undefined) and that you should create two different IP-XACT components to describe those two different RTL IPs. This is an example of a configurable IP that can be used to create two configured IPs. The configured IPs are supported by the IP-XACT component schema. The configurable IP must be handled with a generator (e.g. using TGI). The generator takes the value of ABC as input and generates the IP-XACT component for the configured IP. Best regards, Erwin
  28. Hello Is it possible in ipxact to describe ports which are enclosed in ifdef macro. For example module m( input [31:0] addr, output [31:0] data, `ifdef ABC in abc_in, out abc_out, `endif ); endmodule If yes, how to describe such ports in ipxact. If not, then what is the recommended way to model such RTL IP Thank you
  1. Load more activity
×
×
  • Create New...