17 #include "../../../interfaces/ahb/pe/ahb_initiator.h" 
   19 #include <atp/timing_params.h> 
   20 #include <scc/report.h> 
   22 using namespace sc_core;
 
   27 uint8_t log2n(uint8_t siz) { 
return ((siz > 1) ? 1 + log2n(siz >> 1) : 0); }
 
   31 ahb_initiator_b::ahb_initiator_b(sc_core::sc_module_name nm,
 
   32                                  sc_core::sc_port_b<tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>>& port, 
size_t transfer_width,
 
   36 , transfer_width_in_bytes(transfer_width / 8)
 
   37 , coherent(coherent) {
 
   45 ahb_initiator_b::~ahb_initiator_b() {
 
   46     for(
auto& e : tx_state_by_id)
 
   50 tlm::tlm_sync_enum ahb_initiator_b::nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t) {
 
   52     auto it = tx_state_by_id.find(&trans);
 
   53     sc_assert(it != tx_state_by_id.end());
 
   54     it->second->peq.notify(std::make_tuple(&trans, phase), t);
 
   55     return tlm::TLM_ACCEPTED;
 
   58 void ahb_initiator_b::invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {}
 
   61     sc_core::sc_time delay;
 
   62     SCCTRACE(SCMOD) << 
"Send REQ";
 
   63     tlm::tlm_sync_enum ret = socket_fw->nb_transport_fw(trans, phase, delay);
 
   64     if(ret == tlm::TLM_UPDATED) {
 
   68         auto entry = txs->peq.
get();
 
   69         sc_assert(std::get<0>(entry) == &trans);
 
   70         return std::get<1>(entry);
 
   75     SCCTRACE(SCMOD) << 
"got transport req for id=" << &trans;
 
   78         socket_fw->b_transport(trans, t);
 
   80         auto it = tx_state_by_id.find(&trans);
 
   81         if(it == tx_state_by_id.end()) {
 
   83             std::tie(it, success) = tx_state_by_id.insert(std::make_pair(&trans, 
new tx_state()));
 
   85         auto& txs = it->second;
 
   86         auto timing_e = trans.set_extension<atp::timing_params>(
nullptr);
 
   88         txs->active_tx = &trans;
 
   89         SCCTRACE(SCMOD) << 
"start transport req for id=" << &trans;
 
   93         auto delay_in_cycles = trans.is_read() ? (timing_e ? timing_e->artv : 
artv.value) : (timing_e ? timing_e->awtv : 
awtv.value);
 
   96         for(
unsigned i = 0; i < delay_in_cycles; ++i)
 
   97             wait(clk_i.posedge_event());
 
   98         auto burst_length = 0U;
 
   99         switch(ext->get_burst()) {
 
  100         case ahb::burst_e::SINGLE:
 
  103         case ahb::burst_e::INCR:
 
  106         case ahb::burst_e::WRAP4:
 
  107         case ahb::burst_e::INCR4:
 
  110         case ahb::burst_e::WRAP8:
 
  111         case ahb::burst_e::INCR8:
 
  114         case ahb::burst_e::WRAP16:
 
  115         case ahb::burst_e::INCR16:
 
  119         tlm::tlm_phase next_phase{tlm::UNINITIALIZED_PHASE};
 
  121         SCCTRACE(SCMOD) << 
"starting read address phase of tx with id=" << &trans;
 
  122         auto res = send(trans, txs, tlm::BEGIN_REQ);
 
  123         if(res == tlm::BEGIN_RESP)
 
  125         else if(res != tlm::END_REQ)
 
  126             SCCERR(SCMOD) << 
"target did not repsond with END_REQ to a BEGIN_REQ";
 
  127         wait(clk_i.posedge_event());
 
  128         auto finished = 
false;
 
  129         const auto exp_burst_length = burst_length;
 
  134             auto entry = next_phase == tlm::UNINITIALIZED_PHASE ? txs->peq.
get() : std::make_tuple(&trans, next_phase);
 
  135             next_phase = tlm::UNINITIALIZED_PHASE;
 
  137             if(std::get<0>(entry) == &trans && std::get<1>(entry) == tlm::BEGIN_RESP) {
 
  138                 SCCTRACE(SCMOD) << 
"received last beat of tx with id=" << &trans;
 
  139                 auto delay_in_cycles = timing_e ? (trans.is_read() ? timing_e->rbr : timing_e->br) : 
br.value;
 
  140                 for(
unsigned i = 0; i < delay_in_cycles; ++i)
 
  141                     wait(clk_i.posedge_event());
 
  142                 trans.set_response_status(tlm::TLM_OK_RESPONSE);
 
  144                 tlm::tlm_phase phase = tlm::END_RESP;
 
  145                 sc_time delay = clk_if ? clk_if->period() - 1_ps : SC_ZERO_TIME;
 
  146                 socket_fw->nb_transport_fw(trans, phase, delay);
 
  148                     SCCWARN(SCMOD) << 
"got wrong number of burst beats, expected " << exp_burst_length << 
", got " 
  149                                    << exp_burst_length - burst_length;
 
  150                 wait(clk_i.posedge_event());
 
  155         SCCTRACE(SCMOD) << 
"finished non-blocking protocol";
 
  156         txs->active_tx = 
nullptr;
 
  157         any_tx_finished.notify(SC_ZERO_TIME);
 
  159     SCCTRACE(SCMOD) << 
"finished transport req for id=" << &trans;
 
sc_core::sc_attribute< unsigned > artv
Read address valid to next read address valid.
 
sc_core::sc_attribute< unsigned > br
Write response valid to ready.
 
sc_core::sc_attribute< unsigned > awtv
Write address valid to next write address valid.
 
void transport(payload_type &trans, bool blocking)
The forward transport function. It behaves blocking and is re-entrant.
 
int post() override
unlock (give) the semaphore
 
int wait() override
lock (take) the semaphore, block if not available
 
protocol engine implementations
 
TLM2.0 components modeling AHB.