ECEN 468 Advanced Logic Design Lecture 6: SystemC Channels and Signals ECEN 468 Lecture 6 Communication Between Processes v Events v Tracing the event notification and catching can be complex v wait(request1 | request2) v Sometimes the source event is not clear v For the gas station example, the attendant is not clear which requests gas fill v Additional check is required to find the event source ECEN 468 Lecture 6 2 SystemC Channels v Simpler mechanisms for communications v base class sc_prim_channel v others o sc_mutex o sc_semaphore o sc_fifo<T> v Chapter 8, “SystemC: from the ground up” ECEN 468 Lecture 6 3 sc_mutex v mutex: mutually exclusive text v Program object that lets multiple threads share a common resource without colliding v A process cannot access a locked mutex sc_mutex NAME; NAME.lock(); // lock the mutex, blocking NAME.unlock(); int NAME.trylock(); // One may try to lock a mutex // that has been locked by another process // returns if lock success, non-blocking ECEN 468 Lecture 6 4 Examples of sc_mutex SC_MODULE(car){ sc_mutex drivers_seat; public: void drive(void); … }; void car::drive(void){ drivers_seat.lock(); … drivers_seat.unlock(); … } SC_MODULE(bus){ sc_mutex bus_access; … void write(int addr, int data) { bus_access.lock(); … bus.access.unlock(); } }; void grab_bus(){ if (bus_access.trylock()==0){ … // access bus bus_access.unlock(); } } ECEN 468 Lecture 6 5 sc_semaphore v Model shared resource that has multiple copies v Like parking lot spots v Specify the amount when creating semaphore sc_semaphore NAME; NAME.wait();//lock 1 semaphore, wait if not available // different from wait() for event NAME.post(); //Free one locked semaphore int NAME.trywait(); // non-blocking int NAME.get_value(); //Returns available semaphores ECEN 468 Lecture 6 6 Examples of sc_semaphore SC_MODULE(gas_station){ sc_semaphore pump(12); void customer1(){ … pump.wait(); } }; SC_MODULE(multiport_RAM){ sc_semaphore read_ports(3); sc_semaphore write_ports(2); … void read(int addr, int& data){ read_ports.wait(); … read_ports.post(); } void write(int addr, const int& data){ write_ports.wait(); … write_ports.post(); } }; ECEN 468 Lecture 6 7 sc_fifo<T> v Needs to specify data type v Default depth is 16 sc_fifo<TYPENAME> NAME(size); NAME.write(value); //Blocking, wait if full NAME.read(); // Blocking, wait if empty bool NAME.nb_read(T&); // Non-blocking int NAME.num_available(); //Num of available data int NAME.num_free(); // Num of free slots ECEN 468 Lecture 6 8 Examples of sc_fifo SC_MODULE(kahn_ex){ sc_fifo<double> a,b,y; … }; kahn_ex::kahn_ex():a(24),b(24),y(48){ //Constructor …} void kahn_ex::stim_thread(){ … a.write(double(rand()/1000)); … } void kahn_ex:addsub_thread(){… y.write(kA*a.read() + kB*b.read()); … } ECEN 468 Lecture 6 9 SystemC Signals v Chapter 9, “SystemC: from the Ground Up” ECEN 468 Lecture 6 10 An Example Reg1 Data D Q Reg2 Q1 D Q Reg3 Q2 D Q Reg4 Q3 D Q Q4 Clk Q4=Q3; Q3=Q2; Q2=Q1; Q1=Data; v The order of assignment at a specific simulated time is indefinite v An order can be enforced by notify() and wait(), but awkward v Or implement each register as a two-deep FIFO, which is clumsy ECEN 468 Lecture 6 11 Completed Simulation Engine SystemC Simulation Kernel sc_main() Elaborate sc_start() .notify() Initialize Evaluate .notify(SC_ZERO_TIME) Cleanup δ cycle Update ECEN 468 Lecture 6 Advance time .notify(t) 12 Signal Channels v Signal channels use the update phase as data synchronization v Every signal channel has two storage locations: the current value and the new value v When a process writes to a signal channel, stores into the new value v The new value is copied to the current during the update phase v If check immediately after writing, see the old value New Current s1=v2 s1 v0 s2=v3 s2 v1 Update() ECEN 468 Lecture 6 13 sc_signal<T> sc_signal<TYPENAME> signame; signame.write(value); signame.read(); // Returns current value, not new wait(signame.value_changed_event()); if(signame.event() == true) … //if occurred in the immediately previous δ-cycle event( ) can be employed to tell which signal triggered an event ECEN 468 Lecture 6 14 Example of sc_signal int cnt; string msg; sc_signal<int> cnt_sig; sc_signal<string> msg_sig; cnt=11 cnt_sig=0 msg:’Who’ msg_sig:‘’ cnt=20 cnt_sig=10 msg:’Who’ msg_sig:‘Hi’ cnt_sig.write(10); msg_sig.write(“Hi”); cnt = 11; msg = “Who”; cout << “cnt=” << cnt << “ cnt_sig=” << << “msg:” << msg << “ msg_sig:” << wait(SC_ZERO_TIME); cnt_sig.write(cnt); cnt = 20; cout << “cnt=” << cnt << “ cnt_sig=” << << “msg:” << msg << “ msg_sig:” << ECEN 468 Lecture 6 cnt_sig << endl msg_sig << endl; cnt_sig << endl msg_sig << endl; 15 Alternative Assignment to sc_signal sc_signal<TYPENAME> signame; signame.write(value); signame.read(); // Returns current value, not new signame = value; // implicit .write() dangerous variableA = signame; // implicit .read() mild danger v Only a single process may write to a given signal during a specific delta-cycle v This restriction avoids risk of race condition ECEN 468 Lecture 6 16 Resolved Signal Channels sc_signal_resolved signame; sc_signal_rv<WIDTH> signame; // For vectors v Allow multiple writers A\B ‘0’ ‘1’ ‘X’ ‘Z” ‘0’ ‘0’ ‘X’ ‘X’ ‘0’ ‘1’ ‘X’ ‘1’ ‘X’ ‘1’ ‘X’ ‘X’ ‘X’ ‘X’ ‘X’ ‘Z’ ‘0’ ‘1’ ‘X’ ‘Z’ ECEN 468 Lecture 6 17 Template Specialization v Some template specialization has additional behaviors not available for the general case v sc_signal<bool> and sc_signal<sc_logic> have functions posedge_event() and negedge_event(), which are not available to general sc_signal<T> v bool and sc_bv<WIDTH> support two value logic: o ‘0’ and ‘1’ v sc_logic and sc_lv<WIDTH> support four value logic: o SC_LOGIC_0 (‘0’), SC_LOGIC_1 (‘1’), SC_LOGIC_Z (‘Z’), SC_LOGIC_X (‘X’) v For sc_logic, a posedge_event occurs on any transition to SC_LOGIC_1, including from SC_LOGIC_X and SC_LOGIC_Z ECEN 468 Lecture 6 18
© Copyright 2024