17 #include <axi/checker/axi_protocol.h> 
   18 #include <scc/report.h> 
   22 void axi_protocol::fw_pre(
const axi_protocol::payload_type &trans, 
const axi_protocol::phase_type &phase) {
 
   23     auto cmd = trans.get_command();
 
   24     if (cmd == tlm::TLM_IGNORE_COMMAND)
 
   25         SCCERR(name) << 
"Illegal command: tlm::TLM_IGNORE_COMMAND on forward path";
 
   26     if (check_phase_change(trans, phase))
 
   28         SCCERR(name) << 
"Illegal phase transition: " << phase.get_name() << 
" on forward path";
 
   30         SCCERR(name) << 
"Illegal phase transition: " << phase << 
" on forward path";
 
   34 void axi_protocol::fw_post(
const axi_protocol::payload_type &trans, 
const axi_protocol::phase_type &phase, tlm::tlm_sync_enum rstat) {
 
   35     if(rstat == tlm::TLM_ACCEPTED) 
return;
 
   36     auto cmd = trans.get_command();
 
   37     if(req_beat[cmd]==tlm::BEGIN_REQ && (phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP))
 
   38         req_beat[cmd]= tlm::UNINITIALIZED_PHASE;
 
   39     if (check_phase_change(trans, phase))
 
   41         SCCERR(name) << 
"Illegal phase transition: " << phase.get_name() << 
" on return in forward path";
 
   43         SCCERR(name) << 
"Illegal phase transition: " << phase << 
" on return in forward path";
 
   47 void axi_protocol::bw_pre(
const axi_protocol::payload_type &trans, 
const axi_protocol::phase_type &phase) {
 
   48     auto cmd = trans.get_command();
 
   49     if (cmd == tlm::TLM_IGNORE_COMMAND)
 
   50         SCCERR(name) << 
"Illegal command:  tlm::TLM_IGNORE_COMMAND on forward path";
 
   51     if (check_phase_change(trans, phase))
 
   53         SCCERR(name) << 
"Illegal phase transition: " << phase.get_name() << 
" on backward path";
 
   55         SCCERR(name) << 
"Illegal phase transition: " << phase << 
" on backward path";
 
   59 void axi_protocol::bw_post(
const axi_protocol::payload_type &trans, 
const axi_protocol::phase_type &phase, tlm::tlm_sync_enum rstat) {
 
   60     if(rstat == tlm::TLM_ACCEPTED) 
return;
 
   61     if (check_phase_change(trans, phase))
 
   63         SCCERR(name) << 
"Illegal phase transition: " << phase.get_name() << 
" on return in backward path";
 
   65         SCCERR(name) << 
"Illegal phase transition: " << phase << 
" on return in backward path";
 
   69 bool axi_protocol::check_phase_change(payload_type 
const& trans, 
const axi_protocol::phase_type &phase) {
 
   71     auto cur_req = req_beat[trans.get_command()];
 
   72     auto cur_resp = resp_beat[trans.get_command()];
 
   74     if (phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
 
   75         error |= cur_req != tlm::UNINITIALIZED_PHASE;
 
   77     } 
else if(phase==axi::END_PARTIAL_REQ) {
 
   78         error |= cur_req != axi::BEGIN_PARTIAL_REQ;
 
   79         cur_req = tlm::UNINITIALIZED_PHASE;
 
   80     } 
else if(phase==tlm::END_REQ) {
 
   81         error |= cur_req != tlm::BEGIN_REQ;
 
   82         cur_req = tlm::UNINITIALIZED_PHASE;
 
   83     } 
else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
 
   84         error |= cur_resp!=tlm::UNINITIALIZED_PHASE;
 
   86     } 
else if (phase == tlm::END_RESP) {
 
   87         error |= cur_resp != tlm::BEGIN_RESP;
 
   88         cur_resp = tlm::UNINITIALIZED_PHASE;
 
   89     } 
else if (phase == axi::END_PARTIAL_RESP) {
 
   90         error |= cur_resp != axi::BEGIN_PARTIAL_RESP;
 
   91         cur_resp = tlm::UNINITIALIZED_PHASE;
 
   95     if(req_beat[trans.get_command()] != cur_req){
 
   96         req_beat[trans.get_command()] = cur_req;
 
   97         request_update(trans);
 
   99     if(resp_beat[trans.get_command()] != cur_resp){
 
  100         resp_beat[trans.get_command()] = cur_resp;
 
  101         response_update(trans);
 
  106 void axi_protocol::request_update(
const payload_type &trans) {
 
  107     auto axi_id = axi::get_axi_id(trans);
 
  109     if(trans.is_write()){
 
  110         if(req_beat[tlm::TLM_WRITE_COMMAND]==tlm::UNINITIALIZED_PHASE) {
 
  111             req_id[tlm::TLM_WRITE_COMMAND] = umax;
 
  113             if(req_id[tlm::TLM_WRITE_COMMAND] == umax) {
 
  114                 req_id[tlm::TLM_WRITE_COMMAND] = axi_id;
 
  116             } 
else if(req_id[tlm::TLM_WRITE_COMMAND] != axi_id){
 
  117                 SCCERR(name) << 
"Illegal ordering: a transaction with AWID:0x"<<std::hex<<axi_id<<
" starts while a transaction with AWID:0x"<<req_id[tlm::TLM_WRITE_COMMAND]<<
" is active";
 
  119             if(req_beat[tlm::TLM_WRITE_COMMAND]==tlm::BEGIN_REQ) {
 
  120                 if(wr_req_beat_count != axi_burst_len){
 
  121                     SCCERR(name) << 
"Illegal AXI settings: number of transferred beats ("<<wr_req_beat_count<<
") does not comply with AWLEN:0x"<<std::hex<<
axi::get_burst_length(trans)-1;
 
  124                 open_tx_by_id[tlm::TLM_WRITE_COMMAND][axi_id].push_back(
reinterpret_cast<uintptr_t
>(&trans));
 
  125                 check_properties(trans);
 
  128     } 
else if(trans.is_read()) {
 
  129         if(req_beat[tlm::TLM_READ_COMMAND]==tlm::UNINITIALIZED_PHASE) {
 
  130             req_id[tlm::TLM_READ_COMMAND] = umax;
 
  131         } 
else  if(req_beat[tlm::TLM_READ_COMMAND]==tlm::BEGIN_REQ) {
 
  132             if(req_id[tlm::TLM_READ_COMMAND] == umax) {
 
  133                 req_id[tlm::TLM_READ_COMMAND] = axi_id;
 
  134                 open_tx_by_id[tlm::TLM_READ_COMMAND][axi_id].push_back(
reinterpret_cast<uintptr_t
>(&trans));
 
  135             } 
else if(req_id[tlm::TLM_READ_COMMAND] != axi_id){
 
  136                 SCCERR(name) << 
"Illegal phase: a read transaction uses a phase with id "<<req_beat[tlm::TLM_READ_COMMAND];
 
  138             check_properties(trans);
 
  140             SCCERR(name) << 
"Illegal phase: a read transaction uses a phase with id "<<req_beat[tlm::TLM_READ_COMMAND];
 
  145 void axi_protocol::response_update(
const payload_type &trans) {
 
  146     auto axi_id = axi::get_axi_id(trans);
 
  148     if(trans.is_write()){
 
  149         if(resp_beat[tlm::TLM_WRITE_COMMAND]==tlm::UNINITIALIZED_PHASE) {
 
  150             resp_id[tlm::TLM_WRITE_COMMAND] = umax;
 
  151         } 
else  if(resp_beat[tlm::TLM_WRITE_COMMAND]==tlm::BEGIN_RESP) {
 
  152             if(resp_id[tlm::TLM_WRITE_COMMAND] == umax) {
 
  153                 resp_id[tlm::TLM_WRITE_COMMAND] = axi_id;
 
  154                 if(open_tx_by_id[tlm::TLM_WRITE_COMMAND][axi_id].front()!=
reinterpret_cast<uintptr_t
>(&trans)) {
 
  155                     SCCERR(name) << 
"Write response ordering violation: a response with AWID:0x"<<std::hex<<axi_id<<
" starts before the previous response with the same id finished";
 
  157             } 
else if(resp_id[tlm::TLM_WRITE_COMMAND] != axi_id){
 
  158                 SCCERR(name) << 
"Illegal phase: a read transaction uses a phase with id "<<resp_beat[tlm::TLM_WRITE_COMMAND];
 
  160             open_tx_by_id[tlm::TLM_WRITE_COMMAND][axi_id].pop_front();
 
  162             SCCERR(name) << 
"Illegal phase: a read transaction uses a phase with id "<<resp_beat[tlm::TLM_WRITE_COMMAND];
 
  164     } 
else if(trans.is_read()) {
 
  165         if(resp_beat[tlm::TLM_READ_COMMAND]==tlm::UNINITIALIZED_PHASE) {
 
  166             resp_id[tlm::TLM_READ_COMMAND] = umax;
 
  168             if(resp_id[tlm::TLM_READ_COMMAND] == umax) {
 
  169                 resp_id[tlm::TLM_READ_COMMAND] = axi_id;
 
  170                 if(open_tx_by_id[tlm::TLM_READ_COMMAND][axi_id].front()!=
reinterpret_cast<uintptr_t
>(&trans)) {
 
  171                     SCCERR(name) << 
"Read response ordering violation: a response with ARID:0x"<<std::hex<<axi_id<<
" starts before the previous response with the same id finished";
 
  173                 rd_resp_beat_count[axi_id]++;
 
  174             } 
else if(resp_id[tlm::TLM_READ_COMMAND] != axi_id){
 
  175                 SCCERR(name) << 
"Illegal phase: a read transaction uses a phase with id "<<resp_beat[tlm::TLM_READ_COMMAND];
 
  177             if(resp_beat[tlm::TLM_READ_COMMAND]==tlm::BEGIN_RESP)  {
 
  178                 if(rd_resp_beat_count[axi_id] != axi_burst_len){
 
  179                     SCCERR(name) << 
"Illegal AXI settings: number of transferred beats ("<<wr_req_beat_count<<
") does not comply with AWLEN:0x"<<std::hex<<
axi::get_burst_length(trans)-1;
 
  181                 open_tx_by_id[tlm::TLM_READ_COMMAND][axi_id].pop_front();
 
  182                 rd_resp_beat_count[axi_id]=0;
 
  188 void axi_protocol::check_datawith_settings(payload_type 
const&trans){
 
  192     auto offset = trans.get_address() & mask;
 
  194         if(trans.get_data_length() != (axi_burst_size * axi_burst_len)) {
 
  195             SCCERR(name) << 
"Illegal AXI settings: transaction data length (" << trans.get_data_length() << 
") does not correspond to AxSIZE/AxLEN  setting (" 
  196             << axi_burst_size << 
"/" << axi_burst_len-1 << 
") and buswidth "<<bw<< 
" for " << trans;
 
  199         if((trans.get_data_length() + offset) > (axi_burst_size * axi_burst_len)) {
 
  200             SCCERR(name) << 
"Illegal AXI settings: transaction data length (" << trans.get_data_length() << 
") does not correspond to AxSIZE/AxLEN  setting (" 
  201             << axi_burst_size << 
"/" << axi_burst_len-1 << 
") and buswidth "<<bw<< 
" for " << trans;
 
  210 void axi_protocol::check_properties(
const payload_type &trans) {
 
  211     check_datawith_settings(trans);
 
  213         if(axi4_ext->get_cache()&0xc0) {
 
  214             if(!axi4_ext->get_cache())
 
  215                 SCCERR(name)<<
"Illegal AXI settings: active allocate bit(s) requires modifiable bit set";
 
  217         if(axi4_ext->get_qos()>15)
 
  218             SCCERR(name)<<
"Illegal AXI4 settings: maximum value of QoS is 15, illegal value is "<<axi4_ext->get_qos();
 
  220         if(ace_ext->get_cache()&0xc0) {
 
  221             if(!ace_ext->get_cache())
 
  222                 SCCERR(name)<<
"Illegal ACEL settings: active allocate bit(s) requires modifiable bit set";
 
  223             auto snoop = ace_ext->get_snoop();
 
  224             auto domain = ace_ext->get_domain();
 
  225             auto bar = ace_ext->get_barrier();
 
  226             switch(comb(bar, domain, snoop)){
 
  227             case comb(bar_e::RESPECT_BARRIER, domain_e::NON_SHAREABLE, snoop_e::READ_NO_SNOOP):
 
  257                 SCCERR(name)<<
"Illegal ACEL settings: According to D11.2 ACE-Lite signal requirements of ARM IHI 0022H  the following setting is illegal:\n" 
  262         if(axi3_ext->get_cache()&0xc0) {
 
  263             if(!axi3_ext->get_cache())
 
  264                 SCCERR(name)<<
"Illegal AXI settings: active allocate bit(s) requires modifiable bit set";
 
TLM2.0 components modeling AHB.
unsigned get_burst_length(const request &r)
@ MEMORY_BARRIER
Normal access, respecting barriers.
const char * to_char(E t)
constexpr ULT to_int(E t)
unsigned get_burst_size(const request &r)