17#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18#define SC_INCLUDE_DYNAMIC_PROCESSES
21#include <axi/fsm/protocol_fsm.h>
22#include <axi/fsm/types.h>
23#include <axi/pe/ace_target_pe.h>
24#include <scc/mt19937_rng.h>
25#include <scc/report.h>
26#include <scc/utilities.h>
30using namespace sc_core;
33using 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();
56#if SYSTEMC_VERSION < 20250221
61,
base(transfer_width, true)
63 isckt_axi.bind(*
this);
64 instance_name = name();
68 SC_METHOD(fsm_clk_method);
70 sensitive << clk_i.pos();
73ace_target_pe::~ace_target_pe() =
default;
75void ace_target_pe::end_of_elaboration() { clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface()); }
77void ace_target_pe::start_of_simulation() {
79 SCCFATAL(SCMOD) <<
"No backward interface registered!";
82inline unsigned get_cci_randomized_value(cci::cci_param<int>
const& p) {
84 return ::scc::MT19937::uniform(0, -p.get_value());
88void ace_target_pe::b_transport(payload_type& trans, sc_time& t) {
89 auto latency = operation_cb ? operation_cb(trans)
92 trans.set_dmi_allowed(
false);
93 trans.set_response_status(tlm::TLM_OK_RESPONSE);
95 t += clk_if->period() * latency;
98tlm_sync_enum ace_target_pe::nb_transport_fw(payload_type& trans, phase_type& phase, sc_time& t) {
99 SCCTRACE(SCMOD) <<
"in nb_transport_fw receives pahse " << phase;
100 auto ret = TLM_ACCEPTED;
101 if(phase == END_REQ) {
102 schedule(phase == END_REQ ? EndReqE : EndPartReqE, &trans, t,
false);
103 }
else if(phase == BEGIN_PARTIAL_RESP || phase == BEGIN_RESP) {
104 schedule(phase == BEGIN_RESP ? BegRespE : BegPartRespE, &trans, t,
false);
106 if(phase == axi::ACK)
107 return tlm::TLM_COMPLETED;
108 SCCTRACE(SCMOD) <<
" forward via axi_i_sckt, in nb_transport_fw () with phase " << phase;
109 return isckt_axi->nb_transport_fw(trans, phase, t);
114bool ace_target_pe::get_direct_mem_ptr(payload_type& trans, tlm_dmi& dmi_data) {
115 trans.set_dmi_allowed(
false);
119unsigned int ace_target_pe::transport_dbg(payload_type& trans) {
return 0; }
124 fsm_hndl->
fsm->cb[RequestPhaseBeg] = [
this, fsm_hndl]() ->
void {
126 outstanding_cnt[fsm_hndl->
trans->get_command()]++;
128 fsm_hndl->
fsm->cb[BegPartReqE] = [
this, fsm_hndl]() ->
void {
131 fsm_hndl->
fsm->cb[EndPartReqE] = [
this, fsm_hndl]() ->
void {
134 fsm_hndl->
fsm->cb[BegReqE] = [
this, fsm_hndl]() ->
void {
135 SCCTRACE(SCMOD) <<
"in BegReq of setup_cb";
138 tlm::tlm_phase phase = tlm::BEGIN_REQ;
139 auto ret = socket_bw->nb_transport_bw(*fsm_hndl->
trans, phase, t);
142 fsm_hndl->
fsm->cb[EndReqE] = [
this, fsm_hndl]() ->
void { 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();
180void ace_target_pe::snoop(payload_type& trans) {
181 SCCTRACE(SCMOD) <<
"got transport snoop trans ";
184 fsm->is_snoop =
true;
185 react(RequestPhaseBeg, fsm->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...
ace_target_pe(const sc_core::sc_module_name &nm, size_t transfer_width)
void setup_callbacks(fsm::fsm_handle *) override
protocol engine implementations
TLM2.0 components modeling AHB.
unsigned transport(tlm::tlm_generic_payload &payload) override
void react(axi::fsm::protocol_time_point_e event, tlm::scc::tlm_gp_shared_ptr &trans)
triggers the FSM with event and given transaction
base(size_t transfer_width, bool coherent=false, axi::fsm::protocol_time_point_e wr_start=axi::fsm::RequestPhaseBeg)
the constructor
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