scc  2022.4.0
SystemC components library
ace_target_pe.cpp
1 /*
2  * Copyright 2020 Arteris IP
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.axi_util.cpp
15  */
16 
17 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18 #define SC_INCLUDE_DYNAMIC_PROCESSES
19 #endif
20 
21 #include <axi/pe/ace_target_pe.h>
22 #include <axi/fsm/protocol_fsm.h>
23 #include <axi/fsm/types.h>
24 #include <scc/report.h>
25 #include <scc/utilities.h>
26 #include <systemc>
27 #include <tuple>
28 
29 using namespace sc_core;
30 using namespace tlm;
31 using namespace axi;
32 using namespace axi::fsm;
33 using namespace axi::pe;
34 
35 /******************************************************************************
36  * target
37  ******************************************************************************/
39  ace_target_pe* const that;
41  : that(that) {}
42  unsigned transport(tlm::tlm_generic_payload& payload) override {
43  if((payload.is_read() && that->rd_resp_fifo.num_free())){
44  that->rd_resp_fifo.write(&payload);
45  return 0;
46  } else if((payload.is_write() && that->wr_resp_fifo.num_free())){
47  that->wr_resp_fifo.write(&payload);
48  return 0;
49  }
50  return std::numeric_limits<unsigned>::max();
51  }
52 };
53 
54 SC_HAS_PROCESS(ace_target_pe);
55 
56 ace_target_pe::ace_target_pe(const sc_core::sc_module_name& nm, size_t transfer_width)
57 : sc_module(nm)
58 , base(transfer_width, true) // coherent true
59 , bw_intor(new bw_intor_impl(this)) {
60  isckt_axi.bind(*this);
61  instance_name = name();
62 
63  add_attribute(rd_resp_delay);
64  add_attribute(wr_resp_delay);
65  bw_i.bind(*bw_intor);
66 
67  SC_METHOD(fsm_clk_method);
68  dont_initialize();
69  sensitive << clk_i.pos();
70 }
71 
72 ace_target_pe::~ace_target_pe() = default;
73 
74 void ace_target_pe::end_of_elaboration() {
75  clk_if = dynamic_cast<sc_core::sc_clock*>(clk_i.get_interface());
76 }
77 
78 void ace_target_pe::start_of_simulation() {
79  if (!socket_bw)
80  SCCFATAL(SCMOD) << "No backward interface registered!";
81 }
82 
83 
84 void ace_target_pe::b_transport(payload_type& trans, sc_time& t) {
85  auto latency = operation_cb ? operation_cb(trans) : trans.is_read() ? rd_resp_delay.get_value() : wr_resp_delay.get_value();
86  trans.set_dmi_allowed(false);
87  trans.set_response_status(tlm::TLM_OK_RESPONSE);
88  if(clk_if)
89  t += clk_if->period() * latency;
90 }
91 
92 tlm_sync_enum ace_target_pe::nb_transport_fw(payload_type& trans, phase_type& phase, sc_time& t) {
93  SCCTRACE(SCMOD)<<"in nb_transport_fw receives pahse " << phase;
94  auto ret = TLM_ACCEPTED;
95  if( phase == END_REQ) { // snoop
96  schedule(phase == END_REQ ? EndReqE : EndPartReqE, &trans, t, false);
97  } else if(phase == BEGIN_PARTIAL_RESP || phase == BEGIN_RESP) { // snoop response
98  schedule(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t, false);
99  } else { // forward read/Write
100  if(phase==axi::ACK)
101  return tlm::TLM_COMPLETED;
102  SCCTRACE(SCMOD) << " forward via axi_i_sckt, in nb_transport_fw () with phase "<<phase ;
103  return isckt_axi->nb_transport_fw(trans, phase, t);
104  }
105  return ret;
106 }
107 
108 bool ace_target_pe::get_direct_mem_ptr(payload_type& trans, tlm_dmi& dmi_data) {
109  trans.set_dmi_allowed(false);
110  return false;
111 }
112 
113 unsigned int ace_target_pe::transport_dbg(payload_type& trans) { return 0; }
114 
116 
118  fsm_hndl->fsm->cb[RequestPhaseBeg] = [this, fsm_hndl]() -> void {
119  fsm_hndl->beat_count = 0;
120  outstanding_cnt[fsm_hndl->trans->get_command()]++;
121  };
122  fsm_hndl->fsm->cb[BegPartReqE] = [this, fsm_hndl]() -> void {
123  // for snoop, state will not receive this event
124  };
125  fsm_hndl->fsm->cb[EndPartReqE] = [this, fsm_hndl]() -> void {
126  // for snoop, state will not receive this event
127  };
128  fsm_hndl->fsm->cb[BegReqE] = [this, fsm_hndl]() -> void {
129  SCCTRACE(SCMOD)<< "in BegReq of setup_cb";
130  if(fsm_hndl->is_snoop) {
131  sc_time t;
132  tlm::tlm_phase phase = tlm::BEGIN_REQ;
133  auto ret = socket_bw->nb_transport_bw(*fsm_hndl->trans, phase, t);
134  }
135  };
136  fsm_hndl->fsm->cb[EndReqE] = [this, fsm_hndl]() -> void {
137  SCCTRACE(SCMOD)<<" EndReqE in setup_cb";
138  };
139  fsm_hndl->fsm->cb[BegPartRespE] = [this, fsm_hndl]() -> void {
140  SCCTRACE(SCMOD) <<"in BegPartRespE of setup_cb, ";
141  sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
142  schedule(EndPartRespE, fsm_hndl->trans, t);
143  };
144  fsm_hndl->fsm->cb[EndPartRespE] = [this, fsm_hndl]() -> void {
145  SCCTRACE(SCMOD) <<"in EndPartRespE of setup_cb";
146  //sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
147  sc_time t(SC_ZERO_TIME);
148  tlm::tlm_phase phase = axi::END_PARTIAL_RESP;
149  auto ret = socket_bw->nb_transport_bw(*fsm_hndl->trans, phase, t);
150  fsm_hndl->beat_count++;
151  };
152  fsm_hndl->fsm->cb[BegRespE] = [this, fsm_hndl]() -> void {
153  SCCTRACE(SCMOD) <<"in BegRespE of setup_cb";
154  sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
155  tlm::tlm_phase phase = tlm::END_RESP;
156  auto ret = socket_bw->nb_transport_bw(*fsm_hndl->trans, phase, t);
157  t=::scc::time_to_next_posedge(clk_if);
158  /* here *3 because after send() of intiator ,there is one cycle wait
159  * target here need to wait long cycles so that gp_shared_ptr can be released
160  */
161  schedule(EndRespE, fsm_hndl->trans, 3*t);
162  };
163  fsm_hndl->fsm->cb[EndRespE] = [this, fsm_hndl]() -> void {
164  /*
165  sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
166  tlm::tlm_phase phase = tlm::END_RESP;
167  auto ret = socket_bw->nb_transport_bw(*fsm_hndl->trans, phase, t);
168  */
169  SCCTRACE(SCMOD)<< "notifying finish ";
170  fsm_hndl->finish.notify();
171  };
172  /*TBD threre is ack for snoop_trans
173  * */
174 }
175 
176 void ace_target_pe::snoop(payload_type& trans) {
177  SCCTRACE(SCMOD) << "got transport snoop trans ";
178  bool ace= true;
179  fsm_handle* fsm = find_or_create(&trans,true);
180  fsm->is_snoop = true;
181  react(RequestPhaseBeg, fsm->trans); //
182  SCCTRACE(SCMOD) << "started non-blocking protocol";
183  sc_core::wait(fsm->finish);
184  SCCTRACE(SCMOD) << "finished non-blocking protocol";
185 }
186 
187 
fsm::fsm_handle * create_fsm_handle() override
scc::sc_attribute_randomized< int > wr_resp_delay
the latency between request and response phase. Will be overwritten by the return of the callback fun...
Definition: ace_target_pe.h:66
void setup_callbacks(fsm::fsm_handle *) override
protocol engine implementations
Definition: ace_target_pe.h:37
TLM2.0 components modeling AHB.
Definition: axi_initiator.h:30
SystemC TLM.
unsigned transport(tlm::tlm_generic_payload &payload) override
base class of all AXITLM based adapters and interfaces.
Definition: base.h:43
void react(axi::fsm::protocol_time_point_e event, tlm::scc::tlm_gp_shared_ptr &trans)
triggers the FSM with event and given transaction
Definition: base.h:134
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...
Definition: base.h:107
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
Definition: base.cpp:65
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
Definition: types.h:62
sc_core::sc_event finish
event indicating the end of the transaction
Definition: types.h:68
size_t beat_count
beat count of this transaction
Definition: types.h:64
AxiProtocolFsm *const fsm
pointer to the FSM
Definition: types.h:60
bool is_snoop
indicator if this is a snoop access
Definition: types.h:66