17 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES 
   18 #define SC_INCLUDE_DYNAMIC_PROCESSES 
   22 #include "protocol_fsm.h" 
   23 #include <scc/report.h> 
   25 #include <tlm/scc/tlm_id.h> 
   26 #include <tlm/scc/tlm_mm.h> 
   27 #include <scc/utilities.h> 
   29 using namespace sc_core;
 
   34 fsm_handle::fsm_handle():fsm{new AxiProtocolFsm()} {
 
   38 fsm_handle::~fsm_handle(){
 
   43 base::base(
size_t transfer_width, 
bool coherent, protocol_time_point_e wr_start)
 
   44 : transfer_width_in_bytes(transfer_width / 8)
 
   46 , coherent(coherent) {
 
   47     assert(wr_start == RequestPhaseBeg || wr_start == WValidE);
 
   50     sc_core::sc_spawn_options opts;
 
   51     opts.dont_initialize();
 
   53     opts.set_sensitivity(&fsm_event_queue.
event());
 
   54     sc_core::sc_spawn(sc_bind(&
base::process_fsm_event, 
this), sc_core::sc_gen_unique_name(
"fsm_event_method"), &opts);
 
   55     fsm_clk_queue.set_avail_cb([
this]() {
 
   56         if(fsm_clk_queue_hndl.valid())
 
   57             fsm_clk_queue_hndl.enable();
 
   59     fsm_clk_queue.set_empty_cb([
this]() {
 
   60         if(fsm_clk_queue_hndl.valid())
 
   61             fsm_clk_queue_hndl.disable();
 
   66     auto it = active_fsm.find(gp);
 
   67     if(!gp || it == active_fsm.end()) {
 
   69             SCCTRACE(instance_name) << 
"creating fsm for trans " << *gp;
 
   71             SCCTRACE(instance_name) << 
"creating fsm for new transaction";
 
   73         if(idle_fsm.empty()) {
 
   76             idle_fsm.push_back(fsm_hndl);
 
   77             allocated_fsm.emplace_back(fsm_hndl);
 
   79         auto fsm_hndl = idle_fsm.front();
 
   88         active_fsm.insert(std::make_pair(fsm_hndl->trans.get(), fsm_hndl));
 
   89         fsm_hndl->start = sc_time_stamp();
 
   92         it->second->start = sc_time_stamp();
 
   98     while(
auto e = fsm_event_queue.
get_next()) {
 
  100         if(std::get<2>(entry))
 
  101             schedule(std::get<0>(entry), std::get<1>(entry), 0);
 
  103             react(std::get<0>(entry), std::get<1>(entry));
 
  108     if(!fsm_clk_queue_hndl.valid())
 
  109         fsm_clk_queue_hndl = sc_process_handle(sc_get_current_process_handle());
 
  110     if(fsm_clk_queue.avail())
 
  111         while(fsm_clk_queue.avail()) {
 
  112             auto entry = fsm_clk_queue.front();
 
  113             if(std::get<2>(entry) == 0) {
 
  114                 SCCTRACE(instance_name) << 
"processing event " << evt2str(std::get<0>(entry)) << 
" of trans " 
  115                                         << *std::get<1>(entry);
 
  116                 react(std::get<0>(entry), std::get<1>(entry));
 
  118                 std::get<2>(entry) -= 1;
 
  119                 fsm_clk_queue.push_back(entry);
 
  121             fsm_clk_queue.pop_front();
 
  125         fsm_clk_queue_hndl.disable();
 
  129     SCCTRACE(instance_name)<< 
"in react() base has  coherent =" << coherent << 
" with event " << evt2str(event);
 
  130     fsm_hndl->state=event;
 
  133         fsm_hndl->
fsm->process_event(
WReq());
 
  136     case RequestPhaseBeg:
 
  165         SCCTRACE(instance_name)<< 
"in EndResp of base() with coherent =" << coherent;
 
  166         if(!coherent || fsm_hndl->
is_snoop) {
 
  167             SCCTRACE(instance_name) << 
"freeing fsm for trans " << *fsm_hndl->
trans;
 
  169             active_fsm.erase(fsm_hndl->
trans.
get());
 
  170             fsm_hndl->
trans = 
nullptr;
 
  171             idle_fsm.push_back(fsm_hndl);
 
  174             fsm_hndl->
fsm->process_event(EndRespNoAck());
 
  178         SCCTRACE(instance_name) << 
"freeing fsm for trans " << *fsm_hndl->
trans;
 
  179         fsm_hndl->
fsm->process_event(AckRecv());
 
  180         active_fsm.erase(fsm_hndl->
trans.
get());
 
  181         fsm_hndl->
trans = 
nullptr;
 
  182         idle_fsm.push_back(fsm_hndl);
 
  186         SCCFATAL(instance_name) << 
"No valid protocol time point";
 
  191     SCCTRACE(instance_name) << 
"base::nb_fw " << phase << 
" with delay = " << t << 
" of trans " << trans;
 
  192     if(phase == BEGIN_PARTIAL_REQ || phase == BEGIN_REQ) { 
 
  194         if(!trans.is_read()) {
 
  195             protocol_time_point_e evt = axi::fsm::RequestPhaseBeg;
 
  196             if(fsm_hndl->
beat_count == 0 && wr_start != RequestPhaseBeg)
 
  199                 evt = phase == BEGIN_PARTIAL_REQ ? BegPartReqE : BegReqE;
 
  200             if(t == SC_ZERO_TIME) {
 
  206             if(t == SC_ZERO_TIME) {
 
  207                 react(BegReqE, &trans);
 
  211     } 
else if(phase == END_PARTIAL_RESP || phase == END_RESP) {
 
  212         if(t == SC_ZERO_TIME) {
 
  213             react(phase == END_RESP ? EndRespE : EndPartRespE, &trans);
 
  215             schedule(phase == END_RESP ? EndRespE : EndPartRespE, &trans, t);
 
  216     } 
else if(phase == END_REQ) { 
 
  217         if(t == SC_ZERO_TIME) {
 
  218             react(EndReqE, &trans);
 
  221     } 
else if(phase == BEGIN_PARTIAL_RESP || phase == BEGIN_RESP) { 
 
  222         if(t == SC_ZERO_TIME) {
 
  223             react(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans);
 
  225             schedule(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t);
 
  226     } 
else if(phase == axi::ACK) {
 
  227         if(t == SC_ZERO_TIME) {
 
  236     SCCTRACE(instance_name) << 
"base::nb_bw " << phase << 
" of trans " << trans;
 
  237     if(phase == END_PARTIAL_REQ || phase == END_REQ) { 
 
  238         if(t == SC_ZERO_TIME) {
 
  239             react(phase == END_REQ ? EndReqE : EndPartReqE, &trans);
 
  241             schedule(phase == END_REQ ? EndReqE : EndPartReqE, &trans, t);
 
  242     } 
else if(phase == BEGIN_PARTIAL_RESP || phase == BEGIN_RESP) { 
 
  243         if(t == SC_ZERO_TIME) {
 
  244             react(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans);
 
  246             schedule(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t);
 
  247     } 
else if(phase == BEGIN_REQ) { 
 
  250         if(t == SC_ZERO_TIME) {
 
  251             react(BegReqE, &trans);
 
  254     } 
else if(phase == END_PARTIAL_RESP || phase == END_RESP) { 
 
  255         if(t == SC_ZERO_TIME) {
 
  256             react(phase == END_RESP ? EndRespE : EndPartRespE, &trans);
 
  258             schedule(phase == END_RESP ? EndRespE : EndPartRespE, &trans, t);
 
payload_type * allocate()
get a plain tlm_payload_type without extensions
 
T * get() const noexcept
Return the stored pointer.
 
TLM2.0 components modeling AHB.
 
bool is_burst(const axi::axi_protocol_types::tlm_payload_type &trans)
 
void react(axi::fsm::protocol_time_point_e event, tlm::scc::tlm_gp_shared_ptr &trans)
triggers the FSM with event and given transaction
 
tlm::tlm_sync_enum nb_fw(payload_type &trans, phase_type const &phase, sc_core::sc_time &t)
triggers the FSM based on TLM phases in the forward path. Should be called from np_transport_fw of th...
 
virtual void setup_callbacks(axi::fsm::fsm_handle *)=0
this function is called to add the callbacks to the fsm handle during creation. Needs to be implement...
 
void schedule(axi::fsm::protocol_time_point_e e, tlm::scc::tlm_gp_shared_ptr &gp, unsigned cycles)
processes the fsm_sched_queue and propagates events to fsm_clk_queue. Should be registered as falling...
 
void process_fsm_clk_queue()
processes the fsm_clk_queue and triggers the FSM accordingly. Should be registered as rising-edge clo...
 
tlm::tlm_sync_enum nb_bw(payload_type &trans, phase_type const &phase, sc_core::sc_time &t)
triggers the FSM based on TLM phases in the backward path. Should be called from np_transport_bw of t...
 
axi::fsm::fsm_handle * find_or_create(payload_type *gp=nullptr, bool ace=false)
retrieve the FSM handle based on the transaction passed. If non exist one will be created
 
void process_fsm_event()
processes the fsm_event_queue and triggers FSM aligned
 
axi::axi_protocol_types::tlm_payload_type payload_type
aliases used in the class
 
virtual axi::fsm::fsm_handle * create_fsm_handle()=0
function to create a fsm_handle. Needs to be implemented by the derived class
 
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
 
size_t beat_count
beat count of this transaction
 
AxiProtocolFsm *const fsm
pointer to the FSM
 
bool is_snoop
indicator if this is a snoop access
 
boost::optional< TYPE > get_next()
non-blocking get
 
sc_core::sc_event & event()
get the available event
 
static tlm_mm & get()
accessor function of the singleton