17 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18 #define SC_INCLUDE_DYNAMIC_PROCESSES
21 #include <axi/pe/ace_target_pe.h>
22 #include <axi/fsm/protocol_fsm.h>
23 #include <axi/fsm/types.h>
24 #include <scc/mt19937_rng.h>
25 #include <scc/report.h>
26 #include <scc/utilities.h>
30 using namespace sc_core;
33 using namespace axi::fsm;
43 unsigned transport(tlm::tlm_generic_payload& payload)
override {
44 if((payload.is_read() && that->rd_resp_fifo.num_free())){
45 that->rd_resp_fifo.write(&payload);
47 }
else if((payload.is_write() && that->wr_resp_fifo.num_free())){
48 that->wr_resp_fifo.write(&payload);
51 return std::numeric_limits<unsigned>::max();
58 ace_target_pe::ace_target_pe(
const sc_core::sc_module_name& nm,
size_t transfer_width)
60 ,
base(transfer_width, true)
62 isckt_axi.bind(*
this);
63 instance_name = name();
67 SC_METHOD(fsm_clk_method);
69 sensitive << clk_i.pos();
72 ace_target_pe::~ace_target_pe() =
default;
74 void ace_target_pe::end_of_elaboration() {
75 clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface());
78 void ace_target_pe::start_of_simulation() {
80 SCCFATAL(SCMOD) <<
"No backward interface registered!";
83 inline unsigned get_cci_randomized_value(cci::cci_param<int>
const& p) {
84 if(p.get_value()<0) return ::scc::MT19937::uniform(0, -p.get_value());
88 void ace_target_pe::b_transport(payload_type& trans, sc_time& t) {
89 auto latency = operation_cb ? operation_cb(trans) : trans.is_read()?get_cci_randomized_value(
rd_resp_delay):get_cci_randomized_value(
wr_resp_delay);
90 trans.set_dmi_allowed(
false);
91 trans.set_response_status(tlm::TLM_OK_RESPONSE);
93 t += clk_if->period() * latency;
96 tlm_sync_enum ace_target_pe::nb_transport_fw(payload_type& trans, phase_type& phase, sc_time& t) {
97 SCCTRACE(SCMOD)<<
"in nb_transport_fw receives pahse " << phase;
98 auto ret = TLM_ACCEPTED;
99 if( phase == END_REQ) {
100 schedule(phase == END_REQ ? EndReqE : EndPartReqE, &trans, t,
false);
101 }
else if(phase == BEGIN_PARTIAL_RESP || phase == BEGIN_RESP) {
102 schedule(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t,
false);
105 return tlm::TLM_COMPLETED;
106 SCCTRACE(SCMOD) <<
" forward via axi_i_sckt, in nb_transport_fw () with phase "<<phase ;
107 return isckt_axi->nb_transport_fw(trans, phase, t);
112 bool ace_target_pe::get_direct_mem_ptr(payload_type& trans, tlm_dmi& dmi_data) {
113 trans.set_dmi_allowed(
false);
117 unsigned int ace_target_pe::transport_dbg(payload_type& trans) {
return 0; }
122 fsm_hndl->
fsm->cb[RequestPhaseBeg] = [
this, fsm_hndl]() ->
void {
124 outstanding_cnt[fsm_hndl->
trans->get_command()]++;
126 fsm_hndl->
fsm->cb[BegPartReqE] = [
this, fsm_hndl]() ->
void {
129 fsm_hndl->
fsm->cb[EndPartReqE] = [
this, fsm_hndl]() ->
void {
132 fsm_hndl->
fsm->cb[BegReqE] = [
this, fsm_hndl]() ->
void {
133 SCCTRACE(SCMOD)<<
"in BegReq of setup_cb";
136 tlm::tlm_phase phase = tlm::BEGIN_REQ;
137 auto ret = socket_bw->nb_transport_bw(*fsm_hndl->
trans, phase, t);
140 fsm_hndl->
fsm->cb[EndReqE] = [
this, fsm_hndl]() ->
void {
141 SCCTRACE(SCMOD)<<
" EndReqE in setup_cb";
143 fsm_hndl->
fsm->cb[BegPartRespE] = [
this, fsm_hndl]() ->
void {
144 SCCTRACE(SCMOD) <<
"in BegPartRespE of setup_cb, ";
145 sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
148 fsm_hndl->
fsm->cb[EndPartRespE] = [
this, fsm_hndl]() ->
void {
149 SCCTRACE(SCMOD) <<
"in EndPartRespE of setup_cb";
151 sc_time t(SC_ZERO_TIME);
152 tlm::tlm_phase phase = axi::END_PARTIAL_RESP;
153 auto ret = socket_bw->nb_transport_bw(*fsm_hndl->
trans, phase, t);
156 fsm_hndl->
fsm->cb[BegRespE] = [
this, fsm_hndl]() ->
void {
157 SCCTRACE(SCMOD) <<
"in BegRespE of setup_cb";
158 sc_time t(clk_if ? ::scc::time_to_next_posedge(clk_if) - 1_ps : SC_ZERO_TIME);
159 tlm::tlm_phase phase = tlm::END_RESP;
160 auto ret = socket_bw->nb_transport_bw(*fsm_hndl->
trans, phase, t);
161 t=::scc::time_to_next_posedge(clk_if);
167 fsm_hndl->
fsm->cb[EndRespE] = [
this, fsm_hndl]() ->
void {
173 SCCTRACE(SCMOD)<<
"notifying finish ";
174 fsm_hndl->
finish.notify();
180 void ace_target_pe::snoop(payload_type& trans) {
181 SCCTRACE(SCMOD) <<
"got transport snoop trans ";
186 SCCTRACE(SCMOD) <<
"started non-blocking protocol";
187 sc_core::wait(fsm->
finish);
188 SCCTRACE(SCMOD) <<
"finished non-blocking protocol";
fsm::fsm_handle * create_fsm_handle() override
cci::cci_param< int > wr_resp_delay
the latency between write request and response phase. Will be overwritten by the return of the callba...
cci::cci_param< int > rd_resp_delay
the latency between read request and response phase. Will be overwritten by the return of the callbac...
void setup_callbacks(fsm::fsm_handle *) override
protocol engine implementations
TLM2.0 components modeling AHB.
unsigned transport(tlm::tlm_generic_payload &payload) override
base class of all AXITLM based adapters and interfaces.
void react(axi::fsm::protocol_time_point_e event, tlm::scc::tlm_gp_shared_ptr &trans)
triggers the FSM with event and given transaction
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...
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
tlm::scc::tlm_gp_shared_ptr trans
pointer to the associated AXITLM payload
sc_core::sc_event finish
event indicating the end of the transaction
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